Skip to content

Commit d65f113

Browse files
committed
[CanOSSALife] Respect barrier boundary edges.
When canonicalizing the lifetime of a lexical value, deinit barriers are respected. This is done by walking backwards from destroys and adding encountered deinit barriers to liveness. Previously, barrier edges did not result in any additions to liveness on the theory that they would be rediscovered. This is not always true (as in the case of dead defs). Here, each barrier edge different from the def block results in additions to liveness. Specifically, it results in the back of the single predecessor being added to liveness. rdar://115410893
1 parent dc6d784 commit d65f113

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

lib/SILOptimizer/Utils/CanonicalizeOSSALifetime.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,17 @@ void CanonicalizeOSSALifetime::extendLivenessToDeinitBarriers() {
286286
/*lifetimeEnding*/ false);
287287
}
288288
}
289-
// Ignore barriers.edges. The beginning of the targets of such edges should
290-
// not be added to liveness. These edges will be rediscovered when computing
291-
// the liveness boundary.
289+
for (auto *edge : barriers.edges) {
290+
if (edge == getCurrentDef()->getParentBlock()) {
291+
// A destroy should be inserted at the begin of this block, but that does
292+
// not require adding any instructions to liveness.
293+
continue;
294+
}
295+
auto *predecessor = edge->getSinglePredecessorBlock();
296+
assert(predecessor);
297+
liveness->updateForUse(&predecessor->back(),
298+
/*lifetimeEnding*/ false);
299+
}
292300
}
293301

294302
// Return true if \p inst is an end_access whose access scope overlaps the end

test/SILOptimizer/canonicalize_ossa_lifetime_unit.sil

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,31 @@ entry(%instance : @owned $MoE):
180180
%retval = tuple ()
181181
return %retval : $()
182182
}
183+
184+
// CHECK-LABEL: begin running test 1 of 1 on respect_boundary_edges_when_extending_to_deinit_barriers: canonicalize-ossa-lifetime with: true, false, true, @argument
185+
// respect_boundary_edges_when_extending_to_deinit_barriers
186+
// CHECK-LABEL: sil [ossa] @respect_boundary_edges_when_extending_to_deinit_barriers : {{.*}} {
187+
// CHECK: bb0([[INSTANCE:%[^,]+]] :
188+
// CHECK: apply {{%[^,]+}}()
189+
// CHECK: cond_br undef, [[DIE:bb[0-9]+]], [[DESTROY:bb[0-9]+]]
190+
// CHECK: [[DIE]]:
191+
// CHECK: unreachable
192+
// CHECK: [[DESTROY]]:
193+
// CHECK: destroy_value [[INSTANCE]] : $C
194+
// CHECK-LABEL: } // end sil function 'respect_boundary_edges_when_extending_to_deinit_barriers'
195+
// CHECK-LABEL: end running test 1 of 1 on respect_boundary_edges_when_extending_to_deinit_barriers: canonicalize-ossa-lifetime with: true, false, true, @argument
196+
sil [ossa] @respect_boundary_edges_when_extending_to_deinit_barriers : $@convention(thin) (@owned C) -> () {
197+
entry(%instance : @owned $C):
198+
test_specification "canonicalize-ossa-lifetime true false true @argument"
199+
%barrier = function_ref @barrier : $@convention(thin) () -> ()
200+
apply %barrier() : $@convention(thin) () -> ()
201+
cond_br undef, die, destroy
202+
203+
die:
204+
unreachable
205+
206+
destroy:
207+
destroy_value %instance : $C
208+
%retval = tuple ()
209+
return %retval : $()
210+
}

0 commit comments

Comments
 (0)