@@ -416,6 +416,17 @@ void JointPostDominanceSetComputer::findJointPostDominatingSet(
416
416
// always clean up any resources that we use!
417
417
SWIFT_DEFER { clear (); };
418
418
419
+ // / A set that guards our worklist. Any block before it is added to worklist
420
+ // / should be checked against visitedBlocks.
421
+ SILFunction *function = dominatingBlock->getParent ();
422
+ BasicBlockSet visitedBlocks (function);
423
+
424
+ // / The set of blocks where we begin our walk.
425
+ BasicBlockSet initialBlocks (function);
426
+
427
+ // / True for blocks which are in blocksThatLeakIfNeverVisited.
428
+ BasicBlockFlag isLeakingBlock (function);
429
+
419
430
// Otherwise, we need to compute our joint post dominating set. We do this by
420
431
// performing a backwards walk up the CFG tracking back liveness until we find
421
432
// our dominating block. As we walk up, we keep track of any successor blocks
@@ -429,7 +440,7 @@ void JointPostDominanceSetComputer::findJointPostDominatingSet(
429
440
430
441
// We require dominatedBlockSet to be a set and thus assert if we hit it to
431
442
// flag user error to our caller.
432
- bool succeededInserting = visitedBlocks.insert (block). second ;
443
+ bool succeededInserting = visitedBlocks.insert (block);
433
444
(void )succeededInserting;
434
445
assert (succeededInserting &&
435
446
" Repeat Elt: dominatedBlockSet should be a set?!" );
@@ -441,19 +452,16 @@ void JointPostDominanceSetComputer::findJointPostDominatingSet(
441
452
while (!worklist.empty ()) {
442
453
auto *block = worklist.pop_back_val ();
443
454
444
- // First remove block from blocksThatLeakIfNeverVisited if it is there since
445
- // we know that it isn't leaking since we are visiting it now.
446
- blocksThatLeakIfNeverVisited.remove (block);
447
-
448
455
// Then if our block is not one of our initial blocks, add the block's
449
456
// successors to blocksThatLeakIfNeverVisited.
450
- if (!initialBlocks.count (block)) {
457
+ if (!initialBlocks.contains (block)) {
451
458
for (auto *succBlock : block->getSuccessorBlocks ()) {
452
- if (visitedBlocks.count (succBlock))
459
+ if (visitedBlocks.contains (succBlock))
453
460
continue ;
454
461
if (deadEndBlocks.isDeadEnd (succBlock))
455
462
continue ;
456
- blocksThatLeakIfNeverVisited.insert (succBlock);
463
+ blocksThatLeakIfNeverVisited.push_back (succBlock);
464
+ isLeakingBlock.set (succBlock);
457
465
}
458
466
}
459
467
@@ -465,25 +473,28 @@ void JointPostDominanceSetComputer::findJointPostDominatingSet(
465
473
// our initial blocks (signaling a loop) and then add it to the worklist if
466
474
// we haven't visited it already.
467
475
for (auto *predBlock : block->getPredecessorBlocks ()) {
468
- if (initialBlocks.count (predBlock)) {
476
+ if (initialBlocks.contains (predBlock)) {
469
477
reachableInputBlocks.push_back (predBlock);
470
478
for (auto *succBlock : predBlock->getSuccessorBlocks ()) {
471
- if (visitedBlocks.count (succBlock))
479
+ if (visitedBlocks.contains (succBlock))
472
480
continue ;
473
481
if (deadEndBlocks.isDeadEnd (succBlock))
474
482
continue ;
475
- blocksThatLeakIfNeverVisited.insert (succBlock);
483
+ if (!isLeakingBlock.testAndSet (succBlock))
484
+ blocksThatLeakIfNeverVisited.push_back (succBlock);
476
485
}
477
486
}
478
- if (visitedBlocks.insert (predBlock). second )
487
+ if (visitedBlocks.insert (predBlock))
479
488
worklist.push_back (predBlock);
480
489
}
481
490
}
482
491
483
- // After our worklist has emptied, any blocks left in
492
+ // After our worklist has emptied, any not visited blocks in
484
493
// blocksThatLeakIfNeverVisited are "leaking blocks".
485
- for (auto *leakingBlock : blocksThatLeakIfNeverVisited)
486
- foundJointPostDomSetCompletionBlocks (leakingBlock);
494
+ for (auto *leakingBlock : blocksThatLeakIfNeverVisited) {
495
+ if (!visitedBlocks.contains (leakingBlock))
496
+ foundJointPostDomSetCompletionBlocks (leakingBlock);
497
+ }
487
498
488
499
// Then unique our list of reachable input blocks and pass them to our
489
500
// callback.
0 commit comments