Index: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h +++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h @@ -226,6 +226,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: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -231,6 +231,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, /*CUID=*/0); +} + /// getCurrentSection() - Return the current section we are emitting to. const MCSection *AsmPrinter::getCurrentSection() const { return OutStreamer->getCurrentSectionOnly(); Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -592,6 +592,9 @@ /// 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); + /// Process beginning of an instruction. void beginInstruction(const MachineInstr *MI) override; Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1520,6 +1520,46 @@ return DebugLoc(); } +/// Register a source line with debug info. Returns the unique label that was +/// emitted and which provides correspondence to the source line list. +static void recordSourceLine(AsmPrinter &Asm, unsigned Line, unsigned Col, + const MDNode *S, unsigned Flags, unsigned CUID, + uint16_t DwarfVersion, + ArrayRef> DCUs) { + StringRef Fn; + unsigned FileNo = 1; + unsigned Discriminator = 0; + if (auto *Scope = cast_or_null(S)) { + Fn = Scope->getFilename(); + if (Line != 0 && DwarfVersion >= 4) + if (auto *LBF = dyn_cast(Scope)) + Discriminator = LBF->getDiscriminator(); + + FileNo = static_cast(*DCUs[CUID]) + .getOrCreateSourceID(Scope->getFile()); + } + Asm.OutStreamer->EmitDwarfLocDirective(FileNo, Line, Col, Flags, 0, + Discriminator, Fn); +} + +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(*Asm, SP->getScopeLine(), 0, SP, DWARF2_FLAG_IS_STMT, + CUID, getDwarfVersion(), getUnits()); + 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) { @@ -1542,13 +1582,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() { @@ -1646,21 +1681,9 @@ // emitted and which provides correspondence to the source line list. void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S, unsigned Flags) { - StringRef Fn; - unsigned FileNo = 1; - unsigned Discriminator = 0; - if (auto *Scope = cast_or_null(S)) { - Fn = Scope->getFilename(); - if (Line != 0 && getDwarfVersion() >= 4) - if (auto *LBF = dyn_cast(Scope)) - Discriminator = LBF->getDiscriminator(); - - unsigned CUID = Asm->OutStreamer->getContext().getDwarfCompileUnitID(); - FileNo = static_cast(*InfoHolder.getUnits()[CUID]) - .getOrCreateSourceID(Scope->getFile()); - } - Asm->OutStreamer->EmitDwarfLocDirective(FileNo, Line, Col, Flags, 0, - Discriminator, Fn); + ::recordSourceLine(*Asm, Line, Col, S, Flags, + Asm->OutStreamer->getContext().getDwarfCompileUnitID(), + getDwarfVersion(), getUnits()); } //===----------------------------------------------------------------------===// Index: llvm/trunk/lib/Target/NVPTX/NVPTXAsmPrinter.cpp =================================================================== --- llvm/trunk/lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ llvm/trunk/lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -472,6 +472,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: llvm/trunk/test/DebugInfo/NVPTX/cu-range-hole.ll =================================================================== --- llvm/trunk/test/DebugInfo/NVPTX/cu-range-hole.ll +++ llvm/trunk/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: llvm/trunk/test/DebugInfo/NVPTX/debug-loc-offset.ll =================================================================== --- llvm/trunk/test/DebugInfo/NVPTX/debug-loc-offset.ll +++ llvm/trunk/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