Skip to content

Commit 0af0b52

Browse files
committed
Attempt to fix debug info under opaque pointers
Based on #66409 With the observation that the pre-opaque world was using bitcast as an indication that the storage type and the type of the variable were different. We can recover this information from the storage type of the alloca and the storage type of the type info.
1 parent 3507409 commit 0af0b52

File tree

4 files changed

+47
-39
lines changed

4 files changed

+47
-39
lines changed

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2817,6 +2817,7 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(
28172817
llvm::DIExpression *Expr, unsigned Line, unsigned Col,
28182818
llvm::DILocalScope *Scope, const SILDebugScope *DS, bool InCoroContext,
28192819
AddrDbgInstrKind AddrDInstKind) {
2820+
Storage = Storage->stripPointerCasts();
28202821
// Set the location/scope of the intrinsic.
28212822
auto *InlinedAt = createInlinedAt(DS);
28222823
auto DL =

lib/IRGen/IRGenSIL.cpp

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -981,17 +981,24 @@ class IRGenSILFunction :
981981
&& !isAnonymous;
982982
}
983983

984-
bool shouldShadowStorage(llvm::Value *Storage) {
985-
return !isa<llvm::AllocaInst>(Storage)
986-
&& !isa<llvm::UndefValue>(Storage)
987-
&& needsShadowCopy(Storage);
984+
bool shouldShadowStorage(llvm::Value *Storage,
985+
llvm::Type *StorageType) {
986+
Storage = Storage->stripPointerCasts();
987+
if (isa<llvm::UndefValue>(Storage))
988+
return false;
989+
if (auto *Alloca = dyn_cast<llvm::AllocaInst>(Storage);
990+
Alloca && Alloca->isStaticAlloca() &&
991+
Alloca->getAllocatedType() == StorageType)
992+
return false;
993+
return needsShadowCopy(Storage);
988994
}
989995

990996
/// At -Onone, emit a shadow copy of an Address in an alloca, so the
991997
/// register allocator doesn't elide the dbg.value intrinsic when
992998
/// register pressure is high. There is a trade-off to this: With
993999
/// shadow copies, we lose the precise lifetime.
9941000
llvm::Value *emitShadowCopyIfNeeded(llvm::Value *Storage,
1001+
llvm::Type *StorageType,
9951002
const SILDebugScope *Scope,
9961003
SILDebugVariable VarInfo,
9971004
bool IsAnonymous, bool WasMoved,
@@ -1011,7 +1018,7 @@ class IRGenSILFunction :
10111018
// This condition must be consistent with emitPoisonDebugValueInst to avoid
10121019
// generating extra shadow copies for debug_value [poison].
10131020
if (!shouldShadowVariable(VarInfo, IsAnonymous)
1014-
|| !shouldShadowStorage(Storage)) {
1021+
|| !shouldShadowStorage(Storage, StorageType)) {
10151022
return Storage;
10161023
}
10171024

@@ -1034,11 +1041,12 @@ class IRGenSILFunction :
10341041
/// Like \c emitShadowCopyIfNeeded() but takes an \c Address instead of an
10351042
/// \c llvm::Value.
10361043
llvm::Value *emitShadowCopyIfNeeded(Address Storage,
1044+
llvm::Type *StorageType,
10371045
const SILDebugScope *Scope,
10381046
SILDebugVariable VarInfo,
10391047
bool IsAnonymous, bool WasMoved) {
1040-
return emitShadowCopyIfNeeded(Storage.getAddress(), Scope, VarInfo,
1041-
IsAnonymous, WasMoved,
1048+
return emitShadowCopyIfNeeded(Storage.getAddress(), StorageType, Scope,
1049+
VarInfo, IsAnonymous, WasMoved,
10421050
Storage.getAlignment());
10431051
}
10441052

@@ -1072,7 +1080,9 @@ class IRGenSILFunction :
10721080
return;
10731081

10741082
if (e.size() == 1) {
1075-
copy.push_back(emitShadowCopyIfNeeded(e.claimNext(), Scope, VarInfo,
1083+
auto &ti = getTypeInfo(SILVal->getType());
1084+
copy.push_back(emitShadowCopyIfNeeded(e.claimNext(), ti.getStorageType(),
1085+
Scope, VarInfo,
10761086
IsAnonymous, WasMoved));
10771087
return;
10781088
}
@@ -1116,7 +1126,7 @@ class IRGenSILFunction :
11161126
llvm::raw_svector_ostream(Buf) << "$pack_count_" << Position;
11171127
auto Name = IGM.Context.getIdentifier(Buf.str());
11181128
SILDebugVariable Var(Name.str(), true, 0);
1119-
Shape = emitShadowCopyIfNeeded(Shape, getDebugScope(), Var, false,
1129+
Shape = emitShadowCopyIfNeeded(Shape, nullptr, getDebugScope(), Var, false,
11201130
false /*was move*/);
11211131
if (IGM.DebugInfo)
11221132
IGM.DebugInfo->emitPackCountParameter(*this, Shape, Var);
@@ -5078,7 +5088,7 @@ void IRGenSILFunction::emitErrorResultVar(CanSILFunctionType FnTy,
50785088
auto Var = DbgValue->getVarInfo();
50795089
assert(Var && "error result without debug info");
50805090
auto Storage =
5081-
emitShadowCopyIfNeeded(ErrorResultSlot.getAddress(), getDebugScope(),
5091+
emitShadowCopyIfNeeded(ErrorResultSlot.getAddress(), nullptr, getDebugScope(),
50825092
*Var, false, false /*was move*/);
50835093
if (!IGM.DebugInfo)
50845094
return;
@@ -5125,7 +5135,7 @@ void IRGenSILFunction::emitPoisonDebugValueInst(DebugValueInst *i) {
51255135
// copy--poison should never affect program behavior. Also filter everything
51265136
// not handled by emitShadowCopyIfNeeded to avoid extra shadow copies.
51275137
if (!shouldShadowVariable(*varInfo, isAnonymous)
5128-
|| !shouldShadowStorage(storage)) {
5138+
|| !shouldShadowStorage(storage, nullptr)) {
51295139
return;
51305140
}
51315141

@@ -5272,13 +5282,15 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
52725282

52735283
// Put the value into a shadow-copy stack slot at -Onone.
52745284
llvm::SmallVector<llvm::Value *, 8> Copy;
5275-
if (IsAddrVal)
5285+
if (IsAddrVal) {
5286+
auto &ti = getTypeInfo(SILVal->getType());
52765287
Copy.emplace_back(emitShadowCopyIfNeeded(
5277-
getLoweredAddress(SILVal).getAddress(), i->getDebugScope(), *VarInfo,
5288+
getLoweredAddress(SILVal).getAddress(), ti.getStorageType(), i->getDebugScope(), *VarInfo,
52785289
IsAnonymous, i->getUsesMoveableValueDebugInfo()));
5279-
else
5290+
} else {
52805291
emitShadowCopyIfNeeded(SILVal, i->getDebugScope(), *VarInfo, IsAnonymous,
52815292
i->getUsesMoveableValueDebugInfo(), Copy);
5293+
}
52825294

52835295
bindArchetypes(DbgTy.getType());
52845296
if (!IGM.DebugInfo)
@@ -5899,9 +5911,10 @@ void IRGenSILFunction::visitAllocBoxInst(swift::AllocBoxInst *i) {
58995911
auto VarInfo = i->getVarInfo();
59005912
if (!VarInfo)
59015913
return;
5902-
5914+
auto &ti = getTypeInfo(SILTy);
59035915
auto Storage =
5904-
emitShadowCopyIfNeeded(boxWithAddr.getAddress(), i->getDebugScope(),
5916+
emitShadowCopyIfNeeded(boxWithAddr.getAddress(), ti.getStorageType(),
5917+
i->getDebugScope(),
59055918
*VarInfo, IsAnonymous, false /*was moved*/);
59065919

59075920
if (!IGM.DebugInfo)

test/DebugInfo/debug_info_expression.sil

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,12 @@ bb0:
2929
// CHECK-SIL-SAME: (name "my_struct", loc "file.swift":8:9, scope {{[0-9]+}})
3030
// CHECK-SIL-SAME type $MyStruct, expr op_deref:op_fragment:#MyStruct.x
3131
debug_value %3 : $*Builtin.Int64, var, (name "my_struct", loc "file.swift":8:9, scope 1), type $MyStruct, expr op_deref:op_fragment:#MyStruct.x, loc "file.swift":9:17, scope 1
32-
// CHECK: llvm.dbg.value(metadata {{.*}}* %[[FIELD_X]], metadata ![[VAR_DECL_MD]]
33-
// CHECK-SAME: !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 0, 64)
34-
// CHECK-NOT: ), !dbg ![[VAR_DECL_MD]]
3532

3633
%4 = alloc_stack $SmallStruct, var, name "small_struct", loc "file.swift":10:11, scope 1
3734
%5 = struct_element_addr %4 : $*SmallStruct, #SmallStruct.z, loc "file.swift":11:13, scope 1
3835
// CHECK: %[[FIELD_Z:.*]] = getelementptr {{.*}} %[[SMALL_STRUCT]]
3936
// If the fragment covers the whole struct, we're not generating the
4037
// DW_OP_LLVM_fragment part.
41-
// CHECK: llvm.dbg.value(metadata {{.*}}* %[[FIELD_Z]], metadata ![[SMALL_VAR_DECL_MD]]
42-
// CHECK-SAME: !DIExpression(DW_OP_deref)
4338
debug_value %5 : $*Builtin.Int64, var, (name "small_struct", loc "file.swift":10:11, scope 1), type $SmallStruct, expr op_deref:op_fragment:#SmallStruct.z, loc "file.swift":11:13, scope 1
4439
dealloc_stack %4 : $*SmallStruct
4540

test/DebugInfo/inlined-generics-basic.swift

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,18 @@ public class C<R> {
4444

4545
// SIL-LABEL: // C.f<A>(_:)
4646
// IR-LABEL: define {{.*}} @"$s1A1CC1fyyqd__lF"
47+
// IR-SAME: nocapture %[[ARG_0:.*]], {{.*}} %[[ARG_S:.*]],
4748
#sourceLocation(file: "f.swift", line: 1)
4849
public func f<S>(_ s: S) {
4950
// SIL: debug_value %0 : $*S, let, name "s", argno 1, expr op_deref, {{.*}} scope [[F]]
5051
// SIL: function_ref {{.*}}yes{{.*}} scope [[F1G1]]
5152
// SIL: function_ref {{.*}}use{{.*}} scope [[F1G3H]]
52-
// IR: dbg.value(metadata %swift.type* %S, metadata ![[MD_1_0:[0-9]+]]
53-
// IR: dbg.value(metadata %swift.opaque* %0, metadata ![[S:[0-9]+]]
54-
// IR: dbg.value(metadata %swift.opaque* %0, metadata ![[GS_T:[0-9]+]]
55-
// IR: dbg.value(metadata %swift.opaque* %0, metadata ![[GS_U:[0-9]+]]
53+
// IR: dbg.value(metadata %swift.type* %[[ARG_S]], metadata ![[MD_1_0:[0-9]+]]
54+
// IR: %[[RS_PAIR:.*]] = alloca i8, i64 %
55+
// IR: dbg.declare({{.*}} %[[RS_PAIR]], metadata ![[GRS_T:[0-9]+]],
56+
// IR: dbg.value(metadata %swift.opaque* %[[ARG_0]], metadata ![[S:[0-9]+]]
57+
// IR: dbg.value(metadata %swift.opaque* %[[ARG_0]], metadata ![[GS_T:[0-9]+]]
58+
// IR: dbg.value(metadata %swift.opaque* %[[ARG_0]], metadata ![[GS_U:[0-9]+]]
5659
// IR: call {{.*}}3use
5760
#sourceLocation(file: "f.swift", line: 2)
5861
g(s)
@@ -67,21 +70,19 @@ public class C<R> {
6770
// IR: call {{.*}}3use
6871
#sourceLocation(file: "f.swift", line: 3)
6972
g(r)
70-
// IR: dbg.value({{.*}}, metadata ![[GRS_T:[0-9]+]]
71-
// IR: dbg.value({{.*}}, metadata ![[GRS_U:[0-9]+]]
7273
// IR: call {{.*}}3use
7374
#sourceLocation(file: "f.swift", line: 4)
7475
g((r, s))
7576
// Note to maintainers: the relative order of the constant dbg.values here
7677
// seem to flip back and forth.
77-
// IR: dbg.value({{.*}}, metadata ![[GI_U:[0-9]+]]
78-
// IR: dbg.value({{.*}}, metadata ![[GI_T:[0-9]+]]
79-
// IR: call {{.*}}3use
78+
// IR: dbg.value(metadata i64 0, metadata ![[GI_U:[0-9]+]]
79+
// IR: dbg.value(metadata i64 0, metadata ![[GI_T:[0-9]+]]
80+
// IR: call {{.*}}3use{{.*}}(i64 0)
8081
#sourceLocation(file: "f.swift", line: 5)
8182
g(Int(0))
82-
// IR: dbg.value({{.*}}, metadata ![[GB_U:[0-9]+]]
83-
// IR: dbg.value({{.*}}, metadata ![[GB_T:[0-9]+]]
84-
// IR: call {{.*}}3use
83+
// IR: dbg.value(metadata i1 false, metadata ![[GB_U:[0-9]+]]
84+
// IR: dbg.value(metadata i1 false, metadata ![[GB_T:[0-9]+]]
85+
// IR: call {{.*}}3use{{.*}}(i1 false)
8586
#sourceLocation(file: "f.swift", line: 6)
8687
g(false)
8788
}
@@ -97,6 +98,10 @@ public class C<R> {
9798
// IR-DAG: ![[LET_TAU_0_0:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[TAU_0_0]])
9899
// IR-DAG: ![[TAU_1_0:[0-9]+]] = {{.*}}DW_TAG_structure_type, name: "$sqd__D", file
99100
// IR-DAG: ![[MD_1_0]] = !DILocalVariable(name: "$\CF\84_1_0"
101+
// IR-DAG: ![[GRS_T]] = !DILocalVariable(name: "t", {{.*}} scope: ![[SP_GRS_T:[0-9]+]], {{.*}}type: ![[LET_TUPLE:[0-9]+]]
102+
// IR-DAG: ![[SP_GRS_T]] = {{.*}}linkageName: "$s1A1gyyxlFx_qd__t_Ti5"
103+
// IR-DAG: ![[LET_TUPLE]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[TUPLE:[0-9]+]])
104+
// IR-DAG: ![[TUPLE]] = {{.*}}DW_TAG_structure_type, name: "$sx_qd__tD"
100105
// IR-DAG: ![[S]] = !DILocalVariable(name: "s", {{.*}} type: ![[LET_TAU_1_0:[0-9]+]]
101106
// IR-DAG: ![[LET_TAU_1_0]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[TAU_1_0]])
102107
// IR-DAG: ![[GS_T]] = !DILocalVariable(name: "t", {{.*}} scope: ![[SP_GS_T:[0-9]+]], {{.*}} type: ![[LET_TAU_1_0]])
@@ -111,12 +116,6 @@ public class C<R> {
111116

112117
// IR: ![[GR_U]] = !DILocalVariable(name: "u", {{.*}} scope: ![[SP_GR_U:[0-9]+]], {{.*}}type: ![[LET_TAU_0_0]])
113118
// IR: ![[SP_GR_U]] = {{.*}}linkageName: "$s1A1hyyxlF"
114-
// IR: ![[GRS_T]] = !DILocalVariable(name: "t", {{.*}} scope: ![[SP_GRS_T:[0-9]+]], {{.*}}type: ![[LET_TUPLE:[0-9]+]]
115-
// IR: ![[SP_GRS_T]] = {{.*}}linkageName: "$s1A1gyyxlFx_qd__t_Ti5"
116-
// IR: ![[LET_TUPLE]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[TUPLE:[0-9]+]])
117-
// IR: ![[TUPLE]] = {{.*}}DW_TAG_structure_type, name: "$sx_qd__tD"
118-
// IR: ![[GRS_U]] = !DILocalVariable(name: "u", {{.*}} scope: ![[SP_GRS_U:[0-9]+]], {{.*}}type: ![[LET_TUPLE]]
119-
// IR: ![[SP_GRS_U]] = {{.*}}linkageName: "$s1A1hyyxlFx_qd__t_Ti5"
120119
// IR-DAG: ![[GI_T]] = !DILocalVariable(name: "t", {{.*}} scope: ![[SP_GI_G:[0-9]+]], {{.*}}type: ![[LET_INT]])
121120
// IR-DAG: ![[SP_GI_G]] = {{.*}}linkageName: "$s1A1gyyxlFSi_Tg5"
122121
// IR-DAG: ![[GI_U]] = !DILocalVariable(name: "u", {{.*}} scope: ![[SP_GI_U:[0-9]+]], {{.*}}type: ![[LET_INT]])

0 commit comments

Comments
 (0)