[llvm] Introduce CovMap in ObjectYAML (PR #127432)

NAKAMURA Takumi via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 17 16:20:37 PST 2025


https://github.com/chapuni updated https://github.com/llvm/llvm-project/pull/127432

>From b111a23370a496efa8e941146c4533bd91da1aab Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Sun, 16 Feb 2025 23:49:57 +0900
Subject: [PATCH 1/6] Introduce CovMap in ObjectYAML

---
 llvm/include/llvm/ObjectYAML/CovMap.h         | 385 +++++++
 llvm/include/llvm/ObjectYAML/ELFYAML.h        |  14 +
 llvm/include/llvm/ProfileData/InstrProf.h     |   6 +
 llvm/lib/ObjectYAML/CMakeLists.txt            |   3 +
 llvm/lib/ObjectYAML/CovMap.cpp                | 977 ++++++++++++++++++
 llvm/lib/ObjectYAML/ELFEmitter.cpp            |  38 +
 llvm/lib/ObjectYAML/ELFYAML.cpp               |  12 +
 llvm/lib/ProfileData/InstrProf.cpp            |  23 +-
 .../Inputs/branch-c-general-single.yaml       | 561 ++++++++--
 .../Inputs/branch-logical-mixed-single.yaml   | 145 ++-
 .../llvm-cov/Inputs/branch-macros-single.yaml | 242 ++++-
 .../Inputs/branch-templates-single.yaml       | 119 ++-
 .../showLineExecutionCounts-single.yaml       |  57 +-
 llvm/test/tools/llvm-cov/Inputs/yaml.makefile |   6 +-
 llvm/test/tools/obj2yaml/ELF/covmap.yaml      | 160 +++
 llvm/test/tools/obj2yaml/help.test            |   1 +
 llvm/tools/obj2yaml/elf2yaml.cpp              |  57 +-
 llvm/tools/obj2yaml/obj2yaml.cpp              |   2 +-
 llvm/tools/obj2yaml/obj2yaml.h                |   4 +
 .../llvm-project-overlay/llvm/BUILD.bazel     |   2 +
 20 files changed, 2602 insertions(+), 212 deletions(-)
 create mode 100644 llvm/include/llvm/ObjectYAML/CovMap.h
 create mode 100644 llvm/lib/ObjectYAML/CovMap.cpp
 create mode 100644 llvm/test/tools/obj2yaml/ELF/covmap.yaml

diff --git a/llvm/include/llvm/ObjectYAML/CovMap.h b/llvm/include/llvm/ObjectYAML/CovMap.h
new file mode 100644
index 0000000000000..fa9492fc1ee72
--- /dev/null
+++ b/llvm/include/llvm/ObjectYAML/CovMap.h
@@ -0,0 +1,385 @@
+//===- CovMap.h - ObjectYAML Interface for coverage map ---------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// - llvm::coverage::yaml
+//
+//   Describes binary file formats and YAML structures of coverage map.
+//
+// - llvm::yaml
+//
+//   Attachments for YAMLTraits.
+//
+// - llvm::covmap
+//
+//   Provides YAML encoder and decoder for coverage map.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECTYAML_COVMAP_H
+#define LLVM_OBJECTYAML_COVMAP_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ObjectYAML/ELFYAML.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <variant>
+
+namespace llvm {
+class InstrProfSymtab;
+class raw_ostream;
+} // namespace llvm
+
+namespace llvm::coverage::yaml {
+
+/// This works like vector container but can be replaced with
+/// MutableArrayRef. See also SequenceTraits<VectorOrRef>.
+template <typename T, typename Vec = std::vector<T>> class VectorOrRef {
+  using Ref = MutableArrayRef<T>;
+
+  /// Holds vector type initially.
+  std::variant<Vec, Ref> Array;
+
+public:
+  // FIXME: Iterator impl is minimal easy.
+  using iterator = T *;
+
+  iterator begin() {
+    if (auto *V = std::get_if<Vec>(&Array))
+      return &V->front();
+    else
+      return &std::get<Ref>(Array).front();
+  }
+
+  iterator end() {
+    if (auto *V = std::get_if<Vec>(&Array))
+      return &V->back() + 1;
+    else
+      return &std::get<Ref>(Array).back() + 1;
+  }
+
+  size_t size() const {
+    if (const auto *V = std::get_if<Vec>(&Array))
+      return V->size();
+    else
+      return std::get<Ref>(Array).size();
+  }
+
+  T &operator[](int Idx) {
+    if (auto *V = std::get_if<Vec>(&Array))
+      return (*V)[Idx];
+    else
+      return std::get<Ref>(Array)[Idx];
+  }
+
+  void resize(size_t Size) { std::get<Vec>(Array).resize(Size); }
+
+  VectorOrRef() = default;
+
+  /// Initialize with MutableArrayRef.
+  VectorOrRef(Ref &&Tmp) : Array(std::move(Tmp)) {}
+};
+
+/// Options for Decoder.
+struct DecoderParam {
+  bool Detailed; ///< Generate and show processed records.
+  bool Raw;      ///< Show raw data oriented records.
+  bool dLoc;     ///< Show raw dLoc (differential Loc).
+};
+
+struct DecoderContext;
+
+/// Base Counter, corresponding to coverage::Counter.
+struct CounterTy {
+  enum TagTy : uint8_t {
+    Zero = 0,
+    Ref,
+    Sub,
+    Add,
+  };
+
+  /// Optional in detailed view, since most Tag can be determined from
+  /// other optional fields.
+  std::optional<TagTy> Tag;
+
+  /// Internal use.
+  std::optional<uint64_t> Val;
+
+  std::optional<uint64_t> RefOpt;
+  std::optional<uint64_t> SubOpt;
+  std::optional<uint64_t> AddOpt;
+
+  virtual ~CounterTy() {}
+
+  virtual void mapping(llvm::yaml::IO &IO);
+
+  /// Holds Val for extensions.
+  Error decodeOrTag(DecoderContext &Data);
+
+  /// Raise Error if Val isn't empty.
+  Error decode(DecoderContext &Data);
+
+  void encode(raw_ostream &OS) const;
+};
+
+/// Holds a pair of both hands but doesn't hold ops(add or sub).
+/// Ops is stored in CounterTy::Tag.
+using ExpressionTy = std::array<CounterTy, 2>;
+
+/// {True, False}
+using BranchTy = std::array<CounterTy, 2>;
+
+/// {ID, TrueID, FalseID}
+/// Note: This has +1 offset unlike mcdc::ConditionID.
+using MCDCBranchTy = std::array<uint16_t, 3>;
+
+struct DecisionTy {
+  uint64_t BIdx; ///< Bitmap index
+  uint64_t NC;   ///< NumConds
+
+  void mapping(llvm::yaml::IO &IO);
+
+  Error decode(DecoderContext &Data);
+
+  void encode(raw_ostream &OS) const;
+};
+
+/// {LineStart, ColumnStart, LineEnd, ColumnEnd}
+using LocTy = std::array<uint64_t, 4>;
+
+///
+struct RecTy : CounterTy {
+  enum ExtTagTy : uint8_t {
+    Skip = 2,
+    Branch = 4,
+    Decision = 5,
+    MCDCBranch = 6,
+  };
+
+  /// This is optional in detailed view.
+  std::optional<ExtTagTy> ExtTag;
+
+  // Options for extensions.
+  std::optional<uint64_t> Expansion; ///< Doesn't have ExtTag.
+  std::optional<BranchTy> BranchOpt; ///< Optionally has MCDC.
+  std::optional<MCDCBranchTy> MCDC;
+  std::optional<DecisionTy> DecisionOpt;
+
+  /// True or None.
+  /// Stored in ColumnEnd:31.
+  std::optional<bool> isGap;
+
+  std::optional<LocTy> Loc;  ///< Absolute line numbers.
+  std::optional<LocTy> dLoc; ///< Differential line numbers.
+
+  void mapping(llvm::yaml::IO &IO) override;
+
+  Error decode(DecoderContext &Data);
+
+  void encode(uint64_t &StartLoc, raw_ostream &OS) const;
+};
+
+/// {NumRecs, Recs...}
+struct FileRecsTy {
+  std::optional<unsigned> Index;       ///< Shown in detailed view.
+  std::optional<std::string> Filename; ///< Resolved by FileIDs.
+  std::vector<RecTy> Recs;
+
+  void mapping(llvm::yaml::IO &IO);
+};
+
+/// Key is FilenamesRef.
+using CovMapByRefTy = llvm::DenseMap<uint64_t, struct CovMapTy *>;
+
+/// An element of CovFun array.
+struct CovFunTy {
+  std::optional<llvm::yaml::Hex64> NameRef;     ///< Hash value of the symbol.
+  std::optional<std::string> FuncName;          ///< Resolved by symtab.
+  llvm::yaml::Hex64 FuncHash;                   ///< Signature of this function.
+  llvm::yaml::Hex64 FilenamesRef;               ///< Pointer to CovMap
+  std::optional<std::vector<unsigned>> FileIDs; ///< Resolved by CovMap
+  std::vector<ExpressionTy> Expressions;
+  std::vector<FileRecsTy> Files; ///< 2-dimension array of Recs.
+
+  void mapping(llvm::yaml::IO &IO);
+
+  /// Depends on CovMap and SymTab(IPSK_names)
+  Expected<uint64_t> decode(CovMapByRefTy &CovMapByRef, InstrProfSymtab *SymTab,
+                            const ArrayRef<uint8_t> Content, uint64_t Offset,
+                            const DecoderParam &Param, bool IsLE = true);
+
+  void encode(raw_ostream &OS) const;
+};
+
+/// An element of CovMap array.
+struct CovMapTy {
+  /// This is the key of CovMap but not present in the file
+  /// format. Calculate and store with Filenames.
+  llvm::yaml::Hex64 FilenamesRef;
+
+  std::optional<uint32_t> Version;
+
+  /// Raw Filenames (and storage of Files)
+  std::optional<std::vector<std::string>> Filenames;
+
+  /// Since Version5: Filenames[0] is the working directory (or
+  /// zero-length string). Note that indices in CovFun::FileIDs is
+  /// base on Filenames. (Then, +0, as WD, is not expected to appear)
+  std::optional<std::string> WD;
+  /// This may be ArrayRef in Decoder since Filenames has been
+  /// filled. On the other hand in Encoder, this should be a vector
+  /// since YAML parser doesn't endorse references.
+  std::optional<VectorOrRef<std::string>> Files;
+
+  void mapping(llvm::yaml::IO &IO);
+
+  bool useWD() const { return (!Version || *Version >= 4); }
+  StringRef getWD() const { return (WD ? *WD : StringRef()); }
+
+  Expected<uint64_t> decode(const ArrayRef<uint8_t> Content, uint64_t Offset,
+                            const DecoderParam &Param, bool IsLE = true);
+
+  /// Generate Accumulated list with WD.
+  /// Returns a single element {WD} if AccFiles is not given.
+  std::vector<std::string>
+  generateAccFilenames(const std::optional<ArrayRef<StringRef>> &AccFilesOpt =
+                           std::nullopt) const;
+  /// Regenerate Filenames with WD.
+  /// Use Files if it is not None. Or given AccFiles is used.
+  void
+  regenerateFilenames(const std::optional<ArrayRef<StringRef>> &AccFilesOpt);
+
+  /// Encode Filenames. This is mostly used just to obtain FilenamesRef.
+  std::pair<uint64_t, std::string> encodeFilenames(
+      const std::optional<ArrayRef<StringRef>> &AccFilesOpt = std::nullopt,
+      bool Compress = false) const;
+
+  void encode(raw_ostream &OS) const;
+};
+
+} // namespace llvm::coverage::yaml
+
+namespace llvm::yaml {
+template <typename T>
+struct SequenceTraits<llvm::coverage::yaml::VectorOrRef<T>> {
+  static size_t size(IO &io, llvm::coverage::yaml::VectorOrRef<T> &seq) {
+    return seq.size();
+  }
+  static T &element(IO &, llvm::coverage::yaml::VectorOrRef<T> &seq,
+                    size_t index) {
+    if (index >= seq.size())
+      seq.resize(index + 1);
+    return seq[index];
+  }
+};
+} // namespace llvm::yaml
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::coverage::yaml::CovMapTy)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::coverage::yaml::CovFunTy)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::coverage::yaml::ExpressionTy)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::coverage::yaml::RecTy)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::coverage::yaml::FileRecsTy)
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::coverage::yaml::CounterTy)
+
+#define LLVM_COVERAGE_YAML_ELEM_MAPPING(Ty)                                    \
+  namespace llvm::yaml {                                                       \
+  template <> struct MappingTraits<llvm::coverage::yaml::Ty> {                 \
+    static void mapping(IO &IO, llvm::coverage::yaml::Ty &Obj) {               \
+      Obj.mapping(IO);                                                         \
+    }                                                                          \
+  };                                                                           \
+  }
+
+/// `Flow` is used for emission of a compact oneliner for RecTy.
+#define LLVM_COVERAGE_YAML_ELEM_MAPPING_FLOW(Ty)                               \
+  namespace llvm::yaml {                                                       \
+  template <> struct MappingTraits<llvm::coverage::yaml::Ty> {                 \
+    static void mapping(IO &IO, llvm::coverage::yaml::Ty &Obj) {               \
+      Obj.mapping(IO);                                                         \
+      (void)flow;                                                              \
+    }                                                                          \
+    static const bool flow = true;                                             \
+  };                                                                           \
+  }
+
+#define LLVM_COVERAGE_YAML_ENUM(Ty)                                            \
+  namespace llvm::yaml {                                                       \
+  template <> struct ScalarEnumerationTraits<llvm::coverage::yaml::Ty> {       \
+    static void enumeration(IO &IO, llvm::coverage::yaml::Ty &Value);          \
+  };                                                                           \
+  }
+
+LLVM_COVERAGE_YAML_ENUM(CounterTy::TagTy)
+LLVM_COVERAGE_YAML_ENUM(RecTy::ExtTagTy)
+LLVM_COVERAGE_YAML_ELEM_MAPPING_FLOW(CounterTy)
+LLVM_COVERAGE_YAML_ELEM_MAPPING_FLOW(DecisionTy)
+LLVM_COVERAGE_YAML_ELEM_MAPPING_FLOW(RecTy)
+LLVM_COVERAGE_YAML_ELEM_MAPPING(FileRecsTy)
+LLVM_COVERAGE_YAML_ELEM_MAPPING(CovFunTy)
+LLVM_COVERAGE_YAML_ELEM_MAPPING(CovMapTy)
+
+namespace llvm::covmap {
+
+class Decoder {
+public:
+  virtual ~Decoder() {}
+
+  /// Returns DecoderImpl.
+  static std::unique_ptr<Decoder>
+  get(const coverage::yaml::DecoderParam &Param);
+
+  /// Called from the Sections loop in advance of the final dump.
+  /// Decoder predecodes Names and CovMap, and captures Contents of
+  /// CovFuns.
+  virtual Error
+  acquire(uint64_t Offset, unsigned AddressAlign, StringRef Name,
+          std::function<Expected<ArrayRef<uint8_t>>()> getSectionContents) = 0;
+
+  /// Called before the final dump after `acquire`.
+  /// Decode contents partially and resolve names.
+  virtual Error fixup() = 0;
+
+  /// Create an ELFYAML object. This just puts predecoded data in
+  /// `fixup`.
+  virtual Expected<ELFYAML::Section *>
+  make(uint64_t Offset, StringRef Name,
+       std::function<Error(ELFYAML::Section &S)> dumpCommonSection) = 0;
+
+  /// Suppress emission of CovMap unless enabled.
+  static bool enabled;
+};
+
+class Encoder {
+public:
+  virtual ~Encoder() {}
+
+  /// Returns EncoderImpl.
+  static std::unique_ptr<Encoder> get();
+
+  /// Called from the Sections loop.
+  virtual void collect(ELFYAML::Chunk *Chunk) = 0;
+
+  /// Resolves names along DecoderParam in advance of Emitter. It'd be
+  /// too late to resolve sections in Emitter since they are immutable
+  /// then.
+  virtual void fixup() = 0;
+};
+
+/// Returns whether Name is interested.
+bool nameMatches(StringRef Name);
+
+/// Returns a new ELFYAML Object.
+std::unique_ptr<ELFYAML::Section> make_unique(StringRef Name);
+
+} // namespace llvm::covmap
+
+#endif // LLVM_OBJECTYAML_COVMAP_H
diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h
index dfdfa055d65fa..2dc1a861077c3 100644
--- a/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -229,6 +229,7 @@ struct Chunk {
     DependentLibraries,
     CallGraphProfile,
     BBAddrMap,
+    CovMapBase,
 
     // Special chunks.
     SpecialChunksStart,
@@ -398,6 +399,19 @@ struct RawContentSection : Section {
   std::optional<std::vector<uint8_t>> ContentBuf;
 };
 
+struct CovMapSectionBase : Section {
+  std::optional<llvm::yaml::Hex64> Info;
+
+  CovMapSectionBase() : Section(ChunkKind::CovMapBase) {}
+
+  virtual void mapping(yaml::IO &IO) = 0;
+  virtual Error encode(raw_ostream &OS) const = 0;
+
+  static bool classof(const Chunk *S) {
+    return S->Kind == ChunkKind::CovMapBase;
+  }
+};
+
 struct NoBitsSection : Section {
   NoBitsSection() : Section(ChunkKind::NoBits) {}
 
diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h
index 7133c0c6a302c..e20424da3cac2 100644
--- a/llvm/include/llvm/ProfileData/InstrProf.h
+++ b/llvm/include/llvm/ProfileData/InstrProf.h
@@ -545,6 +545,12 @@ class InstrProfSymtab {
   /// This method is a wrapper to \c readAndDecodeStrings method.
   Error create(StringRef NameStrings);
 
+  // PrfNames is nested array.
+  using PrfNamesTy = SmallVector<std::string>;
+  using PrfNamesChunksTy = SmallVector<PrfNamesTy, 1>;
+
+  Expected<PrfNamesChunksTy> createAndGetList(ArrayRef<uint8_t> Content);
+
   /// Initialize symtab states with function names and vtable names. \c
   /// FuncNameStrings is a string composed of one or more encoded function name
   /// strings, and \c VTableNameStrings composes of one or more encoded vtable
diff --git a/llvm/lib/ObjectYAML/CMakeLists.txt b/llvm/lib/ObjectYAML/CMakeLists.txt
index b36974d47d9f8..11054a1e91388 100644
--- a/llvm/lib/ObjectYAML/CMakeLists.txt
+++ b/llvm/lib/ObjectYAML/CMakeLists.txt
@@ -7,6 +7,7 @@ add_llvm_component_library(LLVMObjectYAML
   CodeViewYAMLTypes.cpp
   COFFEmitter.cpp
   COFFYAML.cpp
+  CovMap.cpp
   DWARFEmitter.cpp
   DWARFYAML.cpp
   DXContainerEmitter.cpp
@@ -34,7 +35,9 @@ add_llvm_component_library(LLVMObjectYAML
 
   LINK_COMPONENTS
   BinaryFormat
+  Coverage
   Object
+  ProfileData
   Support
   TargetParser
   DebugInfoCodeView
diff --git a/llvm/lib/ObjectYAML/CovMap.cpp b/llvm/lib/ObjectYAML/CovMap.cpp
new file mode 100644
index 0000000000000..12c03a651668c
--- /dev/null
+++ b/llvm/lib/ObjectYAML/CovMap.cpp
@@ -0,0 +1,977 @@
+//===- CovMap.cpp - ObjectYAML Interface for coverage map -----------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementations of CovMap, encoder, decoder.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ObjectYAML/CovMap.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ObjectYAML/ELFYAML.h"
+#include "llvm/ProfileData/Coverage/CoverageMapping.h"
+#include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
+#include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/Alignment.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/LEB128.h"
+#include "llvm/Support/MD5.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <cstdint>
+
+#define COVMAP_V3
+
+using namespace llvm;
+using namespace llvm::coverage::yaml;
+using namespace llvm::covmap;
+
+bool Decoder::enabled;
+
+// DataExtractor w/ single Cursor
+struct coverage::yaml::DecoderContext : DataExtractor,
+                                        DataExtractor::Cursor,
+                                        DecoderParam {
+  uint64_t LineStart = 0;
+
+  DecoderContext(const ArrayRef<uint8_t> Content, const DecoderParam &Param,
+                 bool IsLE)
+      : DataExtractor(Content, IsLE, /*AddressSize=*/0),
+        DataExtractor::Cursor(0), DecoderParam(Param) {}
+
+  bool eof() { return DataExtractor::eof(*this); }
+  uint32_t getU32() { return DataExtractor::getU32(*this); }
+  uint64_t getU64() { return DataExtractor::getU64(*this); }
+  Expected<uint64_t> getULEB128() {
+    uint64_t Result = DataExtractor::getULEB128(*this);
+    if (!*this)
+      return takeError();
+    return Result;
+  }
+  StringRef getBytes(size_t sz) { return DataExtractor::getBytes(*this, sz); }
+};
+
+void CounterTy::encode(raw_ostream &OS) const {
+  std::pair<unsigned, uint64_t> C;
+  if (RefOpt)
+    C = {Ref, *RefOpt};
+  else if (SubOpt)
+    C = {Sub, *SubOpt};
+  else if (AddOpt)
+    C = {Add, *AddOpt};
+  else if (Tag && *Tag == Zero)
+    C = {Zero, 0u};
+  else if (Tag && Val)
+    C = {*Tag, *Val};
+  else
+    llvm_unreachable("Null value cannot be met");
+
+  encodeULEB128(C.first | (C.second << 2), OS);
+}
+
+Error CounterTy::decodeOrTag(DecoderContext &Data) {
+  auto COrErr = Data.getULEB128();
+  if (!COrErr)
+    return COrErr.takeError();
+  auto T = static_cast<TagTy>(*COrErr & 0x03);
+  auto V = (*COrErr >> 2);
+  if (T == Zero) {
+    if (V == 0)
+      Tag = Zero; // w/o Val
+    else
+      Val = V; // w/o Tag
+  } else {
+    if (Data.Raw) {
+      Tag = T;
+      Val = V;
+    } else {
+      switch (T) {
+      case Zero:
+        llvm_unreachable("Zero should be handled in advance");
+      case Ref:
+        RefOpt = V;
+        break;
+      case Sub:
+        SubOpt = V;
+        break;
+      case Add:
+        AddOpt = V;
+        break;
+      }
+    }
+  }
+
+  return Error::success();
+}
+
+Error CounterTy::decode(DecoderContext &Data) {
+  if (auto E = decodeOrTag(Data))
+    return E;
+  if (!this->Tag && this->Val)
+    return make_error<CoverageMapError>(
+        coveragemap_error::malformed,
+        "Counter::Zero shouldn't have the Val: 0x" +
+            Twine::utohexstr(*this->Val));
+  return Error::success();
+}
+
+void DecisionTy::encode(raw_ostream &OS) const {
+  encodeULEB128(BIdx, OS);
+  encodeULEB128(NC, OS);
+}
+
+Error DecisionTy::decode(DecoderContext &Data) {
+  auto BIdxOrErr = Data.getULEB128();
+  if (!BIdxOrErr)
+    return BIdxOrErr.takeError();
+  BIdx = *BIdxOrErr;
+
+  auto NCOrErr = Data.getULEB128();
+  if (!NCOrErr)
+    return NCOrErr.takeError();
+  NC = *NCOrErr;
+
+  return Error::success();
+}
+
+void RecTy::encode(uint64_t &StartLoc, raw_ostream &OS) const {
+  if (Expansion) {
+    encodeULEB128(4 + (*Expansion << 3), OS);
+  } else if (ExtTag && *ExtTag == Skip) {
+    encodeULEB128(2 << 3, OS);
+  } else if (DecisionOpt) {
+    assert(!ExtTag || *ExtTag == Decision);
+    encodeULEB128(5 << 3, OS);
+    DecisionOpt->encode(OS);
+  } else if (MCDC) {
+    assert(!ExtTag || *ExtTag == MCDCBranch);
+    assert(BranchOpt);
+    encodeULEB128(6 << 3, OS);
+    (*BranchOpt)[0].encode(OS);
+    (*BranchOpt)[1].encode(OS);
+    encodeULEB128((*MCDC)[0], OS);
+    encodeULEB128((*MCDC)[1], OS);
+    encodeULEB128((*MCDC)[2], OS);
+  } else if (BranchOpt) {
+    assert(!ExtTag || *ExtTag == Branch);
+    encodeULEB128(4 << 3, OS);
+    (*BranchOpt)[0].encode(OS);
+    (*BranchOpt)[1].encode(OS);
+  } else {
+    // Non-tag CounterTy
+    CounterTy::encode(OS);
+  }
+
+  assert((!isGap || *isGap) && "Don't set isGap=false");
+  uint32_t Gap = (isGap ? (1u << 31) : 0u);
+  if (Loc) {
+    encodeULEB128((*Loc)[0] - StartLoc, OS);
+    encodeULEB128((*Loc)[1], OS);
+    encodeULEB128((*Loc)[2] - (*Loc)[0], OS);
+    encodeULEB128((*Loc)[3] | Gap, OS);
+    StartLoc = (*Loc)[0];
+  } else {
+    encodeULEB128((*dLoc)[0], OS);
+    encodeULEB128((*dLoc)[1], OS);
+    encodeULEB128((*dLoc)[2], OS);
+    encodeULEB128((*dLoc)[3] | Gap, OS);
+  }
+}
+
+Error RecTy::decode(DecoderContext &Data) {
+  auto getU16 = [&]() -> Expected<uint16_t> {
+    auto ValOrErr = Data.getULEB128();
+    if (!ValOrErr)
+      return ValOrErr.takeError();
+    if (*ValOrErr > 0x7FFF + 1)
+      return make_error<CoverageMapError>(coveragemap_error::malformed,
+                                          "MC/DC index is out of range: 0x" +
+                                              Twine::utohexstr(*ValOrErr));
+    return static_cast<uint16_t>(*ValOrErr);
+  };
+
+  auto decodeBranch = [&]() -> Error {
+    auto &B = BranchOpt.emplace();
+    if (auto E = B[0].decode(Data))
+      return E;
+    if (auto E = B[1].decode(Data))
+      return E;
+    return Error::success();
+  };
+
+  // Decode tagged CounterTy
+  if (auto E = CounterTy::decodeOrTag(Data))
+    return E;
+  if (!this->Val || this->Tag) {
+    // Compatible to CounterTy
+  } else if (*this->Val & 1u) {
+    Expansion = (*this->Val >> 1);
+    this->Val.reset();
+  } else {
+    auto Tag = *this->Val >> 1;
+    this->Val.reset();
+    switch (Tag) {
+    case Skip:
+      ExtTag = Skip; // w/o Val
+      break;
+    case Decision:
+      if (auto E = DecisionOpt.emplace().decode(Data))
+        return E;
+      if (Data.Raw)
+        ExtTag = Decision;
+      break;
+    case Branch:
+      if (auto E = decodeBranch())
+        return E;
+      if (Data.Raw)
+        ExtTag = Branch;
+      break;
+    case MCDCBranch: {
+      if (auto E = decodeBranch())
+        return E;
+      auto I0OrErr = getU16();
+      if (!I0OrErr)
+        return I0OrErr.takeError();
+      auto I1OrErr = getU16();
+      if (!I1OrErr)
+        return I1OrErr.takeError();
+      auto I2OrErr = getU16();
+      if (!I2OrErr)
+        return I2OrErr.takeError();
+      MCDC = {*I0OrErr, *I1OrErr, *I2OrErr};
+      if (Data.Raw)
+        ExtTag = MCDCBranch;
+      break;
+    }
+    default:
+      return make_error<CoverageMapError>(
+          coveragemap_error::malformed,
+          "Record doesn't have an valid Tag: 0x" + Twine::utohexstr(Tag));
+    }
+  }
+
+  // Decode Loc
+  auto LSDeltaOrErr = Data.getULEB128();
+  if (!LSDeltaOrErr)
+    return LSDeltaOrErr.takeError();
+  Data.LineStart += *LSDeltaOrErr;
+
+  auto CSOrErr = Data.getULEB128();
+  if (!CSOrErr)
+    return CSOrErr.takeError();
+
+  auto NLOrErr = Data.getULEB128();
+  if (!NLOrErr)
+    return NLOrErr.takeError();
+  auto LineEnd = Data.LineStart + *NLOrErr;
+
+  auto CEOrErr = Data.getULEB128();
+  if (!CEOrErr)
+    return CEOrErr.takeError();
+  auto ColumnEnd = *CEOrErr;
+
+  // Gap is set in ColumnEnd:31
+  if (ColumnEnd & (1u << 31))
+    isGap = true;
+  ColumnEnd &= ((1u << 31) - 1);
+
+  dLoc = {*LSDeltaOrErr, *CSOrErr, *NLOrErr, ColumnEnd};
+  Loc = {Data.LineStart, *CSOrErr, LineEnd, ColumnEnd};
+
+  return Error::success();
+}
+
+void CovFunTy::encode(raw_ostream &OS) const {
+  // Encode Body in advance since DataSize should be known.
+  std::string Body;
+  raw_string_ostream SS(Body);
+
+  assert(FileIDs);
+  encodeULEB128(FileIDs->size(), SS);
+  for (auto I : *FileIDs)
+    encodeULEB128(I, SS);
+
+  encodeULEB128(Expressions.size(), SS);
+  for (const auto &[LHS, RHS] : Expressions) {
+    LHS.encode(SS);
+    RHS.encode(SS);
+  }
+
+  for (const auto &File : Files) {
+    encodeULEB128(File.Recs.size(), SS);
+    uint64_t StartLoc = 0;
+    for (const auto &Rec : File.Recs)
+      Rec.encode(StartLoc, SS);
+  }
+
+  // Emit the Header
+  uint64_t NameRef = (this->NameRef ? static_cast<uint64_t>(*this->NameRef)
+                                    : MD5Hash(*this->FuncName));
+  uint32_t DataSize = Body.size();
+  /* this->FuncHash */
+  char CoverageMapping = 0; // dummy
+  /* this->FilenamesRef */
+
+#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Initializer)                  \
+  if (sizeof(Name) > 1) {                                                      \
+    Type t = Name;                                                             \
+    OS << StringRef(reinterpret_cast<const char *>(&t), sizeof(t));            \
+  }
+#include "llvm/ProfileData/InstrProfData.inc"
+
+  // Emit the body.
+  OS << std::move(Body);
+}
+
+std::vector<std::string> CovMapTy::generateAccFilenames(
+    const std::optional<ArrayRef<StringRef>> &AccFilesOpt) const {
+  std::vector<std::string> Result;
+  if (useWD())
+    Result.push_back(getWD().str());
+  // Returns {WD} if AccFiles is None.
+  if (AccFilesOpt) {
+    for (auto &Filename : *AccFilesOpt)
+      Result.push_back(Filename.str());
+  }
+  return Result;
+}
+
+void CovMapTy::regenerateFilenames(
+    const std::optional<ArrayRef<StringRef>> &AccFilesOpt) {
+  assert(!this->Filenames);
+  if (this->Files) {
+    auto &CovMapFilenames = this->Filenames.emplace(generateAccFilenames());
+    assert(CovMapFilenames.size() <= 1);
+    for (auto &&File : *this->Files)
+      CovMapFilenames.push_back(std::move(File));
+  } else {
+    // Encode Accfiles, that comes from CovFun.
+    this->Filenames = generateAccFilenames(AccFilesOpt);
+  }
+}
+
+std::pair<uint64_t, std::string>
+CovMapTy::encodeFilenames(const std::optional<ArrayRef<StringRef>> &AccFilesOpt,
+                          bool Compress) const {
+  ArrayRef<std::string> TempFilenames;
+  std::vector<std::string> AccFilenames; // Storage
+
+  if (AccFilesOpt) {
+    AccFilenames = generateAccFilenames(AccFilesOpt);
+    TempFilenames = AccFilenames;
+  } else {
+    assert(this->Filenames);
+    TempFilenames = ArrayRef(*this->Filenames);
+  }
+
+  std::string FilenamesBlob;
+  llvm::raw_string_ostream OS(FilenamesBlob);
+  CoverageFilenamesSectionWriter(TempFilenames).write(OS, Compress);
+
+  return {llvm::IndexedInstrProf::ComputeHash(FilenamesBlob), FilenamesBlob};
+}
+
+Expected<uint64_t> CovFunTy::decode(CovMapByRefTy &CovMapByRef,
+                                    InstrProfSymtab *Symtab,
+                                    const ArrayRef<uint8_t> Content,
+                                    uint64_t Offset, const DecoderParam &Param,
+                                    bool IsLE) {
+  DecoderContext Data(Content, Param, IsLE);
+  Data.seek(Offset);
+
+  uint32_t DataSize;
+  [[maybe_unused]] char CoverageMapping; // Ignored
+
+#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Initializer)                  \
+  if (sizeof(Type) == sizeof(uint64_t))                                        \
+    Name = Data.getU64();                                                      \
+  else if (sizeof(Type) == sizeof(uint32_t))                                   \
+    Name = Data.getU32();                                                      \
+  else                                                                         \
+    assert(sizeof(Type) == sizeof(CoverageMapping) && "Unknown type");
+
+#include "llvm/ProfileData/InstrProfData.inc"
+
+  if (!Data)
+    return Data.takeError();
+
+  if (Data.Detailed)
+    FuncName = Symtab->getFuncOrVarNameIfDefined(*NameRef);
+
+  if (!Data.Raw)
+    NameRef.reset();
+
+  [[maybe_unused]] auto ExpectedEndOffset = Data.tell() + DataSize;
+
+  // Decode body.
+  assert(CovMapByRef.contains(this->FilenamesRef));
+  auto &CovMap = *CovMapByRef[this->FilenamesRef];
+  FileIDs.emplace();
+
+  auto NumFilesOrErr = Data.getULEB128();
+  if (!NumFilesOrErr)
+    return NumFilesOrErr.takeError();
+  for (unsigned I = 0, E = *NumFilesOrErr; I != E; ++I) {
+    if (auto IDOrErr = Data.getULEB128())
+      FileIDs->push_back(*IDOrErr);
+    else
+      return IDOrErr.takeError();
+  }
+
+  auto NumExprOrErr = Data.getULEB128();
+  if (!NumExprOrErr)
+    return NumExprOrErr.takeError();
+  Expressions.resize(*NumExprOrErr);
+  for (auto &[LHS, RHS] : Expressions) {
+    if (auto E = LHS.decode(Data))
+      return std::move(E);
+    if (auto E = RHS.decode(Data))
+      return std::move(E);
+  }
+
+  for (unsigned FileIdx = 0; FileIdx != *NumFilesOrErr; ++FileIdx) {
+    auto NumRegionsOrErr = Data.getULEB128();
+    if (!NumRegionsOrErr)
+      return NumRegionsOrErr.takeError();
+    auto &File = Files.emplace_back();
+    if (Data.Detailed) {
+      File.Index = FileIdx; // Sequential number.
+      File.Filename = (*CovMap.Filenames)[(*FileIDs)[FileIdx]];
+    }
+
+    // Decode subarray.
+    Data.LineStart = 0;
+    for (unsigned I = 0; I != *NumRegionsOrErr; ++I) {
+      auto &Rec = File.Recs.emplace_back();
+      if (auto E = Rec.decode(Data))
+        return std::move(E);
+
+      // Hide either Loc or dLoc.
+      if (!Data.Detailed || Data.dLoc)
+        Rec.Loc.reset();
+      else if (!Data.Raw)
+        Rec.dLoc.reset();
+    }
+  }
+
+  // Hide FileIDs.
+  if (!Data.Raw)
+    FileIDs.reset();
+
+  assert(Data.tell() == ExpectedEndOffset);
+  return Data.tell();
+}
+
+void CovMapTy::encode(raw_ostream &OS) const {
+  auto [FilenamesRef, FilenamesBlob] = encodeFilenames();
+
+  uint32_t NRecords = 0;
+  uint32_t FilenamesSize = FilenamesBlob.size();
+  uint32_t CoverageSize = 0;
+  uint32_t Version =
+      (this->Version ? *this->Version : INSTR_PROF_COVMAP_VERSION);
+  struct {
+#define COVMAP_HEADER(Type, LLVMType, Name, Initializer) Type Name;
+#include "llvm/ProfileData/InstrProfData.inc"
+  } CovMapHeader = {
+#define COVMAP_HEADER(Type, LLVMType, Name, Initializer) Name,
+#include "llvm/ProfileData/InstrProfData.inc"
+  };
+  StringRef HeaderBytes(reinterpret_cast<char *>(&CovMapHeader),
+                        sizeof(CovMapHeader));
+  OS << HeaderBytes;
+
+  // llvm_covmap's alignment
+  FilenamesBlob.resize(llvm::alignTo(FilenamesBlob.size(), sizeof(uint32_t)));
+  OS << FilenamesBlob;
+}
+
+Expected<uint64_t> CovMapTy::decode(const ArrayRef<uint8_t> Content,
+                                    uint64_t Offset, const DecoderParam &Param,
+                                    bool IsLE) {
+  DecoderContext Data(Content, Param, IsLE);
+  Data.seek(Offset);
+
+#define COVMAP_HEADER(Type, LLVMType, Name, Initializer)                       \
+  static_assert(sizeof(Type) == sizeof(uint32_t));                             \
+  Type Name = Data.getU32();
+#include "llvm/ProfileData/InstrProfData.inc"
+  if (!Data)
+    return Data.takeError();
+  assert(NRecords == 0);
+  // +1: uint32_t FilenamesSize;
+  assert(CoverageSize == 0);
+  this->Version = Version;
+
+  // Decode Body -- Filenames.
+  StringRef FnBlob = Data.getBytes(FilenamesSize);
+  if (!Data)
+    return Data.takeError();
+  this->FilenamesRef = MD5Hash(FnBlob);
+  this->Filenames.emplace();
+  if (auto E = RawCoverageFilenamesReader(FnBlob, *this->Filenames)
+                   .read(static_cast<CovMapVersion>(Version)))
+    return E;
+
+  if (Param.Detailed && useWD()) {
+    assert(this->Filenames->size() >= 1);
+    auto FilenamesI = this->Filenames->begin();
+    StringRef WD = *FilenamesI++;
+    if (!WD.empty())
+      this->WD = WD;
+    // Use Filenames as a storage.
+    this->Files.emplace(
+        MutableArrayRef(&*FilenamesI, &*this->Filenames->end()));
+  }
+
+  Offset = Data.tell();
+  return Offset;
+}
+
+void CounterTy::mapping(llvm::yaml::IO &IO) {
+  IO.mapOptional("Tag", Tag);
+  IO.mapOptional("Val", Val);
+  IO.mapOptional("Ref", RefOpt);
+  IO.mapOptional("Sub", SubOpt);
+  IO.mapOptional("Add", AddOpt);
+}
+
+void DecisionTy::mapping(llvm::yaml::IO &IO) {
+  IO.mapRequired("BIdx", BIdx);
+  IO.mapRequired("NCond", NC);
+}
+
+void RecTy::mapping(llvm::yaml::IO &IO) {
+  IO.mapOptional("Loc", Loc);
+  IO.mapOptional("dLoc", dLoc);
+  IO.mapOptional("isGap", isGap);
+  CounterTy::mapping(IO);
+  IO.mapOptional("ExtTag", ExtTag);
+  IO.mapOptional("Expansion", Expansion);
+  IO.mapOptional("Branch", BranchOpt);
+  IO.mapOptional("MCDC", MCDC);
+  IO.mapOptional("Decision", DecisionOpt);
+}
+
+void FileRecsTy::mapping(llvm::yaml::IO &IO) {
+  IO.mapOptional("Index", Index);
+  IO.mapOptional("Filename", Filename);
+  IO.mapRequired("Regions", Recs);
+}
+
+void CovFunTy::mapping(llvm::yaml::IO &IO) {
+  IO.mapOptional("NameRef", NameRef);
+  IO.mapOptional("FuncName", FuncName);
+  IO.mapRequired("FuncHash", FuncHash);
+  IO.mapRequired("FilenamesRef", FilenamesRef);
+  IO.mapOptional("FileIDs", FileIDs);
+  IO.mapRequired("Expressions", Expressions);
+  IO.mapRequired("Files", Files);
+}
+
+void CovMapTy::mapping(llvm::yaml::IO &IO) {
+  IO.mapRequired("FilenamesRef", FilenamesRef);
+  IO.mapOptional("Version", Version);
+
+  if (!WD && !Files)
+    // Suppress this regardless of (Detailed && Raw).
+    // Since it is obviously redundant.
+    IO.mapOptional("Filenames", Filenames);
+
+  IO.mapOptional("WD", WD);
+  IO.mapOptional("Files", Files);
+}
+
+#define ECase(N, X) IO.enumCase(Value, #X, N::X)
+
+void llvm::yaml::ScalarEnumerationTraits<CounterTy::TagTy>::enumeration(
+    llvm::yaml::IO &IO, CounterTy::TagTy &Value) {
+  ECase(CounterTy, Zero);
+  ECase(CounterTy, Ref);
+  ECase(CounterTy, Sub);
+  ECase(CounterTy, Add);
+}
+
+void llvm::yaml::ScalarEnumerationTraits<RecTy::ExtTagTy>::enumeration(
+    llvm::yaml::IO &IO, RecTy::ExtTagTy &Value) {
+  ECase(RecTy, Skip);
+  ECase(RecTy, Branch);
+  ECase(RecTy, Decision);
+  ECase(RecTy, MCDCBranch);
+}
+
+namespace {
+
+struct PrfNamesSection : ELFYAML::CovMapSectionBase {
+  InstrProfSymtab::PrfNamesChunksTy PrfNames;
+
+  PrfNamesSection() { Name = "__llvm_prf_names"; }
+  static bool nameMatches(StringRef Name) { return Name == "__llvm_prf_names"; }
+  static bool classof(const Chunk *S) {
+    return (isa<CovMapSectionBase>(S) && nameMatches(S->Name));
+  }
+
+  void mapping(llvm::yaml::IO &IO) override {
+    IO.mapOptional("PrfNames", PrfNames);
+  }
+
+  Error encode(raw_ostream &OS) const override {
+    for (const auto &Names : PrfNames) {
+      std::string Result;
+      if (auto E =
+              collectGlobalObjectNameStrings(Names,
+                                             /*doCompression=*/false, Result))
+        return E;
+      OS << Result;
+    }
+    return Error::success();
+  }
+};
+
+struct CovMapSection : ELFYAML::CovMapSectionBase {
+  std::vector<CovMapTy> CovMaps;
+
+  CovMapSection() { Name = "__llvm_covmap"; }
+  static bool nameMatches(StringRef Name) { return Name == "__llvm_covmap"; }
+  static bool classof(const Chunk *S) {
+    return (isa<CovMapSectionBase>(S) && nameMatches(S->Name));
+  }
+
+  void mapping(llvm::yaml::IO &IO) override {
+    IO.mapOptional("CovMap", CovMaps);
+  }
+
+  Error decode(ArrayRef<uint8_t> Blob, unsigned AddressAlign,
+               const DecoderParam &Param) {
+    uint64_t Offset = 0;
+
+    while (true) {
+      Offset = llvm::alignTo(Offset, AddressAlign);
+      if (Offset >= Blob.size()) {
+        break;
+      }
+      auto &CovMap = CovMaps.emplace_back();
+      auto Result = CovMap.decode(Blob, Offset, Param);
+      if (!Result) {
+        return Result.takeError();
+      }
+      Offset = *Result;
+    }
+
+    return Error::success();
+  }
+
+  Error encode(raw_ostream &OS) const override {
+    auto BaseOffset = OS.tell();
+    for (const auto &CovMap : CovMaps) {
+      OS.write_zeros(llvm::offsetToAlignment(OS.tell() - BaseOffset,
+                                             llvm::Align(AddressAlign.value)));
+      CovMap.encode(OS);
+    }
+    return Error::success();
+  }
+};
+
+struct CovFunSection : ELFYAML::CovMapSectionBase {
+  std::vector<CovFunTy> CovFuns;
+
+  CovFunSection() { Name = "__llvm_covfun"; }
+  static bool nameMatches(StringRef Name) {
+    return Name.starts_with("__llvm_covfun");
+  }
+  static bool classof(const Chunk *S) {
+    return (isa<CovMapSectionBase>(S) && nameMatches(S->Name));
+  }
+
+  void mapping(llvm::yaml::IO &IO) override {
+    IO.mapOptional("CovFun", CovFuns);
+  }
+
+  static Expected<std::vector<CovFunTy>> decode(CovMapByRefTy &CovMapByRef,
+                                                InstrProfSymtab *Symtab,
+                                                ArrayRef<uint8_t> CovFunA,
+                                                unsigned AddressAlign,
+                                                const DecoderParam &Param) {
+    std::vector<CovFunTy> CovFuns;
+    uint64_t Offset = 0;
+
+    while (true) {
+      Offset = llvm::alignTo(Offset, AddressAlign);
+      if (Offset >= CovFunA.size())
+        break;
+
+      auto &CovFun = CovFuns.emplace_back();
+      auto Result = CovFun.decode(CovMapByRef, Symtab, CovFunA, Offset, Param);
+      if (!Result)
+        return Result.takeError();
+
+      Offset = *Result;
+    }
+
+    return std::move(CovFuns);
+  }
+
+  Error encode(raw_ostream &OS) const override {
+    auto BaseOffset = OS.tell();
+    for (auto [I, CovFun] : enumerate(CovFuns)) {
+      OS.write_zeros(llvm::offsetToAlignment(OS.tell() - BaseOffset,
+                                             llvm::Align(AddressAlign.value)));
+      CovFun.encode(OS);
+    }
+    return Error::success();
+  }
+};
+
+class CovMapFilenamesResolver {
+  DenseMap<uint64_t, SetVector<StringRef>> FilenamesByCovMap;
+  std::vector<CovFunTy *> UnresolvedCovFuns;
+
+protected:
+  CovMapByRefTy CovMapByRef;
+  std::vector<CovMapTy> TempCovMaps; // For Decoder
+
+public:
+  void collectCovMap(std::vector<CovMapTy> &CovMaps) {
+    for (auto &CovMap : CovMaps)
+      CovMapByRef[CovMap.FilenamesRef] = &CovMap;
+  }
+
+  void moveAndCollectCovMap(std::vector<CovMapTy> &&CovMaps) {
+    TempCovMaps = std::move(CovMaps);
+    collectCovMap(TempCovMaps);
+  }
+
+  void collectCovFunFilenames(std::vector<CovFunTy> &CovFuns) {
+    for (auto &CovFun : CovFuns) {
+      auto &Filenames = FilenamesByCovMap[CovFun.FilenamesRef];
+      for (const auto &File : CovFun.Files) {
+        if (!File.Filename)
+          goto skip;
+        Filenames.insert(*File.Filename);
+      }
+      UnresolvedCovFuns.push_back(&CovFun);
+    skip:;
+    }
+  }
+
+  void decMayeResetFilenames(std::vector<CovMapTy> &CovMaps) {
+    for (auto &CovMap : CovMaps) {
+      auto FilenamesI = FilenamesByCovMap.find(CovMap.FilenamesRef);
+      if (FilenamesI == FilenamesByCovMap.end())
+        continue;
+
+      // Calculate FilenamesRef with Filenames from CovFuns.
+      // If matches, hide Filenames from CovMap.
+      auto [AccFilenamesRef, _] =
+          CovMap.encodeFilenames(FilenamesI->second.getArrayRef());
+      if (CovMap.FilenamesRef == AccFilenamesRef) {
+        CovMap.Files.reset();
+        CovMap.Filenames.reset(); // FilenamesI has been invalidated.
+      }
+    }
+  }
+
+  void encFixup() {
+    for (auto &[_, CovMap] : CovMapByRef) {
+      auto FilenamesI = FilenamesByCovMap.find(CovMap->FilenamesRef);
+      if (FilenamesI != FilenamesByCovMap.end()) {
+        // Check Filenames satisfies covfuns
+        DenseSet<StringRef> FilenamesSet;
+        if (CovMap->Files) {
+          for (const auto &Filename : *CovMap->Files)
+            FilenamesSet.insert(Filename);
+        } else if (CovMap->Filenames) {
+          for (const auto &Filename : *CovMap->Filenames)
+            FilenamesSet.insert(Filename);
+        }
+
+        for (const auto &Filename : FilenamesI->second) {
+          if (!FilenamesSet.contains(Filename)) {
+            // If not, regenerate Filenames.
+            CovMap->Files.reset();
+            CovMap->Filenames.reset();
+            break;
+          }
+        }
+      }
+
+      if (!CovMap->Filenames) {
+        // Regenerate.
+        // Use Files if exists.
+        // Use CovFuns (FilenamesI) otherwise.
+        assert(CovMap->Files || FilenamesI != FilenamesByCovMap.end());
+        CovMap->regenerateFilenames(
+            CovMap->Files ? std::nullopt : FilenamesI->second.getArrayRef());
+      }
+      auto [FilenamesRef, FilenamesBlob] = CovMap->encodeFilenames();
+      assert(CovMap->FilenamesRef == FilenamesRef);
+    }
+
+    // Fill FileIDs
+    for (auto *CovFun : UnresolvedCovFuns) {
+      assert(CovMapByRef[CovFun->FilenamesRef]);
+      assert(CovMapByRef[CovFun->FilenamesRef]->Filenames);
+      const auto &CovMapFilenames =
+          *CovMapByRef[CovFun->FilenamesRef]->Filenames;
+      auto &FileIDs = CovFun->FileIDs.emplace();
+      for (const auto &File : CovFun->Files) {
+        auto I = std::find(CovMapFilenames.begin(), CovMapFilenames.end(),
+                           File.Filename);
+        assert(I != CovMapFilenames.end());
+        FileIDs.push_back(std::distance(CovMapFilenames.begin(), I));
+      }
+      assert(CovFun->Files.size() == FileIDs.size());
+    }
+  }
+};
+
+class DecoderImpl : public Decoder, CovMapFilenamesResolver {
+  DecoderParam Param;
+
+  std::unique_ptr<InstrProfSymtab> ProfileNames;
+
+  InstrProfSymtab::PrfNamesChunksTy PrfNames;
+
+  MapVector<uint64_t, std::pair<ArrayRef<uint8_t>, unsigned>> CovFunBlobs;
+  DenseMap<uint64_t, std::vector<CovFunTy>> TempCovFuns;
+
+public:
+  DecoderImpl(const DecoderParam &Param)
+      : Param(Param), ProfileNames(std::make_unique<InstrProfSymtab>()) {
+    enabled = (Param.Detailed || Param.Raw);
+  }
+
+  Error acquire(uint64_t Offset, unsigned AddressAlign, StringRef Name,
+                std::function<Expected<ArrayRef<uint8_t>>()> getSectionContents)
+      override {
+    // Don't register anything.
+    if (!enabled)
+      return Error::success();
+
+    if (PrfNamesSection::nameMatches(Name)) {
+      auto ContentOrErr = getSectionContents();
+      if (!ContentOrErr)
+        return ContentOrErr.takeError();
+      // Decode PrfNames in advance since CovFun depends on it.
+      auto PrfNamesOrErr = ProfileNames->createAndGetList(*ContentOrErr);
+      if (!PrfNamesOrErr)
+        return PrfNamesOrErr.takeError();
+      PrfNames = std::move(*PrfNamesOrErr);
+    } else if (CovMapSection::nameMatches(Name)) {
+      auto ContentOrErr = getSectionContents();
+      if (!ContentOrErr)
+        return ContentOrErr.takeError();
+
+      // Decode CovMaps in advance, since only CovMap knows its Version.
+      // CovMaps is restored (into CovMapSection) later.
+      auto TempCovMap = std::make_unique<CovMapSection>();
+      if (auto E = TempCovMap->decode(*ContentOrErr, AddressAlign, Param))
+        return E;
+      moveAndCollectCovMap(std::move(TempCovMap->CovMaps));
+    } else if (CovFunSection::nameMatches(Name)) {
+      auto ContentOrErr = getSectionContents();
+      if (!ContentOrErr)
+        return ContentOrErr.takeError();
+
+      // Will be decoded after CovMap is met.
+      CovFunBlobs[Offset] = {*ContentOrErr, AddressAlign};
+    }
+
+    return Error::success();
+  }
+
+  Error fixup() override {
+    // Decode CovFun(s) with predecoded PrfNames and CovMap.
+    for (const auto &[Offset, CovFunBlob] : CovFunBlobs) {
+      auto CovFunsOrErr =
+          CovFunSection::decode(CovMapByRef, ProfileNames.get(),
+                                CovFunBlob.first, CovFunBlob.second, Param);
+      if (!CovFunsOrErr)
+        return CovFunsOrErr.takeError();
+      TempCovFuns[Offset] = std::move(*CovFunsOrErr);
+      collectCovFunFilenames(TempCovFuns[Offset]);
+    }
+    return Error::success();
+  }
+
+  Expected<ELFYAML::Section *>
+  make(uint64_t Offset, StringRef Name,
+       std::function<Error(ELFYAML::Section &S)> dumpCommonSection) override {
+    if (PrfNamesSection::nameMatches(Name)) {
+      auto S = std::make_unique<PrfNamesSection>();
+      if (Error E = dumpCommonSection(*S))
+        return std::move(E);
+      S->PrfNames = std::move(PrfNames);
+      return S.release();
+    } else if (CovMapSection::nameMatches(Name)) {
+      auto S = std::make_unique<CovMapSection>();
+      if (Error E = dumpCommonSection(*S))
+        return std::move(E);
+
+      // Store predecoded CovMaps.
+      S->CovMaps = std::move(TempCovMaps);
+
+      // Hide Filenames if it is reproducible from CovFuns.
+      if (Param.Detailed)
+        decMayeResetFilenames(S->CovMaps);
+
+      return S.release();
+    } else if (CovFunSection::nameMatches(Name)) {
+      auto S = std::make_unique<CovFunSection>();
+      if (Error E = dumpCommonSection(*S))
+        return std::move(E);
+
+      assert(S->CovFuns.empty());
+      assert(TempCovFuns.contains(Offset));
+      S->CovFuns = std::move(TempCovFuns[Offset]);
+
+      return S.release();
+    }
+
+    llvm_unreachable("Name didn't match");
+  }
+};
+
+class EncoderImpl : public Encoder, CovMapFilenamesResolver {
+public:
+  void collect(ELFYAML::Chunk *Chunk) override {
+    if (auto S = dyn_cast<CovMapSection>(Chunk)) {
+      collectCovMap(S->CovMaps);
+    } else if (auto S = dyn_cast<CovFunSection>(Chunk)) {
+      collectCovFunFilenames(S->CovFuns);
+    }
+  }
+
+  void fixup() override { encFixup(); }
+};
+} // namespace
+
+std::unique_ptr<Decoder> Decoder::get(const DecoderParam &Param) {
+  return std::make_unique<DecoderImpl>(Param);
+}
+
+std::unique_ptr<Encoder> Encoder::get() {
+  return std::make_unique<EncoderImpl>();
+}
+
+bool covmap::nameMatches(StringRef Name) {
+  return (PrfNamesSection::nameMatches(Name) ||
+          CovMapSection::nameMatches(Name) || CovFunSection::nameMatches(Name));
+}
+
+std::unique_ptr<ELFYAML::Section> covmap::make_unique(StringRef Name) {
+  if (PrfNamesSection::nameMatches(Name))
+    return std::make_unique<PrfNamesSection>();
+  else if (CovMapSection::nameMatches(Name))
+    return std::make_unique<CovMapSection>();
+  else if (CovFunSection::nameMatches(Name))
+    return std::make_unique<CovFunSection>();
+
+  return nullptr;
+}
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::InstrProfSymtab::PrfNamesTy)
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 9ae76a71ede5e..75b5833983872 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/CovMap.h"
 #include "llvm/ObjectYAML/DWARFEmitter.h"
 #include "llvm/ObjectYAML/DWARFYAML.h"
 #include "llvm/ObjectYAML/ELFYAML.h"
@@ -66,6 +67,13 @@ class ContiguousBlobAccumulator {
   uint64_t getOffset() const { return InitialOffset + OS.tell(); }
   void writeBlobToStream(raw_ostream &Out) const { Out << OS.str(); }
 
+  uint64_t checkAndTell(uint64_t Base) {
+    uint64_t Offset = OS.tell() - Base;
+    if (checkLimit(Offset))
+      return Offset;
+    return 0;
+  }
+
   Error takeLimitError() {
     // Request to write 0 bytes to check we did not reach the limit.
     checkLimit(0);
@@ -308,6 +316,9 @@ template <class ELFT> class ELFState {
   void writeSectionContent(Elf_Shdr &SHeader,
                            const ELFYAML::CallGraphProfileSection &Section,
                            ContiguousBlobAccumulator &CBA);
+  void writeSectionContent(Elf_Shdr &SHeader,
+                           const ELFYAML::CovMapSectionBase &Section,
+                           ContiguousBlobAccumulator &CBA);
 
   void writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA);
 
@@ -761,6 +772,13 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
   // valid SHN_UNDEF entry since SHT_NULL == 0.
   SHeaders.resize(Doc.getSections().size());
 
+  auto CovMapEncoder = covmap::Encoder::get();
+  for (auto &Chunk : Doc.Chunks) {
+    if (isa<ELFYAML::CovMapSectionBase>(Chunk.get()))
+      CovMapEncoder->collect(Chunk.get());
+  }
+  CovMapEncoder->fixup();
+
   for (const std::unique_ptr<ELFYAML::Chunk> &D : Doc.Chunks) {
     if (ELFYAML::Fill *S = dyn_cast<ELFYAML::Fill>(D.get())) {
       S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset);
@@ -894,6 +912,8 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
       writeSectionContent(SHeader, *S, CBA);
     } else if (auto S = dyn_cast<ELFYAML::BBAddrMapSection>(Sec)) {
       writeSectionContent(SHeader, *S, CBA);
+    } else if (auto S = dyn_cast<ELFYAML::CovMapSectionBase>(Sec)) {
+      writeSectionContent(SHeader, *S, CBA);
     } else {
       llvm_unreachable("Unknown section type");
     }
@@ -1903,6 +1923,24 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
                     Section.HashValues->size() * 4;
 }
 
+template <class ELFT>
+void ELFState<ELFT>::writeSectionContent(
+    Elf_Shdr &SHeader, const ELFYAML::CovMapSectionBase &Section,
+    ContiguousBlobAccumulator &CBA) {
+  if (Section.Info)
+    SHeader.sh_info = *Section.Info;
+
+  if (Section.Content)
+    return;
+
+  auto &OS = *CBA.getRawOS(0);
+  auto BaseOffset = OS.tell();
+  if (auto E = Section.encode(OS))
+    reportError(std::move(E));
+
+  SHeader.sh_size = CBA.checkAndTell(BaseOffset);
+}
+
 template <class ELFT>
 void ELFState<ELFT>::writeFill(ELFYAML::Fill &Fill,
                                ContiguousBlobAccumulator &CBA) {
diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index 539834fc8d4db..9f4c3ba5d3b76 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -15,6 +15,7 @@
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/ELF.h"
+#include "llvm/ObjectYAML/CovMap.h"
 #include "llvm/Support/ARMEHABI.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -1425,6 +1426,12 @@ static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
   IO.mapOptional("Info", Section.Info);
 }
 
+static void sectionMapping(IO &IO, ELFYAML::CovMapSectionBase &Section) {
+  commonSectionMapping(IO, Section);
+  Section.mapping(IO);
+  IO.mapOptional("Info", Section.Info);
+}
+
 static void sectionMapping(IO &IO, ELFYAML::BBAddrMapSection &Section) {
   commonSectionMapping(IO, Section);
   IO.mapOptional("Content", Section.Content);
@@ -1734,11 +1741,16 @@ void MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::mapping(
       if (ELFYAML::StackSizesSection::nameMatches(Name))
         Section = std::make_unique<ELFYAML::StackSizesSection>();
       else
+        Section = covmap::make_unique(Name);
+
+      if (!Section)
         Section = std::make_unique<ELFYAML::RawContentSection>();
     }
 
     if (auto S = dyn_cast<ELFYAML::RawContentSection>(Section.get()))
       sectionMapping(IO, *S);
+    else if (auto S = dyn_cast<ELFYAML::CovMapSectionBase>(Section.get()))
+      sectionMapping(IO, *S);
     else
       sectionMapping(IO, *cast<ELFYAML::StackSizesSection>(Section.get()));
   }
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index 819ddd02a24ce..93714a5a05a0d 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -535,9 +535,9 @@ Error InstrProfSymtab::addVTableWithName(GlobalVariable &VTable,
 /// \c NameStrings is a string composed of one of more possibly encoded
 /// sub-strings. The substrings are separated by 0 or more zero bytes. This
 /// method decodes the string and calls `NameCallback` for each substring.
-static Error
-readAndDecodeStrings(StringRef NameStrings,
-                     std::function<Error(StringRef)> NameCallback) {
+static Error readAndDecodeStrings(
+    StringRef NameStrings, std::function<Error(StringRef)> NameCallback,
+    std::function<void(bool)> ChunkCallback = [](bool) {}) {
   const uint8_t *P = NameStrings.bytes_begin();
   const uint8_t *EndP = NameStrings.bytes_end();
   while (P < EndP) {
@@ -567,6 +567,7 @@ readAndDecodeStrings(StringRef NameStrings,
       P += UncompressedSize;
     }
     // Now parse the name strings.
+    ChunkCallback(IsCompressed);
     SmallVector<StringRef, 0> Names;
     NameStrings.split(Names, getInstrProfNameSeparator());
     for (StringRef &Name : Names)
@@ -585,6 +586,22 @@ Error InstrProfSymtab::create(StringRef NameStrings) {
       std::bind(&InstrProfSymtab::addFuncName, this, std::placeholders::_1));
 }
 
+Expected<InstrProfSymtab::PrfNamesChunksTy>
+InstrProfSymtab::createAndGetList(ArrayRef<uint8_t> Content) {
+  PrfNamesChunksTy Result;
+  PrfNamesTy *ArrayP = nullptr;
+  if (auto E = readAndDecodeStrings(
+          StringRef(reinterpret_cast<const char *>(Content.data()),
+                    Content.size()),
+          [&](StringRef Name) {
+            ArrayP->emplace_back(Name.str());
+            return addFuncName(Name);
+          },
+          [&](bool IsCompressed) { ArrayP = &Result.emplace_back(); }))
+    return E;
+  return Result;
+}
+
 Error InstrProfSymtab::create(StringRef FuncNameStrings,
                               StringRef VTableNameStrings) {
   if (Error E = readAndDecodeStrings(FuncNameStrings,
diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml
index 9d23dcb67ad2a..7d7f714353a88 100644
--- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml
+++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml
@@ -11,72 +11,525 @@ Sections:
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         D7878914FBE99B074D000000D136449C106D04004C551E9517F40F4F0101000D010715080205020F0016090018001B0D001C009D808080080D001D0104110203040215000A000F19001001858080800819010500081D01030202210006000825001000181001010001
+    CovFun:
+      - FuncName:        simple_loops
+        FuncHash:        0x46D109C4436D1
+        FilenamesRef:    0x4F0FF417951E554C
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-c-general.c
+            Regions:
+              - { dLoc: [ 7, 21, 8, 2 ], Ref: 0 }
+              - { dLoc: [ 2, 15, 0, 22 ], Ref: 1 }
+              - { dLoc: [ 0, 24, 0, 27 ], Ref: 2 }
+              - { dLoc: [ 0, 28, 0, 29 ], isGap: true, Ref: 3 }
+              - { dLoc: [ 0, 29, 1, 4 ], Ref: 3 }
+              - { dLoc: [ 2, 3, 4, 2 ], Ref: 4 }
+              - { dLoc: [ 0, 10, 0, 15 ], Ref: 5 }
+              - { dLoc: [ 0, 16, 1, 5 ], isGap: true, Ref: 6 }
+              - { dLoc: [ 1, 5, 0, 8 ], Ref: 6 }
+              - { dLoc: [ 1, 3, 2, 2 ], Ref: 7 }
+              - { dLoc: [ 0, 6, 0, 8 ], Ref: 8 }
+              - { dLoc: [ 0, 16, 0, 24 ], Ref: 9 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
   - Name:            '__llvm_covfun (1)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         83AD05A5F1438E68EA00000052D33558163C11444C551E9517F40F4F010100260111150E02050113001A09001C001F0D002000A1808080080D00210B040D0109000E15000F009080808008150010020615010B000C21000D008E8080800821000E0010310106008C8080800831000C04063100100015290016009780808008290017020629010B000C35000D008E8080800835000E00102D0106008C808080082D000C02062D010B000C3D000D008E808080083D000E0010100201005B1D010502041D0009000A1D0009000F4D000E000F45001000918080800845001100134901050104490009000A490009000F5D000E000F55001000918080800855001100131002010001
+    CovFun:
+      - FuncName:        conditionals
+        FuncHash:        0x44113C165835D352
+        FilenamesRef:    0x4F0FF417951E554C
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-c-general.c
+            Regions:
+              - { dLoc: [ 17, 21, 14, 2 ], Ref: 0 }
+              - { dLoc: [ 1, 19, 0, 26 ], Ref: 1 }
+              - { dLoc: [ 0, 28, 0, 31 ], Ref: 2 }
+              - { dLoc: [ 0, 32, 0, 33 ], isGap: true, Ref: 3 }
+              - { dLoc: [ 0, 33, 11, 4 ], Ref: 3 }
+              - { dLoc: [ 1, 9, 0, 14 ], Ref: 3 }
+              - { dLoc: [ 0, 15, 0, 16 ], isGap: true, Ref: 5 }
+              - { dLoc: [ 0, 16, 2, 6 ], Ref: 5 }
+              - { dLoc: [ 1, 11, 0, 12 ], Ref: 5 }
+              - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 8 }
+              - { dLoc: [ 0, 14, 0, 16 ], Ref: 8 }
+              - { dLoc: [ 1, 6, 0, 12 ], isGap: true, Ref: 12 }
+              - { dLoc: [ 0, 12, 4, 6 ], Ref: 12 }
+              - { dLoc: [ 0, 16, 0, 21 ], Ref: 12 }
+              - { dLoc: [ 0, 22, 0, 23 ], isGap: true, Ref: 10 }
+              - { dLoc: [ 0, 23, 2, 6 ], Ref: 10 }
+              - { dLoc: [ 1, 11, 0, 12 ], Ref: 10 }
+              - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 13 }
+              - { dLoc: [ 0, 14, 0, 16 ], Ref: 13 }
+              - { dLoc: [ 1, 6, 0, 12 ], isGap: true, Ref: 11 }
+              - { dLoc: [ 0, 12, 2, 6 ], Ref: 11 }
+              - { dLoc: [ 1, 11, 0, 12 ], Ref: 11 }
+              - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 15 }
+              - { dLoc: [ 0, 14, 0, 16 ], Ref: 15 }
+              - { dLoc: [ 2, 1, 0, 98 ], ExtTag: Skip }
+              - { dLoc: [ 1, 5, 2, 4 ], Ref: 7 }
+              - { dLoc: [ 0, 9, 0, 10 ], Ref: 7 }
+              - { dLoc: [ 0, 9, 0, 15 ], Ref: 7 }
+              - { dLoc: [ 0, 14, 0, 15 ], Ref: 19 }
+              - { dLoc: [ 0, 16, 0, 17 ], isGap: true, Ref: 17 }
+              - { dLoc: [ 0, 17, 0, 19 ], Ref: 17 }
+              - { dLoc: [ 1, 5, 1, 4 ], Ref: 18 }
+              - { dLoc: [ 0, 9, 0, 10 ], Ref: 18 }
+              - { dLoc: [ 0, 9, 0, 15 ], Ref: 18 }
+              - { dLoc: [ 0, 14, 0, 15 ], Ref: 23 }
+              - { dLoc: [ 0, 16, 0, 17 ], isGap: true, Ref: 21 }
+              - { dLoc: [ 0, 17, 0, 19 ], Ref: 21 }
+              - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip }
   - Name:            '__llvm_covfun (2)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         0449C70428C57369F80000003D5C2D0E4B13F9274C551E9517F40F4F01010028012114180210020100010101070008050009008A8080800805000A000C100101000109010313020D000A00111100120093808080081100130604110209000F190010018780808008190107000C1D000D0185808080081D010502041D0009000E21000F018780808008210107000F15010402838080800810010100011501030B021500070008290009008A8080800829000A000C10010100012D010309023100060504310109000F3D00100187808080083D0107000D41000E028780808008410207000A35010C0013390015028380808008100101000139010302023900070008490009008A8080800849000A000C1001010001
+    CovFun:
+      - FuncName:        early_exits
+        FuncHash:        0x27F9134B0E2D5C3D
+        FilenamesRef:    0x4F0FF417951E554C
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-c-general.c
+            Regions:
+              - { dLoc: [ 33, 20, 24, 2 ], Ref: 0 }
+              - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 7, 0, 8 ], Ref: 0 }
+              - { dLoc: [ 0, 9, 0, 10 ], isGap: true, Ref: 1 }
+              - { dLoc: [ 0, 10, 0, 12 ], Ref: 1 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 19, 2 ], Ref: 2 }
+              - { dLoc: [ 0, 10, 0, 17 ], Ref: 3 }
+              - { dLoc: [ 0, 18, 0, 19 ], isGap: true, Ref: 4 }
+              - { dLoc: [ 0, 19, 6, 4 ], Ref: 4 }
+              - { dLoc: [ 2, 9, 0, 15 ], Ref: 4 }
+              - { dLoc: [ 0, 16, 1, 7 ], isGap: true, Ref: 6 }
+              - { dLoc: [ 1, 7, 0, 12 ], Ref: 6 }
+              - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 7 }
+              - { dLoc: [ 1, 5, 2, 4 ], Ref: 7 }
+              - { dLoc: [ 0, 9, 0, 14 ], Ref: 7 }
+              - { dLoc: [ 0, 15, 1, 7 ], isGap: true, Ref: 8 }
+              - { dLoc: [ 1, 7, 0, 15 ], Ref: 8 }
+              - { dLoc: [ 1, 4, 2, 3 ], isGap: true, Ref: 5 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 11, 2 ], Ref: 5 }
+              - { dLoc: [ 0, 7, 0, 8 ], Ref: 5 }
+              - { dLoc: [ 0, 9, 0, 10 ], isGap: true, Ref: 10 }
+              - { dLoc: [ 0, 10, 0, 12 ], Ref: 10 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 9, 2 ], Ref: 11 }
+              - { dLoc: [ 0, 6, 5, 4 ], Ref: 12 }
+              - { dLoc: [ 1, 9, 0, 15 ], Ref: 12 }
+              - { dLoc: [ 0, 16, 1, 7 ], isGap: true, Ref: 15 }
+              - { dLoc: [ 1, 7, 0, 13 ], Ref: 15 }
+              - { dLoc: [ 0, 14, 2, 7 ], isGap: true, Ref: 16 }
+              - { dLoc: [ 2, 7, 0, 10 ], Ref: 16 }
+              - { dLoc: [ 1, 12, 0, 19 ], Ref: 13 }
+              - { dLoc: [ 0, 21, 2, 3 ], isGap: true, Ref: 14 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 2, 2 ], Ref: 14 }
+              - { dLoc: [ 0, 7, 0, 8 ], Ref: 14 }
+              - { dLoc: [ 0, 9, 0, 10 ], isGap: true, Ref: 18 }
+              - { dLoc: [ 0, 10, 0, 12 ], Ref: 18 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
   - Name:            '__llvm_covfun (3)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         55947829059F255EB80100001B9C495D3463E1D04C551E9517F40F4F01010046013B0E2F02100201000105010F001409001600190D001A009B808080080D001B040400011402858080800810010100230001050104000009000A15000B008C8080800815000C000E11010402818080800810010100011D010126021D01070008210009008A8080800821000A000C1001010001250103000D25000E0283808080081001010001000103210229000A000B2D000C008D808080082D000D03043501030204350109000A39000B008C8080800839000C000E1002010001310103000D31000E0181808080084101011B024501011A024901011902490207000C4D000D0185808080084D0105000F5100100283808080081001010001510103140255000A000F5900100091808080085900110A04610103090400011006918080800869010501110001120185808080086D0105011200011301858080800871010501115D030402838080800810010100015D0103080275000F0015790017001A7D001B009C808080087D001C0604000115028580808008100101003F0001050304000009000A8501000B008C808080088501000C000E8D01010302048D010109000A9101000B008C808080089101000C000E1002010001
+    CovFun:
+      - FuncName:        jumps
+        FuncHash:        0xD0E163345D499C1B
+        FilenamesRef:    0x4F0FF417951E554C
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-c-general.c
+            Regions:
+              - { dLoc: [ 59, 14, 47, 2 ], Ref: 0 }
+              - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 15, 0, 20 ], Ref: 1 }
+              - { dLoc: [ 0, 22, 0, 25 ], Ref: 2 }
+              - { dLoc: [ 0, 26, 0, 27 ], isGap: true, Ref: 3 }
+              - { dLoc: [ 0, 27, 4, 4 ], Ref: 3 }
+              - { dLoc: [ 1, 20, 2, 5 ], isGap: true, Tag: Zero }
+              - { dLoc: [ 1, 1, 0, 35 ], ExtTag: Skip }
+              - { dLoc: [ 1, 5, 1, 4 ], Tag: Zero }
+              - { dLoc: [ 0, 9, 0, 10 ], Tag: Zero }
+              - { dLoc: [ 0, 11, 0, 12 ], isGap: true, Ref: 5 }
+              - { dLoc: [ 0, 12, 0, 14 ], Ref: 5 }
+              - { dLoc: [ 1, 4, 2, 1 ], isGap: true, Ref: 4 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 1, 38, 2 ], Ref: 7 }
+              - { dLoc: [ 1, 7, 0, 8 ], Ref: 7 }
+              - { dLoc: [ 0, 9, 0, 10 ], isGap: true, Ref: 8 }
+              - { dLoc: [ 0, 10, 0, 12 ], Ref: 8 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 0, 13 ], Ref: 9 }
+              - { dLoc: [ 0, 14, 2, 3 ], isGap: true, Ref: 9 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 33, 2 ], Tag: Zero }
+              - { dLoc: [ 0, 10, 0, 11 ], Ref: 10 }
+              - { dLoc: [ 0, 12, 0, 13 ], isGap: true, Ref: 11 }
+              - { dLoc: [ 0, 13, 3, 4 ], Ref: 11 }
+              - { dLoc: [ 1, 3, 2, 4 ], Ref: 13 }
+              - { dLoc: [ 1, 9, 0, 10 ], Ref: 13 }
+              - { dLoc: [ 0, 11, 0, 12 ], isGap: true, Ref: 14 }
+              - { dLoc: [ 0, 12, 0, 14 ], Ref: 14 }
+              - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 0, 13 ], Ref: 12 }
+              - { dLoc: [ 0, 14, 1, 1 ], isGap: true, Ref: 12 }
+              - { dLoc: [ 1, 1, 27, 2 ], Ref: 16 }
+              - { dLoc: [ 1, 1, 26, 2 ], Ref: 17 }
+              - { dLoc: [ 1, 1, 25, 2 ], Ref: 18 }
+              - { dLoc: [ 2, 7, 0, 12 ], Ref: 18 }
+              - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 19 }
+              - { dLoc: [ 1, 5, 0, 15 ], Ref: 19 }
+              - { dLoc: [ 0, 16, 2, 3 ], isGap: true, Ref: 20 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 20, 2 ], Ref: 20 }
+              - { dLoc: [ 0, 10, 0, 15 ], Ref: 21 }
+              - { dLoc: [ 0, 16, 0, 17 ], isGap: true, Ref: 22 }
+              - { dLoc: [ 0, 17, 10, 4 ], Ref: 22 }
+              - { dLoc: [ 1, 3, 9, 4 ], Ref: 24 }
+              - { dLoc: [ 1, 16, 6, 17 ], isGap: true, Tag: Zero }
+              - { dLoc: [ 1, 5, 1, 17 ], Ref: 26 }
+              - { dLoc: [ 1, 18, 1, 5 ], isGap: true, Tag: Zero }
+              - { dLoc: [ 1, 5, 1, 18 ], Ref: 27 }
+              - { dLoc: [ 1, 19, 1, 5 ], isGap: true, Tag: Zero }
+              - { dLoc: [ 1, 5, 1, 17 ], Ref: 28 }
+              - { dLoc: [ 3, 4, 2, 3 ], isGap: true, Ref: 23 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 8, 2 ], Ref: 23 }
+              - { dLoc: [ 0, 15, 0, 21 ], Ref: 29 }
+              - { dLoc: [ 0, 23, 0, 26 ], Ref: 30 }
+              - { dLoc: [ 0, 27, 0, 28 ], isGap: true, Ref: 31 }
+              - { dLoc: [ 0, 28, 6, 4 ], Ref: 31 }
+              - { dLoc: [ 1, 21, 2, 5 ], isGap: true, Tag: Zero }
+              - { dLoc: [ 1, 1, 0, 63 ], ExtTag: Skip }
+              - { dLoc: [ 1, 5, 3, 4 ], Tag: Zero }
+              - { dLoc: [ 0, 9, 0, 10 ], Tag: Zero }
+              - { dLoc: [ 0, 11, 0, 12 ], isGap: true, Ref: 33 }
+              - { dLoc: [ 0, 12, 0, 14 ], Ref: 33 }
+              - { dLoc: [ 1, 3, 2, 4 ], Ref: 35 }
+              - { dLoc: [ 1, 9, 0, 10 ], Ref: 35 }
+              - { dLoc: [ 0, 11, 0, 12 ], isGap: true, Ref: 36 }
+              - { dLoc: [ 0, 12, 0, 14 ], Ref: 36 }
+              - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip }
   - Name:            '__llvm_covfun (4)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         7129CA3C268292BF4D0100003E688383C9A099004C551E9517F40F4F01010035016C112502100201011C000217028A80808008090103010A05020402838080800810010100620501031C020D003F0046110048004B15004C00CD8080800815004D1704000119148F80808008210105130F21010B000C25000D008E8080800825000E001010010100152D0105100F2D010B000C31000D008E8080800831000E0010350107000C35000D0185808080083901050D0F39010B000C3D000D008E808080083D000E0010410107000F4100100185808080084501050A0F45010B000C49000D008E8080800849000E00104D0107080F000012039180808008550107021155010D000E59000F00908080800859001000125D010900115101080285808080081001010001610105020F61010B0017650018018980808008650109000F1902040383808080081001010121190203020219000700116D00120093808080086D001300151001010001
