1515// ===----------------------------------------------------------------------===//
1616
1717#define DEBUG_TYPE " debug-info"
18+
1819#include " IRGenDebugInfo.h"
1920#include " GenOpaque.h"
2021#include " GenStruct.h"
2122#include " GenType.h"
23+ #include " IRBuilder.h"
2224#include " swift/AST/ASTMangler.h"
2325#include " swift/AST/Expr.h"
2426#include " swift/AST/GenericEnvironment.h"
4951#include " clang/Serialization/ASTReader.h"
5052#include " llvm/ADT/StringSet.h"
5153#include " llvm/Config/config.h"
54+ #include " llvm/IR/Constants.h"
5255#include " llvm/IR/DIBuilder.h"
5356#include " llvm/IR/DebugInfo.h"
5457#include " llvm/IR/IntrinsicInst.h"
@@ -2655,6 +2658,67 @@ void IRGenDebugInfoImpl::emitVariableDeclaration(
26552658 }
26562659}
26572660
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+
26582722void IRGenDebugInfoImpl::emitDbgIntrinsic (
26592723 IRBuilder &Builder, llvm::Value *Storage, llvm::DILocalVariable *Var,
26602724 llvm::DIExpression *Expr, unsigned Line, unsigned Col,
@@ -2687,73 +2751,94 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(
26872751 }
26882752 }
26892753
2690- struct DbgInserter {
2691- llvm::DIBuilder &builder;
2692- AddrDbgInstrKind forceDbgDeclare;
2754+ auto *ParentBlock = Builder.GetInsertBlock ();
26932755
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+ }
27032763
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};
27142765
27152766 // If we have a single alloca...
27162767 if (auto *Alloca = dyn_cast<llvm::AllocaInst>(Storage)) {
2717- auto *ParentBB = Builder.GetInsertBlock ();
27182768 auto InsertBefore = Builder.GetInsertPoint ();
27192769
27202770 if (AddrDInstKind == AddrDbgInstrKind::DbgDeclare) {
2721- ParentBB = Alloca->getParent ();
2771+ ParentBlock = Alloca->getParent ();
27222772 InsertBefore = std::next (Alloca->getIterator ());
27232773 }
27242774
2725- if (InsertBefore != ParentBB ->end ()) {
2775+ if (InsertBefore != ParentBlock ->end ()) {
27262776 inserter.insert (Alloca, Var, Expr, DL, &*InsertBefore);
27272777 } else {
2728- inserter.insert (Alloca, Var, Expr, DL, ParentBB );
2778+ inserter.insert (Alloca, Var, Expr, DL, ParentBlock );
27292779 }
27302780 return ;
27312781 }
27322782
2733- auto *BB = Builder.GetInsertBlock ();
27342783 if ((isa<llvm::IntrinsicInst>(Storage) &&
27352784 cast<llvm::IntrinsicInst>(Storage)->getIntrinsicID () ==
27362785 llvm::Intrinsic::coro_alloca_get)) {
2737- inserter.insert (Storage, Var, Expr, DL, BB );
2786+ inserter.insert (Storage, Var, Expr, DL, ParentBlock );
27382787 return ;
27392788 }
27402789
27412790 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 *>()) {
27482831 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+ }
27512836 return ;
27522837 }
27532838
27542839 // Insert a dbg.value at the current insertion point.
27552840 if (isa<llvm::Argument>(Storage) && !Var->getArg () &&
2756- BB ->getFirstNonPHIOrDbg ())
2841+ ParentBlock ->getFirstNonPHIOrDbg ())
27572842 // SelectionDAGISel only generates debug info for a dbg.value
27582843 // that is associated with a llvm::Argument if either its !DIVariable
27592844 // is marked as argument or there is no non-debug intrinsic instruction
@@ -2762,9 +2847,9 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(
27622847 // need to make sure that dbg.value is before any non-phi / no-dbg
27632848 // instruction.
27642849 DBuilder.insertDbgValueIntrinsic (Storage, Var, Expr, DL,
2765- BB ->getFirstNonPHIOrDbg ());
2850+ ParentBlock ->getFirstNonPHIOrDbg ());
27662851 else
2767- DBuilder.insertDbgValueIntrinsic (Storage, Var, Expr, DL, BB );
2852+ DBuilder.insertDbgValueIntrinsic (Storage, Var, Expr, DL, ParentBlock );
27682853}
27692854
27702855void IRGenDebugInfoImpl::emitGlobalVariableDeclaration (
0 commit comments