Skip to content

Commit 1400227

Browse files
committed
[loop-arc] Add a simple Loop visitor that visits loops bottom up in the loop tree.
1 parent a768dc2 commit 1400227

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

include/swift/SILPasses/Utils/LoopUtils.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
namespace swift {
2222

23+
class SILFunction;
2324
class SILBasicBlock;
2425
class SILLoop;
2526
class DominanceInfo;
@@ -34,6 +35,24 @@ bool canonicalizeLoop(SILLoop *L, DominanceInfo *DT, SILLoopInfo *LI);
3435
/// information. We update loop info and dominance info while we do this.
3536
bool canonicalizeAllLoops(DominanceInfo *DT, SILLoopInfo *LI);
3637

38+
/// A visitor that visits loops in a function in a bottom up order. It only
39+
/// performs the visit.
40+
class SILLoopVisitor {
41+
SILFunction *F;
42+
SILLoopInfo *LI;
43+
44+
public:
45+
SILLoopVisitor(SILFunction *Func, SILLoopInfo *LInfo) : F(Func), LI(LInfo) {}
46+
virtual ~SILLoopVisitor() {}
47+
48+
void run();
49+
50+
SILFunction *getFunction() const { return F; }
51+
52+
virtual void runOnLoop(SILLoop *L) = 0;
53+
virtual void runOnFunction(SILFunction *F) = 0;
54+
};
55+
3756
} // end swift namespace
3857

3958
#endif

lib/SILPasses/Utils/LoopUtils.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,34 @@ bool swift::canonicalizeAllLoops(DominanceInfo *DT, SILLoopInfo *LI) {
236236

237237
return MadeChange;
238238
}
239+
240+
//===----------------------------------------------------------------------===//
241+
// Loop Visitor
242+
//===----------------------------------------------------------------------===//
243+
244+
void SILLoopVisitor::run() {
245+
// We visit the loop nest inside out via a depth first, post order using
246+
// this
247+
// worklist.
248+
llvm::SmallVector<std::pair<SILLoop *, bool>, 32> Worklist;
249+
for (auto *L : LI->getTopLevelLoops()) {
250+
Worklist.push_back({L, L->empty()});
251+
}
252+
253+
while (Worklist.size()) {
254+
SILLoop *L;
255+
bool Visited;
256+
std::tie(L, Visited) = Worklist.pop_back_val();
257+
258+
if (!Visited) {
259+
Worklist.push_back({L, true});
260+
for (auto *SubLoop : L->getSubLoops()) {
261+
Worklist.push_back({SubLoop, SubLoop->empty()});
262+
}
263+
continue;
264+
}
265+
runOnLoop(L);
266+
}
267+
268+
runOnFunction(F);
269+
}

0 commit comments

Comments
 (0)