[llvm] [llvm-dwp] Replace MCStreamer with direct ELF writer for zero-copy output (PR #192112)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 14 11:48:24 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-debuginfo
Author: Farid Zakaria (fzakaria)
<details>
<summary>Changes</summary>
Replace the MCStreamer-based output pipeline with a lightweight direct ELF writer (DWPWriter). Section data is stored as zero-copy StringRef chunks pointing to the mmap'd input files, and written as a minimal ELF64 relocatable object directly to disk.
## Rationale
The MCStreamer pipeline copies all section data into 16KB MCDataFragment blocks, accumulates them in memory, then writes everything out during MCAssembler::Finish(). This can be cause lots of memory pressure and slow down llvm-dwp.
For instance, on a 3.3GB DWP file, this translates to rougly ~3.3GB of heap allocation and two full copies of the data.
The new DWPWriter avoids this via:
- emitBytes() stores a StringRef chunk (zero-copy, no allocation)
- emitIntValue() writes to a small per-section buffer (index tables)
- writeELF() streams chunks directly from input mmap to output file
- for single-input DWP files, string deduplication is also skipped since all strings are already unique. (minor optimization)
Bonus: this also removes all MC library dependencies from llvm-dwp (AllTargetsCodeGens, AllTargetsDescs, AllTargetsInfos, MC, TargetParser), reducing the binary size.
## Benchmark
I benchmarked on a 3.3GB production DWP file (8638 CUs, ~981MB .debug_str.dwo):
Results:
Before: 23.6s wall (19.6s user, 3.9s sys)
After: 6.0s wall (3.0s user, 2.9s sys)
**3.9x** wall time improvement, 6x fewer page faults (178K vs ~1M).
---
Patch is 39.47 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/192112.diff
6 Files Affected:
- (modified) llvm/include/llvm/DWP/DWP.h (+88-35)
- (modified) llvm/include/llvm/DWP/DWPStringPool.h (+10-31)
- (modified) llvm/lib/DWP/CMakeLists.txt (-1)
- (modified) llvm/lib/DWP/DWP.cpp (+312-112)
- (modified) llvm/tools/llvm-dwp/CMakeLists.txt (-5)
- (modified) llvm/tools/llvm-dwp/llvm-dwp.cpp (+7-93)
``````````diff
diff --git a/llvm/include/llvm/DWP/DWP.h b/llvm/include/llvm/DWP/DWP.h
index 67c73afbfe5ac..af4463ae81377 100644
--- a/llvm/include/llvm/DWP/DWP.h
+++ b/llvm/include/llvm/DWP/DWP.h
@@ -4,11 +4,10 @@
#include "DWPStringPool.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
-#include "llvm/MC/MCSection.h"
-#include "llvm/MC/MCStreamer.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
@@ -16,6 +15,8 @@
#include <vector>
namespace llvm {
+class raw_pwrite_stream;
+
enum OnCuIndexOverflow {
HardStop,
SoftStop,
@@ -28,6 +29,88 @@ enum Dwarf64StrOffsetsPromotion {
Always, ///< Always emit .debug_str_offsets talbes as DWARF64 for testing.
};
+/// Section identifiers for DWP output.
+enum DWPSectionId : unsigned {
+ DS_Info,
+ DS_Types,
+ DS_Abbrev,
+ DS_Line,
+ DS_Loc,
+ DS_Loclists,
+ DS_Rnglists,
+ DS_Macro,
+ DS_Str,
+ DS_StrOffsets,
+ DS_CUIndex,
+ DS_TUIndex,
+ DS_NumSections
+};
+
+/// Direct ELF writer for DWP output, bypassing MCStreamer.
+///
+/// Section data is stored as zero-copy StringRef chunks pointing to the
+/// mmap'd input files, plus an inline buffer for constructed data
+/// (emitIntValue). This avoids copying gigabytes of debug section data
+/// through the MC infrastructure (MCContext, MCAssembler, MCDataFragment
+/// allocation, layout, etc.).
+class LLVM_ABI DWPWriter {
+ /// Per-section storage: zero-copy chunks + inline buffer for small writes.
+ struct SectionData {
+ SmallVector<StringRef, 4> Chunks; // zero-copy refs to input data
+ SmallVector<char, 0> Buffer; // for emitIntValue / constructed data
+
+ uint64_t totalSize() const {
+ uint64_t Size = 0;
+ for (auto &C : Chunks)
+ Size += C.size();
+ Size += Buffer.size();
+ return Size;
+ }
+
+ bool empty() const { return Chunks.empty() && Buffer.empty(); }
+
+ void writeTo(raw_ostream &OS) const {
+ for (auto &C : Chunks)
+ OS.write(C.data(), C.size());
+ if (!Buffer.empty())
+ OS.write(Buffer.data(), Buffer.size());
+ }
+ };
+
+ SectionData Sections[DS_NumSections];
+ DWPSectionId CurrentSection = DS_Info;
+ uint16_t ELFMachine = 0;
+ uint8_t ELFOSABI = 0;
+
+public:
+ DWPWriter() = default;
+
+ void setMachine(uint16_t Machine) { ELFMachine = Machine; }
+ void setOSABI(uint8_t OSABI) { ELFOSABI = OSABI; }
+
+ SmallVectorImpl<char> &getSectionBuffer(DWPSectionId Id) {
+ return Sections[Id].Buffer;
+ }
+
+ void switchSection(DWPSectionId Id) { CurrentSection = Id; }
+
+ /// Zero-copy: stores a reference to the input data without copying.
+ void emitBytes(StringRef Data) {
+ if (!Data.empty())
+ Sections[CurrentSection].Chunks.push_back(Data);
+ }
+
+ void emitIntValue(uint64_t Value, unsigned Size) {
+ auto &Buf = Sections[CurrentSection].Buffer;
+ for (unsigned I = 0; I < Size; ++I) {
+ Buf.push_back(static_cast<char>(Value & 0xff));
+ Value >>= 8;
+ }
+ }
+
+ Error writeELF(raw_pwrite_stream &OS);
+};
+
struct UnitIndexEntry {
DWARFUnitIndex::Entry::SectionContribution Contributions[8];
std::string Name;
@@ -73,45 +156,15 @@ struct CompileUnitIdentifiers {
const char *DWOName = "";
};
-LLVM_ABI Error write(MCStreamer &Out, ArrayRef<std::string> Inputs,
+LLVM_ABI Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
OnCuIndexOverflow OverflowOptValue,
- Dwarf64StrOffsetsPromotion StrOffsetsOptValue);
+ Dwarf64StrOffsetsPromotion StrOffsetsOptValue,
+ raw_pwrite_stream *OS = nullptr);
typedef std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLengths;
-LLVM_ABI Error handleSection(
- const StringMap<std::pair<MCSection *, DWARFSectionKind>> &KnownSections,
- const MCSection *StrSection, const MCSection *StrOffsetSection,
- const MCSection *TypesSection, const MCSection *CUIndexSection,
- const MCSection *TUIndexSection, const MCSection *InfoSection,
- const object::SectionRef &Section, MCStreamer &Out,
- std::deque<SmallString<32>> &UncompressedSections,
- uint32_t (&ContributionOffsets)[8], UnitIndexEntry &CurEntry,
- StringRef &CurStrSection, StringRef &CurStrOffsetSection,
- std::vector<StringRef> &CurTypesSection,
- std::vector<StringRef> &CurInfoSection, StringRef &AbbrevSection,
- StringRef &CurCUIndexSection, StringRef &CurTUIndexSection,
- SectionLengths &SectionLength);
-
LLVM_ABI Expected<InfoSectionUnitHeader>
parseInfoSectionUnitHeader(StringRef Info);
-LLVM_ABI void
-writeStringsAndOffsets(MCStreamer &Out, DWPStringPool &Strings,
- MCSection *StrOffsetSection, StringRef CurStrSection,
- StringRef CurStrOffsetSection, uint16_t Version,
- SectionLengths &SectionLength,
- const Dwarf64StrOffsetsPromotion StrOffsetsOptValue);
-
-LLVM_ABI Error
-buildDuplicateError(const std::pair<uint64_t, UnitIndexEntry> &PrevE,
- const CompileUnitIdentifiers &ID, StringRef DWPName);
-
-LLVM_ABI void
-writeIndex(MCStreamer &Out, MCSection *Section,
- ArrayRef<unsigned> ContributionOffsets,
- const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
- uint32_t IndexVersion);
-
} // namespace llvm
#endif // LLVM_DWP_DWP_H
diff --git a/llvm/include/llvm/DWP/DWPStringPool.h b/llvm/include/llvm/DWP/DWPStringPool.h
index d1486ff7872e1..7122e84cdfff5 100644
--- a/llvm/include/llvm/DWP/DWPStringPool.h
+++ b/llvm/include/llvm/DWP/DWPStringPool.h
@@ -2,49 +2,28 @@
#define LLVM_DWP_DWPSTRINGPOOL_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/MC/MCSection.h"
-#include "llvm/MC/MCStreamer.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include <cassert>
namespace llvm {
class DWPStringPool {
-
- struct CStrDenseMapInfo {
- static inline const char *getEmptyKey() {
- return reinterpret_cast<const char *>(~static_cast<uintptr_t>(0));
- }
- static inline const char *getTombstoneKey() {
- return reinterpret_cast<const char *>(~static_cast<uintptr_t>(1));
- }
- static unsigned getHashValue(const char *Val) {
- assert(Val != getEmptyKey() && "Cannot hash the empty key!");
- assert(Val != getTombstoneKey() && "Cannot hash the tombstone key!");
- return (unsigned)hash_value(StringRef(Val));
- }
- static bool isEqual(const char *LHS, const char *RHS) {
- if (RHS == getEmptyKey())
- return LHS == getEmptyKey();
- if (RHS == getTombstoneKey())
- return LHS == getTombstoneKey();
- return strcmp(LHS, RHS) == 0;
- }
- };
-
- MCStreamer &Out;
- MCSection *Sec;
- DenseMap<const char *, uint64_t, CStrDenseMapInfo> Pool;
+ SmallVectorImpl<char> &Buffer;
+ // Use StringRef keys instead of const char* to avoid redundant strlen
+ // on every hash computation and strcmp on every probe comparison.
+ DenseMap<StringRef, uint64_t> Pool;
uint64_t Offset = 0;
public:
- DWPStringPool(MCStreamer &Out, MCSection *Sec) : Out(Out), Sec(Sec) {}
+ DWPStringPool(SmallVectorImpl<char> &Buffer) : Buffer(Buffer) {}
uint64_t getOffset(const char *Str, unsigned Length) {
assert(strlen(Str) + 1 == Length && "Ensure length hint is correct");
- auto Pair = Pool.insert(std::make_pair(Str, Offset));
+ StringRef Key(Str, Length - 1);
+ auto Pair = Pool.insert(std::make_pair(Key, Offset));
if (Pair.second) {
- Out.switchSection(Sec);
- Out.emitBytes(StringRef(Str, Length));
+ Buffer.insert(Buffer.end(), Str, Str + Length);
Offset += Length;
}
diff --git a/llvm/lib/DWP/CMakeLists.txt b/llvm/lib/DWP/CMakeLists.txt
index 777de1978dae3..56199dec94108 100644
--- a/llvm/lib/DWP/CMakeLists.txt
+++ b/llvm/lib/DWP/CMakeLists.txt
@@ -10,7 +10,6 @@ add_llvm_component_library(LLVMDWP
LINK_COMPONENTS
DebugInfoDWARF
- MC
Object
Support
)
diff --git a/llvm/lib/DWP/DWP.cpp b/llvm/lib/DWP/DWP.cpp
index ea029e97464bc..91afb930c9309 100644
--- a/llvm/lib/DWP/DWP.cpp
+++ b/llvm/lib/DWP/DWP.cpp
@@ -11,20 +11,20 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/DWP/DWP.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/DWP/DWPError.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCObjectFileInfo.h"
-#include "llvm/MC/MCTargetOptionsCommandFlags.h"
#include "llvm/Object/Decompressor.h"
#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/MathExtras.h"
#include <limits>
using namespace llvm;
using namespace llvm::object;
-static mc::RegisterMCTargetOptionsFlags MCTargetOptionsFlags;
-
// Returns the size of debug_str_offsets section headers in bytes.
static uint64_t debugStrOffsetsHeaderSize(DataExtractor StrOffsetsData,
uint16_t DwarfVersion) {
@@ -200,12 +200,12 @@ static Error sectionOverflowErrorOrWarning(uint32_t PrevOffset,
}
static Error addAllTypesFromDWP(
- MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
- const DWARFUnitIndex &TUIndex, MCSection *OutputTypes, StringRef Types,
+ DWPWriter &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
+ const DWARFUnitIndex &TUIndex, DWPSectionId OutputSection, StringRef Types,
const UnitIndexEntry &TUEntry, uint32_t &TypesOffset,
unsigned TypesContributionIndex, OnCuIndexOverflow OverflowOptValue,
bool &AnySectionOverflow) {
- Out.switchSection(OutputTypes);
+ Out.switchSection(OutputSection);
for (const DWARFUnitIndex::Entry &E : TUIndex.getRows()) {
auto *I = E.getContributions();
if (!I)
@@ -249,12 +249,12 @@ static Error addAllTypesFromDWP(
}
static Error addAllTypesFromTypesSection(
- MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
- MCSection *OutputTypes, const std::vector<StringRef> &TypesSections,
+ DWPWriter &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
+ DWPSectionId OutputSection, const std::vector<StringRef> &TypesSections,
const UnitIndexEntry &CUEntry, uint32_t &TypesOffset,
OnCuIndexOverflow OverflowOptValue, bool &AnySectionOverflow) {
for (StringRef Types : TypesSections) {
- Out.switchSection(OutputTypes);
+ Out.switchSection(OutputSection);
uint64_t Offset = 0;
DataExtractor Data(Types, true, 0);
while (Data.isValidOffset(Offset)) {
@@ -351,6 +351,32 @@ handleCompressedSection(std::deque<SmallString<32>> &UncompressedSections,
return Error::success();
}
+static Error buildDuplicateError(const std::pair<uint64_t, UnitIndexEntry> &PrevE,
+ const CompileUnitIdentifiers &ID,
+ StringRef DWPName) {
+ return make_error<DWPError>(
+ std::string("duplicate DWO ID (") + utohexstr(PrevE.first) + ") in " +
+ buildDWODescription(PrevE.second.Name, PrevE.second.DWPName,
+ PrevE.second.DWOName) +
+ " and " + buildDWODescription(ID.Name, DWPName, ID.DWOName));
+}
+
+// Create a mask so we don't trigger a emitIntValue() assert below if the
+// NewOffset is over 4GB.
+static void writeNewOffsetsTo(DWPWriter &Out, DataExtractor &Data,
+ DenseMap<uint64_t, uint64_t> &OffsetRemapping,
+ uint64_t &Offset, const uint64_t Size,
+ uint32_t OldOffsetSize, uint32_t NewOffsetSize) {
+ const uint64_t NewOffsetMask = NewOffsetSize == 8 ? UINT64_MAX : UINT32_MAX;
+ while (Offset < Size) {
+ const uint64_t OldOffset = Data.getUnsigned(&Offset, OldOffsetSize);
+ const uint64_t NewOffset = OffsetRemapping[OldOffset];
+ // Truncate the string offset like the old llvm-dwp would have if we aren't
+ // promoting the .debug_str_offsets to DWARF64.
+ Out.emitIntValue(NewOffset & NewOffsetMask, NewOffsetSize);
+ }
+}
+
namespace llvm {
// Parse and return the header of an info section compile/type unit.
Expected<InfoSectionUnitHeader> parseInfoSectionUnitHeader(StringRef Info) {
@@ -412,33 +438,31 @@ Expected<InfoSectionUnitHeader> parseInfoSectionUnitHeader(StringRef Info) {
return Header;
}
-static void writeNewOffsetsTo(MCStreamer &Out, DataExtractor &Data,
- DenseMap<uint64_t, uint64_t> &OffsetRemapping,
- uint64_t &Offset, const uint64_t Size,
- uint32_t OldOffsetSize, uint32_t NewOffsetSize) {
- // Create a mask so we don't trigger a emitIntValue() assert below if the
- // NewOffset is over 4GB.
- const uint64_t NewOffsetMask = NewOffsetSize == 8 ? UINT64_MAX : UINT32_MAX;
- while (Offset < Size) {
- const uint64_t OldOffset = Data.getUnsigned(&Offset, OldOffsetSize);
- const uint64_t NewOffset = OffsetRemapping[OldOffset];
- // Truncate the string offset like the old llvm-dwp would have if we aren't
- // promoting the .debug_str_offsets to DWARF64.
- Out.emitIntValue(NewOffset & NewOffsetMask, NewOffsetSize);
- }
-}
-
-void writeStringsAndOffsets(
- MCStreamer &Out, DWPStringPool &Strings, MCSection *StrOffsetSection,
- StringRef CurStrSection, StringRef CurStrOffsetSection, uint16_t Version,
- SectionLengths &SectionLength,
- const Dwarf64StrOffsetsPromotion StrOffsetsOptValue) {
+static void
+writeStringsAndOffsets(DWPWriter &Out, DWPStringPool &Strings,
+ StringRef CurStrSection, StringRef CurStrOffsetSection,
+ uint16_t Version, SectionLengths &SectionLength,
+ const Dwarf64StrOffsetsPromotion StrOffsetsOptValue,
+ bool SingleInput) {
// Could possibly produce an error or warning if one of these was non-null but
// the other was null.
if (CurStrSection.empty() || CurStrOffsetSection.empty())
return;
+ // Fast path: when there is only one input, all strings are unique and offsets
+ // don't need remapping. Copy both sections directly without any hashing.
+ if (SingleInput &&
+ StrOffsetsOptValue != Dwarf64StrOffsetsPromotion::Always) {
+ Out.switchSection(DS_Str);
+ Out.emitBytes(CurStrSection);
+ Out.switchSection(DS_StrOffsets);
+ Out.emitBytes(CurStrOffsetSection);
+ return;
+ }
+
DenseMap<uint64_t, uint64_t> OffsetRemapping;
+ // Pre-reserve based on estimated string count to avoid rehashing.
+ OffsetRemapping.reserve(CurStrSection.size() / 20);
DataExtractor Data(CurStrSection, true, 0);
uint64_t LocalOffset = 0;
@@ -464,7 +488,7 @@ void writeStringsAndOffsets(
Data = DataExtractor(CurStrOffsetSection, true, 0);
- Out.switchSection(StrOffsetSection);
+ Out.switchSection(DS_StrOffsets);
uint64_t Offset = 0;
uint64_t Size = CurStrOffsetSection.size();
@@ -530,9 +554,11 @@ void writeStringsAndOffsets(
}
enum AccessField { Offset, Length };
-void writeIndexTable(MCStreamer &Out, ArrayRef<unsigned> ContributionOffsets,
- const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
- const AccessField &Field) {
+
+static void
+writeIndexTable(DWPWriter &Out, ArrayRef<unsigned> ContributionOffsets,
+ const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
+ const AccessField &Field) {
for (const auto &E : IndexEntries)
for (size_t I = 0; I != std::size(E.second.Contributions); ++I)
if (ContributionOffsets[I])
@@ -542,10 +568,10 @@ void writeIndexTable(MCStreamer &Out, ArrayRef<unsigned> ContributionOffsets,
4);
}
-void writeIndex(MCStreamer &Out, MCSection *Section,
- ArrayRef<unsigned> ContributionOffsets,
- const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
- uint32_t IndexVersion) {
+static void writeIndex(DWPWriter &Out, DWPSectionId Section,
+ ArrayRef<unsigned> ContributionOffsets,
+ const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
+ uint32_t IndexVersion) {
if (IndexEntries.empty())
return;
@@ -596,21 +622,29 @@ void writeIndex(MCStreamer &Out, MCSection *Section,
writeIndexTable(Out, ContributionOffsets, IndexEntries, AccessField::Length);
}
-Error buildDuplicateError(const std::pair<uint64_t, UnitIndexEntry> &PrevE,
- const CompileUnitIdentifiers &ID, StringRef DWPName) {
- return make_error<DWPError>(
- std::string("duplicate DWO ID (") + utohexstr(PrevE.first) + ") in " +
- buildDWODescription(PrevE.second.Name, PrevE.second.DWPName,
- PrevE.second.DWOName) +
- " and " + buildDWODescription(ID.Name, DWPName, ID.DWOName));
+/// Map input ELF section names to DWP section IDs and DWARF section kinds.
+static const StringMap<std::pair<DWPSectionId, DWARFSectionKind>> &
+getKnownSections() {
+ static const StringMap<std::pair<DWPSectionId, DWARFSectionKind>> Map = {
+ {"debug_info.dwo", {DS_Info, DW_SECT_INFO}},
+ {"debug_types.dwo", {DS_Types, DW_SECT_EXT_TYPES}},
+ {"debug_str_offsets.dwo", {DS_StrOffsets, DW_SECT_STR_OFFSETS}},
+ {"debug_str.dwo", {DS_Str, static_cast<DWARFSectionKind>(0)}},
+ {"debug_loc.dwo", {DS_Loc, DW_SECT_EXT_LOC}},
+ {"debug_line.dwo", {DS_Line, DW_SECT_LINE}},
+ {"debug_macro.dwo", {DS_Macro, DW_SECT_MACRO}},
+ {"debug_abbrev.dwo", {DS_Abbrev, DW_SECT_ABBREV}},
+ {"debug_loclists.dwo", {DS_Loclists, DW_SECT_LOCLISTS}},
+ {"debug_rnglists.dwo", {DS_Rnglists, DW_SECT_RNGLISTS}},
+ {"debug_cu_index", {DS_CUIndex, static_cast<DWARFSectionKind>(0)}},
+ {"debug_tu_index", {DS_TUIndex, static_cast<DWARFSectionKind>(0)}},
+ };
+ return Map;
}
-Error handleSection(
- const StringMap<std::pair<MCSection *, DWARFSectionKind>> &KnownSections,
- const MCSection *StrSection, const MCSection *StrOffsetSection,
- const MCSection *TypesSection, const MCSection *CUIndexSection,
- const MCSection *TUIndexSection, const MCSection *InfoSection,
- const SectionRef &Section, MCStreamer &Out,
+static Error handleSection(
+ const StringMap<std::pair<DWPSectionId, DWARFSectionKind>> &KnownSections,
+ const SectionRef &Section, DWPWriter &Out,
std::deque<SmallString<32>> &UncompressedSections,
uint32_t (&ContributionOffsets)[8], UnitIndexEntry &CurEntry,
StringRef &CurStrSection, StringRef &CurStrOffsetSection,
@@ -644,61 +678,49 @@ Error handleSection(
if (SectionPair == KnownSections.end())
return Error::success();
- if (DWARFSectionKind Kind = SectionPair->second.second) {
- if (Kind != DW_SECT_EXT_TYPES && Kind != DW_SECT_INFO) {
- SectionLength.push_back(std::make_pair(Kind, Contents.size()));
- }
+ DWPSectionId SectionId = SectionPair->second.first;
+ DWARFSectionKind Kind = SectionPair->second.second;
- if (Kind == DW_SECT_ABBREV) {
+ if (Kind) {
+ if (Kind != DW_SECT_EXT_TYPES && Kind != DW_SECT_INFO)
+ SectionLength.push_back(std::make_pair(Kind, Contents.size()));
+ if (Kind == DW_SECT_ABBREV)
AbbrevSection = Contents;
- }
}
- MCSection *OutSection = SectionPair->second.first;
- if (OutSection == StrOffsetSection)
+ switch (SectionId) {
+ case DS_StrOffsets:
CurStrOffsetSection = Contents;
- else if (OutSection == StrSection)
+ break;
+ case DS_Str:
CurStrSection = Contents;
- else if (OutSection == TypesSection)
+ break;
+ case DS_Types:
CurTypesSection.push_back(Contents);
- else if (OutSection == CUIndexSection)
+ break;
+ case DS_CUIndex:
CurCUIndexSection = Contents;
- else if (OutSection == TUIndexSection)
+ break;
+ case DS_TUIndex:
CurTUIndexSection = Contents;
- else if (OutSection == InfoSection)
+ break;
+ case DS_Info:
CurInfoSection.push_back(Contents);
- else {
- Out.switchSection(OutSection);
+ break;
+ default:
+ // Pass-through: emit directly to output (zero-copy).
+ Out.switchSection(SectionId);
Out.emitBytes(Contents);
+ break;
}
return Error::success();
}
-Error write(MCStrea...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/192112
More information about the llvm-commits
mailing list