Skip to content

Commit 087bf6a

Browse files
committed
[LifetimeCompletion] NFC: Add helper.
It visits users discovered by an SSAPrunedLiveness instance (such as that used by InteriorLiveness) which are outside the LinearLifetime boundary.
1 parent 65397fa commit 087bf6a

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

lib/SIL/Utils/OSSALifetimeCompletion.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,43 @@ static bool endLifetimeAtLivenessBoundary(SILValue value,
109109
return changed;
110110
}
111111

112+
static void visitUsersOutsideLinearLivenessBoundary(
113+
SILValue value, const SSAPrunedLiveness &liveness,
114+
llvm::function_ref<void(SILInstruction *)> visitor) {
115+
if (value->getOwnershipKind() == OwnershipKind::None) {
116+
return;
117+
}
118+
LinearLiveness linearLiveness(value);
119+
linearLiveness.compute();
120+
for (auto pair : liveness.getAllUsers()) {
121+
if (pair.second.isEnding() || isa<ExtendLifetimeInst>(pair.first)) {
122+
continue;
123+
}
124+
auto *user = pair.first;
125+
if (linearLiveness.getLiveness().isWithinBoundary(user)) {
126+
continue;
127+
}
128+
visitor(user);
129+
}
130+
}
131+
132+
namespace swift::test {
133+
// Arguments:
134+
// - SILValue: value
135+
// Dumps:
136+
// - the instructions outside the liveness boundary
137+
static FunctionTest LivenessPartialBoundaryOutsideUsersTest(
138+
"liveness_partial_boundary_outside_users",
139+
[](auto &function, auto &arguments, auto &test) {
140+
SILValue value = arguments.takeValue();
141+
InteriorLiveness liveness(value);
142+
liveness.compute(test.getDominanceInfo());
143+
visitUsersOutsideLinearLivenessBoundary(
144+
value, liveness.getLiveness(),
145+
[](auto *inst) { inst->print(llvm::outs()); });
146+
});
147+
} // end namespace swift::test
148+
112149
namespace {
113150
/// Implements OSSALifetimeCompletion::visitAvailabilityBoundary. Finds
114151
/// positions as near as possible to unreachables at which `value`'s lifetime

test/SILOptimizer/ossa_lifetime_completion.sil

+29
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ case none
2727
case some(Wrapped)
2828
}
2929

30+
typealias AnyObject = Builtin.AnyObject
31+
32+
protocol P : AnyObject {}
33+
3034
// CHECK-LABEL: begin running test 1 of 1 on eagerConsumneOwnedArg: ossa_lifetime_completion with: @argument
3135
// CHECK-LABEL: OSSA lifetime completion on liveness boundary: %0 = argument of bb0 : $C
3236
// CHECK: sil [ossa] @eagerConsumneOwnedArg : $@convention(thin) (@owned C) -> () {
@@ -537,3 +541,28 @@ left:
537541
right:
538542
unreachable
539543
}
544+
545+
// CHECK-LABEL: begin running test {{.*}} on loopy: liveness_partial_boundary_outside_users with: %o
546+
// CHECK: end_borrow
547+
// CHECK-LABEL: end running test {{.*}} on loopy: liveness_partial_boundary_outside_users with: %o
548+
sil [ossa] @loopy : $@convention(thin) () -> () {
549+
%o = apply undef() : $@convention(thin) () -> (@owned C)
550+
specify_test "liveness_partial_boundary_outside_users %o"
551+
%b = begin_borrow %o : $C
552+
end_borrow %b : $C
553+
br loop
554+
555+
loop:
556+
br loop
557+
}
558+
559+
// CHECK-LABEL: begin running test {{.*}} on type_dependent_operand: liveness_partial_boundary_outside_users
560+
// There should be no out-of-boundary users.
561+
// CHECK-NEXT: end running test {{.*}} on type_dependent_operand: liveness_partial_boundary_outside_users
562+
sil [ossa] @type_dependent_operand : $@convention(thin) (@owned any P) -> @owned AnyObject {
563+
bb0(%existential : @owned $any P):
564+
%opened = open_existential_ref %existential : $any P to $@opened("00000000-0000-0000-0000-000000000000", any P) Self
565+
specify_test "liveness_partial_boundary_outside_users %opened"
566+
%ref_existential = init_existential_ref %opened : $@opened("00000000-0000-0000-0000-000000000000", any P) Self : $@opened("00000000-0000-0000-0000-000000000000", any P) Self, $AnyObject
567+
return %ref_existential : $AnyObject
568+
}

0 commit comments

Comments
 (0)