Skip to content

Commit 0d4dec1

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 90c7193 commit 0d4dec1

File tree

4 files changed

+47
-39
lines changed

4 files changed

+47
-39
lines changed

lib/IRGen/IRGenDebugInfo.cpp

+1
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

+29-16
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);
@@ -5061,7 +5071,7 @@ void IRGenSILFunction::emitErrorResultVar(CanSILFunctionType FnTy,
50615071
auto Var = DbgValue->getVarInfo();
50625072
assert(Var && "error result without debug info");
50635073
auto Storage =
5064-
emitShadowCopyIfNeeded(ErrorResultSlot.getAddress(), getDebugScope(),
5074+
emitShadowCopyIfNeeded(ErrorResultSlot.getAddress(), nullptr, getDebugScope(),
50655075
*Var, false, false /*was move*/);
50665076
if (!IGM.DebugInfo)
50675077
return;
@@ -5108,7 +5118,7 @@ void IRGenSILFunction::emitPoisonDebugValueInst(DebugValueInst *i) {
51085118
// copy--poison should never affect program behavior. Also filter everything
51095119
// not handled by emitShadowCopyIfNeeded to avoid extra shadow copies.
51105120
if (!shouldShadowVariable(*varInfo, isAnonymous)
5111-
|| !shouldShadowStorage(storage)) {
5121+
|| !shouldShadowStorage(storage, nullptr)) {
51125122
return;
51135123
}
51145124

@@ -5255,13 +5265,15 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
52555265

52565266
// Put the value into a shadow-copy stack slot at -Onone.
52575267
llvm::SmallVector<llvm::Value *, 8> Copy;
5258-
if (IsAddrVal)
5268+
if (IsAddrVal) {
5269+
auto &ti = getTypeInfo(SILVal->getType());
52595270
Copy.emplace_back(emitShadowCopyIfNeeded(
5260-
getLoweredAddress(SILVal).getAddress(), i->getDebugScope(), *VarInfo,
5271+
getLoweredAddress(SILVal).getAddress(), ti.getStorageType(), i->getDebugScope(), *VarInfo,
52615272
IsAnonymous, i->getUsesMoveableValueDebugInfo()));
5262-
else
5273+
} else {
52635274
emitShadowCopyIfNeeded(SILVal, i->getDebugScope(), *VarInfo, IsAnonymous,
52645275
i->getUsesMoveableValueDebugInfo(), Copy);
5276+
}
52655277

52665278
bindArchetypes(DbgTy.getType());
52675279
if (!IGM.DebugInfo)
@@ -5882,9 +5894,10 @@ void IRGenSILFunction::visitAllocBoxInst(swift::AllocBoxInst *i) {
58825894
auto VarInfo = i->getVarInfo();
58835895
if (!VarInfo)
58845896
return;
5885-
5897+
auto &ti = getTypeInfo(SILTy);
58865898
auto Storage =
5887-
emitShadowCopyIfNeeded(boxWithAddr.getAddress(), i->getDebugScope(),
5899+
emitShadowCopyIfNeeded(boxWithAddr.getAddress(), ti.getStorageType(),
5900+
i->getDebugScope(),
58885901
*VarInfo, IsAnonymous, false /*was moved*/);
58895902

58905903
if (!IGM.DebugInfo)

test/DebugInfo/debug_info_expression.sil

-5
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

+17-18
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)