+    CovFun:
+      - FuncName:        switches
+        FuncHash:        0x99A0C98383683E
+        FilenamesRef:    0x4F0FF417951E554C
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-c-general.c
+            Regions:
+              - { dLoc: [ 108, 17, 37, 2 ], Ref: 0 }
+              - { dLoc: [ 2, 1, 1, 28 ], ExtTag: Skip }
+              - { dLoc: [ 2, 23, 2, 10 ], isGap: true, Tag: Zero }
+              - { dLoc: [ 1, 3, 1, 10 ], Ref: 2 }
+              - { dLoc: [ 2, 4, 2, 3 ], isGap: true, Ref: 1 }
+              - { dLoc: [ 1, 1, 0, 100 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 28, 2 ], Ref: 1 }
+              - { dLoc: [ 0, 63, 0, 70 ], Ref: 3 }
+              - { dLoc: [ 0, 72, 0, 75 ], Ref: 4 }
+              - { dLoc: [ 0, 76, 0, 77 ], isGap: true, Ref: 5 }
+              - { dLoc: [ 0, 77, 23, 4 ], Ref: 5 }
+              - { dLoc: [ 1, 25, 20, 15 ], isGap: true, Tag: Zero }
+              - { dLoc: [ 1, 5, 19, 15 ], Ref: 8 }
+              - { dLoc: [ 1, 11, 0, 12 ], Ref: 8 }
+              - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 9 }
+              - { dLoc: [ 0, 14, 0, 16 ], Ref: 9 }
+              - { dLoc: [ 1, 1, 0, 21 ], ExtTag: Skip }
+              - { dLoc: [ 1, 5, 16, 15 ], Ref: 11 }
+              - { dLoc: [ 1, 11, 0, 12 ], Ref: 11 }
+              - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 12 }
+              - { dLoc: [ 0, 14, 0, 16 ], Ref: 12 }
+              - { dLoc: [ 1, 7, 0, 12 ], Ref: 13 }
+              - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 13 }
+              - { dLoc: [ 1, 5, 13, 15 ], Ref: 14 }
+              - { dLoc: [ 1, 11, 0, 12 ], Ref: 14 }
+              - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 15 }
+              - { dLoc: [ 0, 14, 0, 16 ], Ref: 15 }
+              - { dLoc: [ 1, 7, 0, 15 ], Ref: 16 }
+              - { dLoc: [ 0, 16, 1, 5 ], isGap: true, Ref: 16 }
+              - { dLoc: [ 1, 5, 10, 15 ], Ref: 17 }
+              - { dLoc: [ 1, 11, 0, 12 ], Ref: 17 }
+              - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 18 }
+              - { dLoc: [ 0, 14, 0, 16 ], Ref: 18 }
+              - { dLoc: [ 1, 7, 8, 15 ], Ref: 19 }
+              - { dLoc: [ 0, 18, 3, 17 ], isGap: true, Tag: Zero }
+              - { dLoc: [ 1, 7, 2, 17 ], Ref: 21 }
+              - { dLoc: [ 1, 13, 0, 14 ], Ref: 21 }
+              - { dLoc: [ 0, 15, 0, 16 ], isGap: true, Ref: 22 }
+              - { dLoc: [ 0, 16, 0, 18 ], Ref: 22 }
+              - { dLoc: [ 1, 9, 0, 17 ], Ref: 23 }
+              - { dLoc: [ 1, 8, 2, 5 ], isGap: true, Ref: 20 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 5, 2, 15 ], Ref: 24 }
+              - { dLoc: [ 1, 11, 0, 23 ], Ref: 24 }
+              - { dLoc: [ 0, 24, 1, 9 ], isGap: true, Ref: 25 }
+              - { dLoc: [ 1, 9, 0, 15 ], Ref: 25 }
+              - { dLoc: [ 2, 4, 3, 3 ], isGap: true, Ref: 6 }
+              - { dLoc: [ 1, 1, 1, 33 ], ExtTag: Skip }
+              - { dLoc: [ 2, 3, 2, 2 ], Ref: 6 }
+              - { dLoc: [ 0, 7, 0, 17 ], Ref: 6 }
+              - { dLoc: [ 0, 18, 0, 19 ], isGap: true, Ref: 27 }
+              - { dLoc: [ 0, 19, 0, 21 ], Ref: 27 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
   - Name:            '__llvm_covfun (5)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         3F4D1C6E6087417B32010000D6FF56B8865A69B64C551E9517F40F4F01010031019301131F02050113001909001B001E0D001F00A0808080080D00201C04000115198C80808008190105180C19010B000C1D000D008E808080081D000E00101001010015250105150C25010B000C29000D008E8080800829000E00102D0107000C2D000D018580808008310105120C31010B000C35000D008E8080800835000E0010390107000C39000D03858080800810010101013D02050D0C3D010B000C41000D008E8080800841000E0010450107000C45000D0185808080084901050A0C49010B000C4D000D008E808080084D000E0010510107000C51000D0385808080081001010101550205050C55010B000C59000D008E8080800859000E00105D0107000C5D000D018580808008610105020C61010B000C65000D008E8080800865000E0010690107000C1003010001
+    CovFun:
+      - FuncName:        big_switch
+        FuncHash:        0xB6695A86B856FFD6
+        FilenamesRef:    0x4F0FF417951E554C
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-c-general.c
+            Regions:
+              - { dLoc: [ 147, 19, 31, 2 ], Ref: 0 }
+              - { dLoc: [ 1, 19, 0, 25 ], Ref: 1 }
+              - { dLoc: [ 0, 27, 0, 30 ], Ref: 2 }
+              - { dLoc: [ 0, 31, 0, 32 ], isGap: true, Ref: 3 }
+              - { dLoc: [ 0, 32, 28, 4 ], Ref: 3 }
+              - { dLoc: [ 1, 21, 25, 12 ], isGap: true, Tag: Zero }
+              - { dLoc: [ 1, 5, 24, 12 ], Ref: 6 }
+              - { dLoc: [ 1, 11, 0, 12 ], Ref: 6 }
+              - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 7 }
+              - { dLoc: [ 0, 14, 0, 16 ], Ref: 7 }
+              - { dLoc: [ 1, 1, 0, 21 ], ExtTag: Skip }
+              - { dLoc: [ 1, 5, 21, 12 ], Ref: 9 }
+              - { dLoc: [ 1, 11, 0, 12 ], Ref: 9 }
+              - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 10 }
+              - { dLoc: [ 0, 14, 0, 16 ], Ref: 10 }
+              - { dLoc: [ 1, 7, 0, 12 ], Ref: 11 }
+              - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 11 }
+              - { dLoc: [ 1, 5, 18, 12 ], Ref: 12 }
+              - { dLoc: [ 1, 11, 0, 12 ], Ref: 12 }
+              - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 13 }
+              - { dLoc: [ 0, 14, 0, 16 ], Ref: 13 }
+              - { dLoc: [ 1, 7, 0, 12 ], Ref: 14 }
+              - { dLoc: [ 0, 13, 3, 5 ], isGap: true, Ref: 14 }
+              - { dLoc: [ 1, 1, 1, 1 ], ExtTag: Skip }
+              - { dLoc: [ 2, 5, 13, 12 ], Ref: 15 }
+              - { dLoc: [ 1, 11, 0, 12 ], Ref: 15 }
+              - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 16 }
+              - { dLoc: [ 0, 14, 0, 16 ], Ref: 16 }
+              - { dLoc: [ 1, 7, 0, 12 ], Ref: 17 }
+              - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 17 }
+              - { dLoc: [ 1, 5, 10, 12 ], Ref: 18 }
+              - { dLoc: [ 1, 11, 0, 12 ], Ref: 18 }
+              - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 19 }
+              - { dLoc: [ 0, 14, 0, 16 ], Ref: 19 }
+              - { dLoc: [ 1, 7, 0, 12 ], Ref: 20 }
+              - { dLoc: [ 0, 13, 3, 5 ], isGap: true, Ref: 20 }
+              - { dLoc: [ 1, 1, 1, 1 ], ExtTag: Skip }
+              - { dLoc: [ 2, 5, 5, 12 ], Ref: 21 }
+              - { dLoc: [ 1, 11, 0, 12 ], Ref: 21 }
+              - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 22 }
+              - { dLoc: [ 0, 14, 0, 16 ], Ref: 22 }
+              - { dLoc: [ 1, 7, 0, 12 ], Ref: 23 }
+              - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 23 }
+              - { dLoc: [ 1, 5, 2, 12 ], Ref: 24 }
+              - { dLoc: [ 1, 11, 0, 12 ], Ref: 24 }
+              - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 25 }
+              - { dLoc: [ 0, 14, 0, 16 ], Ref: 25 }
+              - { dLoc: [ 1, 7, 0, 12 ], Ref: 26 }
+              - { dLoc: [ 3, 1, 0, 1 ], ExtTag: Skip }
   - Name:            '__llvm_covfun (6)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         59A48AA8899AA3587200000091E33C8FF36C04004C551E9517F40F4F0101001501B4011A0C02050213001A09001C001F0D002000A1808080080D002108040D0109000E1500120013100101005D0D0109000E1D00120013100101005D0D0109000E0D000900172D0012001725001B001C10010100630D0109000E0D000900173D0012001735001B001C1002010063
