diff --git a/bolt/include/bolt/Core/DIEBuilder.h b/bolt/include/bolt/Core/DIEBuilder.h index 0b840c142ed81..e5b057ea1e42b 100644 --- a/bolt/include/bolt/Core/DIEBuilder.h +++ b/bolt/include/bolt/Core/DIEBuilder.h @@ -127,6 +127,9 @@ class DIEBuilder { DWARFContext *DwarfContext{nullptr}; DWARFUnit *SkeletonCU{nullptr}; uint64_t UnitSize{0}; + /// Adds separate UnitSize counter for updating DebugNames + /// so there is no dependency between the functions. + uint64_t DebugNamesUnitSize{0}; llvm::DenseSet AllProcessed; DWARF5AcceleratorTable &DebugNamesTable; // Unordered map to handle name collision if output DWO directory is @@ -203,13 +206,16 @@ class DIEBuilder { /// Update references once the layout is finalized. void updateReferences(); - /// Update the Offset and Size of DIE, populate DebugNames table. + /// Update the Offset and Size of DIE. /// Along with current CU, and DIE being processed and the new DIE offset to /// be updated, it takes in Parents vector that can be empty if this DIE has /// no parents. - uint32_t finalizeDIEs(DWARFUnit &CU, DIE &Die, - std::optional Parent, - uint32_t NumberParentsInChain, uint32_t &CurOffset); + uint32_t finalizeDIEs(DWARFUnit &CU, DIE &Die, uint32_t &CurOffset); + + /// Populates DebugNames table. + void populateDebugNamesTable(DWARFUnit &CU, const DIE &Die, + std::optional Parent, + uint32_t NumberParentsInChain); void registerUnit(DWARFUnit &DU, bool NeedSort); @@ -338,6 +344,9 @@ class DIEBuilder { /// Finish current DIE construction. void finish(); + /// Update debug names table. + void updateDebugNamesTable(); + // Interface to edit DIE template T *allocateDIEValue() { return new (getState().DIEAlloc) T; diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp index 8f6195f6b6ea1..69cfd58a1df04 100644 --- a/bolt/lib/Core/DIEBuilder.cpp +++ b/bolt/lib/Core/DIEBuilder.cpp @@ -461,17 +461,11 @@ getUnitForOffset(DIEBuilder &Builder, DWARFContext &DWCtx, return nullptr; } -uint32_t -DIEBuilder::finalizeDIEs(DWARFUnit &CU, DIE &Die, - std::optional Parent, - uint32_t NumberParentsInChain, uint32_t &CurOffset) { +uint32_t DIEBuilder::finalizeDIEs(DWARFUnit &CU, DIE &Die, + uint32_t &CurOffset) { getState().DWARFDieAddressesParsed.erase(Die.getOffset()); uint32_t CurSize = 0; Die.setOffset(CurOffset); - std::optional NameEntry = - DebugNamesTable.addAccelTableEntry( - CU, Die, SkeletonCU ? SkeletonCU->getDWOId() : std::nullopt, - NumberParentsInChain, Parent); // It is possible that an indexed debugging information entry has a parent // that is not indexed (for example, if its parent does not have a name // attribute). In such a case, a parent attribute may point to a nameless @@ -485,18 +479,13 @@ DIEBuilder::finalizeDIEs(DWARFUnit &CU, DIE &Die, // If Parent is nullopt and NumberParentsInChain is not zero, then forward // declaration was encountered in this DF traversal. Propagating nullopt for // Parent to children. - if (!Parent && NumberParentsInChain) - NameEntry = std::nullopt; - if (NameEntry) - ++NumberParentsInChain; for (DIEValue &Val : Die.values()) CurSize += Val.sizeOf(CU.getFormParams()); CurSize += getULEB128Size(Die.getAbbrevNumber()); CurOffset += CurSize; for (DIE &Child : Die.children()) { - uint32_t ChildSize = - finalizeDIEs(CU, Child, NameEntry, NumberParentsInChain, CurOffset); + uint32_t ChildSize = finalizeDIEs(CU, Child, CurOffset); CurSize += ChildSize; } // for children end mark. @@ -514,10 +503,9 @@ void DIEBuilder::finish() { DIE *UnitDIE = getUnitDIEbyUnit(CU); uint32_t HeaderSize = CU.getHeaderSize(); uint32_t CurOffset = HeaderSize; - DebugNamesTable.setCurrentUnit(CU, UnitStartOffset); std::vector> Parents; Parents.push_back(std::nullopt); - finalizeDIEs(CU, *UnitDIE, std::nullopt, 0, CurOffset); + finalizeDIEs(CU, *UnitDIE, CurOffset); DWARFUnitInfo &CurUnitInfo = getUnitInfoByDwarfUnit(CU); CurUnitInfo.UnitOffset = UnitStartOffset; @@ -548,6 +536,48 @@ void DIEBuilder::finish() { dbgs() << Twine::utohexstr(Address) << "\n"; } } +} + +void DIEBuilder::populateDebugNamesTable( + DWARFUnit &CU, const DIE &Die, + std::optional Parent, + uint32_t NumberParentsInChain) { + std::optional NameEntry = + DebugNamesTable.addAccelTableEntry( + CU, Die, SkeletonCU ? SkeletonCU->getDWOId() : std::nullopt, + NumberParentsInChain, Parent); + if (!Parent && NumberParentsInChain) + NameEntry = std::nullopt; + if (NameEntry) + ++NumberParentsInChain; + + for (const DIE &Child : Die.children()) + populateDebugNamesTable(CU, Child, NameEntry, NumberParentsInChain); +} + +void DIEBuilder::updateDebugNamesTable() { + auto finalizeDebugNamesTableForCU = [&](DWARFUnit &CU, + uint64_t &UnitStartOffset) -> void { + DIE *UnitDIE = getUnitDIEbyUnit(CU); + DebugNamesTable.setCurrentUnit(CU, UnitStartOffset); + populateDebugNamesTable(CU, *UnitDIE, std::nullopt, 0); + + DWARFUnitInfo &CurUnitInfo = getUnitInfoByDwarfUnit(CU); + UnitStartOffset += CurUnitInfo.UnitLength; + }; + + uint64_t TypeUnitStartOffset = 0; + for (DWARFUnit *CU : getState().DUList) { + if (!(CU->getVersion() < 5 && CU->isTypeUnit())) + break; + finalizeDebugNamesTableForCU(*CU, TypeUnitStartOffset); + } + + for (DWARFUnit *CU : getState().DUList) { + if (CU->getVersion() < 5 && CU->isTypeUnit()) + continue; + finalizeDebugNamesTableForCU(*CU, DebugNamesUnitSize); + } updateReferences(); } diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp index beef1a8f902ad..dfdfe658dd87e 100644 --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -673,9 +673,8 @@ void DWARFRewriter::updateDebugInfo() { DebugRangesSectionWriter &TempRangesSectionWriter, DebugAddrWriter &AddressWriter, const std::string &DWOName, - const std::optional &DwarfOutputPath) { - DIEBuilder DWODIEBuilder(BC, &(SplitCU).getContext(), DebugNamesTable, - &Unit); + const std::optional &DwarfOutputPath, + DIEBuilder &DWODIEBuilder) { DWODIEBuilder.buildDWOUnit(SplitCU); DebugStrOffsetsWriter DWOStrOffstsWriter(BC); DebugStrWriter DWOStrWriter((SplitCU).getContext(), true); @@ -742,6 +741,7 @@ void DWARFRewriter::updateDebugInfo() { CUPartitionVector PartVec = partitionCUs(*BC.DwCtx); for (std::vector &Vec : PartVec) { DIEBlder.buildCompileUnits(Vec); + llvm::SmallVector, 72> DWODIEBuildersByCU; for (DWARFUnit *CU : DIEBlder.getProcessedCUs()) { createRangeLocListAddressWriters(*CU); std::optional SplitCU; @@ -761,11 +761,17 @@ void DWARFRewriter::updateDebugInfo() { : std::optional(opts::DwarfOutputPath.c_str()); std::string DWOName = DIEBlder.updateDWONameCompDir( *StrOffstsWriter, *StrWriter, *CU, DwarfOutputPath, std::nullopt); + auto DWODIEBuilderPtr = std::make_unique( + BC, &(**SplitCU).getContext(), DebugNamesTable, CU); + DIEBuilder &DWODIEBuilder = + *DWODIEBuildersByCU.emplace_back(std::move(DWODIEBuilderPtr)).get(); if (CU->getVersion() >= 5) StrOffstsWriter->finalizeSection(*CU, DIEBlder); processSplitCU(*CU, **SplitCU, DIEBlder, *TempRangesSectionWriter, - AddressWriter, DWOName, DwarfOutputPath); + AddressWriter, DWOName, DwarfOutputPath, DWODIEBuilder); } + for (std::unique_ptr &DWODIEBuilderPtr : DWODIEBuildersByCU) + DWODIEBuilderPtr->updateDebugNamesTable(); for (DWARFUnit *CU : DIEBlder.getProcessedCUs()) processMainBinaryCU(*CU, DIEBlder); finalizeCompileUnits(DIEBlder, *Streamer, OffsetMap, @@ -1468,6 +1474,7 @@ CUOffsetMap DWARFRewriter::finalizeTypeSections(DIEBuilder &DIEBlder, // generate and populate abbrevs here DIEBlder.generateAbbrevs(); DIEBlder.finish(); + DIEBlder.updateDebugNamesTable(); SmallVector OutBuffer; std::shared_ptr ObjOS = std::make_shared(OutBuffer); @@ -1672,6 +1679,7 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder, } DIEBlder.generateAbbrevs(); DIEBlder.finish(); + DIEBlder.updateDebugNamesTable(); // generate debug_info and CUMap for (DWARFUnit *CU : CUs) { emitUnit(DIEBlder, Streamer, *CU);