[llvm] [BOLT][DWARF][NFC] Add support for multithreading (PR #99068)

Sayhaan Siddiqui via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 16 10:57:22 PDT 2024


https://github.com/sayhaan created https://github.com/llvm/llvm-project/pull/99068

Adds support for parallelizing the processing of DWO CUs.

>From cfb901ec45eae9ca0b0a47182d29d9836a827008 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Mon, 8 Jul 2024 10:26:50 -0700
Subject: [PATCH 01/15] Refactor address writers

Summary:

Test Plan:

Reviewers:

Subscribers:

Tasks:

Tags:

Differential Revision: https://phabricator.intern.facebook.com/D59493903
---
 bolt/include/bolt/Core/DebugData.h        | 53 ++++++++++++-----
 bolt/include/bolt/Rewrite/DWARFRewriter.h |  5 ++
 bolt/lib/Core/DebugData.cpp               | 71 +++++++++++------------
 bolt/lib/Rewrite/DWARFRewriter.cpp        | 63 ++++++++++++--------
 4 files changed, 118 insertions(+), 74 deletions(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 2324e577cc7c9..70d3db86a33ff 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -343,14 +343,34 @@ class DebugAddrWriter {
   uint32_t getIndexFromAddress(uint64_t Address, DWARFUnit &CU);
 
   /// Write out entries in to .debug_addr section for CUs.
-  virtual void update(DIEBuilder &DIEBlder, DWARFUnit &CUs);
+  virtual void update();
 
   /// Return buffer with all the entries in .debug_addr already writen out using
   /// update(...).
   virtual AddressSectionBuffer &finalize() { return *Buffer; }
 
   /// Returns False if .debug_addr section was created..
-  bool isInitialized() const { return !AddressMaps.empty(); }
+  bool isInitialized() { return Map.empty; }
+
+  /// Updates address base with the given Offset.
+  virtual void updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
+                              const uint64_t Offset);
+
+  /// Appends an AddressSectionBuffer to the address writer buffer for the given
+  /// CU.
+  void appendToAddressBuffer(const AddressSectionBuffer &Buffer) {
+    *AddressStream << Buffer;
+  }
+
+  /// Sets AddressByteSize for the CU.
+  void setAddressByteSize(uint8_t AddressByteSize) {
+    this->AddressByteSize = AddressByteSize;
+  }
+
+  /// Sets AddrOffsetSectionBase for the CU.
+  void setAddrOffsetSectionBase(std::optional<uint64_t> AddrOffsetSectionBase) {
+    this->AddrOffsetSectionBase = AddrOffsetSectionBase;
+  }
 
 protected:
   class AddressForDWOCU {
@@ -395,6 +415,8 @@ class DebugAddrWriter {
 
     void dump();
 
+    bool empty = false;
+
   private:
     AddressToIndexMap AddressToIndex;
     IndexToAddressMap IndexToAddress;
@@ -407,14 +429,16 @@ class DebugAddrWriter {
   }
 
   BinaryContext *BC;
-  /// Maps DWOID to AddressForDWOCU.
-  std::unordered_map<uint64_t, AddressForDWOCU> AddressMaps;
+  /// Address for the DWO CU associated with the address writer.
+  AddressForDWOCU Map;
+  uint8_t AddressByteSize;
+  std::optional<uint64_t> AddrOffsetSectionBase;
   /// Mutex used for parallel processing of debug info.
   std::mutex WriterMutex;
   std::unique_ptr<AddressSectionBuffer> Buffer;
   std::unique_ptr<raw_svector_ostream> AddressStream;
   /// Used to track sections that were not modified so that they can be re-used.
-  DenseMap<uint64_t, uint64_t> UnmodifiedAddressOffsets;
+  static DenseMap<uint64_t, uint64_t> UnmodifiedAddressOffsets;
 };
 
 class DebugAddrWriterDwarf5 : public DebugAddrWriter {
@@ -423,7 +447,10 @@ class DebugAddrWriterDwarf5 : public DebugAddrWriter {
   DebugAddrWriterDwarf5(BinaryContext *BC) : DebugAddrWriter(BC) {}
 
   /// Write out entries in to .debug_addr section for CUs.
-  virtual void update(DIEBuilder &DIEBlder, DWARFUnit &CUs) override;
+  virtual void update() override;
+
+  virtual void updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
+                              const uint64_t Offset) override;
 
 protected:
   /// Given DWARFUnit \p Unit returns either DWO ID or it's offset within
@@ -583,12 +610,10 @@ class DebugLoclistWriter : public DebugLocWriter {
 public:
   ~DebugLoclistWriter() {}
   DebugLoclistWriter() = delete;
-  DebugLoclistWriter(DWARFUnit &Unit, uint8_t DV, bool SD)
-      : DebugLocWriter(DV, LocWriterKind::DebugLoclistWriter), CU(Unit),
-        IsSplitDwarf(SD) {
-    assert(DebugLoclistWriter::AddrWriter &&
-           "Please use SetAddressWriter to initialize "
-           "DebugAddrWriter before instantiation.");
+  DebugLoclistWriter(DWARFUnit &Unit, uint8_t DV, bool SD,
+                     DebugAddrWriter *AddrW)
+      : DebugLocWriter(DV, LocWriterKind::DebugLoclistWriter),
+        AddrWriter(AddrW), CU(Unit), IsSplitDwarf(SD) {
     if (DwarfVersion >= 5) {
       LocBodyBuffer = std::make_unique<DebugBufferVector>();
       LocBodyStream = std::make_unique<raw_svector_ostream>(*LocBodyBuffer);
@@ -600,7 +625,7 @@ class DebugLoclistWriter : public DebugLocWriter {
     }
   }
 
-  static void setAddressWriter(DebugAddrWriter *AddrW) { AddrWriter = AddrW; }
+  void setAddressWriter(DebugAddrWriter *AddrW) { AddrWriter = AddrW; }
 
   /// Stores location lists internally to be written out during finalize phase.
   virtual void addList(DIEBuilder &DIEBldr, DIE &Die, DIEValue &AttrInfo,
@@ -630,7 +655,7 @@ class DebugLoclistWriter : public DebugLocWriter {
   /// Writes out locations in to a local buffer and applies debug info patches.
   void finalizeDWARF5(DIEBuilder &DIEBldr, DIE &Die);
 
-  static DebugAddrWriter *AddrWriter;
+  DebugAddrWriter *AddrWriter;
   DWARFUnit &CU;
   bool IsSplitDwarf{false};
   // Used for DWARF5 to store location lists before being finalized.
diff --git a/bolt/include/bolt/Rewrite/DWARFRewriter.h b/bolt/include/bolt/Rewrite/DWARFRewriter.h
index 4f576eaa95576..49cec64ce4cea 100644
--- a/bolt/include/bolt/Rewrite/DWARFRewriter.h
+++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h
@@ -93,6 +93,10 @@ class DWARFRewriter {
   std::unordered_map<uint64_t, std::unique_ptr<DebugRangesSectionWriter>>
       LegacyRangesWritersByCU;
 
+  /// Stores address writer for each CU.
+  std::unordered_map<uint64_t, std::unique_ptr<DebugAddrWriter>>
+      AddressWritersByCU;
+
   std::mutex LocListDebugInfoPatchesMutex;
 
   /// Dwo id specific its RangesBase.
@@ -115,6 +119,7 @@ class DWARFRewriter {
   void updateUnitDebugInfo(DWARFUnit &Unit, DIEBuilder &DIEBldr,
                            DebugLocWriter &DebugLocWriter,
                            DebugRangesSectionWriter &RangesSectionWriter,
+                           DebugAddrWriter &AddressWriter,
                            std::optional<uint64_t> RangesBase = std::nullopt);
 
   /// Patches the binary for an object's address ranges to be updated.
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index 76c3545c63088..323464d946c43 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -393,6 +393,7 @@ void DebugARangesSectionWriter::writeARangesSection(
 DebugAddrWriter::DebugAddrWriter(BinaryContext *BC) : BC(BC) {
   Buffer = std::make_unique<AddressSectionBuffer>();
   AddressStream = std::make_unique<raw_svector_ostream>(*Buffer);
+  Map = AddressForDWOCU();
 }
 
 void DebugAddrWriter::AddressForDWOCU::dump() {
@@ -405,11 +406,8 @@ void DebugAddrWriter::AddressForDWOCU::dump() {
 }
 uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address, DWARFUnit &CU) {
   std::lock_guard<std::mutex> Lock(WriterMutex);
-  const uint64_t CUID = getCUID(CU);
-  if (!AddressMaps.count(CUID))
-    AddressMaps[CUID] = AddressForDWOCU();
-
-  AddressForDWOCU &Map = AddressMaps[CUID];
+  if (Map.begin() == Map.end())
+    Map.empty = true;
   auto Entry = Map.find(Address);
   if (Entry == Map.end()) {
     auto Index = Map.getNextIndex();
@@ -449,25 +447,20 @@ static void updateAddressBase(DIEBuilder &DIEBlder, DebugAddrWriter &AddrWriter,
   }
 }
 
-void DebugAddrWriter::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
-  // Handling the case where debug information is a mix of Debug fission and
-  // monolithic.
-  if (!CU.getDWOId())
-    return;
-  const uint64_t CUID = getCUID(CU);
-  auto AM = AddressMaps.find(CUID);
-  // Adding to map even if it did not contribute to .debug_addr.
-  // The Skeleton CU might still have DW_AT_GNU_addr_base.
-  uint64_t Offset = Buffer->size();
-  // If does not exist this CUs DWO section didn't contribute to .debug_addr.
-  if (AM == AddressMaps.end())
+void DebugAddrWriter::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
+                                     const uint64_t Offset) {
+  updateAddressBase(DIEBlder, *this, CU, Offset);
+}
+
+void DebugAddrWriter::update() {
+  if (Map.indexToAddressBegin() == Map.indexToAdddessEnd())
     return;
-  std::vector<IndexAddressPair> SortedMap(AM->second.indexToAddressBegin(),
-                                          AM->second.indexToAdddessEnd());
+  std::vector<IndexAddressPair> SortedMap(Map.indexToAddressBegin(),
+                                          Map.indexToAdddessEnd());
   // Sorting address in increasing order of indices.
   llvm::sort(SortedMap, llvm::less_first());
 
-  uint8_t AddrSize = CU.getAddressByteSize();
+  uint8_t AddrSize = AddressByteSize;
   uint32_t Counter = 0;
   auto WriteAddress = [&](uint64_t Address) -> void {
     ++Counter;
@@ -490,10 +483,23 @@ void DebugAddrWriter::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
       WriteAddress(0);
     WriteAddress(Val.second);
   }
-  updateAddressBase(DIEBlder, *this, CU, Offset);
 }
 
-void DebugAddrWriterDwarf5::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
+void DebugAddrWriterDwarf5::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
+                                           const uint64_t Offset) {
+  /// Doesn't update address base if the CU doesn't access .debug_addr.
+  if (Map.indexToAddressBegin() == Map.indexToAdddessEnd()) {
+    std::optional<uint64_t> BaseOffset = CU.getAddrOffsetSectionBase();
+    if (!BaseOffset)
+      return;
+  }
+  /// Header for DWARF5 has size 8, so we add it to the offset.
+  updateAddressBase(DIEBlder, *this, CU, Offset + 8);
+}
+
+DenseMap<uint64_t, uint64_t> DebugAddrWriter::UnmodifiedAddressOffsets;
+
+void DebugAddrWriterDwarf5::update() {
   // Need to layout all sections within .debug_addr
   // Within each section sort Address by index.
   const endianness Endian = BC->DwCtx->isLittleEndian()
@@ -505,14 +511,11 @@ void DebugAddrWriterDwarf5::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
   DWARFDebugAddrTable AddrTable;
   DIDumpOptions DumpOpts;
   constexpr uint32_t HeaderSize = 8;
-  const uint64_t CUID = getCUID(CU);
-  const uint8_t AddrSize = CU.getAddressByteSize();
-  auto AMIter = AddressMaps.find(CUID);
+  const uint8_t AddrSize = AddressByteSize;
   // A case where CU has entry in .debug_addr, but we don't modify addresses
   // for it.
-  if (AMIter == AddressMaps.end()) {
-    AMIter = AddressMaps.insert({CUID, AddressForDWOCU()}).first;
-    std::optional<uint64_t> BaseOffset = CU.getAddrOffsetSectionBase();
+  if (Map.indexToAddressBegin() == Map.indexToAdddessEnd()) {
+    std::optional<uint64_t> BaseOffset = AddrOffsetSectionBase;
     if (!BaseOffset)
       return;
     // Address base offset is to the first entry.
@@ -520,7 +523,6 @@ void DebugAddrWriterDwarf5::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
     uint64_t Offset = *BaseOffset - HeaderSize;
     auto Iter = UnmodifiedAddressOffsets.find(Offset);
     if (Iter != UnmodifiedAddressOffsets.end()) {
-      updateAddressBase(DIEBlder, *this, CU, Iter->getSecond());
       return;
     }
     UnmodifiedAddressOffsets[Offset] = Buffer->size() + HeaderSize;
@@ -529,16 +531,13 @@ void DebugAddrWriterDwarf5::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
       DumpOpts.RecoverableErrorHandler(std::move(Err));
       return;
     }
-
     uint32_t Index = 0;
     for (uint64_t Addr : AddrTable.getAddressEntries())
-      AMIter->second.insert(Addr, Index++);
+      Map.insert(Addr, Index++);
   }
 
-  updateAddressBase(DIEBlder, *this, CU, Buffer->size() + HeaderSize);
-
-  std::vector<IndexAddressPair> SortedMap(AMIter->second.indexToAddressBegin(),
-                                          AMIter->second.indexToAdddessEnd());
+  std::vector<IndexAddressPair> SortedMap(Map.indexToAddressBegin(),
+                                          Map.indexToAdddessEnd());
   // Sorting address in increasing order of indices.
   llvm::sort(SortedMap, llvm::less_first());
   // Writing out Header
@@ -789,8 +788,6 @@ void DebugLoclistWriter::finalize(DIEBuilder &DIEBldr, DIE &Die) {
     finalizeDWARF5(DIEBldr, Die);
 }
 
-DebugAddrWriter *DebugLoclistWriter::AddrWriter = nullptr;
-
 static std::string encodeLE(size_t ByteSize, uint64_t NewValue) {
   std::string LE64(ByteSize, 0);
   for (size_t I = 0; I < ByteSize; ++I) {
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 89168b4bd559c..2a0fe77315c97 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -615,7 +615,6 @@ void DWARFRewriter::updateDebugInfo() {
   if (BC.isDWARF5Used()) {
     AddrWriter = std::make_unique<DebugAddrWriterDwarf5>(&BC);
     RangeListsSectionWriter = std::make_unique<DebugRangeListsSectionWriter>();
-    DebugRangeListsSectionWriter::setAddressWriter(AddrWriter.get());
   } else {
     AddrWriter = std::make_unique<DebugAddrWriter>(&BC);
   }
@@ -625,8 +624,6 @@ void DWARFRewriter::updateDebugInfo() {
     LegacyRangesSectionWriter->initSection();
   }
 
-  DebugLoclistWriter::setAddressWriter(AddrWriter.get());
-
   uint32_t CUIndex = 0;
   std::mutex AccessMutex;
   // Needs to be invoked in the same order as CUs are processed.
@@ -634,8 +631,16 @@ void DWARFRewriter::updateDebugInfo() {
     std::lock_guard<std::mutex> Lock(AccessMutex);
     const uint16_t DwarfVersion = CU.getVersion();
     if (DwarfVersion >= 5) {
-      LocListWritersByCU[CUIndex] =
-          std::make_unique<DebugLoclistWriter>(CU, DwarfVersion, false);
+      auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(&BC);
+      AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
+      DebugRangeListsSectionWriter::setAddressWriter(
+          AddressWritersByCU[CU.getOffset()].get());
+      AddressWritersByCU[CU.getOffset()]->setAddressByteSize(
+          CU.getAddressByteSize());
+      AddressWritersByCU[CU.getOffset()]->setAddrOffsetSectionBase(
+          CU.getAddrOffsetSectionBase());
+      LocListWritersByCU[CUIndex] = std::make_unique<DebugLoclistWriter>(
+          CU, DwarfVersion, false, AddressWritersByCU[CU.getOffset()].get());
 
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(RangeListsWritersByCU.count(*DWOId) == 0 &&
@@ -647,6 +652,10 @@ void DWARFRewriter::updateDebugInfo() {
       }
 
     } else {
+      auto AddrW = std::make_unique<DebugAddrWriter>(&BC);
+      AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
+      AddressWritersByCU[CU.getOffset()]->setAddressByteSize(
+          CU.getAddressByteSize());
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>();
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(LegacyRangesWritersByCU.count(*DWOId) == 0 &&
@@ -678,6 +687,7 @@ void DWARFRewriter::updateDebugInfo() {
     DebugRangesSectionWriter *RangesSectionWriter =
         Unit->getVersion() >= 5 ? RangeListsSectionWriter.get()
                                 : LegacyRangesSectionWriter.get();
+    auto &AddressWriter = AddressWritersByCU[Unit->getOffset()];
     // Skipping CUs that failed to load.
     if (SplitCU) {
       DIEBuilder DWODIEBuilder(BC, &(*SplitCU)->getContext(), DebugNamesTable,
@@ -698,7 +708,8 @@ void DWARFRewriter::updateDebugInfo() {
       DWODIEBuilder.updateDWONameCompDirForTypes(DWOStrOffstsWriter,
                                                  DWOStrWriter, **SplitCU,
                                                  DwarfOutputPath, DWOName);
-      DebugLoclistWriter DebugLocDWoWriter(*Unit, Unit->getVersion(), true);
+      DebugLoclistWriter DebugLocDWoWriter(*Unit, Unit->getVersion(), true,
+                                           AddressWriter.get());
       DebugRangesSectionWriter *TempRangesSectionWriter = RangesSectionWriter;
       if (Unit->getVersion() >= 5) {
         TempRangesSectionWriter = RangeListsWritersByCU[*DWOId].get();
@@ -709,7 +720,7 @@ void DWARFRewriter::updateDebugInfo() {
       }
 
       updateUnitDebugInfo(*(*SplitCU), DWODIEBuilder, DebugLocDWoWriter,
-                          *TempRangesSectionWriter);
+                          *TempRangesSectionWriter, *AddressWriter.get());
       DebugLocDWoWriter.finalize(DWODIEBuilder,
                                  *DWODIEBuilder.getUnitDIEbyUnit(**SplitCU));
       if (Unit->getVersion() >= 5)
@@ -728,11 +739,10 @@ void DWARFRewriter::updateDebugInfo() {
     }
 
     updateUnitDebugInfo(*Unit, *DIEBlder, *DebugLocWriter, *RangesSectionWriter,
-                        RangesBase);
+                        *AddressWriter.get(), RangesBase);
     DebugLocWriter->finalize(*DIEBlder, *DIEBlder->getUnitDIEbyUnit(*Unit));
     if (Unit->getVersion() >= 5)
       RangesSectionWriter->finalizeSection();
-    AddrWriter->update(*DIEBlder, *Unit);
   };
 
   DIEBuilder DIEBlder(BC, BC.DwCtx.get(), DebugNamesTable);
@@ -782,7 +792,7 @@ void DWARFRewriter::updateDebugInfo() {
 void DWARFRewriter::updateUnitDebugInfo(
     DWARFUnit &Unit, DIEBuilder &DIEBldr, DebugLocWriter &DebugLocWriter,
     DebugRangesSectionWriter &RangesSectionWriter,
-    std::optional<uint64_t> RangesBase) {
+    DebugAddrWriter &AddressWriter, std::optional<uint64_t> RangesBase) {
   // Cache debug ranges so that the offset for identical ranges could be reused.
   std::map<DebugAddressRangesVector, uint64_t> CachedRanges;
 
@@ -816,7 +826,7 @@ void DWARFRewriter::updateUnitDebugInfo(
 
     if (FormLowPC == dwarf::DW_FORM_addrx ||
         FormLowPC == dwarf::DW_FORM_GNU_addr_index)
-      LowPC = AddrWriter->getIndexFromAddress(LowPC, Unit);
+      LowPC = AddressWriter.getIndexFromAddress(LowPC, Unit);
 
     if (LowPCVal)
       DIEBldr.replaceValue(Die, AttrLowPC, FormLowPC, DIEInteger(LowPC));
@@ -980,7 +990,7 @@ void DWARFRewriter::updateUnitDebugInfo(
 
         if (AttrVal.getForm() == dwarf::DW_FORM_addrx) {
           const uint32_t Index =
-              AddrWriter->getIndexFromAddress(UpdatedAddress, Unit);
+              AddressWriter.getIndexFromAddress(UpdatedAddress, Unit);
           DIEBldr.replaceValue(Die, AttrVal.getAttribute(), AttrVal.getForm(),
                                DIEInteger(Index));
         } else if (AttrVal.getForm() == dwarf::DW_FORM_addr) {
@@ -1197,7 +1207,7 @@ void DWARFRewriter::updateUnitDebugInfo(
                 assert(EntryAddress && "Address is not found.");
                 assert(Index <= std::numeric_limits<uint32_t>::max() &&
                        "Invalid Operand Index.");
-                const uint32_t AddrIndex = AddrWriter->getIndexFromAddress(
+                const uint32_t AddrIndex = AddressWriter.getIndexFromAddress(
                     EntryAddress->Address, Unit);
                 // update Index into .debug_address section for DW_AT_location.
                 // The Size field is not stored in IR, we need to minus 1 in
@@ -1249,7 +1259,7 @@ void DWARFRewriter::updateUnitDebugInfo(
           std::lock_guard<std::mutex> Lock(DWARFRewriterMutex);
           if (Form == dwarf::DW_FORM_addrx ||
               Form == dwarf::DW_FORM_GNU_addr_index) {
-            const uint32_t Index = AddrWriter->getIndexFromAddress(
+            const uint32_t Index = AddressWriter.getIndexFromAddress(
                 NewAddress ? NewAddress : Address, Unit);
             DIEBldr.replaceValue(Die, LowPCAttrInfo.getAttribute(),
                                  LowPCAttrInfo.getForm(), DIEInteger(Index));
@@ -1565,14 +1575,10 @@ void DWARFRewriter::finalizeDebugSections(
           LocationListSectionContents->size());
   }
 
-  // AddrWriter should be finalized after debug_loc since more addresses can be
-  // added there.
-  if (AddrWriter->isInitialized()) {
-    AddressSectionBuffer AddressSectionContents = AddrWriter->finalize();
-    BC.registerOrUpdateNoteSection(".debug_addr",
-                                   copyByteArray(AddressSectionContents),
-                                   AddressSectionContents.size());
-  }
+  AddressSectionBuffer AddressSectionContents = AddrWriter->finalize();
+  BC.registerOrUpdateNoteSection(".debug_addr",
+                                 copyByteArray(AddressSectionContents),
+                                 AddressSectionContents.size());
 
   Streamer.emitAbbrevs(DIEBlder.getAbbrevs(), BC.DwCtx->getMaxVersion());
   Streamer.finish();
@@ -1626,6 +1632,16 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
                                          CUOffsetMap &CUMap,
                                          const std::list<DWARFUnit *> &CUs) {
   for (DWARFUnit *CU : CUs) {
+    auto AddressWriterIterator = AddressWritersByCU.find(CU->getOffset());
+    assert(AddressWriterIterator != AddressWritersByCU.end() &&
+           "AddressWriter does not exist for CU");
+    auto &AddressWriter = AddressWriterIterator->second;
+    AddressWriter->update();
+    AddressWriter->updateAddrBase(DIEBlder, *CU, AddrWriter->finalize().size());
+    if (AddressWriter->isInitialized()) {
+      AddressSectionBuffer AddressSectionContents = AddressWriter->finalize();
+      AddrWriter->appendToAddressBuffer(AddressSectionContents);
+    }
     if (CU->getVersion() != 4)
       continue;
     std::optional<uint64_t> DWOId = CU->getDWOId();
@@ -2155,7 +2171,8 @@ void DWARFRewriter::convertToRangesPatchDebugInfo(
   // when it's absent.
   if (IsUnitDie) {
     if (LowForm == dwarf::DW_FORM_addrx) {
-      const uint32_t Index = AddrWriter->getIndexFromAddress(0, Unit);
+      const uint32_t Index =
+          AddressWritersByCU[Unit.getOffset()]->getIndexFromAddress(0, Unit);
       DIEBldr.replaceValue(&Die, LowPCAttrInfo.getAttribute(),
                            LowPCAttrInfo.getForm(), DIEInteger(Index));
     } else {

>From 89eb24d773838b85ae44c28d95412a4bcbefaeae Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Tue, 9 Jul 2024 15:29:42 -0700
Subject: [PATCH 02/15] Updates and formatting changes

---
 bolt/include/bolt/Core/DebugData.h        | 21 +++++---
 bolt/include/bolt/Rewrite/DWARFRewriter.h |  2 +-
 bolt/lib/Core/DebugData.cpp               | 52 ++++++++------------
 bolt/lib/Rewrite/DWARFRewriter.cpp        | 59 ++++++++++++++---------
 4 files changed, 71 insertions(+), 63 deletions(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 70d3db86a33ff..8bec44c19a35c 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -343,14 +343,19 @@ class DebugAddrWriter {
   uint32_t getIndexFromAddress(uint64_t Address, DWARFUnit &CU);
 
   /// Write out entries in to .debug_addr section for CUs.
-  virtual void update();
+  virtual std::optional<uint64_t> finalize(const size_t BufferSize);
 
   /// Return buffer with all the entries in .debug_addr already writen out using
   /// update(...).
-  virtual AddressSectionBuffer &finalize() { return *Buffer; }
+  virtual std::unique_ptr<AddressSectionBuffer> releaseBuffer() {
+    return std::move(Buffer);
+  }
+
+  /// Returns buffer size.
+  virtual size_t getBufferSize() { return Buffer->size(); }
 
   /// Returns False if .debug_addr section was created..
-  bool isInitialized() { return Map.empty; }
+  bool isInitialized() { return Buffer->size() > 0; }
 
   /// Updates address base with the given Offset.
   virtual void updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
@@ -363,12 +368,13 @@ class DebugAddrWriter {
   }
 
   /// Sets AddressByteSize for the CU.
-  void setAddressByteSize(uint8_t AddressByteSize) {
+  void setAddressByteSize(const uint8_t AddressByteSize) {
     this->AddressByteSize = AddressByteSize;
   }
 
   /// Sets AddrOffsetSectionBase for the CU.
-  void setAddrOffsetSectionBase(std::optional<uint64_t> AddrOffsetSectionBase) {
+  void setAddrOffsetSectionBase(
+      const std::optional<uint64_t> AddrOffsetSectionBase) {
     this->AddrOffsetSectionBase = AddrOffsetSectionBase;
   }
 
@@ -415,8 +421,6 @@ class DebugAddrWriter {
 
     void dump();
 
-    bool empty = false;
-
   private:
     AddressToIndexMap AddressToIndex;
     IndexToAddressMap IndexToAddress;
@@ -433,6 +437,7 @@ class DebugAddrWriter {
   AddressForDWOCU Map;
   uint8_t AddressByteSize;
   std::optional<uint64_t> AddrOffsetSectionBase;
+  static constexpr uint32_t HeaderSize = 8;
   /// Mutex used for parallel processing of debug info.
   std::mutex WriterMutex;
   std::unique_ptr<AddressSectionBuffer> Buffer;
@@ -447,7 +452,7 @@ class DebugAddrWriterDwarf5 : public DebugAddrWriter {
   DebugAddrWriterDwarf5(BinaryContext *BC) : DebugAddrWriter(BC) {}
 
   /// Write out entries in to .debug_addr section for CUs.
-  virtual void update() override;
+  virtual std::optional<uint64_t> finalize(const size_t BufferSize) override;
 
   virtual void updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
                               const uint64_t Offset) override;
diff --git a/bolt/include/bolt/Rewrite/DWARFRewriter.h b/bolt/include/bolt/Rewrite/DWARFRewriter.h
index 49cec64ce4cea..ac3b26b08e593 100644
--- a/bolt/include/bolt/Rewrite/DWARFRewriter.h
+++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h
@@ -68,7 +68,7 @@ class DWARFRewriter {
 
   /// Stores and serializes information that will be put into the
   /// .debug_addr DWARF section.
-  std::unique_ptr<DebugAddrWriter> AddrWriter;
+  std::unique_ptr<DebugAddrWriter> FinalAddrWriter;
 
   /// Stores and serializes information that will be put in to the
   /// .debug_addr DWARF section.
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index 323464d946c43..bbf4a9e3b42b1 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -393,7 +393,6 @@ void DebugARangesSectionWriter::writeARangesSection(
 DebugAddrWriter::DebugAddrWriter(BinaryContext *BC) : BC(BC) {
   Buffer = std::make_unique<AddressSectionBuffer>();
   AddressStream = std::make_unique<raw_svector_ostream>(*Buffer);
-  Map = AddressForDWOCU();
 }
 
 void DebugAddrWriter::AddressForDWOCU::dump() {
@@ -406,8 +405,6 @@ void DebugAddrWriter::AddressForDWOCU::dump() {
 }
 uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address, DWARFUnit &CU) {
   std::lock_guard<std::mutex> Lock(WriterMutex);
-  if (Map.begin() == Map.end())
-    Map.empty = true;
   auto Entry = Map.find(Address);
   if (Entry == Map.end()) {
     auto Index = Map.getNextIndex();
@@ -452,19 +449,18 @@ void DebugAddrWriter::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
   updateAddressBase(DIEBlder, *this, CU, Offset);
 }
 
-void DebugAddrWriter::update() {
-  if (Map.indexToAddressBegin() == Map.indexToAdddessEnd())
-    return;
+std::optional<uint64_t> DebugAddrWriter::finalize(size_t BufferSize) {
+  if (Map.begin() == Map.end())
+    return std::nullopt;
   std::vector<IndexAddressPair> SortedMap(Map.indexToAddressBegin(),
                                           Map.indexToAdddessEnd());
   // Sorting address in increasing order of indices.
   llvm::sort(SortedMap, llvm::less_first());
 
-  uint8_t AddrSize = AddressByteSize;
   uint32_t Counter = 0;
   auto WriteAddress = [&](uint64_t Address) -> void {
     ++Counter;
-    switch (AddrSize) {
+    switch (AddressByteSize) {
     default:
       assert(false && "Address Size is invalid.");
       break;
@@ -483,23 +479,18 @@ void DebugAddrWriter::update() {
       WriteAddress(0);
     WriteAddress(Val.second);
   }
+  return std::nullopt;
 }
 
 void DebugAddrWriterDwarf5::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
                                            const uint64_t Offset) {
-  /// Doesn't update address base if the CU doesn't access .debug_addr.
-  if (Map.indexToAddressBegin() == Map.indexToAdddessEnd()) {
-    std::optional<uint64_t> BaseOffset = CU.getAddrOffsetSectionBase();
-    if (!BaseOffset)
-      return;
-  }
   /// Header for DWARF5 has size 8, so we add it to the offset.
-  updateAddressBase(DIEBlder, *this, CU, Offset + 8);
+  updateAddressBase(DIEBlder, *this, CU, Offset + HeaderSize);
 }
 
 DenseMap<uint64_t, uint64_t> DebugAddrWriter::UnmodifiedAddressOffsets;
 
-void DebugAddrWriterDwarf5::update() {
+std::optional<uint64_t> DebugAddrWriterDwarf5::finalize(size_t BufferSize) {
   // Need to layout all sections within .debug_addr
   // Within each section sort Address by index.
   const endianness Endian = BC->DwCtx->isLittleEndian()
@@ -510,26 +501,22 @@ void DebugAddrWriterDwarf5::update() {
                               Endian == llvm::endianness::little, 0);
   DWARFDebugAddrTable AddrTable;
   DIDumpOptions DumpOpts;
-  constexpr uint32_t HeaderSize = 8;
-  const uint8_t AddrSize = AddressByteSize;
   // A case where CU has entry in .debug_addr, but we don't modify addresses
   // for it.
-  if (Map.indexToAddressBegin() == Map.indexToAdddessEnd()) {
-    std::optional<uint64_t> BaseOffset = AddrOffsetSectionBase;
-    if (!BaseOffset)
-      return;
+  if (Map.begin() == Map.end()) {
+    if (!AddrOffsetSectionBase)
+      return std::nullopt;
     // Address base offset is to the first entry.
     // The size of header is 8 bytes.
-    uint64_t Offset = *BaseOffset - HeaderSize;
+    uint64_t Offset = *AddrOffsetSectionBase - HeaderSize;
     auto Iter = UnmodifiedAddressOffsets.find(Offset);
-    if (Iter != UnmodifiedAddressOffsets.end()) {
-      return;
-    }
-    UnmodifiedAddressOffsets[Offset] = Buffer->size() + HeaderSize;
-    if (Error Err = AddrTable.extract(AddrData, &Offset, 5, AddrSize,
+    if (Iter != UnmodifiedAddressOffsets.end())
+      return Iter->second;
+    UnmodifiedAddressOffsets[Offset] = BufferSize;
+    if (Error Err = AddrTable.extract(AddrData, &Offset, 5, AddressByteSize,
                                       DumpOpts.WarningHandler)) {
       DumpOpts.RecoverableErrorHandler(std::move(Err));
-      return;
+      return std::nullopt;
     }
     uint32_t Index = 0;
     for (uint64_t Addr : AddrTable.getAddressEntries())
@@ -541,17 +528,17 @@ void DebugAddrWriterDwarf5::update() {
   // Sorting address in increasing order of indices.
   llvm::sort(SortedMap, llvm::less_first());
   // Writing out Header
-  const uint32_t Length = SortedMap.size() * AddrSize + 4;
+  const uint32_t Length = SortedMap.size() * AddressByteSize + 4;
   support::endian::write(*AddressStream, Length, Endian);
   support::endian::write(*AddressStream, static_cast<uint16_t>(5), Endian);
-  support::endian::write(*AddressStream, static_cast<uint8_t>(AddrSize),
+  support::endian::write(*AddressStream, static_cast<uint8_t>(AddressByteSize),
                          Endian);
   support::endian::write(*AddressStream, static_cast<uint8_t>(0), Endian);
 
   uint32_t Counter = 0;
   auto writeAddress = [&](uint64_t Address) -> void {
     ++Counter;
-    switch (AddrSize) {
+    switch (AddressByteSize) {
     default:
       llvm_unreachable("Address Size is invalid.");
       break;
@@ -570,6 +557,7 @@ void DebugAddrWriterDwarf5::update() {
       writeAddress(0);
     writeAddress(Val.second);
   }
+  return std::nullopt;
 }
 
 void DebugLocWriter::init() {
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 2a0fe77315c97..1283123cfa3f6 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -613,10 +613,10 @@ void DWARFRewriter::updateDebugInfo() {
   }
 
   if (BC.isDWARF5Used()) {
-    AddrWriter = std::make_unique<DebugAddrWriterDwarf5>(&BC);
+    FinalAddrWriter = std::make_unique<DebugAddrWriterDwarf5>(&BC);
     RangeListsSectionWriter = std::make_unique<DebugRangeListsSectionWriter>();
   } else {
-    AddrWriter = std::make_unique<DebugAddrWriter>(&BC);
+    FinalAddrWriter = std::make_unique<DebugAddrWriter>(&BC);
   }
 
   if (BC.isDWARFLegacyUsed()) {
@@ -632,15 +632,16 @@ void DWARFRewriter::updateDebugInfo() {
     const uint16_t DwarfVersion = CU.getVersion();
     if (DwarfVersion >= 5) {
       auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(&BC);
-      AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
+      std::unique_ptr<DebugAddrWriter> &AddressWriterIterator =
+          AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)})
+              .first->second;
       DebugRangeListsSectionWriter::setAddressWriter(
-          AddressWritersByCU[CU.getOffset()].get());
-      AddressWritersByCU[CU.getOffset()]->setAddressByteSize(
-          CU.getAddressByteSize());
-      AddressWritersByCU[CU.getOffset()]->setAddrOffsetSectionBase(
+          AddressWriterIterator.get());
+      AddressWriterIterator->setAddressByteSize(CU.getAddressByteSize());
+      AddressWriterIterator->setAddrOffsetSectionBase(
           CU.getAddrOffsetSectionBase());
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLoclistWriter>(
-          CU, DwarfVersion, false, AddressWritersByCU[CU.getOffset()].get());
+          CU, DwarfVersion, false, AddressWriterIterator.get());
 
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(RangeListsWritersByCU.count(*DWOId) == 0 &&
@@ -653,9 +654,10 @@ void DWARFRewriter::updateDebugInfo() {
 
     } else {
       auto AddrW = std::make_unique<DebugAddrWriter>(&BC);
-      AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
-      AddressWritersByCU[CU.getOffset()]->setAddressByteSize(
-          CU.getAddressByteSize());
+      std::unique_ptr<DebugAddrWriter> &AddressWriterIterator =
+          AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)})
+              .first->second;
+      AddressWriterIterator->setAddressByteSize(CU.getAddressByteSize());
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>();
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(LegacyRangesWritersByCU.count(*DWOId) == 0 &&
@@ -687,7 +689,8 @@ void DWARFRewriter::updateDebugInfo() {
     DebugRangesSectionWriter *RangesSectionWriter =
         Unit->getVersion() >= 5 ? RangeListsSectionWriter.get()
                                 : LegacyRangesSectionWriter.get();
-    auto &AddressWriter = AddressWritersByCU[Unit->getOffset()];
+    std::unique_ptr<DebugAddrWriter> &AddressWriter =
+        AddressWritersByCU[Unit->getOffset()];
     // Skipping CUs that failed to load.
     if (SplitCU) {
       DIEBuilder DWODIEBuilder(BC, &(*SplitCU)->getContext(), DebugNamesTable,
@@ -1575,10 +1578,13 @@ void DWARFRewriter::finalizeDebugSections(
           LocationListSectionContents->size());
   }
 
-  AddressSectionBuffer AddressSectionContents = AddrWriter->finalize();
-  BC.registerOrUpdateNoteSection(".debug_addr",
-                                 copyByteArray(AddressSectionContents),
-                                 AddressSectionContents.size());
+  if (FinalAddrWriter->isInitialized()) {
+    std::unique_ptr<AddressSectionBuffer> AddressSectionContents =
+        FinalAddrWriter->releaseBuffer();
+    BC.registerOrUpdateNoteSection(".debug_addr",
+                                   copyByteArray(*AddressSectionContents),
+                                   AddressSectionContents->size());
+  }
 
   Streamer.emitAbbrevs(DIEBlder.getAbbrevs(), BC.DwCtx->getMaxVersion());
   Streamer.finish();
@@ -1635,12 +1641,18 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
     auto AddressWriterIterator = AddressWritersByCU.find(CU->getOffset());
     assert(AddressWriterIterator != AddressWritersByCU.end() &&
            "AddressWriter does not exist for CU");
-    auto &AddressWriter = AddressWriterIterator->second;
-    AddressWriter->update();
-    AddressWriter->updateAddrBase(DIEBlder, *CU, AddrWriter->finalize().size());
+    std::unique_ptr<DebugAddrWriter> &AddressWriter =
+        AddressWriterIterator->second;
+    const size_t BufferOffset = FinalAddrWriter->getBufferSize();
+    std::optional<uint64_t> Offset = AddressWriter->finalize(BufferOffset);
+    if (Offset)
+      AddressWriter->updateAddrBase(DIEBlder, *CU, *Offset);
+    else if (AddressWriter->isInitialized())
+      AddressWriter->updateAddrBase(DIEBlder, *CU, BufferOffset);
     if (AddressWriter->isInitialized()) {
-      AddressSectionBuffer AddressSectionContents = AddressWriter->finalize();
-      AddrWriter->appendToAddressBuffer(AddressSectionContents);
+      std::unique_ptr<AddressSectionBuffer> AddressSectionContents =
+          AddressWriter->releaseBuffer();
+      FinalAddrWriter->appendToAddressBuffer(*AddressSectionContents);
     }
     if (CU->getVersion() != 4)
       continue;
@@ -2171,8 +2183,11 @@ void DWARFRewriter::convertToRangesPatchDebugInfo(
   // when it's absent.
   if (IsUnitDie) {
     if (LowForm == dwarf::DW_FORM_addrx) {
+      auto AddrWriterIterator = AddressWritersByCU.find(Unit.getOffset());
+      assert(AddrWriterIterator != AddressWritersByCU.end() &&
+             "AddressWriter does not exist for CU");
       const uint32_t Index =
-          AddressWritersByCU[Unit.getOffset()]->getIndexFromAddress(0, Unit);
+          AddrWriterIterator->second->getIndexFromAddress(0, Unit);
       DIEBldr.replaceValue(&Die, LowPCAttrInfo.getAttribute(),
                            LowPCAttrInfo.getForm(), DIEInteger(Index));
     } else {

>From f5d094d2b805abdc1c20d9594211577c89d79bc2 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Tue, 9 Jul 2024 15:37:25 -0700
Subject: [PATCH 03/15] Add comment

---
 bolt/lib/Rewrite/DWARFRewriter.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 1283123cfa3f6..3dd0eba8d2ce7 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -1645,6 +1645,8 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
         AddressWriterIterator->second;
     const size_t BufferOffset = FinalAddrWriter->getBufferSize();
     std::optional<uint64_t> Offset = AddressWriter->finalize(BufferOffset);
+    /// If Offset already exists in UnmodifiedAddressOffsets, then update with
+    /// Offset, else update with BufferOffset.
     if (Offset)
       AddressWriter->updateAddrBase(DIEBlder, *CU, *Offset);
     else if (AddressWriter->isInitialized())

>From ae5b1ba863df538429325aa6e070a7d73d155294 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Tue, 9 Jul 2024 15:40:16 -0700
Subject: [PATCH 04/15] Formatting changes

---
 bolt/lib/Core/DebugData.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index bbf4a9e3b42b1..5ad7582f08280 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -449,7 +449,7 @@ void DebugAddrWriter::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
   updateAddressBase(DIEBlder, *this, CU, Offset);
 }
 
-std::optional<uint64_t> DebugAddrWriter::finalize(size_t BufferSize) {
+std::optional<uint64_t> DebugAddrWriter::finalize(const size_t BufferSize) {
   if (Map.begin() == Map.end())
     return std::nullopt;
   std::vector<IndexAddressPair> SortedMap(Map.indexToAddressBegin(),
@@ -490,7 +490,7 @@ void DebugAddrWriterDwarf5::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
 
 DenseMap<uint64_t, uint64_t> DebugAddrWriter::UnmodifiedAddressOffsets;
 
-std::optional<uint64_t> DebugAddrWriterDwarf5::finalize(size_t BufferSize) {
+std::optional<uint64_t> DebugAddrWriterDwarf5::finalize(const size_t BufferSize) {
   // Need to layout all sections within .debug_addr
   // Within each section sort Address by index.
   const endianness Endian = BC->DwCtx->isLittleEndian()

>From b51aceb778fa9ed97e5d3bb1294b9a168e1f2676 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Tue, 9 Jul 2024 15:45:10 -0700
Subject: [PATCH 05/15] Formatting changes

---
 bolt/lib/Core/DebugData.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index 5ad7582f08280..c93e96b529c79 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -490,7 +490,8 @@ void DebugAddrWriterDwarf5::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
 
 DenseMap<uint64_t, uint64_t> DebugAddrWriter::UnmodifiedAddressOffsets;
 
-std::optional<uint64_t> DebugAddrWriterDwarf5::finalize(const size_t BufferSize) {
+std::optional<uint64_t>
+DebugAddrWriterDwarf5::finalize(const size_t BufferSize) {
   // Need to layout all sections within .debug_addr
   // Within each section sort Address by index.
   const endianness Endian = BC->DwCtx->isLittleEndian()

>From d266b7d425558a476682a16db40ec93378ee9c71 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Tue, 9 Jul 2024 16:32:13 -0700
Subject: [PATCH 06/15] Updated test to catch edge case

---
 bolt/test/X86/dwarf5-addr-section-reuse.s | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/bolt/test/X86/dwarf5-addr-section-reuse.s b/bolt/test/X86/dwarf5-addr-section-reuse.s
index 6b00ce0fdf805..cf511d6d111e0 100644
--- a/bolt/test/X86/dwarf5-addr-section-reuse.s
+++ b/bolt/test/X86/dwarf5-addr-section-reuse.s
@@ -1,7 +1,7 @@
 # RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-main-addr-section-reuse.s    -o %tmain.o
 # RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-helper1-addr-section-reuse.s -o %thelper1.o
 # RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-helper2-addr-section-reuse.s -o %thelper2.o
-# RUN: %clang %cflags -dwarf-5 %tmain.o %thelper1.o %thelper2.o -o %t.exe -Wl,-q
+# RUN: %clang %cflags -dwarf-5 %thelper1.o %tmain.o %thelper2.o -o %t.exe -Wl,-q
 # RUN: llvm-dwarfdump --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s
 # RUN: llvm-bolt %t.exe -o %t.exe.bolt --update-debug-sections
 # RUN: llvm-dwarfdump --debug-info %t.exe.bolt | FileCheck --check-prefix=POSTCHECK %s
@@ -14,5 +14,5 @@
 # PRECHECK: DW_AT_addr_base (0x00000008)
 
 # POSTCHECK: DW_AT_addr_base (0x00000008)
-# POSTCHECK: DW_AT_addr_base (0x00000020)
-# POSTCHECK: DW_AT_addr_base (0x00000020)
+# POSTCHECK: DW_AT_addr_base (0x00000018)
+# POSTCHECK: DW_AT_addr_base (0x00000008)

>From d65ffa88a12f1309ec666c900e8158d4b46d8a32 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Wed, 10 Jul 2024 16:01:31 -0700
Subject: [PATCH 07/15] Updates and formatting changes

---
 bolt/include/bolt/Core/DebugData.h | 38 ++++++++--------------
 bolt/lib/Core/DebugData.cpp        |  7 ++--
 bolt/lib/Rewrite/DWARFRewriter.cpp | 51 ++++++++++++++----------------
 3 files changed, 43 insertions(+), 53 deletions(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 8bec44c19a35c..1bbf13f0c60a6 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -256,7 +256,7 @@ class DebugRangeListsSectionWriter : public DebugRangesSectionWriter {
   };
   virtual ~DebugRangeListsSectionWriter(){};
 
-  static void setAddressWriter(DebugAddrWriter *AddrW) { AddrWriter = AddrW; }
+  void setAddressWriter(DebugAddrWriter *AddrW) { AddrWriter = AddrW; }
 
   /// Add ranges with caching.
   uint64_t addRanges(
@@ -284,7 +284,7 @@ class DebugRangeListsSectionWriter : public DebugRangesSectionWriter {
   }
 
 private:
-  static DebugAddrWriter *AddrWriter;
+  DebugAddrWriter *AddrWriter = nullptr;
   /// Used to find unique CU ID.
   DWARFUnit *CU;
   /// Current relative offset of range list entry within this CUs rangelist
@@ -337,6 +337,7 @@ class DebugAddrWriter {
 public:
   DebugAddrWriter() = delete;
   DebugAddrWriter(BinaryContext *BC_);
+  DebugAddrWriter(BinaryContext *BC_, uint8_t AddressByteSize);
   virtual ~DebugAddrWriter(){};
   /// Given an address returns an index in .debug_addr.
   /// Adds Address to map.
@@ -354,30 +355,18 @@ class DebugAddrWriter {
   /// Returns buffer size.
   virtual size_t getBufferSize() { return Buffer->size(); }
 
-  /// Returns False if .debug_addr section was created..
-  bool isInitialized() { return Buffer->size() > 0; }
+  /// Returns True if Buffer is not empty.
+  bool isInitialized() { return !Buffer->empty(); }
 
   /// Updates address base with the given Offset.
   virtual void updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
                               const uint64_t Offset);
 
-  /// Appends an AddressSectionBuffer to the address writer buffer for the given
-  /// CU.
+  /// Appends an AddressSectionBuffer to the address writer's buffer.
   void appendToAddressBuffer(const AddressSectionBuffer &Buffer) {
     *AddressStream << Buffer;
   }
 
-  /// Sets AddressByteSize for the CU.
-  void setAddressByteSize(const uint8_t AddressByteSize) {
-    this->AddressByteSize = AddressByteSize;
-  }
-
-  /// Sets AddrOffsetSectionBase for the CU.
-  void setAddrOffsetSectionBase(
-      const std::optional<uint64_t> AddrOffsetSectionBase) {
-    this->AddrOffsetSectionBase = AddrOffsetSectionBase;
-  }
-
 protected:
   class AddressForDWOCU {
   public:
@@ -436,8 +425,6 @@ class DebugAddrWriter {
   /// Address for the DWO CU associated with the address writer.
   AddressForDWOCU Map;
   uint8_t AddressByteSize;
-  std::optional<uint64_t> AddrOffsetSectionBase;
-  static constexpr uint32_t HeaderSize = 8;
   /// Mutex used for parallel processing of debug info.
   std::mutex WriterMutex;
   std::unique_ptr<AddressSectionBuffer> Buffer;
@@ -449,7 +436,8 @@ class DebugAddrWriter {
 class DebugAddrWriterDwarf5 : public DebugAddrWriter {
 public:
   DebugAddrWriterDwarf5() = delete;
-  DebugAddrWriterDwarf5(BinaryContext *BC) : DebugAddrWriter(BC) {}
+  DebugAddrWriterDwarf5(BinaryContext *BC) : DebugAddrWriter(BC){}
+  DebugAddrWriterDwarf5(BinaryContext *BC, uint8_t AddressByteSize, std::optional<uint64_t> AddrOffsetSectionBase) : DebugAddrWriter(BC, AddressByteSize), AddrOffsetSectionBase(AddrOffsetSectionBase){}
 
   /// Write out entries in to .debug_addr section for CUs.
   virtual std::optional<uint64_t> finalize(const size_t BufferSize) override;
@@ -467,6 +455,10 @@ class DebugAddrWriterDwarf5 : public DebugAddrWriter {
     }
     return Unit.getOffset();
   }
+
+private:
+  std::optional<uint64_t> AddrOffsetSectionBase;
+  static constexpr uint32_t HeaderSize = 8;
 };
 
 /// This class is NOT thread safe.
@@ -616,9 +608,9 @@ class DebugLoclistWriter : public DebugLocWriter {
   ~DebugLoclistWriter() {}
   DebugLoclistWriter() = delete;
   DebugLoclistWriter(DWARFUnit &Unit, uint8_t DV, bool SD,
-                     DebugAddrWriter *AddrW)
+                     DebugAddrWriter &AddrW)
       : DebugLocWriter(DV, LocWriterKind::DebugLoclistWriter),
-        AddrWriter(AddrW), CU(Unit), IsSplitDwarf(SD) {
+        AddrWriter(&AddrW), CU(Unit), IsSplitDwarf(SD) {
     if (DwarfVersion >= 5) {
       LocBodyBuffer = std::make_unique<DebugBufferVector>();
       LocBodyStream = std::make_unique<raw_svector_ostream>(*LocBodyBuffer);
@@ -630,8 +622,6 @@ class DebugLoclistWriter : public DebugLocWriter {
     }
   }
 
-  void setAddressWriter(DebugAddrWriter *AddrW) { AddrWriter = AddrW; }
-
   /// Stores location lists internally to be written out during finalize phase.
   virtual void addList(DIEBuilder &DIEBldr, DIE &Die, DIEValue &AttrInfo,
                        DebugLocationsVector &LocList) override;
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index c93e96b529c79..562ea5d759a1d 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -184,8 +184,6 @@ void DebugRangesSectionWriter::appendToRangeBuffer(
   *RangesStream << CUBuffer;
 }
 
-DebugAddrWriter *DebugRangeListsSectionWriter::AddrWriter = nullptr;
-
 uint64_t DebugRangeListsSectionWriter::addRanges(
     DebugAddressRangesVector &&Ranges,
     std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) {
@@ -395,6 +393,11 @@ DebugAddrWriter::DebugAddrWriter(BinaryContext *BC) : BC(BC) {
   AddressStream = std::make_unique<raw_svector_ostream>(*Buffer);
 }
 
+DebugAddrWriter::DebugAddrWriter(BinaryContext *BC, const uint8_t AddressByteSize) : BC(BC), AddressByteSize(AddressByteSize) {
+  Buffer = std::make_unique<AddressSectionBuffer>();
+  AddressStream = std::make_unique<raw_svector_ostream>(*Buffer);
+}
+
 void DebugAddrWriter::AddressForDWOCU::dump() {
   std::vector<IndexAddressPair> SortedMap(indexToAddressBegin(),
                                           indexToAdddessEnd());
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 3dd0eba8d2ce7..d9b7982e1232b 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -627,21 +627,18 @@ void DWARFRewriter::updateDebugInfo() {
   uint32_t CUIndex = 0;
   std::mutex AccessMutex;
   // Needs to be invoked in the same order as CUs are processed.
-  auto createRangeLocList = [&](DWARFUnit &CU) -> DebugLocWriter * {
+  auto createRangeLocListAddressWriters = [&](DWARFUnit &CU) -> DebugLocWriter * {
     std::lock_guard<std::mutex> Lock(AccessMutex);
     const uint16_t DwarfVersion = CU.getVersion();
     if (DwarfVersion >= 5) {
-      auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(&BC);
-      std::unique_ptr<DebugAddrWriter> &AddressWriterIterator =
+      auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(&BC, CU.getAddressByteSize(), CU.getAddrOffsetSectionBase());
+      DebugAddrWriter *AddressWriter =
           AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)})
-              .first->second;
-      DebugRangeListsSectionWriter::setAddressWriter(
-          AddressWriterIterator.get());
-      AddressWriterIterator->setAddressByteSize(CU.getAddressByteSize());
-      AddressWriterIterator->setAddrOffsetSectionBase(
-          CU.getAddrOffsetSectionBase());
+              .first->second.get();
+      RangeListsSectionWriter->setAddressWriter(
+          AddressWriter);
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLoclistWriter>(
-          CU, DwarfVersion, false, AddressWriterIterator.get());
+          CU, DwarfVersion, false, *AddressWriter);
 
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(RangeListsWritersByCU.count(*DWOId) == 0 &&
@@ -649,23 +646,22 @@ void DWARFRewriter::updateDebugInfo() {
         auto RangeListsSectionWriter =
             std::make_unique<DebugRangeListsSectionWriter>();
         RangeListsSectionWriter->initSection(CU);
-        RangeListsWritersByCU[*DWOId] = std::move(RangeListsSectionWriter);
+        DebugRangeListsSectionWriter *RangeListSectionWriter = RangeListsWritersByCU.insert({*DWOId, std::move(RangeListsSectionWriter)}).first->second.get();
+        RangeListSectionWriter->setAddressWriter(AddressWriter);
       }
 
     } else {
-      auto AddrW = std::make_unique<DebugAddrWriter>(&BC);
-      std::unique_ptr<DebugAddrWriter> &AddressWriterIterator =
-          AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)})
-              .first->second;
-      AddressWriterIterator->setAddressByteSize(CU.getAddressByteSize());
+      auto AddrW = std::make_unique<DebugAddrWriter>(&BC, CU.getAddressByteSize());
+      AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)});
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>();
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(LegacyRangesWritersByCU.count(*DWOId) == 0 &&
                "LegacyRangeLists writer for DWO unit already exists.");
         auto LegacyRangesSectionWriterByCU =
             std::make_unique<DebugRangesSectionWriter>();
-        LegacyRangesWritersByCU[*DWOId] =
-            std::move(LegacyRangesSectionWriterByCU);
+        LegacyRangesSectionWriterByCU->initSection(CU);
+        LegacyRangesWritersByCU.insert({*DWOId,
+            std::move(LegacyRangesSectionWriterByCU)});
       }
     }
     return LocListWritersByCU[CUIndex++].get();
@@ -685,12 +681,12 @@ void DWARFRewriter::updateDebugInfo() {
     std::optional<uint64_t> DWOId = Unit->getDWOId();
     if (DWOId)
       SplitCU = BC.getDWOCU(*DWOId);
-    DebugLocWriter *DebugLocWriter = createRangeLocList(*Unit);
+    DebugLocWriter *DebugLocWriter = createRangeLocListAddressWriters(*Unit);
     DebugRangesSectionWriter *RangesSectionWriter =
         Unit->getVersion() >= 5 ? RangeListsSectionWriter.get()
                                 : LegacyRangesSectionWriter.get();
-    std::unique_ptr<DebugAddrWriter> &AddressWriter =
-        AddressWritersByCU[Unit->getOffset()];
+    DebugAddrWriter *AddressWriter =
+        AddressWritersByCU[Unit->getOffset()].get();
     // Skipping CUs that failed to load.
     if (SplitCU) {
       DIEBuilder DWODIEBuilder(BC, &(*SplitCU)->getContext(), DebugNamesTable,
@@ -712,7 +708,7 @@ void DWARFRewriter::updateDebugInfo() {
                                                  DWOStrWriter, **SplitCU,
                                                  DwarfOutputPath, DWOName);
       DebugLoclistWriter DebugLocDWoWriter(*Unit, Unit->getVersion(), true,
-                                           AddressWriter.get());
+                                           *AddressWriter);
       DebugRangesSectionWriter *TempRangesSectionWriter = RangesSectionWriter;
       if (Unit->getVersion() >= 5) {
         TempRangesSectionWriter = RangeListsWritersByCU[*DWOId].get();
@@ -723,7 +719,7 @@ void DWARFRewriter::updateDebugInfo() {
       }
 
       updateUnitDebugInfo(*(*SplitCU), DWODIEBuilder, DebugLocDWoWriter,
-                          *TempRangesSectionWriter, *AddressWriter.get());
+                          *TempRangesSectionWriter, *AddressWriter);
       DebugLocDWoWriter.finalize(DWODIEBuilder,
                                  *DWODIEBuilder.getUnitDIEbyUnit(**SplitCU));
       if (Unit->getVersion() >= 5)
@@ -742,7 +738,7 @@ void DWARFRewriter::updateDebugInfo() {
     }
 
     updateUnitDebugInfo(*Unit, *DIEBlder, *DebugLocWriter, *RangesSectionWriter,
-                        *AddressWriter.get(), RangesBase);
+                        *AddressWriter, RangesBase);
     DebugLocWriter->finalize(*DIEBlder, *DIEBlder->getUnitDIEbyUnit(*Unit));
     if (Unit->getVersion() >= 5)
       RangesSectionWriter->finalizeSection();
@@ -1641,8 +1637,8 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
     auto AddressWriterIterator = AddressWritersByCU.find(CU->getOffset());
     assert(AddressWriterIterator != AddressWritersByCU.end() &&
            "AddressWriter does not exist for CU");
-    std::unique_ptr<DebugAddrWriter> &AddressWriter =
-        AddressWriterIterator->second;
+    DebugAddrWriter *AddressWriter =
+        AddressWriterIterator->second.get();
     const size_t BufferOffset = FinalAddrWriter->getBufferSize();
     std::optional<uint64_t> Offset = AddressWriter->finalize(BufferOffset);
     /// If Offset already exists in UnmodifiedAddressOffsets, then update with
@@ -2188,8 +2184,9 @@ void DWARFRewriter::convertToRangesPatchDebugInfo(
       auto AddrWriterIterator = AddressWritersByCU.find(Unit.getOffset());
       assert(AddrWriterIterator != AddressWritersByCU.end() &&
              "AddressWriter does not exist for CU");
+      DebugAddrWriter *AddrWriter = AddrWriterIterator->second.get();
       const uint32_t Index =
-          AddrWriterIterator->second->getIndexFromAddress(0, Unit);
+          AddrWriter->getIndexFromAddress(0, Unit);
       DIEBldr.replaceValue(&Die, LowPCAttrInfo.getAttribute(),
                            LowPCAttrInfo.getForm(), DIEInteger(Index));
     } else {

>From 02b8c9cde97aaba0532f280a8420c70861302118 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Wed, 10 Jul 2024 16:03:54 -0700
Subject: [PATCH 08/15] Formatting changes

---
 bolt/include/bolt/Core/DebugData.h |  7 +++++--
 bolt/lib/Core/DebugData.cpp        |  4 +++-
 bolt/lib/Rewrite/DWARFRewriter.cpp | 27 +++++++++++++++------------
 3 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 1bbf13f0c60a6..481cca05539c2 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -436,8 +436,11 @@ class DebugAddrWriter {
 class DebugAddrWriterDwarf5 : public DebugAddrWriter {
 public:
   DebugAddrWriterDwarf5() = delete;
-  DebugAddrWriterDwarf5(BinaryContext *BC) : DebugAddrWriter(BC){}
-  DebugAddrWriterDwarf5(BinaryContext *BC, uint8_t AddressByteSize, std::optional<uint64_t> AddrOffsetSectionBase) : DebugAddrWriter(BC, AddressByteSize), AddrOffsetSectionBase(AddrOffsetSectionBase){}
+  DebugAddrWriterDwarf5(BinaryContext *BC) : DebugAddrWriter(BC) {}
+  DebugAddrWriterDwarf5(BinaryContext *BC, uint8_t AddressByteSize,
+                        std::optional<uint64_t> AddrOffsetSectionBase)
+      : DebugAddrWriter(BC, AddressByteSize),
+        AddrOffsetSectionBase(AddrOffsetSectionBase) {}
 
   /// Write out entries in to .debug_addr section for CUs.
   virtual std::optional<uint64_t> finalize(const size_t BufferSize) override;
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index 562ea5d759a1d..4b19e7d8440ff 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -393,7 +393,9 @@ DebugAddrWriter::DebugAddrWriter(BinaryContext *BC) : BC(BC) {
   AddressStream = std::make_unique<raw_svector_ostream>(*Buffer);
 }
 
-DebugAddrWriter::DebugAddrWriter(BinaryContext *BC, const uint8_t AddressByteSize) : BC(BC), AddressByteSize(AddressByteSize) {
+DebugAddrWriter::DebugAddrWriter(BinaryContext *BC,
+                                 const uint8_t AddressByteSize)
+    : BC(BC), AddressByteSize(AddressByteSize) {
   Buffer = std::make_unique<AddressSectionBuffer>();
   AddressStream = std::make_unique<raw_svector_ostream>(*Buffer);
 }
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index d9b7982e1232b..8649cc1b0d28c 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -627,16 +627,17 @@ void DWARFRewriter::updateDebugInfo() {
   uint32_t CUIndex = 0;
   std::mutex AccessMutex;
   // Needs to be invoked in the same order as CUs are processed.
-  auto createRangeLocListAddressWriters = [&](DWARFUnit &CU) -> DebugLocWriter * {
+  auto createRangeLocListAddressWriters =
+      [&](DWARFUnit &CU) -> DebugLocWriter * {
     std::lock_guard<std::mutex> Lock(AccessMutex);
     const uint16_t DwarfVersion = CU.getVersion();
     if (DwarfVersion >= 5) {
-      auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(&BC, CU.getAddressByteSize(), CU.getAddrOffsetSectionBase());
+      auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(
+          &BC, CU.getAddressByteSize(), CU.getAddrOffsetSectionBase());
       DebugAddrWriter *AddressWriter =
           AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)})
               .first->second.get();
-      RangeListsSectionWriter->setAddressWriter(
-          AddressWriter);
+      RangeListsSectionWriter->setAddressWriter(AddressWriter);
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLoclistWriter>(
           CU, DwarfVersion, false, *AddressWriter);
 
@@ -646,12 +647,16 @@ void DWARFRewriter::updateDebugInfo() {
         auto RangeListsSectionWriter =
             std::make_unique<DebugRangeListsSectionWriter>();
         RangeListsSectionWriter->initSection(CU);
-        DebugRangeListsSectionWriter *RangeListSectionWriter = RangeListsWritersByCU.insert({*DWOId, std::move(RangeListsSectionWriter)}).first->second.get();
+        DebugRangeListsSectionWriter *RangeListSectionWriter =
+            RangeListsWritersByCU
+                .insert({*DWOId, std::move(RangeListsSectionWriter)})
+                .first->second.get();
         RangeListSectionWriter->setAddressWriter(AddressWriter);
       }
 
     } else {
-      auto AddrW = std::make_unique<DebugAddrWriter>(&BC, CU.getAddressByteSize());
+      auto AddrW =
+          std::make_unique<DebugAddrWriter>(&BC, CU.getAddressByteSize());
       AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)});
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>();
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
@@ -660,8 +665,8 @@ void DWARFRewriter::updateDebugInfo() {
         auto LegacyRangesSectionWriterByCU =
             std::make_unique<DebugRangesSectionWriter>();
         LegacyRangesSectionWriterByCU->initSection(CU);
-        LegacyRangesWritersByCU.insert({*DWOId,
-            std::move(LegacyRangesSectionWriterByCU)});
+        LegacyRangesWritersByCU.insert(
+            {*DWOId, std::move(LegacyRangesSectionWriterByCU)});
       }
     }
     return LocListWritersByCU[CUIndex++].get();
@@ -1637,8 +1642,7 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
     auto AddressWriterIterator = AddressWritersByCU.find(CU->getOffset());
     assert(AddressWriterIterator != AddressWritersByCU.end() &&
            "AddressWriter does not exist for CU");
-    DebugAddrWriter *AddressWriter =
-        AddressWriterIterator->second.get();
+    DebugAddrWriter *AddressWriter = AddressWriterIterator->second.get();
     const size_t BufferOffset = FinalAddrWriter->getBufferSize();
     std::optional<uint64_t> Offset = AddressWriter->finalize(BufferOffset);
     /// If Offset already exists in UnmodifiedAddressOffsets, then update with
@@ -2185,8 +2189,7 @@ void DWARFRewriter::convertToRangesPatchDebugInfo(
       assert(AddrWriterIterator != AddressWritersByCU.end() &&
              "AddressWriter does not exist for CU");
       DebugAddrWriter *AddrWriter = AddrWriterIterator->second.get();
-      const uint32_t Index =
-          AddrWriter->getIndexFromAddress(0, Unit);
+      const uint32_t Index = AddrWriter->getIndexFromAddress(0, Unit);
       DIEBldr.replaceValue(&Die, LowPCAttrInfo.getAttribute(),
                            LowPCAttrInfo.getForm(), DIEInteger(Index));
     } else {

>From fa40d614f4f7cfed6c7d7eaea0ba63c6e4595cdd Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Wed, 10 Jul 2024 20:42:06 -0700
Subject: [PATCH 09/15] Clean up code updating maps

---
 bolt/lib/Rewrite/DWARFRewriter.cpp | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 8649cc1b0d28c..ccb541c9bb361 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -634,25 +634,21 @@ void DWARFRewriter::updateDebugInfo() {
     if (DwarfVersion >= 5) {
       auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(
           &BC, CU.getAddressByteSize(), CU.getAddrOffsetSectionBase());
-      DebugAddrWriter *AddressWriter =
-          AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)})
-              .first->second.get();
-      RangeListsSectionWriter->setAddressWriter(AddressWriter);
-      LocListWritersByCU[CUIndex] = std::make_unique<DebugLoclistWriter>(
-          CU, DwarfVersion, false, *AddressWriter);
+      RangeListsSectionWriter->setAddressWriter(AddrW.get());
+      LocListWritersByCU[CUIndex] =
+          std::make_unique<DebugLoclistWriter>(CU, DwarfVersion, false, *AddrW);
 
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(RangeListsWritersByCU.count(*DWOId) == 0 &&
                "RangeLists writer for DWO unit already exists.");
-        auto RangeListsSectionWriter =
+        auto RangeListSectionWriter =
             std::make_unique<DebugRangeListsSectionWriter>();
-        RangeListsSectionWriter->initSection(CU);
-        DebugRangeListsSectionWriter *RangeListSectionWriter =
-            RangeListsWritersByCU
-                .insert({*DWOId, std::move(RangeListsSectionWriter)})
-                .first->second.get();
-        RangeListSectionWriter->setAddressWriter(AddressWriter);
+        RangeListSectionWriter->initSection(CU);
+        RangeListSectionWriter->setAddressWriter(AddrW.get());
+        RangeListsWritersByCU.insert(
+            {*DWOId, std::move(RangeListSectionWriter)});
       }
+      AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)});
 
     } else {
       auto AddrW =

>From d975f44d4a800f98126ead6579a15d059195e51a Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Wed, 10 Jul 2024 21:05:16 -0700
Subject: [PATCH 10/15] Remove redundant code

---
 bolt/include/bolt/Core/DebugData.h | 4 ++--
 bolt/lib/Core/DebugData.cpp        | 5 -----
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 481cca05539c2..fba5da77451bb 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -336,7 +336,7 @@ using AddressSectionBuffer = SmallVector<char, 4>;
 class DebugAddrWriter {
 public:
   DebugAddrWriter() = delete;
-  DebugAddrWriter(BinaryContext *BC_);
+  DebugAddrWriter(BinaryContext *BC_) : DebugAddrWriter(BC_, 255){};
   DebugAddrWriter(BinaryContext *BC_, uint8_t AddressByteSize);
   virtual ~DebugAddrWriter(){};
   /// Given an address returns an index in .debug_addr.
@@ -460,7 +460,7 @@ class DebugAddrWriterDwarf5 : public DebugAddrWriter {
   }
 
 private:
-  std::optional<uint64_t> AddrOffsetSectionBase;
+  std::optional<uint64_t> AddrOffsetSectionBase = INT_MAX;
   static constexpr uint32_t HeaderSize = 8;
 };
 
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index 4b19e7d8440ff..b5d5c0a62fd2b 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -388,11 +388,6 @@ void DebugARangesSectionWriter::writeARangesSection(
   }
 }
 
-DebugAddrWriter::DebugAddrWriter(BinaryContext *BC) : BC(BC) {
-  Buffer = std::make_unique<AddressSectionBuffer>();
-  AddressStream = std::make_unique<raw_svector_ostream>(*Buffer);
-}
-
 DebugAddrWriter::DebugAddrWriter(BinaryContext *BC,
                                  const uint8_t AddressByteSize)
     : BC(BC), AddressByteSize(AddressByteSize) {

>From 984033dfcefd444b7824c71bd8336f2f03311b88 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Wed, 10 Jul 2024 21:10:36 -0700
Subject: [PATCH 11/15] Formatting change

---
 bolt/include/bolt/Core/DebugData.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index fba5da77451bb..b857745b0fdbe 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -336,7 +336,7 @@ using AddressSectionBuffer = SmallVector<char, 4>;
 class DebugAddrWriter {
 public:
   DebugAddrWriter() = delete;
-  DebugAddrWriter(BinaryContext *BC_) : DebugAddrWriter(BC_, 255){};
+  DebugAddrWriter(BinaryContext *BC_) : DebugAddrWriter(BC_, 255) {};
   DebugAddrWriter(BinaryContext *BC_, uint8_t AddressByteSize);
   virtual ~DebugAddrWriter(){};
   /// Given an address returns an index in .debug_addr.

>From 3755731025f57266615db4bd0be990e48c43d6de Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Thu, 11 Jul 2024 10:01:57 -0700
Subject: [PATCH 12/15] Update to default initialization

---
 bolt/include/bolt/Core/DebugData.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index b857745b0fdbe..2000f512f3246 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -460,7 +460,7 @@ class DebugAddrWriterDwarf5 : public DebugAddrWriter {
   }
 
 private:
-  std::optional<uint64_t> AddrOffsetSectionBase = INT_MAX;
+  std::optional<uint64_t> AddrOffsetSectionBase = std::nullopt;
   static constexpr uint32_t HeaderSize = 8;
 };
 

>From db8f5804e47e20dbd1e9b391997ff7c5d05ee8a5 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Thu, 11 Jul 2024 16:29:13 -0700
Subject: [PATCH 13/15] Updates and formatting changes

---
 bolt/include/bolt/Core/DebugData.h        | 11 +++---
 bolt/include/bolt/Rewrite/DWARFRewriter.h | 10 +++---
 bolt/lib/Core/DebugData.cpp               |  4 +--
 bolt/lib/Rewrite/DWARFRewriter.cpp        | 41 +++++++++++++----------
 4 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 2000f512f3246..fb9ddc7d17bc2 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -336,7 +336,7 @@ using AddressSectionBuffer = SmallVector<char, 4>;
 class DebugAddrWriter {
 public:
   DebugAddrWriter() = delete;
-  DebugAddrWriter(BinaryContext *BC_) : DebugAddrWriter(BC_, 255) {};
+  DebugAddrWriter(BinaryContext *BC_) : DebugAddrWriter(BC_, UCHAR_MAX){};
   DebugAddrWriter(BinaryContext *BC_, uint8_t AddressByteSize);
   virtual ~DebugAddrWriter(){};
   /// Given an address returns an index in .debug_addr.
@@ -353,10 +353,10 @@ class DebugAddrWriter {
   }
 
   /// Returns buffer size.
-  virtual size_t getBufferSize() { return Buffer->size(); }
+  virtual size_t getBufferSize() const { return Buffer->size(); }
 
   /// Returns True if Buffer is not empty.
-  bool isInitialized() { return !Buffer->empty(); }
+  bool isInitialized() const { return !Buffer->empty(); }
 
   /// Updates address base with the given Offset.
   virtual void updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
@@ -445,6 +445,7 @@ class DebugAddrWriterDwarf5 : public DebugAddrWriter {
   /// Write out entries in to .debug_addr section for CUs.
   virtual std::optional<uint64_t> finalize(const size_t BufferSize) override;
 
+  /// Updates address base with the given Offset.
   virtual void updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
                               const uint64_t Offset) override;
 
@@ -613,7 +614,7 @@ class DebugLoclistWriter : public DebugLocWriter {
   DebugLoclistWriter(DWARFUnit &Unit, uint8_t DV, bool SD,
                      DebugAddrWriter &AddrW)
       : DebugLocWriter(DV, LocWriterKind::DebugLoclistWriter),
-        AddrWriter(&AddrW), CU(Unit), IsSplitDwarf(SD) {
+        AddrWriter(AddrW), CU(Unit), IsSplitDwarf(SD) {
     if (DwarfVersion >= 5) {
       LocBodyBuffer = std::make_unique<DebugBufferVector>();
       LocBodyStream = std::make_unique<raw_svector_ostream>(*LocBodyBuffer);
@@ -653,7 +654,7 @@ class DebugLoclistWriter : public DebugLocWriter {
   /// Writes out locations in to a local buffer and applies debug info patches.
   void finalizeDWARF5(DIEBuilder &DIEBldr, DIE &Die);
 
-  DebugAddrWriter *AddrWriter;
+  DebugAddrWriter &AddrWriter;
   DWARFUnit &CU;
   bool IsSplitDwarf{false};
   // Used for DWARF5 to store location lists before being finalized.
diff --git a/bolt/include/bolt/Rewrite/DWARFRewriter.h b/bolt/include/bolt/Rewrite/DWARFRewriter.h
index ac3b26b08e593..abd18b56113b6 100644
--- a/bolt/include/bolt/Rewrite/DWARFRewriter.h
+++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h
@@ -66,10 +66,6 @@ class DWARFRewriter {
   /// .debug_aranges DWARF section.
   std::unique_ptr<DebugARangesSectionWriter> ARangesSectionWriter;
 
-  /// Stores and serializes information that will be put into the
-  /// .debug_addr DWARF section.
-  std::unique_ptr<DebugAddrWriter> FinalAddrWriter;
-
   /// Stores and serializes information that will be put in to the
   /// .debug_addr DWARF section.
   /// Does not do de-duplication.
@@ -146,13 +142,15 @@ class DWARFRewriter {
   /// Process and write out CUs that are passsed in.
   void finalizeCompileUnits(DIEBuilder &DIEBlder, DIEStreamer &Streamer,
                             CUOffsetMap &CUMap,
-                            const std::list<DWARFUnit *> &CUs);
+                            const std::list<DWARFUnit *> &CUs,
+                            DebugAddrWriter &FinalAddrWriter);
 
   /// Finalize debug sections in the main binary.
   void finalizeDebugSections(DIEBuilder &DIEBlder,
                              DWARF5AcceleratorTable &DebugNamesTable,
                              DIEStreamer &Streamer, raw_svector_ostream &ObjOS,
-                             CUOffsetMap &CUMap);
+                             CUOffsetMap &CUMap,
+                             DebugAddrWriter &FinalAddrWriter);
 
   /// Patches the binary for DWARF address ranges (e.g. in functions and lexical
   /// blocks) to be updated.
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index b5d5c0a62fd2b..002f58c474346 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -711,11 +711,11 @@ void DebugLoclistWriter::addList(DIEBuilder &DIEBldr, DIE &Die,
                                  DIEValue &AttrInfo,
                                  DebugLocationsVector &LocList) {
   if (DwarfVersion < 5)
-    writeLegacyLocList(AttrInfo, LocList, DIEBldr, Die, *AddrWriter, *LocBuffer,
+    writeLegacyLocList(AttrInfo, LocList, DIEBldr, Die, AddrWriter, *LocBuffer,
                        CU, *LocStream);
   else
     writeDWARF5LocList(NumberOfEntries, AttrInfo, LocList, Die, DIEBldr,
-                       *AddrWriter, *LocBodyBuffer, RelativeLocListOffsets, CU,
+                       AddrWriter, *LocBodyBuffer, RelativeLocListOffsets, CU,
                        *LocBodyStream);
 }
 
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index ccb541c9bb361..042c39a574561 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -612,6 +612,10 @@ void DWARFRewriter::updateDebugInfo() {
     errs() << "BOLT-WARNING: --deterministic-debuginfo is being deprecated\n";
   }
 
+  /// Stores and serializes information that will be put into the
+  /// .debug_addr DWARF section.
+  std::unique_ptr<DebugAddrWriter> FinalAddrWriter;
+
   if (BC.isDWARF5Used()) {
     FinalAddrWriter = std::make_unique<DebugAddrWriterDwarf5>(&BC);
     RangeListsSectionWriter = std::make_unique<DebugRangeListsSectionWriter>();
@@ -641,19 +645,18 @@ void DWARFRewriter::updateDebugInfo() {
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(RangeListsWritersByCU.count(*DWOId) == 0 &&
                "RangeLists writer for DWO unit already exists.");
-        auto RangeListSectionWriter =
+        auto DWORangeListsSectionWriter =
             std::make_unique<DebugRangeListsSectionWriter>();
-        RangeListSectionWriter->initSection(CU);
-        RangeListSectionWriter->setAddressWriter(AddrW.get());
-        RangeListsWritersByCU.insert(
-            {*DWOId, std::move(RangeListSectionWriter)});
+        DWORangeListsSectionWriter->initSection(CU);
+        DWORangeListsSectionWriter->setAddressWriter(AddrW.get());
+        RangeListsWritersByCU[*DWOId] = std::move(DWORangeListsSectionWriter);
       }
-      AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)});
+      AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
 
     } else {
       auto AddrW =
           std::make_unique<DebugAddrWriter>(&BC, CU.getAddressByteSize());
-      AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)});
+      AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>();
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(LegacyRangesWritersByCU.count(*DWOId) == 0 &&
@@ -661,8 +664,8 @@ void DWARFRewriter::updateDebugInfo() {
         auto LegacyRangesSectionWriterByCU =
             std::make_unique<DebugRangesSectionWriter>();
         LegacyRangesSectionWriterByCU->initSection(CU);
-        LegacyRangesWritersByCU.insert(
-            {*DWOId, std::move(LegacyRangesSectionWriterByCU)});
+        LegacyRangesWritersByCU[*DWOId] =
+            std::move(LegacyRangesSectionWriterByCU);
       }
     }
     return LocListWritersByCU[CUIndex++].get();
@@ -768,7 +771,7 @@ void DWARFRewriter::updateDebugInfo() {
       for (DWARFUnit *CU : DIEBlder.getProcessedCUs())
         processUnitDIE(CU, &DIEBlder);
       finalizeCompileUnits(DIEBlder, *Streamer, OffsetMap,
-                           DIEBlder.getProcessedCUs());
+                           DIEBlder.getProcessedCUs(), *FinalAddrWriter);
     }
   } else {
     // Update unit debug info in parallel
@@ -783,8 +786,8 @@ void DWARFRewriter::updateDebugInfo() {
   if (opts::WriteDWP)
     finalizeDWP(State);
 
-  finalizeDebugSections(DIEBlder, DebugNamesTable, *Streamer, *ObjOS,
-                        OffsetMap);
+  finalizeDebugSections(DIEBlder, DebugNamesTable, *Streamer, *ObjOS, OffsetMap,
+                        *FinalAddrWriter);
   GDBIndexSection.updateGdbIndexSection(OffsetMap, CUIndex,
                                         *ARangesSectionWriter);
 }
@@ -1522,7 +1525,8 @@ CUOffsetMap DWARFRewriter::finalizeTypeSections(DIEBuilder &DIEBlder,
 
 void DWARFRewriter::finalizeDebugSections(
     DIEBuilder &DIEBlder, DWARF5AcceleratorTable &DebugNamesTable,
-    DIEStreamer &Streamer, raw_svector_ostream &ObjOS, CUOffsetMap &CUMap) {
+    DIEStreamer &Streamer, raw_svector_ostream &ObjOS, CUOffsetMap &CUMap,
+    DebugAddrWriter &FinalAddrWriter) {
   if (StrWriter->isInitialized()) {
     RewriteInstance::addToDebugSectionsToOverwrite(".debug_str");
     std::unique_ptr<DebugStrBufferVector> DebugStrSectionContents =
@@ -1575,9 +1579,9 @@ void DWARFRewriter::finalizeDebugSections(
           LocationListSectionContents->size());
   }
 
-  if (FinalAddrWriter->isInitialized()) {
+  if (FinalAddrWriter.isInitialized()) {
     std::unique_ptr<AddressSectionBuffer> AddressSectionContents =
-        FinalAddrWriter->releaseBuffer();
+        FinalAddrWriter.releaseBuffer();
     BC.registerOrUpdateNoteSection(".debug_addr",
                                    copyByteArray(*AddressSectionContents),
                                    AddressSectionContents->size());
@@ -1633,13 +1637,14 @@ void DWARFRewriter::finalizeDebugSections(
 void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
                                          DIEStreamer &Streamer,
                                          CUOffsetMap &CUMap,
-                                         const std::list<DWARFUnit *> &CUs) {
+                                         const std::list<DWARFUnit *> &CUs,
+                                         DebugAddrWriter &FinalAddrWriter) {
   for (DWARFUnit *CU : CUs) {
     auto AddressWriterIterator = AddressWritersByCU.find(CU->getOffset());
     assert(AddressWriterIterator != AddressWritersByCU.end() &&
            "AddressWriter does not exist for CU");
     DebugAddrWriter *AddressWriter = AddressWriterIterator->second.get();
-    const size_t BufferOffset = FinalAddrWriter->getBufferSize();
+    const size_t BufferOffset = FinalAddrWriter.getBufferSize();
     std::optional<uint64_t> Offset = AddressWriter->finalize(BufferOffset);
     /// If Offset already exists in UnmodifiedAddressOffsets, then update with
     /// Offset, else update with BufferOffset.
@@ -1650,7 +1655,7 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
     if (AddressWriter->isInitialized()) {
       std::unique_ptr<AddressSectionBuffer> AddressSectionContents =
           AddressWriter->releaseBuffer();
-      FinalAddrWriter->appendToAddressBuffer(*AddressSectionContents);
+      FinalAddrWriter.appendToAddressBuffer(*AddressSectionContents);
     }
     if (CU->getVersion() != 4)
       continue;

>From 4907b23671450e94e418dfadf6345fa67a6a3a86 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Thu, 11 Jul 2024 16:34:55 -0700
Subject: [PATCH 14/15] Formatting changes

---
 bolt/include/bolt/Core/DebugData.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index fb9ddc7d17bc2..5935ffaa46af7 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -336,7 +336,7 @@ using AddressSectionBuffer = SmallVector<char, 4>;
 class DebugAddrWriter {
 public:
   DebugAddrWriter() = delete;
-  DebugAddrWriter(BinaryContext *BC_) : DebugAddrWriter(BC_, UCHAR_MAX){};
+  DebugAddrWriter(BinaryContext *BC_) : DebugAddrWriter(BC_, UCHAR_MAX) {};
   DebugAddrWriter(BinaryContext *BC_, uint8_t AddressByteSize);
   virtual ~DebugAddrWriter(){};
   /// Given an address returns an index in .debug_addr.

>From e260fba6c34400a0f00260169c5996a9beacc410 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Fri, 12 Jul 2024 17:12:51 -0700
Subject: [PATCH 15/15] [BOLT][DWARF][NFC] Add support for  multithreading

Summary:

Test Plan:

Reviewers:

Subscribers:

Tasks:

Tags:

Differential Revision: https://phabricator.intern.facebook.com/D59708134
---
 bolt/include/bolt/Core/DebugData.h        |   9 -
 bolt/include/bolt/Rewrite/DWARFRewriter.h |   5 -
 bolt/lib/Core/DebugData.cpp               |   7 -
 bolt/lib/Rewrite/DWARFRewriter.cpp        | 247 ++++++++++++----------
 4 files changed, 136 insertions(+), 132 deletions(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 5935ffaa46af7..ebe684d7e821e 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -24,7 +24,6 @@
 #include <cstdint>
 #include <map>
 #include <memory>
-#include <mutex>
 #include <string>
 #include <unordered_map>
 #include <utility>
@@ -234,8 +233,6 @@ class DebugRangesSectionWriter {
 
   std::unique_ptr<raw_svector_ostream> RangesStream;
 
-  std::mutex WriterMutex;
-
   /// Offset of an empty address ranges list.
   static constexpr uint64_t EmptyRangesOffset{0};
 
@@ -325,8 +322,6 @@ class DebugARangesSectionWriter {
   /// to that compile unit. Each interval is a pair
   /// (first address, interval size).
   CUAddressRangesType CUAddressRanges;
-
-  std::mutex CUAddressRangesMutex;
 };
 
 using IndexAddressPair = std::pair<uint32_t, uint64_t>;
@@ -425,8 +420,6 @@ class DebugAddrWriter {
   /// Address for the DWO CU associated with the address writer.
   AddressForDWOCU Map;
   uint8_t AddressByteSize;
-  /// Mutex used for parallel processing of debug info.
-  std::mutex WriterMutex;
   std::unique_ptr<AddressSectionBuffer> Buffer;
   std::unique_ptr<raw_svector_ostream> AddressStream;
   /// Used to track sections that were not modified so that they can be re-used.
@@ -535,8 +528,6 @@ class DebugStrWriter {
   void initialize();
 
 private:
-  /// Mutex used for parallel processing of debug info.
-  std::mutex WriterMutex;
   /// Creates internal data structures.
   void create();
   std::unique_ptr<DebugStrBufferVector> StrBuffer;
diff --git a/bolt/include/bolt/Rewrite/DWARFRewriter.h b/bolt/include/bolt/Rewrite/DWARFRewriter.h
index abd18b56113b6..d6a71e9b02fbb 100644
--- a/bolt/include/bolt/Rewrite/DWARFRewriter.h
+++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h
@@ -20,7 +20,6 @@
 #include "llvm/Support/ToolOutputFile.h"
 #include <cstdint>
 #include <memory>
-#include <mutex>
 #include <optional>
 #include <unordered_map>
 #include <vector>
@@ -52,8 +51,6 @@ class DWARFRewriter {
 private:
   BinaryContext &BC;
 
-  std::mutex DWARFRewriterMutex;
-
   /// Stores and serializes information that will be put into the
   /// .debug_ranges DWARF section.
   std::unique_ptr<DebugRangesSectionWriter> LegacyRangesSectionWriter;
@@ -93,8 +90,6 @@ class DWARFRewriter {
   std::unordered_map<uint64_t, std::unique_ptr<DebugAddrWriter>>
       AddressWritersByCU;
 
-  std::mutex LocListDebugInfoPatchesMutex;
-
   /// Dwo id specific its RangesBase.
   std::unordered_map<uint64_t, uint64_t> DwoRangesBase;
 
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index 002f58c474346..c8a50f787e7e9 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -167,7 +167,6 @@ uint64_t DebugRangesSectionWriter::addRanges(DebugAddressRangesVector &Ranges) {
 
   // Reading the SectionOffset and updating it should be atomic to guarantee
   // unique and correct offsets in patches.
-  std::lock_guard<std::mutex> Lock(WriterMutex);
   const uint32_t EntryOffset = RangesBuffer->size();
   writeAddressRanges(*RangesStream.get(), Ranges);
 
@@ -175,7 +174,6 @@ uint64_t DebugRangesSectionWriter::addRanges(DebugAddressRangesVector &Ranges) {
 }
 
 uint64_t DebugRangesSectionWriter::getSectionOffset() {
-  std::lock_guard<std::mutex> Lock(WriterMutex);
   return RangesBuffer->size();
 }
 
@@ -276,8 +274,6 @@ static bool emitWithBase(raw_ostream &OS, const DebugVector &Entries,
 
 uint64_t
 DebugRangeListsSectionWriter::addRanges(DebugAddressRangesVector &Ranges) {
-  std::lock_guard<std::mutex> Lock(WriterMutex);
-
   RangeEntries.push_back(CurrentOffset);
   std::sort(
       Ranges.begin(), Ranges.end(),
@@ -338,7 +334,6 @@ void DebugRangeListsSectionWriter::initSection(DWARFUnit &Unit) {
 
 void DebugARangesSectionWriter::addCURanges(uint64_t CUOffset,
                                             DebugAddressRangesVector &&Ranges) {
-  std::lock_guard<std::mutex> Lock(CUAddressRangesMutex);
   CUAddressRanges.emplace(CUOffset, std::move(Ranges));
 }
 
@@ -404,7 +399,6 @@ void DebugAddrWriter::AddressForDWOCU::dump() {
     dbgs() << Twine::utohexstr(Pair.second) << "\t" << Pair.first << "\n";
 }
 uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address, DWARFUnit &CU) {
-  std::lock_guard<std::mutex> Lock(WriterMutex);
   auto Entry = Map.find(Address);
   if (Entry == Map.end()) {
     auto Index = Map.getNextIndex();
@@ -924,7 +918,6 @@ void DebugStrWriter::initialize() {
 }
 
 uint32_t DebugStrWriter::addString(StringRef Str) {
-  std::lock_guard<std::mutex> Lock(WriterMutex);
   if (StrBuffer->empty())
     initialize();
   auto Offset = StrBuffer->size();
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 042c39a574561..b719669edfeae 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -40,6 +40,8 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/LEB128.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Parallel.h"
 #include "llvm/Support/ThreadPool.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
@@ -629,47 +631,47 @@ void DWARFRewriter::updateDebugInfo() {
   }
 
   uint32_t CUIndex = 0;
-  std::mutex AccessMutex;
   // Needs to be invoked in the same order as CUs are processed.
   auto createRangeLocListAddressWriters =
-      [&](DWARFUnit &CU) -> DebugLocWriter * {
-    std::lock_guard<std::mutex> Lock(AccessMutex);
-    const uint16_t DwarfVersion = CU.getVersion();
-    if (DwarfVersion >= 5) {
-      auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(
-          &BC, CU.getAddressByteSize(), CU.getAddrOffsetSectionBase());
-      RangeListsSectionWriter->setAddressWriter(AddrW.get());
-      LocListWritersByCU[CUIndex] =
-          std::make_unique<DebugLoclistWriter>(CU, DwarfVersion, false, *AddrW);
-
-      if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
-        assert(RangeListsWritersByCU.count(*DWOId) == 0 &&
-               "RangeLists writer for DWO unit already exists.");
-        auto DWORangeListsSectionWriter =
-            std::make_unique<DebugRangeListsSectionWriter>();
-        DWORangeListsSectionWriter->initSection(CU);
-        DWORangeListsSectionWriter->setAddressWriter(AddrW.get());
-        RangeListsWritersByCU[*DWOId] = std::move(DWORangeListsSectionWriter);
-      }
-      AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
+      [&](DWARFUnit &CU,
+          llvm::DenseMap<uint64_t, unsigned long> &LocListWritersIndexByCU) {
+        const uint16_t DwarfVersion = CU.getVersion();
+        if (DwarfVersion >= 5) {
+          auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(
+              &BC, CU.getAddressByteSize(), CU.getAddrOffsetSectionBase());
+          RangeListsSectionWriter->setAddressWriter(AddrW.get());
+          LocListWritersByCU[CUIndex] = std::make_unique<DebugLoclistWriter>(
+              CU, DwarfVersion, false, *AddrW);
+
+          if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
+            assert(RangeListsWritersByCU.count(*DWOId) == 0 &&
+                   "RangeLists writer for DWO unit already exists.");
+            auto DWORangeListsSectionWriter =
+                std::make_unique<DebugRangeListsSectionWriter>();
+            DWORangeListsSectionWriter->initSection(CU);
+            DWORangeListsSectionWriter->setAddressWriter(AddrW.get());
+            RangeListsWritersByCU[*DWOId] =
+                std::move(DWORangeListsSectionWriter);
+          }
+          AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
 
-    } else {
-      auto AddrW =
-          std::make_unique<DebugAddrWriter>(&BC, CU.getAddressByteSize());
-      AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
-      LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>();
-      if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
-        assert(LegacyRangesWritersByCU.count(*DWOId) == 0 &&
-               "LegacyRangeLists writer for DWO unit already exists.");
-        auto LegacyRangesSectionWriterByCU =
-            std::make_unique<DebugRangesSectionWriter>();
-        LegacyRangesSectionWriterByCU->initSection(CU);
-        LegacyRangesWritersByCU[*DWOId] =
-            std::move(LegacyRangesSectionWriterByCU);
-      }
-    }
-    return LocListWritersByCU[CUIndex++].get();
-  };
+        } else {
+          auto AddrW =
+              std::make_unique<DebugAddrWriter>(&BC, CU.getAddressByteSize());
+          AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
+          LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>();
+          if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
+            assert(LegacyRangesWritersByCU.count(*DWOId) == 0 &&
+                   "LegacyRangeLists writer for DWO unit already exists.");
+            auto LegacyRangesSectionWriterByCU =
+                std::make_unique<DebugRangesSectionWriter>();
+            LegacyRangesSectionWriterByCU->initSection(CU);
+            LegacyRangesWritersByCU[*DWOId] =
+                std::move(LegacyRangesSectionWriterByCU);
+          }
+        }
+        LocListWritersIndexByCU[CU.getOffset()] = CUIndex++;
+      };
 
   DWARF5AcceleratorTable DebugNamesTable(opts::CreateDebugNames, BC,
                                          *StrWriter);
@@ -677,75 +679,77 @@ void DWARFRewriter::updateDebugInfo() {
   DWPState State;
   if (opts::WriteDWP)
     initDWPState(State);
-  auto processUnitDIE = [&](DWARFUnit *Unit, DIEBuilder *DIEBlder) {
-    // Check if the unit is a skeleton and we need special updates for it and
-    // its matching split/DWO CU.
+
+  auto processSplitCU = [&](DWARFUnit *Unit, DIEBuilder *DIEBlder,
+                            std::optional<uint64_t> &RangesBase) {
     std::optional<DWARFUnit *> SplitCU;
-    std::optional<uint64_t> RangesBase;
     std::optional<uint64_t> DWOId = Unit->getDWOId();
     if (DWOId)
       SplitCU = BC.getDWOCU(*DWOId);
-    DebugLocWriter *DebugLocWriter = createRangeLocListAddressWriters(*Unit);
-    DebugRangesSectionWriter *RangesSectionWriter =
-        Unit->getVersion() >= 5 ? RangeListsSectionWriter.get()
-                                : LegacyRangesSectionWriter.get();
-    DebugAddrWriter *AddressWriter =
-        AddressWritersByCU[Unit->getOffset()].get();
-    // Skipping CUs that failed to load.
-    if (SplitCU) {
-      DIEBuilder DWODIEBuilder(BC, &(*SplitCU)->getContext(), DebugNamesTable,
-                               Unit);
-      DWODIEBuilder.buildDWOUnit(**SplitCU);
-      std::string DWOName = "";
-      std::optional<std::string> DwarfOutputPath =
-          opts::DwarfOutputPath.empty()
-              ? std::nullopt
-              : std::optional<std::string>(opts::DwarfOutputPath.c_str());
-      {
-        std::lock_guard<std::mutex> Lock(AccessMutex);
-        DWOName = DIEBlder->updateDWONameCompDir(
-            *StrOffstsWriter, *StrWriter, *Unit, DwarfOutputPath, std::nullopt);
-      }
-      DebugStrOffsetsWriter DWOStrOffstsWriter(BC);
-      DebugStrWriter DWOStrWriter((*SplitCU)->getContext(), true);
-      DWODIEBuilder.updateDWONameCompDirForTypes(DWOStrOffstsWriter,
-                                                 DWOStrWriter, **SplitCU,
-                                                 DwarfOutputPath, DWOName);
-      DebugLoclistWriter DebugLocDWoWriter(*Unit, Unit->getVersion(), true,
-                                           *AddressWriter);
-      DebugRangesSectionWriter *TempRangesSectionWriter = RangesSectionWriter;
-      if (Unit->getVersion() >= 5) {
-        TempRangesSectionWriter = RangeListsWritersByCU[*DWOId].get();
-      } else {
-        TempRangesSectionWriter = LegacyRangesWritersByCU[*DWOId].get();
-        RangesBase = RangesSectionWriter->getSectionOffset();
-        setDwoRangesBase(*DWOId, *RangesBase);
-      }
-
-      updateUnitDebugInfo(*(*SplitCU), DWODIEBuilder, DebugLocDWoWriter,
-                          *TempRangesSectionWriter, *AddressWriter);
-      DebugLocDWoWriter.finalize(DWODIEBuilder,
-                                 *DWODIEBuilder.getUnitDIEbyUnit(**SplitCU));
-      if (Unit->getVersion() >= 5)
-        TempRangesSectionWriter->finalizeSection();
-
-      emitDWOBuilder(DWOName, DWODIEBuilder, *this, **SplitCU, *Unit, State,
-                     DebugLocDWoWriter, DWOStrOffstsWriter, DWOStrWriter,
-                     GDBIndexSection);
+    if (!SplitCU)
+      return;
+    DebugAddrWriter &AddressWriter =
+        *AddressWritersByCU[Unit->getOffset()].get();
+    DIEBuilder DWODIEBuilder(BC, &(*SplitCU)->getContext(), DebugNamesTable,
+                             Unit);
+    DWODIEBuilder.buildDWOUnit(**SplitCU);
+    std::string DWOName = "";
+    std::optional<std::string> DwarfOutputPath =
+        opts::DwarfOutputPath.empty()
+            ? std::nullopt
+            : std::optional<std::string>(opts::DwarfOutputPath.c_str());
+    {
+      DWOName = DIEBlder->updateDWONameCompDir(
+          *StrOffstsWriter, *StrWriter, *Unit, DwarfOutputPath, std::nullopt);
     }
+    DebugStrOffsetsWriter DWOStrOffstsWriter(BC);
+    DebugStrWriter DWOStrWriter((*SplitCU)->getContext(), true);
+    DWODIEBuilder.updateDWONameCompDirForTypes(
+        DWOStrOffstsWriter, DWOStrWriter, **SplitCU, DwarfOutputPath, DWOName);
+    DebugLoclistWriter DebugLocDWoWriter(*Unit, Unit->getVersion(), true,
+                                         AddressWriter);
+    DebugRangesSectionWriter *TempRangesSectionWriter;
+    if (Unit->getVersion() >= 5) {
+      TempRangesSectionWriter = RangeListsWritersByCU[*DWOId].get();
+    } else {
+      TempRangesSectionWriter = LegacyRangesWritersByCU[*DWOId].get();
+      RangesBase = Unit->getVersion() >= 5
+                       ? RangeListsSectionWriter.get()->getSectionOffset()
+                       : LegacyRangesSectionWriter.get()->getSectionOffset();
+      setDwoRangesBase(*DWOId, *RangesBase);
+    }
+
+    updateUnitDebugInfo(*(*SplitCU), DWODIEBuilder, DebugLocDWoWriter,
+                        *TempRangesSectionWriter, AddressWriter);
+    DebugLocDWoWriter.finalize(DWODIEBuilder,
+                               *DWODIEBuilder.getUnitDIEbyUnit(**SplitCU));
+    if (Unit->getVersion() >= 5)
+      TempRangesSectionWriter->finalizeSection();
 
+    emitDWOBuilder(DWOName, DWODIEBuilder, *this, **SplitCU, *Unit, State,
+                   DebugLocDWoWriter, DWOStrOffstsWriter, DWOStrWriter,
+                   GDBIndexSection);
+  };
+  auto processMainBinaryCU = [&](DWARFUnit *Unit, DIEBuilder *DIEBlder,
+                                 DebugLocWriter *DebugLocWriter,
+                                 std::optional<uint64_t> &RangesBase) {
+    DebugAddrWriter &AddressWriter =
+        *AddressWritersByCU[Unit->getOffset()].get();
+    DebugRangesSectionWriter &RangesSectionWriter =
+        Unit->getVersion() >= 5 ? *RangeListsSectionWriter.get()
+                                : *LegacyRangesSectionWriter.get();
     if (Unit->getVersion() >= 5) {
-      RangesBase = RangesSectionWriter->getSectionOffset() +
+      RangesBase = RangesSectionWriter.getSectionOffset() +
                    getDWARF5RngListLocListHeaderSize();
-      RangesSectionWriter->initSection(*Unit);
+      RangesSectionWriter.initSection(*Unit);
       StrOffstsWriter->finalizeSection(*Unit, *DIEBlder);
     }
 
-    updateUnitDebugInfo(*Unit, *DIEBlder, *DebugLocWriter, *RangesSectionWriter,
-                        *AddressWriter, RangesBase);
+    updateUnitDebugInfo(*Unit, *DIEBlder, *DebugLocWriter, RangesSectionWriter,
+                        AddressWriter, RangesBase);
     DebugLocWriter->finalize(*DIEBlder, *DIEBlder->getUnitDIEbyUnit(*Unit));
     if (Unit->getVersion() >= 5)
-      RangesSectionWriter->finalizeSection();
+      RangesSectionWriter.finalizeSection();
   };
 
   DIEBuilder DIEBlder(BC, BC.DwCtx.get(), DebugNamesTable);
@@ -762,23 +766,45 @@ void DWARFRewriter::updateDebugInfo() {
 
   const bool SingleThreadedMode =
       opts::NoThreads || opts::DeterministicDebugInfo;
-  if (!SingleThreadedMode)
-    DIEBlder.buildCompileUnits();
-  if (SingleThreadedMode) {
-    CUPartitionVector PartVec = partitionCUs(*BC.DwCtx);
-    for (std::vector<DWARFUnit *> &Vec : PartVec) {
-      DIEBlder.buildCompileUnits(Vec);
-      for (DWARFUnit *CU : DIEBlder.getProcessedCUs())
-        processUnitDIE(CU, &DIEBlder);
-      finalizeCompileUnits(DIEBlder, *Streamer, OffsetMap,
-                           DIEBlder.getProcessedCUs(), *FinalAddrWriter);
+  CUPartitionVector PartVec = partitionCUs(*BC.DwCtx);
+  for (std::vector<DWARFUnit *> &Vec : PartVec) {
+    DIEBlder.buildCompileUnits(Vec);
+    llvm::SmallVector<DWARFUnit *> CompileUnits(
+        std::begin(DIEBlder.getProcessedCUs()),
+        std::end(DIEBlder.getProcessedCUs()));
+    llvm::DenseMap<uint64_t, uint64_t> RangesBaseByCU;
+    llvm::DenseMap<uint64_t, uint64_t> LocListWritersIndexByCU;
+    if (SingleThreadedMode) {
+      for (DWARFUnit *CU : CompileUnits) {
+        createRangeLocListAddressWriters(*CU, LocListWritersIndexByCU);
+        std::optional<uint64_t> RangesBase;
+        processSplitCU(CU, &DIEBlder, RangesBase);
+        if (RangesBase)
+          RangesBaseByCU[CU->getOffset()] = *RangesBase;
+      }
+    } else {
+      ThreadPoolInterface &ThreadPool = ParallelUtilities::getThreadPool();
+      for (DWARFUnit *CU : CompileUnits) {
+        createRangeLocListAddressWriters(*CU, LocListWritersIndexByCU);
+        ThreadPool.async([&, CU] {
+          std::optional<uint64_t> RangesBase;
+          processSplitCU(CU, &DIEBlder, RangesBase);
+          if (RangesBase)
+            RangesBaseByCU[CU->getOffset()] = *RangesBase;
+        });
+      }
+      ThreadPool.wait();
     }
-  } else {
-    // Update unit debug info in parallel
-    ThreadPoolInterface &ThreadPool = ParallelUtilities::getThreadPool();
-    for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units())
-      ThreadPool.async(processUnitDIE, CU.get(), &DIEBlder);
-    ThreadPool.wait();
+    for (DWARFUnit *CU : CompileUnits) {
+      std::optional<uint64_t> RangesBase;
+      if (RangesBaseByCU.count(CU->getOffset()))
+        RangesBase = RangesBaseByCU[CU->getOffset()];
+      DebugLocWriter *DebugLocWriter =
+          LocListWritersByCU[LocListWritersIndexByCU[CU->getOffset()]].get();
+      processMainBinaryCU(CU, &DIEBlder, DebugLocWriter, RangesBase);
+    }
+    finalizeCompileUnits(DIEBlder, *Streamer, OffsetMap,
+                         DIEBlder.getProcessedCUs(), *FinalAddrWriter);
   }
 
   DebugNamesTable.emitAccelTable();
@@ -1259,7 +1285,6 @@ void DWARFRewriter::updateUnitDebugInfo(
           dwarf::Form Form = LowPCAttrInfo.getForm();
           assert(Form != dwarf::DW_FORM_LLVM_addrx_offset &&
                  "DW_FORM_LLVM_addrx_offset is not supported");
-          std::lock_guard<std::mutex> Lock(DWARFRewriterMutex);
           if (Form == dwarf::DW_FORM_addrx ||
               Form == dwarf::DW_FORM_GNU_addr_index) {
             const uint32_t Index = AddressWriter.getIndexFromAddress(



More information about the llvm-commits mailing list