Skip to content

Commit 3d146b8

Browse files
Merge pull request #65686 from nate-chandler/canonicalize-guaranteed-value/dont-hoist-forwards
[CanonicalizeGuaranteedValue] Rewrite forwards in place.
2 parents 6877778 + ea10281 commit 3d146b8

File tree

5 files changed

+67
-5
lines changed

5 files changed

+67
-5
lines changed

include/swift/SILOptimizer/Utils/CanonicalizeBorrowScope.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,12 @@ class CanonicalizeBorrowScope {
142142
assert(borrow && persistentCopies.empty() &&
143143
(!liveness || liveness->empty()));
144144

145+
borrowedValue = BorrowedValue();
146+
defUseWorklist.clear();
147+
blockWorklist.clear();
148+
persistentCopies.clear();
145149
updatedCopies.clear();
150+
146151
borrowedValue = borrow;
147152
if (liveness)
148153
liveness->initializeDef(borrowedValue.value);

include/swift/SILOptimizer/Utils/InstructionDeleter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ class InstructionDeleter {
159159
///
160160
/// Calls callbacks.notifyWillBeDeleted().
161161
bool deleteIfDead(SILInstruction *inst);
162+
bool deleteIfDead(SILInstruction *inst, bool fixLifetime);
162163

163164
/// Delete the instruction \p inst, ignoring its side effects. If any operand
164165
/// definitions will become dead after deleting this instruction, track them

lib/SILOptimizer/Utils/CanonicalizeBorrowScope.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ class RewriteOuterBorrowUses {
601601
}
602602
// If it's not already dead, update this operand bypassing any copies.
603603
SILValue innerValue = use->get();
604-
if (scope.getDeleter().deleteIfDead(user)) {
604+
if (scope.getDeleter().deleteIfDead(user, /*fixLifetime=*/false)) {
605605
LLVM_DEBUG(llvm::dbgs() << " Deleted " << *user);
606606
} else {
607607
use->set(scope.findDefInBorrowScope(use->get()));
@@ -692,7 +692,7 @@ SILValue RewriteOuterBorrowUses::createOuterValues(SILValue innerValue) {
692692

693693
auto incomingOuterVal = createOuterValues(incomingInnerVal);
694694

695-
auto *insertPt = incomingOuterVal->getNextInstruction();
695+
auto *insertPt = innerValue->getDefiningInsertionPoint();
696696
auto *clone = innerInst->clone(insertPt);
697697
scope.getCallbacks().createdNewInst(clone);
698698
Operand *use = &clone->getOperandRef(0);

lib/SILOptimizer/Utils/InstructionDeleter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,10 @@ void InstructionDeleter::cleanupDeadInstructions() {
276276

277277
bool InstructionDeleter::deleteIfDead(SILInstruction *inst) {
278278
bool fixLifetime = inst->getFunction()->hasOwnership();
279+
return deleteIfDead(inst, fixLifetime);
280+
}
281+
282+
bool InstructionDeleter::deleteIfDead(SILInstruction *inst, bool fixLifetime) {
279283
if (isInstructionTriviallyDead(inst)
280284
|| isScopeAffectingInstructionDead(inst, fixLifetime)) {
281285
getCallbacks().notifyWillBeDeleted(inst);

test/SILOptimizer/canonicalize_borrow_scope_unit.sil

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@ typealias AnyObject = Builtin.AnyObject
66

77
class C {}
88
class D : C {}
9+
struct S {
10+
@_hasStorage var guts: SGuts
11+
}
12+
class SGuts {}
913

1014
sil @getD : $() -> (@owned D)
1115
sil @takeC : $(@owned C) -> ()
16+
sil [ossa] @sink : $@convention(thin) <τ_0_0> (@owned τ_0_0) -> ()
1217

1318
struct Unmanaged<Instance> where Instance : AnyObject {
1419
unowned(unsafe) var _value: @sil_unmanaged Instance
@@ -70,10 +75,8 @@ bb0(%instance : @guaranteed $Instance):
7075
// CHECK: [[TAKE_C:%[^,]+]] = function_ref @takeC
7176
// CHECK: [[C:%[^,]+]] = apply [[GET_C]]()
7277
// CHECK: [[OUTER_COPY:%[^,]+]] = copy_value [[C]]
73-
// CHECK: [[OUTER_UPCAST:%[^,]+]] = upcast [[OUTER_COPY]]
7478
// CHECK: [[B:%[^,]+]] = begin_borrow [[C]]
75-
// CHECK: [[DEAD_INNER_COPY:%[^,]+]] = copy_value [[B]]
76-
// CHECK: destroy_value [[DEAD_INNER_COPY]]
79+
// CHECK: [[OUTER_UPCAST:%[^,]+]] = upcast [[OUTER_COPY]]
7780
// CHECK: [[U:%[^,]+]] = upcast [[B]]
7881
// CHECK: [[C1:%[^,]+]] = copy_value [[U]]
7982
// CHECK: apply [[TAKE_C]]([[C1]])
@@ -97,3 +100,52 @@ sil [ossa] @dont_rewrite_inner_forwarding_user : $@convention(thin) () -> (@owne
97100
destroy_value %d : $D
98101
return %u2 : $C
99102
}
103+
104+
// CHECK-LABEL: begin running test {{.*}} on dont_hoist_inner_destructure: canonicalize-borrow-scope
105+
// CHECK-LABEL: sil [ossa] @dont_hoist_inner_destructure : {{.*}} {
106+
// CHECK: {{bb[0-9]+}}([[S:%[^,]+]] :
107+
// CHECK: [[OUTER_COPY:%[^,]+]] = copy_value [[S]]
108+
// CHECK: [[S_BORROW:%[^,]+]] = begin_borrow [[S]]
109+
// CHECK: cond_br undef, [[LEFT:bb[0-9]+]], [[RIGHT:bb[0-9]+]]
110+
// CHECK: [[LEFT]]:
111+
// CHECK: [[INNARDS:%[^,]+]] = destructure_struct [[OUTER_COPY]]
112+
// CHECK: end_borrow [[S_BORROW]]
113+
// CHECK: destroy_value [[INNARDS]]
114+
// CHECK: destroy_value [[S]]
115+
// CHECK: br [[EXIT:bb[0-9]+]]
116+
// CHECK: [[RIGHT]]:
117+
// CHECK: destroy_value [[OUTER_COPY]]
118+
// CHECK: [[SINK:%[^,]+]] = function_ref @sink
119+
// CHECK: [[INNER_COPY:%[^,]+]] = copy_value [[S_BORROW]]
120+
// CHECK: apply [[SINK]]<S>([[INNER_COPY]])
121+
// CHECK: end_borrow [[S_BORROW]]
122+
// CHECK: destroy_value [[S]]
123+
// CHECK: br [[EXIT]]
124+
// CHECK: [[EXIT]]:
125+
// CHECK-LABEL: } // end sil function 'dont_hoist_inner_destructure'
126+
// CHECK-LABEL: end running test {{.*}} on dont_hoist_inner_destructure: canonicalize-borrow-scope
127+
sil [ossa] @dont_hoist_inner_destructure : $@convention(thin) (@owned S) -> () {
128+
entry(%s : @owned $S):
129+
test_specification "canonicalize-borrow-scope @instruction"
130+
%s_borrow = begin_borrow %s : $S
131+
%s_copy = copy_value %s_borrow : $S
132+
cond_br undef, left, right
133+
134+
left:
135+
%innards = destructure_struct %s_copy : $S
136+
end_borrow %s_borrow : $S
137+
destroy_value %innards : $SGuts
138+
destroy_value %s : $S
139+
br exit
140+
141+
right:
142+
%sink = function_ref @sink : $@convention(thin) <τ_0_0> (@owned τ_0_0) -> ()
143+
apply %sink<S>(%s_copy) : $@convention(thin) <τ_0_0> (@owned τ_0_0) -> ()
144+
end_borrow %s_borrow : $S
145+
destroy_value %s : $S
146+
br exit
147+
148+
exit:
149+
%retval = tuple ()
150+
return %retval : $()
151+
}

0 commit comments

Comments
 (0)