Skip to content

Commit 54862c1

Browse files
authored
Merge pull request #64700 from meg-gupta/updatehaspointerescapedce
Support all BorrowedValueKind in hasPointerEscape(BorrowedValue) api
2 parents 5571de1 + a135f4f commit 54862c1

File tree

2 files changed

+43
-54
lines changed

2 files changed

+43
-54
lines changed

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -25,59 +25,44 @@
2525

2626
using namespace swift;
2727

28-
bool swift::hasPointerEscape(BorrowedValue value) {
29-
assert(value.kind == BorrowedValueKind::BeginBorrow ||
30-
value.kind == BorrowedValueKind::LoadBorrow);
31-
GraphNodeWorklist<Operand *, 8> worklist;
32-
for (Operand *use : value->getUses()) {
33-
if (use->getOperandOwnership() != OperandOwnership::NonUse)
34-
worklist.insert(use);
35-
}
36-
37-
while (Operand *op = worklist.pop()) {
38-
switch (op->getOperandOwnership()) {
39-
case OperandOwnership::NonUse:
40-
case OperandOwnership::TrivialUse:
41-
case OperandOwnership::ForwardingConsume:
42-
case OperandOwnership::DestroyingConsume:
43-
llvm_unreachable("this operand cannot handle an inner guaranteed use");
28+
bool swift::hasPointerEscape(BorrowedValue original) {
29+
ValueWorklist worklist(original->getFunction());
30+
worklist.push(*original);
4431

45-
case OperandOwnership::ForwardingUnowned:
46-
case OperandOwnership::PointerEscape:
32+
if (auto *phi = SILArgument::asPhi(*original)) {
33+
phi->visitTransitiveIncomingPhiOperands([&](auto *phi, auto *operand) {
34+
worklist.pushIfNotVisited(operand->get());
4735
return true;
36+
});
37+
}
4838

49-
case OperandOwnership::Borrow:
50-
case OperandOwnership::EndBorrow:
51-
case OperandOwnership::InstantaneousUse:
52-
case OperandOwnership::UnownedInstantaneousUse:
53-
case OperandOwnership::InteriorPointer:
54-
case OperandOwnership::BitwiseEscape:
55-
break;
56-
case OperandOwnership::Reborrow: {
57-
SILArgument *phi = cast<BranchInst>(op->getUser())
58-
->getDestBB()
59-
->getArgument(op->getOperandNumber());
60-
for (auto *use : phi->getUses()) {
61-
if (use->getOperandOwnership() != OperandOwnership::NonUse)
62-
worklist.insert(use);
39+
while (auto value = worklist.pop()) {
40+
for (auto *op : value->getUses()) {
41+
switch (op->getOperandOwnership()) {
42+
case OperandOwnership::ForwardingUnowned:
43+
case OperandOwnership::PointerEscape:
44+
return true;
45+
46+
case OperandOwnership::Reborrow: {
47+
SILArgument *phi = PhiOperand(op).getValue();
48+
worklist.pushIfNotVisited(phi);
49+
break;
6350
}
64-
break;
65-
}
66-
case OperandOwnership::GuaranteedForwarding: {
67-
// This may follow a guaranteed phis.
68-
ForwardingOperand(op).visitForwardedValues([&](SILValue result) {
69-
// Do not include transitive uses with 'none' ownership
70-
if (result->getOwnershipKind() == OwnershipKind::None)
51+
52+
case OperandOwnership::GuaranteedForwarding: {
53+
// This may follow guaranteed phis.
54+
ForwardingOperand(op).visitForwardedValues([&](SILValue result) {
55+
// Do not include transitive uses with 'none' ownership
56+
if (result->getOwnershipKind() == OwnershipKind::None)
57+
return true;
58+
worklist.pushIfNotVisited(result);
7159
return true;
72-
for (auto *resultUse : result->getUses()) {
73-
if (resultUse->getOperandOwnership() != OperandOwnership::NonUse) {
74-
worklist.insert(resultUse);
75-
}
76-
}
77-
return true;
78-
});
79-
break;
80-
}
60+
});
61+
break;
62+
}
63+
default:
64+
break;
65+
}
8166
}
8267
}
8368
return false;

lib/SILOptimizer/Transforms/DeadCodeElimination.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,16 @@ void DCE::markLive() {
281281
}
282282
break;
283283
}
284-
case SILInstructionKind::EndBorrowInst:
284+
case SILInstructionKind::EndBorrowInst: {
285+
auto phi = PhiValue(I.getOperand(0));
286+
// If there is a pointer escape or phi is lexical, disable DCE.
287+
if (phi && (hasPointerEscape(phi) || phi->isLexical())) {
288+
markInstructionLive(&I);
289+
}
290+
// The instruction is live only if it's operand value is also live
291+
addReverseDependency(I.getOperand(0), &I);
292+
break;
293+
}
285294
case SILInstructionKind::EndLifetimeInst: {
286295
// The instruction is live only if it's operand value is also live
287296
addReverseDependency(I.getOperand(0), &I);
@@ -311,11 +320,6 @@ void DCE::markLive() {
311320
disableBorrowDCE(root);
312321
}
313322
}
314-
// If we have a lexical borrow scope or a pointer escape, disable DCE.
315-
if (borrowInst->isLexical() ||
316-
hasPointerEscape(BorrowedValue(borrowInst))) {
317-
disableBorrowDCE(borrowInst);
318-
}
319323
break;
320324
}
321325
case SILInstructionKind::LoadBorrowInst: {

0 commit comments

Comments
 (0)