summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEric Christopher <echristo@gmail.com>2013-12-03 00:45:45 +0000
committerEric Christopher <echristo@gmail.com>2013-12-03 00:45:45 +0000
commitc2efbdbb6022149b6b94188efd85b72abe19b0ba (patch)
treeda11ff9b576fd28cfe21ac1989c0bce49cfc9336 /lib
parent357fcf9d2ea79d43e4a1a29edb8608225c8f9a54 (diff)
downloadllvm-c2efbdbb6022149b6b94188efd85b72abe19b0ba.tar.gz
llvm-c2efbdbb6022149b6b94188efd85b72abe19b0ba.tar.bz2
llvm-c2efbdbb6022149b6b94188efd85b72abe19b0ba.tar.xz
Make ranges and range lists be a discrete entity that can be located
and emitted per function and CU. Begins coalescing ranges as a first class entity through debug info. No functional change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196178 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp140
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h5
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfUnit.cpp4
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfUnit.h38
4 files changed, 135 insertions, 52 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index cd7cf7bf5b..52a809f9bf 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -185,8 +185,8 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
: Asm(A), MMI(Asm->MMI), FirstCU(0),
AbbreviationsSet(InitAbbreviationsSetSize),
SourceIdMap(DIEValueAllocator), PrevLabel(NULL), GlobalCUIndexCount(0),
- InfoHolder(A, &AbbreviationsSet, Abbreviations, "info_string",
- DIEValueAllocator),
+ GlobalRangeCount(0), InfoHolder(A, &AbbreviationsSet, Abbreviations,
+ "info_string", DIEValueAllocator),
SkeletonAbbrevSet(InitAbbreviationsSetSize),
SkeletonHolder(A, &SkeletonAbbrevSet, SkeletonAbbrevs, "skel_string",
DIEValueAllocator) {
@@ -429,12 +429,12 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, DISubprogram SP) {
}
}
- SPCU->addLabelAddress(
- SPDie, dwarf::DW_AT_low_pc,
- Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()));
- SPCU->addLabelAddress(
- SPDie, dwarf::DW_AT_high_pc,
- Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()));
+ MCSymbol *FuncBegin =
+ Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber());
+ MCSymbol *FuncEnd = Asm->GetTempSymbol("func_end", Asm->getFunctionNumber());
+ SPCU->addLabelAddress(SPDie, dwarf::DW_AT_low_pc, FuncBegin);
+ SPCU->addLabelAddress(SPDie, dwarf::DW_AT_high_pc, FuncEnd);
+
const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
MachineLocation Location(RI->getFrameRegister(*Asm->MF));
SPCU->addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
@@ -478,30 +478,31 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU,
if (Scope->isAbstractScope())
return ScopeDIE;
- const SmallVectorImpl<InsnRange> &Ranges = Scope->getRanges();
+ const SmallVectorImpl<InsnRange> &ScopeRanges = Scope->getRanges();
// If we have multiple ranges, emit them into the range section.
- if (Ranges.size() > 1) {
+ if (ScopeRanges.size() > 1) {
// .debug_range section has not been laid out yet. Emit offset in
// .debug_range as a relocatable label. emitDIE will handle
// emitting it appropriately.
- unsigned Offset = DebugRangeSymbols.size();
- TheCU->addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges,
- Asm->GetTempSymbol("debug_ranges", Offset));
- for (SmallVectorImpl<InsnRange>::const_iterator RI = Ranges.begin(),
- RE = Ranges.end();
+ TheCU->addSectionLabel(
+ ScopeDIE, dwarf::DW_AT_ranges,
+ Asm->GetTempSymbol("debug_ranges", GlobalRangeCount));
+ RangeSpanList *List = new RangeSpanList(GlobalRangeCount++);
+ for (SmallVectorImpl<InsnRange>::const_iterator RI = ScopeRanges.begin(),
+ RE = ScopeRanges.end();
RI != RE; ++RI) {
- DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first));
- DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second));
+ RangeSpan Range(getLabelBeforeInsn(RI->first),
+ getLabelAfterInsn(RI->second));
+ List->addRange(Range);
}
- // Terminate the range list.
- DebugRangeSymbols.push_back(NULL);
- DebugRangeSymbols.push_back(NULL);
+ // Add the range list to the set of ranges to be emitted.
+ TheCU->addRangeList(List);
return ScopeDIE;
}
// Construct the address range for this DIE.
- SmallVectorImpl<InsnRange>::const_iterator RI = Ranges.begin();
+ SmallVectorImpl<InsnRange>::const_iterator RI = ScopeRanges.begin();
MCSymbol *Start = getLabelBeforeInsn(RI->first);
MCSymbol *End = getLabelAfterInsn(RI->second);
assert(End && "End label should not be null!");
@@ -519,8 +520,8 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU,
// represent this concrete inlined copy of the function.
DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU,
LexicalScope *Scope) {
- const SmallVectorImpl<InsnRange> &Ranges = Scope->getRanges();
- assert(Ranges.empty() == false &&
+ const SmallVectorImpl<InsnRange> &ScopeRanges = Scope->getRanges();
+ assert(ScopeRanges.empty() == false &&
"LexicalScope does not have instruction markers!");
if (!Scope->getScopeNode())
@@ -536,23 +537,26 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU,
DIE *ScopeDIE = new DIE(dwarf::DW_TAG_inlined_subroutine);
TheCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin, OriginDIE);
- if (Ranges.size() > 1) {
+ if (ScopeRanges.size() > 1) {
// .debug_range section has not been laid out yet. Emit offset in
// .debug_range as a relocatable label. emitDIE will handle
// emitting it appropriately.
- unsigned Offset = DebugRangeSymbols.size();
- TheCU->addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges,
- Asm->GetTempSymbol("debug_ranges", Offset));
- for (SmallVectorImpl<InsnRange>::const_iterator RI = Ranges.begin(),
- RE = Ranges.end();
+ TheCU->addSectionLabel(
+ ScopeDIE, dwarf::DW_AT_ranges,
+ Asm->GetTempSymbol("debug_ranges", GlobalRangeCount));
+ RangeSpanList *List = new RangeSpanList(GlobalRangeCount++);
+ for (SmallVectorImpl<InsnRange>::const_iterator RI = ScopeRanges.begin(),
+ RE = ScopeRanges.end();
RI != RE; ++RI) {
- DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first));
- DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second));
+ RangeSpan Range(getLabelBeforeInsn(RI->first),
+ getLabelAfterInsn(RI->second));
+ List->addRange(Range);
}
- DebugRangeSymbols.push_back(NULL);
- DebugRangeSymbols.push_back(NULL);
+
+ // Add the range list to the set of ranges to be emitted.
+ TheCU->addRangeList(List);
} else {
- SmallVectorImpl<InsnRange>::const_iterator RI = Ranges.begin();
+ SmallVectorImpl<InsnRange>::const_iterator RI = ScopeRanges.begin();
MCSymbol *StartLabel = getLabelBeforeInsn(RI->first);
MCSymbol *EndLabel = getLabelAfterInsn(RI->second);
@@ -2922,18 +2926,51 @@ void DwarfDebug::emitDebugRanges() {
// Start the dwarf ranges section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfRangesSection());
+
+ // Size for our labels.
unsigned char Size = Asm->getDataLayout().getPointerSize();
- for (uint32_t i = 0, e = DebugRangeSymbols.size(); i < e; ++i) {
- // Only emit a symbol for every range pair for now.
- // FIXME: Make this per range list.
- if ((i % 2) == 0)
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_ranges", i));
-
- const MCSymbol *I = DebugRangeSymbols[i];
- if (I)
- Asm->OutStreamer.EmitSymbolValue(I, Size);
- else
+
+ // Grab the specific ranges for the compile units in the module.
+ for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
+ E = CUMap.end();
+ I != E; ++I) {
+ CompileUnit *TheCU = I->second;
+ unsigned ID = TheCU->getUniqueID();
+
+ // Emit a symbol so we can find the beginning of our ranges.
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("gnu_ranges", ID));
+
+ // Iterate over the misc ranges for the compile units in the module.
+ const SmallVectorImpl<RangeSpanList *> &RangeLists = TheCU->getRangeLists();
+ for (SmallVectorImpl<RangeSpanList *>::const_iterator
+ I = RangeLists.begin(),
+ E = RangeLists.end();
+ I != E; ++I) {
+ RangeSpanList *List = *I;
+
+ // Emit a symbol so we can find the beginning of the range.
+ Asm->OutStreamer.EmitLabel(
+ Asm->GetTempSymbol("debug_ranges", List->getIndex()));
+
+ for (SmallVectorImpl<RangeSpan>::const_iterator
+ I = List->getRanges().begin(),
+ E = List->getRanges().end();
+ I != E; ++I) {
+ RangeSpan Range = *I;
+ // We occasionally have ranges without begin/end labels.
+ // FIXME: Verify and fix.
+ const MCSymbol *Begin = Range.getStart();
+ const MCSymbol *End = Range.getEnd();
+ Begin ? Asm->OutStreamer.EmitSymbolValue(Begin, Size)
+ : Asm->OutStreamer.EmitIntValue(0, Size);
+ End ? Asm->OutStreamer.EmitSymbolValue(End, Size)
+ : Asm->OutStreamer.EmitIntValue(0, Size);
+ }
+
+ // And terminate the list with two 0 values.
+ Asm->OutStreamer.EmitIntValue(0, Size);
Asm->OutStreamer.EmitIntValue(0, Size);
+ }
}
}
@@ -3007,14 +3044,17 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const CompileUnit *CU) {
DwarfGnuPubTypesSectionSym);
}
- // Flag if we've emitted any ranges and their location for the compile unit.
- if (DebugRangeSymbols.size()) {
+ // Attribute if we've emitted any ranges and their location for the compile unit.
+ if (CU->getRangeLists().size()) {
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_ranges_base,
- DwarfDebugRangeSectionSym);
+ NewCU->addSectionLabel(
+ Die, dwarf::DW_AT_GNU_ranges_base,
+ Asm->GetTempSymbol("gnu_ranges", NewCU->getUniqueID()));
else
- NewCU->addUInt(Die, dwarf::DW_AT_GNU_ranges_base, dwarf::DW_FORM_data4,
- 0);
+ NewCU->addSectionDelta(
+ Die, dwarf::DW_AT_GNU_ranges_base,
+ Asm->GetTempSymbol("gnu_ranges", NewCU->getUniqueID()),
+ DwarfDebugRangeSectionSym);
}
SkeletonHolder.addUnit(NewCU);
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 59e7379e44..351637cc02 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -409,8 +409,6 @@ class DwarfDebug {
DbgValueHistoryMap;
DbgValueHistoryMap DbgValues;
- SmallVector<const MCSymbol *, 8> DebugRangeSymbols;
-
// Previous instruction's location information. This is used to determine
// label location to indicate scope boundries in dwarf debug info.
DebugLoc PrevInstLoc;
@@ -437,6 +435,9 @@ class DwarfDebug {
// Counter for assigning globally unique IDs for CUs.
unsigned GlobalCUIndexCount;
+ // Counter for assigning globally unique IDs for ranges.
+ unsigned GlobalRangeCount;
+
// Holder for the file specific debug information.
DwarfUnits InfoHolder;
diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index c13930e4a6..d65862040c 100644
--- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -59,6 +59,10 @@ TypeUnit::TypeUnit(unsigned UID, DIE *D, uint16_t Language, AsmPrinter *A,
Unit::~Unit() {
for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
DIEBlocks[j]->~DIEBlock();
+ for (SmallVectorImpl<RangeSpanList *>::iterator RI = getRangeLists().begin(),
+ RE = getRangeLists().end();
+ RI != RE; ++RI)
+ delete *RI;
}
/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.h b/lib/CodeGen/AsmPrinter/DwarfUnit.h
index 0ee1aade64..89fbd307a8 100644
--- a/lib/CodeGen/AsmPrinter/DwarfUnit.h
+++ b/lib/CodeGen/AsmPrinter/DwarfUnit.h
@@ -31,6 +31,31 @@ class ConstantInt;
class ConstantFP;
class DbgVariable;
+// Data structure to hold a range for range lists.
+class RangeSpan {
+public:
+ RangeSpan(MCSymbol *S, MCSymbol *E) : Start(S), End(E) {}
+ const MCSymbol *getStart() { return Start; }
+ const MCSymbol *getEnd() { return End; }
+
+private:
+ const MCSymbol *Start, *End;
+};
+
+class RangeSpanList {
+private:
+ // Index for locating within the debug_range section this particular span.
+ unsigned Index;
+ // List of ranges.
+ SmallVector<RangeSpan, 2> Ranges;
+
+public:
+ RangeSpanList(unsigned Idx) : Index(Idx) {}
+ unsigned getIndex() const { return Index; }
+ const SmallVectorImpl<RangeSpan> &getRanges() const { return Ranges; }
+ void addRange(RangeSpan Range) { Ranges.push_back(Range); }
+};
+
//===----------------------------------------------------------------------===//
/// Unit - This dwarf writer support class manages information associated
/// with a source file.
@@ -92,6 +117,10 @@ protected:
/// corresponds to the MDNode mapped with the subprogram DIE.
DenseMap<DIE *, const MDNode *> ContainingTypeMap;
+ // List of range lists for a given compile unit, separate from the ranges for
+ // the CU itself.
+ SmallVector<RangeSpanList *, 1> CURangeLists;
+
// DIEValueAllocator - All DIEValues are allocated through this allocator.
BumpPtrAllocator DIEValueAllocator;
@@ -132,6 +161,15 @@ public:
/// hasContent - Return true if this compile unit has something to write out.
bool hasContent() const { return !UnitDie->getChildren().empty(); }
+ /// addRangeList - Add an address range list to the list of range lists.
+ void addRangeList(RangeSpanList *Ranges) { CURangeLists.push_back(Ranges); }
+
+ /// getRangeLists - Get the vector of range lists.
+ const SmallVectorImpl<RangeSpanList *> &getRangeLists() const {
+ return CURangeLists;
+ }
+ SmallVectorImpl<RangeSpanList *> &getRangeLists() { return CURangeLists; }
+
/// getParentContextString - Get a string containing the language specific
/// context for a global name.
std::string getParentContextString(DIScope Context) const;