diff options
author | Derek Schuff <dschuff@chromium.org> | 2013-01-09 16:55:43 -0800 |
---|---|---|
committer | Derek Schuff <dschuff@chromium.org> | 2013-01-11 13:47:37 -0800 |
commit | b770d0e0636a4b5ad61b1ca661caee67576c05fc (patch) | |
tree | c486ce032d41f97313c50629bd5b879f53e6ccbf /lib/CodeGen/AsmPrinter/DwarfDebug.cpp | |
parent | b835840cf112a6178506d834b58aa625f59a8994 (diff) | |
parent | 1ad9253c9d34ccbce3e7e4ea5d87c266cbf93410 (diff) |
Merge commit '1ad9253c9d34ccbce3e7e4ea5d87c266cbf93410'
deplib features commented out due to removal upstream;
will add back as a localmod
Conflicts:
include/llvm/ADT/Triple.h
include/llvm/MC/MCAssembler.h
include/llvm/Target/TargetFrameLowering.h
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.h
lib/CodeGen/BranchFolding.cpp
lib/LLVMBuild.txt
lib/Linker/LinkArchives.cpp
lib/MC/MCAssembler.cpp
lib/MC/MCELFStreamer.cpp
lib/Makefile
lib/Target/ARM/ARMExpandPseudoInsts.cpp
lib/Target/ARM/ARMFrameLowering.cpp
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMSubtarget.h
lib/Target/ARM/ARMTargetObjectFile.cpp
lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
lib/Target/Mips/MipsInstrFPU.td
lib/Target/Mips/MipsInstrInfo.td
lib/Target/X86/X86CodeEmitter.cpp
lib/Target/X86/X86Subtarget.h
lib/VMCore/Module.cpp
test/MC/MachO/ARM/nop-armv4-padding.s
tools/Makefile
tools/llc/llc.cpp
tools/lto/LTOModule.cpp
tools/lto/lto.cpp
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfDebug.cpp')
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 582 |
1 files changed, 328 insertions, 254 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 1a9deb6641..ad18024559 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -16,34 +16,34 @@ #include "DIE.h" #include "DwarfAccelTable.h" #include "DwarfCompileUnit.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Triple.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/Constants.h" -#include "llvm/DebugInfo.h" #include "llvm/DIBuilder.h" -#include "llvm/Module.h" +#include "llvm/DataLayout.h" +#include "llvm/DebugInfo.h" #include "llvm/Instructions.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/DataLayout.h" -#include "llvm/Target/TargetFrameLowering.h" -#include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/Triple.h" +#include "llvm/Module.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ValueHandle.h" #include "llvm/Support/FormattedStream.h" -#include "llvm/Support/Timer.h" #include "llvm/Support/Path.h" +#include "llvm/Support/Timer.h" +#include "llvm/Support/ValueHandle.h" +#include "llvm/Target/TargetFrameLowering.h" +#include "llvm/Target/TargetLoweringObjectFile.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; static cl::opt<bool> DisableDebugInfoPrinting("disable-debug-info-print", @@ -78,8 +78,8 @@ static cl::opt<DefaultOnOff> DarwinGDBCompat("darwin-gdb-compat", cl::Hidden, clEnumValEnd), cl::init(Default)); -static cl::opt<DefaultOnOff> DwarfFission("dwarf-fission", cl::Hidden, - cl::desc("Output prototype dwarf fission."), +static cl::opt<DefaultOnOff> SplitDwarf("split-dwarf", cl::Hidden, + cl::desc("Output prototype dwarf split debug info."), cl::values( clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), @@ -94,8 +94,8 @@ namespace { //===----------------------------------------------------------------------===// -/// Configuration values for initial hash set sizes (log2). -/// +// Configuration values for initial hash set sizes (log2). +// static const unsigned InitAbbreviationsSetSize = 9; // log2(512) namespace llvm { @@ -156,7 +156,9 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) : Asm(A), MMI(Asm->MMI), FirstCU(0), AbbreviationsSet(InitAbbreviationsSetSize), SourceIdMap(DIEValueAllocator), StringPool(DIEValueAllocator), - PrevLabel(NULL) { + PrevLabel(NULL), GlobalCUIndexCount(0), + InfoHolder(A, &AbbreviationsSet, &Abbreviations), + SkeletonCU(0), SkeletonHolder(A, &AbbreviationsSet, &Abbreviations) { NextStringPoolNumber = 0; DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0; @@ -183,10 +185,10 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) } else HasDwarfAccelTables = DwarfAccelTables == Enable ? true : false; - if (DwarfFission == Default) - HasDwarfFission = false; + if (SplitDwarf == Default) + HasSplitDwarf = false; else - HasDwarfFission = DwarfFission == Enable ? true : false; + HasSplitDwarf = SplitDwarf == Enable ? true : false; { NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); @@ -196,8 +198,8 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) DwarfDebug::~DwarfDebug() { } -/// emitSectionSym - Switch to the specified MCSection and emit an assembler -/// temporary label to it if SymbolStem is specified. +// Switch to the specified MCSection and emit an assembler +// temporary label to it if SymbolStem is specified. static MCSymbol *emitSectionSym(AsmPrinter *Asm, const MCSection *Section, const char *SymbolStem = 0) { Asm->OutStreamer.SwitchSection(Section); @@ -220,32 +222,32 @@ MCSymbol *DwarfDebug::getStringPoolEntry(StringRef Str) { return Entry.first = Asm->GetTempSymbol("string", Entry.second); } -/// assignAbbrevNumber - Define a unique number for the abbreviation. -/// -void DwarfDebug::assignAbbrevNumber(DIEAbbrev &Abbrev) { +// Define a unique number for the abbreviation. +// +void DwarfUnits::assignAbbrevNumber(DIEAbbrev &Abbrev) { // Profile the node so that we can make it unique. FoldingSetNodeID ID; Abbrev.Profile(ID); // Check the set for priors. - DIEAbbrev *InSet = AbbreviationsSet.GetOrInsertNode(&Abbrev); + DIEAbbrev *InSet = AbbreviationsSet->GetOrInsertNode(&Abbrev); // If it's newly added. if (InSet == &Abbrev) { // Add to abbreviation list. - Abbreviations.push_back(&Abbrev); + Abbreviations->push_back(&Abbrev); // Assign the vector position + 1 as its number. - Abbrev.setNumber(Abbreviations.size()); + Abbrev.setNumber(Abbreviations->size()); } else { // Assign existing abbreviation number. Abbrev.setNumber(InSet->getNumber()); } } -/// getRealLinkageName - If special LLVM prefix that is used to inform the asm -/// printer to not emit usual symbol prefix before the symbol name is used then -/// return linkage name after skipping this special LLVM prefix. +// If special LLVM prefix that is used to inform the asm +// printer to not emit usual symbol prefix before the symbol name is used then +// return linkage name after skipping this special LLVM prefix. static StringRef getRealLinkageName(StringRef LinkageName) { char One = '\1'; if (LinkageName.startswith(StringRef(&One, 1))) @@ -310,10 +312,9 @@ static void addSubprogramNames(CompileUnit *TheCU, DISubprogram SP, } } -/// updateSubprogramScopeDIE - Find DIE for the given subprogram and -/// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes. -/// If there are global variables in this scope then create and insert -/// DIEs for these variables. +// Find DIE for the given subprogram and attach appropriate DW_AT_low_pc +// and DW_AT_high_pc attributes. If there are global variables in this +// scope then create and insert DIEs for these variables. DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, const MDNode *SPNode) { DIE *SPDie = SPCU->getDIE(SPNode); @@ -383,8 +384,8 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, return SPDie; } -/// constructLexicalScope - Construct new DW_TAG_lexical_block -/// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels. +// Construct new DW_TAG_lexical_block for this scope and attach +// DW_AT_low_pc/DW_AT_high_pc labels. DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block); @@ -427,9 +428,8 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU, return ScopeDIE; } -/// constructInlinedScopeDIE - This scope represents inlined body of -/// a function. Construct DIE to represent this concrete inlined copy -/// of the function. +// This scope represents inlined body of a function. Construct DIE to +// represent this concrete inlined copy of the function. DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { const SmallVector<InsnRange, 4> &Ranges = Scope->getRanges(); @@ -511,7 +511,7 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU, return ScopeDIE; } -/// constructScopeDIE - Construct a DIE for this scope. +// Construct a DIE for this scope. DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { if (!Scope || !Scope->getScopeNode()) return NULL; @@ -580,13 +580,12 @@ DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { return ScopeDIE; } -/// getOrCreateSourceID - Look up the source id with the given directory and -/// source file names. If none currently exists, create a new id and insert it -/// in the SourceIds map. This can update DirectoryNames and SourceFileNames -/// maps as well. +// Look up the source id with the given directory and source file names. +// If none currently exists, create a new id and insert it in the +// SourceIds map. This can update DirectoryNames and SourceFileNames maps +// as well. unsigned DwarfDebug::getOrCreateSourceID(StringRef FileName, - StringRef DirName, - StringRef Extra) { // @LOCALMOD + StringRef DirName) { // If FE did not provide a file name, then assume stdin. if (FileName.empty()) return getOrCreateSourceID("<stdin>", StringRef()); @@ -602,9 +601,6 @@ unsigned DwarfDebug::getOrCreateSourceID(StringRef FileName, NamePair += DirName; NamePair += '\0'; // Zero bytes are not allowed in paths. NamePair += FileName; - // @LOCALMOD - NamePair += '\0'; // Zero bytes are not allowed in paths. - NamePair += Extra; StringMapEntry<unsigned> &Ent = SourceIdMap.GetOrCreateValue(NamePair, SrcId); if (Ent.getValue() != SrcId) @@ -616,47 +612,18 @@ unsigned DwarfDebug::getOrCreateSourceID(StringRef FileName, return SrcId; } -// @LOCALMOD-BEGIN -// A special version of GetOrCreateSourceID for CompileUnits. -// It is possible that with bitcode linking, we end up with distinct -// compile units based on the same source file. -// E.g., compile foo.c with -DMACRO1 to foo1.bc, then compile -// foo.c again with -DMACRO2 to foo2.bc and link. -// We use additional information to form a unique ID in that case. -unsigned DwarfDebug::getOrCreateCompileUnitID(StringRef Filename, - StringRef Dirname, - const MDNode *N) { - std::string DIUnitStr; - raw_string_ostream ostr(DIUnitStr); - - // Using information from the compile unit (N)'s getEnumTypes(), - // getRetainedTypes(), getSubprograms(), getGlobalVariables() - // could be pretty expensive. - // Cheat and use the MDNode's address as an additional identifying factor. - // constructCompileUnit() is only called once per compile unit. - ostr << static_cast<const void*>(N); - return getOrCreateSourceID(Filename, Dirname, ostr.str()); -} -// @LOCALMOD-END - -/// constructCompileUnit - Create new CompileUnit for the given -/// metadata node with tag DW_TAG_compile_unit. +// Create new CompileUnit for the given metadata node with tag DW_TAG_compile_unit. CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) { DICompileUnit DIUnit(N); StringRef FN = DIUnit.getFilename(); CompilationDir = DIUnit.getDirectory(); - // @LOCALMOD-BEGIN - unsigned ID; - if (Triple(Asm->TM.getTargetTriple()).isOSNaCl()) { - ID = getOrCreateCompileUnitID(FN, CompilationDir, N); - } else { - ID = getOrCreateSourceID(FN, CompilationDir); - } - // @LOCALMOD-END + // Call this to emit a .file directive if it wasn't emitted for the source + // file this CU comes from yet. + getOrCreateSourceID(FN, CompilationDir); DIE *Die = new DIE(dwarf::DW_TAG_compile_unit); - CompileUnit *NewCU = new CompileUnit(ID, DIUnit.getLanguage(), Die, - Asm, this); + CompileUnit *NewCU = new CompileUnit(GlobalCUIndexCount++, + DIUnit.getLanguage(), Die, Asm, this); NewCU->addString(Die, dwarf::DW_AT_producer, DIUnit.getProducer()); NewCU->addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2, DIUnit.getLanguage()); @@ -687,11 +654,16 @@ CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) { if (!FirstCU) FirstCU = NewCU; + if (useSplitDwarf() && !SkeletonCU) + SkeletonCU = constructSkeletonCU(N); + + InfoHolder.addUnit(NewCU); + CUMap.insert(std::make_pair(N, NewCU)); return NewCU; } -/// construct SubprogramDIE - Construct subprogram DIE. +// Construct subprogram DIE. void DwarfDebug::constructSubprogramDIE(CompileUnit *TheCU, const MDNode *N) { CompileUnit *&CURef = SPMap[N]; @@ -716,8 +688,7 @@ void DwarfDebug::constructSubprogramDIE(CompileUnit *TheCU, return; } -/// collectInfoFromNamedMDNodes - Collect debug info from named mdnodes such -/// as llvm.dbg.enum and llvm.dbg.ty +// Collect debug info from named mdnodes such as llvm.dbg.enum and llvm.dbg.ty. void DwarfDebug::collectInfoFromNamedMDNodes(const Module *M) { if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.sp")) for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { @@ -748,8 +719,8 @@ void DwarfDebug::collectInfoFromNamedMDNodes(const Module *M) { } } -/// collectLegacyDebugInfo - Collect debug info using DebugInfoFinder. -/// FIXME - Remove this when dragon-egg and llvm-gcc switch to DIBuilder. +// Collect debug info using DebugInfoFinder. +// FIXME - Remove this when dragonegg switches to DIBuilder. bool DwarfDebug::collectLegacyDebugInfo(const Module *M) { DebugInfoFinder DbgFinder; DbgFinder.processModule(*M); @@ -770,6 +741,7 @@ bool DwarfDebug::collectLegacyDebugInfo(const Module *M) { for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(), E = DbgFinder.compile_unit_end(); I != E; ++I) constructCompileUnit(*I); + // Create DIEs for each global variable. for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(), E = DbgFinder.global_variable_end(); I != E; ++I) { @@ -789,9 +761,9 @@ bool DwarfDebug::collectLegacyDebugInfo(const Module *M) { return HasDebugInfo; } -/// beginModule - Emit all Dwarf sections that should come prior to the -/// content. Create global DIEs and emit initial debug info sections. -/// This is invoked by the target AsmPrinter. +// Emit all Dwarf sections that should come prior to the content. Create +// global DIEs and emit initial debug info sections. This is invoked by +// the target AsmPrinter. void DwarfDebug::beginModule() { if (DisableDebugInfoPrinting) return; @@ -834,12 +806,12 @@ void DwarfDebug::beginModule() { void DwarfDebug::computeInlinedDIEs() { // Attach DW_AT_inline attribute with inlined subprogram DIEs. for (SmallPtrSet<DIE *, 4>::iterator AI = InlinedSubprogramDIEs.begin(), - AE = InlinedSubprogramDIEs.end(); AI != AE; ++AI) { + AE = InlinedSubprogramDIEs.end(); AI != AE; ++AI) { DIE *ISP = *AI; FirstCU->addUInt(ISP, dwarf::DW_AT_inline, 0, dwarf::DW_INL_inlined); } for (DenseMap<const MDNode *, DIE *>::iterator AI = AbstractSPDies.begin(), - AE = AbstractSPDies.end(); AI != AE; ++AI) { + AE = AbstractSPDies.end(); AI != AE; ++AI) { DIE *ISP = AI->second; if (InlinedSubprogramDIEs.count(ISP)) continue; @@ -857,30 +829,30 @@ void DwarfDebug::collectDeadVariables() { DICompileUnit TheCU(CU_Nodes->getOperand(i)); DIArray Subprograms = TheCU.getSubprograms(); for (unsigned i = 0, e = Subprograms.getNumElements(); i != e; ++i) { - DISubprogram SP(Subprograms.getElement(i)); - if (ProcessedSPNodes.count(SP) != 0) continue; - if (!SP.Verify()) continue; - if (!SP.isDefinition()) continue; - DIArray Variables = SP.getVariables(); - if (Variables.getNumElements() == 0) continue; - - LexicalScope *Scope = - new LexicalScope(NULL, DIDescriptor(SP), NULL, false); - DeadFnScopeMap[SP] = Scope; - - // Construct subprogram DIE and add variables DIEs. - CompileUnit *SPCU = CUMap.lookup(TheCU); - assert(SPCU && "Unable to find Compile Unit!"); - constructSubprogramDIE(SPCU, SP); - DIE *ScopeDIE = SPCU->getDIE(SP); - for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) { - DIVariable DV(Variables.getElement(vi)); - if (!DV.Verify()) continue; - DbgVariable *NewVar = new DbgVariable(DV, NULL); - if (DIE *VariableDIE = - SPCU->constructVariableDIE(NewVar, Scope->isAbstractScope())) - ScopeDIE->addChild(VariableDIE); - } + DISubprogram SP(Subprograms.getElement(i)); + if (ProcessedSPNodes.count(SP) != 0) continue; + if (!SP.Verify()) continue; + if (!SP.isDefinition()) continue; + DIArray Variables = SP.getVariables(); + if (Variables.getNumElements() == 0) continue; + + LexicalScope *Scope = + new LexicalScope(NULL, DIDescriptor(SP), NULL, false); + DeadFnScopeMap[SP] = Scope; + + // Construct subprogram DIE and add variables DIEs. + CompileUnit *SPCU = CUMap.lookup(TheCU); + assert(SPCU && "Unable to find Compile Unit!"); + constructSubprogramDIE(SPCU, SP); + DIE *ScopeDIE = SPCU->getDIE(SP); + for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) { + DIVariable DV(Variables.getElement(vi)); + if (!DV.Verify()) continue; + DbgVariable *NewVar = new DbgVariable(DV, NULL); + if (DIE *VariableDIE = + SPCU->constructVariableDIE(NewVar, Scope->isAbstractScope())) + ScopeDIE->addChild(VariableDIE); + } } } } @@ -897,13 +869,15 @@ void DwarfDebug::finalizeModuleInfo() { // Emit DW_AT_containing_type attribute to connect types with their // vtable holding type. for (DenseMap<const MDNode *, CompileUnit *>::iterator CUI = CUMap.begin(), - CUE = CUMap.end(); CUI != CUE; ++CUI) { + CUE = CUMap.end(); CUI != CUE; ++CUI) { CompileUnit *TheCU = CUI->second; TheCU->constructContainingTypeDIEs(); } // Compute DIE offsets and sizes. - computeSizeAndOffsets(); + InfoHolder.computeSizeAndOffsets(); + if (useSplitDwarf()) + SkeletonHolder.computeSizeAndOffsets(); } void DwarfDebug::endSections() { @@ -920,8 +894,7 @@ void DwarfDebug::endSections() { } } -/// endModule - Emit all Dwarf sections that should come after the content. -/// +// Emit all Dwarf sections that should come after the content. void DwarfDebug::endModule() { if (!FirstCU) return; @@ -936,11 +909,61 @@ void DwarfDebug::endModule() { // Emit initial sections. emitSectionLabels(); - // Emit all the DIEs into a debug info section - emitDebugInfo(); + if (!useSplitDwarf()) { + // Emit all the DIEs into a debug info section. + emitDebugInfo(); + + // Corresponding abbreviations into a abbrev section. + emitAbbreviations(); + + // Emit info into a debug loc section. + emitDebugLoc(); + + // Emit info into a debug aranges section. + emitDebugARanges(); + + // Emit info into a debug ranges section. + emitDebugRanges(); - // Corresponding abbreviations into a abbrev section. - emitAbbreviations(); + // Emit info into a debug macinfo section. + emitDebugMacInfo(); + + // Emit inline info. + // TODO: When we don't need the option anymore we + // can remove all of the code that this section + // depends upon. + if (useDarwinGDBCompat()) + emitDebugInlineInfo(); + } else { + // TODO: Fill this in for Fission sections and separate + // out information into new sections. + + // Emit the debug info section and compile units. + emitDebugInfo(); + emitDebugInfoDWO(); + + // Corresponding abbreviations into a abbrev section. + emitAbbreviations(); + + // Emit info into a debug loc section. + emitDebugLoc(); + + // Emit info into a debug aranges section. + emitDebugARanges(); + + // Emit info into a debug ranges section. + emitDebugRanges(); + + // Emit info into a debug macinfo section. + emitDebugMacInfo(); + + // Emit inline info. + // TODO: When we don't need the option anymore we + // can remove all of the code that this section + // depends upon. + if (useDarwinGDBCompat()) + emitDebugInlineInfo(); + } // Emit info into the dwarf accelerator table sections. if (useDwarfAccelTables()) { @@ -956,26 +979,7 @@ void DwarfDebug::endModule() { if (useDarwinGDBCompat()) emitDebugPubTypes(); - // Emit info into a debug loc section. - emitDebugLoc(); - - // Emit info into a debug aranges section. - emitDebugARanges(); - - // Emit info into a debug ranges section. - emitDebugRanges(); - - // Emit info into a debug macinfo section. - emitDebugMacInfo(); - - // Emit inline info. - // TODO: When we don't need the option anymore we - // can remove all of the code that this section - // depends upon. - if (useDarwinGDBCompat()) - emitDebugInlineInfo(); - - // Emit info into a debug str section. + // Finally emit string information into a string table. emitDebugStr(); // clean up. @@ -983,10 +987,15 @@ void DwarfDebug::endModule() { for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(), E = CUMap.end(); I != E; ++I) delete I->second; - FirstCU = NULL; // Reset for the next Module, if any. + + delete SkeletonCU; + + // Reset these for the next Module if we have one. + FirstCU = NULL; + SkeletonCU = NULL; } -/// findAbstractVariable - Find abstract variable, if any, associated with Var. +// Find abstract variable, if any, associated with Var. DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV, DebugLoc ScopeLoc) { LLVMContext &Ctx = DV->getContext(); @@ -1006,8 +1015,7 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV, return AbsDbgVariable; } -/// addCurrentFnArgument - If Var is a current function argument then add -/// it to CurrentFnArguments list. +// If Var is a current function argument then add it to CurrentFnArguments list. bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF, DbgVariable *Var, LexicalScope *Scope) { if (!LScopes.isCurrentFunctionScope(Scope)) @@ -1030,8 +1038,7 @@ bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF, return true; } -/// collectVariableInfoFromMMITable - Collect variable information from -/// side table maintained by MMI. +// Collect variable information from side table maintained by MMI. void DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction *MF, SmallPtrSet<const MDNode *, 16> &Processed) { @@ -1060,8 +1067,8 @@ DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction *MF, } } -/// isDbgValueInDefinedReg - Return true if debug value, encoded by -/// DBG_VALUE instruction, is in a defined reg. +// Return true if debug value, encoded by DBG_VALUE instruction, is in a +// defined reg. static bool isDbgValueInDefinedReg(const MachineInstr *MI) { assert(MI->isDebugValue() && "Invalid DBG_VALUE machine instruction!"); return MI->getNumOperands() == 3 && @@ -1069,8 +1076,7 @@ static bool isDbgValueInDefinedReg(const MachineInstr *MI) { MI->getOperand(1).isImm() && MI->getOperand(1).getImm() == 0; } -/// getDebugLocEntry - Get .debug_loc entry for the instruction range starting -/// at MI. +// Get .debug_loc entry for the instruction range starting at MI. static DotDebugLocEntry getDebugLocEntry(AsmPrinter *Asm, const MCSymbol *FLabel, const MCSymbol *SLabel, @@ -1096,12 +1102,12 @@ static DotDebugLocEntry getDebugLocEntry(AsmPrinter *Asm, llvm_unreachable("Unexpected 3 operand DBG_VALUE instruction!"); } -/// collectVariableInfo - Find variables for each lexical scope. +// Find variables for each lexical scope. void DwarfDebug::collectVariableInfo(const MachineFunction *MF, SmallPtrSet<const MDNode *, 16> &Processed) { - /// collection info from MMI table. + // collection info from MMI table. collectVariableInfoFromMMITable(MF, Processed); for (SmallVectorImpl<const MDNode*>::const_iterator @@ -1207,19 +1213,19 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF, } } -/// getLabelBeforeInsn - Return Label preceding the instruction. +// Return Label preceding the instruction. const MCSymbol *DwarfDebug::getLabelBeforeInsn(const MachineInstr *MI) { MCSymbol *Label = LabelsBeforeInsn.lookup(MI); assert(Label && "Didn't insert label before instruction"); return Label; } -/// getLabelAfterInsn - Return Label immediately following the instruction. +// Return Label immediately following the instruction. const MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) { return LabelsAfterInsn.lookup(MI); } -/// beginInstruction - Process beginning of an instruction. +// Process beginning of an instruction. void DwarfDebug::beginInstruction(const MachineInstr *MI) { // Check if source location changes, but ignore DBG_VALUE locations. if (!MI->isDebugValue()) { @@ -1261,7 +1267,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) { I->second = PrevLabel; } -/// endInstruction - Process end of an instruction. +// Process end of an instruction. void DwarfDebug::endInstruction(const MachineInstr *MI) { // Don't create a new label after DBG_VALUE instructions. // They don't generate code. @@ -1287,11 +1293,10 @@ void DwarfDebug::endInstruction(const MachineInstr *MI) { I->second = PrevLabel; } -/// identifyScopeMarkers() - -/// Each LexicalScope has first instruction and last instruction to mark -/// beginning and end of a scope respectively. Create an inverse map that list -/// scopes starts (and ends) with an instruction. One instruction may start (or -/// end) multiple scopes. Ignore scopes that are not reachable. +// Each LexicalScope has first instruction and last instruction to mark +// beginning and end of a scope respectively. Create an inverse map that list +// scopes starts (and ends) with an instruction. One instruction may start (or +// end) multiple scopes. Ignore scopes that are not reachable. void DwarfDebug::identifyScopeMarkers() { SmallVector<LexicalScope *, 4> WorkList; WorkList.push_back(LScopes.getCurrentFunctionScope()); @@ -1320,15 +1325,15 @@ void DwarfDebug::identifyScopeMarkers() { } } -/// getScopeNode - Get MDNode for DebugLoc's scope. +// Get MDNode for DebugLoc's scope. static MDNode *getScopeNode(DebugLoc DL, const LLVMContext &Ctx) { if (MDNode *InlinedAt = DL.getInlinedAt(Ctx)) return getScopeNode(DebugLoc::getFromDILocation(InlinedAt), Ctx); return DL.getScope(Ctx); } -/// getFnDebugLoc - Walk up the scope chain of given debug loc and find -/// line number info for the function. +// Walk up the scope chain of given debug loc and find line number info +// for the function. static DebugLoc getFnDebugLoc(DebugLoc DL, const LLVMContext &Ctx) { const MDNode *Scope = getScopeNode(DL, Ctx); DISubprogram SP = getDISubprogram(Scope); @@ -1344,8 +1349,8 @@ static DebugLoc getFnDebugLoc(DebugLoc DL, const LLVMContext &Ctx) { return DebugLoc(); } -/// beginFunction - Gather pre-function debug information. Assumes being -/// emitted immediately after the function entry point. +// Gather pre-function debug information. Assumes being called immediately +// after the function entry point has been emitted. void DwarfDebug::beginFunction(const MachineFunction *MF) { if (!MMI->hasDebugInfo()) return; LScopes.initialize(*MF); @@ -1360,7 +1365,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { assert(UserVariables.empty() && DbgValues.empty() && "Maps weren't cleaned"); const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo(); - /// LiveUserVar - Map physreg numbers to the MDNode they contain. + // LiveUserVar - Map physreg numbers to the MDNode they contain. std::vector<const MDNode*> LiveUserVar(TRI->getNumRegs()); for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); @@ -1515,7 +1520,9 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { MF->getFunction()->getContext()); recordSourceLine(FnStartDL.getLine(), FnStartDL.getCol(), FnStartDL.getScope(MF->getFunction()->getContext()), - 0); + // 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. + DWARF2_FLAG_IS_STMT); } } @@ -1525,8 +1532,7 @@ void DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { // Vars.push_back(Var); } -/// endFunction - Gather and emit post-function debug information. -/// +// Gather and emit post-function debug information. void DwarfDebug::endFunction(const MachineFunction *MF) { if (!MMI->hasDebugInfo() || LScopes.empty()) return; @@ -1591,9 +1597,8 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { PrevLabel = NULL; } -/// recordSourceLine - Register a source line with debug info. Returns the -/// unique label that was emitted and which provides correspondence to -/// the source line list. +// 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) { StringRef Fn; @@ -1634,10 +1639,9 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S, // Emit Methods //===----------------------------------------------------------------------===// -/// computeSizeAndOffset - Compute the size and offset of a DIE. -/// +// Compute the size and offset of a DIE. unsigned -DwarfDebug::computeSizeAndOffset(DIE *Die, unsigned Offset) { +DwarfUnits::computeSizeAndOffset(DIE *Die, unsigned Offset) { // Get the children. const std::vector<DIE *> &Children = Die->getChildren(); @@ -1646,7 +1650,7 @@ DwarfDebug::computeSizeAndOffset(DIE *Die, unsigned Offset) { // Get the abbreviation for this DIE. unsigned AbbrevNumber = Die->getAbbrevNumber(); - const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1]; + const DIEAbbrev *Abbrev = Abbreviations->at(AbbrevNumber - 1); // Set DIE offset Die->setOffset(Offset); @@ -1678,23 +1682,21 @@ DwarfDebug::computeSizeAndOffset(DIE *Die, unsigned Offset) { return Offset; } -/// computeSizeAndOffsets - Compute the size and offset of all the DIEs. -/// -void DwarfDebug::computeSizeAndOffsets() { - for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(), - E = CUMap.end(); I != E; ++I) { - // Compute size of compile unit header. +// Compute the size and offset of all the DIEs. +void DwarfUnits::computeSizeAndOffsets() { + for (SmallVector<CompileUnit *, 1>::iterator I = CUs.begin(), + E = CUs.end(); I != E; ++I) { unsigned Offset = sizeof(int32_t) + // Length of Compilation Unit Info sizeof(int16_t) + // DWARF version number sizeof(int32_t) + // Offset Into Abbrev. Section sizeof(int8_t); // Pointer Size (in bytes) - computeSizeAndOffset(I->second->getCUDie(), Offset); + + computeSizeAndOffset((*I)->getCUDie(), Offset); } } -/// emitSectionLabels - Emit initial Dwarf sections with a label at -/// the start of each one. +// Emit initial Dwarf sections with a label at the start of each one. void DwarfDebug::emitSectionLabels() { const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); @@ -1723,8 +1725,7 @@ void DwarfDebug::emitSectionLabels() { emitSectionSym(Asm, TLOF.getDataSection()); } -/// emitDIE - Recursively emits a debug information entry. -/// +// Recursively emits a debug information entry. void DwarfDebug::emitDIE(DIE *Die) { // Get the abbreviation for this DIE. unsigned AbbrevNumber = Die->getAbbrevNumber(); @@ -1813,12 +1814,8 @@ void DwarfDebug::emitDIE(DIE *Die) { } } -/// emitDebugInfo - Emit the debug info section. -/// -void DwarfDebug::emitDebugInfo() { - // Start debug info section. - Asm->OutStreamer.SwitchSection( - Asm->getObjFileLowering().getDwarfInfoSection()); +void DwarfDebug::emitCompileUnits(const MCSection *Section) { + Asm->OutStreamer.SwitchSection(Section); for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(), E = CUMap.end(); I != E; ++I) { CompileUnit *TheCU = I->second; @@ -1826,7 +1823,7 @@ void DwarfDebug::emitDebugInfo() { // Emit the compile units header. Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_begin", - TheCU->getID())); + TheCU->getUniqueID())); // Emit size of content not including length itself unsigned ContentSize = Die->getSize() + @@ -1845,12 +1842,20 @@ void DwarfDebug::emitDebugInfo() { Asm->EmitInt8(Asm->getDataLayout().getPointerSize()); emitDIE(Die); - Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_end", TheCU->getID())); + Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_end", + TheCU->getUniqueID())); } } -/// emitAbbreviations - Emit the abbreviation section. -/// +// Emit the debug info section. +void DwarfDebug::emitDebugInfo() { + if (!useSplitDwarf()) + emitCompileUnits(Asm->getObjFileLowering().getDwarfInfoSection()); + else + emitSkeletonCU(Asm->getObjFileLowering().getDwarfInfoSection()); +} + +// Emit the abbreviation section. void DwarfDebug::emitAbbreviations() { // Check to see if it is worth the effort. if (!Abbreviations.empty()) { @@ -1879,9 +1884,7 @@ void DwarfDebug::emitAbbreviations() { } } -/// emitEndOfLineMatrix - Emit the last address of the section and the end of -/// the line matrix. -/// +// Emit the last address of the section and the end of the line matrix. void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) { // Define last address of section. Asm->OutStreamer.AddComment("Extended Op"); @@ -1905,8 +1908,7 @@ void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) { Asm->EmitInt8(1); } -/// emitAccelNames - Emit visible names into a hashed accelerator table -/// section. +// Emit visible names into a hashed accelerator table section. void DwarfDebug::emitAccelNames() { DwarfAccelTable AT(DwarfAccelTable::Atom(DwarfAccelTable::eAtomTypeDIEOffset, dwarf::DW_FORM_data4)); @@ -1934,8 +1936,7 @@ void DwarfDebug::emitAccelNames() { AT.Emit(Asm, SectionBegin, this); } -/// emitAccelObjC - Emit objective C classes and categories into a hashed -/// accelerator table section. +// Emit objective C classes and categories into a hashed accelerator table section. void DwarfDebug::emitAccelObjC() { DwarfAccelTable AT(DwarfAccelTable::Atom(DwarfAccelTable::eAtomTypeDIEOffset, dwarf::DW_FORM_data4)); @@ -1963,8 +1964,7 @@ void DwarfDebug::emitAccelObjC() { AT.Emit(Asm, SectionBegin, this); } -/// emitAccelNamespace - Emit namespace dies into a hashed accelerator -/// table. +// Emit namespace dies into a hashed accelerator table. void DwarfDebug::emitAccelNamespaces() { DwarfAccelTable AT(DwarfAccelTable::Atom(DwarfAccelTable::eAtomTypeDIEOffset, dwarf::DW_FORM_data4)); @@ -1992,7 +1992,7 @@ void DwarfDebug::emitAccelNamespaces() { AT.Emit(Asm, SectionBegin, this); } -/// emitAccelTypes() - Emit type dies into a hashed accelerator table. +// Emit type dies into a hashed accelerator table. void DwarfDebug::emitAccelTypes() { std::vector<DwarfAccelTable::Atom> Atoms; Atoms.push_back(DwarfAccelTable::Atom(DwarfAccelTable::eAtomTypeDIEOffset, @@ -2036,22 +2036,25 @@ void DwarfDebug::emitDebugPubTypes() { Asm->getObjFileLowering().getDwarfPubTypesSection()); Asm->OutStreamer.AddComment("Length of Public Types Info"); Asm->EmitLabelDifference( - Asm->GetTempSymb |