mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Add TopDownClosureFunctionOrder based on ClosureScopeAnalysis.
Simple utility for transfersing functions such that parent scopes are always visited before noescape closures. Note that recursion is disallowed. Noescape closures are not reentrant.
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
|
||||
#define DEBUG_TYPE "closure-scope"
|
||||
|
||||
#include "swift/SIL/SILModule.h"
|
||||
#include "swift/SILOptimizer/Analysis/ClosureScope.h"
|
||||
|
||||
namespace swift {
|
||||
@@ -154,4 +155,42 @@ SILAnalysis *createClosureScopeAnalysis(SILModule *M) {
|
||||
return new ClosureScopeAnalysis(M);
|
||||
}
|
||||
|
||||
void TopDownClosureFunctionOrder::visitFunctions(
|
||||
std::function<void(SILFunction *)> visitor) {
|
||||
auto markVisited = [&](SILFunction *F) {
|
||||
bool visitOnce = visited.insert(F).second;
|
||||
assert(visitOnce);
|
||||
(void)visitOnce;
|
||||
};
|
||||
auto allScopesVisited = [&](SILFunction *closureF) {
|
||||
return llvm::all_of(CSA->getClosureScopes(closureF),
|
||||
[this](SILFunction *F) { return visited.count(F); });
|
||||
};
|
||||
for (auto &F : *CSA->getModule()) {
|
||||
if (!allScopesVisited(&F)) {
|
||||
closureWorklist.insert(&F);
|
||||
continue;
|
||||
}
|
||||
markVisited(&F);
|
||||
visitor(&F);
|
||||
}
|
||||
unsigned numClosures = closureWorklist.size();
|
||||
while (numClosures) {
|
||||
for (auto &closureNode : closureWorklist) {
|
||||
// skip erased closures.
|
||||
if (!closureNode)
|
||||
continue;
|
||||
|
||||
auto closureF = closureNode.getValue();
|
||||
if (!allScopesVisited(closureF))
|
||||
continue;
|
||||
|
||||
markVisited(closureF);
|
||||
visitor(closureF);
|
||||
closureWorklist.erase(closureF);
|
||||
--numClosures;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace swift
|
||||
|
||||
Reference in New Issue
Block a user