+    CovFun:
+      - FuncName:        boolean_operators
+        FuncHash:        0x46CF38F3CE391
+        FilenamesRef:    0x4F0FF417951E554C
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-c-general.c
+            Regions:
+              - { dLoc: [ 180, 26, 12, 2 ], Ref: 0 }
+              - { dLoc: [ 2, 19, 0, 26 ], Ref: 1 }
+              - { dLoc: [ 0, 28, 0, 31 ], Ref: 2 }
+              - { dLoc: [ 0, 32, 0, 33 ], isGap: true, Ref: 3 }
+              - { dLoc: [ 0, 33, 8, 4 ], Ref: 3 }
+              - { dLoc: [ 1, 9, 0, 14 ], Ref: 3 }
+              - { dLoc: [ 0, 18, 0, 19 ], Ref: 5 }
+              - { dLoc: [ 1, 1, 0, 100 ], ExtTag: Skip }
+              - { dLoc: [ 1, 9, 0, 14 ], Ref: 3 }
+              - { dLoc: [ 0, 18, 0, 19 ], Ref: 7 }
+              - { dLoc: [ 1, 1, 0, 100 ], ExtTag: Skip }
+              - { dLoc: [ 1, 9, 0, 14 ], Ref: 3 }
+              - { dLoc: [ 0, 9, 0, 23 ], Ref: 3 }
+              - { dLoc: [ 0, 18, 0, 23 ], Ref: 11 }
+              - { dLoc: [ 0, 27, 0, 28 ], Ref: 9 }
+              - { dLoc: [ 1, 1, 0, 113 ], ExtTag: Skip }
+              - { dLoc: [ 1, 9, 0, 14 ], Ref: 3 }
+              - { dLoc: [ 0, 9, 0, 23 ], Ref: 3 }
+              - { dLoc: [ 0, 18, 0, 23 ], Ref: 15 }
+              - { dLoc: [ 0, 27, 0, 28 ], Ref: 13 }
+              - { dLoc: [ 2, 1, 0, 113 ], ExtTag: Skip }
   - Name:            '__llvm_covfun (7)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         F5953D044B505D139E0000005FD132562FE71EAC4C551E9517F40F4F0101001D01C201150D02100201000111010A000B11000A001511000F0015090016018580808008090105000810010100010D0103070225000A001125000A001C250015001C1D001D0185808080081D01050008100101000121010304023D001100123D0011001C3D0016001C31001E002135002200231001010061390103020255000A001155000A001C550015001C49001E00214D002200231001010061
