Skip to content

Commit 0bc30e6

Browse files
committed
Add ValueLifetimeBoundary::visitInsertionPoints
Given a computed ValueLifetimeBoundary, visit all the points at which the lifetime needs to be terminated, e.g. via and end_borrow or destroy_value. Especially useful for creating a borrow scope over guaranteed uses. This completely decouples the DeadBlocks analysis from the liveness analysis. It will allow phasing out the complex and bug-prone ValueLifetimeAnalysis::Frontier API.
1 parent ab0601d commit 0bc30e6

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

include/swift/SILOptimizer/Utils/ValueLifetime.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ namespace swift {
4848
struct ValueLifetimeBoundary {
4949
SmallVector<SILInstruction *, 8> lastUsers;
5050
SmallVector<SILBasicBlock *, 8> boundaryEdges;
51+
52+
/// Visit the point at which a lifetime-ending instruction must be inserted,
53+
/// exclusing dead-end blocks. This is only useful when it is known that none
54+
/// of the lastUsers ends the lifetime, for example when creating a new borrow
55+
/// scope to enclose all uses.
56+
void visitInsertionPoints(
57+
llvm::function_ref<void(SILBasicBlock::iterator insertPt)> visitor,
58+
DeadEndBlocks *deBlocks = nullptr);
5159
};
5260

5361
/// Computes the lifetime frontier for a given value with respect to a

lib/SILOptimizer/Utils/ValueLifetime.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,31 @@
1818

1919
using namespace swift;
2020

21+
void ValueLifetimeBoundary::visitInsertionPoints(
22+
llvm::function_ref<void(SILBasicBlock::iterator insertPt)> visitor,
23+
DeadEndBlocks *deBlocks) {
24+
for (SILInstruction *user : lastUsers) {
25+
if (!isa<TermInst>(user)) {
26+
visitor(std::next(user->getIterator()));
27+
continue;
28+
}
29+
auto *predBB = user->getParent();
30+
for (SILBasicBlock *succ : predBB->getSuccessors()) {
31+
if (deBlocks && deBlocks->isDeadEnd(succ))
32+
continue;
33+
34+
assert(succ->getSinglePredecessorBlock() == predBB);
35+
visitor(succ->begin());
36+
}
37+
}
38+
for (SILBasicBlock *edge : boundaryEdges) {
39+
if (deBlocks && deBlocks->isDeadEnd(edge))
40+
continue;
41+
42+
visitor(edge->begin());
43+
}
44+
}
45+
2146
void ValueLifetimeAnalysis::propagateLiveness() {
2247
bool defIsInstruction = defValue.is<SILInstruction *>();
2348
assert(liveBlocks.empty() && "frontier computed twice");

0 commit comments

Comments
 (0)