Skip to content

Commit 2a5d075

Browse files
committed
[SIL] Add extend_lifetime instruction.
It indicates that the value's lifetime continues to at least this point. The boundary formed by all consuming uses together with these instructions will encompass all uses of the value.
1 parent 77d26e1 commit 2a5d075

File tree

22 files changed

+117
-1
lines changed

22 files changed

+117
-1
lines changed

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,8 @@ final public class DestroyAddrInst : Instruction, UnaryInstruction {
514514

515515
final public class EndLifetimeInst : Instruction, UnaryInstruction {}
516516

517+
final public class ExtendLifetimeInst : Instruction, UnaryInstruction {}
518+
517519
final public class InjectEnumAddrInst : Instruction, UnaryInstruction, EnumInstruction {
518520
public var `enum`: Value { operand.value }
519521
public var caseIndex: Int { bridged.InjectEnumAddrInst_caseIndex() }

SwiftCompilerSources/Sources/SIL/Registration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public func registerSILClasses() {
7878
register(DestroyValueInst.self)
7979
register(DestroyAddrInst.self)
8080
register(EndLifetimeInst.self)
81+
register(ExtendLifetimeInst.self)
8182
register(StrongCopyUnownedValueInst.self)
8283
register(StrongCopyUnmanagedValueInst.self)
8384
register(StrongCopyWeakValueInst.self)

docs/SIL.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4682,6 +4682,22 @@ The instruction accepts an object or address type.
46824682
This instruction is valid only in OSSA and is lowered to a no-op when lowering
46834683
to non-OSSA.
46844684

4685+
extend_lifetime
4686+
```````````````
4687+
4688+
::
4689+
4690+
sil-instruction ::= 'extend_lifetime' sil-operand
4691+
4692+
// Indicate that %0's linear lifetime extends to this point
4693+
extend_lifetime %0 : $X
4694+
4695+
Indicates that a value's linear lifetime extends to this point. Inserted by
4696+
OSSALifetimeCompletion(AvailabilityBoundary) in order to provide the invariant
4697+
that a value is either consumed OR has an `extend_lifetime` user on all paths
4698+
and furthermore that all uses are within the boundary defined by that set of
4699+
instructions (the consumes and the `extend_lifetime`s).
4700+
46854701
assign
46864702
``````
46874703
::

include/swift/SIL/SILBuilder.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2292,6 +2292,11 @@ class SILBuilder {
22922292
EndLifetimeInst(getSILDebugLocation(Loc), Operand));
22932293
}
22942294

2295+
ExtendLifetimeInst *createExtendLifetime(SILLocation Loc, SILValue Operand) {
2296+
return insert(new (getModule())
2297+
ExtendLifetimeInst(getSILDebugLocation(Loc), Operand));
2298+
}
2299+
22952300
UncheckedOwnershipConversionInst *
22962301
createUncheckedOwnershipConversion(SILLocation Loc, SILValue Operand,
22972302
ValueOwnershipKind Kind) {

include/swift/SIL/SILCloner.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3019,6 +3019,18 @@ void SILCloner<ImplClass>::visitEndLifetimeInst(EndLifetimeInst *Inst) {
30193019
getOpValue(Inst->getOperand())));
30203020
}
30213021

3022+
template <typename ImplClass>
3023+
void SILCloner<ImplClass>::visitExtendLifetimeInst(ExtendLifetimeInst *Inst) {
3024+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
3025+
3026+
if (!getBuilder().hasOwnership())
3027+
return;
3028+
3029+
recordClonedInstruction(
3030+
Inst, getBuilder().createExtendLifetime(getOpLocation(Inst->getLoc()),
3031+
getOpValue(Inst->getOperand())));
3032+
}
3033+
30223034
template <typename ImplClass>
30233035
void SILCloner<ImplClass>::visitUncheckedOwnershipConversionInst(
30243036
UncheckedOwnershipConversionInst *Inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8535,6 +8535,16 @@ class EndLifetimeInst
85358535
: UnaryInstructionBase(DebugLoc, Operand) {}
85368536
};
85378537

8538+
/// Mark the end of the linear live range of a value without destroying it.
8539+
class ExtendLifetimeInst
8540+
: public UnaryInstructionBase<SILInstructionKind::ExtendLifetimeInst,
8541+
NonValueInstruction> {
8542+
friend SILBuilder;
8543+
8544+
ExtendLifetimeInst(SILDebugLocation loc, SILValue operand)
8545+
: UnaryInstructionBase(loc, operand) {}
8546+
};
8547+
85388548
/// An unsafe conversion in between ownership kinds.
85398549
///
85408550
/// This is used today in destructors where due to Objective-C legacy

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,8 @@ NON_VALUE_INST(DestroyAddrInst, destroy_addr,
864864
SILInstruction, MayHaveSideEffects, MayRelease)
865865
NON_VALUE_INST(EndLifetimeInst, end_lifetime,
866866
SILInstruction, MayHaveSideEffects, MayRelease)
867+
NON_VALUE_INST(ExtendLifetimeInst, extend_lifetime,
868+
SILInstruction, None, DoesNotRelease)
867869
NON_VALUE_INST(InjectEnumAddrInst, inject_enum_addr,
868870
SILInstruction, MayWrite, DoesNotRelease)
869871
NON_VALUE_INST(DeinitExistentialAddrInst, deinit_existential_addr,

lib/IRGen/IRGenSIL.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,6 +1350,9 @@ class IRGenSILFunction :
13501350
void visitEndLifetimeInst(EndLifetimeInst *i) {
13511351
llvm_unreachable("unimplemented");
13521352
}
1353+
void visitExtendLifetimeInst(ExtendLifetimeInst *i) {
1354+
llvm_unreachable("should not exist after ownership lowering!?");
1355+
}
13531356
void
13541357
visitUncheckedOwnershipConversionInst(UncheckedOwnershipConversionInst *i) {
13551358
llvm_unreachable("unimplemented");

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ OPERAND_OWNERSHIP(InstantaneousUse, SuperMethod)
225225
OPERAND_OWNERSHIP(InstantaneousUse, ClassifyBridgeObject)
226226
OPERAND_OWNERSHIP(InstantaneousUse, UnownedCopyValue)
227227
OPERAND_OWNERSHIP(InstantaneousUse, WeakCopyValue)
228+
OPERAND_OWNERSHIP(InstantaneousUse, ExtendLifetime)
228229
#define REF_STORAGE(Name, ...) \
229230
OPERAND_OWNERSHIP(InstantaneousUse, StrongCopy##Name##Value)
230231
#include "swift/AST/ReferenceStorage.def"

lib/SIL/IR/SILPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2565,6 +2565,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
25652565
void visitEndLifetimeInst(EndLifetimeInst *ELI) {
25662566
*this << getIDAndType(ELI->getOperand());
25672567
}
2568+
void visitExtendLifetimeInst(ExtendLifetimeInst *ELLI) {
2569+
*this << getIDAndType(ELLI->getOperand());
2570+
}
25682571
void visitValueToBridgeObjectInst(ValueToBridgeObjectInst *VBOI) {
25692572
*this << getIDAndType(VBOI->getOperand());
25702573
}

0 commit comments

Comments
 (0)