Skip to content

Commit c39b0e2

Browse files
committed
[Reachability] NFC: Allow more initial blocks.
Allow clients to specify any number (an array) of blocks beyond which dataflow won't propagate rather than 1 or 0 (a pointer).
1 parent 043c774 commit c39b0e2

File tree

4 files changed

+48
-29
lines changed

4 files changed

+48
-29
lines changed

include/swift/SILOptimizer/Analysis/Reachability.h

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ class IterativeBackwardReachability final {
243243
BasicBlockSet unknownEndBlocks;
244244

245245
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
247247
/// reachability may extend.
248248
BasicBlockSetVector discoveredBlocks;
249249
/// The sublist of gens which are killed within the blocks where they occur.
@@ -296,15 +296,32 @@ class IterativeBackwardReachability final {
296296
};
297297

298298
/// 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.
301302
///
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,
305307
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+
}
308325

309326
/// Step 1: Prepare to run the global dataflow: discover and summarize the
310327
/// blocks in the relevant region.
@@ -358,9 +375,8 @@ class IterativeBackwardReachability final {
358375

359376
/// The function in which the dataflow will run.
360377
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;
364380

365381
/// Input to the dataflow.
366382
Effects &effects;
@@ -375,9 +391,9 @@ class IterativeBackwardReachability final {
375391
/// Current activity of the dataflow.
376392
Stage stage = Stage::Unstarted;
377393

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;
381397
}
382398

383399
/// Form the meet of the end state of the provided predecessor with the begin
@@ -424,8 +440,8 @@ class IterativeBackwardReachability final {
424440
/// effect of each block for use by the dataflow.
425441
///
426442
/// 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.
429445
template <typename Effects>
430446
void IterativeBackwardReachability<Effects>::initialize() {
431447
assert(stage == Stage::Unstarted);
@@ -454,9 +470,9 @@ void IterativeBackwardReachability<Effects>::initialize() {
454470
// adjacent successors.
455471
continue;
456472
}
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.
460476
continue;
461477
}
462478
for (auto *predecessor : block->getPredecessorBlocks())
@@ -631,9 +647,9 @@ void IterativeBackwardReachability<Effects>::solve() {
631647
template <typename Effects>
632648
void IterativeBackwardReachability<Effects>::propagateIntoPredecessors(
633649
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))
637653
return;
638654
assert(result.getBeginStateForBlock(successor) == State::Unreachable() &&
639655
"propagating unreachability into predecessors of block whose begin is "
@@ -776,7 +792,7 @@ bool IterativeBackwardReachability<Effects>::findBarrier(SILInstruction *from,
776792
}
777793
}
778794
assert(result.getEffectForBlock(block) != Effect::Kill());
779-
if (isEffectiveDefBlock(block)) {
795+
if (stopAtBlock(block)) {
780796
visitor.visitBarrierBlock(block);
781797
return true;
782798
}

lib/SILOptimizer/Transforms/SSADestroyHoisting.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,11 @@ class DeinitBarriers final {
275275
public:
276276
DestroyReachability(DeinitBarriers &result)
277277
: result(result), reachability(result.knownUses.getFunction()),
278-
dataflow(result.knownUses.getFunction(),
279-
result.storageDefInst ? result.storageDefInst->getParent()
280-
: nullptr,
281-
*this, reachability) {}
278+
dataflow(Dataflow::untilInitialBlock(
279+
result.knownUses.getFunction(),
280+
result.storageDefInst ? result.storageDefInst->getParent()
281+
: nullptr,
282+
*this, reachability)) {}
282283

283284
void solve();
284285

lib/SILOptimizer/Utils/LexicalDestroyHoisting.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ class Dataflow final {
141141
Dataflow(Context const &context, Usage const &uses, DeinitBarriers &barriers)
142142
: context(context), uses(uses), barriers(barriers),
143143
result(&context.function),
144-
reachability(&context.function, context.defBlock, *this, result) {}
144+
reachability(Reachability::untilInitialBlock(
145+
&context.function, context.defBlock, *this, result)) {}
145146
Dataflow(Dataflow const &) = delete;
146147
Dataflow &operator=(Dataflow const &) = delete;
147148

lib/SILOptimizer/Utils/ShrinkBorrowScope.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ class Dataflow final {
167167
Dataflow(Context const &context, Usage const &uses, DeinitBarriers &barriers)
168168
: context(context), uses(uses), barriers(barriers),
169169
result(&context.function),
170-
reachability(&context.function, context.defBlock, *this, result) {}
170+
reachability(Reachability::untilInitialBlock(
171+
&context.function, context.defBlock, *this, result)) {}
171172
Dataflow(Dataflow const &) = delete;
172173
Dataflow &operator=(Dataflow const &) = delete;
173174

0 commit comments

Comments
 (0)