15
15
// ===----------------------------------------------------------------------===//
16
16
17
17
#define DEBUG_TYPE " debug-info"
18
+
18
19
#include " IRGenDebugInfo.h"
19
20
#include " GenOpaque.h"
20
21
#include " GenStruct.h"
21
22
#include " GenType.h"
23
+ #include " IRBuilder.h"
22
24
#include " swift/AST/ASTMangler.h"
23
25
#include " swift/AST/Expr.h"
24
26
#include " swift/AST/GenericEnvironment.h"
49
51
#include " clang/Serialization/ASTReader.h"
50
52
#include " llvm/ADT/StringSet.h"
51
53
#include " llvm/Config/config.h"
54
+ #include " llvm/IR/Constants.h"
52
55
#include " llvm/IR/DIBuilder.h"
53
56
#include " llvm/IR/DebugInfo.h"
54
57
#include " llvm/IR/IntrinsicInst.h"
@@ -2655,6 +2658,67 @@ void IRGenDebugInfoImpl::emitVariableDeclaration(
2655
2658
}
2656
2659
}
2657
2660
2661
+ namespace {
2662
+
2663
+ // / A helper struct that is used by emitDbgIntrinsic to factor redundant code.
2664
+ struct DbgIntrinsicEmitter {
2665
+ PointerUnion<llvm::BasicBlock *, llvm::Instruction *> InsertPt;
2666
+ irgen::IRBuilder &IRBuilder;
2667
+ llvm::DIBuilder &DIBuilder;
2668
+ AddrDbgInstrKind ForceDbgDeclare;
2669
+
2670
+ // / Initialize the emitter and initialize the emitter to assume that it is
2671
+ // / going to insert an llvm.dbg.declare or an llvm.dbg.addr either at the
2672
+ // / current "generalized insertion point" of the IRBuilder. The "generalized
2673
+ // / insertion point" is
2674
+ DbgIntrinsicEmitter (irgen::IRBuilder &IRBuilder, llvm::DIBuilder &DIBuilder,
2675
+ AddrDbgInstrKind ForceDebugDeclare)
2676
+ : InsertPt(), IRBuilder(IRBuilder), DIBuilder(DIBuilder),
2677
+ ForceDbgDeclare (ForceDebugDeclare) {
2678
+ auto *ParentBB = IRBuilder.GetInsertBlock ();
2679
+ auto InsertBefore = IRBuilder.GetInsertPoint ();
2680
+
2681
+ if (InsertBefore != ParentBB->end ())
2682
+ InsertPt = &*InsertBefore;
2683
+ else
2684
+ InsertPt = ParentBB;
2685
+ }
2686
+
2687
+ // /
2688
+
2689
+ llvm::Instruction *insert (llvm::Value *Addr, llvm::DILocalVariable *VarInfo,
2690
+ llvm::DIExpression *Expr,
2691
+ const llvm::DILocation *DL) {
2692
+ if (auto *Inst = InsertPt.dyn_cast <llvm::Instruction *>()) {
2693
+ return insert (Addr, VarInfo, Expr, DL, Inst);
2694
+ } else {
2695
+ return insert (Addr, VarInfo, Expr, DL,
2696
+ InsertPt.get <llvm::BasicBlock *>());
2697
+ }
2698
+ }
2699
+
2700
+ llvm::Instruction *insert (llvm::Value *Addr, llvm::DILocalVariable *VarInfo,
2701
+ llvm::DIExpression *Expr,
2702
+ const llvm::DILocation *DL,
2703
+ llvm::Instruction *InsertBefore) {
2704
+ if (ForceDbgDeclare == AddrDbgInstrKind::DbgDeclare)
2705
+ return DIBuilder.insertDeclare (Addr, VarInfo, Expr, DL, InsertBefore);
2706
+ return DIBuilder.insertDbgAddrIntrinsic (Addr, VarInfo, Expr, DL,
2707
+ InsertBefore);
2708
+ }
2709
+
2710
+ llvm::Instruction *insert (llvm::Value *Addr, llvm::DILocalVariable *VarInfo,
2711
+ llvm::DIExpression *Expr,
2712
+ const llvm::DILocation *DL,
2713
+ llvm::BasicBlock *Block) {
2714
+ if (ForceDbgDeclare == AddrDbgInstrKind::DbgDeclare)
2715
+ return DIBuilder.insertDeclare (Addr, VarInfo, Expr, DL, Block);
2716
+ return DIBuilder.insertDbgAddrIntrinsic (Addr, VarInfo, Expr, DL, Block);
2717
+ }
2718
+ };
2719
+
2720
+ } // namespace
2721
+
2658
2722
void IRGenDebugInfoImpl::emitDbgIntrinsic (
2659
2723
IRBuilder &Builder, llvm::Value *Storage, llvm::DILocalVariable *Var,
2660
2724
llvm::DIExpression *Expr, unsigned Line, unsigned Col,
@@ -2687,73 +2751,94 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(
2687
2751
}
2688
2752
}
2689
2753
2690
- struct DbgInserter {
2691
- llvm::DIBuilder &builder;
2692
- AddrDbgInstrKind forceDbgDeclare;
2754
+ auto *ParentBlock = Builder.GetInsertBlock ();
2693
2755
2694
- llvm::Instruction *insert (llvm::Value *Addr, llvm::DILocalVariable *VarInfo,
2695
- llvm::DIExpression *Expr,
2696
- const llvm::DILocation *DL,
2697
- llvm::Instruction *InsertBefore) {
2698
- if (forceDbgDeclare == AddrDbgInstrKind::DbgDeclare)
2699
- return builder.insertDeclare (Addr, VarInfo, Expr, DL, InsertBefore);
2700
- return builder.insertDbgAddrIntrinsic (Addr, VarInfo, Expr, DL,
2701
- InsertBefore);
2702
- }
2756
+ // First before we do anything, check if we have an Undef. In this case, we
2757
+ // /always/ emit an llvm.dbg.value of undef.
2758
+ // If we have undef, always emit a llvm.dbg.value in the current position.
2759
+ if (isa<llvm::UndefValue>(Storage)) {
2760
+ DBuilder.insertDbgValueIntrinsic (Storage, Var, Expr, DL, ParentBlock);
2761
+ return ;
2762
+ }
2703
2763
2704
- llvm::Instruction *insert (llvm::Value *Addr, llvm::DILocalVariable *VarInfo,
2705
- llvm::DIExpression *Expr,
2706
- const llvm::DILocation *DL,
2707
- llvm::BasicBlock *Block) {
2708
- if (forceDbgDeclare == AddrDbgInstrKind::DbgDeclare)
2709
- return builder.insertDeclare (Addr, VarInfo, Expr, DL, Block);
2710
- return builder.insertDbgAddrIntrinsic (Addr, VarInfo, Expr, DL, Block);
2711
- }
2712
- };
2713
- DbgInserter inserter{DBuilder, AddrDInstKind};
2764
+ DbgIntrinsicEmitter inserter{Builder, DBuilder, AddrDInstKind};
2714
2765
2715
2766
// If we have a single alloca...
2716
2767
if (auto *Alloca = dyn_cast<llvm::AllocaInst>(Storage)) {
2717
- auto *ParentBB = Builder.GetInsertBlock ();
2718
2768
auto InsertBefore = Builder.GetInsertPoint ();
2719
2769
2720
2770
if (AddrDInstKind == AddrDbgInstrKind::DbgDeclare) {
2721
- ParentBB = Alloca->getParent ();
2771
+ ParentBlock = Alloca->getParent ();
2722
2772
InsertBefore = std::next (Alloca->getIterator ());
2723
2773
}
2724
2774
2725
- if (InsertBefore != ParentBB ->end ()) {
2775
+ if (InsertBefore != ParentBlock ->end ()) {
2726
2776
inserter.insert (Alloca, Var, Expr, DL, &*InsertBefore);
2727
2777
} else {
2728
- inserter.insert (Alloca, Var, Expr, DL, ParentBB );
2778
+ inserter.insert (Alloca, Var, Expr, DL, ParentBlock );
2729
2779
}
2730
2780
return ;
2731
2781
}
2732
2782
2733
- auto *BB = Builder.GetInsertBlock ();
2734
2783
if ((isa<llvm::IntrinsicInst>(Storage) &&
2735
2784
cast<llvm::IntrinsicInst>(Storage)->getIntrinsicID () ==
2736
2785
llvm::Intrinsic::coro_alloca_get)) {
2737
- inserter.insert (Storage, Var, Expr, DL, BB );
2786
+ inserter.insert (Storage, Var, Expr, DL, ParentBlock );
2738
2787
return ;
2739
2788
}
2740
2789
2741
2790
if (InCoroContext) {
2742
- // Function arguments in async functions are emitted without a shadow copy
2743
- // (that would interfer with coroutine splitting) but with a dbg.declare to
2744
- // give CoroSplit.cpp license to emit a shadow copy for them pointing inside
2745
- // the Swift Context argument that is valid throughout the function.
2746
- auto &EntryBlock = BB->getParent ()->getEntryBlock ();
2747
- if (auto *InsertBefore = &*EntryBlock.getFirstInsertionPt ())
2791
+ PointerUnion<llvm::BasicBlock *, llvm::Instruction *> InsertPt;
2792
+
2793
+ // If we have a dbg.declare, we are relying on a contract with the coroutine
2794
+ // splitter that in split coroutines we always create debug info for values
2795
+ // in the coroutine context by creating a llvm.dbg.declare for the variable
2796
+ // in the entry block of each funclet.
2797
+ if (AddrDInstKind == AddrDbgInstrKind::DbgDeclare) {
2798
+ // Function arguments in async functions are emitted without a shadow copy
2799
+ // (that would interfer with coroutine splitting) but with a
2800
+ // llvm.dbg.declare to give CoroSplit.cpp license to emit a shadow copy
2801
+ // for them pointing inside the Swift Context argument that is valid
2802
+ // throughout the function.
2803
+ auto &EntryBlock = ParentBlock->getParent ()->getEntryBlock ();
2804
+ if (auto *InsertBefore = &*EntryBlock.getFirstInsertionPt ()) {
2805
+ InsertPt = InsertBefore;
2806
+ } else {
2807
+ InsertPt = &EntryBlock;
2808
+ }
2809
+ } else {
2810
+ // For llvm.dbg.addr, we just want to insert the intrinsic at the current
2811
+ // insertion point. This is because our contract with the coroutine
2812
+ // splitter is that the coroutine splitter just needs to emit the
2813
+ // llvm.dbg.addr where we placed them. It shouldn't move them or do
2814
+ // anything special with it. Instead, we have previously inserted extra
2815
+ // debug_value clones previously after each instruction at the SIL level
2816
+ // that corresponds with a funclet edge. This operation effectively sets
2817
+ // up the rest of the pipeline to be stupid and just emit the
2818
+ // llvm.dbg.addr in the correct places. This is done by the SILOptimizer
2819
+ // pass DebugInfoCanonicalizer.
2820
+ auto InsertBefore = Builder.GetInsertPoint ();
2821
+ if (InsertBefore != ParentBlock->end ()) {
2822
+ InsertPt = &*InsertBefore;
2823
+ } else {
2824
+ InsertPt = ParentBlock;
2825
+ }
2826
+ }
2827
+
2828
+ // Ok, we now have our insert pt. Call the appropriate operations.
2829
+ assert (InsertPt);
2830
+ if (auto *InsertBefore = InsertPt.dyn_cast <llvm::Instruction *>()) {
2748
2831
inserter.insert (Storage, Var, Expr, DL, InsertBefore);
2749
- else
2750
- inserter.insert (Storage, Var, Expr, DL, &EntryBlock);
2832
+ } else {
2833
+ inserter.insert (Storage, Var, Expr, DL,
2834
+ InsertPt.get <llvm::BasicBlock *>());
2835
+ }
2751
2836
return ;
2752
2837
}
2753
2838
2754
2839
// Insert a dbg.value at the current insertion point.
2755
2840
if (isa<llvm::Argument>(Storage) && !Var->getArg () &&
2756
- BB ->getFirstNonPHIOrDbg ())
2841
+ ParentBlock ->getFirstNonPHIOrDbg ())
2757
2842
// SelectionDAGISel only generates debug info for a dbg.value
2758
2843
// that is associated with a llvm::Argument if either its !DIVariable
2759
2844
// is marked as argument or there is no non-debug intrinsic instruction
@@ -2762,9 +2847,9 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(
2762
2847
// need to make sure that dbg.value is before any non-phi / no-dbg
2763
2848
// instruction.
2764
2849
DBuilder.insertDbgValueIntrinsic (Storage, Var, Expr, DL,
2765
- BB ->getFirstNonPHIOrDbg ());
2850
+ ParentBlock ->getFirstNonPHIOrDbg ());
2766
2851
else
2767
- DBuilder.insertDbgValueIntrinsic (Storage, Var, Expr, DL, BB );
2852
+ DBuilder.insertDbgValueIntrinsic (Storage, Var, Expr, DL, ParentBlock );
2768
2853
}
2769
2854
2770
2855
void IRGenDebugInfoImpl::emitGlobalVariableDeclaration (
0 commit comments