Skip to content

Commit e1c4e10

Browse files
committed
[move-function] Update the behavior for debug intrinsics on values in the coroutine frame.
This uses the previous simple dominance dbg info propagation implementation in the previous commit. I fix in the next commit the debug info for the last move/reinit in the var test.
1 parent 056132c commit e1c4e10

File tree

2 files changed

+295
-39
lines changed

2 files changed

+295
-39
lines changed

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 124 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
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"
@@ -49,6 +51,7 @@
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+
26582722
void 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

27702855
void IRGenDebugInfoImpl::emitGlobalVariableDeclaration(

0 commit comments

Comments
 (0)