Files
swift-mirror/test/SILOptimizer/shrink_borrow_scope.unit.sil
Nate Chandler f79def4cee [BarrierAccessScopes] Handle found gen locality.
As the utility runs, new gens may become local: as access scopes are
determined to contain deinit barriers, their `end_access` instructions
become kills; if such an `end_access` occurs in the same block above an
initially-non-local gen, that gen is now local.

Previously, it was asserted that initially-non-local gens would not
encounter when visiting the block backwards from that gen.  Iteration
would also _stop_ at the discovered kill, if any.  As described above,
the assertion was incorrect.

Stopping at the discovered kill was also incorrect.  It's necessary to
continue walking the block after finding such a new kill because the
book-keeping the utility does for which access scopes contain barriers.
Concretely, there are two cases:
(1) It may contain another `end_access` and above it a deinit barrier
which must result in that second scope becoming a deinit barrier.
(2) Some of its predecessors may be in the region, all the access scopes
which are open at the begin of this block must be unioned into the set
of scopes open at each predecessors' end, and more such access scopes
may be discovered above the just-visited `end_access`.

Here, both the assertion failure and the early bailout are fixed by
walking from the indicated initially-non-local gen backwards over the
entire block, regardless of whether a kill was encountered.  If a kill
is encountered, it is asserted that the kill is an `end_access` to
account for the case described above.

rdar://139840307
2024-12-02 15:36:00 -08:00

70 lines
2.2 KiB
Plaintext

// RUN: %target-sil-opt -test-runner %s 2>&1 | %FileCheck %s
import Builtin
import Swift
class C {}
struct X {}
sil [ossa] @get_owned_c : $@convention(thin) () -> (@owned C)
sil [ossa] @callee_guaranteed: $@convention(thin) (@guaranteed C) -> ()
sil [ossa] @barrier : $@convention(thin) () -> ()
// CHECK-LABEL: begin running test 1 of {{[^,]+}} on nohoist_over_rewritten_copy
// CHECK-NOT: DELETED:
// CHECK-NOT: end_borrow
// CHECK: Result: did not shrink
// CHECK-LABEL: end running test 1 of {{[^,]+}} on nohoist_over_rewritten_copy
sil [ossa] @nohoist_over_rewritten_copy : $@convention(thin) () -> (@owned C, @owned C) {
entry:
specify_test "shrink_borrow_scope %lifetime"
%get_owned_c = function_ref @get_owned_c : $@convention(thin) () -> (@owned C)
%instance = apply %get_owned_c() : $@convention(thin) () -> (@owned C)
%lifetime = begin_borrow [lexical] %instance : $C
debug_value [trace] %lifetime : $C
%callee_guaranteed = function_ref @callee_guaranteed : $@convention(thin) (@guaranteed C) -> ()
apply %callee_guaranteed(%lifetime) : $@convention(thin) (@guaranteed C) -> ()
%copy = copy_value %lifetime : $C
debug_value [trace] %copy : $C
end_borrow %lifetime : $C
%retval = tuple (%copy : $C, %instance : $C)
return %retval : $(C, C)
}
// CHECK-LABEL: begin running test {{.*}} on nohoist_over_access_scope_barrier_1
// CHECK: Result: did not shrink
// CHECK-LABEL: end running test {{.*}} on nohoist_over_access_scope_barrier_1
sil [ossa] @nohoist_over_access_scope_barrier_1 : $@convention(thin) (@guaranteed C, @inout X) -> () {
entry(%c : @guaranteed $C, %addr : $*X):
%borrow = begin_borrow %c : $C
specify_test "shrink_borrow_scope %borrow"
%access = begin_access [modify] [dynamic] %addr : $*X
cond_br undef, kill_introducer, newly_local_gen
kill_introducer:
cond_br undef, left, right
left:
%barrier = function_ref @barrier : $@convention(thin) () -> ()
apply %barrier() : $@convention(thin) () -> ()
end_access %access : $*X
end_borrow %borrow : $C
br exit
right:
end_access %access : $*X
end_borrow %borrow : $C
br exit
newly_local_gen:
end_access %access : $*X
end_borrow %borrow : $C
br exit
exit:
%retval = tuple ()
return %retval : $()
}