diff --git a/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h b/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h
--- a/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h
+++ b/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h
@@ -81,6 +81,37 @@
 
   // All non-debug instructions
   int64_t TotalInstructionCount = 0;
+
+  // Basic blocks grouped by number of successors.
+  int64_t BasicBlocksWithSingleSuccessor = 0;
+  int64_t BasicBlocksWithTwoSuccessors = 0;
+  int64_t BasicBlocksWithMoreThanTwoSuccessors = 0;
+
+  // Basic blocks grouped by number of predecessors.
+  int64_t BasicBlocksWithSinglePredecessor = 0;
+  int64_t BasicBlocksWithTwoPredecessors = 0;
+  int64_t BasicBlocksWithMoreThanTwoPredecessors = 0;
+
+  // Basic blocks grouped by size as determined by the number of non-debug
+  // instructions that they contain.
+  int64_t BigBasicBlocks = 0;
+  int64_t MediumBasicBlocks = 0;
+  int64_t SmallBasicBlocks = 0;
+
+  // The number of cast instructions inside the function.
+  int64_t CastInstructionCount = 0;
+
+  // The number of floating point instructions inside the function.
+  int64_t FloatingPointInstructionCount = 0;
+
+  // The number of integer instructions inside the function.
+  int64_t IntegerInstructionCount = 0;
+
+  // The number of integer constant operands inside the function.
+  int64_t IntegerConstantCount = 0;
+
+  // The number of floating point constant operands inside the function.
+  int64_t FloatingPointConstantCount = 0;
 };
 
 // Analysis pass
diff --git a/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp b/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
--- a/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
+++ b/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
@@ -18,10 +18,25 @@
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/Instructions.h"
+#include "llvm/Support/CommandLine.h"
 #include <deque>
 
 using namespace llvm;
 
+cl::opt<bool> EnableDetailedFunctionProperties(
+    "enable-detailed-function-properties", cl::Hidden, cl::init(false),
+    cl::desc("Whether or not to compute detailed function properties."));
+
+cl::opt<unsigned> BigBasicBlockInstructionThreshold(
+    "big-basic-block-instruction-threshold", cl::Hidden, cl::init(500),
+    cl::desc("The minimum number of instructions a basic block should contain "
+             "before being considered big."));
+
+cl::opt<unsigned> MediumBasicBlockInstructionThreshold(
+    "medium-basic-block-instruction-threshold", cl::Hidden, cl::init(15),
+    cl::desc("The minimum number of instructions a basic block should contain "
+             "before being considered medium-sized."));
+
 namespace {
 int64_t getNrBlocksFromCond(const BasicBlock &BB) {
   int64_t Ret = 0;
@@ -62,6 +77,52 @@
     }
   }
   TotalInstructionCount += Direction * BB.sizeWithoutDebug();
+
+  if (EnableDetailedFunctionProperties) {
+    unsigned SuccessorCount = succ_size(&BB);
+    if (SuccessorCount == 1)
+      BasicBlocksWithSingleSuccessor += Direction;
+    else if (SuccessorCount == 2)
+      BasicBlocksWithTwoSuccessors += Direction;
+    else if (SuccessorCount > 2)
+      BasicBlocksWithMoreThanTwoSuccessors += Direction;
+
+    unsigned PredecessorCount = succ_size(&BB);
+    if (PredecessorCount == 1)
+      BasicBlocksWithSinglePredecessor += Direction;
+    else if (PredecessorCount == 2)
+      BasicBlocksWithTwoPredecessors += Direction;
+    else if (PredecessorCount > 2)
+      BasicBlocksWithMoreThanTwoPredecessors += Direction;
+
+    if (TotalInstructionCount > BigBasicBlockInstructionThreshold)
+      BigBasicBlocks += Direction;
+    else if (TotalInstructionCount > MediumBasicBlockInstructionThreshold)
+      MediumBasicBlocks += Direction;
+    else
+      SmallBasicBlocks += Direction;
+
+    for (const Instruction &I : BB) {
+      if (I.isCast())
+        CastInstructionCount += Direction;
+
+      if (I.getType()->isFloatTy())
+        FloatingPointInstructionCount += Direction;
+      else if (I.getType()->isIntegerTy())
+        IntegerInstructionCount += Direction;
+
+      for (unsigned int OperandIndex = 0; OperandIndex < I.getNumOperands();
+           ++OperandIndex) {
+        if (const Constant *C =
+                dyn_cast<Constant>(I.getOperand(OperandIndex))) {
+          if (C->getType()->isIntegerTy())
+            IntegerConstantCount += 1;
+          else if (C->getType()->isFloatTy())
+            FloatingPointConstantCount += 1;
+        }
+      }
+    }
+  }
 }
 
 void FunctionPropertiesInfo::updateAggregateStats(const Function &F,
@@ -109,7 +170,31 @@
      << "StoreInstCount: " << StoreInstCount << "\n"
      << "MaxLoopDepth: " << MaxLoopDepth << "\n"
      << "TopLevelLoopCount: " << TopLevelLoopCount << "\n"
-     << "TotalInstructionCount: " << TotalInstructionCount << "\n\n";
+     << "TotalInstructionCount: " << TotalInstructionCount << "\n";
+  if (EnableDetailedFunctionProperties) {
+    OS << "BasicBlocksWithSingleSuccessor: " << BasicBlocksWithSingleSuccessor
+       << "\n"
+       << "BasicBlocksWithTwoSuccessors: " << BasicBlocksWithTwoSuccessors
+       << "\n"
+       << "BasicBlocksWithMoreThanTwoSuccessors: "
+       << BasicBlocksWithMoreThanTwoSuccessors << "\n"
+       << "BasicBlocksWithSinglePredecessor: "
+       << BasicBlocksWithSinglePredecessor << "\n"
+       << "BasicBlocksWithTwoPredecessors: " << BasicBlocksWithTwoPredecessors
+       << "\n"
+       << "BasicBlocksWithMoreThanTwoPredecessors: "
+       << BasicBlocksWithMoreThanTwoPredecessors << "\n"
+       << "BigBasicBlocks: " << BigBasicBlocks << "\n"
+       << "MediumBasicBlocks: " << MediumBasicBlocks << "\n"
+       << "SmallBasicBlocks: " << SmallBasicBlocks << "\n"
+       << "CastInstructionCount: " << CastInstructionCount << "\n"
+       << "FloatingPointInstructionCount: " << FloatingPointInstructionCount
+       << "\n"
+       << "IntegerInstructionCount: " << IntegerInstructionCount << "\n"
+       << "IntegerConstantCount: " << IntegerConstantCount << "\n"
+       << "FloatingPointConstantCount: " << FloatingPointConstantCount << "\n";
+  }
+  OS << "\n";
 }
 
 AnalysisKey FunctionPropertiesAnalysis::Key;
