Skip to content

Commit 4c66e73

Browse files
committed
Count Instructions Pass
1 parent 4cdeb7d commit 4c66e73

File tree

6 files changed

+199
-0
lines changed

6 files changed

+199
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===- CountInstructions.h --------------------------------------------*- C++
2+
//-*-===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef LLVM_TRANSFORMS_UTILS_COUNTINSTRUCTIONS_H
11+
#define LLVM_TRANSFORMS_UTILS_COUNTINSTRUCTIONS_H
12+
13+
#include "llvm/ADT/StringMap.h"
14+
#include "llvm/IR/PassManager.h"
15+
16+
namespace llvm {
17+
18+
class Function;
19+
20+
struct CountInstructionsPass : PassInfoMixin<CountInstructionsPass> {
21+
PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
22+
23+
private:
24+
StringMap<uint32_t> Counts;
25+
};
26+
27+
} // end namespace llvm
28+
29+
#endif // LLVM_TRANSFORMS_UTILS_COUNTINSTRUCTIONS_H

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@
347347
#include "llvm/Transforms/Utils/BreakCriticalEdges.h"
348348
#include "llvm/Transforms/Utils/CanonicalizeAliases.h"
349349
#include "llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h"
350+
#include "llvm/Transforms/Utils/CountInstructions.h"
350351
#include "llvm/Transforms/Utils/CountVisits.h"
351352
#include "llvm/Transforms/Utils/DXILUpgrade.h"
352353
#include "llvm/Transforms/Utils/Debugify.h"

llvm/lib/Passes/PassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ FUNCTION_PASS("consthoist", ConstantHoistingPass())
418418
FUNCTION_PASS("constraint-elimination", ConstraintEliminationPass())
419419
FUNCTION_PASS("coro-elide", CoroElidePass())
420420
FUNCTION_PASS("correlated-propagation", CorrelatedValuePropagationPass())
421+
FUNCTION_PASS("count-instructions", CountInstructionsPass())
421422
FUNCTION_PASS("count-visits", CountVisitsPass())
422423
FUNCTION_PASS("dce", DCEPass())
423424
FUNCTION_PASS("declare-to-assign", llvm::AssignmentTrackingPass())

