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 @@ -112,6 +112,14 @@ // The number of floating point constant operands inside the function. int64_t FloatingPointConstantCount = 0; + + // Operand type couns + int64_t ConstantOperandCount = 0; + int64_t InstructionOperandCount = 0; + int64_t BasicBlockOperandCount = 0; + int64_t GlobalValueOperandCount = 0; + int64_t InlineASMOperandCount = 0; + int64_t ArgumentOperandCount = 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 @@ -113,12 +113,25 @@ 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; else if (C->getType()->isFloatTy()) FloatingPointConstantCount += 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; } } } @@ -192,7 +205,13 @@ << "\n" << "IntegerInstructionCount: " << IntegerInstructionCount << "\n" << "IntegerConstantCount: " << IntegerConstantCount << "\n" - << "FloatingPointConstantCount: " << FloatingPointConstantCount << "\n"; + << "FloatingPointConstantCount: " << FloatingPointConstantCount << "\n" + << "ConstantOperandCount: " << ConstantOperandCount << "\n" + << "InstructionOperandCount: " << InstructionOperandCount << "\n" + << "BasicBlockOperandCount: " << BasicBlockOperandCount << "\n" + << "GlobalValueOperandCount: " << GlobalValueOperandCount << "\n" + << "InlineASMOperandCount: " << InlineASMOperandCount << "\n" + << "ArgumentOperandCount: " << ArgumentOperandCount << "\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