Skip to content

Commit 85884e4

Browse files
committed
SIL: A utility for processing basic blocks in a worklist.
BasicBlockWorklist is basically a combination of a block vector and a block set. It can be used for typical worklist-processing algorithms.
1 parent fe10f98 commit 85884e4

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

include/swift/SIL/BasicBlockBits.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,63 @@ template <unsigned N> class BasicBlockSetVector {
211211
}
212212
};
213213

214+
/// A utility for processing basic blocks in a worklist.
215+
///
216+
/// It is basically a combination of a block vector and a block set. It can be
217+
/// used for typical worklist-processing algorithms.
218+
template <unsigned N> class BasicBlockWorklist {
219+
llvm::SmallVector<SILBasicBlock *, N> worklist;
220+
BasicBlockSet visited;
221+
222+
public:
223+
/// Construct an empty worklist.
224+
BasicBlockWorklist(SILFunction *function) : visited(function) {}
225+
226+
/// Initialize the worklist with \p initialBlock.
227+
BasicBlockWorklist(SILBasicBlock *initialBlock)
228+
: visited(initialBlock->getParent()) {
229+
push(initialBlock);
230+
}
231+
232+
/// Pops the last added element from the worklist or returns null, if the
233+
/// worklist is empty.
234+
SILBasicBlock *pop() {
235+
if (worklist.empty())
236+
return nullptr;
237+
return worklist.pop_back_val();
238+
}
239+
240+
/// Pushes \p block onto the worklist if \p block has never been push before.
241+
bool pushIfNotVisited(SILBasicBlock *block) {
242+
if (visited.insert(block)) {
243+
worklist.push_back(block);
244+
return true;
245+
}
246+
return false;
247+
}
248+
249+
/// Like `pushIfNotVisited`, but requires that \p block has never been on the
250+
/// worklist before.
251+
void push(SILBasicBlock *block) {
252+
assert(!visited.contains(block));
253+
visited.insert(block);
254+
worklist.push_back(block);
255+
}
256+
257+
/// Like `pop`, but marks the returned block as "unvisited". This means, that
258+
/// the block can be pushed onto the worklist again.
259+
SILBasicBlock *popAndForget() {
260+
if (worklist.empty())
261+
return nullptr;
262+
SILBasicBlock *block = worklist.pop_back_val();
263+
visited.erase(block);
264+
return block;
265+
}
266+
267+
/// Returns true if \p block was visited, i.e. has been added to the worklist.
268+
bool isVisited(SILBasicBlock *block) const { return visited.contains(block); }
269+
};
270+
214271
} // namespace swift
215272

216273
#endif

0 commit comments

Comments
 (0)