+    CovFun:
+      - FuncName:        boolop_loops
+        FuncHash:        0xAC1EE72F5632D15F
+        FilenamesRef:    0x4F0FF417951E554C
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-c-general.c
+            Regions:
+              - { dLoc: [ 194, 21, 13, 2 ], Ref: 0 }
+              - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 10, 0, 11 ], Ref: 4 }
+              - { dLoc: [ 0, 10, 0, 21 ], Ref: 4 }
+              - { dLoc: [ 0, 15, 0, 21 ], Ref: 4 }
+              - { dLoc: [ 0, 22, 1, 5 ], isGap: true, Ref: 2 }
+              - { dLoc: [ 1, 5, 0, 8 ], Ref: 2 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 7, 2 ], Ref: 3 }
+              - { dLoc: [ 0, 10, 0, 17 ], Ref: 9 }
+              - { dLoc: [ 0, 10, 0, 28 ], Ref: 9 }
+              - { dLoc: [ 0, 21, 0, 28 ], Ref: 9 }
+              - { dLoc: [ 0, 29, 1, 5 ], isGap: true, Ref: 7 }
+              - { dLoc: [ 1, 5, 0, 8 ], Ref: 7 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 4, 2 ], Ref: 8 }
+              - { dLoc: [ 0, 17, 0, 18 ], Ref: 15 }
+              - { dLoc: [ 0, 17, 0, 28 ], Ref: 15 }
+              - { dLoc: [ 0, 22, 0, 28 ], Ref: 15 }
+              - { dLoc: [ 0, 30, 0, 33 ], Ref: 12 }
+              - { dLoc: [ 0, 34, 0, 35 ], Ref: 13 }
+              - { dLoc: [ 1, 1, 0, 104 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 2, 2 ], Ref: 14 }
+              - { dLoc: [ 0, 10, 0, 17 ], Ref: 21 }
+              - { dLoc: [ 0, 10, 0, 28 ], Ref: 21 }
+              - { dLoc: [ 0, 21, 0, 28 ], Ref: 21 }
+              - { dLoc: [ 0, 30, 0, 33 ], Ref: 18 }
+              - { dLoc: [ 0, 34, 0, 35 ], Ref: 19 }
+              - { dLoc: [ 1, 1, 0, 104 ], ExtTag: Skip }
   - Name:            '__llvm_covfun (8)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         20E5C369BDF15C7940000000D0D60000000000004C551E9517F40F4F0101000B01D1011D0702100201000101010B001109001300948080800809001400150D001800191001010001050103020205000B000C01001000111001010001
