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 @@ -107,11 +107,16 @@ // 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; + // Operand type couns + int64_t ConstantIntOperandCount = 0; + int64_t ConstantFPOperandCount = 0; + int64_t ConstantOperandCount = 0; + int64_t InstructionOperandCount = 0; + int64_t BasicBlockOperandCount = 0; + int64_t GlobalValueOperandCount = 0; + int64_t InlineAsmOperandCount = 0; + int64_t ArgumentOperandCount = 0; + int64_t UnknownOperandCount = 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 @@ -16,6 +16,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/IR/CFG.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Instructions.h" #include "llvm/Support/CommandLine.h" @@ -111,16 +112,30 @@ else if (I.getType()->isIntegerTy()) IntegerInstructionCount += Direction; +#define COUNT_OPERAND(OPTYPE) \ + if (isa(Operand)) { \ + OPTYPE##OperandCount += Direction; \ + continue; \ + } + for (unsigned int OperandIndex = 0; OperandIndex < I.getNumOperands(); ++OperandIndex) { - if (const Constant *C = - dyn_cast(I.getOperand(OperandIndex))) { - if (C->getType()->isIntegerTy()) - IntegerConstantCount += Direction; - else if (C->getType()->isFloatTy()) - FloatingPointConstantCount += Direction; - } + Value *Operand = I.getOperand(OperandIndex); + COUNT_OPERAND(GlobalValue) + COUNT_OPERAND(ConstantInt) + COUNT_OPERAND(ConstantFP) + COUNT_OPERAND(Constant) + COUNT_OPERAND(Instruction) + COUNT_OPERAND(BasicBlock) + COUNT_OPERAND(InlineAsm) + COUNT_OPERAND(Argument) + + // We only get to this point if we haven't matched any of the other + // operand types. + UnknownOperandCount += Direction; } + +#undef CHECK_OPERAND } } } @@ -160,40 +175,44 @@ } void FunctionPropertiesInfo::print(raw_ostream &OS) const { - OS << "BasicBlockCount: " << BasicBlockCount << "\n" - << "BlocksReachedFromConditionalInstruction: " - << BlocksReachedFromConditionalInstruction << "\n" - << "Uses: " << Uses << "\n" - << "DirectCallsToDefinedFunctions: " << DirectCallsToDefinedFunctions - << "\n" - << "LoadInstCount: " << LoadInstCount << "\n" - << "StoreInstCount: " << StoreInstCount << "\n" - << "MaxLoopDepth: " << MaxLoopDepth << "\n" - << "TopLevelLoopCount: " << TopLevelLoopCount << "\n" - << "TotalInstructionCount: " << TotalInstructionCount << "\n"; +#define PRINT_PROPERTY(PROP_NAME) OS << #PROP_NAME ": " << PROP_NAME << "\n"; + + PRINT_PROPERTY(BasicBlockCount) + PRINT_PROPERTY(BlocksReachedFromConditionalInstruction) + PRINT_PROPERTY(Uses) + PRINT_PROPERTY(DirectCallsToDefinedFunctions) + PRINT_PROPERTY(LoadInstCount) + PRINT_PROPERTY(StoreInstCount) + PRINT_PROPERTY(MaxLoopDepth) + PRINT_PROPERTY(TopLevelLoopCount) + PRINT_PROPERTY(TotalInstructionCount) + 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"; + PRINT_PROPERTY(BasicBlocksWithSingleSuccessor) + PRINT_PROPERTY(BasicBlocksWithTwoSuccessors) + PRINT_PROPERTY(BasicBlocksWithMoreThanTwoSuccessors) + PRINT_PROPERTY(BasicBlocksWithSinglePredecessor) + PRINT_PROPERTY(BasicBlocksWithTwoPredecessors) + PRINT_PROPERTY(BasicBlocksWithMoreThanTwoPredecessors) + PRINT_PROPERTY(BigBasicBlocks) + PRINT_PROPERTY(MediumBasicBlocks) + PRINT_PROPERTY(SmallBasicBlocks) + PRINT_PROPERTY(CastInstructionCount) + PRINT_PROPERTY(FloatingPointInstructionCount) + PRINT_PROPERTY(IntegerInstructionCount) + PRINT_PROPERTY(ConstantIntOperandCount) + PRINT_PROPERTY(ConstantFPOperandCount) + PRINT_PROPERTY(ConstantOperandCount) + PRINT_PROPERTY(InstructionOperandCount) + PRINT_PROPERTY(BasicBlockOperandCount) + PRINT_PROPERTY(GlobalValueOperandCount) + PRINT_PROPERTY(InlineAsmOperandCount) + PRINT_PROPERTY(ArgumentOperandCount) + PRINT_PROPERTY(UnknownOperandCount) } + +#undef PRINT_PROPERTY + OS << "\n"; } 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 @@ -48,8 +48,15 @@ ; 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 +; DETAILED-PROPERTIES-DAG: ConstantIntOperandCount: 14 +; DETAILED-PROPERTIES-DAG: ConstantFPOperandCount: 0 +; DETAILED-PROPERTIES-DAG: ConstantOperandCount: 0 +; DETAILED-PROPERTIES-DAG: InstructionOperandCount: 7 +; DETAILED-PROPERTIES-DAG: BasicBlockOperandCount: 0 +; DETAILED-PROPERTIES-DAG: GlobalValueOperandCount: 1 +; DETAILED-PROPERTIES-DAG: InlineAsmOperandCount: 0 +; DETAILED-PROPERTIES-DAG: ArgumentOperandCount: 0 +; DETAILED-PROPERTIES-DAG: UnknownOperandCount: 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': @@ -185,5 +192,13 @@ ; 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 +; DETAILED-PROPERTIES-DAG: ConstantIntOperandCount: 20 +; DETAILED-PROPERTIES-DAG: ConstantFPOperandCount: 0 +; DETAILED-PROPERTIES-DAG: ConstantOperandCount: 0 +; DETAILED-PROPERTIES-DAG: InstructionOperandCount: 73 +; DETAILED-PROPERTIES-DAG: BasicBlockOperandCount: 15 +; DETAILED-PROPERTIES-DAG: GlobalValueOperandCount: 0 +; DETAILED-PROPERTIES-DAG: InlineAsmOperandCount: 0 +; DETAILED-PROPERTIES-DAG: ArgumentOperandCount: 3 +; DETAILED-PROPERTIES-DAG: UnknownOperandCount: 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 @@ -137,8 +137,15 @@ 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); + EXPECT_EQ(DetailedBranchesFeatures.ConstantIntOperandCount, 1); + EXPECT_EQ(DetailedBranchesFeatures.ConstantFPOperandCount, 0); + EXPECT_EQ(DetailedBranchesFeatures.ConstantOperandCount, 0); + EXPECT_EQ(DetailedBranchesFeatures.InstructionOperandCount, 4); + EXPECT_EQ(DetailedBranchesFeatures.BasicBlockOperandCount, 4); + EXPECT_EQ(DetailedBranchesFeatures.GlobalValueOperandCount, 2); + EXPECT_EQ(DetailedBranchesFeatures.InlineAsmOperandCount, 0); + EXPECT_EQ(DetailedBranchesFeatures.ArgumentOperandCount, 3); + EXPECT_EQ(DetailedBranchesFeatures.UnknownOperandCount, 0); EnableDetailedFunctionProperties.setValue(false); } @@ -170,8 +177,15 @@ 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); + EXPECT_EQ(DetailedF1Properties.ConstantIntOperandCount, 3); + EXPECT_EQ(DetailedF1Properties.ConstantFPOperandCount, 0); + EXPECT_EQ(DetailedF1Properties.ConstantOperandCount, 0); + EXPECT_EQ(DetailedF1Properties.InstructionOperandCount, 0); + EXPECT_EQ(DetailedF1Properties.BasicBlockOperandCount, 2); + EXPECT_EQ(DetailedF1Properties.GlobalValueOperandCount, 0); + EXPECT_EQ(DetailedF1Properties.InlineAsmOperandCount, 0); + EXPECT_EQ(DetailedF1Properties.ArgumentOperandCount, 0); + EXPECT_EQ(DetailedF1Properties.UnknownOperandCount, 0); EnableDetailedFunctionProperties.setValue(false); } @@ -796,4 +810,46 @@ EXPECT_TRUE(FPU.finishAndTest(FAM)); EXPECT_EQ(FPI, ExpectedFinal); } + +TEST_F(FunctionPropertiesAnalysisTest, DetailedOperandCount) { + LLVMContext C; + std::unique_ptr M = makeLLVMModule(C, + R"IR( +@a = global i64 1 + +define i64 @f1(i64 %e) { + %b = load i64, i64* @a + %c = add i64 %b, 2 + %d = call i64 asm "mov $1,$0", "=r,r" (i64 %c) + %f = add i64 %d, %e + ret i64 %f +} +)IR"); + + Function *F1 = M->getFunction("f1"); + EnableDetailedFunctionProperties.setValue(true); + FunctionPropertiesInfo DetailedF1Properties = buildFPI(*F1); + EXPECT_EQ(DetailedF1Properties.BasicBlocksWithSingleSuccessor, 0); + EXPECT_EQ(DetailedF1Properties.BasicBlocksWithTwoSuccessors, 0); + EXPECT_EQ(DetailedF1Properties.BasicBlocksWithMoreThanTwoSuccessors, 0); + EXPECT_EQ(DetailedF1Properties.BasicBlocksWithSinglePredecessor, 0); + EXPECT_EQ(DetailedF1Properties.BasicBlocksWithTwoPredecessors, 0); + EXPECT_EQ(DetailedF1Properties.BasicBlocksWithMoreThanTwoPredecessors, 0); + EXPECT_EQ(DetailedF1Properties.BigBasicBlocks, 0); + EXPECT_EQ(DetailedF1Properties.MediumBasicBlocks, 0); + EXPECT_EQ(DetailedF1Properties.SmallBasicBlocks, 1); + EXPECT_EQ(DetailedF1Properties.CastInstructionCount, 0); + EXPECT_EQ(DetailedF1Properties.FloatingPointInstructionCount, 0); + EXPECT_EQ(DetailedF1Properties.IntegerInstructionCount, 4); + EXPECT_EQ(DetailedF1Properties.ConstantIntOperandCount, 1); + EXPECT_EQ(DetailedF1Properties.ConstantFPOperandCount, 0); + EXPECT_EQ(DetailedF1Properties.ConstantOperandCount, 0); + EXPECT_EQ(DetailedF1Properties.InstructionOperandCount, 4); + EXPECT_EQ(DetailedF1Properties.BasicBlockOperandCount, 0); + EXPECT_EQ(DetailedF1Properties.GlobalValueOperandCount, 1); + EXPECT_EQ(DetailedF1Properties.InlineAsmOperandCount, 1); + EXPECT_EQ(DetailedF1Properties.ArgumentOperandCount, 1); + EXPECT_EQ(DetailedF1Properties.UnknownOperandCount, 0); + EnableDetailedFunctionProperties.setValue(false); +} } // end anonymous namespace