[LLVM] Successor count added to InstCount#171670
Conversation
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
|
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-llvm-analysis Author: Iñaki V Arrechea (InakiVA) ChangesCounts the number of Basic Block successors when stats are enabled Full diff: https://github.com/llvm/llvm-project/pull/171670.diff 3 Files Affected:
diff --git a/llvm/lib/Analysis/InstCount.cpp b/llvm/lib/Analysis/InstCount.cpp
index b43c9cd074b9d..f7831c49c34f2 100644
--- a/llvm/lib/Analysis/InstCount.cpp
+++ b/llvm/lib/Analysis/InstCount.cpp
@@ -24,6 +24,7 @@ using namespace llvm;
STATISTIC(TotalInsts, "Number of instructions (of all types)");
STATISTIC(TotalBlocks, "Number of basic blocks");
STATISTIC(TotalFuncs, "Number of non-external functions");
+STATISTIC(TotalBlockSucs, "Number of basic block successors");
#define HANDLE_INST(N, OPCODE, CLASS) \
STATISTIC(Num##OPCODE##Inst, "Number of " #OPCODE " insts");
@@ -35,7 +36,11 @@ class InstCount : public InstVisitor<InstCount> {
friend class InstVisitor<InstCount>;
void visitFunction(Function &F) { ++TotalFuncs; }
- void visitBasicBlock(BasicBlock &BB) { ++TotalBlocks; }
+ void visitBasicBlock(BasicBlock &BB) {
+ Instruction *I = BB.getTerminator();
+ TotalBlockSucs += I->getNumSuccessors();
+ ++TotalBlocks;
+ }
#define HANDLE_INST(N, OPCODE, CLASS) \
void visit##OPCODE(CLASS &) { \
diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index 4de527d9ef85e..edafde9f68279 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -21,6 +21,7 @@
#include "llvm/Analysis/CtxProfAnalysis.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/InlineAdvisor.h"
+#include "llvm/Analysis/InstCount.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/ScopedNoAliasAA.h"
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
@@ -1737,8 +1738,13 @@ PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level,
// Emit annotation remarks.
addAnnotationRemarksPass(MPM);
+ // Count the types of instructions used
+ if (AreStatisticsEnabled())
+ MPM.addPass(createModuleToFunctionPassAdaptor(InstCountPass()));
+
if (isLTOPreLink(Phase))
addRequiredLTOPreLinkPasses(MPM);
+
return MPM;
}
diff --git a/llvm/test/Other/instcount.ll b/llvm/test/Other/instcount.ll
new file mode 100644
index 0000000000000..7c19668857538
--- /dev/null
+++ b/llvm/test/Other/instcount.ll
@@ -0,0 +1,76 @@
+; RUN: opt -stats -passes=instcount < %s 2>&1 | FileCheck %s --check-prefix=UNOPT
+; RUN: opt -stats -O3 < %s 2>&1 | FileCheck %s --check-prefix=OPT
+
+; --- FIRST RUN (UNOPTIMIZED) ---
+; UNOPT-DAG: 8 instcount - Number of Br insts
+; UNOPT-DAG: 6 instcount - Number of Call insts
+; UNOPT-DAG: 2 instcount - Number of ICmp insts
+; UNOPT-DAG: 1 instcount - Number of Ret insts
+; UNOPT-DAG: 1 instcount - Number of Switch insts
+; UNOPT-DAG: 10 instcount - Number of basic blocks
+; UNOPT-DAG: 1 instcount - Number of non-external functions
+; UNOPT-DAG: 18 instcount - Number of instructions (of all types)
+; UNOPT-DAG: 14 instcount - Number of basic block successors
+
+; --- SECOND RUN (OPTIMIZED) ---
+; OPT-DAG: 8 instcount - Number of Br insts
+; OPT-DAG: 6 instcount - Number of Call insts
+; OPT-DAG: 2 instcount - Number of ICmp insts
+; OPT-DAG: 1 instcount - Number of Ret insts
+; OPT-DAG: 1 instcount - Number of Switch insts
+; OPT-DAG: 10 instcount - Number of basic blocks
+; OPT-DAG: 1 instcount - Number of non-external functions
+; OPT-DAG: 18 instcount - Number of instructions (of all types)
+; OPT-DAG: 14 instcount - Number of basic block successors
+
+
+define dso_local void @foo(i32 noundef %i, i32 noundef %j, i32 noundef %n) {
+entry:
+ %cmp = icmp slt i32 %i, %j
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ call void @f()
+ br label %if.end
+
+if.end:
+ switch i32 %i, label %sw.default [
+ i32 1, label %sw.bb
+ i32 2, label %sw.bb1
+ i32 3, label %sw.bb1
+ ]
+
+sw.bb:
+ call void @g()
+ br label %sw.epilog
+
+sw.bb1:
+ call void @h()
+ br label %sw.epilog
+
+sw.default:
+ call void @k()
+ br label %sw.epilog
+
+sw.epilog:
+ %cmp2 = icmp sgt i32 %i, %n
+ br i1 %cmp2, label %if.then3, label %if.else
+
+if.then3:
+ call void @l()
+ br label %if.end4
+
+if.else:
+ call void @m()
+ br label %if.end4
+
+if.end4:
+ ret void
+}
+
+declare void @f()
+declare void @g()
+declare void @h()
+declare void @k()
+declare void @l()
+declare void @m()
|
boomanaiden154
left a comment
There was a problem hiding this comment.
I think it makes more sense to do this within FunctionPropertiesAnalysis.
We already collect some data around successors, so that might cover what you need.
Based on #171658, this change is looking for collecting an additional statistic for LLVM IR structure, beyond instruction count. One the one hand, counting successors doesn't fit in with counting instructions, on the other, adding another analysis pass to the default pipelines (either a new one, or extending FunctionPropertiesAnalysis to expose those counts as statistics) seems like unnecessary overhead. |
b03e923 to
897837e
Compare
FunctionPropertiesAnalysis is already in the default pipeline (it's used by the ML inliner). It also has supported for what we call "detailed" statistics that are gated (under a CLI flag in the printer pass, under a pass option in the analysis if I recall correctly). Requiring the analysis here and exposing them as statistics could make sense. I think we have macros already that would make that easy. If it's just this feature that people want, I'm fine landing this as-is. But if the plan is to add a bunch of similar features, I would probably want something more principled to avoid putting this sort of infrastructure in a bunch of places. |
|
Please make sure that your PR descriptions include not just what you are doing, but why you are doing it. |
f7615f0 to
132e440
Compare
f9cf953 to
c14da93
Compare
| int64_t CriticalEdgeCount = 0; | ||
| int64_t ControlFlowEdgeCount = 0; | ||
| int64_t UnconditionalBranchCount = 0; | ||
| int64_t ConditionalBranchCount = 0; |
There was a problem hiding this comment.
can we use FunctionProperties.def here as well?
Counts the number of Basic Block successors when stats are enabled
We want to track this metric for a project in which we analyze the effects of having LLVM Intermediate Representation (IR) code with a high number of branches. We plan to use these capabilities to learn how enabling memory safety features increases the branchiness in LLVM IR and further how it affects binary compilation time and the resulting binary performance.