Skip to content

Commit

Permalink
[silgen] Fix tuple initialization to use destructures instead of borr…
Browse files Browse the repository at this point in the history
…ow+extract+copy.

rdar://43493020
  • Loading branch information
gottesmm committed Aug 21, 2018
1 parent 2686f4a commit 126d1e4
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 31 deletions.
21 changes: 10 additions & 11 deletions lib/SILGen/SILGenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,21 +90,20 @@ static void copyOrInitValueIntoHelper(
void TupleInitialization::copyOrInitValueInto(SILGenFunction &SGF,
SILLocation loc,
ManagedValue value, bool isInit) {
// In the object case, we perform a borrow + extract + copy sequence. This is
// because we do not have a destructure operation.
// In the object case, emit a destructure operation and return.
if (value.getType().isObject()) {
value = value.borrow(SGF, loc);
return copyOrInitValueIntoHelper(
SGF, loc, value, isInit, SubInitializations,
[&](ManagedValue aggregate, unsigned i,
SILType fieldType) -> ManagedValue {
auto elt = SGF.B.createTupleExtract(loc, aggregate, i, fieldType);
return SGF.B.createCopyValue(loc, elt);
return SGF.B.emitDestructureValueOperation(
loc, value, [&](unsigned i, ManagedValue subValue) {
auto &subInit = SubInitializations[i];
subInit->copyOrInitValueInto(SGF, loc, subValue, isInit);
subInit->finishInitialization(SGF);
});
}

// In the address case, we can support takes directly, so forward the cleanup
// of the aggregate and create takes of the underlying addresses.
// In the address case, we forward the underlying value and store it
// into memory and then create a +1 cleanup. since we assume here
// that we have a +1 value since we are forwarding into memory.
assert(value.isPlusOne(SGF) && "Can not store a +0 value into memory?!");
value = ManagedValue::forUnmanaged(value.forward(SGF));
return copyOrInitValueIntoHelper(
SGF, loc, value, isInit, SubInitializations,
Expand Down
24 changes: 6 additions & 18 deletions test/SILGen/indirect_enum.swift
Original file line number Diff line number Diff line change
Expand Up @@ -343,18 +343,12 @@ func guardTreeA<T>(_ tree: TreeA<T>) {
// CHECK: [[VALUE_ADDR:%.*]] = project_box [[BOX]]
// CHECK: [[TUPLE:%.*]] = load [take] [[VALUE_ADDR]]
// CHECK: [[TUPLE_COPY:%.*]] = copy_value [[TUPLE]]
// CHECK: [[BORROWED_TUPLE_COPY:%.*]] = begin_borrow [[TUPLE_COPY]]
// CHECK: [[L:%.*]] = tuple_extract [[BORROWED_TUPLE_COPY]]
// CHECK: [[COPY_L:%.*]] = copy_value [[L]]
// CHECK: [[R:%.*]] = tuple_extract [[BORROWED_TUPLE_COPY]]
// CHECK: [[COPY_R:%.*]] = copy_value [[R]]
// CHECK: end_borrow [[BORROWED_TUPLE_COPY]] from [[TUPLE_COPY]]
// CHECK: destroy_value [[TUPLE_COPY]]
// CHECK: ([[L:%.*]], [[R:%.*]]) = destructure_tuple [[TUPLE_COPY]]
// CHECK: destroy_value [[BOX]]
guard case .Branch(left: let l, right: let r) = tree else { return }

// CHECK: destroy_value [[COPY_R]]
// CHECK: destroy_value [[COPY_L]]
// CHECK: destroy_value [[R]]
// CHECK: destroy_value [[L]]
// CHECK: destroy_addr [[X]]
}

Expand Down Expand Up @@ -390,16 +384,10 @@ func guardTreeA<T>(_ tree: TreeA<T>) {
// CHECK: [[VALUE_ADDR:%.*]] = project_box [[BOX]]
// CHECK: [[TUPLE:%.*]] = load [take] [[VALUE_ADDR]]
// CHECK: [[TUPLE_COPY:%.*]] = copy_value [[TUPLE]]
// CHECK: [[BORROWED_TUPLE_COPY:%.*]] = begin_borrow [[TUPLE_COPY]]
// CHECK: [[L:%.*]] = tuple_extract [[BORROWED_TUPLE_COPY]]
// CHECK: [[COPY_L:%.*]] = copy_value [[L]]
// CHECK: [[R:%.*]] = tuple_extract [[BORROWED_TUPLE_COPY]]
// CHECK: [[COPY_R:%.*]] = copy_value [[R]]
// CHECK: end_borrow [[BORROWED_TUPLE_COPY]] from [[TUPLE_COPY]]
// CHECK: destroy_value [[TUPLE_COPY]]
// CHECK: ([[L:%.*]], [[R:%.*]]) = destructure_tuple [[TUPLE_COPY]]
// CHECK: destroy_value [[BOX]]
// CHECK: destroy_value [[COPY_R]]
// CHECK: destroy_value [[COPY_L]]
// CHECK: destroy_value [[R]]
// CHECK: destroy_value [[L]]
if case .Branch(left: let l, right: let r) = tree { }
}
}
Expand Down
3 changes: 1 addition & 2 deletions test/SILGen/statements.swift
Original file line number Diff line number Diff line change
Expand Up @@ -686,9 +686,8 @@ func let_else_tuple_binding(_ a : (Int, Int)?) -> Int {
return x

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

0 comments on commit 126d1e4

Please sign in to comment.