Skip to content

Commit 58e2caf

Browse files
committed
[irgen] Add support to IRGenDebugInfo for emitting an llvm.dbg.addr instead of llvm.dbg.declare.
By default, we still use llvm.dbg.declare, so this is an NFC commit. But this sets us up for using this in the future.
1 parent d7d3fe3 commit 58e2caf

File tree

3 files changed

+112
-52
lines changed

3 files changed

+112
-52
lines changed

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 80 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,13 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
225225
Optional<SILLocation> VarLoc,
226226
SILDebugVariable VarInfo,
227227
IndirectionKind = DirectValue,
228-
ArtificialKind = RealValue);
228+
ArtificialKind = RealValue,
229+
AddrDbgInstrKind = AddrDbgInstrKind::DbgDeclare);
229230
void emitDbgIntrinsic(IRBuilder &Builder, llvm::Value *Storage,
230231
llvm::DILocalVariable *Var, llvm::DIExpression *Expr,
231232
unsigned Line, unsigned Col, llvm::DILocalScope *Scope,
232-
const SILDebugScope *DS, bool InCoroContext);
233+
const SILDebugScope *DS, bool InCoroContext,
234+
AddrDbgInstrKind = AddrDbgInstrKind::DbgDeclare);
233235

234236
void emitGlobalVariableDeclaration(llvm::GlobalVariable *Storage,
235237
StringRef Name, StringRef LinkageName,
@@ -2486,7 +2488,7 @@ void IRGenDebugInfoImpl::emitVariableDeclaration(
24862488
IRBuilder &Builder, ArrayRef<llvm::Value *> Storage, DebugTypeInfo DbgTy,
24872489
const SILDebugScope *DS, Optional<SILLocation> DbgInstLoc,
24882490
SILDebugVariable VarInfo, IndirectionKind Indirection,
2489-
ArtificialKind Artificial) {
2491+
ArtificialKind Artificial, AddrDbgInstrKind AddrDInstrKind) {
24902492
assert(DS && "variable has no scope");
24912493

24922494
if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables)
@@ -2620,7 +2622,8 @@ void IRGenDebugInfoImpl::emitVariableDeclaration(
26202622
if (DIExpr)
26212623
emitDbgIntrinsic(
26222624
Builder, Piece, Var, DIExpr, DInstLine, DInstLoc.column, Scope, DS,
2623-
Indirection == CoroDirectValue || Indirection == CoroIndirectValue);
2625+
Indirection == CoroDirectValue || Indirection == CoroIndirectValue,
2626+
AddrDInstrKind);
26242627
}
26252628

26262629
// Emit locationless intrinsic for variables that were optimized away.
@@ -2629,14 +2632,16 @@ void IRGenDebugInfoImpl::emitVariableDeclaration(
26292632
emitDbgIntrinsic(Builder, llvm::ConstantInt::get(IGM.Int64Ty, 0), Var,
26302633
DIExpr, DInstLine, DInstLoc.column, Scope, DS,
26312634
Indirection == CoroDirectValue ||
2632-
Indirection == CoroIndirectValue);
2635+
Indirection == CoroIndirectValue,
2636+
AddrDInstrKind);
26332637
}
26342638
}
26352639

