Skip to content

Commit 9d92d40

Browse files
committed
[move-only] Move most move only passes earlier in the pass pipeline before Mandatory Inlining, right after DI.
1 parent 486dc27 commit 9d92d40

File tree

3 files changed

+46
-30
lines changed

3 files changed

+46
-30
lines changed

Diff for: lib/SIL/Verifier/SILVerifier.cpp

+12-2
Original file line numberDiff line numberDiff line change
@@ -4744,8 +4744,18 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
47444744
if (F.getModule().getStage() != SILStage::Lowered) {
47454745
// During the lowered stage, a function type might have different
47464746
// signature
4747-
require(eltArgTy == bbArgTy,
4748-
"switch_enum destination bbarg must match case arg type");
4747+
//
4748+
// We allow for move only wrapped enums to have trivial payloads that
4749+
// are not move only wrapped. This occurs since we want to lower
4750+
// trivial move only wrapped types earlier in the pipeline than
4751+
// non-trivial types.
4752+
if (bbArgTy.isTrivial(F)) {
4753+
require(eltArgTy == bbArgTy.copyingMoveOnlyWrapper(eltArgTy),
4754+
"switch_enum destination bbarg must match case arg type");
4755+
} else {
4756+
require(eltArgTy == bbArgTy,
4757+
"switch_enum destination bbarg must match case arg type");
4758+
}
47494759
}
47504760
require(!dest->getArguments()[0]->getType().isAddress(),
47514761
"switch_enum destination bbarg type must not be an address");

Diff for: lib/SILOptimizer/Mandatory/MoveOnlyWrappedTypeEliminator.cpp

+17-4
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ struct SILMoveOnlyWrappedTypeEliminatorVisitor
9393
endBorrows.push_back(ebi);
9494
}
9595
for (auto *ebi : endBorrows) {
96-
ebi->eraseFromParent();
96+
eraseFromParent(ebi);
9797
}
9898
si->replaceAllUsesWith(si->getDest());
9999
return eraseFromParent(si);
@@ -183,19 +183,32 @@ struct SILMoveOnlyWrappedTypeEliminatorVisitor
183183
NO_UPDATE_NEEDED(DestroyAddr)
184184
NO_UPDATE_NEEDED(DeallocStack)
185185
NO_UPDATE_NEEDED(Branch)
186-
NO_UPDATE_NEEDED(UncheckedAddrCast)
187186
NO_UPDATE_NEEDED(RefElementAddr)
188-
NO_UPDATE_NEEDED(Upcast)
189187
NO_UPDATE_NEEDED(CheckedCastBranch)
190188
NO_UPDATE_NEEDED(Object)
191189
NO_UPDATE_NEEDED(OpenExistentialRef)
192190
NO_UPDATE_NEEDED(ConvertFunction)
193191
NO_UPDATE_NEEDED(RefToBridgeObject)
194192
NO_UPDATE_NEEDED(BridgeObjectToRef)
195-
NO_UPDATE_NEEDED(UnconditionalCheckedCast)
196193
NO_UPDATE_NEEDED(ClassMethod)
197194
#undef NO_UPDATE_NEEDED
198195

196+
bool eliminateIdentityCast(SingleValueInstruction *svi) {
197+
if (svi->getOperand(0)->getType() != svi->getType())
198+
return false;
199+
svi->replaceAllUsesWith(svi->getOperand(0));
200+
eraseFromParent(svi);
201+
return true;
202+
}
203+
204+
#define ELIMINATE_POTENTIAL_IDENTITY_CAST(NAME) \
205+
bool visit##NAME##Inst(NAME##Inst *cast) { \
206+
return eliminateIdentityCast(cast); \
207+
}
208+
ELIMINATE_POTENTIAL_IDENTITY_CAST(Upcast)
209+
ELIMINATE_POTENTIAL_IDENTITY_CAST(UncheckedAddrCast)
210+
ELIMINATE_POTENTIAL_IDENTITY_CAST(UnconditionalCheckedCast)
211+
#undef ELIMINATE_POTENTIAL_IDENTITY_CAST
199212
// We handle apply sites by just inserting a convert_function that converts
200213
// the original function type into a function type without move only. This is
201214
// safe since adding/removing moveonlywrapped types is ABI neutral.

Diff for: lib/SILOptimizer/PassManager/PassPipeline.cpp

+17-24
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,23 @@ static void addMandatoryDiagnosticOptPipeline(SILPassPipelinePlan &P) {
128128
P.addAllocBoxToStack();
129129
P.addNoReturnFolding();
130130
addDefiniteInitialization(P);
131+
132+
133+
//===---
134+
// Ownership Optimizations
135+
//
136+
137+
P.addMoveKillsCopyableAddressesChecker();
138+
P.addMoveOnlyObjectChecker(); // Check noImplicitCopy and move only
139+
// types.
140+
P.addMoveKillsCopyableValuesChecker(); // No uses after _move of copyable
141+
// value.
142+
P.addTrivialMoveOnlyTypeEliminator();
143+
// As a temporary measure, we also eliminate move only for non-trivial types
144+
// until we can audit the later part of the pipeline. Eventually, this should
145+
// occur before IRGen.
146+
P.addMoveOnlyTypeEliminator();
147+
131148
P.addAddressLowering();
132149

133150
P.addFlowIsolation();
@@ -159,34 +176,10 @@ static void addMandatoryDiagnosticOptPipeline(SILPassPipelinePlan &P) {
159176
P.addMandatoryInlining();
160177
P.addMandatorySILLinker();
161178

162-
// Before we promote any loads, perform _move checking for addresses.
163-
P.addMoveKillsCopyableAddressesChecker();
164-
165-
// Now perform move object checking. We again do this before predictable
166-
// memory access opts to ensure that we do not get any non-source related
167-
// diagnostics due to value promotion.
168-
P.addMoveOnlyObjectChecker(); // Check noImplicitCopy and move only
169-
// types.
170-
171179
// Promote loads as necessary to ensure we have enough SSA formation to emit
172180
// SSA based diagnostics.
173181
P.addPredictableMemoryAccessOptimizations();
174182

175-
// Now that we have promoted simple loads for SSA based diagnostics, perform
176-
// SSA based move function checking and no implicit copy checking.
177-
P.addMoveKillsCopyableValuesChecker(); // No uses after _move of copyable
178-
// value.
179-
180-
// Now that we have run move only checking, eliminate SILMoveOnly wrapped
181-
// trivial types from the IR. We cannot introduce extra "copies" of trivial
182-
// things so we can simplify our implementation by eliminating them here.
183-
P.addTrivialMoveOnlyTypeEliminator();
184-
185-
// As a temporary measure, we also eliminate move only for non-trivial types
186-
// until we can audit the later part of the pipeline. Eventually, this should
187-
// occur before IRGen.
188-
P.addMoveOnlyTypeEliminator();
189-
190183
// This phase performs optimizations necessary for correct interoperation of
191184
// Swift os log APIs with C os_log ABIs.
192185
// Pass dependencies: this pass depends on MandatoryInlining and Mandatory

0 commit comments

Comments
 (0)