llvm/lib/Transforms/Utils/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ add_llvm_component_library(LLVMTransformUtils
1818
CodeMoverUtils.cpp
1919
ControlFlowUtils.cpp
2020
CtorUtils.cpp
21+
CountInstructions.cpp
2122
CountVisits.cpp
2223
Debugify.cpp
2324
DebugSSAUpdater.cpp
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//===- CountInstructions.cpp
2+
//----------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "llvm/Transforms/Utils/CountInstructions.h"
11+
#include "llvm/ADT/Statistic.h"
12+
#include "llvm/IR/BasicBlock.h"
13+
#include "llvm/IR/Function.h"
14+
#include "llvm/IR/Instruction.h"
15+
#include "llvm/IR/Instructions.h"
16+
#include "llvm/IR/PassManager.h"
17+
#include "llvm/Support/Casting.h"
18+
#include <cstdint>
19+
20+
using namespace llvm;
21+
22+
#define DEBUG_TYPE "count-instructions"
23+
24+
STATISTIC(TotalBasicBlocks, "Number of basic blocks");
25+
STATISTIC(TotalInstructions, "Number of total instructions");
26+
STATISTIC(TotalBranchInstructions, "Number of branch instructions");
27+
STATISTIC(TotalSwitchInstructions, "Number of switch instructions");
28+
STATISTIC(TotalSuccessors, "Number of basic block successors");
29+
STATISTIC(TotalBranchSuccessors, "Number of branch successors");
30+
STATISTIC(TotalSwitchSuccessors, "Number of switch successors");
31+
PreservedAnalyses CountInstructionsPass::run(Function &F,
32+
FunctionAnalysisManager &) {
33+
uint32_t CountBasicBlocks = 0;
34+
uint32_t CountInstructions = 0;
35+
uint32_t CountBranchInstructions = 0;
36+
uint32_t CountSwitchInstructions = 0;
37+
uint32_t CountSuccessors = 0;
38+
uint32_t CountBranchSuccessors = 0;
39+
uint32_t CountSwitchSuccessors = 0;
40+
41+
for (BasicBlock &BB : F) {
42+
CountBasicBlocks++;
43+
Instruction *I = BB.getTerminator();
44+
CountSuccessors += I->getNumSuccessors();
45+
if (isa<BranchInst>(I)) {
46+
CountBranchInstructions++;
47+
CountBranchSuccessors += I->getNumSuccessors();
48+
} else if (isa<SwitchInst>(I)) {
49+
CountSwitchInstructions++;
50+
CountSwitchSuccessors += I->getNumSuccessors();
51+
}
52+
CountInstructions += BB.size();
53+
}
54+
TotalInstructions += CountInstructions;
55+
TotalBasicBlocks += CountBasicBlocks;
56+
TotalBranchInstructions += CountBranchInstructions;
57+
TotalSwitchInstructions += CountSwitchInstructions;
58+
TotalSuccessors += CountSuccessors;
59+
TotalBranchSuccessors += CountBranchSuccessors;
60+
TotalSwitchSuccessors += CountSwitchSuccessors;
61+
62+
return PreservedAnalyses::all();
63+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
; REQUIRES: asserts, stats
2+
; RUN: opt -stats -passes=count-instructions < %s
3+
4+
define dso_local noundef i32 @add(i32 noundef %n) {
5+
entry:
6+
%n.addr = alloca i32, align 4
7+
store i32 %n, ptr %n.addr, align 4
8+
%0 = load i32, ptr %n.addr, align 4
9+
%add = add nsw i32 %0, 1
10+
ret i32 %add
11+
}
12+
13+
define dso_local void @f(i32 noundef %i) {
14+
entry:
15+
%i.addr = alloca i32, align 4
16+
%x = alloca i32, align 4
17+
store i32 %i, ptr %i.addr, align 4
18+
store i32 0, ptr %x, align 4
19+
%0 = load i32, ptr %i.addr, align 4
20+
switch i32 %0, label %sw.epilog [
21+
i32 0, label %sw.bb
22+
i32 10, label %sw.bb9
23+
i32 1, label %sw.bb9
24+
i32 2, label %sw.bb10
25+
i32 3, label %sw.bb11
26+
i32 4, label %sw.bb12
27+
]
28+
29+
sw.bb:
30+
%call = call noundef i32 @add(i32 noundef 9)
31+
store i32 %call, ptr %x, align 4
32+
%1 = load i32, ptr %x, align 4
33+
%cmp = icmp eq i32 %1, 0
34+
br i1 %cmp, label %if.then, label %if.end
35+
36+
if.then:
37+
store i32 1, ptr %x, align 4
38+
br label %if.end
39+
40+
if.end:
41+
%2 = load i32, ptr %x, align 4
42+
%call1 = call noundef i32 @add(i32 noundef %2)
43+
store i32 %call1, ptr %x, align 4
44+
%3 = load i32, ptr %x, align 4
45+
%cmp2 = icmp eq i32 %3, 0
46+
br i1 %cmp2, label %if.then3, label %if.else
47+
48+
if.then3:
49+
store i32 1, ptr %x, align 4
50+
br label %if.end8
51+
52+
if.else:
53+
%4 = load i32, ptr %x, align 4
54+
%cmp4 = icmp eq i32 %4, 1
55+
br i1 %cmp4, label %if.then5, label %if.else6
56+
57+
if.then5:
58+
store i32 0, ptr %x, align 4
59+
br label %if.end7
60+
61+
if.else6:
62+
store i32 2, ptr %x, align 4
63+
br label %if.end7
64+
65+
if.end7:
66+
br label %if.end8
67+
68+
if.end8:
69+
br label %sw.epilog
70+
71+
sw.bb9:
72+
call void @h()
73+
br label %sw.epilog
74+
75+
sw.bb10:
76+
call void @h()
77+
br label %sw.epilog
78+
79+
sw.bb11:
80+
call void @j()
81+
br label %sw.bb12
82+
83+
sw.bb12:
84+
call void @k()
85+
br label %if.end15
86+
87+
sw.epilog:
88+
%5 = load i32, ptr %x, align 4
89+
%cmp13 = icmp eq i32 %5, 0
90+
br i1 %cmp13, label %if.then14, label %if.end15
91+
92+
if.then14:
93+
store i32 1, ptr %x, align 4
94+
br label %if.end15
95+
96+
if.end15:
97+
ret void
98+
}
99+
100+
declare void @h() #2
101+
102+
declare void @j() #2
103+
104+
declare void @k() #2

0 commit comments

Comments
 (0)