+    CovFun:
+      - FuncName:        conditional_operator
+        FuncHash:        0xD6D0
+        FilenamesRef:    0x4F0FF417951E554C
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-c-general.c
+            Regions:
+              - { dLoc: [ 209, 29, 7, 2 ], Ref: 0 }
+              - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 11, 0, 17 ], Ref: 0 }
+              - { dLoc: [ 0, 19, 0, 20 ], isGap: true, Ref: 2 }
+              - { dLoc: [ 0, 20, 0, 21 ], Ref: 2 }
+              - { dLoc: [ 0, 24, 0, 25 ], Ref: 3 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 2, 2 ], Ref: 1 }
+              - { dLoc: [ 0, 11, 0, 12 ], Ref: 1 }
+              - { dLoc: [ 0, 16, 0, 17 ], Ref: 0 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
   - Name:            '__llvm_covfun (9)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         7DE8E7C47096EB425200000092EAF0986287F0784C551E9517F40F4F0101000D01DA01170B02050113001909001B001E0D001F00A0808080080D002009041502080606100101024D15030B00102100110092808080082100120017250018018780808008250107010619010E0013
+    CovFun:
+      - FuncName:        do_fallthrough
+        FuncHash:        0x78F0876298F0EA92
+        FilenamesRef:    0x4F0FF417951E554C
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-c-general.c
+            Regions:
+              - { dLoc: [ 218, 23, 11, 2 ], Ref: 0 }
+              - { dLoc: [ 1, 19, 0, 25 ], Ref: 1 }
+              - { dLoc: [ 0, 27, 0, 30 ], Ref: 2 }
+              - { dLoc: [ 0, 31, 0, 32 ], isGap: true, Ref: 3 }
+              - { dLoc: [ 0, 32, 9, 4 ], Ref: 3 }
+              - { dLoc: [ 2, 8, 6, 6 ], Ref: 5 }
+              - { dLoc: [ 1, 1, 2, 77 ], ExtTag: Skip }
+              - { dLoc: [ 3, 11, 0, 16 ], Ref: 5 }
+              - { dLoc: [ 0, 17, 0, 18 ], isGap: true, Ref: 8 }
+              - { dLoc: [ 0, 18, 0, 23 ], Ref: 8 }
+              - { dLoc: [ 0, 24, 1, 7 ], isGap: true, Ref: 9 }
+              - { dLoc: [ 1, 7, 1, 6 ], Ref: 9 }
+              - { dLoc: [ 1, 14, 0, 19 ], Ref: 6 }
   - Name:            '__llvm_covfun (10)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         FAD58DE7366495DB0A00000018000000000000004C551E9517F40F4F0101000101F501280F02
+    CovFun:
+      - FuncName:        main
+        FuncHash:        0x18
+        FilenamesRef:    0x4F0FF417951E554C
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-c-general.c
+            Regions:
+              - { dLoc: [ 245, 40, 15, 2 ], Ref: 0 }
   - Name:            '__llvm_covfun (11)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         4CB4F49D6737EBF922000000D1460000000000004C551E9517F40F4F0101000501E7011B0302050113001909001B001E0D001F00A0808080080D00200104
+    CovFun:
+      - FuncName:        'branch-c-general.c:static_func'
+        FuncHash:        0x46D1
+        FilenamesRef:    0x4F0FF417951E554C
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-c-general.c
+            Regions:
+              - { dLoc: [ 231, 27, 3, 2 ], Ref: 0 }
+              - { dLoc: [ 1, 19, 0, 25 ], Ref: 1 }
+              - { dLoc: [ 0, 27, 0, 30 ], Ref: 2 }
+              - { dLoc: [ 0, 31, 0, 32 ], isGap: true, Ref: 3 }
+              - { dLoc: [ 0, 32, 1, 4 ], Ref: 3 }
   - Name:            __llvm_covmap
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         0000000017000000000000000600000002140000126272616E63682D632D67656E6572616C2E6300
+    CovMap:
+      - FilenamesRef:    0x4F0FF417951E554C
+        Version:         6
   - Name:            __llvm_prf_names
     Type:            SHT_PROGBITS
     Flags:           [ SHF_ALLOC, SHF_GNU_RETAIN ]
     AddressAlign:    0x1
-    Content:         A6010073696D706C655F6C6F6F707301636F6E646974696F6E616C73016561726C795F6578697473016A756D7073017377697463686573016269675F73776974636801626F6F6C65616E5F6F70657261746F727301626F6F6C6F705F6C6F6F707301636F6E646974696F6E616C5F6F70657261746F7201646F5F66616C6C7468726F756768016D61696E016272616E63682D632D67656E6572616C2E633A7374617469635F66756E63
+    PrfNames:
+      - - simple_loops
+        - conditionals
+        - early_exits
+        - jumps
+        - switches
+        - big_switch
+        - boolean_operators
+        - boolop_loops
+        - conditional_operator
+        - do_fallthrough
+        - main
+        - 'branch-c-general.c:static_func'
   - Type:            SectionHeaderTable
     Sections:
       - Name:            .strtab
@@ -94,84 +547,4 @@ Sections:
       - Name:            '__llvm_covfun (11)'
       - Name:            __llvm_covmap
       - Name:            __llvm_prf_names
-      - Name:            .symtab
-Symbols:
-  - Name:            __llvm_covmap
-    Type:            STT_SECTION
-    Section:         __llvm_covmap
-  - Name:            __llvm_prf_names
-    Type:            STT_SECTION
-    Section:         __llvm_prf_names
-  - Name:            __covrec_79BE9FB148987D7u
-    Type:            STT_OBJECT
-    Section:         __llvm_covfun
-    Binding:         STB_WEAK
-    Size:            0x69
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_688E43F1A505AD83u
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (1)'
-    Binding:         STB_WEAK
-    Size:            0x106
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_6973C52804C74904u
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (2)'
-    Binding:         STB_WEAK
-    Size:            0x114
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_5E259F0529789455u
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (3)'
-    Binding:         STB_WEAK
-    Size:            0x1D4
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_BF9282263CCA2971u
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (4)'
-    Binding:         STB_WEAK
-    Size:            0x169
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_7B4187606E1C4D3Fu
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (5)'
-    Binding:         STB_WEAK
-    Size:            0x14E
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_58A39A89A88AA459u
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (6)'
-    Binding:         STB_WEAK
-    Size:            0x8E
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_135D504B043D95F5u
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (7)'
-    Binding:         STB_WEAK
-    Size:            0xBA
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_795CF1BD69C3E520u
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (8)'
-    Binding:         STB_WEAK
-    Size:            0x5C
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_42EB9670C4E7E87Du
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (9)'
-    Binding:         STB_WEAK
-    Size:            0x6E
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_DB956436E78DD5FAu
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (10)'
-    Binding:         STB_WEAK
-    Size:            0x26
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_F9EB37679DF4B44Cu
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (11)'
-    Binding:         STB_WEAK
-    Size:            0x3E
-    Other:           [ STV_HIDDEN ]
 ...
diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml
index 56f3d4955f4d9..9ea346722b915 100644
--- a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml
+++ b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml
@@ -11,22 +11,139 @@ Sections:
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         F0A0ED2C305C0BB32D02000089B21C19C99E86758F2950E06FBD46E8010100600108194302100701000101010C000E01000C010E01000C020E01000C030E01000C040E25010C000E1D010C000E15010C000E0D010C000E05010C000E100101000101010C000E01000C010E01000C020E01000C030E01000C040E4D010C000E45010C000E3D010C000E35010C000E2D010C000E100101000101010C011001000C031001000C051001000C071001000C091001000D000F69010D000F65010C011065000D000F71010D000F61010C011061000D000F79010D000F5D010C01105D000D000F8101010D000F59010C011059000D000F8901010D000F55010C011055000D000F9101010D000F100101000101010C011001000C031001000C051001000C071001000C091001000D000FAD01010D000FA901010C0110A901000D000FB501010D000FA501010C0110A501000D000FBD01010D000FA101010C0110A101000D000FC501010D000F9D01010C01109D01000D000FCD01010D000F9901010C01109901000D000FD501010D000F10010100010101070008DD010009018580808008DD0101050016E1010017028580808008E101020500161001010001E50101030E02E50100070008E9010009018580808008E90101050016ED010017028580808008ED01020500161001010001F10101030902F10100070008F5010009018580808008F50101050016F9010017028580808008F901020500161001010001FD0101030402FD01000700088102000901858080800881020105001685020017028580808008850202050016
+    CovFun:
+      - FuncName:        _Z4funcii
+        FuncHash:        0x75869EC9191CB289
+        FilenamesRef:    0xE846BD6FE050298F
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-logical-mixed.cpp
+            Regions:
+              - { dLoc: [ 8, 25, 67, 2 ], Ref: 0 }
+              - { dLoc: [ 7, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 12, 0, 14 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 1, 14 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 2, 14 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 3, 14 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 4, 14 ], Ref: 0 }
+              - { dLoc: [ 1, 12, 0, 14 ], Ref: 9 }
+              - { dLoc: [ 1, 12, 0, 14 ], Ref: 7 }
+              - { dLoc: [ 1, 12, 0, 14 ], Ref: 5 }
+              - { dLoc: [ 1, 12, 0, 14 ], Ref: 3 }
+              - { dLoc: [ 1, 12, 0, 14 ], Ref: 1 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 12, 0, 14 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 1, 14 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 2, 14 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 3, 14 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 4, 14 ], Ref: 0 }
+              - { dLoc: [ 1, 12, 0, 14 ], Ref: 19 }
+              - { dLoc: [ 1, 12, 0, 14 ], Ref: 17 }
+              - { dLoc: [ 1, 12, 0, 14 ], Ref: 15 }
+              - { dLoc: [ 1, 12, 0, 14 ], Ref: 13 }
+              - { dLoc: [ 1, 12, 0, 14 ], Ref: 11 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 12, 1, 16 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 3, 16 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 5, 16 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 7, 16 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 9, 16 ], Ref: 0 }
+              - { dLoc: [ 0, 13, 0, 15 ], Ref: 0 }
+              - { dLoc: [ 1, 13, 0, 15 ], Ref: 26 }
+              - { dLoc: [ 1, 12, 1, 16 ], Ref: 25 }
+              - { dLoc: [ 0, 13, 0, 15 ], Ref: 25 }
+              - { dLoc: [ 1, 13, 0, 15 ], Ref: 28 }
+              - { dLoc: [ 1, 12, 1, 16 ], Ref: 24 }
+              - { dLoc: [ 0, 13, 0, 15 ], Ref: 24 }
+              - { dLoc: [ 1, 13, 0, 15 ], Ref: 30 }
+              - { dLoc: [ 1, 12, 1, 16 ], Ref: 23 }
+              - { dLoc: [ 0, 13, 0, 15 ], Ref: 23 }
+              - { dLoc: [ 1, 13, 0, 15 ], Ref: 32 }
+              - { dLoc: [ 1, 12, 1, 16 ], Ref: 22 }
+              - { dLoc: [ 0, 13, 0, 15 ], Ref: 22 }
+              - { dLoc: [ 1, 13, 0, 15 ], Ref: 34 }
+              - { dLoc: [ 1, 12, 1, 16 ], Ref: 21 }
+              - { dLoc: [ 0, 13, 0, 15 ], Ref: 21 }
+              - { dLoc: [ 1, 13, 0, 15 ], Ref: 36 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 12, 1, 16 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 3, 16 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 5, 16 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 7, 16 ], Ref: 0 }
+              - { dLoc: [ 0, 12, 9, 16 ], Ref: 0 }
+              - { dLoc: [ 0, 13, 0, 15 ], Ref: 0 }
+              - { dLoc: [ 1, 13, 0, 15 ], Ref: 43 }
+              - { dLoc: [ 1, 12, 1, 16 ], Ref: 42 }
+              - { dLoc: [ 0, 13, 0, 15 ], Ref: 42 }
+              - { dLoc: [ 1, 13, 0, 15 ], Ref: 45 }
+              - { dLoc: [ 1, 12, 1, 16 ], Ref: 41 }
+              - { dLoc: [ 0, 13, 0, 15 ], Ref: 41 }
+              - { dLoc: [ 1, 13, 0, 15 ], Ref: 47 }
+              - { dLoc: [ 1, 12, 1, 16 ], Ref: 40 }
+              - { dLoc: [ 0, 13, 0, 15 ], Ref: 40 }
+              - { dLoc: [ 1, 13, 0, 15 ], Ref: 49 }
+              - { dLoc: [ 1, 12, 1, 16 ], Ref: 39 }
+              - { dLoc: [ 0, 13, 0, 15 ], Ref: 39 }
+              - { dLoc: [ 1, 13, 0, 15 ], Ref: 51 }
+              - { dLoc: [ 1, 12, 1, 16 ], Ref: 38 }
+              - { dLoc: [ 0, 13, 0, 15 ], Ref: 38 }
+              - { dLoc: [ 1, 13, 0, 15 ], Ref: 53 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 7, 0, 8 ], Ref: 0 }
+              - { dLoc: [ 0, 9, 1, 5 ], isGap: true, Ref: 55 }
+              - { dLoc: [ 1, 5, 0, 22 ], Ref: 55 }
+              - { dLoc: [ 0, 23, 2, 5 ], isGap: true, Ref: 56 }
+              - { dLoc: [ 2, 5, 0, 22 ], Ref: 56 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 14, 2 ], Ref: 57 }
+              - { dLoc: [ 0, 7, 0, 8 ], Ref: 57 }
+              - { dLoc: [ 0, 9, 1, 5 ], isGap: true, Ref: 58 }
+              - { dLoc: [ 1, 5, 0, 22 ], Ref: 58 }
+              - { dLoc: [ 0, 23, 2, 5 ], isGap: true, Ref: 59 }
+              - { dLoc: [ 2, 5, 0, 22 ], Ref: 59 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 9, 2 ], Ref: 60 }
+              - { dLoc: [ 0, 7, 0, 8 ], Ref: 60 }
+              - { dLoc: [ 0, 9, 1, 5 ], isGap: true, Ref: 61 }
+              - { dLoc: [ 1, 5, 0, 22 ], Ref: 61 }
+              - { dLoc: [ 0, 23, 2, 5 ], isGap: true, Ref: 62 }
+              - { dLoc: [ 2, 5, 0, 22 ], Ref: 62 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 4, 2 ], Ref: 63 }
+              - { dLoc: [ 0, 7, 0, 8 ], Ref: 63 }
+              - { dLoc: [ 0, 9, 1, 5 ], isGap: true, Ref: 64 }
+              - { dLoc: [ 1, 5, 0, 22 ], Ref: 64 }
+              - { dLoc: [ 0, 23, 2, 5 ], isGap: true, Ref: 65 }
+              - { dLoc: [ 2, 5, 0, 22 ], Ref: 65 }
   - Name:            '__llvm_covfun (1)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         FAD58DE7366495DB0900000018000000000000008F2950E06FBD46E801010001014F010402
