Skip to content

Commit 1d04df9

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
1 parent 8579c19 commit 1d04df9

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
@@ -78,9 +78,21 @@ static bool performTransform(SILFunction &fn) {
7878
auto subMap =
7979
astType->getContextSubstitutionMap(nom->getModuleContext(), nom);
8080
SILBuilderWithScope builder(dvi);
81+
82+
SILValue value = dvi->getOperand();
83+
auto conv = deinitFunc->getConventionsInContext();
84+
if (conv.getSILArgumentConvention(conv.getSILArgIndexOfSelf())
85+
.isIndirectConvention()) {
86+
auto *asi =
87+
builder.createAllocStack(dvi->getLoc(), value->getType());
88+
builder.emitStoreValueOperation(dvi->getLoc(), value, asi,
89+
StoreOwnershipQualifier::Init);
90+
value = asi;
91+
}
8192
auto *funcRef = builder.createFunctionRef(dvi->getLoc(), deinitFunc);
82-
builder.createApply(dvi->getLoc(), funcRef, subMap,
83-
dvi->getOperand());
93+
builder.createApply(dvi->getLoc(), funcRef, subMap, value);
94+
if (isa<AllocStackInst>(value))
95+
builder.createDeallocStack(dvi->getLoc(), value);
8496
dvi->eraseFromParent();
8597
changed = true;
8698
continue;
@@ -105,9 +117,15 @@ static bool performTransform(SILFunction &fn) {
105117
auto *funcRef = builder.createFunctionRef(dai->getLoc(), deinitFunc);
106118
auto subMap = destroyType.getASTType()->getContextSubstitutionMap(
107119
nom->getModuleContext(), nom);
108-
auto loadedValue = builder.emitLoadValueOperation(
109-
dai->getLoc(), dai->getOperand(), LoadOwnershipQualifier::Take);
110-
builder.createApply(dai->getLoc(), funcRef, subMap, loadedValue);
120+
121+
auto conv = deinitFunc->getConventionsInContext();
122+
auto argConv =
123+
conv.getSILArgumentConvention(conv.getSILArgIndexOfSelf());
124+
SILValue value = dai->getOperand();
125+
if (!argConv.isIndirectConvention())
126+
value = builder.emitLoadValueOperation(
127+
dai->getLoc(), dai->getOperand(), LoadOwnershipQualifier::Take);
128+
builder.createApply(dai->getLoc(), funcRef, subMap, value);
111129
dai->eraseFromParent();
112130
changed = true;
113131
continue;

0 commit comments

Comments
 (0)