Skip to content

Commit fd6e8a9

Browse files
committed
Debug Info: Support updates to debug values.
This allows SIL transformations to describe one source variable with more than one debug_value instruction. rdar://problem/22705966
1 parent e423ad0 commit fd6e8a9

File tree

2 files changed

+81
-19
lines changed

2 files changed

+81
-19
lines changed

lib/IRGen/IRGenSIL.cpp

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,9 @@ class IRGenSILFunction :
292292

293293
/// All alloc_ref instructions which allocate the object on the stack.
294294
llvm::SmallPtrSet<SILInstruction *, 8> StackAllocs;
295+
/// Keeps track of the mapping of source variables to -O0 shadow copy allocas.
296+
llvm::SmallDenseMap<std::pair<const SILDebugScope *, StringRef>, Address, 8>
297+
ShadowStackSlots;
295298

296299
/// Accumulative amount of allocated bytes on the stack. Used to limit the
297300
/// size for stack promoted objects.
@@ -483,6 +486,7 @@ class IRGenSILFunction :
483486
/// register pressure is high. There is a trade-off to this: With
484487
/// shadow copies, we lose the precise lifetime.
485488
llvm::Value *emitShadowCopy(llvm::Value *Storage,
489+
const SILDebugScope *Scope,
486490
StringRef Name,
487491
Alignment Align = Alignment(0)) {
488492
auto Ty = Storage->getType();
@@ -495,16 +499,21 @@ class IRGenSILFunction :
495499
if (Align.isZero())
496500
Align = IGM.getPointerAlignment();
497501

498-
auto Alloca = createAlloca(Ty, Align, Name+".addr");
502+
auto &Alloca = ShadowStackSlots[{Scope, Name}];
503+
if (!Alloca.isValid())
504+
Alloca = createAlloca(Ty, Align, Name+".addr");
499505
Builder.CreateStore(Storage, Alloca.getAddress(), Align);
500506
return Alloca.getAddress();
501507
}
502508

503-
llvm::Value *emitShadowCopy(Address storage, StringRef name) {
504-
return emitShadowCopy(storage.getAddress(), name, storage.getAlignment());
509+
llvm::Value *emitShadowCopy(Address Storage, const SILDebugScope *Scope,
510+
StringRef Name) {
511+
return emitShadowCopy(Storage.getAddress(), Scope, Name,
512+
Storage.getAlignment());
505513
}
506514

507-
void emitShadowCopy(ArrayRef<llvm::Value *> vals, StringRef name,
515+
void emitShadowCopy(ArrayRef<llvm::Value *> vals, const SILDebugScope *scope,
516+
StringRef name,
508517
llvm::SmallVectorImpl<llvm::Value *> &copy) {
509518
// Only do this at -O0.
510519
if (IGM.Opts.Optimize) {
@@ -515,7 +524,7 @@ class IRGenSILFunction :
515524
// Single or empty values.
516525
if (vals.size() <= 1) {
517526
for (auto val : vals)
518-
copy.push_back(emitShadowCopy(val, name));
527+
copy.push_back(emitShadowCopy(val, scope, name));
519528
return;
520529
}
521530

@@ -1402,8 +1411,9 @@ void IRGenSILFunction::emitFunctionArgDebugInfo(SILBasicBlock *BB) {
14021411
unsigned ArgNo =
14031412
countArgs(CurSILFn->getDeclContext()) + 1 + BB->getBBArgs().size();
14041413
IGM.DebugInfo->emitVariableDeclaration(
1405-
Builder, emitShadowCopy(ErrorResultSlot.getAddress(), Name), DTI,
1406-
getDebugScope(), Name, ArgNo, IndirectValue, ArtificialValue);
1414+
Builder,
1415+
emitShadowCopy(ErrorResultSlot.getAddress(), getDebugScope(), Name),
1416+
DTI, getDebugScope(), Name, ArgNo, IndirectValue, ArtificialValue);
14071417
}
14081418
}
14091419

@@ -2935,24 +2945,29 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
29352945
if (!IGM.DebugInfo)
29362946
return;
29372947

2938-
VarDecl *Decl = i->getDecl();
2939-
if (!Decl)
2940-
return;
2941-
29422948
auto SILVal = i->getOperand();
29432949
if (isa<SILUndef>(SILVal))
29442950
return;
29452951

29462952
StringRef Name = i->getVarInfo().Name;
2947-
Explosion e = getLoweredExplosion(SILVal);
2948-
DebugTypeInfo DbgTy(Decl, Decl->getType(), getTypeInfo(SILVal.getType()));
2953+
DebugTypeInfo DbgTy;
2954+
SILType SILTy = SILVal.getType();
2955+
if (VarDecl *Decl = i->getDecl())
2956+
DbgTy = DebugTypeInfo(Decl, Decl->getType(), getTypeInfo(SILTy));
2957+
else if (i->getFunction()->isBare() &&
2958+
!SILTy.getSwiftType()->hasArchetype() && !Name.empty())
2959+
// Preliminary support for .sil debug information.
2960+
DbgTy = DebugTypeInfo(SILTy.getSwiftType(), getTypeInfo(SILTy), nullptr);
2961+
else
2962+
return;
29492963
// An inout/lvalue type that is described by a debug value has been
29502964
// promoted by an optimization pass. Unwrap the type.
29512965
DbgTy.unwrapLValueOrInOutType();
29522966

29532967
// Put the value into a stack slot at -Onone.
2954-
llvm::SmallVector<llvm::Value *, 8> Copy;
2955-
emitShadowCopy(e.claimAll(), Name, Copy);
2968+
llvm::SmallVector<llvm::Value *, 8> Copy;
2969+
Explosion e = getLoweredExplosion(SILVal);
2970+
emitShadowCopy(e.claimAll(), i->getDebugScope(), Name, Copy);
29562971
emitDebugVariableDeclaration(Copy, DbgTy, i->getDebugScope(), Name,
29572972
i->getVarInfo().ArgNo);
29582973
}
@@ -2972,9 +2987,9 @@ void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) {
29722987
auto Addr = getLoweredAddress(SILVal).getAddress();
29732988
DebugTypeInfo DbgTy(Decl, Decl->getType(), getTypeInfo(SILVal.getType()));
29742989
// Put the value into a stack slot at -Onone and emit a debug intrinsic.
2975-
emitDebugVariableDeclaration(emitShadowCopy(Addr, Name), DbgTy,
2976-
i->getDebugScope(), Name,
2977-
i->getVarInfo().ArgNo, IndirectValue);
2990+
emitDebugVariableDeclaration(
2991+
emitShadowCopy(Addr, i->getDebugScope(), Name), DbgTy,
2992+
i->getDebugScope(), Name, i->getVarInfo().ArgNo, IndirectValue);
29782993
}
29792994

