Skip to content

Commit 70ab38d

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 }
1 parent 65a9ba4 commit 70ab38d

25 files changed

+226
-16
lines changed

include/swift/AST/DiagnosticsParse.def

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

919921
// SIL function types
920922
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
@@ -1413,6 +1413,12 @@ class SILBuilder {
14131413
CopyableToMoveOnlyWrapperValueInst::Guaranteed));
14141414
}
14151415

1416+
MoveOnlyWrapperToCopyableBoxInst *
1417+
createMoveOnlyWrapperToCopyableBox(SILLocation loc, SILValue src) {
1418+
return insert(new (getModule()) MoveOnlyWrapperToCopyableBoxInst(
1419+
getSILDebugLocation(loc), src, src->getOwnershipKind()));
1420+
}
1421+
14161422
MoveOnlyWrapperToCopyableAddrInst *
14171423
createMoveOnlyWrapperToCopyableAddr(SILLocation loc, SILValue src) {
14181424
return insert(new (getModule()) MoveOnlyWrapperToCopyableAddrInst(

include/swift/SIL/SILCloner.h

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

1944+
template <typename ImplClass>
1945+
void SILCloner<ImplClass>::visitMoveOnlyWrapperToCopyableBoxInst(
1946+
MoveOnlyWrapperToCopyableBoxInst *inst) {
1947+
getBuilder().setCurrentDebugScope(getOpScope(inst->getDebugScope()));
1948+
recordClonedInstruction(
1949+
inst, getBuilder().createMoveOnlyWrapperToCopyableBox(
1950+
getOpLocation(inst->getLoc()), getOpValue(inst->getOperand())));
1951+
}
1952+
19441953
template <typename ImplClass>
19451954
void SILCloner<ImplClass>::visitMoveOnlyWrapperToCopyableAddrInst(
19461955
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:
@@ -8574,6 +8575,29 @@ class MoveOnlyWrapperToCopyableValueInst
85748575
InitialKind getInitialKind() const { return initialKind; }
85758576
};
85768577

8578+
/// Convert a ${ @moveOnly T } to $T. This is a forwarding instruction that acts
8579+
/// similarly to an object cast like upcast, unlike
8580+
/// MoveOnlyWrapperToCopyableValue which provides artificial semantics injected
8581+
/// by SILGen.
8582+
class MoveOnlyWrapperToCopyableBoxInst
8583+
: public UnaryInstructionBase<
8584+
SILInstructionKind::MoveOnlyWrapperToCopyableBoxInst,
8585+
FirstArgOwnershipForwardingSingleValueInst> {
8586+
friend class SILBuilder;
8587+
8588+
MoveOnlyWrapperToCopyableBoxInst(SILDebugLocation DebugLoc, SILValue operand,
8589+
ValueOwnershipKind forwardingOwnershipKind)
8590+
: UnaryInstructionBase(
8591+
DebugLoc, operand,
8592+
operand->getType().removingMoveOnlyWrapperToBoxedType(
8593+
operand->getFunction()),
8594+
forwardingOwnershipKind) {
8595+
assert(
8596+
operand->getType().isBoxedMoveOnlyWrappedType(operand->getFunction()) &&
8597+
"Expected moveonlywrapped argument!");
8598+
}
8599+
};
8600+
85778601
class CopyableToMoveOnlyWrapperAddrInst
85788602
: public UnaryInstructionBase<
85798603
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
@@ -757,8 +757,8 @@ class SILType {
757757
return getRawASTType()->is<SILMoveOnlyWrappedType>();
758758
}
759759

760-
/// If this is already a move only wrapped type, return *this. Otherwise, wrap
761-
/// the copyable type in the mov eonly wrapper.
760+
/// If this is already a moveonlywrapped type, return *this. Otherwise, wrap
761+
/// the copyable type in the moveonlywrapper.
762762
SILType addingMoveOnlyWrapper() const {
763763
if (isMoveOnlyWrapped())
764764
return *this;
@@ -785,6 +785,20 @@ class SILType {
785785
return *this;
786786
}
787787

788+
/// If this is a box type containing a moveonlywrapped type, return a new box
789+
/// with the moveonlywrapped type unwrapped.
790+
///
791+
/// DISCUSSION: This is separate from addingMoveOnlyWrapper since this API
792+
/// requires a SILFunction * and is specialized.
793+
SILType addingMoveOnlyWrapperToBoxedType(const SILFunction *fn);
794+
795+
/// If this is a box type containing a copyable type, return a new box type
796+
/// with the copyable type wrapped in a moveonly wrapped type.
797+
///
798+
/// DISCUSSION: This is separate from removingMoveOnlyWrapper since this API
799+
/// requires a SILFunction * and is specialized.
800+
SILType removingMoveOnlyWrapperToBoxedType(const SILFunction *fn);
801+
788802
/// Returns a SILType with any archetypes mapped out of context.
789803
SILType mapTypeOutOfContext() const;
790804

@@ -835,6 +849,12 @@ class SILType {
835849
return isBoxedNonCopyableType(&fn);
836850
}
837851

852+
bool isBoxedMoveOnlyWrappedType(const SILFunction *fn) const {
853+
if (!this->is<SILBoxType>())
854+
return false;
855+
return getSILBoxFieldType(fn).isMoveOnlyWrapped();
856+
}
857+
838858
SILType getInstanceTypeOfMetatype(SILFunction *function) const;
839859

840860
bool isOrContainsObjectiveCClass() const;

include/swift/SIL/SILValue.h

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

lib/IRGen/IRGenSIL.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,6 +1270,10 @@ class IRGenSILFunction :
12701270
setLoweredExplosion(i, e);
12711271
}
12721272
void
1273+
visitMoveOnlyWrapperToCopyableBoxInst(MoveOnlyWrapperToCopyableBoxInst *i) {
1274+
llvm_unreachable("OSSA instruction");
1275+
}
1276+
void
12731277
visitMoveOnlyWrapperToCopyableAddrInst(MoveOnlyWrapperToCopyableAddrInst *i) {
12741278
auto e = getLoweredExplosion(i->getOperand());
12751279
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
@@ -2494,6 +2494,10 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
24942494
MoveOnlyWrapperToCopyableAddrInst *BAI) {
24952495
*this << getIDAndType(BAI->getOperand());
24962496
}
2497+
void
2498+
visitMoveOnlyWrapperToCopyableBoxInst(MoveOnlyWrapperToCopyableBoxInst *BAI) {
2499+
*this << getIDAndType(BAI->getOperand());
2500+
}
24972501
void visitCopyableToMoveOnlyWrapperAddrInst(
24982502
CopyableToMoveOnlyWrapperAddrInst *BAI) {
24992503
*this << getIDAndType(BAI->getOperand());

0 commit comments

Comments
 (0)