Skip to content

Commit aaa7f1e

Browse files
committed
[SimplifyCFG][profcheck] Synthesize profile for `br (X == 0 | X == 1), T, F1 -> switch
1 parent 36dc2a9 commit aaa7f1e

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
@@ -5152,14 +5152,18 @@ bool SimplifyCFGOpt::simplifyBranchOnICmpChain(BranchInst *BI,
51525152
if (ExtraCase && Values.size() < 2)
51535153
return false;
51545154

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

51585159
// Figure out which block is which destination.
51595160
BasicBlock *DefaultBB = BI->getSuccessor(1);
51605161
BasicBlock *EdgeBB = BI->getSuccessor(0);
5161-
if (!TrueWhenEqual)
5162+
if (!TrueWhenEqual) {
51625163
std::swap(DefaultBB, EdgeBB);
5164+
if (HasProfile)
5165+
std::swap(BranchWeights[0], BranchWeights[1]);
5166+
}
51635167

51645168
BasicBlock *BB = BI->getParent();
51655169

@@ -5190,10 +5194,11 @@ bool SimplifyCFGOpt::simplifyBranchOnICmpChain(BranchInst *BI,
51905194
if (!isGuaranteedNotToBeUndefOrPoison(ExtraCase, AC, BI, nullptr))
51915195
ExtraCase = Builder.CreateFreeze(ExtraCase);
51925196

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

51985203
OldTI->eraseFromParent();
51995204

@@ -5220,6 +5225,17 @@ bool SimplifyCFGOpt::simplifyBranchOnICmpChain(BranchInst *BI,
52205225

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

52245240
// Add all of the 'cases' to the switch instruction.
52255241
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)