[SIL] Key consume addr checking off var_decl attr.

Previously, the lexical attribute on allock_stack instructions was used.
This doesn't work for values without lexical lifetimes which are
consumed, e.g. stdlib CoW types.  Here, the new var_decl attribute on
alloc_stack is keyed off of instead.  This flag encodes exactly that a
value corresponds to a source-level VarDecl, which is the condition
under which checking needs to run.
This commit is contained in:
Nate Chandler
2024-03-08 21:12:00 -08:00
parent 08a832b803
commit a54a8ddaa3
5 changed files with 24 additions and 19 deletions

View File

@@ -2475,8 +2475,8 @@ class ConsumeOperatorCopyableAddressesCheckerPass
++ii;
if (auto *asi = dyn_cast<AllocStackInst>(inst)) {
// Only check lexical alloc_stack that were not emitted as vars.
if (asi->isLexical()) {
// Only check var_decl alloc_stack insts.
if (asi->isFromVarDecl()) {
LLVM_DEBUG(llvm::dbgs() << "Found lexical alloc_stack: " << *asi);
addressesToCheck.insert(asi);
continue;

View File

@@ -19,7 +19,7 @@ func testNoDerivativeStructProjection(_ s: HasNoDerivativeProperty) -> Float {
// CHECK-LABEL: [AD] Activity info for ${{.*}}testNoDerivativeStructProjection{{.*}} at parameter indices (0) and result indices (0):
// CHECK: [ACTIVE] %0 = argument of bb0 : $HasNoDerivativeProperty
// CHECK: [ACTIVE] %2 = alloc_stack $HasNoDerivativeProperty, var, name "tmp"
// CHECK: [ACTIVE] %2 = alloc_stack [var_decl] $HasNoDerivativeProperty, var, name "tmp"
// CHECK: [ACTIVE] %4 = begin_access [read] [static] %2 : $*HasNoDerivativeProperty
// CHECK: [ACTIVE] %5 = struct_element_addr %4 : $*HasNoDerivativeProperty, #HasNoDerivativeProperty.x
// CHECK: [VARIED] %6 = load [trivial] %5 : $*Float
@@ -43,7 +43,7 @@ func testNondifferentiableTupleElementAddr<T>(_ x: T) -> T {
// CHECK-LABEL: [AD] Activity info for ${{.*}}testNondifferentiableTupleElementAddr{{.*}} at parameter indices (0) and result indices (0):
// CHECK: [ACTIVE] %0 = argument of bb0 : $*T
// CHECK: [ACTIVE] %1 = argument of bb0 : $*T
// CHECK: [ACTIVE] %3 = alloc_stack [lexical] $(Int, Int, (T, Int), Int), var, name "tuple"
// CHECK: [ACTIVE] %3 = alloc_stack [lexical] [var_decl] $(Int, Int, (T, Int), Int), var, name "tuple"
// CHECK: [USEFUL] %4 = tuple_element_addr %3 : $*(Int, Int, (T, Int), Int), 0
// CHECK: [USEFUL] %5 = tuple_element_addr %3 : $*(Int, Int, (T, Int), Int), 1
// CHECK: [ACTIVE] %6 = tuple_element_addr %3 : $*(Int, Int, (T, Int), Int), 2
@@ -77,7 +77,7 @@ func TF_781(_ x: Float, _ y: Float) -> Float {
// CHECK-LABEL: [AD] Activity info for ${{.*}}TF_781{{.*}} at parameter indices (0) and result indices (0)
// CHECK: [ACTIVE] %0 = argument of bb0 : $Float
// CHECK: [USEFUL] %1 = argument of bb0 : $Float
// CHECK: [ACTIVE] %4 = alloc_stack $Float, var, name "result"
// CHECK: [ACTIVE] %4 = alloc_stack [var_decl] $Float, var, name "result"
// CHECK: [ACTIVE] %19 = begin_access [read] [static] %4 : $*Float
// CHECK: [ACTIVE] %20 = load [trivial] %19 : $*Float
// CHECK: [ACTIVE] %23 = apply %22(%20, %0, %18) : $@convention(method) (Float, Float, @thin Float.Type) -> Float
@@ -104,9 +104,9 @@ func TF_954(_ x: Float) -> Float {
// CHECK-LABEL: [AD] Activity info for ${{.*}}TF_954{{.*}} at parameter indices (0) and result indices (0)
// CHECK: bb0:
// CHECK: [ACTIVE] %0 = argument of bb0 : $Float
// CHECK: [ACTIVE] %2 = alloc_stack $Float, var, name "outer"
// CHECK: [ACTIVE] %2 = alloc_stack [var_decl] $Float, var, name "outer"
// CHECK: bb1:
// CHECK: [ACTIVE] %10 = alloc_stack $Float, var, name "inner"
// CHECK: [ACTIVE] %10 = alloc_stack [var_decl] $Float, var, name "inner"
// CHECK: [ACTIVE] %11 = begin_access [read] [static] %2 : $*Float
// CHECK: [USEFUL] %14 = metatype $@thin Float.Type
// CHECK: [ACTIVE] %15 = begin_access [read] [static] %10 : $*Float
@@ -289,7 +289,7 @@ func testArrayUninitializedIntrinsicAddress(_ x: Float, _ y: Float) -> [Float] {
// CHECK-LABEL: [AD] Activity info for ${{.*}}testArrayUninitializedIntrinsicAddress{{.*}} at parameter indices (0, 1) and result indices (0)
// CHECK: [ACTIVE] %0 = argument of bb0 : $Float
// CHECK: [ACTIVE] %1 = argument of bb0 : $Float
// CHECK: [ACTIVE] %4 = alloc_stack $Float, var, name "result"
// CHECK: [ACTIVE] %4 = alloc_stack [var_decl] $Float, var, name "result"
// CHECK: [ACTIVE] %7 = begin_access [read] [static] %4 : $*Float
// CHECK: [ACTIVE] %8 = load [trivial] %7 : $*Float
// CHECK: [NONE] // function_ref static Float.* infix(_:_:)
@@ -448,7 +448,7 @@ func activeInoutArgMutatingMethod(_ x: Mut) -> Mut {
// CHECK-LABEL: [AD] Activity info for ${{.*}}28activeInoutArgMutatingMethodyAA3MutVADF at parameter indices (0) and result indices (0)
// CHECK: [ACTIVE] %0 = argument of bb0 : $Mut
// CHECK: [ACTIVE] %2 = alloc_stack $Mut, var, name "result"
// CHECK: [ACTIVE] %2 = alloc_stack [var_decl] $Mut, var, name "result"
// CHECK: [ACTIVE] %4 = begin_access [read] [static] %2 : $*Mut
// CHECK: [ACTIVE] %5 = load [trivial] %4 : $*Mut
// CHECK: [ACTIVE] %7 = begin_access [modify] [static] %2 : $*Mut
@@ -467,7 +467,7 @@ func activeInoutArgMutatingMethodVar(_ nonactive: inout Mut, _ x: Mut) {
// CHECK-LABEL: [AD] Activity info for ${{.*}}31activeInoutArgMutatingMethodVaryyAA3MutVz_ADtF at parameter indices (0, 1) and result indices (0)
// CHECK: [ACTIVE] %0 = argument of bb0 : $*Mut
// CHECK: [ACTIVE] %1 = argument of bb0 : $Mut
// CHECK: [ACTIVE] %4 = alloc_stack $Mut, var, name "result"
// CHECK: [ACTIVE] %4 = alloc_stack [var_decl] $Mut, var, name "result"
// CHECK: [ACTIVE] %5 = begin_access [read] [static] %0 : $*Mut
// CHECK: [ACTIVE] %8 = begin_access [modify] [static] %4 : $*Mut
// CHECK: [NONE] // function_ref Mut.mutatingMethod(_:)
@@ -488,7 +488,7 @@ func activeInoutArgMutatingMethodTuple(_ nonactive: inout Mut, _ x: Mut) {
// CHECK-LABEL: [AD] Activity info for ${{.*}}33activeInoutArgMutatingMethodTupleyyAA3MutVz_ADtF at parameter indices (0, 1) and result indices (0)
// CHECK: [ACTIVE] %0 = argument of bb0 : $*Mut
// CHECK: [ACTIVE] %1 = argument of bb0 : $Mut
// CHECK: [ACTIVE] %4 = alloc_stack $(Mut, Mut), var, name "result"
// CHECK: [ACTIVE] %4 = alloc_stack [var_decl] $(Mut, Mut), var, name "result"
// CHECK: [ACTIVE] %5 = tuple_element_addr %4 : $*(Mut, Mut), 0
// CHECK: [ACTIVE] %6 = tuple_element_addr %4 : $*(Mut, Mut), 1
// CHECK: [ACTIVE] %7 = begin_access [read] [static] %0 : $*Mut
@@ -515,7 +515,7 @@ func activeInoutArg(_ x: inout Float) -> Float {
// CHECK-LABEL: [AD] Activity info for ${{.*}}activeInoutArg{{.*}} at parameter indices (0) and result indices (0, 1)
// CHECK: [ACTIVE] %0 = argument of bb0 : $*Float
// CHECK: [ACTIVE] %2 = alloc_stack $Float, var, name "result"
// CHECK: [ACTIVE] %2 = alloc_stack [var_decl] $Float, var, name "result"
// CHECK: [ACTIVE] %10 = begin_access [modify] [static] %2 : $*Float
// CHECK: [NONE] // function_ref static Float.+= infix(_:_:)
// CHECK: [NONE] %12 = apply %11(%10, %8, %6) : $@convention(method) (@inout Float, Float, @thin Float.Type) -> ()
@@ -531,7 +531,7 @@ func activeInoutArgNonactiveInitialResult(_ x: inout Float) -> Float {
// CHECK-LABEL: [AD] Activity info for ${{.*}}activeInoutArgNonactiveInitialResult{{.*}} at parameter indices (0) and result indices (0, 1)
// CHECK: [ACTIVE] %0 = argument of bb0 : $*Float
// CHECK: [ACTIVE] %2 = alloc_stack $Float, var, name "result"
// CHECK: [ACTIVE] %2 = alloc_stack [var_decl] $Float, var, name "result"
// CHECK: [NONE] // function_ref Float.init(_builtinIntegerLiteral:)
// CHECK: [USEFUL] %6 = apply %5(%3, %4) : $@convention(method) (Builtin.IntLiteral, @thin Float.Type) -> Float
// CHECK: [USEFUL] %8 = metatype $@thin Float.Type
@@ -592,7 +592,7 @@ func testAccessorCoroutines(_ x: HasCoroutineAccessors) -> HasCoroutineAccessors
// CHECK-LABEL: [AD] Activity info for ${{.*}}testAccessorCoroutines{{.*}} at parameter indices (0) and result indices (0)
// CHECK: [ACTIVE] %0 = argument of bb0 : $HasCoroutineAccessors
// CHECK: [ACTIVE] %2 = alloc_stack $HasCoroutineAccessors, var, name "x"
// CHECK: [ACTIVE] %2 = alloc_stack [var_decl] $HasCoroutineAccessors, var, name "x"
// CHECK: [ACTIVE] %4 = begin_access [read] [static] %2 : $*HasCoroutineAccessors
// CHECK: [ACTIVE] %5 = load [trivial] %4 : $*HasCoroutineAccessors
// CHECK: [NONE] // function_ref HasCoroutineAccessors.computed.read
@@ -625,7 +625,7 @@ func testBeginApplyActiveInoutArgument(array: [Float], x: Float) -> Float {
// CHECK-LABEL: [AD] Activity info for ${{.*}}testBeginApplyActiveInoutArgument{{.*}} at parameter indices (0, 1) and result indices (0)
// CHECK: [ACTIVE] %0 = argument of bb0 : $Array<Float>
// CHECK: [ACTIVE] %1 = argument of bb0 : $Float
// CHECK: [ACTIVE] %4 = alloc_stack $Array<Float>, var, name "array"
// CHECK: [ACTIVE] %4 = alloc_stack [var_decl] $Array<Float>, var, name "array"
// CHECK: [ACTIVE] %5 = copy_value %0 : $Array<Float>
// CHECK: [USEFUL] %7 = integer_literal $Builtin.IntLiteral, 0
// CHECK: [USEFUL] %8 = metatype $@thin Int.Type
@@ -662,7 +662,7 @@ func testBeginApplyActiveButInitiallyNonactiveInoutArgument(x: Float) -> Float {
// CHECK-LABEL: [AD] Activity info for ${{.*}}testBeginApplyActiveButInitiallyNonactiveInoutArgument{{.*}} at parameter indices (0) and result indices (0)
// CHECK: [ACTIVE] %0 = argument of bb0 : $Float
// CHECK: [ACTIVE] %2 = alloc_stack $Array<Float>, var, name "array"
// CHECK: [ACTIVE] %2 = alloc_stack [var_decl] $Array<Float>, var, name "array"
// CHECK: [USEFUL] %3 = integer_literal $Builtin.Word, 1
// CHECK: [NONE] // function_ref _allocateUninitializedArray<A>(_:)
// CHECK: [USEFUL] %5 = apply %4<Float>(%3) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
@@ -763,7 +763,7 @@ func testActiveOptional(_ x: Float) -> Float {
// CHECK-LABEL: [AD] Activity info for ${{.*}}testActiveOptional{{.*}} at parameter indices (0) and result indices (0)
// CHECK: bb0:
// CHECK: [ACTIVE] %0 = argument of bb0 : $Float
// CHECK: [ACTIVE] %2 = alloc_stack $Optional<Float>, var, name "maybe"
// CHECK: [ACTIVE] %2 = alloc_stack [var_decl] $Optional<Float>, var, name "maybe"
// CHECK: [USEFUL] %3 = integer_literal $Builtin.IntLiteral, 10
// CHECK: [USEFUL] %4 = metatype $@thin Float.Type
// CHECK: [NONE] // function_ref Float.init(_builtinIntegerLiteral:)

View File

@@ -9,7 +9,7 @@ func main() {
// CHECK-SIL-DAG: debug_value {{.*}}: $Int, let, name "x"
// CHECK-DAG: DILocalVariable(name: "x"
let x = 10
// CHECK-SIL-DAG: alloc_stack $Int, var, name "y"
// CHECK-SIL-DAG: alloc_stack [var_decl] $Int, var, name "y"
// CHECK-DAG: DILocalVariable(name: "y"
var y = 10
// The expression x+y may become constant folded.

View File

@@ -28,7 +28,7 @@ func use<T>(_ t : T) {}
// CHECK-SIL: sil hidden @$s16debug_value_addr11GenericSelfV1xACyxGx_tcfC : $@convention(method) <T> (@in T, @thin GenericSelf<T>.Type) -> GenericSelf<T> {
// CHECK-SIL: bb0(%0 : $*T, %1 : $@thin GenericSelf<T>.Type):
//
// CHECK-SIL-NEXT: alloc_stack $GenericSelf<T>, var, name "self", implicit, loc {{.*}}
// CHECK-SIL-NEXT: alloc_stack [var_decl] $GenericSelf<T>, var, name "self", implicit, loc {{.*}}
// CHECK-SIL-NEXT: debug_value %0 : $*T, let, name "x", argno 1, expr op_deref, loc {{.*}}
struct GenericSelf<T> {
init(x: T) {

View File

@@ -708,6 +708,11 @@ func multipleCapture2(_ k: Klass) -> () {
print("foo bar")
}
func consumeString() {
var s = "asdf" // expected-warning{{}}
_ = consume s
}
//////////////////////
// Reinit in pieces //
//////////////////////