@@ -211,6 +211,63 @@ template <unsigned N> class BasicBlockSetVector {
211
211
}
212
212
};
213
213
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
+
214
271
} // namespace swift
215
272
216
273
#endif
0 commit comments