Skip to content

Commit 6df53e4

Browse files
committed
[PrunedLiveness] Addressed boundary TODO.
With guaranteed phis, we'll be able to encounter cases where the last users are BranchInsts which use but don't consume a value. But even without them, we can still test the API.
1 parent 7432d0d commit 6df53e4

File tree

3 files changed

+55
-9
lines changed

3 files changed

+55
-9
lines changed

lib/SIL/Utils/PrunedLiveness.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -227,28 +227,30 @@ void PrunedLivenessBoundary::dump() const {
227227
print(llvm::dbgs());
228228
}
229229

230-
// TODO: with guaranteed phis, it will be possible to hit this assert:
231-
// assert(succ->getSinglePredecessorBlock() == predBB);
232-
//
233-
// Once it's possible to test dead guaranteed phis, replace the assert with a
234-
// set to avoid multiple insertions at a merge point:
235-
// // Control flow merge blocks used as insertion points.
236-
// BasicBlockSet mergeBlocks;
237-
//
238230
void PrunedLivenessBoundary::visitInsertionPoints(
239231
llvm::function_ref<void(SILBasicBlock::iterator insertPt)> visitor,
240232
DeadEndBlocks *deBlocks) {
233+
// Control flow merge blocks used as insertion points.
234+
SmallPtrSet<SILBasicBlock *, 4> mergeBlocks;
235+
241236
for (SILInstruction *user : lastUsers) {
242237
if (!isa<TermInst>(user)) {
243238
visitor(std::next(user->getIterator()));
244239
continue;
245240
}
246241
auto *predBB = user->getParent();
247242
for (SILBasicBlock *succ : predBB->getSuccessors()) {
243+
if (!succ->getSinglePredecessorBlock()) {
244+
assert(predBB->getSingleSuccessorBlock() == succ);
245+
if (!mergeBlocks.insert(succ).second) {
246+
continue;
247+
}
248+
} else {
249+
assert(succ->getSinglePredecessorBlock() == predBB);
250+
}
248251
if (deBlocks && deBlocks->isDeadEnd(succ))
249252
continue;
250253

251-
assert(succ->getSinglePredecessorBlock() == predBB);
252254
visitor(succ->begin());
253255
}
254256
}

lib/SILOptimizer/UtilityPasses/UnitTestRunner.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666

6767
#include "swift/AST/Type.h"
6868
#include "swift/Basic/TaggedUnion.h"
69+
#include "swift/SIL/PrunedLiveness.h"
6970
#include "swift/SIL/SILArgumentArrayRef.h"
7071
#include "swift/SIL/SILBasicBlock.h"
7172
#include "swift/SIL/SILFunction.h"
@@ -216,6 +217,24 @@ struct VisitAdjacentReborrowsOfPhiTest : UnitTest {
216217
}
217218
};
218219

220+
// Arguments:
221+
// - variadic list of - instruction: a last user
222+
// Dumps:
223+
// - the insertion points
224+
struct PrunedLivenessBoundaryWithListOfLastUsersInsertionPointsTest : UnitTest {
225+
PrunedLivenessBoundaryWithListOfLastUsersInsertionPointsTest(
226+
UnitTestRunner *pass)
227+
: UnitTest(pass) {}
228+
void invoke(Arguments &arguments) override {
229+
PrunedLivenessBoundary boundary;
230+
while (arguments.hasUntaken()) {
231+
boundary.lastUsers.push_back(arguments.takeInstruction());
232+
}
233+
boundary.visitInsertionPoints(
234+
[](SILBasicBlock::iterator point) { point->dump(); });
235+
}
236+
};
237+
219238
// Arguments: NONE
220239
// Dumps:
221240
// - the function
@@ -260,6 +279,9 @@ class UnitTestRunner : public SILFunctionTransform {
260279
CanonicalizeOSSALifetimeTest)
261280
ADD_UNIT_TEST_SUBCLASS("visit-adjacent-reborrows-of-phi",
262281
VisitAdjacentReborrowsOfPhiTest)
282+
ADD_UNIT_TEST_SUBCLASS(
283+
"pruned-liveness-boundary-with-list-of-last-users-insertion-points",
284+
PrunedLivenessBoundaryWithListOfLastUsersInsertionPointsTest)
263285
/// [new_tests] Add the new mapping from string to subclass above this line.
264286

265287
#undef ADD_UNIT_TEST_SUBCLASS
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-sil-opt -unit-test-runner %s 2>&1 | %FileCheck %s
2+
3+
// CHECK: begin running test 1 of {{[^,]+}} on last_uses_merge_points: dump-function
4+
// CHECK: [[REGISTER_3:%[^,]+]] = tuple ()
5+
// CHECK: return [[REGISTER_3]]
6+
// CHECK: end running test 1 of {{[^,]+}} on last_uses_merge_points: dump-function
7+
// CHECK: begin running test 2 of {{[^,]+}} on last_uses_merge_points: pruned-liveness-boundary-with-list-of-last-users-insertion-points
8+
// CHECK: [[REGISTER_3]] = tuple ()
9+
// CHECK: end running test 2 of {{[^,]+}} on last_uses_merge_points: pruned-liveness-boundary-with-list-of-last-users-insertion-points
10+
sil [ossa] @last_uses_merge_points : $@convention(thin) () -> () {
11+
entry:
12+
test_specification "dump-function"
13+
test_specification "pruned-liveness-boundary-with-list-of-last-users-insertion-points @block[1].instruction[0] @block[2].instruction[0]"
14+
cond_br undef, left, right
15+
left:
16+
br bottom
17+
right:
18+
br bottom
19+
bottom:
20+
%retval = tuple ()
21+
return %retval : $()
22+
}

0 commit comments

Comments
 (0)