[llvm] Enable All Function Properties when Stats are enabled (PR #180658)
IƱaki V Arrechea via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 9 18:00:58 PST 2026
https://github.com/InakiVA updated https://github.com/llvm/llvm-project/pull/180658
>From 6a0b34217635328fac46c5a7848f7d455670622a Mon Sep 17 00:00:00 2001
From: Inaki Arrechea <inakiarrechea at google.com>
Date: Tue, 10 Feb 2026 01:27:26 +0000
Subject: [PATCH] enable all function properties instead of beilg locked behind
flag
---
llvm/include/llvm/IR/FunctionProperties.def | 86 ++++---
.../Analysis/FunctionPropertiesAnalysis.cpp | 219 ++++++++----------
llvm/test/Other/functionpropertiesanalysis.ll | 12 +-
3 files changed, 148 insertions(+), 169 deletions(-)
diff --git a/llvm/include/llvm/IR/FunctionProperties.def b/llvm/include/llvm/IR/FunctionProperties.def
index a212af4859877..f12005d243398 100644
--- a/llvm/include/llvm/IR/FunctionProperties.def
+++ b/llvm/include/llvm/IR/FunctionProperties.def
@@ -24,11 +24,6 @@
#define FUNCTION_PROPERTY(Name, Description)
#endif
-// Detailed Properties (only processed if DETAILED_FUNCTION_PROPERTY is defined)
-#ifndef DETAILED_FUNCTION_PROPERTY
-#define DETAILED_FUNCTION_PROPERTY(Name, Description)
-#endif
-
FUNCTION_PROPERTY(BasicBlockCount, "Number of basic blocks")
FUNCTION_PROPERTY(BlocksReachedFromConditionalInstruction,
"Number of blocks reached from a conditional instruction, or "
@@ -45,61 +40,60 @@ FUNCTION_PROPERTY(TopLevelLoopCount,
"Number of Top Level Loops in the Function")
FUNCTION_PROPERTY(TotalInstructionCount,
"Number of instructions (of all types)")
-DETAILED_FUNCTION_PROPERTY(BasicBlocksWithSingleSuccessor,
+FUNCTION_PROPERTY(BasicBlocksWithSingleSuccessor,
"Basic blocks with one successors")
-DETAILED_FUNCTION_PROPERTY(BasicBlocksWithTwoSuccessors,
+FUNCTION_PROPERTY(BasicBlocksWithTwoSuccessors,
"Basic blocks with two successors")
-DETAILED_FUNCTION_PROPERTY(BasicBlocksWithMoreThanTwoSuccessors,
+FUNCTION_PROPERTY(BasicBlocksWithMoreThanTwoSuccessors,
"Basic blocks with more than two successors")
-DETAILED_FUNCTION_PROPERTY(BasicBlocksWithSinglePredecessor,
+FUNCTION_PROPERTY(BasicBlocksWithSinglePredecessor,
"Basic blocks with one predecessors")
-DETAILED_FUNCTION_PROPERTY(BasicBlocksWithTwoPredecessors,
+FUNCTION_PROPERTY(BasicBlocksWithTwoPredecessors,
"Basic blocks with two predecessors")
-DETAILED_FUNCTION_PROPERTY(BasicBlocksWithMoreThanTwoPredecessors,
+FUNCTION_PROPERTY(BasicBlocksWithMoreThanTwoPredecessors,
"Basic blocks with more than two predecessors")
-DETAILED_FUNCTION_PROPERTY(BigBasicBlocks, "Number of big basic blocks")
-DETAILED_FUNCTION_PROPERTY(MediumBasicBlocks, "Number of medium basic blocks")
-DETAILED_FUNCTION_PROPERTY(SmallBasicBlocks, "Number of small basic blocks")
-DETAILED_FUNCTION_PROPERTY(CastInstructionCount,
+FUNCTION_PROPERTY(BigBasicBlocks, "Number of big basic blocks")
+FUNCTION_PROPERTY(MediumBasicBlocks, "Number of medium basic blocks")
+FUNCTION_PROPERTY(SmallBasicBlocks, "Number of small basic blocks")
+FUNCTION_PROPERTY(CastInstructionCount,
"The number of cast instructions inside the function")
-DETAILED_FUNCTION_PROPERTY(
+FUNCTION_PROPERTY(
FloatingPointInstructionCount,
"The number of floating point instructions inside the function")
-DETAILED_FUNCTION_PROPERTY(IntegerInstructionCount,
+FUNCTION_PROPERTY(IntegerInstructionCount,
"The number of integer instructions inside the function")
-DETAILED_FUNCTION_PROPERTY(ConstantIntOperandCount, "Constant Int Operand Count")
-DETAILED_FUNCTION_PROPERTY(ConstantFPOperandCount, "Constant FP Operand Count")
-DETAILED_FUNCTION_PROPERTY(ConstantOperandCount, "Constant Operand Count")
-DETAILED_FUNCTION_PROPERTY(InstructionOperandCount, "Instruction Operand Count")
-DETAILED_FUNCTION_PROPERTY(BasicBlockOperandCount, "Basic Block Operand Count")
-DETAILED_FUNCTION_PROPERTY(GlobalValueOperandCount, "Global Value Operand Count")
-DETAILED_FUNCTION_PROPERTY(InlineAsmOperandCount, "Inline Asm Operand Count")
-DETAILED_FUNCTION_PROPERTY(ArgumentOperandCount, "Argument Operand Count")
-DETAILED_FUNCTION_PROPERTY(UnknownOperandCount, "Unknown Operand Count")
-DETAILED_FUNCTION_PROPERTY(CriticalEdgeCount, "Critical Edge Count")
-DETAILED_FUNCTION_PROPERTY(ControlFlowEdgeCount, "Number of basic block successors")
-DETAILED_FUNCTION_PROPERTY(UnconditionalBranchCount,
+FUNCTION_PROPERTY(ConstantIntOperandCount, "Constant Int Operand Count")
+FUNCTION_PROPERTY(ConstantFPOperandCount, "Constant FP Operand Count")
+FUNCTION_PROPERTY(ConstantOperandCount, "Constant Operand Count")
+FUNCTION_PROPERTY(InstructionOperandCount, "Instruction Operand Count")
+FUNCTION_PROPERTY(BasicBlockOperandCount, "Basic Block Operand Count")
+FUNCTION_PROPERTY(GlobalValueOperandCount, "Global Value Operand Count")
+FUNCTION_PROPERTY(InlineAsmOperandCount, "Inline Asm Operand Count")
+FUNCTION_PROPERTY(ArgumentOperandCount, "Argument Operand Count")
+FUNCTION_PROPERTY(UnknownOperandCount, "Unknown Operand Count")
+FUNCTION_PROPERTY(CriticalEdgeCount, "Critical Edge Count")
+FUNCTION_PROPERTY(ControlFlowEdgeCount, "Number of basic block successors")
+FUNCTION_PROPERTY(UnconditionalBranchCount,
"Number of unconditional branch instructions")
-DETAILED_FUNCTION_PROPERTY(ConditionalBranchCount,
+FUNCTION_PROPERTY(ConditionalBranchCount,
"Number of conditional branch instructions")
-DETAILED_FUNCTION_PROPERTY(BranchInstructionCount, "Number of branch instructions")
-DETAILED_FUNCTION_PROPERTY(BranchSuccessorCount, "Number of branch successors")
-DETAILED_FUNCTION_PROPERTY(SwitchInstructionCount, "Number of switch instructions")
-DETAILED_FUNCTION_PROPERTY(SwitchSuccessorCount, "Number of switch successors")
-DETAILED_FUNCTION_PROPERTY(IntrinsicCount, "Intrinsic Count")
-DETAILED_FUNCTION_PROPERTY(DirectCallCount, "Direct Call Count")
-DETAILED_FUNCTION_PROPERTY(IndirectCallCount, "Indirect Call Count")
-DETAILED_FUNCTION_PROPERTY(CallReturnsIntegerCount, "Call Returns Integer Count")
-DETAILED_FUNCTION_PROPERTY(CallReturnsFloatCount, "Call Returns Float Count")
-DETAILED_FUNCTION_PROPERTY(CallReturnsPointerCount, "Call Returns Pointer Count")
-DETAILED_FUNCTION_PROPERTY(CallReturnsVectorIntCount, "Call Returns Vector Int Count")
-DETAILED_FUNCTION_PROPERTY(CallReturnsVectorFloatCount,
+FUNCTION_PROPERTY(BranchInstructionCount, "Number of branch instructions")
+FUNCTION_PROPERTY(BranchSuccessorCount, "Number of branch successors")
+FUNCTION_PROPERTY(SwitchInstructionCount, "Number of switch instructions")
+FUNCTION_PROPERTY(SwitchSuccessorCount, "Number of switch successors")
+FUNCTION_PROPERTY(IntrinsicCount, "Intrinsic Count")
+FUNCTION_PROPERTY(DirectCallCount, "Direct Call Count")
+FUNCTION_PROPERTY(IndirectCallCount, "Indirect Call Count")
+FUNCTION_PROPERTY(CallReturnsIntegerCount, "Call Returns Integer Count")
+FUNCTION_PROPERTY(CallReturnsFloatCount, "Call Returns Float Count")
+FUNCTION_PROPERTY(CallReturnsPointerCount, "Call Returns Pointer Count")
+FUNCTION_PROPERTY(CallReturnsVectorIntCount, "Call Returns Vector Int Count")
+FUNCTION_PROPERTY(CallReturnsVectorFloatCount,
"Call Returns Vector Float Count")
-DETAILED_FUNCTION_PROPERTY(CallReturnsVectorPointerCount,
+FUNCTION_PROPERTY(CallReturnsVectorPointerCount,
"Call Returns Vector Pointer Count")
-DETAILED_FUNCTION_PROPERTY(CallWithManyArgumentsCount, "Call With Many Arguments Count")
-DETAILED_FUNCTION_PROPERTY(CallWithPointerArgumentCount,
+FUNCTION_PROPERTY(CallWithManyArgumentsCount, "Call With Many Arguments Count")
+FUNCTION_PROPERTY(CallWithPointerArgumentCount,
"Call With Pointer Argument Count")
#undef FUNCTION_PROPERTY
-#undef DETAILED_FUNCTION_PROPERTY
diff --git a/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp b/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
index 27de3a9357c9f..0e231450c6fe2 100644
--- a/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
+++ b/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
@@ -30,14 +30,9 @@ using namespace llvm;
#define DEBUG_TYPE "func-properties-stats"
#define FUNCTION_PROPERTY(Name, Description) STATISTIC(Num##Name, Description);
-#define DETAILED_FUNCTION_PROPERTY(Name, Description) \
- STATISTIC(Num##Name, Description);
#include "llvm/IR/FunctionProperties.def"
namespace llvm {
-LLVM_ABI cl::opt<bool> EnableDetailedFunctionProperties(
- "enable-detailed-function-properties", cl::Hidden, cl::init(false),
- cl::desc("Whether or not to compute detailed function properties."));
static cl::opt<unsigned> BigBasicBlockInstructionThreshold(
"big-basic-block-instruction-threshold", cl::Hidden, cl::init(500),
@@ -96,100 +91,99 @@ 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;
-
- // Calculate critical edges by looking through all successors of a basic
- // block that has multiple successors and finding ones that have multiple
- // predecessors, which represent critical edges.
- if (SuccessorCount > 1) {
- for (const auto *Successor : successors(&BB)) {
- if (pred_size(Successor) > 1)
- CriticalEdgeCount += Direction;
- }
+ 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;
+
+ // Calculate critical edges by looking through all successors of a basic
+ // block that has multiple successors and finding ones that have multiple
+ // predecessors, which represent critical edges.
+ if (SuccessorCount > 1) {
+ for (const auto *Successor : successors(&BB)) {
+ if (pred_size(Successor) > 1)
+ CriticalEdgeCount += Direction;
}
+ }
- ControlFlowEdgeCount += Direction * SuccessorCount;
+ ControlFlowEdgeCount += Direction * SuccessorCount;
- const Instruction *TI = BB.getTerminator();
- const int64_t InstructionSuccessorCount = TI->getNumSuccessors();
- if (isa<BranchInst>(TI)) {
- BranchInstructionCount += Direction;
- BranchSuccessorCount += Direction * InstructionSuccessorCount;
- const auto *BI = dyn_cast<BranchInst>(TI);
- if (BI->isConditional())
- ConditionalBranchCount += Direction;
- else
- UnconditionalBranchCount += Direction;
- } else if (isa<SwitchInst>(TI)) {
- SwitchInstructionCount += Direction;
- SwitchSuccessorCount += Direction * InstructionSuccessorCount;
- }
+ const Instruction *TI = BB.getTerminator();
+ const int64_t InstructionSuccessorCount = TI->getNumSuccessors();
+ if (isa<BranchInst>(TI)) {
+ BranchInstructionCount += Direction;
+ BranchSuccessorCount += Direction * InstructionSuccessorCount;
+ const auto *BI = dyn_cast<BranchInst>(TI);
+ if (BI->isConditional())
+ ConditionalBranchCount += Direction;
+ else
+ UnconditionalBranchCount += Direction;
+ } else if (isa<SwitchInst>(TI)) {
+ SwitchInstructionCount += Direction;
+ SwitchSuccessorCount += Direction * InstructionSuccessorCount;
+ }
- for (const Instruction &I : BB.instructionsWithoutDebug()) {
- if (I.isCast())
- CastInstructionCount += Direction;
-
- if (I.getType()->isFloatTy())
- FloatingPointInstructionCount += Direction;
- else if (I.getType()->isIntegerTy())
- IntegerInstructionCount += Direction;
-
- if (isa<IntrinsicInst>(I))
- ++IntrinsicCount;
-
- if (const auto *Call = dyn_cast<CallInst>(&I)) {
- if (Call->isIndirectCall())
- IndirectCallCount += Direction;
- else
- DirectCallCount += Direction;
-
- if (Call->getType()->isIntegerTy())
- CallReturnsIntegerCount += Direction;
- else if (Call->getType()->isFloatingPointTy())
- CallReturnsFloatCount += Direction;
- else if (Call->getType()->isPointerTy())
- CallReturnsPointerCount += Direction;
- else if (Call->getType()->isVectorTy()) {
- if (Call->getType()->getScalarType()->isIntegerTy())
- CallReturnsVectorIntCount += Direction;
- else if (Call->getType()->getScalarType()->isFloatingPointTy())
- CallReturnsVectorFloatCount += Direction;
- else if (Call->getType()->getScalarType()->isPointerTy())
- CallReturnsVectorPointerCount += Direction;
- }
+ for (const Instruction &I : BB.instructionsWithoutDebug()) {
+ if (I.isCast())
+ CastInstructionCount += Direction;
- if (Call->arg_size() > CallWithManyArgumentsThreshold)
- CallWithManyArgumentsCount += Direction;
+ if (I.getType()->isFloatTy())
+ FloatingPointInstructionCount += Direction;
+ else if (I.getType()->isIntegerTy())
+ IntegerInstructionCount += Direction;
- for (const auto &Arg : Call->args()) {
- if (Arg->getType()->isPointerTy()) {
- CallWithPointerArgumentCount += Direction;
- break;
- }
+ if (isa<IntrinsicInst>(I))
+ ++IntrinsicCount;
+
+ if (const auto *Call = dyn_cast<CallInst>(&I)) {
+ if (Call->isIndirectCall())
+ IndirectCallCount += Direction;
+ else
+ DirectCallCount += Direction;
+
+ if (Call->getType()->isIntegerTy())
+ CallReturnsIntegerCount += Direction;
+ else if (Call->getType()->isFloatingPointTy())
+ CallReturnsFloatCount += Direction;
+ else if (Call->getType()->isPointerTy())
+ CallReturnsPointerCount += Direction;
+ else if (Call->getType()->isVectorTy()) {
+ if (Call->getType()->getScalarType()->isIntegerTy())
+ CallReturnsVectorIntCount += Direction;
+ else if (Call->getType()->getScalarType()->isFloatingPointTy())
+ CallReturnsVectorFloatCount += Direction;
+ else if (Call->getType()->getScalarType()->isPointerTy())
+ CallReturnsVectorPointerCount += Direction;
+ }
+
+ if (Call->arg_size() > CallWithManyArgumentsThreshold)
+ CallWithManyArgumentsCount += Direction;
+
+ for (const auto &Arg : Call->args()) {
+ if (Arg->getType()->isPointerTy()) {
+ CallWithPointerArgumentCount += Direction;
+ break;
}
}
+ }
#define COUNT_OPERAND(OPTYPE) \
if (isa<OPTYPE>(Operand)) { \
@@ -197,25 +191,24 @@ void FunctionPropertiesInfo::updateForBB(const BasicBlock &BB,
continue; \
}
- for (unsigned int OperandIndex = 0; OperandIndex < I.getNumOperands();
- ++OperandIndex) {
- 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;
- }
+ for (unsigned int OperandIndex = 0; OperandIndex < I.getNumOperands();
+ ++OperandIndex) {
+ 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
- }
}
if (IR2VecVocab) {
@@ -345,15 +338,9 @@ bool FunctionPropertiesInfo::operator==(
void FunctionPropertiesInfo::print(raw_ostream &OS) const {
#define FUNCTION_PROPERTY(Name, Description) OS << #Name ": " << Name << "\n";
-#define DETAILED_FUNCTION_PROPERTY(Name, Description) \
- if (EnableDetailedFunctionProperties) { \
- OS << #Name ": " << Name << "\n"; \
- }
-
#include "llvm/IR/FunctionProperties.def"
#undef FUNCTION_PROPERTY
-#undef DETAILED_FUNCTION_PROPERTY
OS << "\n";
}
@@ -382,8 +369,6 @@ FunctionPropertiesStatisticsPass::run(Function &F,
auto &AnalysisResults = FAM.getResult<FunctionPropertiesAnalysis>(F);
#define FUNCTION_PROPERTY(Name, Description) Num##Name += AnalysisResults.Name;
-#define DETAILED_FUNCTION_PROPERTY(Name, Description) \
- Num##Name += AnalysisResults.Name;
#include "llvm/IR/FunctionProperties.def"
return PreservedAnalyses::all();
@@ -586,4 +571,4 @@ bool FunctionPropertiesUpdater::isUpdateValid(Function &F,
auto Fresh =
FunctionPropertiesInfo::getFunctionPropertiesInfo(F, DT, LI, Vocabulary);
return FPI == Fresh;
-}
+}
\ No newline at end of file
diff --git a/llvm/test/Other/functionpropertiesanalysis.ll b/llvm/test/Other/functionpropertiesanalysis.ll
index 06da908d63974..0f84a933b3a05 100644
--- a/llvm/test/Other/functionpropertiesanalysis.ll
+++ b/llvm/test/Other/functionpropertiesanalysis.ll
@@ -1,11 +1,11 @@
; Testing with all of the below run lines that the pass gets added to the appropriate pipelines
; REQUIRES: asserts
-; RUN: opt -stats -enable-detailed-function-properties -disable-output -passes=func-properties-stats < %s 2>&1 | FileCheck %s
-; RUN: opt -stats -enable-detailed-function-properties -disable-output -passes='thinlto<O3>'< %s 2>&1 | FileCheck %s
-; RUN: opt -stats -enable-detailed-function-properties -disable-output -passes='thinlto-pre-link<O2>' < %s 2>&1 | FileCheck %s
-; RUN: opt -stats -enable-detailed-function-properties -disable-output -passes='lto<O1>' < %s 2>&1 | FileCheck %s
-; RUN: opt -stats -enable-detailed-function-properties -disable-output -O3 < %s 2>&1 | FileCheck %s
-; RUN: opt -stats -enable-detailed-function-properties -disable-output -O0 < %s 2>&1 | FileCheck %s
+; RUN: opt -stats -disable-output -passes=func-properties-stats < %s 2>&1 | FileCheck %s
+; RUN: opt -stats -disable-output -passes='thinlto<O3>'< %s 2>&1 | FileCheck %s
+; RUN: opt -stats -disable-output -passes='thinlto-pre-link<O2>' < %s 2>&1 | FileCheck %s
+; RUN: opt -stats -disable-output -passes='lto<O1>' < %s 2>&1 | FileCheck %s
+; RUN: opt -stats -disable-output -O3 < %s 2>&1 | FileCheck %s
+; RUN: opt -stats -disable-output -O0 < %s 2>&1 | FileCheck %s
; CHECK-DAG: 10 func-properties-stats - Number of basic blocks
; CHECK-DAG: 8 func-properties-stats - Number of branch instructions
More information about the llvm-commits
mailing list