Skip to content

Commit 5a71b61

Browse files
committed
[OpaqueValues] Assign tuple into tuple.
In address-lowered mode, to initialize tuple-typed memory in a single step, tuple_addr_constructor must generally be used because it's not possible to construct a tuple any of whose fields are address-only. In opaque values mode, there is no problem constructing such a tuple. So construct the tuple and then assign it into the tuple-typed memory; the single instruction that initializes the memory will be the assign.
1 parent 5db0339 commit 5a71b61

File tree

2 files changed

+59
-5
lines changed

2 files changed

+59
-5
lines changed

lib/SILGen/RValue.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -579,11 +579,22 @@ void RValue::assignInto(SILGenFunction &SGF, SILLocation loc,
579579
assert(destAddr->getType().castTo<TupleType>()->getNumElements() ==
580580
srcTupleType->getNumElements());
581581

582-
// If we do have any srcMvValues, then emit a TupleAddrConstructor. If we do
583-
// not have any, then our tuple must consist only of empty tuples.
584-
if (srcMvValues.size())
585-
SGF.B.createTupleAddrConstructor(loc, destAddr, srcMvValues,
586-
IsNotInitialization);
582+
// If there are sourced managed values, initialize the address with a tuple.
583+
if (srcMvValues.size()) {
584+
if (SGF.useLoweredAddresses()) {
585+
// Without opaque values, a tuple_addr_constructor is used to initialize
586+
// the memory all at once.
587+
SGF.B.createTupleAddrConstructor(loc, destAddr, srcMvValues,
588+
IsNotInitialization);
589+
} else {
590+
// With opaque values, a tuple can always be formed and assigned to the
591+
// memory.
592+
auto tupleTy = destAddr->getType().getObjectType();
593+
auto tuple = SGF.B.createTuple(loc, tupleTy, srcMvValues);
594+
SGF.B.createAssign(loc, tuple.forward(SGF), destAddr,
595+
AssignOwnershipQualifier::Unknown);
596+
}
597+
}
587598
srcMvValues = ArrayRef<ManagedValue>();
588599
}
589600

test/SILGen/opaque_values_silgen.swift

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,3 +823,46 @@ func consumeExprOfLoadExprOfOwnedAddrOnlyLValue<T>(_ ty: T.Type) {
823823
var t = source(ty)
824824
sink(consume t)
825825
}
826+
827+
struct Twople<T> {
828+
var storage: (T, T)
829+
830+
// CHECK-LABEL: sil {{.*}}[ossa] @$s20opaque_values_silgen6TwopleV2t12t2ACyxGx_xtcfC : {{.*}} {
831+
// CHECK: bb0([[T1:%[^,]+]] :
832+
// CHECK-SAME: [[T2:%[^,]+]] :
833+
// CHECK-SAME: ):
834+
// CHECK: [[VAR:%[^,]+]] = alloc_box
835+
// CHECK: [[VAR_UNINIT:%[^,]+]] = mark_uninitialized [rootself] [[VAR]]
836+
// CHECK: [[VAR_LIFETIME:%[^,]+]] = begin_borrow [lexical] [var_decl] [[VAR_UNINIT]]
837+
// CHECK: [[VAR_ADDR:%[^,]+]] = project_box [[VAR_LIFETIME]]
838+
// CHECK: [[T1_BORROW:%[^,]+]] = begin_borrow [[T1]]
839+
// CHECK: [[T1_COPY:%[^,]+]] = copy_value [[T1_BORROW]]
840+
// CHECK: [[T2_BORROW:%[^,]+]] = begin_borrow [[T2]]
841+
// CHECK: [[T2_COPY:%[^,]+]] = copy_value [[T2_BORROW]]
842+
// CHECK: [[VAR_ACCESS:%[^,]+]] = begin_access [modify] [unknown] [[VAR_ADDR]]
843+
// CHECK: [[STORAGE_ACCESS:%[^,]+]] = struct_element_addr [[VAR_ACCESS]]
844+
845+
// In opaque values mode, without regard to the fact that T is
846+
// address-only, a tuple is constructed and assigned into the
847+
// storage.
848+
// CHECK: [[TUPLE:%[^,]+]] = tuple (
849+
// CHECK-SAME: [[T1_COPY]]
850+
// CHECK-SAME: [[T2_COPY]]
851+
// CHECK-SAME: )
852+
// CHECK: assign [[TUPLE]] to [[STORAGE_ACCESS]]
853+
854+
// CHECK: end_access [[VAR_ACCESS]]
855+
// CHECK: end_borrow [[T2_BORROW]]
856+
// CHECK: end_borrow [[T1_BORROW]]
857+
// CHECK: [[RETVAL:%[^,]+]] = load [copy] [[VAR_ADDR]]
858+
// CHECK: destroy_value [[T2]]
859+
// CHECK: destroy_value [[T1]]
860+
// CHECK: end_borrow [[VAR_LIFETIME]]
861+
// CHECK: destroy_value [[VAR_UNINIT]]
862+
// CHECK: return [[RETVAL]]
863+
// CHECK-LABEL: } // end sil function '$s20opaque_values_silgen6TwopleV2t12t2ACyxGx_xtcfC'
864+
@_silgen_name("Twople_init_from_t1_t2")
865+
init(t1: T, t2: T) {
866+
self.storage = (t1, t2)
867+
}
868+
}

0 commit comments

Comments
 (0)