Skip to content

Commit fe321ca

Browse files
authored
Merge pull request #39267 from gottesmm/pr-c8321c6af93e6ad619f35474eb2a74f181c17384
[sil] Add a move_value instruction.
2 parents 03e32c4 + 5590c7b commit fe321ca

File tree

20 files changed

+155
-2
lines changed

20 files changed

+155
-2
lines changed

docs/SIL.rst

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5245,6 +5245,34 @@ independent of the operand. In terms of specific types:
52455245
In ownership qualified functions, a ``copy_value`` produces a +1 value that must
52465246
be consumed at most once along any path through the program.
52475247

5248+
move_value
5249+
``````````
5250+
5251+
::
5252+
5253+
sil-instruction ::= 'move_value' sil-operand
5254+
5255+
%1 = move_value %0 : $@_moveOnly A
5256+
5257+
Performs a move of the operand, ending its lifetime. When ownership is enabled,
5258+
it always takes in an `@owned T` and produces a new `@owned @_moveOnly T`.
5259+
5260+
1. For trivial types, this is equivalent to just propagating through the trivial
5261+
value.
5262+
2. For reference types, this is equivalent to ending the lifetime of the
5263+
operand, beginning a new lifetime for the result and setting the result to
5264+
the value of the operand.
5265+
3. For aggregates, the operation is equivalent to performing a move_value on
5266+
each of its fields recursively.
5267+
5268+
After ownership is lowered, we leave in the move_value to provide a place for
5269+
IRGenSIL to know to store a potentially new variable (in case the move was
5270+
associated with a let binding).
5271+
5272+
NOTE: This instruction is used in an experimental feature called 'move only
5273+
values'. A move_value instruction is an instruction that introduces (or injects)
5274+
a type `T` into the move only value space.
5275+
52485276
release_value
52495277
`````````````
52505278

include/swift/SIL/SILBuilder.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,14 @@ class SILBuilder {
12321232
operand, poisonRefs));
12331233
}
12341234

1235+
MoveValueInst *createMoveValue(SILLocation loc, SILValue operand) {
1236+
assert(!operand->getType().isTrivial(getFunction()) &&
1237+
"Should not be passing trivial values to this api. Use instead "
1238+
"emitMoveValueOperation");
1239+
return insert(new (getModule())
1240+
MoveValueInst(getSILDebugLocation(loc), operand));
1241+
}
1242+
12351243
UnconditionalCheckedCastInst *
12361244
createUnconditionalCheckedCast(SILLocation Loc, SILValue op,
12371245
SILType destLoweredTy,
@@ -2466,6 +2474,17 @@ class SILBuilder {
24662474
createDestroyAddr(loc, v);
24672475
}
24682476

2477+
/// Convenience function that is a no-op for trivial values and inserts a
2478+
/// move_value on non-trivial instructions.
2479+
SILValue emitMoveValueOperation(SILLocation Loc, SILValue v) {
2480+
assert(!v->getType().isAddress());
2481+
if (v->getType().isTrivial(*getInsertionBB()->getParent()))
2482+
return v;
2483+
assert(v.getOwnershipKind() == OwnershipKind::Owned &&
2484+
"move_value consumes its argument");
2485+
return createMoveValue(Loc, v);
2486+
}
2487+
24692488
SILValue emitTupleExtract(SILLocation Loc, SILValue Operand, unsigned FieldNo,
24702489
SILType ResultTy) {
24712490
// Fold tuple_extract(tuple(x,y,z),2)

include/swift/SIL/SILCloner.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,6 +1717,14 @@ void SILCloner<ImplClass>::visitCopyValueInst(CopyValueInst *Inst) {
17171717
getOpValue(Inst->getOperand())));
17181718
}
17191719

1720+
template <typename ImplClass>
1721+
void SILCloner<ImplClass>::visitMoveValueInst(MoveValueInst *Inst) {
1722+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1723+
recordClonedInstruction(
1724+
Inst, getBuilder().createMoveValue(getOpLocation(Inst->getLoc()),
1725+
getOpValue(Inst->getOperand())));
1726+
}
1727+
17201728
template <typename ImplClass>
17211729
void SILCloner<ImplClass>::visitReleaseValueInst(ReleaseValueInst *Inst) {
17221730
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));

include/swift/SIL/SILInstruction.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7321,6 +7321,15 @@ class DestroyValueInst
73217321
}
73227322
};
73237323

7324+
class MoveValueInst
7325+
: public UnaryInstructionBase<SILInstructionKind::MoveValueInst,
7326+
SingleValueInstruction> {
7327+
friend class SILBuilder;
7328+
7329+
MoveValueInst(SILDebugLocation DebugLoc, SILValue operand)
7330+
: UnaryInstructionBase(DebugLoc, operand, operand->getType()) {}
7331+
};
7332+
73247333
/// Given an object reference, return true iff it is non-nil and refers
73257334
/// to a native swift object with strong reference count of 1.
73267335
class IsUniqueInst

include/swift/SIL/SILNodes.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,10 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
587587
#include "swift/AST/ReferenceStorage.def"
588588
SINGLE_VALUE_INST(UncheckedOwnershipConversionInst, unchecked_ownership_conversion,
589589
SingleValueInstruction, None, MayRelease)
590+
// A move_value is an OSSA only instruction. Its result does not have any side
591+
// effects relative to other OSSA values like copy_value.
592+
SINGLE_VALUE_INST(MoveValueInst, move_value,
593+
SingleValueInstruction, None, DoesNotRelease)
590594

591595
// IsUnique does not actually write to memory but should be modeled
592596
// as such. Its operand is a pointer to an object reference. The

lib/IRGen/IRGenSIL.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,10 @@ class IRGenSILFunction :
11491149
void visitRetainValueInst(RetainValueInst *i);
11501150
void visitRetainValueAddrInst(RetainValueAddrInst *i);
11511151
void visitCopyValueInst(CopyValueInst *i);
1152+
void visitMoveValueInst(MoveValueInst *i) {
1153+
auto e = getLoweredExplosion(i->getOperand());
1154+
setLoweredExplosion(i, e);
1155+
}
11521156
void visitReleaseValueInst(ReleaseValueInst *i);
11531157
void visitReleaseValueAddrInst(ReleaseValueAddrInst *i);
11541158
void visitDestroyValueInst(DestroyValueInst *i);

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,9 @@ OPERAND_OWNERSHIP(DestroyingConsume, EndLifetime)
249249
OPERAND_OWNERSHIP(DestroyingConsume, BeginCOWMutation)
250250
OPERAND_OWNERSHIP(DestroyingConsume, EndCOWMutation)
251251

252+
// TODO: Should this be a forwarding consume.
253+
OPERAND_OWNERSHIP(DestroyingConsume, MoveValue)
254+
252255
// Instructions that move an owned value.
253256
OPERAND_OWNERSHIP(ForwardingConsume, CheckedCastValueBranch)
254257
OPERAND_OWNERSHIP(ForwardingConsume, UnconditionalCheckedCastValue)

lib/SIL/IR/SILPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1826,6 +1826,10 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
18261826
*this << getIDAndType(I->getOperand());
18271827
}
18281828

1829+
void visitMoveValueInst(MoveValueInst *I) {
1830+
*this << getIDAndType(I->getOperand());
1831+
}
1832+
18291833
#define UNCHECKED_REF_STORAGE(Name, ...) \
18301834
void visitStrongCopy##Name##ValueInst(StrongCopy##Name##ValueInst *I) { \
18311835
*this << getIDAndType(I->getOperand()); \

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ CONSTANT_OWNERSHIP_INST(None, AllocValueBuffer)
7474
CONSTANT_OWNERSHIP_INST(Owned, CopyBlock)
7575
CONSTANT_OWNERSHIP_INST(Owned, CopyBlockWithoutEscaping)
7676
CONSTANT_OWNERSHIP_INST(Owned, CopyValue)
77+
CONSTANT_OWNERSHIP_INST(Owned, MoveValue)
7778
CONSTANT_OWNERSHIP_INST(Owned, EndCOWMutation)
7879
CONSTANT_OWNERSHIP_INST(Owned, KeyPath)
7980
CONSTANT_OWNERSHIP_INST(Owned, InitExistentialValue)

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3113,6 +3113,7 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
31133113
UNARY_INSTRUCTION(IsUnique)
31143114
UNARY_INSTRUCTION(DestroyAddr)
31153115
UNARY_INSTRUCTION(CopyValue)
3116+
UNARY_INSTRUCTION(MoveValue)
31163117
UNARY_INSTRUCTION(EndBorrow)
31173118
UNARY_INSTRUCTION(DestructureStruct)
31183119
UNARY_INSTRUCTION(DestructureTuple)

0 commit comments

Comments
 (0)