+    CovFun:
+      - FuncName:        main
+        FuncHash:        0x18
+        FilenamesRef:    0xE846BD6FE050298F
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-logical-mixed.cpp
+            Regions:
+              - { dLoc: [ 79, 1, 4, 2 ], Ref: 0 }
   - Name:            __llvm_covmap
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         000000001D0000000000000006000000021A0000186272616E63682D6C6F676963616C2D6D697865642E637070000000
+    CovMap:
+      - FilenamesRef:    0xE846BD6FE050298F
+        Version:         6
   - Name:            __llvm_prf_names
     Type:            SHT_PROGBITS
     Flags:           [ SHF_ALLOC, SHF_GNU_RETAIN ]
     AddressAlign:    0x1
-    Content:         0E005F5A3466756E636969016D61696E
+    PrfNames:
+      - - _Z4funcii
+        - main
   - Type:            SectionHeaderTable
     Sections:
       - Name:            .strtab
@@ -34,24 +151,4 @@ Sections:
       - Name:            '__llvm_covfun (1)'
       - Name:            __llvm_covmap
       - Name:            __llvm_prf_names
-      - Name:            .symtab
-Symbols:
-  - Name:            __llvm_covmap
-    Type:            STT_SECTION
-    Section:         __llvm_covmap
-  - Name:            __llvm_prf_names
-    Type:            STT_SECTION
-    Section:         __llvm_prf_names
-  - Name:            __covrec_B30B5C302CEDA0F0u
-    Type:            STT_OBJECT
-    Section:         __llvm_covfun
-    Binding:         STB_WEAK
-    Size:            0x249
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_DB956436E78DD5FAu
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (1)'
-    Binding:         STB_WEAK
-    Size:            0x25
-    Other:           [ STV_HIDDEN ]
 ...
diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml
index 5c5f62b11863b..00a085c3e660f 100644
--- a/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml
+++ b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml
@@ -11,27 +11,233 @@ Sections:
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         F0A0ED2C305C0BB33F010000D238C8100334540693E696313ECE8F5D15010101010101010101010101010101010101010101001501101911020C010C0011140015001A100101005C1C010C0011100101006224010C001210010100682C010C0012100101006E34010C0012100101007401010A000B01000A001001000A001501000A001A45000F00103D00140015350019001A2D001E001F10010104550201050F001701000F00170105060F00170301070F001F3C00100015440019001E014C0910001501540A100016015C0B1000160201050F001701000F0017010D060F00170301070F001F64001000156C0019001E017409100015017C0A1000160201050F001701000F00170115060F00170301070F001F8401001000158C010019001E019401091000150201050F001701000F0017011D060F00170301070F001F9C0100100015A4010019001E0201050F001701000F00170125060F0017
+    CovFun:
+      - FuncName:        _Z4funcii
+        FuncHash:        0x654340310C838D2
+        FilenamesRef:    0x5D8FCE3E3196E693
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 16, 25, 17, 2 ], Ref: 0 }
+              - { dLoc: [ 1, 12, 0, 17 ], Expansion: 1 }
+              - { dLoc: [ 0, 21, 0, 26 ], Expansion: 2 }
+              - { dLoc: [ 1, 1, 0, 92 ], ExtTag: Skip }
+              - { dLoc: [ 1, 12, 0, 17 ], Expansion: 3 }
+              - { dLoc: [ 1, 1, 0, 98 ], ExtTag: Skip }
+              - { dLoc: [ 1, 12, 0, 18 ], Expansion: 4 }
+              - { dLoc: [ 1, 1, 0, 104 ], ExtTag: Skip }
+              - { dLoc: [ 1, 12, 0, 18 ], Expansion: 5 }
+              - { dLoc: [ 1, 1, 0, 110 ], ExtTag: Skip }
+              - { dLoc: [ 1, 12, 0, 18 ], Expansion: 6 }
+              - { dLoc: [ 1, 1, 0, 116 ], ExtTag: Skip }
+              - { dLoc: [ 1, 10, 0, 11 ], Ref: 0 }
+              - { dLoc: [ 0, 10, 0, 16 ], Ref: 0 }
+              - { dLoc: [ 0, 10, 0, 21 ], Ref: 0 }
+              - { dLoc: [ 0, 10, 0, 26 ], Ref: 0 }
+              - { dLoc: [ 0, 15, 0, 16 ], Ref: 17 }
+              - { dLoc: [ 0, 20, 0, 21 ], Ref: 15 }
+              - { dLoc: [ 0, 25, 0, 26 ], Ref: 13 }
+              - { dLoc: [ 0, 30, 0, 31 ], Ref: 11 }
+              - { dLoc: [ 1, 1, 4, 85 ], ExtTag: Skip }
+          - Index:           1
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 }
+              - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 }
+          - Index:           2
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 6, 15, 0, 23 ], Ref: 1 }
+          - Index:           3
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 7, 15, 0, 31 ], Ref: 0 }
+              - { dLoc: [ 0, 16, 0, 21 ], Expansion: 7 }
+              - { dLoc: [ 0, 25, 0, 30 ], Expansion: 8 }
+          - Index:           4
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 9, 16, 0, 21 ], Expansion: 9 }
+          - Index:           5
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 10, 16, 0, 22 ], Expansion: 10 }
+          - Index:           6
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 11, 16, 0, 22 ], Expansion: 11 }
+          - Index:           7
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 }
+              - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 }
+          - Index:           8
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 6, 15, 0, 23 ], Ref: 3 }
+          - Index:           9
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 7, 15, 0, 31 ], Ref: 0 }
+              - { dLoc: [ 0, 16, 0, 21 ], Expansion: 12 }
+              - { dLoc: [ 0, 25, 0, 30 ], Expansion: 13 }
+          - Index:           10
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 9, 16, 0, 21 ], Expansion: 14 }
+          - Index:           11
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 10, 16, 0, 22 ], Expansion: 15 }
+          - Index:           12
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 }
+              - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 }
+          - Index:           13
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 6, 15, 0, 23 ], Ref: 5 }
+          - Index:           14
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 7, 15, 0, 31 ], Ref: 0 }
+              - { dLoc: [ 0, 16, 0, 21 ], Expansion: 16 }
+              - { dLoc: [ 0, 25, 0, 30 ], Expansion: 17 }
+          - Index:           15
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 9, 16, 0, 21 ], Expansion: 18 }
+          - Index:           16
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 }
+              - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 }
+          - Index:           17
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 6, 15, 0, 23 ], Ref: 7 }
+          - Index:           18
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 7, 15, 0, 31 ], Ref: 0 }
+              - { dLoc: [ 0, 16, 0, 21 ], Expansion: 19 }
+              - { dLoc: [ 0, 25, 0, 30 ], Expansion: 20 }
+          - Index:           19
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 }
+              - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 }
+          - Index:           20
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 6, 15, 0, 23 ], Ref: 9 }
   - Name:            '__llvm_covfun (1)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         B01D983FC67363959E000000039B9E2C8DB865C493E696313ECE8F5D0D01010101010101010101010101000401241A07020C010E0014140018001D1001010365011C0B1000160405080F002624001000152C0018001D3400200025013C0A1000160305070F001F44001000154C0019001E0119060F0017011D050F00170154091000150205050F001705000F00170121060F00170401070F001F01000F001F5C00100015640019001E0201050F001701000F0017010D060F0017
