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

Haohai Wen via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 16 18:07:19 PDT 2026


https://github.com/HaohaiWen updated https://github.com/llvm/llvm-project/pull/205991

>From 11e2b2d3c70513d7340548eab5283e5bd4351c7b Mon Sep 17 00:00:00 2001
From: Haohai Wen <haohai.wen at intel.com>
Date: Fri, 26 Jun 2026 13:40:22 +0800
Subject: [PATCH 1/3] [ObjectYAML][NFC] Add BBAddrMap Writer interface for
 yaml2obj

Add BBAddrMapYAML::Writer, a CRTP interface abstracting the write
primitives for BBAddrMap payload, so the encode logic can be shared
by the ELF and upcoming COFF yaml2obj emitters.
---
 .../llvm/ObjectYAML/BBAddrMapYAMLEmitter.h    | 58 +++++++++++++++++++
 llvm/lib/ObjectYAML/ELFEmitter.cpp            | 57 +++++++++++-------
 2 files changed, 95 insertions(+), 20 deletions(-)
 create mode 100644 llvm/include/llvm/ObjectYAML/BBAddrMapYAMLEmitter.h

diff --git a/llvm/include/llvm/ObjectYAML/BBAddrMapYAMLEmitter.h b/llvm/include/llvm/ObjectYAML/BBAddrMapYAMLEmitter.h
new file mode 100644
index 0000000000000..c9cc4c848e3e2
--- /dev/null
+++ b/llvm/include/llvm/ObjectYAML/BBAddrMapYAMLEmitter.h
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Shared yaml2obj BBAddrMap writer, in a standalone header so type-only
+/// includers don't pull in its dependencies.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECTYAML_BBADDRMAPYAMLEMITTER_H
+#define LLVM_OBJECTYAML_BBADDRMAPYAMLEMITTER_H
+
+#include "llvm/ADT/bit.h"
+#include "llvm/ObjectYAML/BBAddrMapYAML.h"
+#include <cassert>
+#include <cstdint>
+
+namespace llvm {
+namespace BBAddrMapYAML {
+
+/// CRTP interface for emitting the BBAddrMap payload to a target-specific
+/// writer, so the encode logic can be shared across formats.
+template <typename Derived> class Writer {
+  llvm::endianness Endian;
+  unsigned AddressSize;
+
+  Derived &derived() { return static_cast<Derived &>(*this); }
+
+public:
+  Writer(llvm::endianness Endian, unsigned AddressSize)
+      : Endian(Endian), AddressSize(AddressSize) {
+    assert((AddressSize == 4 || AddressSize == 8) && "invalid address size");
+  }
+
+  template <typename T> void writeInt(T Val) {
+    derived().template emitInt<T>(Val, Endian);
+  }
+
+  // Pointer-sized: 4 or 8 bytes per AddressSize.
+  void writeAddress(uint64_t Val) {
+    if (AddressSize == 8)
+      writeInt<uint64_t>(Val);
+    else
+      writeInt<uint32_t>(static_cast<uint32_t>(Val));
+  }
+
+  void writeULEB128(uint64_t Val) { derived().emitULEB128(Val); }
+};
+
+} // end namespace BBAddrMapYAML
+} // end namespace llvm
+
+#endif // LLVM_OBJECTYAML_BBADDRMAPYAMLEMITTER_H
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 6dc162356ab40..2e60132995fa1 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -18,6 +18,7 @@
 #include "llvm/BinaryFormat/ELF.h"
 #include "llvm/MC/StringTableBuilder.h"
 #include "llvm/Object/ELFTypes.h"
+#include "llvm/ObjectYAML/BBAddrMapYAMLEmitter.h"
 #include "llvm/ObjectYAML/DWARFEmitter.h"
 #include "llvm/ObjectYAML/DWARFYAML.h"
 #include "llvm/ObjectYAML/ELFYAML.h"
