Skip to content

Commit dc597b8

Browse files
authored
Merge pull request #41379 from gottesmm/pr-aa7d71cdb8ea8518b4d7e9b78a9f99d91639c1c0
[irgen] Add support to IRGenDebugInfo for emitting an llvm.dbg.addr instead of llvm.dbg.declare.
2 parents 35cef58 + 504fe52 commit dc597b8

File tree

6 files changed

+223
-57
lines changed

6 files changed

+223
-57
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() {
@@ -4929,7 +4932,11 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
49294932
auto funcTy = CurSILFn->getLoweredFunctionType();
49304933
emitErrorResultVar(funcTy, funcTy->getErrorResult(), i);
49314934
}
4932-
return;
4935+
4936+
// If we were not moved return early. If this SILUndef was moved, then we
4937+
// need to let it through so we can ensure the debug info invalidated.
4938+
if (!i->getWasMoved())
4939+
return;
49334940
}
49344941
bool IsInCoro = InCoroContext(*CurSILFn, *i);
49354942

@@ -4989,7 +4996,8 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
49894996
return;
49904997

49914998
emitDebugVariableDeclaration(Copy, DbgTy, SILTy, i->getDebugScope(),
4992-
i->getLoc(), *VarInfo, Indirection);
4999+
i->getLoc(), *VarInfo, Indirection,
5000+
AddrDbgInstrKind(i->getWasMoved()));
49935001
}
49945002

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

lib/SILOptimizer/Mandatory/MoveKillsCopyableAddressesChecker.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1767,7 +1767,7 @@ bool DataflowState::process(
17671767
debug.markAsMoved();
17681768
if (auto varInfo = debug.getVarInfo()) {
17691769
builder.createDebugValue(
1770-
mvi->getLoc(),
1770+
debug.inst->getLoc(),
17711771
SILUndef::get(address->getType(), builder.getModule()), *varInfo,
17721772
false /*poison*/, true /*was moved*/);
17731773
}
@@ -1913,7 +1913,7 @@ static bool performSingleBasicBlockAnalysis(DataflowState &dataflowState,
19131913
if (auto debug = DebugVarCarryingInst::getFromValue(address)) {
19141914
if (auto varInfo = debug.getVarInfo()) {
19151915
builder.createDebugValue(
1916-
mvi->getLoc(),
1916+
debug.inst->getLoc(),
19171917
SILUndef::get(address->getType(), builder.getModule()), *varInfo,
19181918
false,
19191919
/*was moved*/ true);
@@ -2021,7 +2021,7 @@ static bool performSingleBasicBlockAnalysis(DataflowState &dataflowState,
20212021
if (auto debug = DebugVarCarryingInst::getFromValue(address)) {
20222022
if (auto varInfo = debug.getVarInfo()) {
20232023
builder.createDebugValue(
2024-
mvi->getLoc(),
2024+
debug.inst->getLoc(),
20252025
SILUndef::get(address->getType(), builder.getModule()), *varInfo,
20262026
false,
20272027
/*was moved*/ true);
@@ -2060,7 +2060,7 @@ static bool performSingleBasicBlockAnalysis(DataflowState &dataflowState,
20602060
if (auto debug = DebugVarCarryingInst::getFromValue(address)) {
20612061
if (auto varInfo = debug.getVarInfo()) {
20622062
builder.createDebugValue(
2063-
mvi->getLoc(),
2063+
debug.inst->getLoc(),
20642064
SILUndef::get(address->getType(), builder.getModule()), *varInfo,
20652065
false,
20662066
/*was moved*/ true);

lib/SILOptimizer/Mandatory/MoveKillsCopyableValuesChecker.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ bool MoveKillsCopyableValuesChecker::check() {
400400
// Use an autogenerated location to ensure that if we are next to a
401401
// terminator, we don't assert.
402402
builder.createDebugValue(
403-
RegularLocation::getAutoGeneratedLocation(),
403+
dbgVarInfo.inst->getLoc(),
404404
SILUndef::get(mvi->getOperand()->getType(), mod), *varInfo,
405405
false /*poison*/, true /*moved*/);
406406
}

0 commit comments

Comments
 (0)