Skip to content

[BOLT][DWARF][NFC] Split DIEBuilder::finish #101244

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions bolt/include/bolt/Core/DIEBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ class DIEBuilder {
DWARFContext *DwarfContext{nullptr};
DWARFUnit *SkeletonCU{nullptr};
uint64_t UnitSize{0};
uint64_t DebugNamesUnitSize{0};
llvm::DenseSet<uint64_t> AllProcessed;
DWARF5AcceleratorTable &DebugNamesTable;
// Unordered map to handle name collision if output DWO directory is
Expand Down Expand Up @@ -203,13 +204,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<BOLTDWARF5AccelTableData *> Parent,
uint32_t NumberParentsInChain, uint32_t &CurOffset);
uint32_t finalizeDIEs(DWARFUnit &CU, DIE &Die, uint32_t &CurOffset);

/// Populates DebugNames table.
void populateDebugNamesTable(DWARFUnit &CU, DIE &Die,
std::optional<BOLTDWARF5AccelTableData *> Parent,
uint32_t NumberParentsInChain);

void registerUnit(DWARFUnit &DU, bool NeedSort);

Expand Down Expand Up @@ -338,6 +342,9 @@ class DIEBuilder {
/// Finish current DIE construction.
void finish();

/// Update debug names table.
void updateDebugNamesTable();

// Interface to edit DIE
template <class T> T *allocateDIEValue() {
return new (getState().DIEAlloc) T;
Expand Down
63 changes: 46 additions & 17 deletions bolt/lib/Core/DIEBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,17 +461,11 @@ getUnitForOffset(DIEBuilder &Builder, DWARFContext &DWCtx,
return nullptr;
}

uint32_t
DIEBuilder::finalizeDIEs(DWARFUnit &CU, DIE &Die,
std::optional<BOLTDWARF5AccelTableData *> 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<BOLTDWARF5AccelTableData *> 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
Expand All @@ -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.
Expand All @@ -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<std::optional<BOLTDWARF5AccelTableData *>> Parents;
Parents.push_back(std::nullopt);
finalizeDIEs(CU, *UnitDIE, std::nullopt, 0, CurOffset);
finalizeDIEs(CU, *UnitDIE, CurOffset);

DWARFUnitInfo &CurUnitInfo = getUnitInfoByDwarfUnit(CU);
CurUnitInfo.UnitOffset = UnitStartOffset;
Expand All @@ -539,7 +527,7 @@ void DIEBuilder::finish() {
// Skipping DWARF4 types.
if (CU->getVersion() < 5 && CU->isTypeUnit())
continue;
finalizeCU(*CU, UnitSize);
finalizeCU(*CU, DebugNamesUnitSize);
}
if (opts::Verbosity >= 1) {
if (!getState().DWARFDieAddressesParsed.empty())
Expand All @@ -548,6 +536,47 @@ void DIEBuilder::finish() {
dbgs() << Twine::utohexstr(Address) << "\n";
}
}
}

void DIEBuilder::populateDebugNamesTable(
DWARFUnit &CU, DIE &Die, std::optional<BOLTDWARF5AccelTableData *> Parent,
uint32_t NumberParentsInChain) {
std::optional<BOLTDWARF5AccelTableData *> NameEntry =
DebugNamesTable.addAccelTableEntry(
CU, Die, SkeletonCU ? SkeletonCU->getDWOId() : std::nullopt,
NumberParentsInChain, Parent);
if (!Parent && NumberParentsInChain)
NameEntry = std::nullopt;
if (NameEntry)
++NumberParentsInChain;

for (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, UnitSize);
}
updateReferences();
}

Expand Down
26 changes: 22 additions & 4 deletions bolt/lib/Rewrite/DWARFRewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -673,9 +673,8 @@ void DWARFRewriter::updateDebugInfo() {
DebugRangesSectionWriter &TempRangesSectionWriter,
DebugAddrWriter &AddressWriter,
const std::string &DWOName,
const std::optional<std::string> &DwarfOutputPath) {
DIEBuilder DWODIEBuilder(BC, &(SplitCU).getContext(), DebugNamesTable,
&Unit);
const std::optional<std::string> &DwarfOutputPath,
DIEBuilder &DWODIEBuilder) {
DWODIEBuilder.buildDWOUnit(SplitCU);
DebugStrOffsetsWriter DWOStrOffstsWriter(BC);
DebugStrWriter DWOStrWriter((SplitCU).getContext(), true);
Expand Down Expand Up @@ -742,6 +741,7 @@ void DWARFRewriter::updateDebugInfo() {
CUPartitionVector PartVec = partitionCUs(*BC.DwCtx);
for (std::vector<DWARFUnit *> &Vec : PartVec) {
DIEBlder.buildCompileUnits(Vec);
llvm::SmallVector<std::unique_ptr<DIEBuilder>> DWODIEBuildersByCU;
for (DWARFUnit *CU : DIEBlder.getProcessedCUs()) {
createRangeLocListAddressWriters(*CU);
std::optional<DWARFUnit *> SplitCU;
Expand All @@ -761,10 +761,26 @@ void DWARFRewriter::updateDebugInfo() {
: std::optional<std::string>(opts::DwarfOutputPath.c_str());
std::string DWOName = DIEBlder.updateDWONameCompDir(
*StrOffstsWriter, *StrWriter, *CU, DwarfOutputPath, std::nullopt);
auto DWODIEBuilderPtr = std::make_unique<DIEBuilder>(
BC, &(**SplitCU).getContext(), DebugNamesTable, CU);
DWODIEBuildersByCU.emplace_back(std::move(DWODIEBuilderPtr));
DIEBuilder &DWODIEBuilder = *DWODIEBuildersByCU.back().get();
if (CU->getVersion() >= 5)
StrOffstsWriter->finalizeSection(*CU, DIEBlder);
processSplitCU(*CU, **SplitCU, DIEBlder, *TempRangesSectionWriter,
AddressWriter, DWOName, DwarfOutputPath);
AddressWriter, DWOName, DwarfOutputPath, DWODIEBuilder);
}
unsigned DWODIEBuilderIndex = 0;
for (DWARFUnit *CU : DIEBlder.getProcessedCUs()) {
std::optional<DWARFUnit *> SplitCU;
std::optional<uint64_t> DWOId = CU->getDWOId();
if (DWOId)
SplitCU = BC.getDWOCU(*DWOId);
if (!SplitCU)
continue;
DIEBuilder &DWODIEBuilder =
*DWODIEBuildersByCU[DWODIEBuilderIndex++].get();
DWODIEBuilder.updateDebugNamesTable();
}
for (DWARFUnit *CU : DIEBlder.getProcessedCUs())
processMainBinaryCU(*CU, DIEBlder);
Expand Down Expand Up @@ -1468,6 +1484,7 @@ CUOffsetMap DWARFRewriter::finalizeTypeSections(DIEBuilder &DIEBlder,
// generate and populate abbrevs here
DIEBlder.generateAbbrevs();
DIEBlder.finish();
DIEBlder.updateDebugNamesTable();
SmallVector<char, 20> OutBuffer;
std::shared_ptr<raw_svector_ostream> ObjOS =
std::make_shared<raw_svector_ostream>(OutBuffer);
Expand Down Expand Up @@ -1672,6 +1689,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);
Expand Down
Loading