Skip to content

Commit 0dfce6c

Browse files
committed
Don't rerun mandatory lowering passes on deserialized SIL.
1 parent 66a579c commit 0dfce6c

File tree

3 files changed

+38
-13
lines changed

3 files changed

+38
-13
lines changed

lib/SILOptimizer/Analysis/ClosureScope.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ class ClosureScopeData {
9191
auto scopeFunc = PAI->getFunction();
9292
int scopeIdx = lookupScopeIndex(scopeFunc);
9393

94+
// Passes may assume that a deserialized function can only refer to
95+
// deserialized closures. For example, AccessEnforcementSelection skips
96+
// deserialized functions but assumes all a closure's parent scope have been
97+
// processed.
98+
assert(scopeFunc->wasDeserializedCanonical()
99+
== closureFunc->wasDeserializedCanonical() &&
100+
"A closure cannot be serialized in a different module than its "
101+
"parent context");
102+
94103
auto &indices = closureToScopesMap[closureFunc];
95104
if (std::find(indices.begin(), indices.end(), scopeIdx) != indices.end())
96105
return;

lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,19 @@
1313
/// This pass eliminates 'unknown' access enforcement by selecting either
1414
/// static or dynamic enforcement.
1515
///
16-
/// TODO: This is currently a module transform so that closures can be
17-
/// transformed after their parent scope is analyzed. This isn't a big problem
18-
/// now because AccessMarkerElimination is also a module pass that follows this
19-
/// pass. However, we would like to mostly eliminate module transforms. This
20-
/// could be done by changing the PassManager to follow CloseScopeAnalysis. A
21-
/// new ClosureTransform type would be pipelined just like FunctionTransform,
22-
/// but would have an entry point that handled a parent closure scope and all
23-
/// its children in one invocation. For function pipelining to be upheld, we
24-
/// would need to verify that BasicCalleeAnalysis never conflicts with
25-
/// ClosureScopeAnalysis. i.e. we could never create a caller->callee edge when
26-
/// the callee is passed as a function argument. Normal FunctionTransforms would
27-
/// then be called on each closure function and its parent scope before calling
28-
/// the ClosureTransform.
16+
/// TODO: This is currently a module transform so that it can process closures
17+
/// after analyzing their parent scope. This isn't a big problem now because
18+
/// AccessMarkerElimination is also a module pass that follows this pass, so all
19+
/// markers will still be present when this pass runs. However, we would like to
20+
/// mostly eliminate module transforms. This could be done by changing the
21+
/// PassManager to follow ClosureScopeAnalysis. A new ClosureTransform type
22+
/// would be pipelined just like FunctionTransform, but would have an entry
23+
/// point that handled a parent closure scope and all its children in one
24+
/// invocation. For function pipelining to be upheld, we would need to verify
25+
/// that BasicCalleeAnalysis never conflicts with ClosureScopeAnalysis. i.e. we
26+
/// could never create a caller->callee edge when the callee is passed as a
27+
/// function argument. Normal FunctionTransforms would then be called on each
28+
/// closure function and its parent scope before calling the ClosureTransform.
2929
///
3030
/// FIXME: handle boxes used by copy_value when neither copy is captured.
3131
///
@@ -521,6 +521,12 @@ struct SourceAccess {
521521
};
522522

523523
/// The pass.
524+
///
525+
/// This can't be a SILFunctionTransform because DynamicCaptures need to be
526+
/// recorded while analyzing a closure's parent scopes before processing the
527+
/// closures.
528+
///
529+
/// TODO: Make this a "ClosureTransform". See the file-level comments above.
524530
class AccessEnforcementSelection : public SILModuleTransform {
525531
// Reference back to the known dynamically enforced non-escaping closure
526532
// arguments in this module. Parent scopes are processed before the closures
@@ -554,6 +560,12 @@ void AccessEnforcementSelection::run() {
554560
}
555561

556562
void AccessEnforcementSelection::processFunction(SILFunction *F) {
563+
if (F->wasDeserializedCanonical()) {
564+
DEBUG(llvm::dbgs() << "Skipping Access Enforcement Selection of "
565+
"deserialized "
566+
<< F->getName() << "\n");
567+
return;
568+
}
557569
DEBUG(llvm::dbgs() << "Access Enforcement Selection in " << F->getName()
558570
<< "\n");
559571
#ifndef NDEBUG

lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ namespace {
297297
struct OwnershipModelEliminator : SILModuleTransform {
298298
void run() override {
299299
for (auto &F : *getModule()) {
300+
// Don't rerun early lowering on deserialized functions.
301+
if (F.wasDeserializedCanonical())
302+
continue;
303+
300304
// Set F to have unqualified ownership.
301305
F.setUnqualifiedOwnership();
302306

0 commit comments

Comments
 (0)