Skip to content

Commit bb2fc82

Browse files
authored
Merge pull request #65060 from eeckstein/drop_deinit
Add the `drop_deinit` instruction
2 parents 0bdacfb + 6b44d5a commit bb2fc82

32 files changed

+230
-16
lines changed

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,10 @@ final public class MoveValueInst : SingleValueInstruction, UnaryInstruction {
647647
public var fromValue: Value { operand.value }
648648
}
649649

650+
final public class DropDeinitInst : SingleValueInstruction, UnaryInstruction {
651+
public var fromValue: Value { operand.value }
652+
}
653+
650654
final public class StrongCopyUnownedValueInst : SingleValueInstruction, UnaryInstruction {}
651655

652656
final public class StrongCopyUnmanagedValueInst : SingleValueInstruction, UnaryInstruction {}

SwiftCompilerSources/Sources/SIL/Registration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ public func registerSILClasses() {
125125
register(ProjectBoxInst.self)
126126
register(CopyValueInst.self)
127127
register(MoveValueInst.self)
128+
register(DropDeinitInst.self)
128129
register(EndCOWMutationInst.self)
129130
register(ClassifyBridgeObjectInst.self)
130131
register(PartialApplyInst.self)

docs/SIL.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6117,6 +6117,29 @@ a type `T` into the move only value space.
61176117
The ``lexical`` attribute specifies that the value corresponds to a local
61186118
variable in the Swift source.
61196119

6120+
6121+
drop_deinit
6122+
```````````
6123+
6124+
::
6125+
6126+
sil-instruction ::= 'drop_deinit' sil-operand
6127+
6128+
%1 = drop_deinit %0 : $T
6129+
// T must be a move-only type
6130+
// %1 is an @owned T
6131+
%3 = drop_deinit %2 : $*T
6132+
// T must be a move-only type
6133+
// %2 has type *T
6134+
6135+
This instruction is a marker for a following destroy instruction to suppress
6136+
the call of the move-only type's deinitializer.
6137+
The instruction accepts an object or address type.
6138+
If its argument is an object type it takes in an `@owned T` and produces a new
6139+
`@owned T`. If its argument is an address type, it's an identity projection.
6140+
6141+
The instruction is only valid in ownership SIL.
6142+
61206143
release_value
61216144
`````````````
61226145

include/swift/SIL/MemAccessUtils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,6 +1632,7 @@ inline bool isAccessStorageIdentityCast(SingleValueInstruction *svi) {
16321632
// Simply pass-thru the incoming address.
16331633
case SILInstructionKind::MarkUninitializedInst:
16341634
case SILInstructionKind::MarkMustCheckInst:
1635+
case SILInstructionKind::DropDeinitInst:
16351636
case SILInstructionKind::MarkUnresolvedReferenceBindingInst:
16361637
case SILInstructionKind::MarkDependenceInst:
16371638
case SILInstructionKind::CopyValueInst:

include/swift/SIL/SILBuilder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,6 +1355,14 @@ class SILBuilder {
13551355
operand, isLexical));
13561356
}
13571357

1358+
DropDeinitInst *createDropDeinit(SILLocation loc, SILValue operand) {
1359+
assert(getFunction().hasOwnership());
1360+
assert(!operand->getType().isTrivial(getFunction()) &&
1361+
"Should not be passing trivial values to this api.");
1362+
return insert(new (getModule()) DropDeinitInst(getSILDebugLocation(loc),
1363+
operand));
1364+
}
1365+
13581366
MarkUnresolvedMoveAddrInst *createMarkUnresolvedMoveAddr(SILLocation loc,
13591367
SILValue srcAddr,
13601368
SILValue takeAddr) {

include/swift/SIL/SILCloner.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1888,6 +1888,17 @@ void SILCloner<ImplClass>::visitMoveValueInst(MoveValueInst *Inst) {
18881888
recordClonedInstruction(Inst, MVI);
18891889
}
18901890

1891+
template <typename ImplClass>
1892+
void SILCloner<ImplClass>::visitDropDeinitInst(DropDeinitInst *Inst) {
1893+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1894+
if (!getBuilder().hasOwnership()) {
1895+
return recordFoldedValue(Inst, getOpValue(Inst->getOperand()));
1896+
}
1897+
auto *MVI = getBuilder().createDropDeinit(getOpLocation(Inst->getLoc()),
1898+
getOpValue(Inst->getOperand()));
1899+
recordClonedInstruction(Inst, MVI);
1900+
}
1901+
18911902
template <typename ImplClass>
18921903
void SILCloner<ImplClass>::visitMarkMustCheckInst(MarkMustCheckInst *Inst) {
18931904
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));

include/swift/SIL/SILInstruction.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8268,6 +8268,15 @@ class MoveValueInst
82688268
void removeIsLexical() { lexical = false; }
82698269
};
82708270

8271+
class DropDeinitInst
8272+
: public UnaryInstructionBase<SILInstructionKind::DropDeinitInst,
8273+
SingleValueInstruction> {
8274+
friend class SILBuilder;
8275+
8276+
DropDeinitInst(SILDebugLocation DebugLoc, SILValue operand)
8277+
: UnaryInstructionBase(DebugLoc, operand, operand->getType()) {}
8278+
};
8279+
82718280
/// Equivalent to a copy_addr to [init] except that it is used for diagnostics
82728281
/// and should not be pattern matched. During the diagnostic passes, the "move
82738282
/// function" checker for addresses always converts this to a copy_addr [init]

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,8 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
461461
// effects relative to other OSSA values like copy_value.
462462
SINGLE_VALUE_INST(MoveValueInst, move_value, SingleValueInstruction, None,
463463
DoesNotRelease)
464+
SINGLE_VALUE_INST(DropDeinitInst, drop_deinit, SingleValueInstruction, None,
465+
DoesNotRelease)
464466
// A canary value inserted by a SIL generating frontend to signal to the move
465467
// checker to check a specific value. Valid only in Raw SIL. The relevant
466468
// checkers should remove the mark_must_check instruction after successfully

lib/IRGen/IRGenSIL.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,6 +1222,10 @@ class IRGenSILFunction :
12221222
auto e = getLoweredExplosion(i->getOperand());
12231223
setLoweredExplosion(i, e);
12241224
}
1225+
void visitDropDeinitInst(DropDeinitInst *i) {
1226+
auto e = getLoweredExplosion(i->getOperand());
1227+
setLoweredExplosion(i, e);
1228+
}
12251229
void visitMarkMustCheckInst(MarkMustCheckInst *i) {
12261230
llvm_unreachable("Invalid in Lowered SIL");
12271231
}

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,12 @@ OperandOwnershipClassifier::visitStoreBorrowInst(StoreBorrowInst *i) {
455455
return OperandOwnership::TrivialUse;
456456
}
457457

458+
OperandOwnership
459+
OperandOwnershipClassifier::visitDropDeinitInst(DropDeinitInst *i) {
460+
return i->getType().isAddress() ? OperandOwnership::TrivialUse
461+
: OperandOwnership::ForwardingConsume;
462+
}
463+
458464
// Get the OperandOwnership for instantaneous apply, yield, and return uses.
459465
// This does not apply to uses that begin an explicit borrow scope in the
460466
// caller, such as begin_apply.

0 commit comments

Comments
 (0)