+    CovFun:
+      - FuncName:        _Z5func2ii
+        FuncHash:        0xC465B88D2C9E9B03
+        FilenamesRef:    0x5D8FCE3E3196E693
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 36, 26, 7, 2 ], Ref: 0 }
+              - { dLoc: [ 1, 14, 0, 20 ], Expansion: 1 }
+              - { dLoc: [ 0, 24, 0, 29 ], Expansion: 2 }
+              - { dLoc: [ 1, 1, 3, 108 ], ExtTag: Skip }
+          - Index:           1
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 11, 16, 0, 22 ], Expansion: 3 }
+          - Index:           2
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 8, 15, 0, 38 ], Ref: 1 }
+              - { dLoc: [ 0, 16, 0, 21 ], Expansion: 4 }
+              - { dLoc: [ 0, 24, 0, 29 ], Expansion: 5 }
+              - { dLoc: [ 0, 32, 0, 37 ], Expansion: 6 }
+          - Index:           3
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 10, 16, 0, 22 ], Expansion: 7 }
+          - Index:           4
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 7, 15, 0, 31 ], Ref: 1 }
+              - { dLoc: [ 0, 16, 0, 21 ], Expansion: 8 }
+              - { dLoc: [ 0, 25, 0, 30 ], Expansion: 9 }
+          - Index:           5
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 6, 15, 0, 23 ], Ref: 6 }
+          - Index:           6
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 5, 15, 0, 23 ], Ref: 7 }
+          - Index:           7
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 9, 16, 0, 21 ], Expansion: 10 }
+          - Index:           8
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 5, 15, 0, 23 ], Ref: 1 }
+              - { dLoc: [ 0, 15, 0, 23 ], Ref: 1 }
+          - Index:           9
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 6, 15, 0, 23 ], Ref: 8 }
+          - Index:           10
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 7, 15, 0, 31 ], Ref: 0 }
+              - { dLoc: [ 0, 15, 0, 31 ], Ref: 0 }
+              - { dLoc: [ 0, 16, 0, 21 ], Expansion: 11 }
+              - { dLoc: [ 0, 25, 0, 30 ], Expansion: 12 }
+          - Index:           11
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 }
+              - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 }
+          - Index:           12
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 6, 15, 0, 23 ], Ref: 3 }
   - Name:            '__llvm_covfun (2)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         FAD58DE7366495DB09000000180000000000000093E696313ECE8F5D01010001012F010502
+    CovFun:
+      - FuncName:        main
+        FuncHash:        0x18
+        FilenamesRef:    0x5D8FCE3E3196E693
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-macros.cpp
+            Regions:
+              - { dLoc: [ 47, 1, 5, 2 ], Ref: 0 }
   - Name:            __llvm_covmap
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         0000000016000000000000000600000002130000116272616E63682D6D6163726F732E6370700000
+    CovMap:
+      - FilenamesRef:    0x5D8FCE3E3196E693
+        Version:         6
   - Name:            __llvm_prf_names
     Type:            SHT_PROGBITS
     Flags:           [ SHF_ALLOC, SHF_GNU_RETAIN ]
     AddressAlign:    0x1
-    Content:         19005F5A3466756E636969015F5A3566756E63326969016D61696E
+    PrfNames:
+      - - _Z4funcii
+        - _Z5func2ii
+        - main
   - Type:            SectionHeaderTable
     Sections:
       - Name:            .strtab
@@ -40,30 +246,4 @@ Sections:
       - Name:            '__llvm_covfun (2)'
       - Name:            __llvm_covmap
       - Name:            __llvm_prf_names
-      - Name:            .symtab
-Symbols:
-  - Name:            __llvm_covmap
-    Type:            STT_SECTION
-    Section:         __llvm_covmap
-  - Name:            __llvm_prf_names
-    Type:            STT_SECTION
-    Section:         __llvm_prf_names
-  - Name:            __covrec_B30B5C302CEDA0F0u
-    Type:            STT_OBJECT
-    Section:         __llvm_covfun
-    Binding:         STB_WEAK
-    Size:            0x15B
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_956373C63F981DB0u
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (1)'
-    Binding:         STB_WEAK
-    Size:            0xBA
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_DB956436E78DD5FAu
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (2)'
-    Binding:         STB_WEAK
-    Size:            0x25
-    Other:           [ STV_HIDDEN ]
 ...
diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml
index d4ede6db448e6..03e918953cdc9 100644
--- a/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml
+++ b/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml
@@ -11,32 +11,107 @@ Sections:
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         FAD58DE7366495DB5100000058242991A444920226ED9A40DAABBC6B0101000D011D0C090201010700130500140185808080080501050016090103060209000700170D00180185808080080D01050016110103040211000700171500180185808080081501050016190103010B
+    CovFun:
+      - FuncName:        main
+        FuncHash:        0x29244A491292458
+        FilenamesRef:    0x6BBCABDA409AED26
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-templates.cpp
+            Regions:
+              - { dLoc: [ 29, 12, 9, 2 ], Ref: 0 }
+              - { dLoc: [ 1, 7, 0, 19 ], Ref: 0 }
+              - { dLoc: [ 0, 20, 1, 5 ], isGap: true, Ref: 1 }
+              - { dLoc: [ 1, 5, 0, 22 ], Ref: 1 }
+              - { dLoc: [ 1, 3, 6, 2 ], Ref: 2 }
+              - { dLoc: [ 0, 7, 0, 23 ], Ref: 2 }
+              - { dLoc: [ 0, 24, 1, 5 ], isGap: true, Ref: 3 }
+              - { dLoc: [ 1, 5, 0, 22 ], Ref: 3 }
+              - { dLoc: [ 1, 3, 4, 2 ], Ref: 4 }
+              - { dLoc: [ 0, 7, 0, 23 ], Ref: 4 }
+              - { dLoc: [ 0, 24, 1, 5 ], isGap: true, Ref: 5 }
+              - { dLoc: [ 1, 5, 0, 22 ], Ref: 5 }
+              - { dLoc: [ 1, 3, 1, 11 ], Ref: 6 }
   - Name:            '__llvm_covfun (1)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         5427717259E0E43E38000000113661920200000026ED9A40DAABBC6B01010008010D0F06020101060007050008018580808008050105000D09000E028580808008090205000D0D000E0183808080080D01030102
+    CovFun:
+      - FuncName:        _Z4funcIiEiT_
+        FuncHash:        0x292613611
+        FilenamesRef:    0x6BBCABDA409AED26
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-templates.cpp
+            Regions:
+              - { dLoc: [ 13, 15, 6, 2 ], Ref: 0 }
+              - { dLoc: [ 1, 6, 0, 7 ], Ref: 0 }
+              - { dLoc: [ 0, 8, 1, 5 ], isGap: true, Ref: 1 }
+              - { dLoc: [ 1, 5, 0, 13 ], Ref: 1 }
+              - { dLoc: [ 0, 14, 2, 5 ], isGap: true, Ref: 2 }
+              - { dLoc: [ 2, 5, 0, 13 ], Ref: 2 }
+              - { dLoc: [ 0, 14, 1, 3 ], isGap: true, Ref: 3 }
+              - { dLoc: [ 1, 3, 1, 2 ], Ref: 3 }
   - Name:            '__llvm_covfun (2)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         4B7E22082F0551AA38000000113661920200000026ED9A40DAABBC6B01010008010D0F06020101060007050008018580808008050105000D09000E028580808008090205000D0D000E0183808080080D01030102
+    CovFun:
+      - FuncName:        _Z4funcIbEiT_
+        FuncHash:        0x292613611
+        FilenamesRef:    0x6BBCABDA409AED26
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-templates.cpp
+            Regions:
+              - { dLoc: [ 13, 15, 6, 2 ], Ref: 0 }
+              - { dLoc: [ 1, 6, 0, 7 ], Ref: 0 }
+              - { dLoc: [ 0, 8, 1, 5 ], isGap: true, Ref: 1 }
+              - { dLoc: [ 1, 5, 0, 13 ], Ref: 1 }
+              - { dLoc: [ 0, 14, 2, 5 ], isGap: true, Ref: 2 }
+              - { dLoc: [ 2, 5, 0, 13 ], Ref: 2 }
+              - { dLoc: [ 0, 14, 1, 3 ], isGap: true, Ref: 3 }
+              - { dLoc: [ 1, 3, 1, 2 ], Ref: 3 }
   - Name:            '__llvm_covfun (3)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         AC1440BC3DA3E41A38000000113661920200000026ED9A40DAABBC6B01010008010D0F06020101060007050008018580808008050105000D09000E028580808008090205000D0D000E0183808080080D01030102
+    CovFun:
+      - FuncName:        _Z4funcIfEiT_
+        FuncHash:        0x292613611
+        FilenamesRef:    0x6BBCABDA409AED26
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        branch-templates.cpp
+            Regions:
+              - { dLoc: [ 13, 15, 6, 2 ], Ref: 0 }
+              - { dLoc: [ 1, 6, 0, 7 ], Ref: 0 }
+              - { dLoc: [ 0, 8, 1, 5 ], isGap: true, Ref: 1 }
+              - { dLoc: [ 1, 5, 0, 13 ], Ref: 1 }
+              - { dLoc: [ 0, 14, 2, 5 ], isGap: true, Ref: 2 }
+              - { dLoc: [ 2, 5, 0, 13 ], Ref: 2 }
+              - { dLoc: [ 0, 14, 1, 3 ], isGap: true, Ref: 3 }
+              - { dLoc: [ 1, 3, 1, 2 ], Ref: 3 }
   - Name:            __llvm_covmap
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         0000000019000000000000000600000002160000146272616E63682D74656D706C617465732E637070000000
+    CovMap:
+      - FilenamesRef:    0x6BBCABDA409AED26
+        Version:         6
   - Name:            __llvm_prf_names
     Type:            SHT_PROGBITS
     Flags:           [ SHF_ALLOC, SHF_GNU_RETAIN ]
     AddressAlign:    0x1
-    Content:         2E006D61696E015F5A3466756E6349694569545F015F5A3466756E6349624569545F015F5A3466756E6349664569545F
+    PrfNames:
+      - - main
+        - _Z4funcIiEiT_
+        - _Z4funcIbEiT_
+        - _Z4funcIfEiT_
   - Type:            SectionHeaderTable
     Sections:
       - Name:            .strtab
@@ -46,36 +121,4 @@ Sections:
       - Name:            '__llvm_covfun (3)'
       - Name:            __llvm_covmap
       - Name:            __llvm_prf_names
-      - Name:            .symtab
-Symbols:
-  - Name:            __llvm_covmap
-    Type:            STT_SECTION
-    Section:         __llvm_covmap
-  - Name:            __llvm_prf_names
-    Type:            STT_SECTION
-    Section:         __llvm_prf_names
-  - Name:            __covrec_DB956436E78DD5FAu
-    Type:            STT_OBJECT
-    Section:         __llvm_covfun
-    Binding:         STB_WEAK
-    Size:            0x6D
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_3EE4E05972712754u
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (1)'
-    Binding:         STB_WEAK
-    Size:            0x54
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_AA51052F08227E4Bu
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (2)'
-    Binding:         STB_WEAK
-    Size:            0x54
-    Other:           [ STV_HIDDEN ]
-  - Name:            __covrec_1AE4A33DBC4014ACu
-    Type:            STT_OBJECT
-    Section:         '__llvm_covfun (3)'
-    Binding:         STB_WEAK
-    Size:            0x54
-    Other:           [ STV_HIDDEN ]
 ...
diff --git a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml
index 84b184023f082..cd82f4437ae55 100644
--- a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml
+++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml
@@ -11,35 +11,58 @@ Sections:
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         FAD58DE7366495DB9A0000006733DBEA42F87ED3C60E0B951FF3509D0101001A01060C130210020100010101070008050009008A8080800805000A0204090204008A8080800809000A020410030100010D01030A02110013001A15001C001F19002000A180808008190021020410030100011D010306021D0007000D25000F0090808080082500100015290018001D2101030502210007000D31000F018980808008310109000E350109000E10010100012D0103000B
+    CovFun:
+      - FuncName:        main
+        FuncHash:        0xD37EF842EADB3367
+        FilenamesRef:    0x9D50F31F950B0EC6
+        Expressions:     []
+        Files:
+          - Index:           0
+            Filename:        showLineExecutionCounts.cpp
+            Regions:
+              - { dLoc: [ 6, 12, 19, 2 ], Ref: 0 }
+              - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 7, 0, 8 ], Ref: 0 }
+              - { dLoc: [ 0, 9, 0, 10 ], isGap: true, Ref: 1 }
+              - { dLoc: [ 0, 10, 2, 4 ], Ref: 1 }
+              - { dLoc: [ 2, 4, 0, 10 ], isGap: true, Ref: 2 }
+              - { dLoc: [ 0, 10, 2, 4 ], Ref: 2 }
+              - { dLoc: [ 3, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 10, 2 ], Ref: 3 }
+              - { dLoc: [ 0, 19, 0, 26 ], Ref: 4 }
+              - { dLoc: [ 0, 28, 0, 31 ], Ref: 5 }
+              - { dLoc: [ 0, 32, 0, 33 ], isGap: true, Ref: 6 }
+              - { dLoc: [ 0, 33, 2, 4 ], Ref: 6 }
+              - { dLoc: [ 3, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 6, 2 ], Ref: 7 }
+              - { dLoc: [ 0, 7, 0, 13 ], Ref: 7 }
+              - { dLoc: [ 0, 15, 0, 16 ], isGap: true, Ref: 9 }
+              - { dLoc: [ 0, 16, 0, 21 ], Ref: 9 }
+              - { dLoc: [ 0, 24, 0, 29 ], Ref: 10 }
+              - { dLoc: [ 1, 3, 5, 2 ], Ref: 8 }
+              - { dLoc: [ 0, 7, 0, 13 ], Ref: 8 }
+              - { dLoc: [ 0, 15, 1, 9 ], isGap: true, Ref: 12 }
+              - { dLoc: [ 1, 9, 0, 14 ], Ref: 12 }
+              - { dLoc: [ 1, 9, 0, 14 ], Ref: 13 }
+              - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip }
+              - { dLoc: [ 1, 3, 0, 11 ], Ref: 11 }
   - Name:            __llvm_covmap
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         00000000200000000000000006000000021D00001B73686F774C696E65457865637574696F6E436F756E74732E637070
+    CovMap:
+      - FilenamesRef:    0x9D50F31F950B0EC6
+        Version:         6
   - Name:            __llvm_prf_names
     Type:            SHT_PROGBITS
     Flags:           [ SHF_ALLOC, SHF_GNU_RETAIN ]
     AddressAlign:    0x1
-    Content:         04006D61696E
+    PrfNames:
+      - - main
   - Type:            SectionHeaderTable
     Sections:
       - Name:            .strtab
       - Name:            __llvm_covfun
       - Name:            __llvm_covmap
       - Name:            __llvm_prf_names
-      - Name:            .symtab
-Symbols:
-  - Name:            __llvm_covmap
-    Type:            STT_SECTION
-    Section:         __llvm_covmap
-  - Name:            __llvm_prf_names
-    Type:            STT_SECTION
-    Section:         __llvm_prf_names
-  - Name:            __covrec_DB956436E78DD5FAu
-    Type:            STT_OBJECT
-    Section:         __llvm_covfun
-    Binding:         STB_WEAK
-    Size:            0xB6
-    Other:           [ STV_HIDDEN ]
 ...
diff --git a/llvm/test/tools/llvm-cov/Inputs/yaml.makefile b/llvm/test/tools/llvm-cov/Inputs/yaml.makefile
index 2a256f0cffc0b..449542cee5477 100644
--- a/llvm/test/tools/llvm-cov/Inputs/yaml.makefile
+++ b/llvm/test/tools/llvm-cov/Inputs/yaml.makefile
@@ -2,7 +2,7 @@
 #
 # Usage:
 #   cd /path/to/llvm-project/llvm/test/tools/llvm-cov/Inputs
-#   PATH=/path/to/build/bin:$PATH make -f yaml.makefile
+#   PATH=/path/to/build/bin:$PATH make -f yaml.makefile *.yaml
 
 CFLAGS_COVMAP	= -fcoverage-compilation-dir=. \
 		  -mllvm -runtime-counter-relocation=true \
@@ -34,11 +34,11 @@ CFLAGS_MCDC	= -fcoverage-mcdc
 		--only-section=__llvm_covfun \
 		--only-section=__llvm_covmap \
 		--only-section=__llvm_prf_names \
-		--strip-unneeded \
+		--strip-all \
 		$< $@
 
 %.yaml: %.covmap.o
-	obj2yaml $< > $@
+	obj2yaml --covmap --covmap-dloc $< > $@
 
 %.exe: %.o
 	clang++ -fprofile-instr-generate $^ -o $@
