Skip to content

Commit a21e77b

Browse files
authored
Merge pull request #25404 from atrick/fix-simplifycfg-hang
SimplifyCFG: fix a compile time bug from exponential jump threading.
2 parents 051d08b + 75ff621 commit a21e77b

File tree

2 files changed

+1102
-12
lines changed

2 files changed

+1102
-12
lines changed

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ namespace {
7272
llvm::SmallDenseMap<SILBasicBlock*, unsigned, 32> WorklistMap;
7373
// Keep track of loop headers - we don't want to jump-thread through them.
7474
SmallPtrSet<SILBasicBlock *, 32> LoopHeaders;
75-
// The number of times jump threading was done through a block.
76-
// Used to prevent infinite jump threading loops.
77-
llvm::SmallDenseMap<SILBasicBlock*, unsigned, 8> JumpThreadedBlocks;
75+
// The cost (~ number of copied instructions) of jump threading per basic
76+
// block. Used to prevent infinite jump threading loops.
77+
llvm::SmallDenseMap<SILBasicBlock *, int, 8> JumpThreadingCost;
7878

7979
// Dominance and post-dominance info for the current function
8080
DominanceInfo *DT = nullptr;
@@ -1014,15 +1014,19 @@ bool SimplifyCFG::tryJumpThreading(BranchInst *BI) {
10141014
}
10151015
}
10161016

1017+
ThreadingBudget -= JumpThreadingCost[SrcBB];
1018+
ThreadingBudget -= JumpThreadingCost[DestBB];
1019+
10171020
// If we don't have anything that we can simplify, don't do it.
1018-
if (ThreadingBudget == 0)
1021+
if (ThreadingBudget <= 0)
10191022
return false;
10201023

10211024
// If it looks potentially interesting, decide whether we *can* do the
10221025
// operation and whether the block is small enough to be worth duplicating.
1026+
int copyCosts = 0;
10231027
for (auto &Inst : *DestBB) {
1024-
ThreadingBudget -= getThreadingCost(&Inst);
1025-
if (ThreadingBudget <= 0)
1028+
copyCosts += getThreadingCost(&Inst);
1029+
if (ThreadingBudget <= copyCosts)
10261030
return false;
10271031

10281032
// We need to update ssa if a value is used outside the duplicated block.
@@ -1044,15 +1048,11 @@ bool SimplifyCFG::tryJumpThreading(BranchInst *BI) {
10441048
return false;
10451049
}
10461050

1047-
// Limit the number we jump-thread through a block.
1048-
// Otherwise we may end up with jump-threading indefinitely.
1049-
unsigned &NumThreaded = JumpThreadedBlocks[DestBB];
1050-
if (++NumThreaded > 16)
1051-
return false;
1052-
10531051
LLVM_DEBUG(llvm::dbgs() << "jump thread from bb" << SrcBB->getDebugID()
10541052
<< " to bb" << DestBB->getDebugID() << '\n');
10551053

1054+
JumpThreadingCost[DestBB] += copyCosts;
1055+
10561056
// Okay, it looks like we want to do this and we can. Duplicate the
10571057
// destination block into this one, rewriting uses of the BBArgs to use the
10581058
// branch arguments as we go.
@@ -1267,6 +1267,12 @@ bool SimplifyCFG::simplifyBranchBlock(BranchInst *BI) {
12671267
if (LoopHeaders.count(DestBB))
12681268
LoopHeaders.insert(BB);
12691269

1270+
auto Iter = JumpThreadingCost.find(DestBB);
1271+
if (Iter != JumpThreadingCost.end()) {
1272+
int costs = Iter->second;
1273+
JumpThreadingCost[BB] += costs;
1274+
}
1275+
12701276
removeFromWorklist(DestBB);
12711277
DestBB->eraseFromParent();
12721278
++NumBlocksMerged;

0 commit comments

Comments
 (0)