File tree 2 files changed +60
-0
lines changed
include/swift/SILOptimizer/Analysis
lib/SILOptimizer/Analysis
2 files changed +60
-0
lines changed Original file line number Diff line number Diff line change 48
48
#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_CLOSURESCOPE_H
49
49
#define SWIFT_SILOPTIMIZER_ANALYSIS_CLOSURESCOPE_H
50
50
51
+ #include " swift/Basic/BlotSetVector.h"
51
52
#include " swift/SIL/SILFunction.h"
52
53
#include " swift/SILOptimizer/Analysis/Analysis.h"
53
54
#include " llvm/ADT/SmallSet.h"
@@ -120,6 +121,8 @@ class ClosureScopeAnalysis : public SILAnalysis {
120
121
return S->getKind () == AnalysisKind::ClosureScope;
121
122
}
122
123
124
+ SILModule *getModule () const { return M; }
125
+
123
126
// Return true if the given function is the parent scope for any closures.
124
127
bool isClosureScope (SILFunction *scopeFunc);
125
128
@@ -157,6 +160,24 @@ class ClosureScopeAnalysis : public SILAnalysis {
157
160
ClosureScopeData *getOrComputeScopeData ();
158
161
};
159
162
163
+ // ClosureScopeAnalysis utility for visiting functions top down in closure scope
164
+ // order.
165
+ class TopDownClosureFunctionOrder {
166
+ ClosureScopeAnalysis *CSA;
167
+
168
+ llvm::SmallSet<SILFunction *, 16 > visited;
169
+
170
+ BlotSetVector<SILFunction *> closureWorklist;
171
+
172
+ public:
173
+ TopDownClosureFunctionOrder (ClosureScopeAnalysis *CSA) : CSA(CSA) {}
174
+
175
+ // Visit all functions in a module, visiting each closure scope function
176
+ // before
177
+ // the closure function itself.
178
+ void visitFunctions (std::function<void (SILFunction *)> visitor);
179
+ };
180
+
160
181
} // end namespace swift
161
182
162
183
#endif
Original file line number Diff line number Diff line change 14
14
15
15
#define DEBUG_TYPE " closure-scope"
16
16
17
+ #include " swift/SIL/SILModule.h"
17
18
#include " swift/SILOptimizer/Analysis/ClosureScope.h"
18
19
19
20
namespace swift {
@@ -154,4 +155,42 @@ SILAnalysis *createClosureScopeAnalysis(SILModule *M) {
154
155
return new ClosureScopeAnalysis (M);
155
156
}
156
157
158
+ void TopDownClosureFunctionOrder::visitFunctions (
159
+ std::function<void (SILFunction *)> visitor) {
160
+ auto markVisited = [&](SILFunction *F) {
161
+ bool visitOnce = visited.insert (F).second ;
162
+ assert (visitOnce);
163
+ (void )visitOnce;
164
+ };
165
+ auto allScopesVisited = [&](SILFunction *closureF) {
166
+ return llvm::all_of (CSA->getClosureScopes (closureF),
167
+ [this ](SILFunction *F) { return visited.count (F); });
168
+ };
169
+ for (auto &F : *CSA->getModule ()) {
170
+ if (!allScopesVisited (&F)) {
171
+ closureWorklist.insert (&F);
172
+ continue ;
173
+ }
174
+ markVisited (&F);
175
+ visitor (&F);
176
+ }
177
+ unsigned numClosures = closureWorklist.size ();
178
+ while (numClosures) {
179
+ for (auto &closureNode : closureWorklist) {
180
+ // skip erased closures.
181
+ if (!closureNode)
182
+ continue ;
183
+
184
+ auto closureF = closureNode.getValue ();
185
+ if (!allScopesVisited (closureF))
186
+ continue ;
187
+
188
+ markVisited (closureF);
189
+ visitor (closureF);
190
+ closureWorklist.erase (closureF);
191
+ --numClosures;
192
+ }
193
+ }
194
+ }
195
+
157
196
} // namespace swift
You can’t perform that action at this time.
0 commit comments