Index: include/llvm/CodeGen/AsmPrinter.h =================================================================== --- include/llvm/CodeGen/AsmPrinter.h +++ include/llvm/CodeGen/AsmPrinter.h @@ -223,6 +223,9 @@ void EmitToStreamer(MCStreamer &S, const MCInst &Inst); + /// Emits inital debug location directive. + void emitInitialRawDwarfLocDirective(const MachineFunction &MF); + /// Return the current section we are emitting to. const MCSection *getCurrentSection() const; Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -229,6 +229,12 @@ S.EmitInstruction(Inst, getSubtargetInfo()); } +void AsmPrinter::emitInitialRawDwarfLocDirective(const MachineFunction &MF) { + assert(DD && "Dwarf debug file is not defined."); + assert(OutStreamer->hasRawTextSupport() && "Expected assembly output mode."); + (void)DD->emitInitialLocDirective(MF); +} + /// getCurrentSection() - Return the current section we are emitting to. const MCSection *AsmPrinter::getCurrentSection() const { return OutStreamer->getCurrentSectionOnly(); Index: lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.h +++ lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -466,7 +466,7 @@ /// label that was emitted and which provides correspondence to the /// source line list. void recordSourceLine(unsigned Line, unsigned Col, const MDNode *Scope, - unsigned Flags); + unsigned Flags, Optional CUID = None); /// Populate LexicalScope entries with variables' info. void collectVariableInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP, @@ -508,6 +508,10 @@ /// Emit all Dwarf sections that should come after the content. void endModule() override; + /// Emits inital debug location directive. + DebugLoc emitInitialLocDirective(const MachineFunction &MF, + unsigned CUID = 0); + /// Process beginning of an instruction. void beginInstruction(const MachineInstr *MI) override; Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1366,13 +1366,31 @@ return DebugLoc(); } +DebugLoc DwarfDebug::emitInitialLocDirective(const MachineFunction &MF, + unsigned CUID) { + // Get beginning of function. + if (DebugLoc PrologEndLoc = findPrologueEndLoc(&MF)) { + // Ensure the compile unit is created if the function is called before + // beginFunction(). + (void)getOrCreateDwarfCompileUnit( + MF.getFunction().getSubprogram()->getUnit()); + // We'd like to list the prologue as "not statements" but GDB behaves + // poorly if we do that. Revisit this with caution/GDB (7.5+) testing. + const DISubprogram *SP = PrologEndLoc->getInlinedAtScope()->getSubprogram(); + recordSourceLine(SP->getScopeLine(), 0, SP, DWARF2_FLAG_IS_STMT, CUID); + return PrologEndLoc; + } + return DebugLoc(); +} + // Gather pre-function debug information. Assumes being called immediately // after the function entry point has been emitted. void DwarfDebug::beginFunctionImpl(const MachineFunction *MF) { CurFn = MF; - auto *SP = MF->getFunction().getSubprogram(); - assert(LScopes.empty() || SP == LScopes.getCurrentFunctionScope()->getScopeNode()); + const DISubprogram *SP = MF->getFunction().getSubprogram(); + assert(LScopes.empty() || + SP == LScopes.getCurrentFunctionScope()->getScopeNode()); if (SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug) return; @@ -1388,13 +1406,8 @@ Asm->OutStreamer->getContext().setDwarfCompileUnitID(CU.getUniqueID()); // Record beginning of function. - PrologEndLoc = findPrologueEndLoc(MF); - if (PrologEndLoc) { - // We'd like to list the prologue as "not statements" but GDB behaves - // poorly if we do that. Revisit this with caution/GDB (7.5+) testing. - auto *SP = PrologEndLoc->getInlinedAtScope()->getSubprogram(); - recordSourceLine(SP->getScopeLine(), 0, SP, DWARF2_FLAG_IS_STMT); - } + PrologEndLoc = emitInitialLocDirective( + *MF, Asm->OutStreamer->getContext().getDwarfCompileUnitID()); } void DwarfDebug::skippedNonDebugFunction() { @@ -1481,7 +1494,7 @@ // Register a source line with debug info. Returns the unique label that was // emitted and which provides correspondence to the source line list. void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S, - unsigned Flags) { + unsigned Flags, Optional CUID) { StringRef Fn; unsigned FileNo = 1; unsigned Discriminator = 0; @@ -1491,9 +1504,10 @@ if (auto *LBF = dyn_cast(Scope)) Discriminator = LBF->getDiscriminator(); - unsigned CUID = Asm->OutStreamer->getContext().getDwarfCompileUnitID(); - FileNo = static_cast(*InfoHolder.getUnits()[CUID]) - .getOrCreateSourceID(Scope->getFile()); + unsigned ID = + CUID.getValueOr(Asm->OutStreamer->getContext().getDwarfCompileUnitID()); + FileNo = static_cast(*InfoHolder.getUnits()[ID]) + .getOrCreateSourceID(Scope->getFile()); } Asm->OutStreamer->EmitDwarfLocDirective(FileNo, Line, Col, Flags, 0, Discriminator, Fn); Index: lib/Target/NVPTX/NVPTXAsmPrinter.cpp =================================================================== --- lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -470,6 +470,9 @@ // Emit open brace for function body. OutStreamer->EmitRawText(StringRef("{\n")); setAndEmitFunctionVirtualRegisters(*MF); + // Emit initial .loc debug directive for correct relocation symbol data. + if (MMI && MMI->hasDebugInfo()) + emitInitialRawDwarfLocDirective(*MF); } bool NVPTXAsmPrinter::runOnMachineFunction(MachineFunction &F) { Index: test/DebugInfo/NVPTX/cu-range-hole.ll =================================================================== --- test/DebugInfo/NVPTX/cu-range-hole.ll +++ test/DebugInfo/NVPTX/cu-range-hole.ll @@ -6,6 +6,7 @@ ; CHECK: .param .b32 b_param_0 ; CHECK: ) ; CHECK: { +; CHECK: .loc 1 1 0 ; CHECK: Lfunc_begin0: ; CHECK: .loc 1 1 0 ; CHECK: .loc 1 1 0 @@ -27,6 +28,7 @@ ; CHECK: .param .b32 d_param_0 ; CHECK: ) ; CHECK: { +; CHECK: .loc 1 3 0 ; CHECK: Lfunc_begin2: ; CHECK: .loc 1 3 0 ; CHECK: ret; Index: test/DebugInfo/NVPTX/debug-loc-offset.ll =================================================================== --- test/DebugInfo/NVPTX/debug-loc-offset.ll +++ test/DebugInfo/NVPTX/debug-loc-offset.ll @@ -11,8 +11,9 @@ ; CHECK: .visible .func (.param .b32 func_retval0) _Z3bari( ; CHECK: { -; CHECK: Lfunc_begin0: ; CHECK: .loc [[CU1:[0-9]+]] 1 0 +; CHECK: Lfunc_begin0: +; CHECK: .loc [[CU1]] 1 0 ; CHECK: //DEBUG_VALUE: bar:b <- {{[0-9]+}} ; CHECK: //DEBUG_VALUE: bar:b <- {{[0-9]+}} @@ -39,8 +40,9 @@ ; CHECK: .visible .func _Z3baz1A( ; CHECK: { -; CHECK: Lfunc_begin1: ; CHECK: .loc [[CU2:[0-9]+]] 6 0 +; CHECK: Lfunc_begin1: +; CHECK: .loc [[CU2]] 6 0 ; CHECK: //DEBUG_VALUE: baz:z <- {{[0-9]+}} ; CHECK: //DEBUG_VALUE: baz:z <- {{[0-9]+}} ; CHECK: .loc [[CU2]] 10 0