diff --git a/llvm/test/tools/obj2yaml/ELF/covmap.yaml b/llvm/test/tools/obj2yaml/ELF/covmap.yaml
new file mode 100644
index 0000000000000..52d067a8354a1
--- /dev/null
+++ b/llvm/test/tools/obj2yaml/ELF/covmap.yaml
@@ -0,0 +1,160 @@
+# RUN: yaml2obj %s -o %t.o
+# RUN: obj2yaml %t.o | tee %t.plain.yaml | FileCheck %s --check-prefixes=CHECK,PLAIN
+# RUN: obj2yaml --covmap-raw %t.o | tee %t.raw.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,RAWONLY,RAW,DLOC
+# RUN: obj2yaml --covmap --covmap-raw %t.o | tee %t.mixed.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,RAW,DET,LOC,DLOC
+# RUN: obj2yaml --covmap --covmap-dloc %t.o | tee %t.dloc.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,DET,DETONLY,DLOC
+# RUN: obj2yaml --covmap %t.o | tee %t.covmap.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,DET,DETONLY,LOC
+# RUN: sed -E '/^(#.*)?$/d' %s | diff -au %t.covmap.yaml -
+# RUN: yaml2obj %t.plain.yaml -o - | cmp %t.o -
+# RUN: yaml2obj %t.raw.yaml -o - | cmp %t.o -
+# RUN: yaml2obj %t.mixed.yaml -o - | cmp %t.o -
+# RUN: yaml2obj %t.dloc.yaml -o - | cmp %t.o -
+# RUN: yaml2obj %t.covmap.yaml -o - | cmp %t.o -
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_GNU
+  Type:            ET_REL
+  Machine:         EM_X86_64
+  SectionHeaderStringTable: .strtab
+Sections:
+# CHECK:             __llvm_covfun
+  - Name:            __llvm_covfun
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_GNU_RETAIN ]
+    AddressAlign:    0x8
+# PLAIN: Content:
+# COVMAP: CovFun:
+    CovFun:
+# RAW:- NameRef:         0xA72DB7A33048E6A3
+      - FuncName:        _Z4funci
+# COVMAP: FuncHash:      0xAFC772D567676299
+        FuncHash:        0xAFC772D567676299
+        FilenamesRef:    0x70DA2CAFD8CE198E
+# COVMAP: Expressions:
+        Expressions:
+# RAW:    - [ { Tag: Ref, Val: 0 }, { Tag: Ref, Val: 1 } ]
+          - [ { Ref: 0 }, { Ref: 1 } ]
+          - [ { Add: 0 }, { Ref: 2 } ]
+          - [ { Add: 0 }, { Ref: 2 } ]
+          - [ { Add: 0 }, { Ref: 2 } ]
+          - [ { Ref: 0 }, { Ref: 2 } ]
+          - [ { Ref: 0 }, { Ref: 2 } ]
+          - [ { Ref: 0 }, { Ref: 2 } ]
+          - [ { Add: 0 }, { Ref: 5 } ]
+# COVMAP: Files:
+        Files:
+# DET:    - Index:           0
+          - Index:           0
+# DET:      Filename:        func.cpp
+            Filename:        func.cpp
+# COVMAP:   Regions:
+            Regions:
+# LOC:     Loc: [ 3, 17, 14, 2 ]
+# DLOC:   dLoc: [ 3, 17, 11, 2 ]
+# RAW:     Tag: Ref, Val: 0
+# DETONLY: Ref: 0
+              - { Loc: [ 3, 17, 14, 2 ], Ref: 0 }
+# LOC:     Loc: [ 6, 6, 11, 4 ]
+# DLOC    dLoc: [ 3, 6, 5, 4 ]
+# RAW:     Tag: Add, Val: 0
+# DETONLY: Add: 0
+              - { Loc: [ 6, 6, 11, 4 ], Add: 0 }
+# COVMAP: Expansion: 1
+              - { Loc: [ 7, 9, 7, 13 ], Expansion: 1 }
+# COVMAP: isGap: true
+# RAW:      Tag: Ref, Val: 2
+# DETONLY:  Ref: 2
+              - { Loc: [ 7, 23, 8, 7 ], isGap: true, Ref: 2 }
+              - { Loc: [ 8, 7, 8, 16 ], Ref: 2 }
+# COVMAP: isGap: true
+# RAW:      Tag: Sub, Val: 3
+# DETONLY:  Sub: 3
+              - { Loc: [ 8, 17, 10, 5 ], isGap: true, Sub: 3 }
+# COVMAP: ExtTag: Skip
+              - { Loc: [ 9, 1, 9, 1 ], ExtTag: Skip }
+              - { Loc: [ 10, 5, 11, 4 ], Sub: 3 }
+              - { Loc: [ 11, 12, 11, 17 ], Sub: 3 }
+# RAW: ExtTag: Branch, Branch: [ { Tag: Ref, Val: 1 }, { Tag: Sub, Val: 6 } ] }
+# DETONLY: Branch: [ { Ref: 1 }, { Sub: 6 } ]
+              - { Loc: [ 11, 12, 11, 17 ], Branch: [ { Ref: 1 }, { Sub: 6 } ] }
+              - { Loc: [ 11, 19, 12, 3 ], isGap: true, Sub: 6 }
+              - { Loc: [ 12, 3, 12, 11 ], Sub: 6 }
+              - { Loc: [ 12, 12, 13, 3 ], isGap: true, Tag: Zero }
+# LOC:    Loc: [ 13, 3, 13, 12 ]
+# DLOC:  dLoc: [ 1, 3, 0, 12 ]
+# COVMAP: Tag: Zero
+              - { Loc: [ 13, 3, 13, 12 ], Tag: Zero }
+# DET:    - Index:           1
+          - Index:           1
+# DET:      Filename:        func.cpp
+            Filename:        func.cpp
+# COVMAP:   Regions:
+            Regions:
+              - { Loc: [ 1, 17, 1, 41 ], Add: 0 }
+              - { Loc: [ 1, 18, 1, 32 ], Add: 0 }
+# RAW:      ExtTag: Decision
+# COVMAP: Decision: { BIdx: 5, NCond: 3 } }
+              - { Loc: [ 1, 18, 1, 40 ], Decision: { BIdx: 5, NCond: 3 } }
+              - { Loc: [ 1, 19, 1, 22 ], Add: 0 }
+# RAW: ExtTag: MCDCBranch
+# RAW:     Branch: [ { Tag: Sub, Val: 7 }, { Tag: Ref, Val: 5 } ]
+# DETONLY: Branch: [ { Sub: 7 }, { Ref: 5 } ]
+# COVMAP: MCDC: [ 1, 2, 3 ]
+              - { Loc: [ 1, 19, 1, 22 ], Branch: [ { Sub: 7 }, { Ref: 5 } ], MCDC: [ 1, 2, 3 ] }
+              - { Loc: [ 1, 26, 1, 31 ], Ref: 5 }
+              - { Loc: [ 1, 26, 1, 31 ], Branch: [ { Tag: Zero }, { Ref: 6 } ], MCDC: [ 3, 2, 0 ] }
+              - { Loc: [ 1, 36, 1, 40 ], Ref: 3 }
+              - { Loc: [ 1, 36, 1, 40 ], Branch: [ { Ref: 4 }, { Tag: Zero } ], MCDC: [ 2, 0, 0 ] }
+# CHECK:             __llvm_covmap
+  - Name:            __llvm_covmap
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_GNU_RETAIN ]
+    AddressAlign:    0x8
+# PLAIN: Content:
+# COVMAP: CovMap:
+    CovMap:
+# COVMAP: - FilenamesRef:    0x70DA2CAFD8CE198E
+      - FilenamesRef:    0x70DA2CAFD8CE198E
+# COVMAP: Version:
+        Version:         6
+# RAWONLY: Filenames:
+# RAWONLY:    - ''
+# RAWONLY:    - func.cpp
+# CHECK:             __llvm_prf_names
+  - Name:            __llvm_prf_names
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_GNU_RETAIN ]
+    AddressAlign:    0x1
+# PLAIN-NOT: CovFun:
+# PLAIN-NOT: CovMap:
+# PLAIN-NOT: PrfNames:
+# PLAIN: Content:
+# CovMap: ProfNames
+    PrfNames:
+# CovMap: - - _Z4funci
+      - - _Z4funci
+  - Type:            SectionHeaderTable
+    Sections:
+      - Name:            .strtab
+      - Name:            __llvm_covfun
+      - Name:            __llvm_covmap
+      - Name:            __llvm_prf_names
+...
+
+# #define EXPR(x) (((x) || false) && true)
+#
+# int func(int a) {
+#   int r = 0;
+#   int i = 0;
+#   do {
+#     if (EXPR(30 <= i))
+#       return -1;
+#
+#     r += i++;
+#   } while (i < a);
+#   return r;
+#   return -1;
+# }
diff --git a/llvm/test/tools/obj2yaml/help.test b/llvm/test/tools/obj2yaml/help.test
index 72e8e75b7d158..4f85a255f904d 100644
--- a/llvm/test/tools/obj2yaml/help.test
+++ b/llvm/test/tools/obj2yaml/help.test
@@ -7,5 +7,6 @@
 # CHECK: OVERVIEW: Dump a YAML description from an object file
 # CHECK: USAGE: obj2yaml{{(.exe)?}} [options] <input file>{{$}}
 # CHECK: OPTIONS:
+# CATEG: ELF Options:
 # CATEG: Generic Options:
 # CATEG: obj2yaml Options:
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index b1c8032ea2192..39f50fb05ef6d 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -11,8 +11,10 @@
 #include "llvm/ADT/Twine.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/Object/ELFObjectFile.h"
+#include "llvm/ObjectYAML/CovMap.h"
 #include "llvm/ObjectYAML/DWARFYAML.h"
 #include "llvm/ObjectYAML/ELFYAML.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/DataExtractor.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -21,6 +23,18 @@
 
 using namespace llvm;
 
+cl::OptionCategory ELFCat("ELF Options");
+
+static cl::opt<bool>
+    CovMapDetailed("covmap", cl::desc("Dump detailed YAML in Coverage Map."),
+                   cl::cat(ELFCat));
+static cl::opt<bool> CovMapRaw("covmap-raw",
+                               cl::desc("Dump raw YAML in Coverage Map."),
+                               cl::cat(ELFCat));
+static cl::opt<bool> CovMapDLoc("covmap-dloc",
+                                cl::desc("Prefer dLoc thatn absolute Loc."),
+                                cl::cat(ELFCat));
+
 namespace {
 
 template <class ELFT>
@@ -97,6 +111,8 @@ class ELFDumper {
   dumpStackSizesSection(const Elf_Shdr *Shdr);
   Expected<ELFYAML::BBAddrMapSection *>
   dumpBBAddrMapSection(const Elf_Shdr *Shdr);
+  Expected<ELFYAML::Section *> dumpCovMap(const Elf_Shdr *Shdr, StringRef Name,
+                                          covmap::Decoder *CovMapDecoder);
   Expected<ELFYAML::RawContentSection *>
   dumpPlaceholderSection(const Elf_Shdr *Shdr);
 
@@ -580,6 +596,31 @@ ELFDumper<ELFT>::dumpSections() {
     return Error::success();
   };
 
+  coverage::yaml::DecoderParam Param;
+  Param.Detailed = CovMapDetailed;
+  Param.Raw = CovMapRaw;
+  Param.dLoc = CovMapDLoc;
+  auto CovMapDecoder = covmap::Decoder::get(Param);
+  if (covmap::Decoder::enabled) {
+    // Look up covmap-related sections.
+    for (const auto &Sec : Sections) {
+      if (Sec.sh_type != ELF::SHT_PROGBITS)
+        continue;
+
+      auto NameOrErr = Obj.getSectionName(Sec);
+      if (!NameOrErr)
+        return NameOrErr.takeError();
+
+      if (auto E = CovMapDecoder->acquire(
+              Sec.sh_offset, Sec.sh_addralign, *NameOrErr,
+              [&] { return Obj.getSectionContents(Sec); }))
+        return std::move(E);
+    }
+
+    if (auto E = CovMapDecoder->fixup())
+      return std::move(E);
+  }
+
   auto GetDumper = [this](unsigned Type)
       -> std::function<Expected<ELFYAML::Chunk *>(const Elf_Shdr *)> {
     if (Obj.getHeader().e_machine == ELF::EM_ARM && Type == ELF::SHT_ARM_EXIDX)
@@ -661,6 +702,10 @@ ELFDumper<ELFT>::dumpSections() {
         if (Error E = Add(dumpStackSizesSection(&Sec)))
           return std::move(E);
         continue;
+      } else if (covmap::Decoder::enabled && covmap::nameMatches(*NameOrErr)) {
+        if (Error E = Add(dumpCovMap(&Sec, *NameOrErr, CovMapDecoder.get())))
+          return std::move(E);
+        continue;
       }
     }
 
@@ -1662,6 +1707,15 @@ ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) {
   return S.release();
 }
 
+template <class ELFT>
+Expected<ELFYAML::Section *>
+ELFDumper<ELFT>::dumpCovMap(const Elf_Shdr *Shdr, StringRef Name,
+                            covmap::Decoder *CovMapDecoder) {
+  return CovMapDecoder->make(Shdr->sh_offset, Name, [&](ELFYAML::Section &S) {
+    return dumpCommonSection(Shdr, S);
+  });
+}
+
 template <class ELFT>
 static Error elf2yaml(raw_ostream &Out, const object::ELFFile<ELFT> &Obj,
                       std::unique_ptr<DWARFContext> DWARFCtx) {
@@ -1671,7 +1725,8 @@ static Error elf2yaml(raw_ostream &Out, const object::ELFFile<ELFT> &Obj,
     return YAMLOrErr.takeError();
 
   std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get());
-  yaml::Output Yout(Out);
+  yaml::Output Yout(Out, nullptr, /*WrapColumn*/
+                    (covmap::Decoder::enabled ? 160 : 70));
   Yout << *YAML;
 
   return Error::success();
diff --git a/llvm/tools/obj2yaml/obj2yaml.cpp b/llvm/tools/obj2yaml/obj2yaml.cpp
index 63c8cc55ee2d4..ecc9f7eed49ff 100644
--- a/llvm/tools/obj2yaml/obj2yaml.cpp
+++ b/llvm/tools/obj2yaml/obj2yaml.cpp
@@ -101,7 +101,7 @@ static void reportError(StringRef Input, Error Err) {
 
 int main(int argc, char *argv[]) {
   InitLLVM X(argc, argv);
-  cl::HideUnrelatedOptions(Cat);
+  cl::HideUnrelatedOptions({&Cat, &ELFCat});
   cl::ParseCommandLineOptions(
       argc, argv, "Dump a YAML description from an object file", nullptr,
       nullptr, /*LongOptionsUseDoubleDash=*/true);
diff --git a/llvm/tools/obj2yaml/obj2yaml.h b/llvm/tools/obj2yaml/obj2yaml.h
index 03d7db5317acd..8a10be085eefc 100644
--- a/llvm/tools/obj2yaml/obj2yaml.h
+++ b/llvm/tools/obj2yaml/obj2yaml.h
@@ -16,11 +16,15 @@
 #include "llvm/Object/Minidump.h"
 #include "llvm/Object/Wasm.h"
 #include "llvm/Object/XCOFFObjectFile.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/MemoryBufferRef.h"
 #include "llvm/Support/raw_ostream.h"
 #include <system_error>
 
 enum RawSegments : unsigned { none = 0, data = 1, linkedit = 1 << 1 };
+
+extern llvm::cl::OptionCategory ELFCat;
+
 std::error_code coff2yaml(llvm::raw_ostream &Out,
                           const llvm::object::COFFObjectFile &Obj);
 llvm::Error elf2yaml(llvm::raw_ostream &Out,
diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
index 2f50dfb1c5802..10ef327e02b9a 100644
--- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
@@ -1124,9 +1124,11 @@ cc_library(
     copts = llvm_copts,
     deps = [
         ":BinaryFormat",
+        ":Coverage",
         ":DebugInfoCodeView",
         ":MC",
         ":Object",
+        ":ProfileData",
         ":Support",
         ":TargetParser",
     ],

>From 5aac44a3baf2c9abccd95fde5a7d01d380b02736 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Mon, 17 Feb 2025 21:43:59 +0900
Subject: [PATCH 2/6] Reformat.

---
 llvm/lib/ObjectYAML/ELFYAML.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index 9f4c3ba5d3b76..0b7cead2d6d19 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -20,8 +20,8 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MipsABIFlags.h"
-#include "llvm/Support/YAMLTraits.h"
 #include "llvm/Support/WithColor.h"
+#include "llvm/Support/YAMLTraits.h"
 #include <cassert>
 #include <cstdint>
 #include <optional>

>From e0efeaa04e1b3770473134dc540f6e716178ab67 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Mon, 17 Feb 2025 21:47:47 +0900
Subject: [PATCH 3/6] Prune else

---
 llvm/include/llvm/ObjectYAML/CovMap.h | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/llvm/include/llvm/ObjectYAML/CovMap.h b/llvm/include/llvm/ObjectYAML/CovMap.h
index fa9492fc1ee72..e7a03a632e3e4 100644
--- a/llvm/include/llvm/ObjectYAML/CovMap.h
+++ b/llvm/include/llvm/ObjectYAML/CovMap.h
@@ -56,29 +56,25 @@ template <typename T, typename Vec = std::vector<T>> class VectorOrRef {
   iterator begin() {
     if (auto *V = std::get_if<Vec>(&Array))
       return &V->front();
-    else
-      return &std::get<Ref>(Array).front();
+    return &std::get<Ref>(Array).front();
   }
 
   iterator end() {
     if (auto *V = std::get_if<Vec>(&Array))
       return &V->back() + 1;
-    else
-      return &std::get<Ref>(Array).back() + 1;
+    return &std::get<Ref>(Array).back() + 1;
   }
 
   size_t size() const {
     if (const auto *V = std::get_if<Vec>(&Array))
       return V->size();
-    else
-      return std::get<Ref>(Array).size();
+    return std::get<Ref>(Array).size();
   }
 
   T &operator[](int Idx) {
     if (auto *V = std::get_if<Vec>(&Array))
       return (*V)[Idx];
-    else
-      return std::get<Ref>(Array)[Idx];
+    return std::get<Ref>(Array)[Idx];
   }
 
   void resize(size_t Size) { std::get<Vec>(Array).resize(Size); }

>From ad569f76579985cd7df2a9db4022fb5ffdc2d70e Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Mon, 17 Feb 2025 21:49:59 +0900
Subject: [PATCH 4/6] --covmap-dloc

---
 llvm/tools/obj2yaml/elf2yaml.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index 39f50fb05ef6d..9f21c2b67a858 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -32,7 +32,7 @@ static cl::opt<bool> CovMapRaw("covmap-raw",
                                cl::desc("Dump raw YAML in Coverage Map."),
                                cl::cat(ELFCat));
 static cl::opt<bool> CovMapDLoc("covmap-dloc",
-                                cl::desc("Prefer dLoc thatn absolute Loc."),
+                                cl::desc("Prefer dLoc over absolute Loc."),
                                 cl::cat(ELFCat));
 
 namespace {

>From f21cb946a2f10eda966e1d94d1611b7aec30f167 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Mon, 17 Feb 2025 22:12:31 +0900
Subject: [PATCH 5/6] Workaround "Unsupported: 'diff': option -a not
 recognized"

---
 llvm/test/tools/obj2yaml/ELF/covmap.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/tools/obj2yaml/ELF/covmap.yaml b/llvm/test/tools/obj2yaml/ELF/covmap.yaml
index 52d067a8354a1..838e85ca0c9a0 100644
--- a/llvm/test/tools/obj2yaml/ELF/covmap.yaml
+++ b/llvm/test/tools/obj2yaml/ELF/covmap.yaml
@@ -4,7 +4,7 @@
 # RUN: obj2yaml --covmap --covmap-raw %t.o | tee %t.mixed.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,RAW,DET,LOC,DLOC
 # RUN: obj2yaml --covmap --covmap-dloc %t.o | tee %t.dloc.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,DET,DETONLY,DLOC
 # RUN: obj2yaml --covmap %t.o | tee %t.covmap.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,DET,DETONLY,LOC
-# RUN: sed -E '/^(#.*)?$/d' %s | diff -au %t.covmap.yaml -
+# RUN: sed -E '/^(#.*)?$/d' %s | diff -c %t.covmap.yaml -
 # RUN: yaml2obj %t.plain.yaml -o - | cmp %t.o -
 # RUN: yaml2obj %t.raw.yaml -o - | cmp %t.o -
 # RUN: yaml2obj %t.mixed.yaml -o - | cmp %t.o -

>From e1586c723b271c0fba26494a44126a84394449a2 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Tue, 18 Feb 2025 09:20:27 +0900
Subject: [PATCH 6/6] Update covmap.yaml: What's DIFF.EXE on buildkite?

---
 llvm/test/tools/obj2yaml/ELF/covmap.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/tools/obj2yaml/ELF/covmap.yaml b/llvm/test/tools/obj2yaml/ELF/covmap.yaml
index 838e85ca0c9a0..fc77a3d02f909 100644
--- a/llvm/test/tools/obj2yaml/ELF/covmap.yaml
+++ b/llvm/test/tools/obj2yaml/ELF/covmap.yaml
@@ -4,7 +4,7 @@
 # RUN: obj2yaml --covmap --covmap-raw %t.o | tee %t.mixed.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,RAW,DET,LOC,DLOC
 # RUN: obj2yaml --covmap --covmap-dloc %t.o | tee %t.dloc.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,DET,DETONLY,DLOC
 # RUN: obj2yaml --covmap %t.o | tee %t.covmap.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,DET,DETONLY,LOC
-# RUN: sed -E '/^(#.*)?$/d' %s | diff -c %t.covmap.yaml -
+# RUN: sed -E '/^(#.*)?$/d' %s | diff %t.covmap.yaml -
 # RUN: yaml2obj %t.plain.yaml -o - | cmp %t.o -
 # RUN: yaml2obj %t.raw.yaml -o - | cmp %t.o -
 # RUN: yaml2obj %t.mixed.yaml -o - | cmp %t.o -



More information about the llvm-commits mailing list