[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