[llvm] [MC] Add MCFragment allocation helpers (PR #95197)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 13 14:59:52 PDT 2024
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/95197
>From 5a49e4f5575134a2b19fd1018ebfd8996cf40762 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Tue, 11 Jun 2024 22:01:22 -0700
Subject: [PATCH 1/4] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
=?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.5-bogner
---
llvm/include/llvm/MC/MCContext.h | 7 +++++
llvm/include/llvm/MC/MCObjectStreamer.h | 6 +++++
llvm/lib/MC/MCContext.cpp | 34 ++++++++++---------------
llvm/lib/MC/MCELFStreamer.cpp | 6 ++---
llvm/lib/MC/MCMachOStreamer.cpp | 2 +-
llvm/lib/MC/MCObjectStreamer.cpp | 28 +++++++++-----------
6 files changed, 42 insertions(+), 41 deletions(-)
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 72eae85467dc9..f5938475510bf 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -44,6 +44,7 @@ namespace llvm {
class CodeViewContext;
class MCAsmInfo;
+class MCDataFragment;
class MCInst;
class MCLabel;
class MCObjectFileInfo;
@@ -345,6 +346,8 @@ class MCContext {
void reportCommon(SMLoc Loc,
std::function<void(SMDiagnostic &, const SourceMgr *)>);
+ MCDataFragment *allocInitialFragment(MCSection &Sec);
+
MCSymbol *createSymbolImpl(const StringMapEntry<bool> *Name,
bool IsTemporary);
MCSymbol *createSymbol(StringRef Name, bool AlwaysAddSuffix,
@@ -438,6 +441,10 @@ class MCContext {
/// Create and return a new MC instruction.
MCInst *createMCInst();
+ template <typename F, typename... Args> F *allocFragment(Args &&...args) {
+ return new F(std::forward<Args>(args)...);
+ }
+
/// \name Symbol Management
/// @{
diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h
index c0a337f5ea45e..555c4e1d3f1a1 100644
--- a/llvm/include/llvm/MC/MCObjectStreamer.h
+++ b/llvm/include/llvm/MC/MCObjectStreamer.h
@@ -90,6 +90,12 @@ class MCObjectStreamer : public MCStreamer {
MCFragment *getCurrentFragment() const;
+ template <typename F, typename... Args> F *allocAndAdd(Args &&...args) {
+ F *Frag = new F(std::forward<Args>(args)...);
+ insert(Frag);
+ return Frag;
+ }
+
void insert(MCFragment *F) {
flushPendingLabels(F);
MCSection *CurSection = getCurrentSectionOnly();
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 1590054717960..82ac5f04c9076 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -195,6 +195,15 @@ MCInst *MCContext::createMCInst() {
return new (MCInstAllocator.Allocate()) MCInst;
}
+// Allocate the initial MCDataFragment for the begin symbol.
+MCDataFragment *MCContext::allocInitialFragment(MCSection &Sec) {
+ assert(!Sec.curFragList()->Head);
+ auto *F = allocFragment<MCDataFragment>();
+ F->setParent(&Sec);
+ Sec.addFragment(*F);
+ return F;
+}
+
//===----------------------------------------------------------------------===//
// Symbol Manipulation
//===----------------------------------------------------------------------===//
@@ -497,11 +506,8 @@ MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
MCSectionELF(Section, Type, Flags, K, EntrySize, Group, Comdat, UniqueID,
R, LinkedToSym);
- auto *F = new MCDataFragment();
- Ret->addFragment(*F);
- F->setParent(Ret);
+ auto *F = allocInitialFragment(*Ret);
R->setFragment(F);
-
return Ret;
}
@@ -797,11 +803,8 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,
MCSectionWasm(CachedName, Kind, Flags, GroupSym, UniqueID, Begin);
Entry.second = Result;
- auto *F = new MCDataFragment();
- Result->addFragment(*F);
- F->setParent(Result);
+ auto *F = allocInitialFragment(*Result);
Begin->setFragment(F);
-
return Result;
}
@@ -863,10 +866,7 @@ MCSectionXCOFF *MCContext::getXCOFFSection(
Entry.second = Result;
- auto *F = new MCDataFragment();
- Result->addFragment(*F);
- F->setParent(Result);
-
+ auto *F = allocInitialFragment(*Result);
if (Begin)
Begin->setFragment(F);
@@ -886,10 +886,7 @@ MCSectionSPIRV *MCContext::getSPIRVSection() {
MCSectionSPIRV *Result = new (SPIRVAllocator.Allocate())
MCSectionSPIRV(SectionKind::getText(), Begin);
- auto *F = new MCDataFragment();
- Result->addFragment(*F);
- F->setParent(Result);
-
+ allocInitialFragment(*Result);
return Result;
}
@@ -909,10 +906,7 @@ MCSectionDXContainer *MCContext::getDXContainerSection(StringRef Section,
new (DXCAllocator.Allocate()) MCSectionDXContainer(Name, K, nullptr);
// The first fragment will store the header
- auto *F = new MCDataFragment();
- MapIt->second->addFragment(*F);
- F->setParent(MapIt->second);
-
+ allocInitialFragment(*MapIt->second);
return MapIt->second;
}
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 23e926c3a9d14..b2bef3934aa9a 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -596,14 +596,12 @@ void MCELFStreamer::emitInstToData(const MCInst &Inst,
// Optimize memory usage by emitting the instruction to a
// MCCompactEncodedInstFragment when not in a bundle-locked group and
// there are no fixups registered.
- MCCompactEncodedInstFragment *CEIF = new MCCompactEncodedInstFragment();
- insert(CEIF);
+ auto *CEIF = allocAndAdd<MCCompactEncodedInstFragment>();
CEIF->getContents().append(Code.begin(), Code.end());
CEIF->setHasInstructions(STI);
return;
} else {
- DF = new MCDataFragment();
- insert(DF);
+ DF = allocAndAdd<MCDataFragment>();
}
if (Sec.getBundleLockState() == MCSection::BundleLockedAlignToEnd) {
// If this fragment is for a group marked "align_to_end", set a flag
diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp
index 10f9988b9d16a..7c3f3fa84bd1a 100644
--- a/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/llvm/lib/MC/MCMachOStreamer.cpp
@@ -199,7 +199,7 @@ void MCMachOStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
// We have to create a new fragment if this is an atom defining symbol,
// fragments cannot span atoms.
if (getAssembler().isSymbolLinkerVisible(*Symbol))
- insert(new MCDataFragment());
+ allocAndAdd<MCDataFragment>();
MCObjectStreamer::emitLabel(Symbol, Loc);
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index bf1ce76cdc14b..37f90e8bd10bf 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -224,10 +224,8 @@ static bool canReuseDataFragment(const MCDataFragment &F,
MCDataFragment *
MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) {
MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
- if (!F || !canReuseDataFragment(*F, *Assembler, STI)) {
- F = new MCDataFragment();
- insert(F);
- }
+ if (!F || !canReuseDataFragment(*F, *Assembler, STI))
+ F = allocAndAdd<MCDataFragment>();
return F;
}
@@ -343,7 +341,7 @@ void MCObjectStreamer::emitULEB128Value(const MCExpr *Value) {
emitULEB128IntValue(IntValue);
return;
}
- insert(new MCLEBFragment(*Value, false));
+ allocAndAdd<MCLEBFragment>(*Value, false);
}
void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) {
@@ -352,7 +350,7 @@ void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) {
emitSLEB128IntValue(IntValue);
return;
}
- insert(new MCLEBFragment(*Value, true));
+ allocAndAdd<MCLEBFragment>(*Value, true);
}
void MCObjectStreamer::emitWeakReference(MCSymbol *Alias,
@@ -470,9 +468,7 @@ void MCObjectStreamer::emitInstToFragment(const MCInst &Inst,
// Always create a new, separate fragment here, because its size can change
// during relaxation.
- MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
- insert(IF);
-
+ auto *IF = allocAndAdd<MCRelaxableFragment>(Inst, STI);
SmallString<128> Code;
getAssembler().getEmitter().encodeInstruction(Inst, Code, IF->getFixups(),
STI);
@@ -544,7 +540,7 @@ void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
return;
}
const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel, SMLoc());
- insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
+ allocAndAdd<MCDwarfLineAddrFragment>(LineDelta, *AddrDelta);
}
void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section,
@@ -569,7 +565,7 @@ void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
const MCSymbol *Label,
SMLoc Loc) {
const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel, Loc);
- insert(new MCDwarfCallFrameFragment(*AddrDelta, nullptr));
+ allocAndAdd<MCDwarfCallFrameFragment>(*AddrDelta, nullptr);
}
void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
@@ -640,7 +636,7 @@ void MCObjectStreamer::emitValueToAlignment(Align Alignment, int64_t Value,
unsigned MaxBytesToEmit) {
if (MaxBytesToEmit == 0)
MaxBytesToEmit = Alignment.value();
- insert(new MCAlignFragment(Alignment, Value, ValueSize, MaxBytesToEmit));
+ allocAndAdd<MCAlignFragment>(Alignment, Value, ValueSize, MaxBytesToEmit);
// Update the maximum alignment on the current section if necessary.
MCSection *CurSec = getCurrentSectionOnly();
@@ -657,7 +653,7 @@ void MCObjectStreamer::emitCodeAlignment(Align Alignment,
void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
unsigned char Value,
SMLoc Loc) {
- insert(new MCOrgFragment(*Offset, Value, Loc));
+ allocAndAdd<MCOrgFragment>(*Offset, Value, Loc);
}
// Associate DTPRel32 fixup with data and resize data area
@@ -844,7 +840,7 @@ void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
flushPendingLabels(DF, DF->getContents().size());
assert(getCurrentSectionOnly() && "need a section");
- insert(new MCFillFragment(FillValue, 1, NumBytes, Loc));
+ allocAndAdd<MCFillFragment>(FillValue, 1, NumBytes, Loc);
}
void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
@@ -874,7 +870,7 @@ void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
flushPendingLabels(DF, DF->getContents().size());
assert(getCurrentSectionOnly() && "need a section");
- insert(new MCFillFragment(Expr, Size, NumValues, Loc));
+ allocAndAdd<MCFillFragment>(Expr, Size, NumValues, Loc);
}
void MCObjectStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLength,
@@ -885,7 +881,7 @@ void MCObjectStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLength,
assert(getCurrentSectionOnly() && "need a section");
- insert(new MCNopsFragment(NumBytes, ControlledNopLength, Loc, STI));
+ allocAndAdd<MCNopsFragment>(NumBytes, ControlledNopLength, Loc, STI);
}
void MCObjectStreamer::emitFileDirective(StringRef Filename) {
>From 489e783defec4b2c8bbe86e0a69494f3027cb4b0 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Wed, 12 Jun 2024 21:24:05 -0700
Subject: [PATCH 2/4] update more
Created using spr 1.3.5-bogner
---
llvm/lib/MC/MCAssembler.cpp | 7 +++++--
llvm/lib/MC/MCMachOStreamer.cpp | 8 ++++++--
llvm/lib/MC/WinCOFFObjectWriter.cpp | 10 ++++++----
3 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 24a9781775a2b..08420ed2b3a39 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -820,8 +820,11 @@ void MCAssembler::layout(MCAsmLayout &Layout) {
for (MCSection &Sec : *this) {
// Create dummy fragments to eliminate any empty sections, this simplifies
// layout.
- if (Sec.empty())
- getContext().allocFragment<MCDataFragment>(&Sec);
+ if (Sec.empty()) {
+ auto *F = getContext().allocFragment<MCDataFragment>();
+ F->setParent(&Sec);
+ Sec.addFragment(*F);
+ }
Sec.setOrdinal(SectionIndex++);
}
diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp
index b0057fd9ff94f..7139fb1192a4d 100644
--- a/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/llvm/lib/MC/MCMachOStreamer.cpp
@@ -553,7 +553,9 @@ void MCMachOStreamer::finalizeCGProfile() {
MCSection *CGProfileSection = Asm.getContext().getMachOSection(
"__LLVM", "__cg_profile", 0, SectionKind::getMetadata());
Asm.registerSection(*CGProfileSection);
- auto *Frag = getContext().allocFragment<MCDataFragment>(CGProfileSection);
+ auto *Frag = getContext().allocFragment<MCDataFragment>();
+ Frag->setParent(CGProfileSection);
+ CGProfileSection->addFragment(*Frag);
// For each entry, reserve space for 2 32-bit indices and a 64-bit count.
size_t SectionBytes =
Asm.CGProfile.size() * (2 * sizeof(uint32_t) + sizeof(uint64_t));
@@ -593,7 +595,9 @@ void MCMachOStreamer::createAddrSigSection() {
MCSection *AddrSigSection =
Asm.getContext().getObjectFileInfo()->getAddrSigSection();
Asm.registerSection(*AddrSigSection);
- auto *Frag = getContext().allocFragment<MCDataFragment>(AddrSigSection);
+ auto *Frag = getContext().allocFragment<MCDataFragment>();
+ Frag->setParent(AddrSigSection);
+ AddrSigSection->addFragment(*Frag);
// We will generate a series of pointer-sized symbol relocations at offset
// 0x0. Set the section size to be large enough to contain a single pointer
// (instead of emitting a zero-sized section) so these relocations are
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index a2b6c4e5c3a5c..e877bf88df81b 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -1097,8 +1097,9 @@ uint64_t WinCOFFWriter::writeObject(MCAssembler &Asm,
// Create the contents of the .llvm_addrsig section.
if (Mode != DwoOnly && OWriter.EmitAddrsigSection) {
- auto Frag = new MCDataFragment(AddrsigSection);
- Frag->setLayoutOrder(0);
+ auto *Frag = Asm.getContext().allocFragment<MCDataFragment>();
+ Frag->setParent(AddrsigSection);
+ AddrsigSection->addFragment(*Frag);
raw_svector_ostream OS(Frag->getContents());
for (const MCSymbol *S : OWriter.AddrsigSyms) {
if (!S->isRegistered())
@@ -1118,8 +1119,9 @@ uint64_t WinCOFFWriter::writeObject(MCAssembler &Asm,
// Create the contents of the .llvm.call-graph-profile section.
if (Mode != DwoOnly && CGProfileSection) {
- auto *Frag = new MCDataFragment(CGProfileSection);
- Frag->setLayoutOrder(0);
+ auto *Frag = Asm.getContext().allocFragment<MCDataFragment>();
+ Frag->setParent(CGProfileSection);
+ CGProfileSection->addFragment(*Frag);
raw_svector_ostream OS(Frag->getContents());
for (const MCAssembler::CGProfileEntry &CGPE : Asm.CGProfile) {
uint32_t FromIndex = CGPE.From->getSymbol().getIndex();
>From e4fde9bf05af7fe180a9eb404c768ed5cde2ee62 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Thu, 13 Jun 2024 14:55:27 -0700
Subject: [PATCH 3/4] update MCCodeView.cpp
Created using spr 1.3.5-bogner
---
llvm/include/llvm/MC/MCCodeView.h | 4 +++-
llvm/lib/MC/MCCodeView.cpp | 10 ++++------
llvm/lib/MC/MCContext.cpp | 2 +-
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/llvm/include/llvm/MC/MCCodeView.h b/llvm/include/llvm/MC/MCCodeView.h
index d15f2e42c6cc9..b1d8fe37a3188 100644
--- a/llvm/include/llvm/MC/MCCodeView.h
+++ b/llvm/include/llvm/MC/MCCodeView.h
@@ -143,7 +143,7 @@ struct MCCVFunctionInfo {
/// Holds state from .cv_file and .cv_loc directives for later emission.
class CodeViewContext {
public:
- CodeViewContext();
+ CodeViewContext(MCContext *MCCtx) : MCCtx(MCCtx) {}
~CodeViewContext();
CodeViewContext &operator=(const CodeViewContext &other) = delete;
@@ -223,6 +223,8 @@ class CodeViewContext {
std::pair<StringRef, unsigned> addToStringTable(StringRef S);
private:
+ MCContext *MCCtx;
+
/// Map from string to string table offset.
StringMap<unsigned> StringTable;
diff --git a/llvm/lib/MC/MCCodeView.cpp b/llvm/lib/MC/MCCodeView.cpp
index d234ce110918e..696e693b244e3 100644
--- a/llvm/lib/MC/MCCodeView.cpp
+++ b/llvm/lib/MC/MCCodeView.cpp
@@ -26,8 +26,6 @@
using namespace llvm;
using namespace llvm::codeview;
-CodeViewContext::CodeViewContext() = default;
-
CodeViewContext::~CodeViewContext() {
// If someone inserted strings into the string table but never actually
// emitted them somewhere, clean up the fragment.
@@ -138,7 +136,7 @@ void CodeViewContext::recordCVLoc(MCContext &Ctx, const MCSymbol *Label,
MCDataFragment *CodeViewContext::getStringTableFragment() {
if (!StrTabFragment) {
- StrTabFragment = new MCDataFragment();
+ StrTabFragment = MCCtx->allocFragment<MCDataFragment>();
// Start a new string table out with a null byte.
StrTabFragment->getContents().push_back('\0');
}
@@ -450,9 +448,9 @@ void CodeViewContext::emitInlineLineTableForFunction(MCObjectStreamer &OS,
const MCSymbol *FnEndSym) {
// Create and insert a fragment into the current section that will be encoded
// later.
- new MCCVInlineLineTableFragment(PrimaryFunctionId, SourceFileId,
- SourceLineNum, FnStartSym, FnEndSym,
- OS.getCurrentSectionOnly());
+ auto *F = MCCtx->allocFragment<MCCVInlineLineTableFragment>(
+ PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
+ OS.insert(F);
}
MCFragment *CodeViewContext::emitDefRange(
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 1c025df60b323..f12a3bc0e56f5 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -1037,7 +1037,7 @@ void MCContext::finalizeDwarfSections(MCStreamer &MCOS) {
CodeViewContext &MCContext::getCVContext() {
if (!CVContext)
- CVContext.reset(new CodeViewContext);
+ CVContext.reset(new CodeViewContext(this));
return *CVContext;
}
>From a7c84cf04ef425921a90bf2a4aa0e562f405cd86 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Thu, 13 Jun 2024 14:59:43 -0700
Subject: [PATCH 4/4] fix CodeViewContext::emitDefRange
Created using spr 1.3.5-bogner
---
llvm/lib/MC/MCCodeView.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/MC/MCCodeView.cpp b/llvm/lib/MC/MCCodeView.cpp
index 696e693b244e3..713ae07c3a730 100644
--- a/llvm/lib/MC/MCCodeView.cpp
+++ b/llvm/lib/MC/MCCodeView.cpp
@@ -459,8 +459,10 @@ MCFragment *CodeViewContext::emitDefRange(
StringRef FixedSizePortion) {
// Create and insert a fragment into the current section that will be encoded
// later.
- return new MCCVDefRangeFragment(Ranges, FixedSizePortion,
- OS.getCurrentSectionOnly());
+ auto *F =
+ MCCtx->allocFragment<MCCVDefRangeFragment>(Ranges, FixedSizePortion);
+ OS.insert(F);
+ return F;
}
static unsigned computeLabelDiff(MCAsmLayout &Layout, const MCSymbol *Begin,
More information about the llvm-commits
mailing list