From: Alexey Bataev Date: Tue, 22 Jan 2019 17:24:16 +0000 (+0000) Subject: [DEBUG_INFO, NVPTX] Fix relocation info. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d3046a26188fb8a62ba57067f2b8ee3d0f4ed7c3;p=llvm [DEBUG_INFO, NVPTX] Fix relocation info. Summary: Initial function labels must follow the debug location for the correct relocation info generation. Reviewers: tra, jlebar, echristo Subscribers: jholewinski, llvm-commits Differential Revision: https://reviews.llvm.org/D45784 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351843 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 5c43134bb71..4297450546a 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -226,6 +226,9 @@ public: 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; diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 67fa79fd3c6..aed46d58f99 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -231,6 +231,12 @@ void AsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) { 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(); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index b82d5a53fb2..7d8f26d348c 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1520,6 +1520,46 @@ static DebugLoc findPrologueEndLoc(const MachineFunction *MF) { 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 @@ void DwarfDebug::beginFunctionImpl(const MachineFunction *MF) { 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 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) { // 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()); } //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index e285f8826b9..f0d50a47640 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -592,6 +592,9 @@ public: /// 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; diff --git a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp index 9ac4044e5a0..f07266d1fae 100644 --- a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -472,6 +472,9 @@ void NVPTXAsmPrinter::EmitFunctionEntryLabel() { // 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) { diff --git a/test/DebugInfo/NVPTX/cu-range-hole.ll b/test/DebugInfo/NVPTX/cu-range-hole.ll index e44b43d2b90..48570e090c8 100644 --- a/test/DebugInfo/NVPTX/cu-range-hole.ll +++ b/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; diff --git a/test/DebugInfo/NVPTX/debug-loc-offset.ll b/test/DebugInfo/NVPTX/debug-loc-offset.ll index df7835f8a2d..72ed6c1cc2f 100644 --- a/test/DebugInfo/NVPTX/debug-loc-offset.ll +++ b/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 @@ declare void @llvm.dbg.value(metadata, metadata, metadata) #1 ; 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