Skip to content

Commit d1b555f

Browse files
committed
[ownership] Make destructure_{struct,tuple} true forwarding instructions instead of inferring from results/arguments.
1 parent d74dbeb commit d1b555f

File tree

3 files changed

+77
-10
lines changed

3 files changed

+77
-10
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8753,6 +8753,23 @@ SILFunction *ApplyInstBase<Impl, Base, false>::getCalleeFunction() const {
87538753
}
87548754
}
87558755

8756+
class OwnershipForwardingMultipleValueInstruction
8757+
: public MultipleValueInstruction {
8758+
ValueOwnershipKind ownershipKind;
8759+
8760+
public:
8761+
OwnershipForwardingMultipleValueInstruction(SILInstructionKind kind,
8762+
SILDebugLocation loc,
8763+
ValueOwnershipKind ownershipKind)
8764+
: MultipleValueInstruction(kind, loc), ownershipKind(ownershipKind) {}
8765+
8766+
/// Returns the preferred ownership kind of this multiple value instruction.
8767+
ValueOwnershipKind getOwnershipKind() const { return ownershipKind; }
8768+
void setOwnershipKind(ValueOwnershipKind newOwnershipKind) {
8769+
ownershipKind = newOwnershipKind;
8770+
}
8771+
};
8772+
87568773
/// A result for the destructure_struct instruction. See documentation for
87578774
/// destructure_struct for more information.
87588775
class DestructureStructResult final : public MultipleValueInstructionResult {
@@ -8776,15 +8793,15 @@ class DestructureStructResult final : public MultipleValueInstructionResult {
87768793
/// struct's fields.
87778794
class DestructureStructInst final
87788795
: public UnaryInstructionBase<SILInstructionKind::DestructureStructInst,
8779-
MultipleValueInstruction>,
8780-
public MultipleValueInstructionTrailingObjects<
8781-
DestructureStructInst, DestructureStructResult> {
8796+
OwnershipForwardingMultipleValueInstruction>,
8797+
public MultipleValueInstructionTrailingObjects<DestructureStructInst,
8798+
DestructureStructResult> {
87828799
friend TrailingObjects;
87838800

87848801
DestructureStructInst(SILModule &M, SILDebugLocation Loc, SILValue Operand,
87858802
ArrayRef<SILType> Types,
87868803
ArrayRef<ValueOwnershipKind> OwnershipKinds)
8787-
: UnaryInstructionBase(Loc, Operand),
8804+
: UnaryInstructionBase(Loc, Operand, Operand.getOwnershipKind()),
87888805
MultipleValueInstructionTrailingObjects(this, Types, OwnershipKinds) {}
87898806

87908807
public:
@@ -8825,15 +8842,15 @@ class DestructureTupleResult final : public MultipleValueInstructionResult {
88258842
/// tuples's elements.
88268843
class DestructureTupleInst final
88278844
: public UnaryInstructionBase<SILInstructionKind::DestructureTupleInst,
8828-
MultipleValueInstruction>,
8829-
public MultipleValueInstructionTrailingObjects<
8830-
DestructureTupleInst, DestructureTupleResult> {
8845+
OwnershipForwardingMultipleValueInstruction>,
8846+
public MultipleValueInstructionTrailingObjects<DestructureTupleInst,
8847+
DestructureTupleResult> {
88318848
friend TrailingObjects;
88328849

88338850
DestructureTupleInst(SILModule &M, SILDebugLocation Loc, SILValue Operand,
88348851
ArrayRef<SILType> Types,
88358852
ArrayRef<ValueOwnershipKind> OwnershipKinds)
8836-
: UnaryInstructionBase(Loc, Operand),
8853+
: UnaryInstructionBase(Loc, Operand, Operand.getOwnershipKind()),
88378854
MultipleValueInstructionTrailingObjects(this, Types, OwnershipKinds) {}
88388855

88398856
public:

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,14 +344,29 @@ FORWARD_ANY_OWNERSHIP_INST(RefToBridgeObject)
344344
FORWARD_ANY_OWNERSHIP_INST(BridgeObjectToRef)
345345
FORWARD_ANY_OWNERSHIP_INST(UnconditionalCheckedCast)
346346
FORWARD_ANY_OWNERSHIP_INST(UncheckedEnumData)
347-
FORWARD_ANY_OWNERSHIP_INST(DestructureStruct)
348-
FORWARD_ANY_OWNERSHIP_INST(DestructureTuple)
349347
FORWARD_ANY_OWNERSHIP_INST(InitExistentialRef)
350348
FORWARD_ANY_OWNERSHIP_INST(DifferentiableFunction)
351349
FORWARD_ANY_OWNERSHIP_INST(LinearFunction)
352350
FORWARD_ANY_OWNERSHIP_INST(UncheckedValueCast)
353351
#undef FORWARD_ANY_OWNERSHIP_INST
354352

353+
// Temporary implementation for staging purposes.
354+
OperandOwnershipKindMap
355+
OperandOwnershipKindClassifier::visitDestructureStructInst(
356+
DestructureStructInst *dsi) {
357+
auto kind = dsi->getOwnershipKind();
358+
auto constraint = kind.getForwardingLifetimeConstraint();
359+
return {kind, constraint};
360+
}
361+
362+
OperandOwnershipKindMap
363+
OperandOwnershipKindClassifier::visitDestructureTupleInst(
364+
DestructureTupleInst *dsi) {
365+
auto kind = dsi->getOwnershipKind();
366+
auto constraint = kind.getForwardingLifetimeConstraint();
367+
return {kind, constraint};
368+
}
369+
355370
// An instruction that forwards a constant ownership or trivial ownership.
356371
#define FORWARD_CONSTANT_OR_NONE_OWNERSHIP_INST(OWNERSHIP, \
357372
USE_LIFETIME_CONSTRAINT, INST) \

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2915,6 +2915,41 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
29152915
require(!sd->isResilient(F.getModule().getSwiftModule(),
29162916
F.getResilienceExpansion()),
29172917
"cannot access storage of resilient struct");
2918+
if (F.hasOwnership()) {
2919+
// Make sure that all of our destructure results ownership kinds are
2920+
// compatible with our destructure_struct's ownership kind /and/ that if
2921+
// our destructure ownership kind is non-trivial then all non-trivial
2922+
// results must have the same ownership kind as our operand.
2923+
auto parentKind = DSI->getOwnershipKind();
2924+
for (const DestructureStructResult &result : DSI->getAllResultsBuffer()) {
2925+
require(parentKind.isCompatibleWith(result.getOwnershipKind()),
2926+
"destructure result with ownership that is incompatible with "
2927+
"parent forwarding ownership kind");
2928+
require(parentKind != ValueOwnershipKind::None ||
2929+
result.getOwnershipKind() == ValueOwnershipKind::None,
2930+
"destructure with none ownership kind operand and non-none "
2931+
"ownership kind result?!");
2932+
}
2933+
}
2934+
}
2935+
2936+
void checkDestructureTupleInst(DestructureTupleInst *dti) {
2937+
if (F.hasOwnership()) {
2938+
// Make sure that all of our destructure results ownership kinds are
2939+
// compatible with our destructure_struct's ownership kind /and/ that if
2940+
// our destructure ownership kind is non-trivial then all non-trivial
2941+
// results must have the same ownership kind as our operand.
2942+
auto parentKind = dti->getOwnershipKind();
2943+
for (const auto &result : dti->getAllResultsBuffer()) {
2944+
require(parentKind.isCompatibleWith(result.getOwnershipKind()),
2945+
"destructure result with ownership that is incompatible with "
2946+
"parent forwarding ownership kind");
2947+
require(parentKind != ValueOwnershipKind::None ||
2948+
result.getOwnershipKind() == ValueOwnershipKind::None,
2949+
"destructure with none ownership kind operand and non-none "
2950+
"ownership kind result?!");
2951+
}
2952+
}
29182953
}
29192954

29202955
SILType getMethodSelfType(CanSILFunctionType ft) {

0 commit comments

Comments
 (0)