Skip to content

Commit 86c51c1

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 aa82a76 commit 86c51c1

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
@@ -229,28 +229,30 @@ void PrunedLivenessBoundary::dump() const {
229229
print(llvm::dbgs());
230230
}
231231

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

253-
assert(succ->getSinglePredecessorBlock() == predBB);
254256
visitor(succ->begin());
255257
}
256258
}

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)