X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FDwarfDebug.cpp;h=95dedb5549b6efbcb5cd6524ab4881c2a932c225;hp=2559120edaa235082a7dc8bf41e37d88b0b42906;hb=dc1d16ae54aceebdecc7262b2ef806387f98ace3;hpb=446817b4ef197188c213a1f60f37446ee9c57862 diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 2559120edaa..95dedb5549b 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -169,10 +169,10 @@ static LLVM_CONSTEXPR DwarfAccelTable::Atom TypeAtoms[] = { DwarfAccelTable::Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1)}; DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) - : Asm(A), MMI(Asm->MMI), FirstCU(nullptr), PrevLabel(nullptr), - GlobalRangeCount(0), InfoHolder(A, "info_string", DIEValueAllocator), + : Asm(A), MMI(Asm->MMI), PrevLabel(nullptr), GlobalRangeCount(0), + InfoHolder(A, *this, "info_string", DIEValueAllocator), UsedNonDefaultText(false), - SkeletonHolder(A, "skel_string", DIEValueAllocator), + SkeletonHolder(A, *this, "skel_string", DIEValueAllocator), IsDarwin(Triple(A->getTargetTriple()).isOSDarwin()), AccelNames(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)), @@ -330,289 +330,18 @@ bool DwarfDebug::isLexicalScopeDIENull(LexicalScope *Scope) { return !getLabelAfterInsn(Ranges.front().second); } -static void addSectionLabel(AsmPrinter &Asm, DwarfUnit &U, DIE &D, - dwarf::Attribute A, const MCSymbol *L, - const MCSymbol *Sec) { - if (Asm.MAI->doesDwarfUseRelocationsAcrossSections()) - U.addSectionLabel(D, A, L); - else - U.addSectionDelta(D, A, L, Sec); -} - -void DwarfDebug::addScopeRangeList(DwarfCompileUnit &TheCU, DIE &ScopeDIE, - const SmallVectorImpl &Range) { - // Emit offset in .debug_range as a relocatable label. emitDIE will handle - // emitting it appropriately. - MCSymbol *RangeSym = Asm->GetTempSymbol("debug_ranges", GlobalRangeCount++); - - // Under fission, ranges are specified by constant offsets relative to the - // CU's DW_AT_GNU_ranges_base. - if (useSplitDwarf()) - TheCU.addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, RangeSym, - DwarfDebugRangeSectionSym); - else - addSectionLabel(*Asm, TheCU, ScopeDIE, dwarf::DW_AT_ranges, RangeSym, - DwarfDebugRangeSectionSym); - - RangeSpanList List(RangeSym); - for (const InsnRange &R : Range) { - RangeSpan Span(getLabelBeforeInsn(R.first), getLabelAfterInsn(R.second)); - List.addRange(std::move(Span)); - } - - // Add the range list to the set of ranges to be emitted. - TheCU.addRangeList(std::move(List)); -} - -void DwarfDebug::attachRangesOrLowHighPC(DwarfCompileUnit &TheCU, DIE &Die, - const SmallVectorImpl &Ranges) { - assert(!Ranges.empty()); - if (Ranges.size() == 1) - TheCU.attachLowHighPC(Die, getLabelBeforeInsn(Ranges.front().first), - getLabelAfterInsn(Ranges.front().second)); - else - addScopeRangeList(TheCU, Die, Ranges); -} - -// Construct new DW_TAG_lexical_block for this scope and attach -// DW_AT_low_pc/DW_AT_high_pc labels. -std::unique_ptr -DwarfDebug::constructLexicalScopeDIE(DwarfCompileUnit &TheCU, - LexicalScope *Scope) { - if (isLexicalScopeDIENull(Scope)) - return nullptr; - - auto ScopeDIE = make_unique(dwarf::DW_TAG_lexical_block); - if (Scope->isAbstractScope()) - return ScopeDIE; - - attachRangesOrLowHighPC(TheCU, *ScopeDIE, Scope->getRanges()); - - return ScopeDIE; -} - -// This scope represents inlined body of a function. Construct DIE to -// represent this concrete inlined copy of the function. -std::unique_ptr -DwarfDebug::constructInlinedScopeDIE(DwarfCompileUnit &TheCU, - LexicalScope *Scope) { - assert(Scope->getScopeNode()); - DIScope DS(Scope->getScopeNode()); - DISubprogram InlinedSP = getDISubprogram(DS); - // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram - // was inlined from another compile unit. - DIE *OriginDIE = AbstractSPDies[InlinedSP]; - assert(OriginDIE && "Unable to find original DIE for an inlined subprogram."); - - auto ScopeDIE = make_unique(dwarf::DW_TAG_inlined_subroutine); - TheCU.addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE); - - attachRangesOrLowHighPC(TheCU, *ScopeDIE, Scope->getRanges()); - - // Add the call site information to the DIE. - DILocation DL(Scope->getInlinedAt()); - TheCU.addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None, - TheCU.getOrCreateSourceID(DL.getFilename(), DL.getDirectory())); - TheCU.addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, DL.getLineNumber()); - - // Add name to the name table, we do this here because we're guaranteed - // to have concrete versions of our DW_TAG_inlined_subprogram nodes. - addSubprogramNames(InlinedSP, *ScopeDIE); - - return ScopeDIE; -} - -static std::unique_ptr constructVariableDIE(DwarfCompileUnit &TheCU, - DbgVariable &DV, - const LexicalScope &Scope, - DIE *&ObjectPointer) { - auto Var = TheCU.constructVariableDIE(DV, Scope.isAbstractScope()); - if (DV.isObjectPointer()) - ObjectPointer = Var.get(); - return Var; -} - -DIE *DwarfDebug::createScopeChildrenDIE( - DwarfCompileUnit &TheCU, LexicalScope *Scope, - SmallVectorImpl> &Children, - unsigned *ChildScopeCount) { - DIE *ObjectPointer = nullptr; - - for (DbgVariable *DV : ScopeVariables.lookup(Scope)) - Children.push_back(constructVariableDIE(TheCU, *DV, *Scope, ObjectPointer)); - - unsigned ChildCountWithoutScopes = Children.size(); - - for (LexicalScope *LS : Scope->getChildren()) - constructScopeDIE(TheCU, LS, Children); - - if (ChildScopeCount) - *ChildScopeCount = Children.size() - ChildCountWithoutScopes; - - return ObjectPointer; -} - -DIE *DwarfDebug::createAndAddScopeChildren(DwarfCompileUnit &TheCU, - LexicalScope *Scope, DIE &ScopeDIE) { - // We create children when the scope DIE is not null. - SmallVector, 8> Children; - DIE *ObjectPointer = createScopeChildrenDIE(TheCU, Scope, Children); - - // Add children - for (auto &I : Children) - ScopeDIE.addChild(std::move(I)); - - return ObjectPointer; -} - -void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &TheCU, - LexicalScope *Scope) { +void DwarfDebug::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) { assert(Scope && Scope->getScopeNode()); assert(Scope->isAbstractScope()); assert(!Scope->getInlinedAt()); - DISubprogram SP(Scope->getScopeNode()); + const MDNode *SP = Scope->getScopeNode(); ProcessedSPNodes.insert(SP); - DIE *&AbsDef = AbstractSPDies[SP]; - if (AbsDef) - return; - // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram // was inlined from another compile unit. - DwarfCompileUnit &SPCU = *SPMap[SP]; - DIE *ContextDIE; - - // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with - // the important distinction that the DIDescriptor is not associated with the - // DIE (since the DIDescriptor will be associated with the concrete DIE, if - // any). It could be refactored to some common utility function. - if (DISubprogram SPDecl = SP.getFunctionDeclaration()) { - ContextDIE = &SPCU.getUnitDie(); - SPCU.getOrCreateSubprogramDIE(SPDecl); - } else - ContextDIE = SPCU.getOrCreateContextDIE(resolve(SP.getContext())); - - // Passing null as the associated DIDescriptor because the abstract definition - // shouldn't be found by lookup. - AbsDef = &SPCU.createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, - DIDescriptor()); - SPCU.applySubprogramAttributesToDefinition(SP, *AbsDef); - - if (TheCU.getCUNode().getEmissionKind() != DIBuilder::LineTablesOnly) - SPCU.addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); - if (DIE *ObjectPointer = createAndAddScopeChildren(SPCU, Scope, *AbsDef)) - SPCU.addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); -} - -void DwarfDebug::constructSubprogramScopeDIE(DwarfCompileUnit &TheCU, - LexicalScope *Scope) { - assert(Scope && Scope->getScopeNode()); - assert(!Scope->getInlinedAt()); - assert(!Scope->isAbstractScope()); - DISubprogram Sub(Scope->getScopeNode()); - - assert(Sub.isSubprogram()); - - ProcessedSPNodes.insert(Sub); - - DIE &ScopeDIE = TheCU.updateSubprogramScopeDIE(Sub); - - // Collect arguments for current function. - assert(LScopes.isCurrentFunctionScope(Scope)); - DIE *ObjectPointer = nullptr; - for (DbgVariable *ArgDV : CurrentFnArguments) - if (ArgDV) - ScopeDIE.addChild( - constructVariableDIE(TheCU, *ArgDV, *Scope, ObjectPointer)); - - // If this is a variadic function, add an unspecified parameter. - DITypeArray FnArgs = Sub.getType().getTypeArray(); - // If we have a single element of null, it is a function that returns void. - // If we have more than one elements and the last one is null, it is a - // variadic function. - if (FnArgs.getNumElements() > 1 && - !FnArgs.getElement(FnArgs.getNumElements() - 1)) - ScopeDIE.addChild(make_unique(dwarf::DW_TAG_unspecified_parameters)); - - // Collect lexical scope children first. - // ObjectPointer might be a local (non-argument) local variable if it's a - // block's synthetic this pointer. - if (DIE *BlockObjPtr = createAndAddScopeChildren(TheCU, Scope, ScopeDIE)) { - assert(!ObjectPointer && "multiple object pointers can't be described"); - ObjectPointer = BlockObjPtr; - } - - if (ObjectPointer) - TheCU.addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer); -} - -// Construct a DIE for this scope. -void DwarfDebug::constructScopeDIE( - DwarfCompileUnit &TheCU, LexicalScope *Scope, - SmallVectorImpl> &FinalChildren) { - if (!Scope || !Scope->getScopeNode()) - return; - - DIScope DS(Scope->getScopeNode()); - - assert((Scope->getInlinedAt() || !DS.isSubprogram()) && - "Only handle inlined subprograms here, use " - "constructSubprogramScopeDIE for non-inlined " - "subprograms"); - - SmallVector, 8> Children; - - // We try to create the scope DIE first, then the children DIEs. This will - // avoid creating un-used children then removing them later when we find out - // the scope DIE is null. - std::unique_ptr ScopeDIE; - if (Scope->getParent() && DS.isSubprogram()) { - ScopeDIE = constructInlinedScopeDIE(TheCU, Scope); - if (!ScopeDIE) - return; - // We create children when the scope DIE is not null. - createScopeChildrenDIE(TheCU, Scope, Children); - } else { - // Early exit when we know the scope DIE is going to be null. - if (isLexicalScopeDIENull(Scope)) - return; - - unsigned ChildScopeCount; - - // We create children here when we know the scope DIE is not going to be - // null and the children will be added to the scope DIE. - createScopeChildrenDIE(TheCU, Scope, Children, &ChildScopeCount); - - // There is no need to emit empty lexical block DIE. - std::pair Range = - std::equal_range(ScopesWithImportedEntities.begin(), - ScopesWithImportedEntities.end(), - std::pair(DS, nullptr), - less_first()); - for (ImportedEntityMap::const_iterator i = Range.first; i != Range.second; - ++i) - Children.push_back( - constructImportedEntityDIE(TheCU, DIImportedEntity(i->second))); - // If there are only other scopes as children, put them directly in the - // parent instead, as this scope would serve no purpose. - if (Children.size() == ChildScopeCount) { - FinalChildren.insert(FinalChildren.end(), - std::make_move_iterator(Children.begin()), - std::make_move_iterator(Children.end())); - return; - } - ScopeDIE = constructLexicalScopeDIE(TheCU, Scope); - assert(ScopeDIE && "Scope DIE should not be null."); - } - - // Add children - for (auto &I : Children) - ScopeDIE->addChild(std::move(I)); - - FinalChildren.push_back(std::move(ScopeDIE)); + SPMap[SP]->constructAbstractSubprogramScopeDIE(Scope); } void DwarfDebug::addGnuPubAttributes(DwarfUnit &U, DIE &D) const { @@ -633,6 +362,8 @@ DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) { DwarfCompileUnit &NewCU = *OwnedUnit; DIE &Die = NewCU.getUnitDie(); InfoHolder.addUnit(std::move(OwnedUnit)); + if (useSplitDwarf()) + NewCU.setSkeleton(constructSkeletonCU(NewCU)); // LTO with assembly output shares a single line table amongst multiple CUs. // To avoid the compilation directory being ambiguous, let the line table @@ -669,14 +400,10 @@ DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) { NewCU.addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers, dwarf::DW_FORM_data1, RVer); - if (!FirstCU) - FirstCU = &NewCU; - - if (useSplitDwarf()) { + if (useSplitDwarf()) NewCU.initSection(Asm->getObjFileLowering().getDwarfInfoDWOSection(), DwarfInfoDWOSectionSym); - NewCU.setSkeleton(constructSkeletonCU(NewCU)); - } else + else NewCU.initSection(Asm->getObjFileLowering().getDwarfInfoSection(), DwarfInfoSectionSym); @@ -690,36 +417,7 @@ void DwarfDebug::constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU, DIImportedEntity Module(N); assert(Module.Verify()); if (DIE *D = TheCU.getOrCreateContextDIE(Module.getContext())) - D->addChild(constructImportedEntityDIE(TheCU, Module)); -} - -std::unique_ptr -DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU, - const DIImportedEntity &Module) { - assert(Module.Verify() && - "Use one of the MDNode * overloads to handle invalid metadata"); - std::unique_ptr IMDie = make_unique((dwarf::Tag)Module.getTag()); - TheCU.insertDIE(Module, IMDie.get()); - DIE *EntityDie; - DIDescriptor Entity = resolve(Module.getEntity()); - if (Entity.isNameSpace()) - EntityDie = TheCU.getOrCreateNameSpace(DINameSpace(Entity)); - else if (Entity.isSubprogram()) - EntityDie = TheCU.getOrCreateSubprogramDIE(DISubprogram(Entity)); - else if (Entity.isType()) - EntityDie = TheCU.getOrCreateTypeDIE(DIType(Entity)); - else - EntityDie = TheCU.getDIE(Entity); - assert(EntityDie); - TheCU.addSourceLine(*IMDie, Module.getLineNumber(), - Module.getContext().getFilename(), - Module.getContext().getDirectory()); - TheCU.addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie); - StringRef Name = Module.getName(); - if (!Name.empty()) - TheCU.addString(*IMDie, dwarf::DW_AT_name, Name); - - return IMDie; + D->addChild(TheCU.constructImportedEntityDIE(Module)); } // Emit all Dwarf sections that should come prior to the content. Create @@ -733,8 +431,6 @@ void DwarfDebug::beginModule() { FunctionDIs = makeSubprogramMap(*M); - // If module has named metadata anchors then use them, otherwise scan the - // module using debug info finder to collect debug info. NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); if (!CU_Nodes) return; @@ -809,38 +505,8 @@ void DwarfDebug::finishVariableDefinitions() { } void DwarfDebug::finishSubprogramDefinitions() { - const Module *M = MMI->getModule(); - - NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); - for (MDNode *N : CU_Nodes->operands()) { - DICompileUnit TheCU(N); - // Construct subprogram DIE and add variables DIEs. - DwarfCompileUnit *SPCU = - static_cast(CUMap.lookup(TheCU)); - DIArray Subprograms = TheCU.getSubprograms(); - for (unsigned i = 0, e = Subprograms.getNumElements(); i != e; ++i) { - DISubprogram SP(Subprograms.getElement(i)); - // Perhaps the subprogram is in another CU (such as due to comdat - // folding, etc), in which case ignore it here. - if (SPMap[SP] != SPCU) - continue; - DIE *D = SPCU->getDIE(SP); - if (DIE *AbsSPDIE = AbstractSPDies.lookup(SP)) { - if (D) - // If this subprogram has an abstract definition, reference that - SPCU->addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE); - } else { - if (!D && TheCU.getEmissionKind() != DIBuilder::LineTablesOnly) - // Lazily construct the subprogram if we didn't see either concrete or - // inlined versions during codegen. (except in -gmlt ^ where we want - // to omit these entirely) - D = SPCU->getOrCreateSubprogramDIE(SP); - if (D) - // And attach the attributes - SPCU->applySubprogramAttributesToDefinition(SP, *D); - } - } - } + for (const auto &P : SPMap) + P.second->finishSubprogramDefinition(DISubprogram(P.first)); } @@ -860,26 +526,7 @@ void DwarfDebug::collectDeadVariables() { DISubprogram SP(Subprograms.getElement(i)); if (ProcessedSPNodes.count(SP) != 0) continue; - assert(SP.isSubprogram() && - "CU's subprogram list contains a non-subprogram"); - assert(SP.isDefinition() && - "CU's subprogram list contains a subprogram declaration"); - DIArray Variables = SP.getVariables(); - if (Variables.getNumElements() == 0) - continue; - - DIE *SPDIE = AbstractSPDies.lookup(SP); - if (!SPDIE) - SPDIE = SPCU->getDIE(SP); - assert(SPDIE); - for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) { - DIVariable DV(Variables.getElement(vi)); - assert(DV.isVariable()); - DbgVariable NewVar(DV, DIExpression(nullptr), this); - auto VariableDie = SPCU->constructVariableDIE(NewVar); - SPCU->applyVariableAttributes(NewVar, *VariableDie); - SPDIE->addChild(std::move(VariableDie)); - } + SPCU->collectDeadVariables(SP); } } } @@ -895,62 +542,58 @@ void DwarfDebug::finalizeModuleInfo() { // Handle anything that needs to be done on a per-unit basis after // all other generation. - for (const auto &TheU : getUnits()) { + for (const auto &P : CUMap) { + auto &TheCU = *P.second; // Emit DW_AT_containing_type attribute to connect types with their // vtable holding type. - TheU->constructContainingTypeDIEs(); + TheCU.constructContainingTypeDIEs(); // Add CU specific attributes if we need to add any. - if (TheU->getUnitDie().getTag() == dwarf::DW_TAG_compile_unit) { - // If we're splitting the dwarf out now that we've got the entire - // CU then add the dwo id to it. - DwarfCompileUnit *SkCU = - static_cast(TheU->getSkeleton()); - if (useSplitDwarf()) { - // Emit a unique identifier for this CU. - uint64_t ID = DIEHash(Asm).computeCUSignature(TheU->getUnitDie()); - TheU->addUInt(TheU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, - dwarf::DW_FORM_data8, ID); - SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, - dwarf::DW_FORM_data8, ID); - - // We don't keep track of which addresses are used in which CU so this - // is a bit pessimistic under LTO. - if (!AddrPool.isEmpty()) - addSectionLabel(*Asm, *SkCU, SkCU->getUnitDie(), - dwarf::DW_AT_GNU_addr_base, DwarfAddrSectionSym, - DwarfAddrSectionSym); - if (!TheU->getRangeLists().empty()) - addSectionLabel(*Asm, *SkCU, SkCU->getUnitDie(), - dwarf::DW_AT_GNU_ranges_base, - DwarfDebugRangeSectionSym, DwarfDebugRangeSectionSym); - } + // If we're splitting the dwarf out now that we've got the entire + // CU then add the dwo id to it. + auto *SkCU = TheCU.getSkeleton(); + if (useSplitDwarf()) { + // Emit a unique identifier for this CU. + uint64_t ID = DIEHash(Asm).computeCUSignature(TheCU.getUnitDie()); + TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id, + dwarf::DW_FORM_data8, ID); + SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, + dwarf::DW_FORM_data8, ID); + + // We don't keep track of which addresses are used in which CU so this + // is a bit pessimistic under LTO. + if (!AddrPool.isEmpty()) + SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_addr_base, + DwarfAddrSectionSym, DwarfAddrSectionSym); + if (!TheCU.getRangeLists().empty()) + SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base, + DwarfDebugRangeSectionSym, + DwarfDebugRangeSectionSym); + } - // 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(*TheU); - unsigned NumRanges = TheU->getRanges().size(); - if (NumRanges) { - if (NumRanges > 1) { - addSectionLabel(*Asm, U, U.getUnitDie(), dwarf::DW_AT_ranges, + // 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 : TheCU; + unsigned NumRanges = TheCU.getRanges().size(); + if (NumRanges) { + if (NumRanges > 1) { + U.addSectionLabel(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.attachLowHighPC(U.getUnitDie(), Range.getStart(), Range.getEnd()); - } + // 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 { + const RangeSpan &Range = TheCU.getRanges().back(); + TheCU.setBaseAddress(Range.getStart()); + U.attachLowHighPC(U.getUnitDie(), Range.getStart(), Range.getEnd()); } } } @@ -1013,7 +656,10 @@ void DwarfDebug::endModule() { assert(CurFn == nullptr); assert(CurMI == nullptr); - if (!FirstCU) + // If we aren't actually generating debug info (check beginModule - + // conditionalized on !DisableDebugInfoPrinting and the presence of the + // llvm.dbg.cu metadata node) + if (!DwarfInfoSectionSym) return; // End any existing sections. @@ -1067,9 +713,6 @@ void DwarfDebug::endModule() { // clean up. SPMap.clear(); AbstractVariables.clear(); - - // Reset these for the next Module if we have one. - FirstCU = nullptr; } // Find abstract variable, if any, associated with Var. @@ -1096,7 +739,7 @@ DbgVariable *DwarfDebug::getExistingAbstractVariable(const DIVariable &DV) { void DwarfDebug::createAbstractVariable(const DIVariable &Var, LexicalScope *Scope) { auto AbsDbgVariable = make_unique(Var, DIExpression(), this); - addScopeVariable(Scope, AbsDbgVariable.get()); + InfoHolder.addScopeVariable(Scope, AbsDbgVariable.get()); AbstractVariables[Var] = std::move(AbsDbgVariable); } @@ -1120,29 +763,6 @@ DwarfDebug::ensureAbstractVariableIsCreatedIfScoped(const DIVariable &DV, createAbstractVariable(Cleansed, Scope); } -// If Var is a current function argument then add it to CurrentFnArguments list. -bool DwarfDebug::addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope) { - if (!LScopes.isCurrentFunctionScope(Scope)) - return false; - DIVariable DV = Var->getVariable(); - if (DV.getTag() != dwarf::DW_TAG_arg_variable) - return false; - unsigned ArgNo = DV.getArgNumber(); - if (ArgNo == 0) - return false; - - size_t Size = CurrentFnArguments.size(); - if (Size == 0) - CurrentFnArguments.resize(CurFn->getFunction()->arg_size()); - // llvm::Function argument size is not good indicator of how many - // arguments does the function have at source level. - if (ArgNo > Size) - CurrentFnArguments.resize(ArgNo * 2); - assert(!CurrentFnArguments[ArgNo - 1]); - CurrentFnArguments[ArgNo - 1] = Var; - return true; -} - // Collect variable information from side table maintained by MMI. void DwarfDebug::collectVariableInfoFromMMITable( SmallPtrSetImpl &Processed) { @@ -1150,19 +770,19 @@ void DwarfDebug::collectVariableInfoFromMMITable( if (!VI.Var) continue; Processed.insert(VI.Var); - DIVariable DV(VI.Var); - DIExpression Expr(VI.Expr); LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc); // If variable scope is not found then skip this variable. if (!Scope) continue; + DIVariable DV(VI.Var); + DIExpression Expr(VI.Expr); ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); ConcreteVariables.push_back(make_unique(DV, Expr, this)); DbgVariable *RegVar = ConcreteVariables.back().get(); RegVar->setFrameIndex(VI.Slot); - addScopeVariable(Scope, RegVar); + InfoHolder.addScopeVariable(Scope, RegVar); } } @@ -1310,10 +930,8 @@ DwarfDebug::buildLocationList(SmallVectorImpl &DebugLoc, // Find variables for each lexical scope. void -DwarfDebug::collectVariableInfo(SmallPtrSetImpl &Processed) { - LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); - DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode()); - +DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, DISubprogram SP, + SmallPtrSetImpl &Processed) { // Grab the variable info that was squirreled away in the MMI side-table. collectVariableInfoFromMMITable(Processed); @@ -1344,7 +962,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSetImpl &Processed) { ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); ConcreteVariables.push_back(make_unique(MInsn, this)); DbgVariable *RegVar = ConcreteVariables.back().get(); - addScopeVariable(Scope, RegVar); + InfoHolder.addScopeVariable(Scope, RegVar); // Check if the first DBG_VALUE is valid for the rest of the function. if (Ranges.size() == 1 && Ranges.front().second == nullptr) @@ -1355,7 +973,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSetImpl &Processed) { DotDebugLocEntries.resize(DotDebugLocEntries.size() + 1); DebugLocList &LocList = DotDebugLocEntries.back(); - LocList.CU = TheCU; + LocList.CU = &TheCU; LocList.Label = Asm->GetTempSymbol("debug_loc", DotDebugLocEntries.size() - 1); @@ -1364,7 +982,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSetImpl &Processed) { } // Collect info for variables that were optimized out. - DIArray Variables = DISubprogram(FnScope->getScopeNode()).getVariables(); + DIArray Variables = SP.getVariables(); for (unsigned i = 0, e = Variables.getNumElements(); i != e; ++i) { DIVariable DV(Variables.getElement(i)); assert(DV.isVariable()); @@ -1374,7 +992,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSetImpl &Processed) { ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); DIExpression NoExpr; ConcreteVariables.push_back(make_unique(DV, NoExpr, this)); - addScopeVariable(Scope, ConcreteVariables.back().get()); + InfoHolder.addScopeVariable(Scope, ConcreteVariables.back().get()); } } } @@ -1604,49 +1222,10 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { } } -void DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { - if (addCurrentFnArgument(Var, LS)) - return; - SmallVectorImpl &Vars = ScopeVariables[LS]; - DIVariable DV = Var->getVariable(); - // Variables with positive arg numbers are parameters. - if (unsigned ArgNum = DV.getArgNumber()) { - // Keep all parameters in order at the start of the variable list to ensure - // function types are correct (no out-of-order parameters) - // - // This could be improved by only doing it for optimized builds (unoptimized - // builds have the right order to begin with), searching from the back (this - // would catch the unoptimized case quickly), or doing a binary search - // rather than linear search. - SmallVectorImpl::iterator I = Vars.begin(); - while (I != Vars.end()) { - unsigned CurNum = (*I)->getVariable().getArgNumber(); - // A local (non-parameter) variable has been found, insert immediately - // before it. - if (CurNum == 0) - break; - // A later indexed parameter has been found, insert immediately before it. - if (CurNum > ArgNum) - break; - ++I; - } - Vars.insert(I, Var); - return; - } - - Vars.push_back(Var); -} - // Gather and emit post-function debug information. void DwarfDebug::endFunction(const MachineFunction *MF) { - // Every beginFunction(MF) call should be followed by an endFunction(MF) call, - // though the beginFunction may not be called at all. - // We should handle both cases. - if (!CurFn) - CurFn = MF; - else - assert(CurFn == MF); - assert(CurFn != nullptr); + assert(CurFn == MF && + "endFunction should be called with the same function as beginFunction"); if (!MMI->hasDebugInfo() || LScopes.empty() || !FunctionDIs.count(MF->getFunction())) { @@ -1666,11 +1245,12 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { // Set DwarfDwarfCompileUnitID in MCContext to default value. Asm->OutStreamer.getContext().setDwarfCompileUnitID(0); - SmallPtrSet ProcessedVars; - collectVariableInfo(ProcessedVars); - LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); - DwarfCompileUnit &TheCU = *SPMap.lookup(FnScope->getScopeNode()); + DISubprogram SP(FnScope->getScopeNode()); + DwarfCompileUnit &TheCU = *SPMap.lookup(SP); + + SmallPtrSet ProcessedVars; + collectVariableInfo(TheCU, SP, ProcessedVars); // Add the range of this function to the list of ranges for the CU. TheCU.addRange(RangeSpan(FunctionBeginSym, FunctionEndSym)); @@ -1679,9 +1259,10 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { // subroutines inside it. if (TheCU.getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly && LScopes.getAbstractScopesList().empty() && !IsDarwin) { - assert(ScopeVariables.empty()); - assert(CurrentFnArguments.empty()); + assert(InfoHolder.getScopeVariables().empty()); assert(DbgValues.empty()); + // FIXME: This wouldn't be true in LTO with a -g (with inlining) CU followed + // by a -gmlt CU. Add a test and remove this assertion. assert(AbstractVariables.empty()); LabelsBeforeInsn.clear(); LabelsAfterInsn.clear(); @@ -1690,6 +1271,9 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { return; } +#ifndef NDEBUG + size_t NumAbstractScopes = LScopes.getAbstractScopesList().size(); +#endif // Construct abstract scopes. for (LexicalScope *AScope : LScopes.getAbstractScopesList()) { DISubprogram SP(AScope->getScopeNode()); @@ -1702,18 +1286,19 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { if (!ProcessedVars.insert(DV)) continue; ensureAbstractVariableIsCreated(DV, DV.getContext()); + assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes + && "ensureAbstractVariableIsCreated inserted abstract scopes"); } - constructAbstractSubprogramScopeDIE(TheCU, AScope); + constructAbstractSubprogramScopeDIE(AScope); } - constructSubprogramScopeDIE(TheCU, FnScope); + TheCU.constructSubprogramScopeDIE(FnScope); // Clear debug info // Ownership of DbgVariables is a bit subtle - ScopeVariables owns all the // DbgVariables except those that are also in AbstractVariables (since they // can be used cross-function) - ScopeVariables.clear(); - CurrentFnArguments.clear(); + InfoHolder.getScopeVariables().clear(); DbgValues.clear(); LabelsBeforeInsn.clear(); LabelsAfterInsn.clear(); @@ -1844,7 +1429,7 @@ void DwarfDebug::emitDIE(DIE &Die) { void DwarfDebug::emitDebugInfo() { DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; - Holder.emitUnits(this, DwarfAbbrevSectionSym); + Holder.emitUnits(DwarfAbbrevSectionSym); } // Emit the abbreviation section. @@ -1979,12 +1564,13 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) { GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection() : Asm->getObjFileLowering().getDwarfPubNamesSection(); - emitDebugPubSection(GnuStyle, PSec, "Names", &DwarfUnit::getGlobalNames); + emitDebugPubSection(GnuStyle, PSec, "Names", + &DwarfCompileUnit::getGlobalNames); } void DwarfDebug::emitDebugPubSection( bool GnuStyle, const MCSection *PSec, StringRef Name, - const StringMap &(DwarfUnit::*Accessor)() const) { + const StringMap &(DwarfCompileUnit::*Accessor)() const) { for (const auto &NU : CUMap) { DwarfCompileUnit *TheU = NU.second; @@ -1993,7 +1579,7 @@ void DwarfDebug::emitDebugPubSection( if (Globals.empty()) continue; - if (auto Skeleton = static_cast(TheU->getSkeleton())) + if (auto *Skeleton = TheU->getSkeleton()) TheU = Skeleton; unsigned ID = TheU->getUniqueID(); @@ -2015,7 +1601,7 @@ void DwarfDebug::emitDebugPubSection( Asm->EmitSectionOffset(TheU->getLabelBegin(), TheU->getSectionSym()); Asm->OutStreamer.AddComment("Compilation Unit Length"); - Asm->EmitLabelDifference(TheU->getLabelEnd(), TheU->getLabelBegin(), 4); + Asm->EmitInt32(TheU->getLength()); // Emit the pubnames for this compilation unit. for (const auto &GI : Globals) { @@ -2048,7 +1634,8 @@ void DwarfDebug::emitDebugPubTypes(bool GnuStyle) { GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection() : Asm->getObjFileLowering().getDwarfPubTypesSection(); - emitDebugPubSection(GnuStyle, PSec, "Types", &DwarfUnit::getGlobalTypes); + emitDebugPubSection(GnuStyle, PSec, "Types", + &DwarfCompileUnit::getGlobalTypes); } // Emit visible names into a debug str section. @@ -2205,9 +1792,7 @@ void DwarfDebug::emitDebugLoc() { // Set up the range. This range is relative to the entry point of the // compile unit. This is a hard coded 0 for low_pc when we're emitting // ranges, or the DW_AT_low_pc on the compile unit otherwise. - if (CU->getRanges().size() == 1) { - // Grab the begin symbol from the first range as our base. - const MCSymbol *Base = CU->getRanges()[0].getStart(); + if (auto *Base = CU->getBaseAddress()) { Asm->EmitLabelDifference(Entry.getBeginSym(), Base, Size); Asm->EmitLabelDifference(Entry.getEndSym(), Base, Size); } else { @@ -2337,6 +1922,10 @@ void DwarfDebug::emitDebugARanges() { for (DwarfCompileUnit *CU : CUs) { std::vector &List = Spans[CU]; + // Describe the skeleton CU's offset and length, not the dwo file's. + if (auto *Skel = CU->getSkeleton()) + CU = Skel; + // Emit size of content not including length itself. unsigned ContentSize = sizeof(int16_t) + // DWARF ARange version number @@ -2359,7 +1948,7 @@ void DwarfDebug::emitDebugARanges() { Asm->OutStreamer.AddComment("DWARF Arange version number"); Asm->EmitInt16(dwarf::DW_ARANGES_VERSION); Asm->OutStreamer.AddComment("Offset Into Debug Info Section"); - Asm->EmitSectionOffset(CU->getLocalLabelBegin(), CU->getLocalSectionSym()); + Asm->EmitSectionOffset(CU->getLabelBegin(), CU->getSectionSym()); Asm->OutStreamer.AddComment("Address Size (in bytes)"); Asm->EmitInt8(PtrSize); Asm->OutStreamer.AddComment("Segment Size (in bytes)"); @@ -2413,9 +2002,7 @@ void DwarfDebug::emitDebugRanges() { const MCSymbol *End = Range.getEnd(); assert(Begin && "Range without a begin symbol?"); assert(End && "Range without an end symbol?"); - if (TheCU->getRanges().size() == 1) { - // Grab the begin symbol from the first range as our base. - const MCSymbol *Base = TheCU->getRanges()[0].getStart(); + if (auto *Base = TheCU->getBaseAddress()) { Asm->EmitLabelDifference(Begin, Base, Size); Asm->EmitLabelDifference(End, Base, Size); } else { @@ -2452,11 +2039,11 @@ void DwarfDebug::emitDebugRanges() { void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die, std::unique_ptr NewU) { - NewU->addLocalString(Die, dwarf::DW_AT_GNU_dwo_name, - U.getCUNode().getSplitDebugFilename()); + NewU->addString(Die, dwarf::DW_AT_GNU_dwo_name, + U.getCUNode().getSplitDebugFilename()); if (!CompilationDir.empty()) - NewU->addLocalString(Die, dwarf::DW_AT_comp_dir, CompilationDir); + NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir); addGnuPubAttributes(*NewU, Die); @@ -2487,7 +2074,7 @@ void DwarfDebug::emitDebugInfoDWO() { assert(useSplitDwarf() && "No split dwarf debug info?"); // Don't pass an abbrev symbol, using a constant zero instead so as not to // emit relocations into the dwo file. - InfoHolder.emitUnits(this, /* AbbrevSymbol */ nullptr); + InfoHolder.emitUnits(/* AbbrevSymbol */ nullptr); } // Emit the .debug_abbrev.dwo section for separated dwarf. This contains the @@ -2568,8 +2155,7 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, NewTU.setTypeSignature(Signature); if (useSplitDwarf()) - NewTU.initSection(Asm->getObjFileLowering().getDwarfTypesDWOSection(), - DwarfTypesDWOSectionSym); + NewTU.initSection(Asm->getObjFileLowering().getDwarfTypesDWOSection()); else { CU.applyStmtList(UnitDie); NewTU.initSection(