Skip to content

Commit 804e3f0

Browse files
authored
Merge pull request #61126 from meg-gupta/fixdce
Don't shrink escaped borrow scopes in DCE
2 parents 1894a58 + 88782ac commit 804e3f0

File tree

4 files changed

+89
-1
lines changed

4 files changed

+89
-1
lines changed

include/swift/SIL/OwnershipUtils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ inline bool isForwardingConsume(SILValue value) {
7878
return canOpcodeForwardOwnedValues(value);
7979
}
8080

81+
bool hasEscaped(BorrowedValue value);
82+
8183
/// Find leaf "use points" of \p guaranteedValue that determine its lifetime
8284
/// requirement. Return true if no PointerEscape use was found.
8385
///

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,62 @@
2525

2626
using namespace swift;
2727

28+
bool swift::hasEscaped(BorrowedValue value) {
29+
GraphNodeWorklist<Operand *, 8> worklist;
30+
for (Operand *use : value->getUses()) {
31+
if (use->getOperandOwnership() != OperandOwnership::NonUse)
32+
worklist.insert(use);
33+
}
34+
35+
while (Operand *op = worklist.pop()) {
36+
switch (op->getOperandOwnership()) {
37+
case OperandOwnership::NonUse:
38+
case OperandOwnership::TrivialUse:
39+
case OperandOwnership::ForwardingConsume:
40+
case OperandOwnership::DestroyingConsume:
41+
llvm_unreachable("this operand cannot handle an inner guaranteed use");
42+
43+
case OperandOwnership::ForwardingUnowned:
44+
case OperandOwnership::PointerEscape:
45+
case OperandOwnership::BitwiseEscape:
46+
return true;
47+
48+
case OperandOwnership::Borrow:
49+
case OperandOwnership::EndBorrow:
50+
case OperandOwnership::InstantaneousUse:
51+
case OperandOwnership::UnownedInstantaneousUse:
52+
case OperandOwnership::InteriorPointer:
53+
break;
54+
55+
case OperandOwnership::Reborrow: {
56+
SILArgument *phi = cast<BranchInst>(op->getUser())
57+
->getDestBB()
58+
->getArgument(op->getOperandNumber());
59+
for (auto *use : phi->getUses()) {
60+
if (use->getOperandOwnership() != OperandOwnership::NonUse)
61+
worklist.insert(use);
62+
}
63+
break;
64+
}
65+
case OperandOwnership::ForwardingBorrow: {
66+
ForwardingOperand(op).visitForwardedValues([&](SILValue result) {
67+
// Do not include transitive uses with 'none' ownership
68+
if (result->getOwnershipKind() == OwnershipKind::None)
69+
return true;
70+
for (auto *resultUse : result->getUses()) {
71+
if (resultUse->getOperandOwnership() != OperandOwnership::NonUse) {
72+
worklist.insert(resultUse);
73+
}
74+
}
75+
return true;
76+
});
77+
break;
78+
}
79+
}
80+
}
81+
return false;
82+
}
83+
2884
bool swift::isValueAddressOrTrivial(SILValue v) {
2985
return v->getType().isAddress() ||
3086
v->getOwnershipKind() == OwnershipKind::None;

lib/SILOptimizer/Transforms/DeadCodeElimination.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,15 @@ void DCE::markLive() {
301301
}
302302
continue;
303303
}
304-
// If not populate reborrowDependencies for this borrow
304+
// Populate reborrowDependencies for this borrow
305305
findReborrowDependencies(borrowInst);
306+
if (hasEscaped(BorrowedValue(borrowInst))) {
307+
// Visit all end_borrows and mark them live
308+
visitTransitiveEndBorrows(borrowInst, [&](EndBorrowInst *endBorrow) {
309+
markInstructionLive(endBorrow);
310+
});
311+
continue;
312+
}
306313
break;
307314
}
308315
default:

test/SILOptimizer/dead_code_elimination_nontrivial_ossa.sil

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,3 +972,26 @@ bb0(%0 : $@sil_unmanaged AnyObject):
972972
%242 = tuple ()
973973
return %242 : $()
974974
}
975+
976+
sil @foo : $@convention(thin) () -> ()
977+
978+
// CHECK-LABEL: sil [ossa] @test_escape : {{.*}} {
979+
// CHECK: br bb1
980+
// CHECK: end_borrow
981+
// CHECK-LABEL: } // end sil function 'test_escape'
982+
sil [ossa] @test_escape : $@convention(thin) () -> () {
983+
bb0:
984+
%13 = function_ref @foo : $@convention(thin) () -> ()
985+
%14 = partial_apply [callee_guaranteed] %13() : $@convention(thin) () -> ()
986+
%15 = convert_escape_to_noescape %14 : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
987+
%17 = begin_borrow %14 : $@callee_guaranteed () -> ()
988+
%18 = mark_dependence %15 : $@noescape @callee_guaranteed () -> () on %17 : $@callee_guaranteed () -> ()
989+
br bb1(%18 : $@noescape @callee_guaranteed () -> (), %17 : $@callee_guaranteed () -> (), %14 : $@callee_guaranteed () -> ())
990+
991+
bb1(%21 : $@noescape @callee_guaranteed () -> (), %22 : @guaranteed $@callee_guaranteed () -> (), %23 : @owned $@callee_guaranteed () -> ()):
992+
%27 = apply %21() : $@noescape @callee_guaranteed () -> ()
993+
end_borrow %22 : $@callee_guaranteed () -> ()
994+
destroy_value %23 : $@callee_guaranteed () -> ()
995+
%28 = tuple ()
996+
return %28: $()
997+
}

0 commit comments

Comments
 (0)