@@ -225,11 +225,13 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
225
225
Optional<SILLocation> VarLoc,
226
226
SILDebugVariable VarInfo,
227
227
IndirectionKind = DirectValue,
228
- ArtificialKind = RealValue);
228
+ ArtificialKind = RealValue,
229
+ AddrDbgInstrKind = AddrDbgInstrKind::DbgDeclare);
229
230
void emitDbgIntrinsic (IRBuilder &Builder, llvm::Value *Storage,
230
231
llvm::DILocalVariable *Var, llvm::DIExpression *Expr,
231
232
unsigned Line, unsigned Col, llvm::DILocalScope *Scope,
232
- const SILDebugScope *DS, bool InCoroContext);
233
+ const SILDebugScope *DS, bool InCoroContext,
234
+ AddrDbgInstrKind = AddrDbgInstrKind::DbgDeclare);
233
235
234
236
void emitGlobalVariableDeclaration (llvm::GlobalVariable *Storage,
235
237
StringRef Name, StringRef LinkageName,
@@ -2486,7 +2488,7 @@ void IRGenDebugInfoImpl::emitVariableDeclaration(
2486
2488
IRBuilder &Builder, ArrayRef<llvm::Value *> Storage, DebugTypeInfo DbgTy,
2487
2489
const SILDebugScope *DS, Optional<SILLocation> DbgInstLoc,
2488
2490
SILDebugVariable VarInfo, IndirectionKind Indirection,
2489
- ArtificialKind Artificial) {
2491
+ ArtificialKind Artificial, AddrDbgInstrKind AddrDInstrKind ) {
2490
2492
assert (DS && " variable has no scope" );
2491
2493
2492
2494
if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables)
@@ -2620,7 +2622,8 @@ void IRGenDebugInfoImpl::emitVariableDeclaration(
2620
2622
if (DIExpr)
2621
2623
emitDbgIntrinsic (
2622
2624
Builder, Piece, Var, DIExpr, DInstLine, DInstLoc.column , Scope, DS,
2623
- Indirection == CoroDirectValue || Indirection == CoroIndirectValue);
2625
+ Indirection == CoroDirectValue || Indirection == CoroIndirectValue,
2626
+ AddrDInstrKind);
2624
2627
}
2625
2628
2626
2629
// Emit locationless intrinsic for variables that were optimized away.
@@ -2629,14 +2632,16 @@ void IRGenDebugInfoImpl::emitVariableDeclaration(
2629
2632
emitDbgIntrinsic (Builder, llvm::ConstantInt::get (IGM.Int64Ty , 0 ), Var,
2630
2633
DIExpr, DInstLine, DInstLoc.column , Scope, DS,
2631
2634
Indirection == CoroDirectValue ||
2632
- Indirection == CoroIndirectValue);
2635
+ Indirection == CoroIndirectValue,
2636
+ AddrDInstrKind);
2633
2637
}
2634
2638
}
2635
2639
2636
2640
void IRGenDebugInfoImpl::emitDbgIntrinsic (
2637
2641
IRBuilder &Builder, llvm::Value *Storage, llvm::DILocalVariable *Var,
2638
2642
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) {
2640
2645
// Set the location/scope of the intrinsic.
2641
2646
auto *InlinedAt = createInlinedAt (DS);
2642
2647
auto DL =
@@ -2650,12 +2655,11 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(
2650
2655
2651
2656
// Fragment DIExpression cannot cover the whole variable
2652
2657
// or going out-of-bound.
2653
- if (auto Fragment = Expr->getFragmentInfo ())
2658
+ if (auto Fragment = Expr->getFragmentInfo ()) {
2654
2659
if (auto VarSize = Var->getSizeInBits ()) {
2655
2660
unsigned FragSize = Fragment->SizeInBits ;
2656
2661
unsigned FragOffset = Fragment->OffsetInBits ;
2657
- if (FragOffset + FragSize > *VarSize ||
2658
- FragSize == *VarSize) {
2662
+ if (FragOffset + FragSize > *VarSize || FragSize == *VarSize) {
2659
2663
// Drop the fragment part
2660
2664
assert (Expr->isValid ());
2661
2665
// Since this expression is valid, DW_OP_LLVM_fragment
@@ -2664,49 +2668,78 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(
2664
2668
Expr = DBuilder.createExpression (OrigElements.drop_back (3 ));
2665
2669
}
2666
2670
}
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};
2667
2697
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
2670
2699
if (auto *Alloca = dyn_cast<llvm::AllocaInst>(Storage)) {
2671
2700
auto *ParentBB = Alloca->getParent ();
2672
2701
auto InsertBefore = std::next (Alloca->getIterator ());
2673
2702
if (InsertBefore != ParentBB->end ())
2674
- DBuilder. insertDeclare (Alloca, Var, Expr, DL, &*InsertBefore);
2703
+ inserter. insert (Alloca, Var, Expr, DL, &*InsertBefore);
2675
2704
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) {
2685
2717
// Function arguments in async functions are emitted without a shadow copy
2686
2718
// (that would interfer with coroutine splitting) but with a dbg.declare to
2687
2719
// give CoroSplit.cpp license to emit a shadow copy for them pointing inside
2688
2720
// the Swift Context argument that is valid throughout the function.
2689
2721
auto &EntryBlock = BB->getParent ()->getEntryBlock ();
2690
2722
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);
2707
2724
else
2708
- DBuilder.insertDbgValueIntrinsic (Storage, Var, Expr, DL, BB);
2725
+ inserter.insert (Storage, Var, Expr, DL, &EntryBlock);
2726
+ return ;
2709
2727
}
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);
2710
2743
}
2711
2744
2712
2745
void IRGenDebugInfoImpl::emitGlobalVariableDeclaration (
@@ -2875,20 +2908,24 @@ void IRGenDebugInfo::emitArtificialFunction(IRBuilder &Builder,
2875
2908
2876
2909
void IRGenDebugInfo::emitVariableDeclaration (
2877
2910
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) {
2880
2914
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);
2882
2917
}
2883
2918
2884
2919
void IRGenDebugInfo::emitDbgIntrinsic (IRBuilder &Builder, llvm::Value *Storage,
2885
2920
llvm::DILocalVariable *Var,
2886
2921
llvm::DIExpression *Expr, unsigned Line,
2887
2922
unsigned Col, llvm::DILocalScope *Scope,
2888
2923
const SILDebugScope *DS,
2889
- bool InCoroContext) {
2924
+ bool InCoroContext,
2925
+ AddrDbgInstrKind AddrDInstKind) {
2890
2926
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);
2892
2929
}
2893
2930
2894
2931
void IRGenDebugInfo::emitGlobalVariableDeclaration (
0 commit comments