@@ -258,4 +343,4 @@
   LoopInfo LI(DT);
   auto Fresh = FunctionPropertiesInfo::getFunctionPropertiesInfo(F, DT, LI);
   return FPI == Fresh;
-}
\ No newline at end of file
+}
diff --git a/llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll b/llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll
--- a/llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll
+++ b/llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll
@@ -1,7 +1,9 @@
 ; RUN: opt < %s -passes='print<func-properties>' -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -passes='print<func-properties>' -disable-output 2>&1 -enable-detailed-function-properties | FileCheck %s --check-prefix=DETAILED-PROPERTIES
 
 define i32 @main() {
 ; CHECK-DAG: Printing analysis results of CFA for function 'main':
+; DETAILED-PROPERTIES-DAG: Printing analysis results of CFA for function 'main':
 
 entry:
   %retval = alloca i32, align 4
@@ -26,8 +28,32 @@
 ; CHECK-DAG: MaxLoopDepth: 0
 ; CHECK-DAG: TopLevelLoopCount: 0
 
+; DETAILED-PROPERTIES-DAG: BasicBlockCount: 1
+; DETAILED-PROPERTIES-DAG: BlocksReachedFromConditionalInstruction: 0
+; DETAILED-PROPERTIES-DAG: Uses: 1
+; DETAILED-PROPERTIES-DAG: DirectCallsToDefinedFunctions: 1
+; DETAILED-PROPERTIES-DAG: LoadInstCount: 0
+; DETAILED-PROPERTIES-DAG: StoreInstCount: 1
+; DETAILED-PROPERTIES-DAG: MaxLoopDepth: 0
+; DETAILED-PROPERTIES-DAG: TopLevelLoopCount: 0
+; DETAILED-PROPERTIES-DAG: BasicBlocksWithSingleSuccessor: 0
+; DETAILED-PROPERTIES-DAG: BasicBlocksWithTwoSuccessors: 0
+; DETAILED-PROPERTIES-DAG: BasicBlocksWithMoreThanTwoSuccessors: 0
+; DETAILED-PROPERTIES-DAG: BasicBlocksWithSinglePredecessor: 0
+; DETAILED-PROPERTIES-DAG: BasicBlocksWithTwoPredecessors: 0
+; DETAILED-PROPERTIES-DAG: BasicBlocksWithMoreThanTwoPredecessors: 0
+; DETAILED-PROPERTIES-DAG: BigBasicBlocks: 0
+; DETAILED-PROPERTIES-DAG: MediumBasicBlocks: 0
+; DETAILED-PROPERTIES-DAG: SmallBasicBlocks: 1
+; DETAILED-PROPERTIES-DAG: CastInstructionCount: 0
+; DETAILED-PROPERTIES-DAG: FloatingPointInstructionCount: 0
+; DETAILED-PROPERTIES-DAG: IntegerInstructionCount: 0
+; DETAILED-PROPERTIES-DAG: IntegerConstantCount: 14
+; DETAILED-PROPERTIES-DAG: FloatingPointConstantCount: 0
+
 define void @multiply([2 x i32]* %mat1, [2 x i32]* %mat2, [2 x i32]* %res) {
 ; CHECK-DAG: Printing analysis results of CFA for function 'multiply':
+; DETAILED-PROPERTIES-DAG: Printing analysis results of CFA for function 'multiply':
 entry:
   %mat1.addr = alloca [2 x i32]*, align 8
   %mat2.addr = alloca [2 x i32]*, align 8
@@ -137,4 +163,27 @@
 ; CHECK-DAG: LoadInstCount: 21
 ; CHECK-DAG: StoreInstCount: 11
 ; CHECK-DAG: MaxLoopDepth: 3
-; CHECK-DAG: TopLevelLoopCount: 1
\ No newline at end of file
+; CHECK-DAG: TopLevelLoopCount: 1
+
+; DETAILED-PROPERTIES-DAG: BasicBlockCount: 13
+; DETAILED-PROPERTIES-DAG: BlocksReachedFromConditionalInstruction: 6
+; DETAILED-PROPERTIES-DAG: Uses: 2
+; DETAILED-PROPERTIES-DAG: DirectCallsToDefinedFunctions: 0
+; DETAILED-PROPERTIES-DAG: LoadInstCount: 21
+; DETAILED-PROPERTIES-DAG: StoreInstCount: 11
+; DETAILED-PROPERTIES-DAG: MaxLoopDepth: 3
+; DETAILED-PROPERTIES-DAG: TopLevelLoopCount: 1
+; DETAILED-PROPERTIES-DAG: BasicBlocksWithSingleSuccessor: 9
+; DETAILED-PROPERTIES-DAG: BasicBlocksWithTwoSuccessors: 3
+; DETAILED-PROPERTIES-DAG: BasicBlocksWithMoreThanTwoSuccessors: 0
+; DETAILED-PROPERTIES-DAG: BasicBlocksWithSinglePredecessor: 9
+; DETAILED-PROPERTIES-DAG: BasicBlocksWithTwoPredecessors: 3
+; DETAILED-PROPERTIES-DAG: BasicBlocksWithMoreThanTwoPredecessors: 0
+; DETAILED-PROPERTIES-DAG: BigBasicBlocks: 0
+; DETAILED-PROPERTIES-DAG: MediumBasicBlocks: 11
+; DETAILED-PROPERTIES-DAG: SmallBasicBlocks: 2
+; DETAILED-PROPERTIES-DAG: CastInstructionCount: 8
+; DETAILED-PROPERTIES-DAG: FloatingPointInstructionCount: 0
+; DETAILED-PROPERTIES-DAG: IntegerInstructionCount: 33
+; DETAILED-PROPERTIES-DAG: IntegerConstantCount: 20
+; DETAILED-PROPERTIES-DAG: FloatingPointConstantCount: 0
diff --git a/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp b/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp
--- a/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp
+++ b/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp
@@ -24,6 +24,11 @@
 #include <cstring>
 
 using namespace llvm;
+
+extern cl::opt<bool> EnableDetailedFunctionProperties;
+extern cl::opt<bool> BigBasicBlockInstructionThreshold;
+extern cl::opt<bool> MediumBasicBlockInstrutionThreshold;
+
 namespace {
 
 class FunctionPropertiesAnalysisTest : public testing::Test {
@@ -117,6 +122,20 @@
   EXPECT_EQ(BranchesFeatures.StoreInstCount, 0);
   EXPECT_EQ(BranchesFeatures.MaxLoopDepth, 0);
   EXPECT_EQ(BranchesFeatures.TopLevelLoopCount, 0);
+
+  EnableDetailedFunctionProperties.setValue(true);
+  FunctionPropertiesInfo DetailedBranchesFeatures = buildFPI(*BranchesFunction);
+  EXPECT_EQ(DetailedBranchesFeatures.BasicBlocksWithSingleSuccessor, 2);
+  EXPECT_EQ(DetailedBranchesFeatures.BasicBlocksWithTwoSuccessors, 1);
+  EXPECT_EQ(DetailedBranchesFeatures.BasicBlocksWithMoreThanTwoSuccessors, 0);
+  EXPECT_EQ(DetailedBranchesFeatures.BasicBlocksWithSinglePredecessor, 2);
+  EXPECT_EQ(DetailedBranchesFeatures.BasicBlocksWithTwoPredecessors, 1);
+  EXPECT_EQ(DetailedBranchesFeatures.BasicBlocksWithMoreThanTwoPredecessors, 0);
+  EXPECT_EQ(DetailedBranchesFeatures.CastInstructionCount, 0);
+  EXPECT_EQ(DetailedBranchesFeatures.FloatingPointInstructionCount, 0);
+  EXPECT_EQ(DetailedBranchesFeatures.IntegerInstructionCount, 4);
+  EXPECT_EQ(DetailedBranchesFeatures.IntegerConstantCount, 1);
+  EXPECT_EQ(DetailedBranchesFeatures.FloatingPointConstantCount, 0);
 }
 
 TEST_F(FunctionPropertiesAnalysisTest, InlineSameBBSimple) {