@@ -137,6 +138,21 @@ class ContiguousBlobAccumulator {
   }
 };
 
+// BBAddrMap writer backed by CBA, keeping its size-limit checks.
+class ELFWriter : public BBAddrMapYAML::Writer<ELFWriter> {
+  ContiguousBlobAccumulator &CBA;
+
+public:
+  ELFWriter(ContiguousBlobAccumulator &CBA, llvm::endianness Endian,
+            unsigned AddressSize)
+      : Writer(Endian, AddressSize), CBA(CBA) {}
+
+  template <typename T> void emitInt(T Val, llvm::endianness Endian) {
+    CBA.write<T>(Val, Endian);
+  }
+  void emitULEB128(uint64_t Val) { CBA.writeULEB128(Val); }
+};
+
 // Used to keep track of section and symbol names, so that in the YAML file
 // sections and symbols can be referenced by name instead of by index.
 class NameToIdxMap {
@@ -1462,6 +1478,7 @@ void ELFState<ELFT>::writeSectionContent(
       PGOAnalyses = &Section.PGOAnalyses.value();
   }
 
+  ELFWriter W(CBA, ELFT::Endianness, sizeof(uintX_t));
   uint64_t CurrentOffset = CBA.getOffset();
   for (const auto &[Idx, E] : llvm::enumerate(*Section.Entries)) {
     // Write version and feature values.
@@ -1469,11 +1486,11 @@ void ELFState<ELFT>::writeSectionContent(
       WithColor::warning() << "unsupported BB address map version: "
                            << static_cast<int>(E.Version)
                            << "; encoding using the most recent version";
-    CBA.write(E.Version);
+    W.writeInt<uint8_t>(E.Version);
     if (E.Version < 5)
-      CBA.write(static_cast<uint8_t>(E.Feature));
+      W.writeInt<uint8_t>(static_cast<uint8_t>(E.Feature));
     else
-      CBA.write<uint16_t>(E.Feature, ELFT::Endianness);
+      W.writeInt<uint16_t>(E.Feature);
     auto FeatureOrErr = llvm::object::BBAddrMap::Features::decode(E.Feature);
     if (!FeatureOrErr) {
       // Invalid feature: warn and skip the entry.
@@ -1493,7 +1510,7 @@ void ELFState<ELFT>::writeSectionContent(
       // 'NumBBRanges' field when specified.
       uint64_t NumBBRanges =
           E.NumBBRanges.value_or(E.BBRanges ? E.BBRanges->size() : 0);
-      CBA.writeULEB128(NumBBRanges);
+      W.writeULEB128(NumBBRanges);
     }
     if (!E.BBRanges)
       continue;
@@ -1502,36 +1519,36 @@ void ELFState<ELFT>::writeSectionContent(
         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);
+      W.writeAddress(BBR.BaseAddress);
       // 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);
+      W.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);
+          W.writeULEB128(BBE.ID);
+        W.writeULEB128(BBE.AddressOffset);
         if (EmitCallsiteEndOffsets) {
           size_t NumCallsiteEndOffsets =
               BBE.CallsiteEndOffsets ? BBE.CallsiteEndOffsets->size() : 0;
-          CBA.writeULEB128(NumCallsiteEndOffsets);
+          W.writeULEB128(NumCallsiteEndOffsets);
           if (BBE.CallsiteEndOffsets) {
             for (uint32_t Offset : *BBE.CallsiteEndOffsets)
-              CBA.writeULEB128(Offset);
+              W.writeULEB128(Offset);
           }
         }
-        CBA.writeULEB128(BBE.Size);
-        CBA.writeULEB128(BBE.Metadata);
+        W.writeULEB128(BBE.Size);
+        W.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);
+          W.writeInt<uint64_t>(Hash);
         }
       }
     }
