Skip to content

Commit be6ff5f

Browse files
committed
[InstrProf] Support conditional counter updates for integer counters
In llvm#102542. conditional counter updates were only implemented for boolean counters. This PR implements conditional counter updates for integer counters. When the flag -conditional-counter-update is set, integer counters are now treated like boolean counters - @llvm.instrprof.update now checks whether or not a counter is zero, and if not, writes 1 to it. The motiviation for this mode is that we can bring the benefits of conditional single byte counter updates to languages whose frontends do not support single byte counters (e.g. Rust).
1 parent e0ad34e commit be6ff5f

File tree

2 files changed

+105
-2
lines changed

2 files changed

+105
-2
lines changed

llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,8 +1263,20 @@ void InstrLowerer::lowerIncrement(InstrProfIncrementInst *Inc) {
12631263
MaybeAlign(), AtomicOrdering::Monotonic);
12641264
} else {
12651265
Value *IncStep = Inc->getStep();
1266-
Value *Load = Builder.CreateLoad(IncStep->getType(), Addr, "pgocount");
1267-
auto *Count = Builder.CreateAdd(Load, Inc->getStep());
1266+
auto *CtrTy = IncStep->getType();
1267+
Value *Load = Builder.CreateLoad(CtrTy, Addr, "pgocount");
1268+
Value *Count;
1269+
1270+
if (ConditionalCounterUpdate) {
1271+
Instruction *SplitBefore = Inc->getNextNode();
1272+
Value *Cmp = Builder.CreateIsNull(Load, "pgocount.ifzero");
1273+
Instruction *ThenBranch =
1274+
SplitBlockAndInsertIfThen(Cmp, SplitBefore, false);
1275+
Builder.SetInsertPoint(ThenBranch);
1276+
Count = ConstantInt::get(CtrTy, 1);
1277+
} else {
1278+
Count = Builder.CreateAdd(Load, Inc->getStep());
1279+
}
12681280
auto *Store = Builder.CreateStore(Count, Addr);
12691281
if (isCounterPromotionEnabled())
12701282
PromotionCandidates.emplace_back(cast<Instruction>(Load), Store);

llvm/test/Instrumentation/InstrProfiling/conditional-counter-updates.ll

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ target triple = "x86_64-unknown-linux-gnu"
55
@__profn_foo = private constant [3 x i8] c"foo"
66
@__profn_bar = private constant [3 x i8] c"bar"
77

8+
@__profn_fooint = private constant [6 x i8] c"fooint"
9+
@__profn_barint = private constant [6 x i8] c"barint"
10+
811
; CHECK-LABEL: define void @foo
912
; CHECK-NEXT: %pgocount = load i8, ptr @__profc_foo, align 1
1013
; CHECK-NEXT: %pgocount.ifnonzero = icmp ne i8 %pgocount, 0
@@ -67,3 +70,91 @@ return: ; preds = %if.end, %if.then
6770
%1 = load i32, ptr %retval, align 4
6871
ret i32 %1
6972
}
73+
74+
; CHECK-LABEL: define void @fooint
75+
; CHECK-NEXT: %pgocount = load i64, ptr @__profc_fooint, align 8
76+
; CHECK-NEXT: %pgocount.ifzero = icmp eq i64 %pgocount, 0
77+
; CHECK-NEXT: br i1 %pgocount.ifzero, label %1, label %2
78+
79+
; CHECK-LABEL: 1:
80+
; CHECK-NEXT: store i64 1, ptr @__profc_fooint, align 8
81+
; CHECK-NEXT: br label %2
82+
83+
; CHECK-LABEL: 2:
84+
; CHECK-NEXT: ret void
85+
define void @fooint() {
86+
call void @llvm.instrprof.increment(ptr @__profn_fooint, i64 0, i32 1, i32 0)
87+
ret void
88+
}
89+
90+
; CHECK-LABEL: define i32 @barint
91+
; CHECK-LABEL: entry:
92+
; CHECK-NEXT: %retval = alloca i32, align 4
93+
; CHECK-NEXT: %cond.addr = alloca i32, align 4
94+
; CHECK-NEXT: store i32 %cond, ptr %cond.addr, align 4
95+
; CHECK-NEXT: %pgocount = load i64, ptr @__profc_barint, align 8
96+
; CHECK-NEXT: %pgocount.ifzero = icmp eq i64 %pgocount, 0
97+
; CHECK-NEXT: br i1 %pgocount.ifzero, label %0, label %1
98+
99+
; CHECK-LABEL: 0: ; preds = %entry
100+
; CHECK-NEXT: store i64 1, ptr @__profc_barint, align 8
101+
; CHECK-NEXT: br label %1
102+
103+
; CHECK-LABEL: 1: ; preds = %entry, %0
104+
; CHECK-NEXT: %2 = load i32, ptr %cond.addr, align 4
105+
; CHECK-NEXT: %cmp = icmp slt i32 %2, 0
106+
; CHECK-NEXT: br i1 %cmp, label %if.then, label %if.end
107+
108+
; CHECK-LABEL: if.then: ; preds = %1
109+
; CHECK-NEXT: %pgocount1 = load i64, ptr getelementptr inbounds ([3 x i64], ptr @__profc_barint, i32 0, i32 1), align 8
110+
; CHECK-NEXT: %pgocount.ifzero2 = icmp eq i64 %pgocount1, 0
111+
; CHECK-NEXT: br i1 %pgocount.ifzero2, label %3, label %4
112+
113+
; CHECK-LABEL: 3: ; preds = %if.then
114+
; CHECK-NEXT: store i64 1, ptr getelementptr inbounds ([3 x i64], ptr @__profc_barint, i32 0, i32 1), align 8
115+
; CHECK-NEXT: br label %4
116+
;
117+
; CHECK-LABEL: 4: ; preds = %if.then, %3
118+
; CHECK-NEXT: store i32 -1, ptr %retval, align 4
119+
; CHECK-NEXT: br label %return
120+
;
121+
; CHECK-LABEL: if.end: ; preds = %1
122+
; CHECK-NEXT: %pgocount3 = load i64, ptr getelementptr inbounds ([3 x i64], ptr @__profc_barint, i32 0, i32 2), align 8
123+
; CHECK-NEXT: %pgocount.ifzero4 = icmp eq i64 %pgocount3, 0
124+
; CHECK-NEXT: br i1 %pgocount.ifzero4, label %5, label %6
125+
;
126+
; CHECK-LABEL: 5: ; preds = %if.end
127+
; CHECK-NEXT: store i64 1, ptr getelementptr inbounds ([3 x i64], ptr @__profc_barint, i32 0, i32 2), align 8
128+
; CHECK-NEXT: br label %6
129+
;
130+
; CHECK-LABEL: 6: ; preds = %if.end, %5
131+
; CHECK-NEXT: store i32 0, ptr %retval, align 4
132+
; CHECK-NEXT: br label %return
133+
;
134+
; CHECK-LABEL: return: ; preds = %6, %4
135+
; CHECK-NEXT: %7 = load i32, ptr %retval, align 4
136+
; CHECK-NEXT: ret i32 %7
137+
define i32 @barint(i32 %cond) #0 {
138+
entry:
139+
%retval = alloca i32, align 4
140+
%cond.addr = alloca i32, align 4
141+
store i32 %cond, ptr %cond.addr, align 4
142+
call void @llvm.instrprof.increment(ptr @__profn_barint, i64 0, i32 3, i32 0)
143+
%0 = load i32, ptr %cond.addr, align 4
144+
%cmp = icmp slt i32 %0, 0
145+
br i1 %cmp, label %if.then, label %if.end
146+
147+
if.then: ; preds = %entry
148+
call void @llvm.instrprof.increment(ptr @__profn_barint, i64 0, i32 3, i32 1)
149+
store i32 -1, ptr %retval, align 4
150+
br label %return
151+
152+
if.end: ; preds = %entry
153+
call void @llvm.instrprof.increment(ptr @__profn_barint, i64 0, i32 3, i32 2)
154+
store i32 0, ptr %retval, align 4
155+
br label %return
156+
157+
return: ; preds = %if.end, %if.then
158+
%1 = load i32, ptr %retval, align 4
159+
ret i32 %1
160+
}

0 commit comments

Comments
 (0)