Skip to content

Commit 51eaf4a

Browse files
committed
rewrite findNonisolatedBlame to use BasicBlockWorkqueue
also simplifies the logic of the search quite a bit.
1 parent bd753d1 commit 51eaf4a

File tree

1 file changed

+34
-34
lines changed

1 file changed

+34
-34
lines changed

lib/SILOptimizer/Mandatory/FlowIsolation.cpp

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/SIL/BitDataflow.h"
2121
#include "swift/SIL/BasicBlockBits.h"
2222
#include "swift/SIL/DebugUtils.h"
23+
#include "swift/SIL/BasicBlockDatastructures.h"
2324
#include "swift/SILOptimizer/PassManager/Transforms.h"
2425

2526
using namespace swift;
@@ -277,34 +278,13 @@ SILInstruction *AnalysisInfo::findNonisolatedBlame(SILInstruction* startInst) {
277278
SILBasicBlock* firstBlk = startInst->getParent();
278279
assert(firstBlk->getParent() == getFunction());
279280

280-
// workList for breadth-first search to find one of the closest blocks.
281-
std::deque<SILBasicBlock*> workList;
282-
BasicBlockSet visited(getFunction());
283-
284-
// seed the search
285-
workList.push_back(firstBlk);
286-
SILBasicBlock::reverse_iterator cursor = startInst->getReverseIterator();
287-
288-
while (!workList.empty()) {
289-
auto *block = workList.front();
290-
workList.pop_front();
281+
// searches the a block starting at the provided position in reverse
282+
// order of instructions (i.e., from terminator to first instruction).
283+
auto searchBlockForNonisolated =
284+
[&](SILBasicBlock::reverse_iterator cursor) -> SILInstruction * {
285+
SILBasicBlock *block = cursor->getParent();
291286
auto &state = flow[block];
292287

293-
// if this block doesn't have exiting nonisolation, then there's no
294-
// way we'll find nonisolation in a predecessor.
295-
assert(state.exitSet[State::Nonisolated] && "nonisolation is unreachable!");
296-
297-
// If this is the first time we're scanning the start block, then leave
298-
// the cursor alone and do a partial scan. If the block is part of
299-
// a cycle, we want to scan the block entirely on the second visit, so we
300-
// do not count this as a visit.
301-
if (startInst) {
302-
startInst = nullptr; // make sure second visit scans entirely.
303-
} else {
304-
cursor = block->rbegin();
305-
visited.insert(block);
306-
}
307-
308288
// does this block generate non-isolation?
309289
if (state.genSet[State::Nonisolated]) {
310290
auto &data = this->operator[](block);
@@ -321,16 +301,36 @@ SILInstruction *AnalysisInfo::findNonisolatedBlame(SILInstruction* startInst) {
321301
}
322302
}
323303

324-
for (auto *pred : block->getPredecessorBlocks()) {
325-
// skip visited
326-
if (visited.contains(pred))
327-
continue;
304+
return nullptr;
305+
};
306+
307+
// whether we should visit a given predecessor block in the search.
308+
auto shouldVisit = [&](SILBasicBlock *pred) {
309+
// visit blocks that contribute nonisolation to successors.
310+
return flow[pred].exitSet[State::Nonisolated];
311+
};
328312

329-
// skip blocks that do not contribute nonisolation.
330-
if (flow[pred].exitSet[State::Nonisolated] == false)
331-
continue;
313+
// first check if the nonisolated use precedes the start instruction in
314+
// this same block.
315+
if (auto *inst = searchBlockForNonisolated(startInst->getReverseIterator()))
316+
return inst;
332317

333-
workList.push_back(pred);
318+
// Seed a workQueue with the predecessors of this start block to
319+
// begin a breadth-first search to find one of the closest predecessors.
320+
BasicBlockWorkqueue workQueue(firstBlk->getFunction());
321+
for (auto *pred : firstBlk->getPredecessorBlocks())
322+
if (shouldVisit(pred))
323+
workQueue.push(pred);
324+
325+
while (auto *block = workQueue.pop()) {
326+
// do we have a nonisolated use here?
327+
if (auto *inst = searchBlockForNonisolated(block->rbegin()))
328+
return inst;
329+
330+
// otherwise keep looking
331+
for (auto *pred : block->getPredecessorBlocks()) {
332+
if (shouldVisit(pred))
333+
workQueue.pushIfNotVisited(pred);
334334
}
335335
}
336336

0 commit comments

Comments
 (0)