@@ -1540,7 +1557,7 @@ void ELFState<ELFT>::writeSectionContent(
     const BBAddrMapYAML::PGOAnalysisMapEntry &PGOEntry = PGOAnalyses->at(Idx);
 
     if (PGOEntry.FuncEntryCount)
-      CBA.writeULEB128(*PGOEntry.FuncEntryCount);
+      W.writeULEB128(*PGOEntry.FuncEntryCount);
 
     if (!PGOEntry.PGOBBEntries)
       continue;
@@ -1556,16 +1573,16 @@ void ELFState<ELFT>::writeSectionContent(
 
     for (const auto &PGOBBE : PGOBBEntries) {
       if (PGOBBE.BBFreq)
-        CBA.writeULEB128(*PGOBBE.BBFreq);
+        W.writeULEB128(*PGOBBE.BBFreq);
       if (FeatureOrErr->PostLinkCfg || PGOBBE.PostLinkBBFreq.has_value())
-        CBA.writeULEB128(PGOBBE.PostLinkBBFreq.value_or(0));
+        W.writeULEB128(PGOBBE.PostLinkBBFreq.value_or(0));
       if (PGOBBE.Successors) {
-        CBA.writeULEB128(PGOBBE.Successors->size());
+        W.writeULEB128(PGOBBE.Successors->size());
         for (const auto &[ID, BrProb, PostLinkBrFreq] : *PGOBBE.Successors) {
-          CBA.writeULEB128(ID);
-          CBA.writeULEB128(BrProb);
+          W.writeULEB128(ID);
+          W.writeULEB128(BrProb);
           if (FeatureOrErr->PostLinkCfg || PostLinkBrFreq.has_value())
-            CBA.writeULEB128(PostLinkBrFreq.value_or(0));
+            W.writeULEB128(PostLinkBrFreq.value_or(0));
         }
       }
     }

>From 588a4e0571a51bf5f7aa956f351f5347f8b1cd50 Mon Sep 17 00:00:00 2001
From: Haohai Wen <haohai.wen at intel.com>
Date: Fri, 26 Jun 2026 14:10:24 +0800
Subject: [PATCH 2/3] [ObjectYAML][NFC] Hoist BBAddrMap yaml2obj encoder into a
 shared helper

Move the .llvm_bb_addr_map payload encode loop out of
ELFState::writeSectionContent and into BBAddrMapYAML::encodePayload, a
function template over the Writer interface, so the upcoming COFF
emitter can reuse it. The ELF path becomes a thin wrapper: it keeps the
format-specific pre-loop validation and sh_size accounting and forwards
the entries through an ELFWriter.
---
 .../llvm/ObjectYAML/BBAddrMapYAMLEmitter.h    | 122 ++++++++++++++++++
 llvm/lib/ObjectYAML/ELFEmitter.cpp            | 108 +---------------
 2 files changed, 123 insertions(+), 107 deletions(-)

diff --git a/llvm/include/llvm/ObjectYAML/BBAddrMapYAMLEmitter.h b/llvm/include/llvm/ObjectYAML/BBAddrMapYAMLEmitter.h
index c9cc4c848e3e2..3b23674b67141 100644
--- a/llvm/include/llvm/ObjectYAML/BBAddrMapYAMLEmitter.h
+++ b/llvm/include/llvm/ObjectYAML/BBAddrMapYAMLEmitter.h
@@ -15,10 +15,16 @@
 #ifndef LLVM_OBJECTYAML_BBADDRMAPYAMLEMITTER_H
 #define LLVM_OBJECTYAML_BBADDRMAPYAMLEMITTER_H
 
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/bit.h"
+#include "llvm/Object/BBAddrMap.h"
 #include "llvm/ObjectYAML/BBAddrMapYAML.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/WithColor.h"
 #include <cassert>
 #include <cstdint>
+#include <vector>
 
 namespace llvm {
 namespace BBAddrMapYAML {
@@ -52,6 +58,122 @@ template <typename Derived> class Writer {
   void writeULEB128(uint64_t Val) { derived().emitULEB128(Val); }
 };
 
+/// Encodes the BBAddrMap section body through \p W, walking \p PGOAnalyses
+/// alongside \p Entries when non-null. Warns and continues on malformed YAML,
+/// so yaml2obj can still emit intentionally-broken test objects.
+template <typename Derived>
+void encodePayload(ArrayRef<BBAddrMapEntry> Entries,
+                   const std::vector<PGOAnalysisMapEntry> *PGOAnalyses,
+                   Writer<Derived> &W) {
+  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";
+    W.template writeInt<uint8_t>(E.Version);
+    if (E.Version < 5)
+      W.template writeInt<uint8_t>(static_cast<uint8_t>(E.Feature));
+    else
+      W.template writeInt<uint16_t>(E.Feature);
+    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);
+      W.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 base address of the range.
+      W.writeAddress(BBR.BaseAddress);
+      // 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);
+      W.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)
+          W.writeULEB128(BBE.ID);
+        W.writeULEB128(BBE.AddressOffset);
+        if (EmitCallsiteEndOffsets) {
+          size_t NumCallsiteEndOffsets =
+              BBE.CallsiteEndOffsets ? BBE.CallsiteEndOffsets->size() : 0;
+          W.writeULEB128(NumCallsiteEndOffsets);
+          if (BBE.CallsiteEndOffsets) {
+            for (uint32_t Offset : *BBE.CallsiteEndOffsets)
+              W.writeULEB128(Offset);
+          }
+        }
+        W.writeULEB128(BBE.Size);
+        W.writeULEB128(BBE.Metadata);
+        if (FeatureOrErr->BBHash || BBE.Hash.has_value()) {
+          uint64_t Hash =
+              BBE.Hash.has_value() ? BBE.Hash.value() : llvm::yaml::Hex64(0);
+          W.template writeInt<uint64_t>(Hash);
+        }
+      }
+    }
+    if (!PGOAnalyses)
+      continue;
+    const PGOAnalysisMapEntry &PGOEntry = PGOAnalyses->at(Idx);
+
+    if (PGOEntry.FuncEntryCount)
+      W.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)
+        W.writeULEB128(*PGOBBE.BBFreq);
+      if (FeatureOrErr->PostLinkCfg || PGOBBE.PostLinkBBFreq.has_value())
+        W.writeULEB128(PGOBBE.PostLinkBBFreq.value_or(0));
+      if (PGOBBE.Successors) {
+        W.writeULEB128(PGOBBE.Successors->size());
+        for (const auto &[ID, BrProb, PostLinkBrFreq] : *PGOBBE.Successors) {
+          W.writeULEB128(ID);
+          W.writeULEB128(BrProb);
+          if (FeatureOrErr->PostLinkCfg || PostLinkBrFreq.has_value())
+            W.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 2e60132995fa1..0fe1d458e5891 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -1480,113 +1480,7 @@ void ELFState<ELFT>::writeSectionContent(
 
   ELFWriter W(CBA, ELFT::Endianness, sizeof(uintX_t));
   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";
-    W.writeInt<uint8_t>(E.Version);
-    if (E.Version < 5)
-      W.writeInt<uint8_t>(static_cast<uint8_t>(E.Feature));
-    else
-      W.writeInt<uint16_t>(E.Feature);
-    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);
-      W.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.
-      W.writeAddress(BBR.BaseAddress);
-      // 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);
-      W.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)
-          W.writeULEB128(BBE.ID);
-        W.writeULEB128(BBE.AddressOffset);
-        if (EmitCallsiteEndOffsets) {
-          size_t NumCallsiteEndOffsets =
-              BBE.CallsiteEndOffsets ? BBE.CallsiteEndOffsets->size() : 0;
-          W.writeULEB128(NumCallsiteEndOffsets);
-          if (BBE.CallsiteEndOffsets) {
-            for (uint32_t Offset : *BBE.CallsiteEndOffsets)
-              W.writeULEB128(Offset);
-          }
-        }
-        W.writeULEB128(BBE.Size);
-        W.writeULEB128(BBE.Metadata);
-        if (FeatureOrErr->BBHash || BBE.Hash.has_value()) {
-          uint64_t Hash =
-              BBE.Hash.has_value() ? BBE.Hash.value() : llvm::yaml::Hex64(0);
-          W.writeInt<uint64_t>(Hash);
-        }
-      }
-    }
-    if (!PGOAnalyses)
-      continue;
-    const BBAddrMapYAML::PGOAnalysisMapEntry &PGOEntry = PGOAnalyses->at(Idx);
-
-    if (PGOEntry.FuncEntryCount)
-      W.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)
-        W.writeULEB128(*PGOBBE.BBFreq);
-      if (FeatureOrErr->PostLinkCfg || PGOBBE.PostLinkBBFreq.has_value())
-        W.writeULEB128(PGOBBE.PostLinkBBFreq.value_or(0));
-      if (PGOBBE.Successors) {
-        W.writeULEB128(PGOBBE.Successors->size());
-        for (const auto &[ID, BrProb, PostLinkBrFreq] : *PGOBBE.Successors) {
-          W.writeULEB128(ID);
-          W.writeULEB128(BrProb);
-          if (FeatureOrErr->PostLinkCfg || PostLinkBrFreq.has_value())
-            W.writeULEB128(PostLinkBrFreq.value_or(0));
-        }
-      }
-    }
-  }
+  BBAddrMapYAML::encodePayload(*Section.Entries, PGOAnalyses, W);
   SHeader.sh_size += CBA.getOffset() - CurrentOffset;
 }
 

