Skip to content

Commit f915b0c

Browse files
committed
[InstrProf] Support conditional counter updates
This patch adds support of conditional counter updates in single byte counters mode to reduce the write contention by first checking whether the counter is set before overwriting it.
1 parent 37ec6e5 commit f915b0c

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ cl::opt<bool> AtomicFirstCounter(
132132
"the entry counter)"),
133133
cl::init(false));
134134

135+
cl::opt<bool> ConditionalCounterUpdate(
136+
"conditional-counter-update",
137+
cl::desc("Do conditional counter updates in single byte counters mode)"),
138+
cl::init(false));
139+
135140
// If the option is not specified, the default behavior about whether
136141
// counter promotion is done depends on how instrumentaiton lowering
137142
// pipeline is setup, i.e., the default value of true of this option
@@ -1213,6 +1218,18 @@ Value *InstrLowerer::getBitmapAddress(InstrProfMCDCTVBitmapUpdate *I) {
12131218
void InstrLowerer::lowerCover(InstrProfCoverInst *CoverInstruction) {
12141219
auto *Addr = getCounterAddress(CoverInstruction);
12151220
IRBuilder<> Builder(CoverInstruction);
1221+
if (ConditionalCounterUpdate) {
1222+
Instruction *SplitBefore = CoverInstruction->getNextNode();
1223+
auto &Ctx = CoverInstruction->getParent()->getContext();
1224+
auto *Int8Ty = llvm::Type::getInt8Ty(Ctx);
1225+
Value *Load = Builder.CreateLoad(Int8Ty, Addr, "pgocount");
1226+
Value *Cmp = Builder.CreateICmpNE(Load, ConstantInt::get(Int8Ty, 0),
1227+
"pgocount.ifnonzero");
1228+
Instruction *ThenBranch =
1229+
SplitBlockAndInsertIfThen(Cmp, SplitBefore, false);
1230+
Builder.SetInsertPoint(ThenBranch);
1231+
}
1232+
12161233
// We store zero to represent that this block is covered.
12171234
Builder.CreateStore(Builder.getInt8(0), Addr);
12181235
CoverInstruction->eraseFromParent();
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
; RUN: opt < %s -S -passes=instrprof -conditional-counter-update | FileCheck %s
2+
3+
target triple = "x86_64-unknown-linux-gnu"
4+
5+
@__profn_foo = private constant [3 x i8] c"foo"
6+
@__profn_bar = private constant [3 x i8] c"bar"
7+
8+
; CHECK-LABEL: define void @foo
9+
; CHECK-NEXT: %pgocount = load i8, ptr @__profc_foo, align 1
10+
; CHECK-NEXT: %pgocount.ifnonzero = icmp ne i8 %pgocount, 0
11+
; CHECK-NEXT: br i1 %pgocount.ifnonzero, label %1, label %2
12+
13+
; CHECK-LABEL: 1:
14+
; CHECK-NEXT: store i8 0, ptr @__profc_foo, align 1
15+
; CHECK-NEXT: br label %2
16+
17+
; CHECK-LABEL: 2:
18+
; CHECK-NEXT: ret void
19+
define void @foo() {
20+
call void @llvm.instrprof.cover(ptr @__profn_foo, i64 0, i32 1, i32 0)
21+
ret void
22+
}
23+
24+
; CHECK-LABEL: define i32 @bar
25+
; CHECK-LABEL: entry:
26+
; CHECK-NEXT: %retval = alloca i32, align 4
27+
; CHECK-NEXT: %cond.addr = alloca i32, align 4
28+
; CHECK-NEXT: store i32 %cond, ptr %cond.addr, align 4
29+
; CHECK-NEXT: %pgocount = load i8, ptr @__profc_bar, align 1
30+
; CHECK-NEXT: %pgocount.ifnonzero = icmp ne i8 %pgocount, 0
31+
; CHECK-NEXT: br i1 %pgocount.ifnonzero, label %0, label %1
32+
33+
; CHECK-LABEL: 0: ; preds = %entry
34+
; CHECK-NEXT: store i8 0, ptr @__profc_bar, align 1
35+
; CHECK-NEXT: br label %1
36+
37+
; CHECK-LABEL: 1: ; preds = %entry, %0
38+
; CHECK-NEXT: %2 = load i32, ptr %cond.addr, align 4
39+
; CHECK-NEXT: %cmp = icmp slt i32 %2, 0
40+
; CHECK-NEXT: br i1 %cmp, label %if.then, label %if.end
41+
42+
; CHECK-LABEL: if.then: ; preds = %1
43+
; CHECK-NEXT: %pgocount1 = load i8, ptr getelementptr inbounds ([3 x i8], ptr @__profc_bar, i32 0, i32 1), align 1
44+
; CHECK-NEXT: %pgocount.ifnonzero2 = icmp ne i8 %pgocount1, 0
45+
; CHECK-NEXT: br i1 %pgocount.ifnonzero2, label %3, label %4
46+
define i32 @bar(i32 %cond) #0 {
47+
entry:
48+
%retval = alloca i32, align 4
49+
%cond.addr = alloca i32, align 4
50+
store i32 %cond, ptr %cond.addr, align 4
51+
call void @llvm.instrprof.cover(ptr @__profn_bar, i64 0, i32 3, i32 0)
52+
%0 = load i32, ptr %cond.addr, align 4
53+
%cmp = icmp slt i32 %0, 0
54+
br i1 %cmp, label %if.then, label %if.end
55+
56+
if.then: ; preds = %entry
57+
call void @llvm.instrprof.cover(ptr @__profn_bar, i64 0, i32 3, i32 1)
58+
store i32 -1, ptr %retval, align 4
59+
br label %return
60+
61+
if.end: ; preds = %entry
62+
call void @llvm.instrprof.cover(ptr @__profn_bar, i64 0, i32 3, i32 2)
63+
store i32 0, ptr %retval, align 4
64+
br label %return
65+
66+
return: ; preds = %if.end, %if.then
67+
%1 = load i32, ptr %retval, align 4
68+
ret i32 %1
69+
}

0 commit comments

Comments
 (0)