29802995
void IRGenSILFunction::visitLoadWeakInst(swift::LoadWeakInst *i) {
@@ -3390,7 +3405,7 @@ void IRGenSILFunction::visitAllocBoxInst(swift::AllocBoxInst *i) {
33903405
return;
33913406

33923407
IGM.DebugInfo->emitVariableDeclaration(
3393-
Builder, emitShadowCopy(addr.getAddress(), Name),
3408+
Builder, emitShadowCopy(addr.getAddress(), i->getDebugScope(), Name),
33943409
DebugTypeInfo(Decl, i->getElementType().getSwiftType(), type),
33953410
i->getDebugScope(), Name, 0, IndirectValue);
33963411
}

test/DebugInfo/value-update.sil

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: %target-swift-frontend %s -emit-ir -module-name test -g -o - | FileCheck %s
2+
// REQUIRES: CPU=x86_64
3+
sil_stage canonical
4+
5+
import Builtin
6+
import Swift
7+
import SwiftShims
8+
9+
// test.foo () -> ()
10+
sil @_TF4test3fooFT_T_ : $@convention(thin) () -> () {
11+
bb0:
12+
%1 = integer_literal $Builtin.Int64, 23
13+
%2 = struct $Int (%1 : $Builtin.Int64)
14+
debug_value %2 : $Int, var, name "v"
15+
// CHECK: store i64 23, i64* %[[ALLOCA:.*]], align 8, !dbg
16+
// CHECK: dbg.declare
17+
// function_ref StdlibUnittest._blackHole <A> (A) -> ()
18+
%5 = function_ref @_TF14StdlibUnittest10_blackHoleurFxT_ : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () // user: %8
19+
%6 = tuple ()
20+
%7 = alloc_stack $() // users: %8, %9
21+
%8 = apply %5<()>(%7#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
22+
dealloc_stack %7#0 : $*@local_storage () // id: %9
23+
24+
// CHECK: store i64 42, i64* %[[ALLOCA]], align 8, !dbg
25+
// CHECK-NOT: dbg.declare
26+
%9 = integer_literal $Builtin.Int64, 42 // user: %10
27+
%10 = struct $Int (%9 : $Builtin.Int64) // user: %11
28+
debug_value %10 : $Int, var, name "v"
29+
30+
// function_ref StdlibUnittest._blackHole <A> (A) -> ()
31+
%13 = function_ref @_TF14StdlibUnittest10_blackHoleurFxT_ : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () // user: %16
32+
%14 = tuple ()
33+
%15 = alloc_stack $() // users: %16, %17
34+
%16 = apply %13<()>(%15#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
35+
dealloc_stack %15#0 : $*@local_storage () // id: %17
36+
37+
%18 = tuple () // user: %21
38+
return %18 : $() // id: %21
39+
// CHECK: {{^}}}
40+
}
41+
42+
// Swift.Int.init (_builtinIntegerLiteral : Builtin.Int2048) -> Swift.Int
43+
sil [transparent] [fragile] @_TFSiCfT22_builtinIntegerLiteralBi2048__Si : $@convention(thin) (Builtin.Int2048, @thin Int.Type) -> Int
44+
45+
// StdlibUnittest._blackHole <A> (A) -> ()
46+
sil @_TF14StdlibUnittest10_blackHoleurFxT_ : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
47+

0 commit comments

Comments
 (0)