Skip to content

Commit 0029ab3

Browse files
committed
[SimplifyCFG][profcheck] Synthesize profile for `br (X == 0 | X == 1), T, F1 -> switch
1 parent 03cb514 commit 0029ab3

File tree

2 files changed

+43
-14
lines changed

2 files changed

+43
-14
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5148,14 +5148,18 @@ bool SimplifyCFGOpt::simplifyBranchOnICmpChain(BranchInst *BI,
51485148
if (ExtraCase && Values.size() < 2)
51495149
return false;
51505150

5151-
// TODO: Preserve branch weight metadata, similarly to how
5152-
// foldValueComparisonIntoPredecessors preserves it.
5151+
SmallVector<uint32_t> BranchWeights;
5152+
const bool HasProfile = !ProfcheckDisableMetadataFixes &&
5153+
extractBranchWeights(*BI, BranchWeights);
51535154

51545155
// Figure out which block is which destination.
51555156
BasicBlock *DefaultBB = BI->getSuccessor(1);
51565157
BasicBlock *EdgeBB = BI->getSuccessor(0);
5157-
if (!TrueWhenEqual)
5158+
if (!TrueWhenEqual) {
51585159
std::swap(DefaultBB, EdgeBB);
5160+
if (HasProfile)
5161+
std::swap(BranchWeights[0], BranchWeights[1]);
5162+
}
51595163

51605164
BasicBlock *BB = BI->getParent();
51615165

@@ -5186,10 +5190,11 @@ bool SimplifyCFGOpt::simplifyBranchOnICmpChain(BranchInst *BI,
51865190
if (!isGuaranteedNotToBeUndefOrPoison(ExtraCase, AC, BI, nullptr))
51875191
ExtraCase = Builder.CreateFreeze(ExtraCase);
51885192

5189-
if (TrueWhenEqual)
5190-
Builder.CreateCondBr(ExtraCase, EdgeBB, NewBB);
5191-
else
5192-
Builder.CreateCondBr(ExtraCase, NewBB, EdgeBB);
5193+
// We don't have any info about this condition.
5194+
auto *Br = TrueWhenEqual ? Builder.CreateCondBr(ExtraCase, EdgeBB, NewBB)
5195+
: Builder.CreateCondBr(ExtraCase, NewBB, EdgeBB);
5196+
setExplicitlyUnknownBranchWeightsIfProfiled(*Br, *NewBB->getParent(),
5197+
DEBUG_TYPE);
51935198

51945199
OldTI->eraseFromParent();
51955200

@@ -5216,6 +5221,17 @@ bool SimplifyCFGOpt::simplifyBranchOnICmpChain(BranchInst *BI,
52165221

52175222
// Create the new switch instruction now.
52185223
SwitchInst *New = Builder.CreateSwitch(CompVal, DefaultBB, Values.size());
5224+
if (HasProfile) {
5225+
// We know the weight of the default case. We don't know the weight of the
5226+
// other cases, but rather than completely loose profiling info, we split
5227+
// the remaining probability equally over them.
5228+
SmallVector<uint32_t> NewWeights(Values.size() + 1);
5229+
NewWeights[0] = BranchWeights[1]; // this is the default, and we swapped if
5230+
// TrueWhenEqual.
5231+
for (auto &V : drop_begin(NewWeights))
5232+
V = BranchWeights[0] / Values.size();
5233+
setBranchWeights(*New, NewWeights, /*IsExpected=*/false);
5234+
}
52195235

52205236
// Add all of the 'cases' to the switch instruction.
52215237
for (ConstantInt *Val : Values)

llvm/test/Transforms/SimplifyCFG/switch_create.ll

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
22
; RUN: opt -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -switch-range-to-icmp < %s | FileCheck %s
33
; RUN: opt -S -data-layout="p:32:32-p1:16:16" -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -switch-range-to-icmp < %s | FileCheck -check-prefix=CHECK -check-prefix=DL %s
44

55
declare void @foo1()
66

77
declare void @foo2()
88

9-
define void @test1(i32 %V) {
9+
define void @test1(i32 %V) !prof !0 {
1010
; CHECK-LABEL: @test1(
1111
; CHECK-NEXT: switch i32 [[V:%.*]], label [[F:%.*]] [
1212
; CHECK-NEXT: i32 17, label [[T:%.*]]
1313
; CHECK-NEXT: i32 4, label [[T]]
14-
; CHECK-NEXT: ]
14+
; CHECK-NEXT: ], !prof [[PROF1:![0-9]+]]
1515
; CHECK: common.ret:
1616
; CHECK-NEXT: ret void
1717
; CHECK: T:
@@ -24,7 +24,7 @@ define void @test1(i32 %V) {
2424
%C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1]
2525
%C2 = icmp eq i32 %V, 17 ; <i1> [#uses=1]
2626
%CN = or i1 %C1, %C2 ; <i1> [#uses=1]
27-
br i1 %CN, label %T, label %F
27+
br i1 %CN, label %T, label %F, !prof !1
2828
T: ; preds = %0
2929
call void @foo1( )
3030
ret void
@@ -116,12 +116,12 @@ F: ; preds = %0
116116
ret void
117117
}
118118

119-
define void @test2(i32 %V) {
119+
define void @test2(i32 %V) !prof !0 {
120120
; CHECK-LABEL: @test2(
121121
; CHECK-NEXT: switch i32 [[V:%.*]], label [[T:%.*]] [
122122
; CHECK-NEXT: i32 17, label [[F:%.*]]
123123
; CHECK-NEXT: i32 4, label [[F]]
124-
; CHECK-NEXT: ]
124+
; CHECK-NEXT: ], !prof [[PROF2:![0-9]+]]
125125
; CHECK: common.ret:
126126
; CHECK-NEXT: ret void
127127
; CHECK: T:
@@ -134,7 +134,7 @@ define void @test2(i32 %V) {
134134
%C1 = icmp ne i32 %V, 4 ; <i1> [#uses=1]
135135
%C2 = icmp ne i32 %V, 17 ; <i1> [#uses=1]
136136
%CN = and i1 %C1, %C2 ; <i1> [#uses=1]
137-
br i1 %CN, label %T, label %F
137+
br i1 %CN, label %T, label %F, !prof !1
138138
T: ; preds = %0
139139
call void @foo1( )
140140
ret void
@@ -1313,3 +1313,16 @@ if.then:
13131313
if.end:
13141314
ret void
13151315
}
1316+
1317+
!0 = !{!"function_entry_count", i32 100}
1318+
!1 = !{!"branch_weights", i32 6, i32 10}
1319+
;.
1320+
; DL: attributes #[[ATTR0:[0-9]+]] = { noredzone nounwind ssp }
1321+
; DL: attributes #[[ATTR1:[0-9]+]] = { nounwind }
1322+
; DL: attributes #[[ATTR2]] = { noredzone nounwind }
1323+
; DL: attributes #[[ATTR3]] = { noredzone }
1324+
;.
1325+
; DL: [[META0:![0-9]+]] = !{!"function_entry_count", i32 100}
1326+
; DL: [[PROF1]] = !{!"branch_weights", i32 10, i32 3, i32 3}
1327+
; DL: [[PROF2]] = !{!"branch_weights", i32 6, i32 5, i32 5}
1328+
;.

0 commit comments

Comments
 (0)