Skip to content

Commit ae2e714

Browse files
committed
[move-only] Add a new instruction: moveonlywrapper_to_copyable_box.
I am going to use this to unwrap ${ @moveOnly T } so that I can pass it to partial_apply that expect a ${ T } (cherry picked from commit 70ab38d) Conflicts: lib/SIL/IR/SILType.cpp lib/Serialization/ModuleFormat.h test/SIL/Parser/basic2.sil
1 parent 18b4d67 commit ae2e714

24 files changed

+225
-16
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,8 @@ ERROR(sil_box_expected_r_brace,none,
914914
"expected '}' to complete SIL box field type list", ())
915915
ERROR(sil_box_expected_r_angle,none,
916916
"expected '>' to complete SIL box generic argument list", ())
917+
ERROR(sil_box_expected,none,
918+
"%0 expects its operand to be of SIL box field type", (StringRef))
917919

918920
// SIL function types
919921
ERROR(sil_function_subst_expected_l_angle,none,

include/swift/SIL/SILBuilder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,6 +1410,12 @@ class SILBuilder {
14101410
CopyableToMoveOnlyWrapperValueInst::Guaranteed));
14111411
}
14121412

1413+
MoveOnlyWrapperToCopyableBoxInst *
1414+
createMoveOnlyWrapperToCopyableBox(SILLocation loc, SILValue src) {
1415+
return insert(new (getModule()) MoveOnlyWrapperToCopyableBoxInst(
1416+
getSILDebugLocation(loc), src, src->getOwnershipKind()));
1417+
}
1418+
14131419
MoveOnlyWrapperToCopyableAddrInst *
14141420
createMoveOnlyWrapperToCopyableAddr(SILLocation loc, SILValue src) {
14151421
return insert(new (getModule()) MoveOnlyWrapperToCopyableAddrInst(

include/swift/SIL/SILCloner.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,6 +1942,15 @@ void SILCloner<ImplClass>::visitMoveOnlyWrapperToCopyableValueInst(
19421942
recordClonedInstruction(inst, cvt);
19431943
}
19441944

1945+
template <typename ImplClass>
1946+
void SILCloner<ImplClass>::visitMoveOnlyWrapperToCopyableBoxInst(
1947+
MoveOnlyWrapperToCopyableBoxInst *inst) {
1948+
getBuilder().setCurrentDebugScope(getOpScope(inst->getDebugScope()));
1949+
recordClonedInstruction(
1950+
inst, getBuilder().createMoveOnlyWrapperToCopyableBox(
1951+
getOpLocation(inst->getLoc()), getOpValue(inst->getOperand())));
1952+
}
1953+
19451954
template <typename ImplClass>
19461955
void SILCloner<ImplClass>::visitMoveOnlyWrapperToCopyableAddrInst(
19471956
MoveOnlyWrapperToCopyableAddrInst *inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,7 @@ FirstArgOwnershipForwardingSingleValueInst::classof(SILInstructionKind kind) {
13971397
case SILInstructionKind::InitExistentialRefInst:
13981398
case SILInstructionKind::MarkDependenceInst:
13991399
case SILInstructionKind::MoveOnlyWrapperToCopyableValueInst:
1400+
case SILInstructionKind::MoveOnlyWrapperToCopyableBoxInst:
14001401
case SILInstructionKind::CopyableToMoveOnlyWrapperValueInst:
14011402
return true;
14021403
default:
@@ -8540,6 +8541,29 @@ class MoveOnlyWrapperToCopyableValueInst
85408541
InitialKind getInitialKind() const { return initialKind; }
85418542
};
85428543

8544+
/// Convert a ${ @moveOnly T } to $T. This is a forwarding instruction that acts
8545+
/// similarly to an object cast like upcast, unlike
8546+
/// MoveOnlyWrapperToCopyableValue which provides artificial semantics injected
8547+
/// by SILGen.
8548+
class MoveOnlyWrapperToCopyableBoxInst
8549+
: public UnaryInstructionBase<
8550+
SILInstructionKind::MoveOnlyWrapperToCopyableBoxInst,
8551+
FirstArgOwnershipForwardingSingleValueInst> {
8552+
friend class SILBuilder;
8553+
8554+
MoveOnlyWrapperToCopyableBoxInst(SILDebugLocation DebugLoc, SILValue operand,
8555+
ValueOwnershipKind forwardingOwnershipKind)
8556+
: UnaryInstructionBase(
8557+
DebugLoc, operand,
8558+
operand->getType().removingMoveOnlyWrapperToBoxedType(
8559+
operand->getFunction()),
8560+
forwardingOwnershipKind) {
8561+
assert(
8562+
operand->getType().isBoxedMoveOnlyWrappedType(operand->getFunction()) &&
8563+
"Expected moveonlywrapped argument!");
8564+
}
8565+
};
8566+
85438567
class CopyableToMoveOnlyWrapperAddrInst
85448568
: public UnaryInstructionBase<
85458569
SILInstructionKind::CopyableToMoveOnlyWrapperAddrInst,

include/swift/SIL/SILNodes.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,11 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
496496
SINGLE_VALUE_INST(MoveOnlyWrapperToCopyableValueInst,
497497
moveonlywrapper_to_copyable, SingleValueInstruction, None,
498498
DoesNotRelease)
499+
// Convert a ${ @moveOnly T } to $T. This is a forwarding instruction that
500+
// acts similarly to an object cast, unlike MoveOnlyWrapperToCopyableValue.
501+
SINGLE_VALUE_INST(MoveOnlyWrapperToCopyableBoxInst,
502+
moveonlywrapper_to_copyable_box, SingleValueInstruction, None,
503+
DoesNotRelease)
499504
// Convert a $*@moveOnly T to $*T. Acts just as a cast.
500505
SINGLE_VALUE_INST(MoveOnlyWrapperToCopyableAddrInst,
501506
moveonlywrapper_to_copyable_addr, SingleValueInstruction,

include/swift/SIL/SILType.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -721,8 +721,8 @@ class SILType {
721721
return getRawASTType()->is<SILMoveOnlyWrappedType>();
722722
}
723723

724-
/// If this is already a move only wrapped type, return *this. Otherwise, wrap
725-
/// the copyable type in the mov eonly wrapper.
724+
/// If this is already a moveonlywrapped type, return *this. Otherwise, wrap
725+
/// the copyable type in the moveonlywrapper.
726726
SILType addingMoveOnlyWrapper() const {
727727
if (isMoveOnlyWrapped())
728728
return *this;
@@ -749,6 +749,20 @@ class SILType {
749749
return *this;
750750
}
751751

752+
/// If this is a box type containing a moveonlywrapped type, return a new box
753+
/// with the moveonlywrapped type unwrapped.
754+
///
755+
/// DISCUSSION: This is separate from addingMoveOnlyWrapper since this API
756+
/// requires a SILFunction * and is specialized.
757+
SILType addingMoveOnlyWrapperToBoxedType(const SILFunction *fn);
758+
759+
/// If this is a box type containing a copyable type, return a new box type
760+
/// with the copyable type wrapped in a moveonly wrapped type.
761+
///
762+
/// DISCUSSION: This is separate from removingMoveOnlyWrapper since this API
763+
/// requires a SILFunction * and is specialized.
764+
SILType removingMoveOnlyWrapperToBoxedType(const SILFunction *fn);
765+
752766
/// Returns a SILType with any archetypes mapped out of context.
753767
SILType mapTypeOutOfContext() const;
754768

@@ -799,6 +813,12 @@ class SILType {
799813
return isBoxedNonCopyableType(&fn);
800814
}
801815

816+
bool isBoxedMoveOnlyWrappedType(const SILFunction *fn) const {
817+
if (!this->is<SILBoxType>())
818+
return false;
819+
return getSILBoxFieldType(fn).isMoveOnlyWrapped();
820+
}
821+
802822
SILType getInstanceTypeOfMetatype(SILFunction *function) const;
803823

804824
bool isOrContainsObjectiveCClass() const;

include/swift/SIL/SILValue.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -576,10 +576,15 @@ class ValueBase : public SILNode, public SILAllocated<ValueBase> {
576576
///
577577
/// NOTE: Please do not use this directly! It is only meant to be used by the
578578
/// optimizer pass: SILMoveOnlyWrappedTypeEliminator.
579-
bool unsafelyEliminateMoveOnlyWrapper() {
580-
if (!Type.isMoveOnlyWrapped())
579+
bool unsafelyEliminateMoveOnlyWrapper(const SILFunction *fn) {
580+
if (!Type.isMoveOnlyWrapped() && !Type.isBoxedMoveOnlyWrappedType(fn))
581581
return false;
582-
Type = Type.removingMoveOnlyWrapper();
582+
if (Type.isMoveOnlyWrapped()) {
583+
Type = Type.removingMoveOnlyWrapper();
584+
} else {
585+
assert(Type.isBoxedMoveOnlyWrappedType(fn));
586+
Type = Type.removingMoveOnlyWrapperToBoxedType(fn);
587+
}
583588
return true;
584589
}
585590

lib/IRGen/IRGenSIL.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,10 @@ class IRGenSILFunction :
12691269
setLoweredExplosion(i, e);
12701270
}
12711271
void
1272+
visitMoveOnlyWrapperToCopyableBoxInst(MoveOnlyWrapperToCopyableBoxInst *i) {
1273+
llvm_unreachable("OSSA instruction");
1274+
}
1275+
void
12721276
visitMoveOnlyWrapperToCopyableAddrInst(MoveOnlyWrapperToCopyableAddrInst *i) {
12731277
auto e = getLoweredExplosion(i->getOperand());
12741278
setLoweredExplosion(i, e);

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ FORWARDING_OWNERSHIP(MarkMustCheck)
374374
FORWARDING_OWNERSHIP(MarkUnresolvedReferenceBinding)
375375
FORWARDING_OWNERSHIP(MoveOnlyWrapperToCopyableValue)
376376
FORWARDING_OWNERSHIP(CopyableToMoveOnlyWrapperValue)
377+
FORWARDING_OWNERSHIP(MoveOnlyWrapperToCopyableBox)
377378
#undef FORWARDING_OWNERSHIP
378379

379380
// Arbitrary value casts are forwarding instructions that are also allowed to

lib/SIL/IR/SILPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2463,6 +2463,10 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
24632463
MoveOnlyWrapperToCopyableAddrInst *BAI) {
24642464
*this << getIDAndType(BAI->getOperand());
24652465
}
2466+
void
2467+
visitMoveOnlyWrapperToCopyableBoxInst(MoveOnlyWrapperToCopyableBoxInst *BAI) {
2468+
*this << getIDAndType(BAI->getOperand());
2469+
}
24662470
void visitCopyableToMoveOnlyWrapperAddrInst(
24672471
CopyableToMoveOnlyWrapperAddrInst *BAI) {
24682472
*this << getIDAndType(BAI->getOperand());

0 commit comments

Comments
 (0)