>From d610979865d1fb9f06def865a4eccb492a512775 Mon Sep 17 00:00:00 2001
From: Haohai Wen <haohai.wen at intel.com>
Date: Thu, 16 Jul 2026 13:10:01 +0800
Subject: [PATCH 3/3] [ObjectYAML][NFC] Move BBAddrMap YAML encoding to source

Define the shared BBAddrMap payload encoder in BBAddrMapYAML.cpp
instead of a template header. Keep ELFEmitter using the helper
and remove now-unused includes.
---
 llvm/include/llvm/ObjectYAML/BBAddrMapYAML.h  |  15 +-
 .../llvm/ObjectYAML/BBAddrMapYAMLEmitter.h    | 180 ------------------
 llvm/lib/ObjectYAML/BBAddrMapYAML.cpp         | 124 ++++++++++++
 llvm/lib/ObjectYAML/ELFEmitter.cpp            | 112 +----------
 4 files changed, 138 insertions(+), 293 deletions(-)
 delete mode 100644 llvm/include/llvm/ObjectYAML/BBAddrMapYAMLEmitter.h

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/include/llvm/ObjectYAML/BBAddrMapYAMLEmitter.h b/llvm/include/llvm/ObjectYAML/BBAddrMapYAMLEmitter.h
deleted file mode 100644
index 3b23674b67141..0000000000000
--- a/llvm/include/llvm/ObjectYAML/BBAddrMapYAMLEmitter.h
+++ /dev/null
@@ -1,180 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// Shared yaml2obj BBAddrMap writer, in a standalone header so type-only
-/// includers don't pull in its dependencies.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECTYAML_BBADDRMAPYAMLEMITTER_H
-#define LLVM_OBJECTYAML_BBADDRMAPYAMLEMITTER_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/bit.h"
-#include "llvm/Object/BBAddrMap.h"
-#include "llvm/ObjectYAML/BBAddrMapYAML.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/WithColor.h"
-#include <cassert>
-#include <cstdint>
-#include <vector>
-
-namespace llvm {
-namespace BBAddrMapYAML {
-
-/// CRTP interface for emitting the BBAddrMap payload to a target-specific
-/// writer, so the encode logic can be shared across formats.
-template <typename Derived> class Writer {
-  llvm::endianness Endian;
-  unsigned AddressSize;
-
-  Derived &derived() { return static_cast<Derived &>(*this); }
-
-public:
-  Writer(llvm::endianness Endian, unsigned AddressSize)
-      : Endian(Endian), AddressSize(AddressSize) {
-    assert((AddressSize == 4 || AddressSize == 8) && "invalid address size");
-  }
-
-  template <typename T> void writeInt(T Val) {
-    derived().template emitInt<T>(Val, Endian);
-  }
-
-  // Pointer-sized: 4 or 8 bytes per AddressSize.
-  void writeAddress(uint64_t Val) {
-    if (AddressSize == 8)
-      writeInt<uint64_t>(Val);
-    else
-      writeInt<uint32_t>(static_cast<uint32_t>(Val));
-  }
-
-  void writeULEB128(uint64_t Val) { derived().emitULEB128(Val); }
-};
-
-/// Encodes the BBAddrMap section body through \p W, walking \p PGOAnalyses
-/// alongside \p Entries when non-null. Warns and continues on malformed YAML,
-/// so yaml2obj can still emit intentionally-broken test objects.
-template <typename Derived>
-void encodePayload(ArrayRef<BBAddrMapEntry> Entries,
-                   const std::vector<PGOAnalysisMapEntry> *PGOAnalyses,
-                   Writer<Derived> &W) {
-  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";
-    W.template writeInt<uint8_t>(E.Version);
-    if (E.Version < 5)
-      W.template writeInt<uint8_t>(static_cast<uint8_t>(E.Feature));
-    else
-      W.template writeInt<uint16_t>(E.Feature);
-    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);
-      W.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 base address of the range.
-      W.writeAddress(BBR.BaseAddress);
-      // 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);
-      W.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)
-          W.writeULEB128(BBE.ID);
-        W.writeULEB128(BBE.AddressOffset);
-        if (EmitCallsiteEndOffsets) {
-          size_t NumCallsiteEndOffsets =
-              BBE.CallsiteEndOffsets ? BBE.CallsiteEndOffsets->size() : 0;
-          W.writeULEB128(NumCallsiteEndOffsets);
-          if (BBE.CallsiteEndOffsets) {
-            for (uint32_t Offset : *BBE.CallsiteEndOffsets)
-              W.writeULEB128(Offset);
-          }
-        }
-        W.writeULEB128(BBE.Size);
-        W.writeULEB128(BBE.Metadata);
-        if (FeatureOrErr->BBHash || BBE.Hash.has_value()) {
-          uint64_t Hash =
-              BBE.Hash.has_value() ? BBE.Hash.value() : llvm::yaml::Hex64(0);
-          W.template writeInt<uint64_t>(Hash);
-        }
-      }
-    }
-    if (!PGOAnalyses)
-      continue;
-    const PGOAnalysisMapEntry &PGOEntry = PGOAnalyses->at(Idx);
-
-    if (PGOEntry.FuncEntryCount)
-      W.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)
-        W.writeULEB128(*PGOBBE.BBFreq);
-      if (FeatureOrErr->PostLinkCfg || PGOBBE.PostLinkBBFreq.has_value())
-        W.writeULEB128(PGOBBE.PostLinkBBFreq.value_or(0));
-      if (PGOBBE.Successors) {
-        W.writeULEB128(PGOBBE.Successors->size());
-        for (const auto &[ID, BrProb, PostLinkBrFreq] : *PGOBBE.Successors) {
-          W.writeULEB128(ID);
-          W.writeULEB128(BrProb);
-          if (FeatureOrErr->PostLinkCfg || PostLinkBrFreq.has_value())
-            W.writeULEB128(PostLinkBrFreq.value_or(0));
-        }
-      }
-    }
-  }
-}
-
-} // end namespace BBAddrMapYAML
-} // end namespace llvm
-
-#endif // LLVM_OBJECTYAML_BBADDRMAPYAMLEMITTER_H
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