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 ConstantIntegerOperandCount = 0; + int64_t ConstantFloatingPointOperandCount = 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 @@ -17,7 +17,9 @@ #include "llvm/Analysis/LoopInfo.h" #include "llvm/IR/CFG.h" #include "llvm/IR/Dominators.h" +#include "llvm/IR/InlineAsm.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/Metadata.h" #include "llvm/Support/CommandLine.h" #include @@ -113,12 +115,27 @@ for (unsigned int OperandIndex = 0; OperandIndex < I.getNumOperands(); ++OperandIndex) { - if (const Constant *C = - dyn_cast(I.getOperand(OperandIndex))) { + Value *Operand = I.getOperand(OperandIndex); + if (const GlobalValue *GV = dyn_cast(Operand)) { + // Global values are constants, so we need to check first if we have + // a global value before checking if we have a more generic constant. + GlobalValueOperandCount += Direction; + } else if (const Constant *C = dyn_cast(Operand)) { if (C->getType()->isIntegerTy()) - IntegerConstantCount += Direction; + ConstantIntegerOperandCount += Direction; else if (C->getType()->isFloatTy()) - FloatingPointConstantCount += Direction; + ConstantFloatingPointOperandCount += Direction; + ConstantOperandCount += Direction; + } else if (const Instruction *I = dyn_cast(Operand)) { + InstructionOperandCount += Direction; + } else if (const BasicBlock *BB = dyn_cast(Operand)) { + BasicBlockOperandCount += Direction; + } else if (isa(Operand)) { + InlineASMOperandCount += Direction; + } else if (isa(Operand)) { + ArgumentOperandCount += Direction; + } else { + UnknownOperandCount += Direction; } } } @@ -191,8 +208,16 @@ << "FloatingPointInstructionCount: " << FloatingPointInstructionCount << "\n" << "IntegerInstructionCount: " << IntegerInstructionCount << "\n" - << "IntegerConstantCount: " << IntegerConstantCount << "\n" - << "FloatingPointConstantCount: " << FloatingPointConstantCount << "\n"; + << "IntegerConstantCount: " << ConstantIntegerOperandCount << "\n" + << "FloatingPointConstantCount: " << ConstantFloatingPointOperandCount + << "\n" + << "ConstantOperandCount: " << ConstantOperandCount << "\n" + << "InstructionOperandCount: " << InstructionOperandCount << "\n" + << "BasicBlockOperandCount: " << BasicBlockOperandCount << "\n" + << "GlobalValueOperandCount: " << GlobalValueOperandCount << "\n" + << "InlineASMOperandCount: " << InlineASMOperandCount << "\n" + << "ArgumentOperandCount: " << ArgumentOperandCount << "\n" + << "UnknownOperandCount: " << UnknownOperandCount << "\n"; } 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 @@ -50,6 +50,12 @@ ; DETAILED-PROPERTIES-DAG: IntegerInstructionCount: 0 ; DETAILED-PROPERTIES-DAG: IntegerConstantCount: 14 ; DETAILED-PROPERTIES-DAG: FloatingPointConstantCount: 0 +; DETAILED-PROPERTIES-DAG: ConstantOperandCount: 14 +; 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 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': @@ -187,3 +193,10 @@ ; DETAILED-PROPERTIES-DAG: IntegerInstructionCount: 33 ; DETAILED-PROPERTIES-DAG: IntegerConstantCount: 20 ; DETAILED-PROPERTIES-DAG: FloatingPointConstantCount: 0 +; DETAILED-PROPERTIES-DAG: ConstantOperandCount: 20 +; 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 + 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 @@ -139,6 +139,12 @@ EXPECT_EQ(DetailedBranchesFeatures.IntegerInstructionCount, 4); EXPECT_EQ(DetailedBranchesFeatures.IntegerConstantCount, 1); EXPECT_EQ(DetailedBranchesFeatures.FloatingPointConstantCount, 0); + EXPECT_EQ(DetailedBranchesFeatures.ConstantOperandCount, 1); + 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); EnableDetailedFunctionProperties.setValue(false); } @@ -172,6 +178,12 @@ EXPECT_EQ(DetailedF1Properties.IntegerInstructionCount, 0); EXPECT_EQ(DetailedF1Properties.IntegerConstantCount, 3); EXPECT_EQ(DetailedF1Properties.FloatingPointConstantCount, 0); + EXPECT_EQ(DetailedF1Properties.ConstantOperandCount, 3); + 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); EnableDetailedFunctionProperties.setValue(false); } @@ -796,4 +808,45 @@ 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.IntegerConstantCount, 1); + EXPECT_EQ(DetailedF1Properties.FloatingPointConstantCount, 0); + EXPECT_EQ(DetailedF1Properties.ConstantOperandCount, 1); + 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); + EnableDetailedFunctionProperties.setValue(false); +} } // end anonymous namespace