26362640
void IRGenDebugInfoImpl::emitDbgIntrinsic(
26372641
IRBuilder &Builder, llvm::Value *Storage, llvm::DILocalVariable *Var,
26382642
llvm::DIExpression *Expr, unsigned Line, unsigned Col,
2639-
llvm::DILocalScope *Scope, const SILDebugScope *DS, bool InCoroContext) {
2643+
llvm::DILocalScope *Scope, const SILDebugScope *DS, bool InCoroContext,
2644+
AddrDbgInstrKind AddrDInstKind) {
26402645
// Set the location/scope of the intrinsic.
26412646
auto *InlinedAt = createInlinedAt(DS);
26422647
auto DL =
@@ -2650,12 +2655,11 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(
26502655

26512656
// Fragment DIExpression cannot cover the whole variable
26522657
// or going out-of-bound.
2653-
if (auto Fragment = Expr->getFragmentInfo())
2658+
if (auto Fragment = Expr->getFragmentInfo()) {
26542659
if (auto VarSize = Var->getSizeInBits()) {
26552660
unsigned FragSize = Fragment->SizeInBits;
26562661
unsigned FragOffset = Fragment->OffsetInBits;
2657-
if (FragOffset + FragSize > *VarSize ||
2658-
FragSize == *VarSize) {
2662+
if (FragOffset + FragSize > *VarSize || FragSize == *VarSize) {
26592663
// Drop the fragment part
26602664
assert(Expr->isValid());
26612665
// Since this expression is valid, DW_OP_LLVM_fragment
@@ -2664,49 +2668,78 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(
26642668
Expr = DBuilder.createExpression(OrigElements.drop_back(3));
26652669
}
26662670
}
2671+
}
2672+
2673+
struct DbgInserter {
2674+
llvm::DIBuilder &builder;
2675+
AddrDbgInstrKind forceDbgDeclare;
2676+
2677+
llvm::Instruction *insert(llvm::Value *Addr, llvm::DILocalVariable *VarInfo,
2678+
llvm::DIExpression *Expr,
2679+
const llvm::DILocation *DL,
2680+
llvm::Instruction *InsertBefore) {
2681+
if (forceDbgDeclare == AddrDbgInstrKind::DbgDeclare)
2682+
return builder.insertDeclare(Addr, VarInfo, Expr, DL, InsertBefore);
2683+
return builder.insertDbgAddrIntrinsic(Addr, VarInfo, Expr, DL,
2684+
InsertBefore);
2685+
}
2686+
2687+
llvm::Instruction *insert(llvm::Value *Addr, llvm::DILocalVariable *VarInfo,
2688+
llvm::DIExpression *Expr,
2689+
const llvm::DILocation *DL,
2690+
llvm::BasicBlock *Block) {
2691+
if (forceDbgDeclare == AddrDbgInstrKind::DbgDeclare)
2692+
return builder.insertDeclare(Addr, VarInfo, Expr, DL, Block);
2693+
return builder.insertDbgAddrIntrinsic(Addr, VarInfo, Expr, DL, Block);
2694+
}
2695+
};
2696+
DbgInserter inserter{DBuilder, AddrDInstKind};
26672697

2668-
// A dbg.declare is only meaningful if there is a single alloca for
2669-
// the variable that is live throughout the function.
2698+
// If we have a single alloca, just insert the debug in
26702699
if (auto *Alloca = dyn_cast<llvm::AllocaInst>(Storage)) {
26712700
auto *ParentBB = Alloca->getParent();
26722701
auto InsertBefore = std::next(Alloca->getIterator());
26732702
if (InsertBefore != ParentBB->end())
2674-
DBuilder.insertDeclare(Alloca, Var, Expr, DL, &*InsertBefore);
2703+
inserter.insert(Alloca, Var, Expr, DL, &*InsertBefore);
26752704
else
2676-
DBuilder.insertDeclare(Alloca, Var, Expr, DL, ParentBB);
2677-
} else if ((isa<llvm::IntrinsicInst>(Storage) &&
2678-
cast<llvm::IntrinsicInst>(Storage)->getIntrinsicID() ==
2679-
llvm::Intrinsic::coro_alloca_get)) {
2680-
// FIXME: The live range of a coroutine alloca within the function may be
2681-
// limited, so using a dbg.addr instead of a dbg.declare would be more
2682-
// appropriate.
2683-
DBuilder.insertDeclare(Storage, Var, Expr, DL, BB);
2684-
} else if (InCoroContext) {
2705+
inserter.insert(Alloca, Var, Expr, DL, ParentBB);
2706+
return;
2707+
}
2708+
2709+
if ((isa<llvm::IntrinsicInst>(Storage) &&
2710+
cast<llvm::IntrinsicInst>(Storage)->getIntrinsicID() ==
2711+
llvm::Intrinsic::coro_alloca_get)) {
2712+
inserter.insert(Storage, Var, Expr, DL, BB);
2713+
return;
2714+
}
2715+
2716+
if (InCoroContext) {
26852717
// Function arguments in async functions are emitted without a shadow copy
26862718
// (that would interfer with coroutine splitting) but with a dbg.declare to
26872719
// give CoroSplit.cpp license to emit a shadow copy for them pointing inside
26882720
// the Swift Context argument that is valid throughout the function.
26892721
auto &EntryBlock = BB->getParent()->getEntryBlock();
26902722
if (auto *InsertBefore = &*EntryBlock.getFirstInsertionPt())
2691-
DBuilder.insertDeclare(Storage, Var, Expr, DL, InsertBefore);
2692-
else
2693-
DBuilder.insertDeclare(Storage, Var, Expr, DL, &EntryBlock);
2694-
} else {
2695-
// Insert a dbg.value at the current insertion point.
2696-
if (isa<llvm::Argument>(Storage) && !Var->getArg() &&
2697-
BB->getFirstNonPHIOrDbg())
2698-
// SelectionDAGISel only generates debug info for a dbg.value
2699-
// that is associated with a llvm::Argument if either its !DIVariable
2700-
// is marked as argument or there is no non-debug intrinsic instruction
2701-
// before it. So In the case of associating a llvm::Argument with a
2702-
// non-argument debug variable -- usually via a !DIExpression -- we
2703-
// need to make sure that dbg.value is before any non-phi / no-dbg
2704-
// instruction.
2705-
DBuilder.insertDbgValueIntrinsic(Storage, Var, Expr, DL,
2706-
BB->getFirstNonPHIOrDbg());
2723+
inserter.insert(Storage, Var, Expr, DL, InsertBefore);
27072724
else
2708-
DBuilder.insertDbgValueIntrinsic(Storage, Var, Expr, DL, BB);
2725+
inserter.insert(Storage, Var, Expr, DL, &EntryBlock);
2726+
return;
27092727
}
2728+
2729+
// Insert a dbg.value at the current insertion point.
2730+
if (isa<llvm::Argument>(Storage) && !Var->getArg() &&
2731+
BB->getFirstNonPHIOrDbg())
2732+
// SelectionDAGISel only generates debug info for a dbg.value
2733+
// that is associated with a llvm::Argument if either its !DIVariable
2734+
// is marked as argument or there is no non-debug intrinsic instruction
2735+
// before it. So In the case of associating a llvm::Argument with a
2736+
// non-argument debug variable -- usually via a !DIExpression -- we
2737+
// need to make sure that dbg.value is before any non-phi / no-dbg
2738+
// instruction.
2739+
DBuilder.insertDbgValueIntrinsic(Storage, Var, Expr, DL,
2740+
BB->getFirstNonPHIOrDbg());
2741+
else
2742+
DBuilder.insertDbgValueIntrinsic(Storage, Var, Expr, DL, BB);
27102743
}
27112744

27122745
void IRGenDebugInfoImpl::emitGlobalVariableDeclaration(
@@ -2875,20 +2908,24 @@ void IRGenDebugInfo::emitArtificialFunction(IRBuilder &Builder,
28752908

28762909
void IRGenDebugInfo::emitVariableDeclaration(
28772910
IRBuilder &Builder, ArrayRef<llvm::Value *> Storage, DebugTypeInfo Ty,
2878-
const SILDebugScope *DS, Optional<SILLocation> VarLoc, SILDebugVariable VarInfo,
2879-
IndirectionKind Indirection, ArtificialKind Artificial) {
2911+
const SILDebugScope *DS, Optional<SILLocation> VarLoc,
2912+
SILDebugVariable VarInfo, IndirectionKind Indirection,
2913+
ArtificialKind Artificial, AddrDbgInstrKind AddrDInstKind) {
28802914
static_cast<IRGenDebugInfoImpl *>(this)->emitVariableDeclaration(
2881-
Builder, Storage, Ty, DS, VarLoc, VarInfo, Indirection, Artificial);
2915+
Builder, Storage, Ty, DS, VarLoc, VarInfo, Indirection, Artificial,
2916+
AddrDInstKind);
28822917
}
28832918

28842919
void IRGenDebugInfo::emitDbgIntrinsic(IRBuilder &Builder, llvm::Value *Storage,
28852920
llvm::DILocalVariable *Var,
28862921
llvm::DIExpression *Expr, unsigned Line,
28872922
unsigned Col, llvm::DILocalScope *Scope,
28882923
const SILDebugScope *DS,
2889-
bool InCoroContext) {
2924+
bool InCoroContext,
2925+
AddrDbgInstrKind AddrDInstKind) {
28902926
static_cast<IRGenDebugInfoImpl *>(this)->emitDbgIntrinsic(
2891-
Builder, Storage, Var, Expr, Line, Col, Scope, DS, InCoroContext);
2927+
Builder, Storage, Var, Expr, Line, Col, Scope, DS, InCoroContext,
2928+
AddrDInstKind);
28922929
}
28932930

28942931
void IRGenDebugInfo::emitGlobalVariableDeclaration(

lib/IRGen/IRGenDebugInfo.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ enum IndirectionKind {
4646
};
4747
enum ArtificialKind : bool { RealValue = false, ArtificialValue = true };
4848

49+
/// Used to signal to emitDbgIntrinsic that we actually want to emit dbg.declare
50+
/// instead of dbg.addr. By default, we now emit llvm.dbg.addr instead of
51+
/// llvm.dbg.declare for normal variables. This is not true for metadata which
52+
/// truly are function wide and should be llvm.dbg.declare.
53+
enum class AddrDbgInstrKind : bool {
54+
DbgDeclare,
55+
DbgAddr,
56+
};
57+
4958
/// Helper object that keeps track of the current CompileUnit, File,
5059
/// LexicalScope, and knows how to translate a \c SILLocation into an
5160
/// \c llvm::DebugLoc.
@@ -144,13 +153,19 @@ class IRGenDebugInfo {
144153
Optional<SILLocation> VarLoc,
145154
SILDebugVariable VarInfo,
146155
IndirectionKind Indirection = DirectValue,
147-
ArtificialKind Artificial = RealValue);
148-
149-
/// Emit a dbg.declare or dbg.value intrinsic, depending on Storage.
156+
ArtificialKind Artificial = RealValue,
157+
AddrDbgInstrKind = AddrDbgInstrKind::DbgDeclare);
158+
159+
/// Emit a dbg.addr or dbg.value intrinsic, depending on Storage. If \p
160+
/// ForceDbgDeclare is set to Yes, then instead of emitting a dbg.addr, we
161+
/// will insert a dbg.declare. Please only use that if you know that the given
162+
/// value can never be moved and have its lifetime ended early (e.x.: type
163+
/// metadata).
150164
void emitDbgIntrinsic(IRBuilder &Builder, llvm::Value *Storage,
151165
llvm::DILocalVariable *Var, llvm::DIExpression *Expr,
152166
unsigned Line, unsigned Col, llvm::DILocalScope *Scope,
153-
const SILDebugScope *DS, bool InCoroContext = false);
167+
const SILDebugScope *DS, bool InCoroContext = false,
168+
AddrDbgInstrKind = AddrDbgInstrKind::DbgDeclare);
154169

155170
enum { NotHeapAllocated = false };
156171

lib/IRGen/IRGenSIL.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,8 @@ class IRGenSILFunction :
10571057
SILType SILTy, const SILDebugScope *DS,
10581058
SILLocation VarLoc,
10591059
SILDebugVariable VarInfo,
1060-
IndirectionKind Indirection) {
1060+
IndirectionKind Indirection,
1061+
AddrDbgInstrKind DbgInstrKind = AddrDbgInstrKind::DbgDeclare) {
10611062
// TODO: fix demangling for C++ types (SR-13223).
10621063
if (swift::TypeBase *ty = SILTy.getASTType().getPointer()) {
10631064
if (MetatypeType *metaTy = dyn_cast<MetatypeType>(ty))
@@ -1072,10 +1073,12 @@ class IRGenSILFunction :
10721073
if (VarInfo.ArgNo) {
10731074
PrologueLocation AutoRestore(IGM.DebugInfo.get(), Builder);
10741075
IGM.DebugInfo->emitVariableDeclaration(Builder, Storage, Ty, DS, VarLoc,
1075-
VarInfo, Indirection);
1076+
VarInfo, Indirection, ArtificialKind::RealValue,
1077+
DbgInstrKind);
10761078
} else
10771079
IGM.DebugInfo->emitVariableDeclaration(Builder, Storage, Ty, DS, VarLoc,
1078-
VarInfo, Indirection);
1080+
VarInfo, Indirection, ArtificialKind::RealValue,
1081+
DbgInstrKind);
10791082
}
10801083

10811084
void emitFailBB() {
@@ -4914,7 +4917,11 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
49144917
auto funcTy = CurSILFn->getLoweredFunctionType();
49154918
emitErrorResultVar(funcTy, funcTy->getErrorResult(), i);
49164919
}
4917-
return;
4920+
4921+
// If we were not moved return early. If this SILUndef was moved, then we
4922+
// need to let it through so we can ensure the debug info invalidated.
4923+
if (!i->getWasMoved())
4924+
return;
49184925
}
49194926
bool IsInCoro = InCoroContext(*CurSILFn, *i);
49204927

@@ -4974,7 +4981,8 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
49744981
return;
49754982

49764983
emitDebugVariableDeclaration(Copy, DbgTy, SILTy, i->getDebugScope(),
4977-
i->getLoc(), *VarInfo, Indirection);
4984+
i->getLoc(), *VarInfo, Indirection,
4985+
AddrDbgInstrKind(i->getWasMoved()));
49784986
}
49794987

49804988
void IRGenSILFunction::visitFixLifetimeInst(swift::FixLifetimeInst *i) {

0 commit comments

Comments
 (0)