Skip to content

Commit 5530aa9

Browse files
committed
[move-only] Teach deinit devirtualization how to handle devirtualizing a deinit of a resilient type.
Specifically, such a type has an @in convention for its deinit and the pass was setup expecting self to always be @owned. rdar://109904633 (cherry picked from commit 1d04df9)
1 parent 6a5ef8a commit 5530aa9

File tree

3 files changed

+428
-5
lines changed

3 files changed

+428
-5
lines changed

include/swift/SIL/SILFunctionConventions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,11 @@ class SILFunctionConventions {
371371
return getNumIndirectSILResults();
372372
}
373373

374+
/// Returns the index of self.
375+
unsigned getSILArgIndexOfSelf() const {
376+
return getSILArgIndexOfFirstParam() + getNumParameters() - 1;
377+
}
378+
374379
/// Get the index into formal indirect results corresponding to the given SIL
375380
/// indirect result argument index.
376381
unsigned getIndirectFormalResultIndexForSILArg(unsigned argIdx) const {

lib/SILOptimizer/Mandatory/MoveOnlyDeinitInsertion.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,21 @@ static bool performTransform(SILFunction &fn) {
7777
auto subMap =
7878
astType->getContextSubstitutionMap(nom->getModuleContext(), nom);
7979
SILBuilderWithScope builder(dvi);
80+
81+
SILValue value = dvi->getOperand();
82+
auto conv = deinitFunc->getConventionsInContext();
83+
if (conv.getSILArgumentConvention(conv.getSILArgIndexOfSelf())
84+
.isIndirectConvention()) {
85+
auto *asi =
86+
builder.createAllocStack(dvi->getLoc(), value->getType());
87+
builder.emitStoreValueOperation(dvi->getLoc(), value, asi,
88+
StoreOwnershipQualifier::Init);
89+
value = asi;
90+
}
8091
auto *funcRef = builder.createFunctionRef(dvi->getLoc(), deinitFunc);
81-
builder.createApply(dvi->getLoc(), funcRef, subMap,
82-
dvi->getOperand());
92+
builder.createApply(dvi->getLoc(), funcRef, subMap, value);
93+
if (isa<AllocStackInst>(value))
94+
builder.createDeallocStack(dvi->getLoc(), value);
8395
dvi->eraseFromParent();
8496
changed = true;
8597
continue;
@@ -103,9 +115,15 @@ static bool performTransform(SILFunction &fn) {
103115
auto *funcRef = builder.createFunctionRef(dai->getLoc(), deinitFunc);
104116
auto subMap = destroyType.getASTType()->getContextSubstitutionMap(
105117
nom->getModuleContext(), nom);
106-
auto loadedValue = builder.emitLoadValueOperation(
107-
dai->getLoc(), dai->getOperand(), LoadOwnershipQualifier::Take);
108-
builder.createApply(dai->getLoc(), funcRef, subMap, loadedValue);
118+
119+
auto conv = deinitFunc->getConventionsInContext();
120+
auto argConv =
121+
conv.getSILArgumentConvention(conv.getSILArgIndexOfSelf());
122+
SILValue value = dai->getOperand();
123+
if (!argConv.isIndirectConvention())
124+
value = builder.emitLoadValueOperation(
125+
dai->getLoc(), dai->getOperand(), LoadOwnershipQualifier::Take);
126+
builder.createApply(dai->getLoc(), funcRef, subMap, value);
109127
dai->eraseFromParent();
110128
changed = true;
111129
continue;

0 commit comments

Comments
 (0)