@@ -217,10 +217,84 @@ class SILCfgTraits : public CfgTraits<SILCfgTraitsBase, SILCfgTraits> {
217
217
template <> struct CfgTraitsFor <swift::SILBasicBlock> {
218
218
using CfgTraits = SILCfgTraits;
219
219
};
220
-
221
220
#endif
222
221
223
222
} // end llvm namespace
224
223
224
+ #include " swift/SIL/BasicBlockDatastructures.h"
225
+
226
+ namespace swift {
227
+ // / Given a region, specified via \p visitor's \p isInRegion member function,
228
+ // / backwards-reachable from \r root, traverse the region backwards, depth-first
229
+ // / and visit its nodes in the associated post-order.
230
+ // /
231
+ // / interface Visitor {
232
+ // / /// Whether the indicated basic block is within the region of the graph
233
+ // / /// that should be traversed.
234
+ // / bool isInRegion(SILBasicBlock *)
235
+ // /
236
+ // / /// Visit each block in post-order.
237
+ // / void visit(SILBasicBlock *)
238
+ // / }
239
+ template <typename Visitor>
240
+ void visitPostOrderBackwards (SILFunction *function, SILBasicBlock *root,
241
+ Visitor visitor) {
242
+ SmallVector<std::pair<SILBasicBlock *, SILBasicBlock::pred_iterator>, 32 >
243
+ stack;
244
+ BasicBlockSet visited (function);
245
+ stack.push_back ({root, root->pred_begin ()});
246
+ while (!stack.empty ()) {
247
+ while (stack.back ().second != stack.back ().first ->pred_end ()) {
248
+ auto predecessor = *stack.back ().second ;
249
+ stack.back ().second ++;
250
+ if (!visitor.isInRegion (predecessor))
251
+ continue ;
252
+ if (visited.insert (predecessor))
253
+ stack.push_back ({predecessor, predecessor->pred_begin ()});
254
+ }
255
+ visitor.visit (stack.back ().first );
256
+ stack.pop_back ();
257
+ }
258
+ }
259
+
260
+ // / Given a region, specified via \p visitor's \p isInRegion member function,
261
+ // / backwards-reachable from \r roots, traverse the region in topological order.
262
+ // / Node M shall be visited before node N if and only if there is an edge from
263
+ // / M to N, except for backedges*.
264
+ // /
265
+ // / * The backedges in question are backedges according to backwards depth-first
266
+ // / searches from roots.
267
+ // /
268
+ // / interface Visitor {
269
+ // / /// Whether the indicated basic block is within the region of the graph
270
+ // / /// that should be traversed.
271
+ // / bool isInRegion(SILBasicBlock *)
272
+ // /
273
+ // / /// Visit each block in topological order.
274
+ // / void visit(SILBasicBlock *)
275
+ // / }
276
+ template <typename Visitor>
277
+ void visitSortedTopologicallyBackwards (SILFunction *function,
278
+ ArrayRef<SILBasicBlock *> roots,
279
+ Visitor &visitor) {
280
+ BasicBlockSet visited (function);
281
+ for (auto *root : roots) {
282
+ struct Inner {
283
+ Visitor &outer;
284
+ BasicBlockSet &visited;
285
+ int offset = 0 ;
286
+ Inner (Visitor &outer, BasicBlockSet &visited)
287
+ : outer(outer), visited(visited) {}
288
+ bool isInRegion (SILBasicBlock *block) {
289
+ return !visited.contains (block) && outer.isInRegion (block);
290
+ }
291
+ void visit (SILBasicBlock *block) { outer.visit (block); }
292
+ };
293
+ Inner inner (visitor, visited);
294
+ visitPostOrderBackwards (function, root, inner);
295
+ }
296
+ }
297
+ } // namespace swift
298
+
225
299
#endif
226
300
0 commit comments