Skip to content

Commit 126d1e4

Browse files
committed
[silgen] Fix tuple initialization to use destructures instead of borrow+extract+copy.
rdar://43493020
1 parent 2686f4a commit 126d1e4

File tree

3 files changed

+17
-31
lines changed

3 files changed

+17
-31
lines changed

lib/SILGen/SILGenDecl.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,21 +90,20 @@ static void copyOrInitValueIntoHelper(
9090
void TupleInitialization::copyOrInitValueInto(SILGenFunction &SGF,
9191
SILLocation loc,
9292
ManagedValue value, bool isInit) {
93-
// In the object case, we perform a borrow + extract + copy sequence. This is
94-
// because we do not have a destructure operation.
93+
// In the object case, emit a destructure operation and return.
9594
if (value.getType().isObject()) {
96-
value = value.borrow(SGF, loc);
97-
return copyOrInitValueIntoHelper(
98-
SGF, loc, value, isInit, SubInitializations,
99-
[&](ManagedValue aggregate, unsigned i,
100-
SILType fieldType) -> ManagedValue {
101-
auto elt = SGF.B.createTupleExtract(loc, aggregate, i, fieldType);
102-
return SGF.B.createCopyValue(loc, elt);
95+
return SGF.B.emitDestructureValueOperation(
96+
loc, value, [&](unsigned i, ManagedValue subValue) {
97+
auto &subInit = SubInitializations[i];
98+
subInit->copyOrInitValueInto(SGF, loc, subValue, isInit);
99+
subInit->finishInitialization(SGF);
103100
});
104101
}
105102

106-
// In the address case, we can support takes directly, so forward the cleanup
107-
// of the aggregate and create takes of the underlying addresses.
103+
// In the address case, we forward the underlying value and store it
104+
// into memory and then create a +1 cleanup. since we assume here
105+
// that we have a +1 value since we are forwarding into memory.
106+
assert(value.isPlusOne(SGF) && "Can not store a +0 value into memory?!");
108107
value = ManagedValue::forUnmanaged(value.forward(SGF));
109108
return copyOrInitValueIntoHelper(
110109
SGF, loc, value, isInit, SubInitializations,

test/SILGen/indirect_enum.swift

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -343,18 +343,12 @@ func guardTreeA<T>(_ tree: TreeA<T>) {
343343
// CHECK: [[VALUE_ADDR:%.*]] = project_box [[BOX]]
344344
// CHECK: [[TUPLE:%.*]] = load [take] [[VALUE_ADDR]]
345345
// CHECK: [[TUPLE_COPY:%.*]] = copy_value [[TUPLE]]
346-
// CHECK: [[BORROWED_TUPLE_COPY:%.*]] = begin_borrow [[TUPLE_COPY]]
347-
// CHECK: [[L:%.*]] = tuple_extract [[BORROWED_TUPLE_COPY]]
348-
// CHECK: [[COPY_L:%.*]] = copy_value [[L]]
349-
// CHECK: [[R:%.*]] = tuple_extract [[BORROWED_TUPLE_COPY]]
350-
// CHECK: [[COPY_R:%.*]] = copy_value [[R]]
351-
// CHECK: end_borrow [[BORROWED_TUPLE_COPY]] from [[TUPLE_COPY]]
352-
// CHECK: destroy_value [[TUPLE_COPY]]
346+
// CHECK: ([[L:%.*]], [[R:%.*]]) = destructure_tuple [[TUPLE_COPY]]
353347
// CHECK: destroy_value [[BOX]]
354348
guard case .Branch(left: let l, right: let r) = tree else { return }
355349

356-
// CHECK: destroy_value [[COPY_R]]
357-
// CHECK: destroy_value [[COPY_L]]
350+
// CHECK: destroy_value [[R]]
351+
// CHECK: destroy_value [[L]]
358352
// CHECK: destroy_addr [[X]]
359353
}
360354

@@ -390,16 +384,10 @@ func guardTreeA<T>(_ tree: TreeA<T>) {
390384
// CHECK: [[VALUE_ADDR:%.*]] = project_box [[BOX]]
391385
// CHECK: [[TUPLE:%.*]] = load [take] [[VALUE_ADDR]]
392386
// CHECK: [[TUPLE_COPY:%.*]] = copy_value [[TUPLE]]
393-
// CHECK: [[BORROWED_TUPLE_COPY:%.*]] = begin_borrow [[TUPLE_COPY]]
394-
// CHECK: [[L:%.*]] = tuple_extract [[BORROWED_TUPLE_COPY]]
395-
// CHECK: [[COPY_L:%.*]] = copy_value [[L]]
396-
// CHECK: [[R:%.*]] = tuple_extract [[BORROWED_TUPLE_COPY]]
397-
// CHECK: [[COPY_R:%.*]] = copy_value [[R]]
398-
// CHECK: end_borrow [[BORROWED_TUPLE_COPY]] from [[TUPLE_COPY]]
399-
// CHECK: destroy_value [[TUPLE_COPY]]
387+
// CHECK: ([[L:%.*]], [[R:%.*]]) = destructure_tuple [[TUPLE_COPY]]
400388
// CHECK: destroy_value [[BOX]]
401-
// CHECK: destroy_value [[COPY_R]]
402-
// CHECK: destroy_value [[COPY_L]]
389+
// CHECK: destroy_value [[R]]
390+
// CHECK: destroy_value [[L]]
403391
if case .Branch(left: let l, right: let r) = tree { }
404392
}
405393
}

test/SILGen/statements.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -686,9 +686,8 @@ func let_else_tuple_binding(_ a : (Int, Int)?) -> Int {
686686
return x
687687

688688
// CHECK: [[SOME_BB]]([[PAYLOAD:%.*]] : @trivial $(Int, Int)):
689-
// CHECK-NEXT: [[PAYLOAD_1:%.*]] = tuple_extract [[PAYLOAD]] : $(Int, Int), 0
689+
// CHECK-NEXT: ([[PAYLOAD_1:%.*]], [[PAYLOAD_2:%.*]]) = destructure_tuple [[PAYLOAD]]
690690
// CHECK-NEXT: debug_value [[PAYLOAD_1]] : $Int, let, name "x"
691-
// CHECK-NEXT: [[PAYLOAD_2:%.*]] = tuple_extract [[PAYLOAD]] : $(Int, Int), 1
692691
// CHECK-NEXT: debug_value [[PAYLOAD_2]] : $Int, let, name "y"
693692
// CHECK-NEXT: br [[CONT_BB:bb[0-9]+]]
694693
// CHECK: [[CONT_BB]]:

0 commit comments

Comments
 (0)