mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Emit llvm.dbg.declare intrisics immediately after the described alloca.
This cleanup change doesn't change the semantics, but it makes the resulting IR much easier to read and debug.
This commit is contained in:
@@ -1998,8 +1998,13 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(
|
||||
// the variable that is live throughout the function. With SIL
|
||||
// optimizations this is not guaranteed and a variable can end up in
|
||||
// two allocas (for example, one function inlined twice).
|
||||
if (isa<llvm::AllocaInst>(Storage)) {
|
||||
DBuilder.insertDeclare(Storage, Var, Expr, DL, BB);
|
||||
if (auto *Alloca = dyn_cast<llvm::AllocaInst>(Storage)) {
|
||||
auto *ParentBB = Alloca->getParent();
|
||||
auto InsertBefore = std::next(Alloca->getIterator());
|
||||
if (InsertBefore != ParentBB->end())
|
||||
DBuilder.insertDeclare(Alloca, Var, Expr, DL, &*InsertBefore);
|
||||
else
|
||||
DBuilder.insertDeclare(Alloca, Var, Expr, DL, ParentBB);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ func markUsed<T>(_ t: T) {}
|
||||
|
||||
func main() {
|
||||
// CHECK: call void @llvm.dbg.declare(metadata %Any* {{.*}}, metadata ![[S:.*]], metadata !{{[0-9]+}}), !dbg ![[DBG:.*]]
|
||||
// CHECK: ![[S]] = !DILocalVariable(name: "s", {{.*}}line: [[@LINE+3]]
|
||||
// CHECK: ![[SCOPE:.*]] = distinct !DILexicalBlock({{.*}}line: 5, column: 13)
|
||||
// CHECK: ![[S]] = !DILocalVariable(name: "s", {{.*}}line: [[@LINE+2]]
|
||||
// CHECK: ![[DBG]] = !DILocation(line: [[@LINE+1]], column: 7, scope: ![[SCOPE]])
|
||||
// CHECK: ![[DBG]] = !DILocation(line: [[@LINE+1]], column: 7, scope: ![[SCOPE:.*]])
|
||||
var s: Any = "hello world"
|
||||
var n: Any = 12
|
||||
var t: Any = (1,2)
|
||||
|
||||
@@ -12,8 +12,8 @@ func main() -> Void
|
||||
var backward_ptr =
|
||||
// CHECK: define internal {{.*}} i1 @_T04mainAAyyFSbSS_SStcfU_(
|
||||
// CHECK: %[[RANDOM_STR_ADDR:.*]] = alloca %TSS*, align {{(4|8)}}
|
||||
// CHECK: store %TSS* %{{.*}}, %TSS** %[[RANDOM_STR_ADDR]], align {{(4|8)}}
|
||||
// CHECK-NEXT: call void @llvm.dbg.declare(metadata %TSS** %[[RANDOM_STR_ADDR]], metadata !{{.*}}, metadata !{{[0-9]+}}), !dbg
|
||||
// CHECK: store %TSS* %{{.*}}, %TSS** %[[RANDOM_STR_ADDR]], align {{(4|8)}}
|
||||
// CHECK-DAG: !DILocalVariable(name: "lhs",{{.*}} line: [[@LINE+5]],
|
||||
// CHECK-DAG: !DILocalVariable(name: "rhs",{{.*}} line: [[@LINE+4]],
|
||||
// CHECK-DAG: !DILocalVariable(name: "random_string",{{.*}} line: 8,
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
// RUN: %target-swift-frontend -g -emit-ir %s | %FileCheck %s
|
||||
// FIXME: This test should be testing a non-shadow-copied value instead.
|
||||
for i in 0 ..< 3 {
|
||||
// CHECK: %[[ALLOCA:[0-9]+]] = alloca %TSiSg
|
||||
// CHECK: %i.addr = alloca i{{32|64}}
|
||||
// CHECK-NEXT: call void @llvm.dbg.declare(metadata i{{32|64}}* %i.addr,
|
||||
// CHECK-SAME: metadata ![[I:[0-9]+]],
|
||||
// CHECK: %[[CAST:[0-9]+]] = bitcast %TSiSg* %[[ALLOCA]] to i{{32|64}}*
|
||||
// CHECK: %[[LD:[0-9]+]] = load i{{32|64}}, i{{32|64}}* %[[CAST]]
|
||||
// CHECK: br i1 {{%.*}}, label %[[FAIL:.*]], label %[[SUCCESS:.*]],
|
||||
@@ -12,7 +15,5 @@ for i in 0 ..< 3 {
|
||||
// CHECK: ; <label>:[[NEXT_BB]]:
|
||||
// CHECK: %[[PHI_VAL:.*]] = phi i{{32|64}} [ %[[LD]], %[[SUCCESS]] ]
|
||||
// CHECK: store i{{32|64}} %[[PHI_VAL]], i{{32|64}}* %i.addr
|
||||
// CHECK-NEXT: call void @llvm.dbg.declare(metadata i{{32|64}}* %i.addr,
|
||||
// CHECK-SAME: metadata ![[I:[0-9]+]],
|
||||
// CHECK: ![[I]] = !DILocalVariable(name: "i",
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
// CHECK: define {{.*}}_T016debug_value_addr4testyxlF
|
||||
// CHECK: entry:
|
||||
// CHECK-NEXT: %[[TADDR:.*]] = alloca
|
||||
// CHECK: store %swift.opaque* %0, %swift.opaque** %[[TADDR:.*]], align
|
||||
// CHECK-NEXT: call void @llvm.dbg.declare({{.*}}%[[TADDR]]
|
||||
// CHECK: store %swift.opaque* %0, %swift.opaque** %[[TADDR:.*]], align
|
||||
|
||||
struct S<T> {
|
||||
var a : T
|
||||
|
||||
@@ -3,13 +3,13 @@ import StdlibUnittest
|
||||
func foo<T>(_ x: T) -> () {
|
||||
// CHECK: define {{.*}} @_T011generic_arg3fooyxlF
|
||||
// CHECK: %[[T:.*]] = alloca %swift.type*
|
||||
// CHECK: %[[X:.*]] = alloca %swift.opaque*
|
||||
// CHECK: store %swift.type* %T, %swift.type** %[[T]],
|
||||
// CHECK: call void @llvm.dbg.declare(metadata %swift.type** %[[T]],
|
||||
// CHECK-SAME: metadata ![[T1:.*]], metadata ![[EMPTY:.*]])
|
||||
// CHECK: store %swift.opaque* %0, %swift.opaque** %[[X]],
|
||||
// CHECK: %[[X:.*]] = alloca %swift.opaque*
|
||||
// CHECK: call void @llvm.dbg.declare(metadata %swift.opaque** %[[X]],
|
||||
// CHECK-SAME: metadata ![[X1:.*]], metadata ![[EMPTY]])
|
||||
// CHECK: store %swift.type* %T, %swift.type** %[[T]],
|
||||
// CHECK: store %swift.opaque* %0, %swift.opaque** %[[X]],
|
||||
// CHECK: ![[T1]] = !DILocalVariable(name: "$swift.type.T",
|
||||
// CHECK-SAME: flags: DIFlagArtificial)
|
||||
// CHECK: ![[EMPTY]] = !DIExpression()
|
||||
|
||||
@@ -5,9 +5,9 @@ func apply<Type>(_ T : Type, fn: (Type) -> Type) -> Type { return fn(T) }
|
||||
public func f<Type>(_ value : Type)
|
||||
{
|
||||
// CHECK: define {{.*}}_T012generic_arg31fyxlFxxcfU_
|
||||
// CHECK: store %swift.opaque* %1, %swift.opaque** %[[ALLOCA:.*]], align
|
||||
// CHECK: call void @llvm.dbg.declare(metadata %swift.opaque** %[[ALLOCA]],
|
||||
// CHECK: call void @llvm.dbg.declare(metadata %swift.opaque** %[[ALLOCA:[^,]+]],
|
||||
// CHECK-SAME: metadata ![[ARG:.*]], metadata ![[EXPR:.*]])
|
||||
// CHECK: store %swift.opaque* %1, %swift.opaque** %[[ALLOCA]], align
|
||||
// No deref here: The argument is an Archetype and this implicitly indirect.
|
||||
// CHECK: ![[EXPR]] = !DIExpression()
|
||||
// CHECK: ![[TY:.*]] = !DICompositeType({{.*}}identifier: "_T012generic_arg31fyxlFQq_D"
|
||||
|
||||
@@ -3,14 +3,15 @@
|
||||
public struct Q<T> {
|
||||
let x: T
|
||||
}
|
||||
// CHECK: define {{.*}}_T012generic_arg43fooySayAA1QVyxGGlF
|
||||
// CHECK: store %[[TY:.*]]* %0, %[[TY]]** %[[ALLOCA:.*]], align
|
||||
// CHECK: call void @llvm.dbg.declare(metadata %[[TY]]** %[[ALLOCA]],
|
||||
// CHECK-SAME: metadata ![[ARG:.*]], metadata ![[EXPR:.*]])
|
||||
// No deref here: the array argument is passed by value.
|
||||
// CHECK: ![[EXPR]] = !DIExpression()
|
||||
// CHECK: ![[ARG]] = !DILocalVariable(name: "arg", arg: 1,
|
||||
// CHECK-SAME: line: [[@LINE+2]], type: ![[TY:.*]])
|
||||
// CHECK: ![[TY]] = !DICompositeType({{.*}}identifier: "_T0Say12generic_arg41QVyAA3fooySayACyxGGlFQq_GGD")
|
||||
// CHECK: define {{.*}}_T012generic_arg43fooySayAA1QVyxGGlF
|
||||
// CHECK: call void @llvm.dbg.declare
|
||||
// CHECK: call void @llvm.dbg.declare(metadata %[[TY:.*]]** %[[ALLOCA:[^,]+]],
|
||||
// CHECK-SAME: metadata ![[ARG:.*]], metadata ![[EXPR:.*]])
|
||||
// CHECK: store %[[TY]]* %0, %[[TY]]** %[[ALLOCA]], align
|
||||
// No deref here: the array argument is passed by value.
|
||||
// CHECK: ![[EXPR]] = !DIExpression()
|
||||
// CHECK: ![[ARG]] = !DILocalVariable(name: "arg", arg: 1,
|
||||
// CHECK-SAME: line: [[@LINE+2]], type: ![[TY:.*]])
|
||||
// CHECK: ![[TY]] = !DICompositeType({{.*}}identifier: "_T0Say12generic_arg41QVyAA3fooySayACyxGGlFQq_GGD")
|
||||
public func foo<T>(_ arg: [Q<T>]) {
|
||||
}
|
||||
|
||||
@@ -7,9 +7,10 @@ public struct S<Type>
|
||||
public func foo<Type>(_ values : [S<Type>])
|
||||
{
|
||||
// CHECK: define {{.*}}_T012generic_arg53fooySayAA1SVyxGGlFAESgAEcfU_
|
||||
// CHECK: store %[[TY:.*]]* %1, %[[TY]]** %[[ALLOCA:.*]], align
|
||||
// CHECK: call void @llvm.dbg.declare(metadata %[[TY]]** %[[ALLOCA]],
|
||||
// CHECK: call void @llvm.dbg.declare
|
||||
// CHECK: call void @llvm.dbg.declare(metadata %[[TY:.*]]** %[[ALLOCA:[^,]+]],
|
||||
// CHECK-SAME: metadata ![[ARG:.*]], metadata ![[EXPR:.*]])
|
||||
// CHECK: store %[[TY]]* %1, %[[TY]]** %[[ALLOCA]], align
|
||||
// The argument is a by-ref struct and thus needs to be dereferenced.
|
||||
// CHECK: ![[ARG]] = !DILocalVariable(name: "arg", arg: 1,
|
||||
// CHECK-SAME: line: [[@LINE+4]],
|
||||
|
||||
@@ -5,13 +5,13 @@ func use<T>(_ t: T) {}
|
||||
public func f(_ i : Int?)
|
||||
{
|
||||
// CHECK: define {{.*}}@_T04main1fySiSgF
|
||||
// CHECK: %[[PHI:.*]] = phi
|
||||
// The shadow copy store should not have a location.
|
||||
// CHECK: store {{(i32|i64)}} %[[PHI]], {{(i32|i64)}}* %val.addr, align {{(4|8)}}, !dbg ![[DBG0:.*]]
|
||||
// CHECK: @llvm.dbg.declare(metadata {{(i32|i64)}}* %val.addr, {{.*}}, !dbg ![[DBG1:.*]]
|
||||
// CHECK: %[[PHI:.*]] = phi
|
||||
// CHECK: store {{(i32|i64)}} %[[PHI]], {{(i32|i64)}}* %val.addr, align {{(4|8)}}, !dbg ![[DBG0:.*]]
|
||||
// CHECK: ![[F:.*]] = distinct !DISubprogram(name: "f",
|
||||
// CHECK: ![[DBG1]] = !DILocation(line: [[@LINE+2]],
|
||||
// CHECK: ![[DBG0]] = !DILocation(line: 0, scope: ![[F]])
|
||||
// CHECK: ![[DBG1]] = !DILocation(line: [[@LINE+1]],
|
||||
guard let val = i else { return }
|
||||
use(val)
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@ func yieldValue() -> Int64? { return 23 }
|
||||
|
||||
// Verify that variables bound in the while statements are in distinct scopes.
|
||||
if let val = yieldValue() {
|
||||
// CHECK: ![[SCOPE1:[0-9]+]] = distinct !DILexicalBlock(scope: ![[MAIN:[0-9]+]]
|
||||
// CHECK: !DILocalVariable(name: "val", scope: ![[SCOPE1]]
|
||||
// CHECK: !DILocalVariable(name: "val", scope: ![[SCOPE1:[0-9]+]]
|
||||
// CHECK: ![[SCOPE1]] = distinct !DILexicalBlock(scope: ![[MAIN:[0-9]+]]
|
||||
}
|
||||
if let val = yieldValue() {
|
||||
// CHECK: ![[SCOPE2:[0-9]+]] = distinct !DILexicalBlock(scope: ![[MAIN]]
|
||||
// CHECK: !DILocalVariable(name: "val", scope: ![[SCOPE2]]
|
||||
// CHECK: !DILocalVariable(name: "val", scope: ![[SCOPE2:[0-9]+]]
|
||||
// CHECK: ![[SCOPE2]] = distinct !DILexicalBlock(scope: ![[MAIN]]
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ class MyClass {
|
||||
func filterImage(_ image: UIImage!, _ doSomething:Bool) -> UIImage
|
||||
{
|
||||
// Test that image is in an alloca, but not an indirect location.
|
||||
// CHECK: store {{(i32|i64)}} %0, {{(i32|i64)}}* %[[ALLOCA:.*]], align
|
||||
// CHECK: call void @llvm.dbg.declare(metadata {{(i32|i64)}}* %[[ALLOCA]], metadata ![[IMAGE:.*]], metadata !{{[0-9]+}})
|
||||
// CHECK: call void @llvm.dbg.declare(metadata {{(i32|i64)}}* %[[ALLOCA:.*]], metadata ![[IMAGE:.*]], metadata !{{[0-9]+}})
|
||||
// CHECK: store {{(i32|i64)}} %0, {{(i32|i64)}}* %[[ALLOCA]], align
|
||||
// CHECK: ![[IMAGE]] = !DILocalVariable(name: "image", arg: 1
|
||||
// CHECK-NOT: flags:
|
||||
// CHECK-SAME: line: [[@LINE-7]]
|
||||
|
||||
@@ -12,6 +12,7 @@ import Foundation
|
||||
// CHECK_NONE: define{{( protected)?}} {{.*}}void {{.*}}none
|
||||
public func none(_ a: inout Int64) {
|
||||
// CHECK_NONE: call void @llvm.dbg{{.*}}, !dbg
|
||||
// CHECK_NONE: store{{.*}}, !dbg
|
||||
// CHECK_NONE: !dbg ![[NONE_INIT:.*]]
|
||||
a -= 2
|
||||
// CHECK_NONE: ret {{.*}}, !dbg ![[NONE_RET:.*]]
|
||||
|
||||
@@ -7,9 +7,9 @@ func foo(_ x: inout Int64) {
|
||||
// line 0), but the code to load the value from the inout storage is
|
||||
// not.
|
||||
// CHECK: %[[X:.*]] = alloca %Ts5Int64V*, align {{(4|8)}}
|
||||
// CHECK-NEXT: call void @llvm.dbg.declare
|
||||
// CHECK: store %Ts5Int64V* %0, %Ts5Int64V** %[[X]], align {{(4|8)}}
|
||||
// CHECK-SAME: !dbg ![[LOC0:.*]]
|
||||
// CHECK-NEXT: call void @llvm.dbg.declare
|
||||
// CHECK-NEXT: getelementptr inbounds %Ts5Int64V, %Ts5Int64V* %0, i32 0, i32 0,
|
||||
// CHECK-SAME: !dbg ![[LOC1:.*]]
|
||||
// CHECK: ![[LOC0]] = !DILocation(line: 0,
|
||||
|
||||
@@ -4,10 +4,10 @@ func yieldValues() -> Int64? { return .none }
|
||||
|
||||
// Verify that variables bound in the while statements are in distinct scopes.
|
||||
while let val = yieldValues() {
|
||||
// CHECK: ![[SCOPE1:[0-9]+]] = distinct !DILexicalBlock(scope: ![[MAIN:[0-9]+]]
|
||||
// CHECK: !DILocalVariable(name: "val", scope: ![[SCOPE1]]
|
||||
// CHECK: !DILocalVariable(name: "val", scope: ![[SCOPE1:[0-9]+]]
|
||||
// CHECK: ![[SCOPE1]] = distinct !DILexicalBlock(scope: ![[MAIN:[0-9]+]]
|
||||
}
|
||||
while let val = yieldValues() {
|
||||
// CHECK: ![[SCOPE2:[0-9]+]] = distinct !DILexicalBlock(scope: ![[MAIN]]
|
||||
// CHECK: !DILocalVariable(name: "val", scope: ![[SCOPE2]]
|
||||
// CHECK: !DILocalVariable(name: "val", scope: ![[SCOPE2:[0-9]+]]
|
||||
// CHECK: ![[SCOPE2]] = distinct !DILexicalBlock(scope: ![[MAIN]]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user