22
22
#include " swift/SIL/SILUndef.h"
23
23
#include " swift/SIL/TerminatorUtils.h"
24
24
#include " swift/SIL/BasicBlockDatastructures.h"
25
+ #include " swift/SILOptimizer/Analysis/DeadEndBlocksAnalysis.h"
25
26
#include " swift/SILOptimizer/Analysis/DominanceAnalysis.h"
26
27
#include " swift/SILOptimizer/Analysis/ProgramTerminationAnalysis.h"
27
28
#include " swift/SILOptimizer/Analysis/SimplifyInstruction.h"
@@ -91,6 +92,12 @@ class SimplifyCFG {
91
92
SILFunction &Fn;
92
93
SILPassManager *PM;
93
94
95
+ // DeadEndBlocks remains conservatively valid across updates that rewrite
96
+ // branches and remove edges. Any transformation that adds a block must call
97
+ // updateForReachableBlock(). Removing a block causes a dangling pointer
98
+ // within DeadEndBlocks, but this pointer can't be accessed by queries.
99
+ DeadEndBlocks *deBlocks = nullptr ;
100
+
94
101
// WorklistList is the actual list that we iterate over (for determinism).
95
102
// Slots may be null, which should be ignored.
96
103
SmallVector<SILBasicBlock *, 32 > WorklistList;
@@ -700,7 +707,7 @@ bool SimplifyCFG::dominatorBasedSimplify(DominanceAnalysis *DA) {
700
707
// Do dominator based simplification of terminator condition. This does not
701
708
// and MUST NOT change the CFG without updating the dominator tree to
702
709
// reflect such change.
703
- if (tryCheckedCastBrJumpThreading (&Fn, DT, BlocksForWorklist,
710
+ if (tryCheckedCastBrJumpThreading (&Fn, DT, deBlocks, BlocksForWorklist,
704
711
EnableOSSARewriteTerminator)) {
705
712
for (auto BB: BlocksForWorklist)
706
713
addToWorklist (BB);
@@ -1204,7 +1211,7 @@ bool SimplifyCFG::simplifyBranchOperands(OperandValueArrayRef Operands) {
1204
1211
// All of our interesting simplifications are on single-value instructions
1205
1212
// for now.
1206
1213
if (auto *I = dyn_cast<SingleValueInstruction>(*O)) {
1207
- simplifyAndReplaceAllSimplifiedUsesAndErase (I, callbacks);
1214
+ simplifyAndReplaceAllSimplifiedUsesAndErase (I, callbacks, deBlocks );
1208
1215
}
1209
1216
}
1210
1217
return callbacks.hadCallbackInvocation ();
@@ -3373,6 +3380,16 @@ bool SimplifyCFG::run() {
3373
3380
// First remove any block not reachable from the entry.
3374
3381
bool Changed = removeUnreachableBlocks (Fn);
3375
3382
3383
+ DeadEndBlocksAnalysis *deBlocksAnalysis =
3384
+ PM->getAnalysis <DeadEndBlocksAnalysis>();
3385
+ if (Changed) {
3386
+ // Eliminate unreachable blocks from deBlocks. This isn't strictly necessary
3387
+ // but avoids excess dangling pointers in deBlocks.
3388
+ deBlocksAnalysis->invalidate (&Fn,
3389
+ SILAnalysis::InvalidationKind::Everything);
3390
+ }
3391
+ deBlocks = deBlocksAnalysis->get (&Fn);
3392
+
3376
3393
// Find the set of loop headers. We don't want to jump-thread through headers.
3377
3394
findLoopHeaders ();
3378
3395
@@ -3391,11 +3408,15 @@ bool SimplifyCFG::run() {
3391
3408
3392
3409
// Do simplifications that require the dominator tree to be accurate.
3393
3410
DominanceAnalysis *DA = PM->getAnalysis <DominanceAnalysis>();
3394
-
3395
3411
if (Changed) {
3396
3412
// Force dominator recomputation since we modified the cfg.
3397
3413
DA->invalidate (&Fn, SILAnalysis::InvalidationKind::Everything);
3414
+ // Eliminate unreachable blocks from deBlocks. This isn't strictly necessary
3415
+ // but avoids excess dangling pointers in deBlocks.
3416
+ deBlocksAnalysis->invalidate (&Fn,
3417
+ SILAnalysis::InvalidationKind::Everything);
3398
3418
}
3419
+ deBlocks = deBlocksAnalysis->get (&Fn);
3399
3420
3400
3421
Changed |= dominatorBasedSimplify (DA);
3401
3422
0 commit comments