@@ -243,7 +243,7 @@ class IterativeBackwardReachability final {
243
243
BasicBlockSet unknownEndBlocks;
244
244
245
245
public:
246
- // / The blocks found between the gens and the defBlock into which
246
+ // / The blocks found between the gens and the initialBlocks into which
247
247
// / reachability may extend.
248
248
BasicBlockSetVector discoveredBlocks;
249
249
// / The sublist of gens which are killed within the blocks where they occur.
@@ -296,15 +296,32 @@ class IterativeBackwardReachability final {
296
296
};
297
297
298
298
// / Construct a dataflow for the specified function to run from the gens
299
- // / provided by \p effects to the specified def block. So that the result
300
- // / structure can be owned by the caller, it is taken by reference here.
299
+ // / provided by \p effects to the specified \p initialBlocks. So that the
300
+ // / result structure can be owned by the caller, it is taken by reference
301
+ // / here.
301
302
// /
302
- // / If a nullptr defBlock is specified, the dataflow may run up to the begin
303
- // / of the function.
304
- IterativeBackwardReachability (SILFunction *function, SILBasicBlock *defBlock,
303
+ // / If \p initialBlocks is empty, the dataflow may run up to the begin of the
304
+ // / function.
305
+ IterativeBackwardReachability (SILFunction *function,
306
+ ArrayRef<SILBasicBlock *> initialBlocks,
305
307
Effects &effects, Result &result)
306
- : function(function), defBlock(defBlock), effects(effects),
307
- result(result), dataflowWorklist(function) {}
308
+ : function(function), initialBlocks(function), effects(effects),
309
+ result(result), dataflowWorklist(function) {
310
+ for (auto *block : initialBlocks) {
311
+ this ->initialBlocks .insert (block);
312
+ }
313
+ }
314
+
315
+ // / Convenience constructor to pass a single initial block.
316
+ static IterativeBackwardReachability
317
+ untilInitialBlock (SILFunction *function, SILBasicBlock *initialBlock,
318
+ Effects &effects, Result &result) {
319
+ using InitialBlocks = ArrayRef<SILBasicBlock *>;
320
+ InitialBlocks initialBlocks =
321
+ initialBlock ? InitialBlocks (initialBlock) : InitialBlocks ();
322
+ return IterativeBackwardReachability (function, initialBlocks, effects,
323
+ result);
324
+ }
308
325
309
326
// / Step 1: Prepare to run the global dataflow: discover and summarize the
310
327
// / blocks in the relevant region.
@@ -358,9 +375,8 @@ class IterativeBackwardReachability final {
358
375
359
376
// / The function in which the dataflow will run.
360
377
SILFunction *function;
361
- // / The block containing the def for the value--the dataflow will not
362
- // / propagate beyond this block.
363
- SILBasicBlock *defBlock;
378
+ // / The blocks beyond which the dataflow will not propagate.
379
+ BasicBlockSet initialBlocks;
364
380
365
381
// / Input to the dataflow.
366
382
Effects &effects;
@@ -375,9 +391,9 @@ class IterativeBackwardReachability final {
375
391
// / Current activity of the dataflow.
376
392
Stage stage = Stage::Unstarted;
377
393
378
- // / Whether the def effectively occurs within the specified block.
379
- bool isEffectiveDefBlock (SILBasicBlock *block) {
380
- return defBlock ? block == defBlock : block == &*function->begin ();
394
+ // / Whether dataflow continues beyond this block.
395
+ bool stopAtBlock (SILBasicBlock *block) {
396
+ return initialBlocks. contains ( block) || &*function->begin () == block ;
381
397
}
382
398
383
399
// / Form the meet of the end state of the provided predecessor with the begin
@@ -424,8 +440,8 @@ class IterativeBackwardReachability final {
424
440
// / effect of each block for use by the dataflow.
425
441
// /
426
442
// / Starting from the gens, find all blocks which might be reached up to and
427
- // / including the defBlock . Summarize the effects of these blocks along the
428
- // / way.
443
+ // / including the initialBlocks . Summarize the effects of these blocks along
444
+ // / the way.
429
445
template <typename Effects>
430
446
void IterativeBackwardReachability<Effects>::initialize() {
431
447
assert (stage == Stage::Unstarted);
@@ -454,9 +470,9 @@ void IterativeBackwardReachability<Effects>::initialize() {
454
470
// adjacent successors.
455
471
continue ;
456
472
}
457
- if (isEffectiveDefBlock (block)) {
458
- // If this block is the effective def block, dataflow mustn't propagate
459
- // a reachable state through this block to its predecessors.
473
+ if (stopAtBlock (block)) {
474
+ // If dataflow is to stop at this block, it mustn't propagate a reachable
475
+ // state through this block to its predecessors.
460
476
continue ;
461
477
}
462
478
for (auto *predecessor : block->getPredecessorBlocks ())
@@ -631,9 +647,9 @@ void IterativeBackwardReachability<Effects>::solve() {
631
647
template <typename Effects>
632
648
void IterativeBackwardReachability<Effects>::propagateIntoPredecessors(
633
649
SILBasicBlock *successor) {
634
- // State isn't tracked above the def block . Don't propagate state changes
635
- // into its predecessors.
636
- if (isEffectiveDefBlock (successor))
650
+ // State isn't tracked above the blocks dataflow stops at . Don't propagate
651
+ // state changes into its predecessors.
652
+ if (stopAtBlock (successor))
637
653
return ;
638
654
assert (result.getBeginStateForBlock (successor) == State::Unreachable () &&
639
655
" propagating unreachability into predecessors of block whose begin is "
@@ -776,7 +792,7 @@ bool IterativeBackwardReachability<Effects>::findBarrier(SILInstruction *from,
776
792
}
777
793
}
778
794
assert (result.getEffectForBlock (block) != Effect::Kill ());
779
- if (isEffectiveDefBlock (block)) {
795
+ if (stopAtBlock (block)) {
780
796
visitor.visitBarrierBlock (block);
781
797
return true ;
782
798
}
0 commit comments