[llvm] 8aaa15e - [ObjectYAML][NFC] Hoist BBAddrMap yaml2obj encoder into a shared helper (#205991)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 16 19:55:57 PDT 2026


Author: Haohai Wen
Date: 2026-07-17T10:55:52+08:00
New Revision: 8aaa15e82688177db7c0c3fa06103d10f6799598

URL: https://github.com/llvm/llvm-project/commit/8aaa15e82688177db7c0c3fa06103d10f6799598
DIFF: https://github.com/llvm/llvm-project/commit/8aaa15e82688177db7c0c3fa06103d10f6799598.diff

LOG: [ObjectYAML][NFC] Hoist BBAddrMap yaml2obj encoder into a shared helper (#205991)

Preparatory NFC refactor to let the upcoming COFF emitter reuse the
BBAddrMap YAML encoder.

Added: 
    

Modified: 
    llvm/include/llvm/ObjectYAML/BBAddrMapYAML.h
    llvm/lib/ObjectYAML/BBAddrMapYAML.cpp
    llvm/lib/ObjectYAML/ELFEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ObjectYAML/BBAddrMapYAML.h b/llvm/include/llvm/ObjectYAML/BBAddrMapYAML.h
index dd672b6b82510..78cb99e2df30e 100644
--- a/llvm/include/llvm/ObjectYAML/BBAddrMapYAML.h
+++ b/llvm/include/llvm/ObjectYAML/BBAddrMapYAML.h
@@ -17,11 +17,13 @@
 #define LLVM_OBJECTYAML_BBADDRMAPYAML_H
 
 #include "llvm/Support/YAMLTraits.h"
-#include <cstdint>
-#include <optional>
-#include <vector>
 
 namespace llvm {
+
+namespace yaml {
+class ContiguousBlobAccumulator;
+}
+
 namespace BBAddrMapYAML {
 
 struct BBAddrMapEntry {
@@ -81,6 +83,13 @@ struct PGOAnalysisMapEntry {
   std::optional<std::vector<PGOBBEntry>> PGOBBEntries;
 };
 
+/// Encodes the BBAddrMap payload into \p CBA. \p AddressSize must be 4 or 8.
+/// If non-null, \p PGOAnalyses must have the same length as \p Entries.
+LLVM_ABI void encodePayload(ArrayRef<BBAddrMapEntry> Entries,
+                            const std::vector<PGOAnalysisMapEntry> *PGOAnalyses,
+                            yaml::ContiguousBlobAccumulator &CBA,
+                            llvm::endianness Endian, unsigned AddressSize);
+
 } // end namespace BBAddrMapYAML
 } // end namespace llvm
 

diff  --git a/llvm/lib/ObjectYAML/BBAddrMapYAML.cpp b/llvm/lib/ObjectYAML/BBAddrMapYAML.cpp
index fbeda0d7f4ef5..f3dbefbcc6191 100644
--- a/llvm/lib/ObjectYAML/BBAddrMapYAML.cpp
+++ b/llvm/lib/ObjectYAML/BBAddrMapYAML.cpp
@@ -13,6 +13,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ObjectYAML/BBAddrMapYAML.h"
+#include "llvm/Object/BBAddrMap.h"
+#include "llvm/ObjectYAML/ContiguousBlobAccumulator.h"
+#include "llvm/Support/WithColor.h"
 
 namespace llvm {
 namespace yaml {
@@ -70,4 +73,125 @@ void MappingTraits<
 }
 
 } // end namespace yaml
+
+namespace BBAddrMapYAML {
+
+void encodePayload(ArrayRef<BBAddrMapEntry> Entries,
+                   const std::vector<PGOAnalysisMapEntry> *PGOAnalyses,
+                   yaml::ContiguousBlobAccumulator &CBA,
+                   llvm::endianness Endian, unsigned AddressSize) {
+  assert((AddressSize == 4 || AddressSize == 8) && "invalid address size");
+  for (const auto &[Idx, E] : llvm::enumerate(Entries)) {
+    // Write version and feature values.
+    if (E.Version > 5)
+      WithColor::warning() << "unsupported BB address map version: "
+                           << static_cast<int>(E.Version)
+                           << "; encoding using the most recent version";
+    CBA.write(E.Version);
+    if (E.Version < 5)
+      CBA.write(static_cast<uint8_t>(E.Feature));
+    else
+      CBA.write<uint16_t>(E.Feature, Endian);
+    auto FeatureOrErr = llvm::object::BBAddrMap::Features::decode(E.Feature);
+    if (!FeatureOrErr) {
+      // Invalid feature: warn and skip the entry.
+      WithColor::warning() << toString(FeatureOrErr.takeError());
+      continue;
+    }
+    bool MultiBBRangeFeatureEnabled = FeatureOrErr->MultiBBRange;
+    bool MultiBBRange =
+        MultiBBRangeFeatureEnabled ||
+        (E.NumBBRanges.has_value() && E.NumBBRanges.value() != 1) ||
+        (E.BBRanges && E.BBRanges->size() != 1);
+    if (MultiBBRange && !MultiBBRangeFeatureEnabled)
+      WithColor::warning() << "feature value(" << E.Feature
+                           << ") does not support multiple BB ranges.";
+    if (MultiBBRange) {
+      // Write the number of basic block ranges, which is overridden by the
+      // 'NumBBRanges' field when specified.
+      uint64_t NumBBRanges =
+          E.NumBBRanges.value_or(E.BBRanges ? E.BBRanges->size() : 0);
+      CBA.writeULEB128(NumBBRanges);
+    }
+    if (!E.BBRanges)
+      continue;
+    uint64_t TotalNumBlocks = 0;
+    bool EmitCallsiteEndOffsets =
+        FeatureOrErr->CallsiteEndOffsets || E.hasAnyCallsiteEndOffsets();
+    for (const BBAddrMapEntry::BBRangeEntry &BBR : *E.BBRanges) {
+      // Write the pointer-sized base address of the range.
+      if (AddressSize == 8)
+        CBA.write<uint64_t>(BBR.BaseAddress, Endian);
+      else
+        CBA.write<uint32_t>(static_cast<uint32_t>(BBR.BaseAddress), Endian);
+      // Write number of BBEntries (number of basic blocks in this basic block
+      // range). This is overridden by the 'NumBlocks' YAML field when
+      // specified.
+      uint64_t NumBlocks =
+          BBR.NumBlocks.value_or(BBR.BBEntries ? BBR.BBEntries->size() : 0);
+      CBA.writeULEB128(NumBlocks);
+      // Write all BBEntries in this BBRange.
+      if (!BBR.BBEntries || FeatureOrErr->OmitBBEntries)
+        continue;
+      for (const BBAddrMapEntry::BBEntry &BBE : *BBR.BBEntries) {
+        ++TotalNumBlocks;
+        if (E.Version > 1)
+          CBA.writeULEB128(BBE.ID);
+        CBA.writeULEB128(BBE.AddressOffset);
+        if (EmitCallsiteEndOffsets) {
+          size_t NumCallsiteEndOffsets =
+              BBE.CallsiteEndOffsets ? BBE.CallsiteEndOffsets->size() : 0;
+          CBA.writeULEB128(NumCallsiteEndOffsets);
+          if (BBE.CallsiteEndOffsets) {
+            for (uint32_t Offset : *BBE.CallsiteEndOffsets)
+              CBA.writeULEB128(Offset);
+          }
+        }
+        CBA.writeULEB128(BBE.Size);
+        CBA.writeULEB128(BBE.Metadata);
+        if (FeatureOrErr->BBHash || BBE.Hash.has_value()) {
+          uint64_t Hash =
+              BBE.Hash.has_value() ? BBE.Hash.value() : llvm::yaml::Hex64(0);
+          CBA.write<uint64_t>(Hash, Endian);
+        }
+      }
+    }
+    if (!PGOAnalyses)
+      continue;
+    const PGOAnalysisMapEntry &PGOEntry = PGOAnalyses->at(Idx);
+
+    if (PGOEntry.FuncEntryCount)
+      CBA.writeULEB128(*PGOEntry.FuncEntryCount);
+
+    if (!PGOEntry.PGOBBEntries)
+      continue;
+
+    const auto &PGOBBEntries = PGOEntry.PGOBBEntries.value();
+    if (TotalNumBlocks != PGOBBEntries.size()) {
+      WithColor::warning() << "PGOBBEntries must be the same length as "
+                              "BBEntries in the BB address map.\n"
+                           << "Mismatch on function with address: "
+                           << E.getFunctionAddress();
+      continue;
+    }
+
+    for (const auto &PGOBBE : PGOBBEntries) {
+      if (PGOBBE.BBFreq)
+        CBA.writeULEB128(*PGOBBE.BBFreq);
+      if (FeatureOrErr->PostLinkCfg || PGOBBE.PostLinkBBFreq.has_value())
+        CBA.writeULEB128(PGOBBE.PostLinkBBFreq.value_or(0));
+      if (PGOBBE.Successors) {
+        CBA.writeULEB128(PGOBBE.Successors->size());
+        for (const auto &[ID, BrProb, PostLinkBrFreq] : *PGOBBE.Successors) {
+          CBA.writeULEB128(ID);
+          CBA.writeULEB128(BrProb);
+          if (FeatureOrErr->PostLinkCfg || PostLinkBrFreq.has_value())
+            CBA.writeULEB128(PostLinkBrFreq.value_or(0));
+        }
+      }
+    }
+  }
+}
+
+} // end namespace BBAddrMapYAML
 } // end namespace llvm

diff  --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 1b40a54088313..8bbecc82b6a18 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -23,10 +23,7 @@
 #include "llvm/ObjectYAML/DWARFYAML.h"
 #include "llvm/ObjectYAML/ELFYAML.h"
 #include "llvm/ObjectYAML/yaml2obj.h"
-#include "llvm/Support/EndianStream.h"
-#include "llvm/Support/Errc.h"
 #include "llvm/Support/Error.h"
-#include "llvm/Support/LEB128.h"
 #include "llvm/Support/WithColor.h"
 #include "llvm/Support/YAMLTraits.h"
 #include "llvm/Support/raw_ostream.h"
@@ -1362,113 +1359,8 @@ void ELFState<ELFT>::writeSectionContent(
   }
 
   uint64_t CurrentOffset = CBA.getOffset();
-  for (const auto &[Idx, E] : llvm::enumerate(*Section.Entries)) {
-    // Write version and feature values.
-    if (E.Version > 5)
-      WithColor::warning() << "unsupported BB address map version: "
-                           << static_cast<int>(E.Version)
-                           << "; encoding using the most recent version";
-    CBA.write(E.Version);
-    if (E.Version < 5)
-      CBA.write(static_cast<uint8_t>(E.Feature));
-    else
-      CBA.write<uint16_t>(E.Feature, ELFT::Endianness);
-    auto FeatureOrErr = llvm::object::BBAddrMap::Features::decode(E.Feature);
-    if (!FeatureOrErr) {
-      // Invalid feature: warn and skip the entry.
-      WithColor::warning() << toString(FeatureOrErr.takeError());
-      continue;
-    }
-    bool MultiBBRangeFeatureEnabled = FeatureOrErr->MultiBBRange;
-    bool MultiBBRange =
-        MultiBBRangeFeatureEnabled ||
-        (E.NumBBRanges.has_value() && E.NumBBRanges.value() != 1) ||
-        (E.BBRanges && E.BBRanges->size() != 1);
-    if (MultiBBRange && !MultiBBRangeFeatureEnabled)
-      WithColor::warning() << "feature value(" << E.Feature
-                           << ") does not support multiple BB ranges.";
-    if (MultiBBRange) {
-      // Write the number of basic block ranges, which is overridden by the
-      // 'NumBBRanges' field when specified.
-      uint64_t NumBBRanges =
-          E.NumBBRanges.value_or(E.BBRanges ? E.BBRanges->size() : 0);
-      CBA.writeULEB128(NumBBRanges);
-    }
-    if (!E.BBRanges)
-      continue;
-    uint64_t TotalNumBlocks = 0;
-    bool EmitCallsiteEndOffsets =
-        FeatureOrErr->CallsiteEndOffsets || E.hasAnyCallsiteEndOffsets();
-    for (const BBAddrMapYAML::BBAddrMapEntry::BBRangeEntry &BBR : *E.BBRanges) {
-      // Write the base address of the range.
-      CBA.write<uintX_t>(BBR.BaseAddress, ELFT::Endianness);
-      // Write number of BBEntries (number of basic blocks in this basic block
-      // range). This is overridden by the 'NumBlocks' YAML field when
-      // specified.
-      uint64_t NumBlocks =
-          BBR.NumBlocks.value_or(BBR.BBEntries ? BBR.BBEntries->size() : 0);
-      CBA.writeULEB128(NumBlocks);
-      // Write all BBEntries in this BBRange.
-      if (!BBR.BBEntries || FeatureOrErr->OmitBBEntries)
-        continue;
-      for (const BBAddrMapYAML::BBAddrMapEntry::BBEntry &BBE : *BBR.BBEntries) {
-        ++TotalNumBlocks;
-        if (E.Version > 1)
-          CBA.writeULEB128(BBE.ID);
-        CBA.writeULEB128(BBE.AddressOffset);
-        if (EmitCallsiteEndOffsets) {
-          size_t NumCallsiteEndOffsets =
-              BBE.CallsiteEndOffsets ? BBE.CallsiteEndOffsets->size() : 0;
-          CBA.writeULEB128(NumCallsiteEndOffsets);
-          if (BBE.CallsiteEndOffsets) {
-            for (uint32_t Offset : *BBE.CallsiteEndOffsets)
-              CBA.writeULEB128(Offset);
-          }
-        }
-        CBA.writeULEB128(BBE.Size);
-        CBA.writeULEB128(BBE.Metadata);
-        if (FeatureOrErr->BBHash || BBE.Hash.has_value()) {
-          uint64_t Hash =
-              BBE.Hash.has_value() ? BBE.Hash.value() : llvm::yaml::Hex64(0);
-          CBA.write<uint64_t>(Hash, ELFT::Endianness);
-        }
-      }
-    }
-    if (!PGOAnalyses)
-      continue;
-    const BBAddrMapYAML::PGOAnalysisMapEntry &PGOEntry = PGOAnalyses->at(Idx);
-
-    if (PGOEntry.FuncEntryCount)
-      CBA.writeULEB128(*PGOEntry.FuncEntryCount);
-
-    if (!PGOEntry.PGOBBEntries)
-      continue;
-
-    const auto &PGOBBEntries = PGOEntry.PGOBBEntries.value();
-    if (TotalNumBlocks != PGOBBEntries.size()) {
-      WithColor::warning() << "PGOBBEntries must be the same length as "
-                              "BBEntries in the BB address map.\n"
-                           << "Mismatch on function with address: "
-                           << E.getFunctionAddress();
-      continue;
-    }
-
-    for (const auto &PGOBBE : PGOBBEntries) {
-      if (PGOBBE.BBFreq)
-        CBA.writeULEB128(*PGOBBE.BBFreq);
-      if (FeatureOrErr->PostLinkCfg || PGOBBE.PostLinkBBFreq.has_value())
-        CBA.writeULEB128(PGOBBE.PostLinkBBFreq.value_or(0));
-      if (PGOBBE.Successors) {
-        CBA.writeULEB128(PGOBBE.Successors->size());
-        for (const auto &[ID, BrProb, PostLinkBrFreq] : *PGOBBE.Successors) {
-          CBA.writeULEB128(ID);
-          CBA.writeULEB128(BrProb);
-          if (FeatureOrErr->PostLinkCfg || PostLinkBrFreq.has_value())
-            CBA.writeULEB128(PostLinkBrFreq.value_or(0));
-        }
-      }
-    }
-  }
+  BBAddrMapYAML::encodePayload(*Section.Entries, PGOAnalyses, CBA,
+                               ELFT::Endianness, sizeof(uintX_t));
   SHeader.sh_size += CBA.getOffset() - CurrentOffset;
 }
 


        


More information about the llvm-commits mailing list