diff options
author | Eric Christopher <echristo@gmail.com> | 2014-03-19 22:42:36 +0000 |
---|---|---|
committer | Eric Christopher <echristo@gmail.com> | 2014-03-19 22:42:36 +0000 |
commit | e33c990616e948a610d7d2deb48efdf171bafca3 (patch) | |
tree | 1d0dd5f073ec84d915cfdbfa3578e4d399092b5b /llvm/lib/CodeGen | |
parent | fb4447688f847407ec1a448d5385c386271b440b (diff) | |
download | bcm5719-llvm-e33c990616e948a610d7d2deb48efdf171bafca3.tar.gz bcm5719-llvm-e33c990616e948a610d7d2deb48efdf171bafca3.zip |
Use the range machinery for DW_AT_ranges and DW_AT_high/lo_pc.
This commit moves us from a single range per subprogram to extending
ranges if we are:
a) In the same section, and
b) In the same enclosing CU.
This means we have more fine grained ranges for compile units, and fewer
ranges overall when we have multiple functions in the same CU
adjacent to each other in the object file.
Also remove all of the earlier hacks around this functionality for
function sections etc. Also update all of the testcases to take into
account the merging functionality.
llvm-svn: 204277
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 77 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 16 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 54 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h | 15 |
4 files changed, 101 insertions, 61 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 6925cb6bdde..ed9e90a7dd2 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -178,7 +178,7 @@ static unsigned getDwarfVersionFromModule(const Module *M) { DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) : Asm(A), MMI(Asm->MMI), FirstCU(0), PrevLabel(NULL), GlobalRangeCount(0), - InfoHolder(A, "info_string", DIEValueAllocator), HasCURanges(false), + InfoHolder(A, "info_string", DIEValueAllocator), UsedNonDefaultText(false), SkeletonHolder(A, "skel_string", DIEValueAllocator) { @@ -947,26 +947,34 @@ void DwarfDebug::finalizeModuleInfo() { dwarf::DW_FORM_data8, ID); } - // If we have code split among multiple sections or we've requested - // it then emit a DW_AT_ranges attribute on the unit that will remain - // in the .o file, otherwise add a DW_AT_low_pc. - // FIXME: Also add a high pc if we can. - // FIXME: We should use ranges if we have multiple compile units or - // allow reordering of code ala .subsections_via_symbols in mach-o. + // If we have code split among multiple sections or non-contiguous + // ranges of code then emit a DW_AT_ranges attribute on the unit that will + // remain in the .o file, otherwise add a DW_AT_low_pc. + // FIXME: We should use ranges allow reordering of code ala + // .subsections_via_symbols in mach-o. This would mean turning on + // ranges for all subprogram DIEs for mach-o. DwarfCompileUnit *U = SkCU ? SkCU : static_cast<DwarfCompileUnit *>(TheU); - if (useCURanges() && TheU->getRanges().size()) { - addSectionLabel(Asm, U, U->getUnitDie(), dwarf::DW_AT_ranges, - Asm->GetTempSymbol("cu_ranges", U->getUniqueID()), - DwarfDebugRangeSectionSym); - - // A DW_AT_low_pc attribute may also be specified in combination with - // DW_AT_ranges to specify the default base address for use in location - // lists (see Section 2.6.2) and range lists (see Section 2.17.3). - U->addUInt(U->getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, - 0); - } else - U->addUInt(U->getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, - 0); + unsigned NumRanges = TheU->getRanges().size(); + if (NumRanges) { + if (NumRanges > 1) { + addSectionLabel(Asm, U, U->getUnitDie(), dwarf::DW_AT_ranges, + Asm->GetTempSymbol("cu_ranges", U->getUniqueID()), + DwarfDebugRangeSectionSym); + + // A DW_AT_low_pc attribute may also be specified in combination with + // DW_AT_ranges to specify the default base address for use in + // location lists (see Section 2.6.2) and range lists (see Section + // 2.17.3). + U->addUInt(U->getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, + 0); + } else { + RangeSpan &Range = TheU->getRanges().back(); + U->addLocalLabelAddress(U->getUnitDie(), dwarf::DW_AT_low_pc, + Range.getStart()); + U->addLabelDelta(U->getUnitDie(), dwarf::DW_AT_high_pc, + Range.getEnd(), Range.getStart()); + } + } } } @@ -1021,14 +1029,6 @@ void DwarfDebug::endSections() { // Insert a final terminator. SectionMap[Section].push_back(SymbolCU(NULL, Sym)); } - - // For now only turn on CU ranges if we have -ffunction-sections enabled, - // we've emitted a function into a unique section, or we're using LTO. If - // we're using LTO then we can't know that any particular function in the - // module is correlated to a particular CU and so we need to be conservative. - // At this point all sections should be finalized except for dwarf sections. - HasCURanges = UsedNonDefaultText || (CUMap.size() > 1) || - TargetMachine::getFunctionSections(); } // Emit all Dwarf sections that should come after the content. @@ -1423,12 +1423,8 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { // Grab the lexical scopes for the function, if we don't have any of those // then we're not going to be able to do anything. LScopes.initialize(*MF); - if (LScopes.empty()) { - // If we don't have a lexical scope for this function then there will - // be a hole in the range information. Keep note of this. - UsedNonDefaultText = true; + if (LScopes.empty()) return; - } assert(UserVariables.empty() && DbgValues.empty() && "Maps weren't cleaned"); @@ -1447,12 +1443,6 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { else Asm->OutStreamer.getContext().setDwarfCompileUnitID(TheCU->getUniqueID()); - // Check the current section against the standard text section. If different - // keep track so that we will know when we're emitting functions into multiple - // sections. - if (Asm->getObjFileLowering().getTextSection() != Asm->getCurrentSection()) - UsedNonDefaultText = true; - // Emit a label for the function so that we have a beginning address. FunctionBeginSym = Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()); // Assumes in correct section after the entry point. @@ -1658,6 +1648,11 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { assert(CurFn != 0); if (!MMI->hasDebugInfo() || LScopes.empty()) { + // If we don't have a lexical scope for this function then there will + // be a hole in the range information. Keep note of this by setting the + // previously used section to nullptr. + PrevSection = nullptr; + PrevCU = nullptr; CurFn = 0; return; } @@ -1708,6 +1703,8 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { // Add the range of this function to the list of ranges for the CU. RangeSpan Span(FunctionBeginSym, FunctionEndSym); TheCU->addRange(std::move(Span)); + PrevSection = Asm->getCurrentSection(); + PrevCU = TheCU; // Clear debug info for (auto &I : ScopeVariables) @@ -2597,7 +2594,7 @@ void DwarfDebug::emitDebugRanges() { } // Now emit a range for the CU itself. - if (useCURanges() && TheCU->getRanges().size()) { + if (TheCU->getRanges().size() > 1) { Asm->OutStreamer.EmitLabel( Asm->GetTempSymbol("cu_ranges", TheCU->getUniqueID())); for (const RangeSpan &Range : TheCU->getRanges()) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 73150442c67..52be24c7963 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -406,6 +406,13 @@ class DwarfDebug : public AsmPrinterHandler { // If nonnull, stores the current machine instruction we're processing. const MachineInstr *CurMI; + // If nonnull, stores the section that the previous function was allocated to + // emitting. + const MCSection *PrevSection; + + // If nonnull, stores the CU in which the previous subprogram was contained. + const DwarfCompileUnit *PrevCU; + // Section Symbols: these are assembler temporary labels that are emitted at // the beginning of each supported dwarf section. These are used to form // section offsets and are created by EmitSectionLabels. @@ -741,15 +748,18 @@ public: /// split dwarf proposal support. bool useSplitDwarf() const { return HasSplitDwarf; } - /// \brief Returns whether or not to use AT_ranges for compilation units. - bool useCURanges() const { return HasCURanges; } - /// Returns the Dwarf Version. unsigned getDwarfVersion() const { return DwarfVersion; } /// Returns the section symbol for the .debug_loc section. MCSymbol *getDebugLocSym() const { return DwarfDebugLocSectionSym; } + /// Returns the previous section that was emitted into. + const MCSection *getPrevSection() const { return PrevSection; } + + /// Returns the previous CU that was being updated + const DwarfCompileUnit *getPrevCU() const { return PrevCU; } + /// Returns the entries for the .debug_loc section. const SmallVectorImpl<DebugLocEntry> &getDebugLocEntries() const { return DotDebugLocEntries; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index bf377f52d41..c1ece004779 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -282,22 +282,31 @@ void DwarfUnit::addSectionOffset(DIE *Die, dwarf::Attribute Attribute, /// DW_FORM_addr or DW_FORM_GNU_addr_index. /// void DwarfCompileUnit::addLabelAddress(DIE *Die, dwarf::Attribute Attribute, - MCSymbol *Label) { + const MCSymbol *Label) { + + if (!DD->useSplitDwarf()) + return addLocalLabelAddress(Die, Attribute, Label); + if (Label) DD->addArangeLabel(SymbolCU(this, Label)); - if (!DD->useSplitDwarf()) { - if (Label) { - DIEValue *Value = new (DIEValueAllocator) DIELabel(Label); - Die->addValue(Attribute, dwarf::DW_FORM_addr, Value); - } else { - DIEValue *Value = new (DIEValueAllocator) DIEInteger(0); - Die->addValue(Attribute, dwarf::DW_FORM_addr, Value); - } + unsigned idx = DU->getAddrPoolIndex(Label); + DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx); + Die->addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value); +} + +void DwarfCompileUnit::addLocalLabelAddress(DIE *Die, + dwarf::Attribute Attribute, + const MCSymbol *Label) { + if (Label) + DD->addArangeLabel(SymbolCU(this, Label)); + + if (Label) { + DIEValue *Value = new (DIEValueAllocator) DIELabel(Label); + Die->addValue(Attribute, dwarf::DW_FORM_addr, Value); } else { - unsigned idx = DU->getAddrPoolIndex(Label); - DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx); - Die->addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value); + DIEValue *Value = new (DIEValueAllocator) DIEInteger(0); + Die->addValue(Attribute, dwarf::DW_FORM_addr, Value); } } @@ -2034,6 +2043,27 @@ void DwarfUnit::emitHeader(const MCSection *ASection, Asm->EmitInt8(Asm->getDataLayout().getPointerSize()); } +void DwarfUnit::addRange(RangeSpan Range) { + // Only add a range for this unit if we're emitting full debug. + if (getCUNode().getEmissionKind() == DIBuilder::FullDebug) { + // If we have no current ranges just add the range and return, otherwise, + // check the current section and CU against the previous section and CU we + // emitted into and the subprogram was contained within. If these are the + // same then extend our current range, otherwise add this as a new range. + if (CURanges.size() == 0 || + this != DD->getPrevCU() || + Asm->getCurrentSection() != DD->getPrevSection()) { + CURanges.push_back(Range); + return; + } + + assert(&(CURanges.back().getEnd()->getSection()) == + &(Range.getEnd()->getSection()) && + "We can only append to a range in the same section!"); + CURanges.back().setEnd(Range.getEnd()); + } +} + void DwarfCompileUnit::initStmtList(MCSymbol *DwarfLineSectionSym) { // Define start line table label for each Compile Unit. MCSymbol *LineTableStartSym = diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h index 6f8e55edc91..a9e52e674a4 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -41,6 +41,7 @@ public: RangeSpan(MCSymbol *S, MCSymbol *E) : Start(S), End(E) {} const MCSymbol *getStart() const { return Start; } const MCSymbol *getEnd() const { return End; } + void setEnd(const MCSymbol *E) { End = E; } private: const MCSymbol *Start, *End; @@ -251,11 +252,7 @@ public: bool hasContent() const { return !UnitDie->getChildren().empty(); } /// addRange - Add an address range to the list of ranges for this unit. - void addRange(RangeSpan Range) { - // Only add a range for this unit if we're emitting full debug. - if (getCUNode().getEmissionKind() == DIBuilder::FullDebug) - CURanges.push_back(Range); - } + void addRange(RangeSpan Range); /// getRanges - Get the list of ranges for this unit. const SmallVectorImpl<RangeSpan> &getRanges() const { return CURanges; } @@ -583,7 +580,13 @@ public: /// addLabelAddress - Add a dwarf label attribute data and value using /// either DW_FORM_addr or DW_FORM_GNU_addr_index. - void addLabelAddress(DIE *Die, dwarf::Attribute Attribute, MCSymbol *Label); + void addLabelAddress(DIE *Die, dwarf::Attribute Attribute, + const MCSymbol *Label); + + /// addLocalLabelAddress - Add a dwarf label attribute data and value using + /// DW_FORM_addr only. + void addLocalLabelAddress(DIE *Die, dwarf::Attribute Attribute, + const MCSymbol *Label); DwarfCompileUnit &getCU() override { return *this; } |