[llvm] fe6bb84 - [FunctionPropertiesAnalysis] Add detailed analysis

Aiden Grossman via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 8 18:07:36 PDT 2023


Author: Aiden Grossman
Date: 2023-08-08T18:03:16-07:00
New Revision: fe6bb84c7ec815fab279cc20b10cbe3a3d3ab553

URL: https://github.com/llvm/llvm-project/commit/fe6bb84c7ec815fab279cc20b10cbe3a3d3ab553
DIFF: https://github.com/llvm/llvm-project/commit/fe6bb84c7ec815fab279cc20b10cbe3a3d3ab553.diff

LOG: [FunctionPropertiesAnalysis] Add detailed analysis

This patch adds more detailed function properties gated behind a command
line flag for use primarily in experimentation and gathering statistics
on the functions in a module or project. The runtime cost should be
minimal as the computation is only done when the flag is set. There will
be a slight memory overhead when the ML inliner is enabled, but it
should be fairly small at a handful of bytes per function.

This is an adapted form of https://reviews.llvm.org/D109661.

Reviewed By: mtrofin

Differential Revision: https://reviews.llvm.org/D157358

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h
    llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
    llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll
    llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h b/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h
index 85d98a05bbd7c1..3dc0656f93be4d 100644
--- a/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h
+++ b/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h
@@ -81,6 +81,37 @@ class FunctionPropertiesInfo {
 
   // 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
index 6094f22a17fd3d..e505dd924cc40f 100644
--- 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 @@ void FunctionPropertiesInfo::updateForBB(const BasicBlock &BB,
     }
   }
   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 = pred_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.instructionsWithoutDebug()) {
+      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 += Direction;
+          else if (C->getType()->isFloatTy())
+            FloatingPointConstantCount += Direction;
+        }
+      }
+    }
+  }
 }
 
 void FunctionPropertiesInfo::updateAggregateStats(const Function &F,
@@ -109,7 +170,31 @@ void FunctionPropertiesInfo::print(raw_ostream &OS) const {
      << "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 @@ bool FunctionPropertiesUpdater::isUpdateValid(Function &F,
   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
index 506914972a1042..c67b84cbb9519f 100644
--- 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 @@ entry:
 ; 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 @@ for.end26:                                        ; preds = %for.cond
 ; 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
index 181066acd1fabc..571e541704f7d1 100644
--- 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,57 @@ define internal i32 @top() {
   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.BigBasicBlocks, 0);
+  EXPECT_EQ(DetailedBranchesFeatures.MediumBasicBlocks, 0);
+  EXPECT_EQ(DetailedBranchesFeatures.SmallBasicBlocks, 4);
+  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);
+  EnableDetailedFunctionProperties.setValue(false);
+}
+
+TEST_F(FunctionPropertiesAnalysisTest, DifferentPredecessorSuccessorCounts) {
+  LLVMContext C;
+  std::unique_ptr<Module> M = makeLLVMModule(C,
+                                             R"IR(
+define i64 @f1() {
+  br i1 0, label %br1, label %finally
+br1:
+  ret i64 0
+finally:
+  ret i64 3
+}
+)IR");
+
+  Function *F1 = M->getFunction("f1");
+  EnableDetailedFunctionProperties.setValue(true);
+  FunctionPropertiesInfo DetailedF1Properties = buildFPI(*F1);
+  EXPECT_EQ(DetailedF1Properties.BasicBlocksWithSingleSuccessor, 0);
+  EXPECT_EQ(DetailedF1Properties.BasicBlocksWithTwoSuccessors, 1);
+  EXPECT_EQ(DetailedF1Properties.BasicBlocksWithMoreThanTwoSuccessors, 0);
+  EXPECT_EQ(DetailedF1Properties.BasicBlocksWithSinglePredecessor, 2);
+  EXPECT_EQ(DetailedF1Properties.BasicBlocksWithTwoPredecessors, 0);
+  EXPECT_EQ(DetailedF1Properties.BasicBlocksWithMoreThanTwoPredecessors, 0);
+  EXPECT_EQ(DetailedF1Properties.BigBasicBlocks, 0);
+  EXPECT_EQ(DetailedF1Properties.MediumBasicBlocks, 0);
+  EXPECT_EQ(DetailedF1Properties.SmallBasicBlocks, 3);
+  EXPECT_EQ(DetailedF1Properties.CastInstructionCount, 0);
+  EXPECT_EQ(DetailedF1Properties.FloatingPointInstructionCount, 0);
+  EXPECT_EQ(DetailedF1Properties.IntegerInstructionCount, 0);
+  EXPECT_EQ(DetailedF1Properties.IntegerConstantCount, 3);
+  EXPECT_EQ(DetailedF1Properties.FloatingPointConstantCount, 0);
+  EnableDetailedFunctionProperties.setValue(false);
 }
 
 TEST_F(FunctionPropertiesAnalysisTest, InlineSameBBSimple) {


        


More information about the llvm-commits mailing list