Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 32 additions & 11 deletions llvm/lib/Transforms/Utils/SimplifyCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4895,9 +4895,8 @@ bool SimplifyCFGOpt::simplifyTerminatorOnSelect(Instruction *OldTerm,
// We found both of the successors we were looking for.
// Create a conditional branch sharing the condition of the select.
BranchInst *NewBI = Builder.CreateCondBr(Cond, TrueBB, FalseBB);
if (TrueWeight != FalseWeight)
setBranchWeights(*NewBI, {TrueWeight, FalseWeight},
/*IsExpected=*/false, /*ElideAllZero=*/true);
setBranchWeights(*NewBI, {TrueWeight, FalseWeight},
/*IsExpected=*/false, /*ElideAllZero=*/true);
}
} else if (KeepEdge1 && (KeepEdge2 || TrueBB == FalseBB)) {
// Neither of the selected blocks were successors, so this
Expand Down Expand Up @@ -4982,9 +4981,15 @@ bool SimplifyCFGOpt::simplifyIndirectBrOnSelect(IndirectBrInst *IBI,
BasicBlock *TrueBB = TBA->getBasicBlock();
BasicBlock *FalseBB = FBA->getBasicBlock();

// The select's profile becomes the profile of the conditional branch that
// replaces the indirect branch.
SmallVector<uint32_t> SelectBranchWeights(2);
if (!ProfcheckDisableMetadataFixes)
extractBranchWeights(*SI, SelectBranchWeights);
// Perform the actual simplification.
return simplifyTerminatorOnSelect(IBI, SI->getCondition(), TrueBB, FalseBB, 0,
0);
return simplifyTerminatorOnSelect(IBI, SI->getCondition(), TrueBB, FalseBB,
SelectBranchWeights[0],
SelectBranchWeights[1]);
}

/// This is called when we find an icmp instruction
Expand Down Expand Up @@ -7877,19 +7882,30 @@ bool SimplifyCFGOpt::simplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
bool SimplifyCFGOpt::simplifyIndirectBr(IndirectBrInst *IBI) {
BasicBlock *BB = IBI->getParent();
bool Changed = false;
SmallVector<uint32_t> BranchWeights;
const bool HasBranchWeights = !ProfcheckDisableMetadataFixes &&
extractBranchWeights(*IBI, BranchWeights);

DenseMap<const BasicBlock *, uint64_t> TargetWeight;
if (HasBranchWeights)
for (size_t I = 0, E = IBI->getNumDestinations(); I < E; ++I) {
auto [It, Inserted] =
TargetWeight.insert({IBI->getDestination(I), BranchWeights[I]});
if (!Inserted)
It->second += BranchWeights[I];
}
// Eliminate redundant destinations.
SmallPtrSet<Value *, 8> Succs;
SmallSetVector<BasicBlock *, 8> RemovedSuccs;
for (unsigned i = 0, e = IBI->getNumDestinations(); i != e; ++i) {
BasicBlock *Dest = IBI->getDestination(i);
for (unsigned I = 0, E = IBI->getNumDestinations(); I != E; ++I) {
BasicBlock *Dest = IBI->getDestination(I);
if (!Dest->hasAddressTaken() || !Succs.insert(Dest).second) {
if (!Dest->hasAddressTaken())
RemovedSuccs.insert(Dest);
Dest->removePredecessor(BB);
IBI->removeDestination(i);
--i;
--e;
IBI->removeDestination(I);
--I;
--E;
Changed = true;
}
}
Expand All @@ -7915,7 +7931,12 @@ bool SimplifyCFGOpt::simplifyIndirectBr(IndirectBrInst *IBI) {
eraseTerminatorAndDCECond(IBI);
return true;
}

if (HasBranchWeights) {
SmallVector<uint64_t> NewBranchWeights(IBI->getNumDestinations());
for (size_t I = 0, E = IBI->getNumDestinations(); I < E; ++I)
NewBranchWeights[I] += TargetWeight.find(IBI->getDestination(I))->second;
setFittedBranchWeights(*IBI, NewBranchWeights, /*IsExpected=*/false);
}
if (SelectInst *SI = dyn_cast<SelectInst>(IBI->getAddress())) {
if (simplifyIndirectBrOnSelect(IBI, SI))
return requestResimplify();
Expand Down
32 changes: 24 additions & 8 deletions llvm/test/Transforms/SimplifyCFG/indirectbr.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
; RUN: opt -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s

; SimplifyCFG should eliminate redundant indirectbr edges.
Expand All @@ -8,15 +8,19 @@ declare void @A()
declare void @B(i32)
declare void @C()

define void @indbrtest0(ptr %P, ptr %Q) {
;.
; CHECK: @anchor = constant [13 x ptr] [ptr blockaddress(@indbrtest3, %L1), ptr blockaddress(@indbrtest3, %L2), ptr inttoptr (i32 1 to ptr), ptr blockaddress(@indbrtest4, %L1), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr)]
; CHECK: @xblkx.bbs = internal unnamed_addr constant [9 x ptr] [ptr blockaddress(@indbrtest7, %xlab4x), ptr blockaddress(@indbrtest7, %xlab4x), ptr blockaddress(@indbrtest7, %v2j), ptr blockaddress(@indbrtest7, %xlab4x), ptr blockaddress(@indbrtest7, %xlab4x), ptr blockaddress(@indbrtest7, %xlab4x), ptr blockaddress(@indbrtest7, %xlab4x), ptr blockaddress(@indbrtest7, %xlab4x), ptr blockaddress(@indbrtest7, %v2j)]
;.
define void @indbrtest0(ptr %P, ptr %Q) !prof !0 {
; CHECK-LABEL: @indbrtest0(
; CHECK-NEXT: entry:
; CHECK-NEXT: store ptr blockaddress(@indbrtest0, [[BB0:%.*]]), ptr [[P:%.*]], align 8
; CHECK-NEXT: store ptr blockaddress(@indbrtest0, [[BB1:%.*]]), ptr [[P]], align 8
; CHECK-NEXT: store ptr blockaddress(@indbrtest0, [[BB2:%.*]]), ptr [[P]], align 8
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: [[T:%.*]] = load ptr, ptr [[Q:%.*]], align 8
; CHECK-NEXT: indirectbr ptr [[T]], [label [[BB0]], label [[BB1]], label %BB2]
; CHECK-NEXT: indirectbr ptr [[T]], [label [[BB0]], label [[BB1]], label %BB2], !prof [[PROF1:![0-9]+]]
; CHECK: BB0:
; CHECK-NEXT: call void @A()
; CHECK-NEXT: br label [[BB1]]
Expand All @@ -36,7 +40,7 @@ entry:
store ptr blockaddress(@indbrtest0, %BB2), ptr %P
call void @foo()
%t = load ptr, ptr %Q
indirectbr ptr %t, [label %BB0, label %BB1, label %BB2, label %BB0, label %BB1, label %BB2]
indirectbr ptr %t, [label %BB0, label %BB1, label %BB2, label %BB0, label %BB1, label %BB2], !prof !1
BB0:
call void @A()
br label %BB1
Expand Down Expand Up @@ -103,10 +107,10 @@ BB0:
; SimplifyCFG should turn the indirectbr into a conditional branch on the
; condition of the select.

define void @indbrtest3(i1 %cond, ptr %address) nounwind {
define void @indbrtest3(i1 %cond, ptr %address) nounwind !prof !0 {
; CHECK-LABEL: @indbrtest3(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[COND:%.*]], label [[L1:%.*]], label [[L2:%.*]]
; CHECK-NEXT: br i1 [[COND:%.*]], label [[L1:%.*]], label [[L2:%.*]], !prof [[PROF2:![0-9]+]]
; CHECK: common.ret:
; CHECK-NEXT: ret void
; CHECK: L1:
Expand All @@ -117,8 +121,8 @@ define void @indbrtest3(i1 %cond, ptr %address) nounwind {
; CHECK-NEXT: br label [[COMMON_RET]]
;
entry:
%indirect.goto.dest = select i1 %cond, ptr blockaddress(@indbrtest3, %L1), ptr blockaddress(@indbrtest3, %L2)
indirectbr ptr %indirect.goto.dest, [label %L1, label %L2, label %L3]
%indirect.goto.dest = select i1 %cond, ptr blockaddress(@indbrtest3, %L1), ptr blockaddress(@indbrtest3, %L2), !prof !2
indirectbr ptr %indirect.goto.dest, [label %L1, label %L2, label %L3], !prof !3

L1:
call void @A()
Expand Down Expand Up @@ -385,3 +389,15 @@ declare i32 @xfunc5x()
declare i8 @xfunc7x()
declare i32 @xselectorx()
declare i32 @xactionx()

!0 = !{!"function_entry_count", i32 10}
!1 = !{!"branch_weights", i32 3, i32 5, i32 7, i32 11, i32 13, i32 17}
!2 = !{!"branch_weights", i32 3, i32 5}
!3 = !{!"branch_weights", i32 3, i32 5, i32 7}
;.
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind }
;.
; CHECK: [[META0:![0-9]+]] = !{!"function_entry_count", i32 10}
; CHECK: [[PROF1]] = !{!"branch_weights", i32 14, i32 18, i32 24}
; CHECK: [[PROF2]] = !{!"branch_weights", i32 3, i32 5}
;.