[llvm] MC: Restructure MCFragment as a fixed part and a variable tail (PR #148544)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 15 10:13:34 PDT 2025
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/148544
>From f3b795b3402c37bf29b68aadc6158158101ccfca Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Sun, 13 Jul 2025 11:54:21 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=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/MCAsmBackend.h | 16 +-
llvm/include/llvm/MC/MCAssembler.h | 18 +-
llvm/include/llvm/MC/MCCodeView.h | 3 +-
llvm/include/llvm/MC/MCContext.h | 3 +-
llvm/include/llvm/MC/MCELFStreamer.h | 3 +-
llvm/include/llvm/MC/MCObjectStreamer.h | 6 +-
llvm/include/llvm/MC/MCSection.h | 309 +++++++++---------
llvm/lib/MC/MCAsmBackend.cpp | 9 +-
llvm/lib/MC/MCAssembler.cpp | 129 ++++----
llvm/lib/MC/MCELFStreamer.cpp | 4 +-
llvm/lib/MC/MCExpr.cpp | 8 +-
llvm/lib/MC/MCFragment.cpp | 93 +++---
llvm/lib/MC/MCObjectStreamer.cpp | 69 ++--
llvm/lib/MC/MCSection.cpp | 34 +-
llvm/lib/MC/WasmObjectWriter.cpp | 6 +-
.../MCTargetDesc/AArch64ELFStreamer.cpp | 8 +-
.../Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 3 +-
.../Target/ARM/MCTargetDesc/ARMAsmBackend.h | 3 +-
.../ARM/MCTargetDesc/ARMELFStreamer.cpp | 11 +-
.../CSKY/MCTargetDesc/CSKYAsmBackend.cpp | 3 +-
.../Target/CSKY/MCTargetDesc/CSKYAsmBackend.h | 3 +-
.../MCTargetDesc/HexagonAsmBackend.cpp | 15 +-
.../MCTargetDesc/LoongArchAsmBackend.cpp | 33 +-
.../MCTargetDesc/LoongArchAsmBackend.h | 8 +-
.../RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 45 ++-
.../RISCV/MCTargetDesc/RISCVAsmBackend.h | 11 +-
.../Target/X86/MCTargetDesc/X86AsmBackend.cpp | 58 ++--
llvm/test/MC/ELF/mc-dump.s | 22 +-
28 files changed, 486 insertions(+), 447 deletions(-)
diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h
index 6b81bdba25e67..9a4862baaeb3a 100644
--- a/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/llvm/include/llvm/MC/MCAsmBackend.h
@@ -19,11 +19,8 @@
namespace llvm {
class MCAlignFragment;
-class MCDwarfCallFrameFragment;
-class MCDwarfLineAddrFragment;
class MCFragment;
class MCLEBFragment;
-class MCRelaxableFragment;
class MCSymbol;
class MCAssembler;
class MCContext;
@@ -157,8 +154,9 @@ class LLVM_ABI MCAsmBackend {
/// Target specific predicate for whether a given fixup requires the
/// associated instruction to be relaxed.
- virtual bool fixupNeedsRelaxationAdvanced(const MCFixup &, const MCValue &,
- uint64_t, bool Resolved) const;
+ virtual bool fixupNeedsRelaxationAdvanced(const MCFragment &, const MCFixup &,
+ const MCValue &, uint64_t,
+ bool Resolved) const;
/// Simple predicate for targets where !Resolved implies requiring relaxation
virtual bool fixupNeedsRelaxation(const MCFixup &Fixup,
@@ -179,18 +177,16 @@ class LLVM_ABI MCAsmBackend {
}
// Defined by linker relaxation targets.
- virtual bool relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF,
- bool &WasRelaxed) const {
+ virtual bool relaxDwarfLineAddr(MCFragment &, bool &WasRelaxed) const {
return false;
}
- virtual bool relaxDwarfCFA(MCDwarfCallFrameFragment &DF,
- bool &WasRelaxed) const {
+ virtual bool relaxDwarfCFA(MCFragment &, bool &WasRelaxed) const {
return false;
}
// Defined by linker relaxation targets to possibly emit LEB128 relocations
// and set Value at the relocated location.
- virtual std::pair<bool, bool> relaxLEB128(MCLEBFragment &LF,
+ virtual std::pair<bool, bool> relaxLEB128(MCFragment &,
int64_t &Value) const {
return std::make_pair(false, false);
}
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h
index 1015992cedf29..858596ff8757c 100644
--- a/llvm/include/llvm/MC/MCAssembler.h
+++ b/llvm/include/llvm/MC/MCAssembler.h
@@ -34,13 +34,10 @@ namespace llvm {
class MCBoundaryAlignFragment;
class MCCVDefRangeFragment;
class MCCVInlineLineTableFragment;
-class MCDwarfCallFrameFragment;
-class MCDwarfLineAddrFragment;
-class MCEncodedFragment;
+class MCFragment;
class MCFixup;
class MCLEBFragment;
class MCPseudoProbeAddrFragment;
-class MCRelaxableFragment;
class MCSymbolRefExpr;
class raw_ostream;
class MCAsmBackend;
@@ -107,7 +104,7 @@ class MCAssembler {
/// Check whether a fixup can be satisfied, or whether it needs to be relaxed
/// (increased in size, in order to hold its value correctly).
- bool fixupNeedsRelaxation(const MCRelaxableFragment &, const MCFixup &) const;
+ bool fixupNeedsRelaxation(const MCFragment &, const MCFixup &) const;
void layoutSection(MCSection &Sec);
/// Perform one layout iteration and return the index of the first stable
@@ -116,11 +113,11 @@ class MCAssembler {
/// Perform relaxation on a single fragment.
bool relaxFragment(MCFragment &F);
- bool relaxInstruction(MCRelaxableFragment &IF);
- bool relaxLEB(MCLEBFragment &IF);
+ bool relaxInstruction(MCFragment &F);
+ bool relaxLEB(MCFragment &F);
bool relaxBoundaryAlign(MCBoundaryAlignFragment &BF);
- bool relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF);
- bool relaxDwarfCallFrameFragment(MCDwarfCallFrameFragment &DF);
+ bool relaxDwarfLineAddr(MCFragment &F);
+ bool relaxDwarfCallFrameFragment(MCFragment &F);
bool relaxCVInlineLineTable(MCCVInlineLineTableFragment &DF);
bool relaxCVDefRange(MCCVDefRangeFragment &DF);
bool relaxFill(MCFillFragment &F);
@@ -228,8 +225,7 @@ class MCAssembler {
/// Write the necessary bundle padding to \p OS.
/// Expects a fragment \p F containing instructions and its size \p FSize.
- LLVM_ABI void writeFragmentPadding(raw_ostream &OS,
- const MCEncodedFragment &F,
+ LLVM_ABI void writeFragmentPadding(raw_ostream &OS, const MCFragment &F,
uint64_t FSize) const;
LLVM_ABI void reportError(SMLoc L, const Twine &Msg) const;
diff --git a/llvm/include/llvm/MC/MCCodeView.h b/llvm/include/llvm/MC/MCCodeView.h
index 88f84a2462841..9cde44c71baff 100644
--- a/llvm/include/llvm/MC/MCCodeView.h
+++ b/llvm/include/llvm/MC/MCCodeView.h
@@ -26,7 +26,6 @@ namespace llvm {
class MCAssembler;
class MCCVDefRangeFragment;
class MCCVInlineLineTableFragment;
-class MCDataFragment;
class MCFragment;
class MCSection;
class MCSymbol;
@@ -231,7 +230,7 @@ class CodeViewContext {
StringMap<unsigned> StringTable;
/// The fragment that ultimately holds our strings.
- MCDataFragment *StrTabFragment = nullptr;
+ MCFragment *StrTabFragment = nullptr;
SmallVector<char, 0> StrTab = {'\0'};
/// Get a string table offset.
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 5a8ec17dae1cc..c137f6184a9a7 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -47,7 +47,6 @@ namespace llvm {
class CodeViewContext;
class MCAsmInfo;
-class MCDataFragment;
class MCInst;
class MCLabel;
class MCObjectFileInfo;
@@ -334,7 +333,7 @@ class MCContext {
void reportCommon(SMLoc Loc,
std::function<void(SMDiagnostic &, const SourceMgr *)>);
- MCDataFragment *allocInitialFragment(MCSection &Sec);
+ MCFragment *allocInitialFragment(MCSection &Sec);
MCSymbolTableEntry &getSymbolTableEntry(StringRef Name);
diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h
index aba87cb19b21c..5affe206a3535 100644
--- a/llvm/include/llvm/MC/MCELFStreamer.h
+++ b/llvm/include/llvm/MC/MCELFStreamer.h
@@ -17,7 +17,6 @@ namespace llvm {
class ELFObjectWriter;
class MCContext;
-class MCDataFragment;
class MCFragment;
class MCObjectWriter;
class MCSection;
@@ -51,7 +50,7 @@ class MCELFStreamer : public MCObjectStreamer {
void initSections(bool NoExecStack, const MCSubtargetInfo &STI) override;
void changeSection(MCSection *Section, uint32_t Subsection = 0) override;
void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
- void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCDataFragment &F,
+ void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment &F,
uint64_t Offset) override;
void emitWeakReference(MCSymbol *Alias, const MCSymbol *Target) override;
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h
index 58c18af406158..f8635fb989417 100644
--- a/llvm/include/llvm/MC/MCObjectStreamer.h
+++ b/llvm/include/llvm/MC/MCObjectStreamer.h
@@ -43,8 +43,8 @@ class MCObjectStreamer : public MCStreamer {
struct PendingMCFixup {
const MCSymbol *Sym;
MCFixup Fixup;
- MCDataFragment *DF;
- PendingMCFixup(const MCSymbol *McSym, MCDataFragment *F, MCFixup McFixup)
+ MCFragment *DF;
+ PendingMCFixup(const MCSymbol *McSym, MCFragment *F, MCFixup McFixup)
: Sym(McSym), Fixup(McFixup), DF(F) {}
};
SmallVector<PendingMCFixup, 2> PendingFixups;
@@ -95,7 +95,7 @@ class MCObjectStreamer : public MCStreamer {
/// fragment is not a data fragment.
/// Optionally a \p STI can be passed in so that a new fragment is created
/// if the Subtarget differs from the current fragment.
- MCDataFragment *getOrCreateDataFragment(const MCSubtargetInfo* STI = nullptr);
+ MCFragment *getOrCreateDataFragment(const MCSubtargetInfo *STI = nullptr);
protected:
bool changeSectionImpl(MCSection *Section, uint32_t Subsection);
diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h
index 16d57a7772a40..e018e98d66151 100644
--- a/llvm/include/llvm/MC/MCSection.h
+++ b/llvm/include/llvm/MC/MCSection.h
@@ -46,8 +46,6 @@ class LLVM_ABI MCSection {
friend MCAssembler;
friend MCObjectStreamer;
friend class MCFragment;
- friend class MCEncodedFragment;
- friend class MCRelaxableFragment;
static constexpr unsigned NonUniqueID = ~0U;
enum SectionVariant {
@@ -265,55 +263,55 @@ class MCFragment {
/// MCRelaxableFragment: x86-specific
bool AllowAutoPadding : 1;
- LLVM_ABI MCFragment(FragmentType Kind, bool HasInstructions);
-
-public:
- MCFragment() = delete;
- MCFragment(const MCFragment &) = delete;
- MCFragment &operator=(const MCFragment &) = delete;
-
- MCFragment *getNext() const { return Next; }
-
- FragmentType getKind() const { return Kind; }
-
- MCSection *getParent() const { return Parent; }
- void setParent(MCSection *Value) { Parent = Value; }
-
- LLVM_ABI const MCSymbol *getAtom() const;
-
- unsigned getLayoutOrder() const { return LayoutOrder; }
- void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
-
- /// Does this fragment have instructions emitted into it? By default
- /// this is false, but specific fragment types may set it to true.
- bool hasInstructions() const { return HasInstructions; }
-
- bool isLinkerRelaxable() const { return LinkerRelaxable; }
- void setLinkerRelaxable() { LinkerRelaxable = true; }
-
- LLVM_ABI void dump() const;
-};
-
-/// Interface implemented by fragments that contain encoded instructions and/or
-/// data.
-class MCEncodedFragment : public MCFragment {
uint8_t BundlePadding = 0;
+
uint32_t ContentStart = 0;
uint32_t ContentEnd = 0;
uint32_t FixupStart = 0;
uint32_t FixupEnd = 0;
-protected:
- MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions)
- : MCFragment(FType, HasInstructions) {}
+ uint32_t VarContentStart = 0;
+ uint32_t VarContentEnd = 0;
+ uint32_t VarFixupStart = 0;
+ uint32_t VarFixupEnd = 0;
- /// The MCSubtargetInfo in effect when the instruction was encoded.
- /// It must be non-null for instructions.
const MCSubtargetInfo *STI = nullptr;
+ // Optional variable-size tail used by various fragment types.
+ union Tail {
+ struct {
+ uint32_t Opcode;
+ uint32_t Flags;
+ uint32_t OperandStart;
+ uint32_t OperandSize;
+ } relax;
+ struct {
+ // True if this is a sleb128, false if uleb128.
+ bool IsSigned;
+ // The value this fragment should contain.
+ const MCExpr *Value;
+ } leb;
+ struct {
+ const MCExpr *AddrDelta;
+ } dwarf_frame;
+ struct {
+ // The expression for the difference of the two symbols that make up the
+ // address delta between two .loc dwarf directives.
+ const MCExpr *AddrDelta;
+ // The value of the difference between the two line numbers between two
+ // .loc dwarf directives.
+ int64_t LineDelta;
+ } dwarf;
+ } u{};
+
public:
- static bool classof(const MCFragment *F) {
- MCFragment::FragmentType Kind = F->getKind();
+ LLVM_ABI MCFragment(FragmentType Kind = MCFragment::FT_Data,
+ bool HasInstructions = false);
+ MCFragment(const MCFragment &) = delete;
+ MCFragment &operator=(const MCFragment &) = delete;
+
+ bool isEncoded() const {
+ MCFragment::FragmentType Kind = getKind();
switch (Kind) {
default:
return false;
@@ -329,20 +327,23 @@ class MCEncodedFragment : public MCFragment {
}
}
- /// Should this fragment be placed at the end of an aligned bundle?
- bool alignToBundleEnd() const { return AlignToBundleEnd; }
- void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
+ MCFragment *getNext() const { return Next; }
- /// Get the padding size that must be inserted before this fragment.
- /// Used for bundling. By default, no padding is inserted.
- /// Note that padding size is restricted to 8 bits. This is an optimization
- /// to reduce the amount of space used for each fragment. In practice, larger
- /// padding should never be required.
- uint8_t getBundlePadding() const { return BundlePadding; }
+ FragmentType getKind() const { return Kind; }
- /// Set the padding size for this fragment. By default it's a no-op,
- /// and only some fragments have a meaningful implementation.
- void setBundlePadding(uint8_t N) { BundlePadding = N; }
+ MCSection *getParent() const { return Parent; }
+ void setParent(MCSection *Value) { Parent = Value; }
+
+ LLVM_ABI const MCSymbol *getAtom() const;
+
+ unsigned getLayoutOrder() const { return LayoutOrder; }
+ void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
+
+ /// Does this fragment have instructions emitted into it? By default
+ /// this is false, but specific fragment types may set it to true.
+ bool hasInstructions() const { return HasInstructions; }
+
+ LLVM_ABI void dump() const;
/// Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
/// Guaranteed to be non-null if hasInstructions() == true
@@ -355,9 +356,27 @@ class MCEncodedFragment : public MCFragment {
this->STI = &STI;
}
+ bool isLinkerRelaxable() const { return LinkerRelaxable; }
+ void setLinkerRelaxable() { LinkerRelaxable = true; }
+
bool getAllowAutoPadding() const { return AllowAutoPadding; }
void setAllowAutoPadding(bool V) { AllowAutoPadding = V; }
+ /// Should this fragment be placed at the end of an aligned bundle?
+ bool alignToBundleEnd() const { return AlignToBundleEnd; }
+ void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
+
+ /// Get the padding size that must be inserted before this fragment.
+ /// Used for bundling. By default, no padding is inserted.
+ /// Note that padding size is restricted to 8 bits. This is an optimization
+ /// to reduce the amount of space used for each fragment. In practice, larger
+ /// padding should never be required.
+ uint8_t getBundlePadding() const { return BundlePadding; }
+
+ /// Set the padding size for this fragment. By default it's a no-op,
+ /// and only some fragments have a meaningful implementation.
+ void setBundlePadding(uint8_t N) { BundlePadding = N; }
+
// Content-related functions manage parent's storage using ContentStart and
// ContentSize.
void clearContents() { ContentEnd = ContentStart; }
@@ -394,7 +413,24 @@ class MCEncodedFragment : public MCFragment {
.slice(ContentStart, ContentEnd - ContentStart);
}
- // Fixup-related functions manage parent's storage using FixupStart and
+ void setVarContents(ArrayRef<char> Contents);
+ void clearVarContents() { setVarContents({}); }
+ MutableArrayRef<char> getVarContents() {
+ return MutableArrayRef(getParent()->ContentStorage)
+ .slice(VarContentStart, VarContentEnd - VarContentStart);
+ }
+ ArrayRef<char> getVarContents() const {
+ return ArrayRef(getParent()->ContentStorage)
+ .slice(VarContentStart, VarContentEnd - VarContentStart);
+ }
+
+ size_t getFixedSize() const { return ContentEnd - ContentStart; }
+ size_t getVarSize() const { return VarContentEnd - VarContentStart; }
+ size_t getSize() const {
+ return ContentEnd - ContentStart + (VarContentEnd - VarContentStart);
+ }
+
+ //== Fixup-related functions manage parent's storage using FixupStart and
// FixupSize.
void clearFixups() { FixupEnd = FixupStart; }
LLVM_ABI void addFixup(MCFixup Fixup);
@@ -409,65 +445,91 @@ class MCEncodedFragment : public MCFragment {
.slice(FixupStart, FixupEnd - FixupStart);
}
- size_t getSize() const { return ContentEnd - ContentStart; }
-};
-
-/// Fragment for data and encoded instructions.
-///
-class MCDataFragment : public MCEncodedFragment {
-public:
- MCDataFragment() : MCEncodedFragment(FT_Data, false) {}
-
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Data;
+ // Source fixup offsets are relative to the variable part's start.
+ // Stored fixup offsets are relative to the fixed part's start.
+ void setVarFixups(ArrayRef<MCFixup> Fixups);
+ void clearVarFixups() { setVarFixups({}); }
+ MutableArrayRef<MCFixup> getVarFixups() {
+ return MutableArrayRef(getParent()->FixupStorage)
+ .slice(VarFixupStart, VarFixupEnd - VarFixupStart);
}
-};
-
-/// A relaxable fragment holds on to its MCInst, since it may need to be
-/// relaxed during the assembler layout and relaxation stage.
-///
-class MCRelaxableFragment : public MCEncodedFragment {
- uint32_t Opcode = 0;
- uint32_t Flags = 0;
- uint32_t OperandStart = 0;
- uint32_t OperandSize = 0;
-
-public:
- MCRelaxableFragment(const MCSubtargetInfo &STI)
- : MCEncodedFragment(FT_Relaxable, true) {
- this->STI = &STI;
+ ArrayRef<MCFixup> getVarFixups() const {
+ return ArrayRef(getParent()->FixupStorage)
+ .slice(VarFixupStart, VarFixupEnd - VarFixupStart);
}
- unsigned getOpcode() const { return Opcode; }
+ //== FT_Relaxable functions
+ unsigned getOpcode() const {
+ assert(Kind == FT_Relaxable);
+ return u.relax.Opcode;
+ }
ArrayRef<MCOperand> getOperands() const {
+ assert(Kind == FT_Relaxable);
return MutableArrayRef(getParent()->MCOperandStorage)
- .slice(OperandStart, OperandSize);
+ .slice(u.relax.OperandStart, u.relax.OperandSize);
}
MCInst getInst() const {
+ assert(Kind == FT_Relaxable);
MCInst Inst;
- Inst.setOpcode(Opcode);
- Inst.setFlags(Flags);
+ Inst.setOpcode(u.relax.Opcode);
+ Inst.setFlags(u.relax.Flags);
Inst.setOperands(ArrayRef(getParent()->MCOperandStorage)
- .slice(OperandStart, OperandSize));
+ .slice(u.relax.OperandStart, u.relax.OperandSize));
return Inst;
}
void setInst(const MCInst &Inst) {
- Opcode = Inst.getOpcode();
- Flags = Inst.getFlags();
+ assert(Kind == FT_Relaxable);
+ u.relax.Opcode = Inst.getOpcode();
+ u.relax.Flags = Inst.getFlags();
auto &S = getParent()->MCOperandStorage;
- if (Inst.getNumOperands() > OperandSize) {
- OperandStart = S.size();
+ if (Inst.getNumOperands() > u.relax.OperandSize) {
+ u.relax.OperandStart = S.size();
S.resize_for_overwrite(S.size() + Inst.getNumOperands());
}
- OperandSize = Inst.getNumOperands();
- llvm::copy(Inst, S.begin() + OperandStart);
+ u.relax.OperandSize = Inst.getNumOperands();
+ llvm::copy(Inst, S.begin() + u.relax.OperandStart);
}
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Relaxable;
+ //== FT_LEB functions
+ const MCExpr &getLEBValue() const {
+ assert(Kind == FT_LEB);
+ return *u.leb.Value;
}
+ void setLEBValue(const MCExpr *Expr) { u.leb.Value = Expr; }
+ bool isLEBSigned() const { return u.leb.IsSigned; }
+ void setLEBSigned(bool S) { u.leb.IsSigned = S; }
+
+ //== FT_DwarfFrame functions
+ const MCExpr &getAddrDelta() const {
+ assert(Kind == FT_Dwarf || Kind == FT_DwarfFrame);
+ return *u.dwarf.AddrDelta;
+ }
+ void setAddrDelta(const MCExpr *E) {
+ assert(Kind == FT_Dwarf || Kind == FT_DwarfFrame);
+ u.dwarf.AddrDelta = E;
+ }
+ int64_t getLineDelta() const {
+ assert(Kind == FT_Dwarf);
+ return u.dwarf.LineDelta;
+ }
+ void setLineDelta(int64_t LineDelta) {
+ assert(Kind == FT_Dwarf);
+ u.dwarf.LineDelta = LineDelta;
+ }
+};
+
+/// Interface implemented by fragments that contain encoded instructions and/or
+/// data.
+class MCEncodedFragment : public MCFragment {
+protected:
+ MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions)
+ : MCFragment(FType, HasInstructions) {}
};
+// TODO Delete
+using MCDataFragment = MCFragment;
+using MCRelaxableFragment = MCFragment;
+
class MCAlignFragment : public MCFragment {
/// The alignment to ensure, in bytes.
Align Alignment;
@@ -602,67 +664,6 @@ class MCOrgFragment : public MCFragment {
}
};
-class MCLEBFragment final : public MCEncodedFragment {
- /// True if this is a sleb128, false if uleb128.
- bool IsSigned;
-
- /// The value this fragment should contain.
- const MCExpr *Value;
-
-public:
- MCLEBFragment(const MCExpr &Value, bool IsSigned)
- : MCEncodedFragment(FT_LEB, false), IsSigned(IsSigned), Value(&Value) {}
-
- const MCExpr &getValue() const { return *Value; }
- void setValue(const MCExpr *Expr) { Value = Expr; }
-
- bool isSigned() const { return IsSigned; }
-
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_LEB;
- }
-};
-
-class MCDwarfLineAddrFragment : public MCEncodedFragment {
- /// The value of the difference between the two line numbers
- /// between two .loc dwarf directives.
- int64_t LineDelta;
-
- /// The expression for the difference of the two symbols that
- /// make up the address delta between two .loc dwarf directives.
- const MCExpr *AddrDelta;
-
-public:
- MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta)
- : MCEncodedFragment(FT_Dwarf, false), LineDelta(LineDelta),
- AddrDelta(&AddrDelta) {}
-
- int64_t getLineDelta() const { return LineDelta; }
-
- const MCExpr &getAddrDelta() const { return *AddrDelta; }
-
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Dwarf;
- }
-};
-
-class MCDwarfCallFrameFragment : public MCEncodedFragment {
- /// The expression for the difference of the two symbols that
- /// make up the address delta between two .cfi_* dwarf directives.
- const MCExpr *AddrDelta;
-
-public:
- MCDwarfCallFrameFragment(const MCExpr &AddrDelta)
- : MCEncodedFragment(FT_DwarfFrame, false), AddrDelta(&AddrDelta) {}
-
- const MCExpr &getAddrDelta() const { return *AddrDelta; }
- void setAddrDelta(const MCExpr *E) { AddrDelta = E; }
-
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_DwarfFrame;
- }
-};
-
/// Represents a symbol table index fragment.
class MCSymbolIdFragment : public MCFragment {
const MCSymbol *Sym;
diff --git a/llvm/lib/MC/MCAsmBackend.cpp b/llvm/lib/MC/MCAsmBackend.cpp
index 39ef521031069..828d9cf56a71f 100644
--- a/llvm/lib/MC/MCAsmBackend.cpp
+++ b/llvm/lib/MC/MCAsmBackend.cpp
@@ -105,7 +105,8 @@ MCFixupKindInfo MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
return Builtins[Kind - FK_NONE];
}
-bool MCAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
+bool MCAsmBackend::fixupNeedsRelaxationAdvanced(const MCFragment &,
+ const MCFixup &Fixup,
const MCValue &, uint64_t Value,
bool Resolved) const {
if (!Resolved)
@@ -138,9 +139,7 @@ bool MCAsmBackend::isDarwinCanonicalPersonality(const MCSymbol *Sym) const {
const MCSubtargetInfo *MCAsmBackend::getSubtargetInfo(const MCFragment &F) {
const MCSubtargetInfo *STI = nullptr;
- if (auto *DF = dyn_cast<MCEncodedFragment>(&F)) {
- STI = DF->getSubtargetInfo();
- assert(!DF->hasInstructions() || STI != nullptr);
- }
+ STI = F.getSubtargetInfo();
+ assert(!F.hasInstructions() || STI != nullptr);
return STI;
}
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 480e6fe027beb..51027a4d9440b 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -203,7 +203,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
case MCFragment::FT_CVInlineLines:
case MCFragment::FT_CVDefRange:
case MCFragment::FT_PseudoProbe:
- return cast<MCEncodedFragment>(F).getContents().size();
+ return F.getSize();
case MCFragment::FT_Fill: {
auto &FF = cast<MCFillFragment>(F);
int64_t NumValues = 0;
@@ -285,8 +285,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
// Compute the amount of padding required before the fragment \p F to
// obey bundling restrictions, where \p FOffset is the fragment's offset in
// its section and \p FSize is the fragment's size.
-static uint64_t computeBundlePadding(unsigned BundleSize,
- const MCEncodedFragment *F,
+static uint64_t computeBundlePadding(unsigned BundleSize, const MCFragment *F,
uint64_t FOffset, uint64_t FSize) {
uint64_t OffsetInBundle = FOffset & (BundleSize - 1);
uint64_t EndOfFragment = OffsetInBundle + FSize;
@@ -322,7 +321,7 @@ static uint64_t computeBundlePadding(unsigned BundleSize,
return 0;
}
-void MCAssembler::layoutBundle(MCFragment *Prev, MCFragment *F) const {
+void MCAssembler::layoutBundle(MCFragment *Prev, MCFragment *EF) const {
// If bundling is enabled and this fragment has instructions in it, it has to
// obey the bundling restrictions. With padding, we'll have:
//
@@ -344,9 +343,6 @@ void MCAssembler::layoutBundle(MCFragment *Prev, MCFragment *F) const {
// within-fragment padding (which would produce less padding when N is less
// than the bundle size), but for now we don't.
//
- assert(isa<MCEncodedFragment>(F) &&
- "Only MCEncodedFragment implementations have instructions");
- MCEncodedFragment *EF = cast<MCEncodedFragment>(F);
uint64_t FSize = computeFragmentSize(*EF);
if (FSize > getBundleAlignSize())
@@ -358,9 +354,9 @@ void MCAssembler::layoutBundle(MCFragment *Prev, MCFragment *F) const {
report_fatal_error("Padding cannot exceed 255 bytes");
EF->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));
EF->Offset += RequiredBundlePadding;
- if (auto *DF = dyn_cast_or_null<MCDataFragment>(Prev))
- if (DF->getContents().empty())
- DF->Offset = EF->Offset;
+ if (Prev->getKind() == MCFragment::FT_Data)
+ if (Prev->getFixedSize() == 0)
+ Prev->Offset = EF->Offset;
}
// Simple getSymbolOffset helper for the non-variable case.
@@ -480,8 +476,7 @@ bool MCAssembler::registerSymbol(const MCSymbol &Symbol) {
return Changed;
}
-void MCAssembler::writeFragmentPadding(raw_ostream &OS,
- const MCEncodedFragment &EF,
+void MCAssembler::writeFragmentPadding(raw_ostream &OS, const MCFragment &EF,
uint64_t FSize) const {
assert(getBackendPtr() && "Expected assembler backend");
// Should NOP padding be written out before this fragment?
@@ -523,8 +518,7 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
llvm::endianness Endian = Asm.getBackend().Endian;
- if (const MCEncodedFragment *EF = dyn_cast<MCEncodedFragment>(&F))
- Asm.writeFragmentPadding(OS, *EF, FragmentSize);
+ Asm.writeFragmentPadding(OS, F, FragmentSize);
// This variable (and its dummy usage) is to participate in the assert at
// the end of the function.
@@ -546,8 +540,9 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
++stats::EmittedDataFragments;
else if (F.getKind() == MCFragment::FT_Relaxable)
++stats::EmittedRelaxableFragments;
- const auto &EF = cast<MCEncodedFragment>(F);
+ const auto &EF = cast<MCFragment>(F);
OS << StringRef(EF.getContents().data(), EF.getContents().size());
+ OS << StringRef(EF.getVarContents().data(), EF.getVarContents().size());
break;
}
case MCFragment::FT_Align: {
@@ -717,11 +712,10 @@ void MCAssembler::writeSectionData(raw_ostream &OS,
// Check that we aren't trying to write a non-zero contents (or fixups)
// into a virtual section. This is to support clients which use standard
// directives to fill the contents of virtual sections.
- const MCDataFragment &DF = cast<MCDataFragment>(F);
- if (DF.getFixups().size())
+ if (F.getFixups().size() || F.getVarFixups().size())
reportError(SMLoc(), Sec->getVirtualSectionKind() + " section '" +
Sec->getName() + "' cannot have fixups");
- for (char C : DF.getContents())
+ for (char C : F.getContents())
if (C) {
reportError(SMLoc(), Sec->getVirtualSectionKind() + " section '" +
Sec->getName() +
@@ -822,17 +816,28 @@ void MCAssembler::layout() {
// Evaluate and apply the fixups, generating relocation entries as necessary.
for (MCSection &Sec : *this) {
- for (MCFragment &Frag : Sec) {
+ for (MCFragment &F : Sec) {
// Process fragments with fixups here.
- if (auto *F = dyn_cast<MCEncodedFragment>(&Frag)) {
- auto Contents = F->getContents();
- for (MCFixup &Fixup : F->getFixups()) {
+ if (F.isEncoded()) {
+ auto Contents = F.getContents();
+ for (MCFixup &Fixup : F.getFixups()) {
uint64_t FixedValue;
MCValue Target;
- evaluateFixup(Frag, Fixup, Target, FixedValue,
+ evaluateFixup(F, Fixup, Target, FixedValue,
/*RecordReloc=*/true, Contents);
}
- } else if (auto *AF = dyn_cast<MCAlignFragment>(&Frag)) {
+ // In the variable part, fixup offsets are relative to the fixed part's
+ // start. Extend the variable contents to the left to account for the
+ // fixed part size.
+ Contents = MutableArrayRef(F.getParent()->ContentStorage)
+ .slice(F.VarContentStart - Contents.size(), F.getSize());
+ for (MCFixup &Fixup : F.getVarFixups()) {
+ uint64_t FixedValue;
+ MCValue Target;
+ evaluateFixup(F, Fixup, Target, FixedValue,
+ /*RecordReloc=*/true, Contents);
+ }
+ } else if (auto *AF = dyn_cast<MCAlignFragment>(&F)) {
// For RISC-V linker relaxation, an alignment relocation might be
// needed.
if (AF->hasEmitNops())
@@ -852,18 +857,18 @@ void MCAssembler::Finish() {
assert(PendingErrors.empty());
}
-bool MCAssembler::fixupNeedsRelaxation(const MCRelaxableFragment &F,
+bool MCAssembler::fixupNeedsRelaxation(const MCFragment &F,
const MCFixup &Fixup) const {
assert(getBackendPtr() && "Expected assembler backend");
MCValue Target;
uint64_t Value;
bool Resolved = evaluateFixup(F, const_cast<MCFixup &>(Fixup), Target, Value,
/*RecordReloc=*/false, {});
- return getBackend().fixupNeedsRelaxationAdvanced(Fixup, Target, Value,
+ return getBackend().fixupNeedsRelaxationAdvanced(F, Fixup, Target, Value,
Resolved);
}
-bool MCAssembler::relaxInstruction(MCRelaxableFragment &F) {
+bool MCAssembler::relaxInstruction(MCFragment &F) {
assert(getEmitterPtr() &&
"Expected CodeEmitter defined for relaxInstruction");
// If this inst doesn't ever need relaxation, ignore it. This occurs when we
@@ -874,7 +879,7 @@ bool MCAssembler::relaxInstruction(MCRelaxableFragment &F) {
return false;
bool DoRelax = false;
- for (const MCFixup &Fixup : F.getFixups())
+ for (const MCFixup &Fixup : F.getVarFixups())
if ((DoRelax = fixupNeedsRelaxation(F, Fixup)))
break;
if (!DoRelax)
@@ -882,7 +887,7 @@ bool MCAssembler::relaxInstruction(MCRelaxableFragment &F) {
++stats::RelaxedInstructions;
- // TODO Refactor relaxInstruction to accept MCRelaxableFragment and remove
+ // TODO Refactor relaxInstruction to accept MCFragment and remove
// `setInst`.
MCInst Relaxed = F.getInst();
getBackend().relaxInstruction(Relaxed, *F.getSubtargetInfo());
@@ -892,30 +897,30 @@ bool MCAssembler::relaxInstruction(MCRelaxableFragment &F) {
SmallVector<char, 16> Data;
SmallVector<MCFixup, 1> Fixups;
getEmitter().encodeInstruction(Relaxed, Data, Fixups, *F.getSubtargetInfo());
- F.setContents(Data);
- F.setFixups(Fixups);
+ F.setVarContents(Data);
+ F.setVarFixups(Fixups);
return true;
}
-bool MCAssembler::relaxLEB(MCLEBFragment &LF) {
- const unsigned OldSize = static_cast<unsigned>(LF.getContents().size());
+bool MCAssembler::relaxLEB(MCFragment &F) {
+ const unsigned OldSize = F.getVarSize();
unsigned PadTo = OldSize;
int64_t Value;
- LF.clearFixups();
+ F.clearVarFixups();
// Use evaluateKnownAbsolute for Mach-O as a hack: .subsections_via_symbols
// requires that .uleb128 A-B is foldable where A and B reside in different
// fragments. This is used by __gcc_except_table.
bool Abs = getWriter().getSubsectionsViaSymbols()
- ? LF.getValue().evaluateKnownAbsolute(Value, *this)
- : LF.getValue().evaluateAsAbsolute(Value, *this);
+ ? F.getLEBValue().evaluateKnownAbsolute(Value, *this)
+ : F.getLEBValue().evaluateAsAbsolute(Value, *this);
if (!Abs) {
bool Relaxed, UseZeroPad;
- std::tie(Relaxed, UseZeroPad) = getBackend().relaxLEB128(LF, Value);
+ std::tie(Relaxed, UseZeroPad) = getBackend().relaxLEB128(F, Value);
if (!Relaxed) {
- reportError(LF.getValue().getLoc(),
- Twine(LF.isSigned() ? ".s" : ".u") +
+ reportError(F.getLEBValue().getLoc(),
+ Twine(F.isLEBSigned() ? ".s" : ".u") +
"leb128 expression is not absolute");
- LF.setValue(MCConstantExpr::create(0, Context));
+ F.setLEBValue(MCConstantExpr::create(0, Context));
}
uint8_t Tmp[10]; // maximum size: ceil(64/7)
PadTo = std::max(PadTo, encodeULEB128(uint64_t(Value), Tmp));
@@ -928,11 +933,11 @@ bool MCAssembler::relaxLEB(MCLEBFragment &LF) {
// without either adding padding to an LEB fragment or adding extra padding
// to a later alignment fragment. To accommodate such tables, relaxation can
// only increase an LEB fragment size here, not decrease it. See PR35809.
- if (LF.isSigned())
+ if (F.isLEBSigned())
Size = encodeSLEB128(Value, Data, PadTo);
else
Size = encodeULEB128(Value, Data, PadTo);
- LF.setContents({reinterpret_cast<char *>(Data), Size});
+ F.setVarContents({reinterpret_cast<char *>(Data), Size});
return OldSize != Size;
}
@@ -997,48 +1002,48 @@ bool MCAssembler::relaxBoundaryAlign(MCBoundaryAlignFragment &BF) {
return true;
}
-bool MCAssembler::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF) {
+bool MCAssembler::relaxDwarfLineAddr(MCFragment &F) {
bool WasRelaxed;
- if (getBackend().relaxDwarfLineAddr(DF, WasRelaxed))
+ if (getBackend().relaxDwarfLineAddr(F, WasRelaxed))
return WasRelaxed;
MCContext &Context = getContext();
- auto OldSize = DF.getContents().size();
+ auto OldSize = F.getVarSize();
int64_t AddrDelta;
- bool Abs = DF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, *this);
+ bool Abs = F.getAddrDelta().evaluateKnownAbsolute(AddrDelta, *this);
assert(Abs && "We created a line delta with an invalid expression");
(void)Abs;
int64_t LineDelta;
- LineDelta = DF.getLineDelta();
+ LineDelta = F.getLineDelta();
SmallVector<char, 8> Data;
MCDwarfLineAddr::encode(Context, getDWARFLinetableParams(), LineDelta,
AddrDelta, Data);
- DF.setContents(Data);
- DF.clearFixups();
+ F.setVarContents(Data);
+ F.clearVarFixups();
return OldSize != Data.size();
}
-bool MCAssembler::relaxDwarfCallFrameFragment(MCDwarfCallFrameFragment &DF) {
+bool MCAssembler::relaxDwarfCallFrameFragment(MCFragment &F) {
bool WasRelaxed;
- if (getBackend().relaxDwarfCFA(DF, WasRelaxed))
+ if (getBackend().relaxDwarfCFA(F, WasRelaxed))
return WasRelaxed;
MCContext &Context = getContext();
int64_t Value;
- bool Abs = DF.getAddrDelta().evaluateAsAbsolute(Value, *this);
+ bool Abs = F.getAddrDelta().evaluateAsAbsolute(Value, *this);
if (!Abs) {
- reportError(DF.getAddrDelta().getLoc(),
+ reportError(F.getAddrDelta().getLoc(),
"invalid CFI advance_loc expression");
- DF.setAddrDelta(MCConstantExpr::create(0, Context));
+ F.setAddrDelta(MCConstantExpr::create(0, Context));
return false;
}
- auto OldSize = DF.getContents().size();
+ auto OldSize = F.getVarContents().size();
SmallVector<char, 8> Data;
MCDwarfFrameEmitter::encodeAdvanceLoc(Context, Value, Data);
- DF.setContents(Data);
- DF.clearFixups();
+ F.setVarContents(Data);
+ F.clearVarFixups();
return OldSize != Data.size();
}
@@ -1085,13 +1090,13 @@ bool MCAssembler::relaxFragment(MCFragment &F) {
case MCFragment::FT_Relaxable:
assert(!getRelaxAll() &&
"Did not expect a MCRelaxableFragment in RelaxAll mode");
- return relaxInstruction(cast<MCRelaxableFragment>(F));
+ return relaxInstruction(F);
+ case MCFragment::FT_LEB:
+ return relaxLEB(F);
case MCFragment::FT_Dwarf:
- return relaxDwarfLineAddr(cast<MCDwarfLineAddrFragment>(F));
+ return relaxDwarfLineAddr(F);
case MCFragment::FT_DwarfFrame:
- return relaxDwarfCallFrameFragment(cast<MCDwarfCallFrameFragment>(F));
- case MCFragment::FT_LEB:
- return relaxLEB(cast<MCLEBFragment>(F));
+ return relaxDwarfCallFrameFragment(F);
case MCFragment::FT_BoundaryAlign:
return relaxBoundaryAlign(cast<MCBoundaryAlignFragment>(F));
case MCFragment::FT_CVInlineLines:
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index e84b91c5c41b0..44fdaad8617f8 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -417,14 +417,14 @@ void MCELFStreamer::emitInstToData(const MCInst &Inst,
// data fragment because we want all the instructions in a group to get into
// the same fragment. Be careful not to do that for the first instruction in
// the group, though.
- MCDataFragment *DF;
+ MCFragment *DF;
if (Assembler.isBundlingEnabled()) {
MCSection &Sec = *getCurrentSectionOnly();
if (isBundleLocked() && !Sec.isBundleGroupBeforeFirstInst()) {
// If we are bundle-locked, we re-use the current fragment.
// The bundle-locking directive ensures this is a new data fragment.
- DF = cast<MCDataFragment>(getCurrentFragment());
+ DF = getCurrentFragment();
CheckBundleSubtargets(DF->getSubtargetInfo(), &STI);
} else {
DF = getContext().allocFragment<MCDataFragment>();
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index a196591744099..bef0462e8de5c 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -352,7 +352,7 @@ static void attemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,
// the linker.
bool BBeforeRelax = false, AAfterRelax = false;
for (auto F = FB; F; F = F->getNext()) {
- auto DF = dyn_cast<MCDataFragment>(F);
+ auto DF = F->getKind() == MCFragment::FT_Data ? F : nullptr;
if (DF && DF->isLinkerRelaxable()) {
if (&*F != FB || SBOffset != DF->getContents().size())
BBeforeRelax = true;
@@ -373,12 +373,12 @@ static void attemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,
unsigned Count;
if (DF) {
Displacement += DF->getContents().size();
- } else if (auto *RF = dyn_cast<MCRelaxableFragment>(F);
- RF && Asm->hasFinalLayout()) {
+ } else if (F->getKind() == MCFragment::FT_Relaxable &&
+ Asm->hasFinalLayout()) {
// Before finishLayout, a relaxable fragment's size is indeterminate.
// After layout, during relocation generation, it can be treated as a
// data fragment.
- Displacement += RF->getContents().size();
+ Displacement += F->getSize();
} else if (auto *AF = dyn_cast<MCAlignFragment>(F);
AF && Layout && AF->hasEmitNops() &&
!Asm->getBackend().shouldInsertExtraNopBytesForCodeAlign(
diff --git a/llvm/lib/MC/MCFragment.cpp b/llvm/lib/MC/MCFragment.cpp
index 5cf47e3325ff2..cd1bba8df62b9 100644
--- a/llvm/lib/MC/MCFragment.cpp
+++ b/llvm/lib/MC/MCFragment.cpp
@@ -24,12 +24,15 @@
using namespace llvm;
-static_assert(std::is_trivially_destructible_v<MCDataFragment>,
+static_assert(std::is_trivially_destructible_v<MCFragment>,
"fragment classes must be trivially destructible");
MCFragment::MCFragment(FragmentType Kind, bool HasInstructions)
: Kind(Kind), HasInstructions(HasInstructions), AlignToBundleEnd(false),
- LinkerRelaxable(false), AllowAutoPadding(false) {}
+ LinkerRelaxable(false), AllowAutoPadding(false) {
+ static_assert(sizeof(MCFragment::Tail) <= 16,
+ "Keep the variable-size tail small");
+}
const MCSymbol *MCFragment::getAtom() const {
return cast<MCSectionMachO>(Parent)->getAtom(LayoutOrder);
@@ -59,9 +62,8 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
// clang-format on
}
- if (const auto *EF = dyn_cast<MCEncodedFragment>(this))
- if (auto Pad = static_cast<unsigned>(EF->getBundlePadding()))
- OS << " BundlePadding:" << Pad;
+ if (auto Pad = static_cast<unsigned>(getBundlePadding()))
+ OS << " BundlePadding:" << Pad;
auto printFixups = [&](llvm::ArrayRef<MCFixup> Fixups) {
if (Fixups.empty())
@@ -83,18 +85,56 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
OS << " Nops";
break;
}
- case MCFragment::FT_Data: {
- const auto *F = cast<MCDataFragment>(this);
- if (F->isLinkerRelaxable())
+ case MCFragment::FT_Data:
+ case MCFragment::FT_Relaxable:
+ case MCFragment::FT_LEB:
+ case MCFragment::FT_Dwarf:
+ case MCFragment::FT_DwarfFrame: {
+ if (isLinkerRelaxable())
OS << " LinkerRelaxable";
- auto Contents = F->getContents();
- OS << " Size:" << Contents.size() << " [";
- for (unsigned i = 0, e = Contents.size(); i != e; ++i) {
+ auto Fixed = getContents();
+ auto Var = getVarContents();
+ OS << " Size:" << Fixed.size();
+ if (getKind() != MCFragment::FT_Data)
+ OS << '+' << Var.size();
+ OS << " [";
+ for (unsigned i = 0, e = Fixed.size(); i != e; ++i) {
if (i) OS << ",";
- OS << format("%02x", uint8_t(Contents[i]));
+ OS << format("%02x", uint8_t(Fixed[i]));
+ }
+ for (unsigned i = 0, e = Var.size(); i != e; ++i) {
+ if (Fixed.size() || i)
+ OS << ",";
+ OS << format("%02x", uint8_t(Var[i]));
}
OS << ']';
- printFixups(F->getFixups());
+ switch (getKind()) {
+ case MCFragment::FT_Data:
+ break;
+ case MCFragment::FT_Relaxable:
+ OS << ' ';
+ getInst().dump_pretty(OS);
+ break;
+ case MCFragment::FT_LEB: {
+ OS << " Value:";
+ getLEBValue().print(OS, nullptr);
+ OS << " Signed:" << isLEBSigned();
+ break;
+ }
+ case MCFragment::FT_Dwarf:
+ OS << " AddrDelta:";
+ getAddrDelta().print(OS, nullptr);
+ OS << " LineDelta:" << getLineDelta();
+ break;
+ case MCFragment::FT_DwarfFrame:
+ OS << " AddrDelta:";
+ getAddrDelta().print(OS, nullptr);
+ break;
+ default:
+ llvm_unreachable("");
+ }
+ printFixups(getFixups());
+ printFixups(getVarFixups());
break;
}
case MCFragment::FT_Fill: {
@@ -111,13 +151,6 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
<< " ControlledNopLength:" << NF->getControlledNopLength();
break;
}
- case MCFragment::FT_Relaxable: {
- const auto *F = cast<MCRelaxableFragment>(this);
- OS << " Size:" << F->getContents().size() << ' ';
- F->getInst().dump_pretty(OS);
- printFixups(F->getFixups());
- break;
- }
case MCFragment::FT_Org: {
const auto *OF = cast<MCOrgFragment>(this);
OS << " Offset:";
@@ -125,26 +158,6 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
OS << " Value:" << static_cast<unsigned>(OF->getValue());
break;
}
- case MCFragment::FT_Dwarf: {
- const auto *OF = cast<MCDwarfLineAddrFragment>(this);
- OS << " AddrDelta:";
- OF->getAddrDelta().print(OS, nullptr);
- OS << " LineDelta:" << OF->getLineDelta();
- break;
- }
- case MCFragment::FT_DwarfFrame: {
- const auto *CF = cast<MCDwarfCallFrameFragment>(this);
- OS << " AddrDelta:";
- CF->getAddrDelta().print(OS, nullptr);
- break;
- }
- case MCFragment::FT_LEB: {
- const auto *LF = cast<MCLEBFragment>(this);
- OS << " Value:";
- LF->getValue().print(OS, nullptr);
- OS << " Signed:" << LF->isSigned();
- break;
- }
case MCFragment::FT_BoundaryAlign: {
const auto *BF = cast<MCBoundaryAlignFragment>(this);
OS << " BoundarySize:" << BF->getAlignment().value()
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index b03c2283cdf4d..b43f109f68332 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -66,8 +66,8 @@ void MCObjectStreamer::resolvePendingFixups() {
// If the location symbol to relocate is in MCEncodedFragment,
// put the Fixup into location symbol's fragment. Otherwise
// put into PendingFixup.DF
- MCFragment *SymFragment = PendingFixup.Sym->getFragment();
- if (auto *F = dyn_cast<MCEncodedFragment>(SymFragment))
+ MCFragment *F = PendingFixup.Sym->getFragment();
+ if (F->isEncoded())
F->addFixup(PendingFixup.Fixup);
else
PendingFixup.DF->addFixup(PendingFixup.Fixup);
@@ -76,7 +76,8 @@ void MCObjectStreamer::resolvePendingFixups() {
}
// As a compile-time optimization, avoid allocating and evaluating an MCExpr
-// tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment.
+// tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment's fixed
+// part.
static std::optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
const MCSymbol *Lo) {
assert(Hi && Lo);
@@ -85,8 +86,11 @@ static std::optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
if (Hi->isVariable() || Lo->isVariable())
return std::nullopt;
auto *LoF = Lo->getFragment();
- if (!LoF || LoF->getKind() != MCFragment::FT_Data ||
- Hi->getFragment() != LoF || LoF->isLinkerRelaxable())
+ if (!LoF || Hi->getFragment() != LoF || LoF->isLinkerRelaxable())
+ return std::nullopt;
+ // If either symbol resides in the variable part, bail out.
+ auto Fixed = LoF->getFixedSize();
+ if (Lo->getOffset() > Fixed || Hi->getOffset() > Fixed)
return std::nullopt;
return Hi->getOffset() - Lo->getOffset();
@@ -131,7 +135,7 @@ void MCObjectStreamer::emitFrames(MCAsmBackend *MAB) {
MCDwarfFrameEmitter::Emit(*this, MAB, false);
}
-static bool canReuseDataFragment(const MCDataFragment &F,
+static bool canReuseDataFragment(const MCFragment &F,
const MCAssembler &Assembler,
const MCSubtargetInfo *STI) {
if (!F.hasInstructions())
@@ -150,11 +154,12 @@ static bool canReuseDataFragment(const MCDataFragment &F,
return !STI || F.getSubtargetInfo() == STI;
}
-MCDataFragment *
+MCFragment *
MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) {
- auto *F = dyn_cast<MCDataFragment>(getCurrentFragment());
- if (!F || !canReuseDataFragment(*F, *Assembler, STI)) {
- F = getContext().allocFragment<MCDataFragment>();
+ auto *F = getCurrentFragment();
+ if (F->getKind() != MCFragment::FT_Data ||
+ !canReuseDataFragment(*F, *Assembler, STI)) {
+ F = getContext().allocFragment<MCFragment>();
insert(F);
}
return F;
@@ -256,7 +261,10 @@ void MCObjectStreamer::emitULEB128Value(const MCExpr *Value) {
emitULEB128IntValue(IntValue);
return;
}
- insert(getContext().allocFragment<MCLEBFragment>(*Value, false));
+ auto *F = getOrCreateDataFragment();
+ F->Kind = MCFragment::FT_LEB;
+ F->setLEBSigned(false);
+ F->setLEBValue(Value);
}
void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) {
@@ -265,7 +273,10 @@ void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) {
emitSLEB128IntValue(IntValue);
return;
}
- insert(getContext().allocFragment<MCLEBFragment>(*Value, true));
+ auto *F = getOrCreateDataFragment();
+ F->Kind = MCFragment::FT_LEB;
+ F->setLEBSigned(true);
+ F->setLEBValue(Value);
}
void MCObjectStreamer::emitWeakReference(MCSymbol *Alias,
@@ -374,7 +385,6 @@ void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst,
return;
}
- // Otherwise emit to a separate fragment.
emitInstToFragment(Inst, STI);
}
@@ -396,18 +406,17 @@ void MCObjectStreamer::emitInstToData(const MCInst &Inst,
void MCObjectStreamer::emitInstToFragment(const MCInst &Inst,
const MCSubtargetInfo &STI) {
- // Always create a new, separate fragment here, because its size can change
- // during relaxation.
- MCRelaxableFragment *IF =
- getContext().allocFragment<MCRelaxableFragment>(STI);
- insert(IF);
- IF->setInst(Inst);
-
+ auto *F = getOrCreateDataFragment();
+ SmallVector<char, 16> Data;
SmallVector<MCFixup, 1> Fixups;
- getAssembler().getEmitter().encodeInstruction(
- Inst, IF->getContentsForAppending(), Fixups, STI);
- IF->doneAppending();
- IF->appendFixups(Fixups);
+ getAssembler().getEmitter().encodeInstruction(Inst, Data, Fixups, STI);
+
+ F->Kind = MCFragment::FT_Relaxable;
+ F->STI = &STI;
+ F->HasInstructions = true;
+ F->setVarContents(Data);
+ F->setVarFixups(Fixups);
+ F->setInst(Inst);
}
#ifndef NDEBUG
@@ -486,9 +495,10 @@ void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
return;
}
- const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel, SMLoc());
- insert(getContext().allocFragment<MCDwarfLineAddrFragment>(LineDelta,
- *AddrDelta));
+ auto *F = getOrCreateDataFragment();
+ F->Kind = MCFragment::FT_Dwarf;
+ F->setAddrDelta(buildSymbolDiff(*this, Label, LastLabel, SMLoc()));
+ F->setLineDelta(LineDelta);
}
void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section,
@@ -516,8 +526,9 @@ void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section,
void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
const MCSymbol *Label,
SMLoc Loc) {
- const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel, Loc);
- insert(getContext().allocFragment<MCDwarfCallFrameFragment>(*AddrDelta));
+ auto *F = getOrCreateDataFragment();
+ F->Kind = MCFragment::FT_DwarfFrame;
+ F->setAddrDelta(buildSymbolDiff(*this, Label, LastLabel, Loc));
}
void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
diff --git a/llvm/lib/MC/MCSection.cpp b/llvm/lib/MC/MCSection.cpp
index 56450033529bc..006120b0eb447 100644
--- a/llvm/lib/MC/MCSection.cpp
+++ b/llvm/lib/MC/MCSection.cpp
@@ -81,7 +81,7 @@ LLVM_DUMP_METHOD void MCSection::dump(
}
#endif
-void MCEncodedFragment::setContents(ArrayRef<char> Contents) {
+void MCFragment::setContents(ArrayRef<char> Contents) {
auto &S = getParent()->ContentStorage;
if (ContentStart + Contents.size() > ContentEnd) {
ContentStart = S.size();
@@ -91,9 +91,19 @@ void MCEncodedFragment::setContents(ArrayRef<char> Contents) {
llvm::copy(Contents, S.begin() + ContentStart);
}
-void MCEncodedFragment::addFixup(MCFixup Fixup) { appendFixups({Fixup}); }
+void MCFragment::setVarContents(ArrayRef<char> Contents) {
+ auto &S = getParent()->ContentStorage;
+ if (VarContentStart + Contents.size() > VarContentEnd) {
+ VarContentStart = S.size();
+ S.resize_for_overwrite(S.size() + Contents.size());
+ }
+ VarContentEnd = VarContentStart + Contents.size();
+ llvm::copy(Contents, S.begin() + VarContentStart);
+}
+
+void MCFragment::addFixup(MCFixup Fixup) { appendFixups({Fixup}); }
-void MCEncodedFragment::appendFixups(ArrayRef<MCFixup> Fixups) {
+void MCFragment::appendFixups(ArrayRef<MCFixup> Fixups) {
auto &S = getParent()->FixupStorage;
if (LLVM_UNLIKELY(FixupEnd != S.size())) {
// Move the elements to the end. Reserve space to avoid invalidating
@@ -107,7 +117,7 @@ void MCEncodedFragment::appendFixups(ArrayRef<MCFixup> Fixups) {
FixupEnd = S.size();
}
-void MCEncodedFragment::setFixups(ArrayRef<MCFixup> Fixups) {
+void MCFragment::setFixups(ArrayRef<MCFixup> Fixups) {
auto &S = getParent()->FixupStorage;
if (FixupStart + Fixups.size() > FixupEnd) {
FixupStart = S.size();
@@ -116,3 +126,19 @@ void MCEncodedFragment::setFixups(ArrayRef<MCFixup> Fixups) {
FixupEnd = FixupStart + Fixups.size();
llvm::copy(Fixups, S.begin() + FixupStart);
}
+
+void MCFragment::setVarFixups(ArrayRef<MCFixup> Fixups) {
+ auto &S = getParent()->FixupStorage;
+ if (VarFixupStart + Fixups.size() > VarFixupEnd) {
+ VarFixupStart = S.size();
+ S.resize_for_overwrite(S.size() + Fixups.size());
+ }
+ VarFixupEnd = VarFixupStart + Fixups.size();
+ // Source fixup offsets are relative to the variable part's start. Add the
+ // fixed part size to make them relative to the fixed part's start.
+ std::transform(Fixups.begin(), Fixups.end(), S.begin() + VarFixupStart,
+ [Fixed = getFixedSize()](MCFixup F) {
+ F.setOffset(Fixed + F.getOffset());
+ return F;
+ });
+}
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index d148b521ff9fe..5c4a355f59fc4 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -711,10 +711,8 @@ static void addData(SmallVectorImpl<char> &DataBytes,
llvm_unreachable("The fill should be an assembler constant");
DataBytes.insert(DataBytes.end(), Fill->getValueSize() * NumValues,
Fill->getValue());
- } else if (auto *LEB = dyn_cast<MCLEBFragment>(&Frag)) {
- llvm::append_range(DataBytes, LEB->getContents());
} else {
- llvm::append_range(DataBytes, cast<MCDataFragment>(Frag).getContents());
+ llvm::append_range(DataBytes, Frag.getContents());
}
}
@@ -1884,7 +1882,7 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
if (WS.getName().substr(PrefixLength + 1).getAsInteger(10, Priority))
report_fatal_error("invalid .init_array section priority");
}
- const auto &DataFrag = cast<MCDataFragment>(Frag);
+ const auto &DataFrag = Frag;
assert(llvm::all_of(DataFrag.getContents(), [](char C) { return !C; }));
for (const MCFixup &Fixup : DataFrag.getFixups()) {
assert(Fixup.getKind() ==
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
index f2144375fd95e..233f42b7a4790 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
@@ -529,11 +529,9 @@ void AArch64TargetELFStreamer::finish() {
static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
bool Empty = true;
for (auto &F : *Text) {
- if (auto *DF = dyn_cast<MCDataFragment>(&F)) {
- if (!DF->getContents().empty()) {
- Empty = false;
- break;
- }
+ if (F.getSize()) {
+ Empty = false;
+ break;
}
}
if (Empty)
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 376bddb120d5f..980031355bf43 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -311,7 +311,8 @@ static bool needsInterworking(const MCAssembler &Asm, const MCSymbol *Sym,
return false;
}
-bool ARMAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
+bool ARMAsmBackend::fixupNeedsRelaxationAdvanced(const MCFragment &,
+ const MCFixup &Fixup,
const MCValue &Target,
uint64_t Value,
bool Resolved) const {
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
index 877e3afdb1d57..07d2cf784c442 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
@@ -51,7 +51,8 @@ class ARMAsmBackend : public MCAsmBackend {
const char *reasonForFixupRelaxation(const MCFixup &Fixup,
uint64_t Value) const;
- bool fixupNeedsRelaxationAdvanced(const MCFixup &, const MCValue &, uint64_t,
+ bool fixupNeedsRelaxationAdvanced(const MCFragment &, const MCFixup &,
+ const MCValue &, uint64_t,
bool) const override;
void relaxInstruction(MCInst &Inst,
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
index c61e405bd3a02..910806e99836a 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
@@ -650,11 +650,11 @@ class ARMELFStreamer : public MCELFStreamer {
// This is a tentative symbol, it won't really be emitted until it's
// actually needed.
ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
- auto *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
- if (!DF)
+ auto *DF = getCurrentFragment();
+ if (DF->getKind() != MCFragment::FT_Data)
return;
EMS->F = DF;
- EMS->Offset = DF->getContents().size();
+ EMS->Offset = DF->getFixedSize();
LastEMSInfo->State = EMS_Data;
return;
}
@@ -1145,9 +1145,8 @@ void ARMTargetELFStreamer::finish() {
auto *Text =
static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
for (auto &F : *Text)
- if (auto *DF = dyn_cast<MCDataFragment>(&F))
- if (!DF->getContents().empty())
- return;
+ if (F.getSize())
+ return;
Text->setFlags(Text->getFlags() | ELF::SHF_ARM_PURECODE);
}
}
diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
index ce1da6e58b9cd..5b5112881fd3d 100644
--- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
+++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
@@ -157,7 +157,8 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
}
}
-bool CSKYAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
+bool CSKYAsmBackend::fixupNeedsRelaxationAdvanced(const MCFragment &,
+ const MCFixup &Fixup,
const MCValue &,
uint64_t Value,
bool Resolved) const {
diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
index 1d3a22c2bbbb4..1c8516fbf53a7 100644
--- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
+++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
@@ -38,7 +38,8 @@ class CSKYAsmBackend : public MCAsmBackend {
void relaxInstruction(MCInst &Inst,
const MCSubtargetInfo &STI) const override;
- bool fixupNeedsRelaxationAdvanced(const MCFixup &, const MCValue &, uint64_t,
+ bool fixupNeedsRelaxationAdvanced(const MCFragment &, const MCFixup &,
+ const MCValue &, uint64_t,
bool) const override;
bool writeNopData(raw_ostream &OS, uint64_t Count,
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp
index de7bd5d4b2c66..2bb8069062ba5 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp
@@ -46,16 +46,15 @@ class HexagonAsmBackend : public MCAsmBackend {
MCInst * Extender;
unsigned MaxPacketSize;
- void ReplaceInstruction(MCCodeEmitter &E, MCRelaxableFragment &RF,
- MCInst &HMB) const {
+ void ReplaceInstruction(MCCodeEmitter &E, MCFragment &RF, MCInst &HMB) const {
SmallVector<MCFixup, 4> Fixups;
SmallString<256> Code;
E.encodeInstruction(HMB, Code, Fixups, *RF.getSubtargetInfo());
// Update the fragment.
RF.setInst(HMB);
- RF.setContents(Code);
- RF.getFixups() = Fixups;
+ RF.setVarContents(Code);
+ RF.setVarFixups(Fixups);
}
public:
@@ -438,15 +437,15 @@ class HexagonAsmBackend : public MCAsmBackend {
/// fixupNeedsRelaxation - Target specific predicate for whether a given
/// fixup requires the associated instruction to be relaxed.
- bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, const MCValue &,
- uint64_t Value,
+ bool fixupNeedsRelaxationAdvanced(const MCFragment &F, const MCFixup &Fixup,
+ const MCValue &, uint64_t Value,
bool Resolved) const override {
MCInst const &MCB = RelaxedMCB;
assert(HexagonMCInstrInfo::isBundle(MCB));
*RelaxTarget = nullptr;
MCInst &MCI = const_cast<MCInst &>(HexagonMCInstrInfo::instruction(
- MCB, Fixup.getOffset() / HEXAGON_INSTR_SIZE));
+ MCB, (Fixup.getOffset() - F.getFixedSize()) / HEXAGON_INSTR_SIZE));
bool Relaxable = isInstRelaxable(MCI);
if (Relaxable == false)
return false;
@@ -595,7 +594,7 @@ class HexagonAsmBackend : public MCAsmBackend {
}
case MCFragment::FT_Relaxable: {
MCContext &Context = getContext();
- auto &RF = cast<MCRelaxableFragment>(*Frags[K]);
+ auto &RF = *Frags[K];
MCInst Inst = RF.getInst();
const bool WouldTraverseLabel = llvm::any_of(
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
index 1b8893029bb33..3df5f1e619168 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
@@ -279,23 +279,23 @@ getRelocPairForSize(unsigned Size) {
}
}
-std::pair<bool, bool> LoongArchAsmBackend::relaxLEB128(MCLEBFragment &LF,
+std::pair<bool, bool> LoongArchAsmBackend::relaxLEB128(MCFragment &LF,
int64_t &Value) const {
- const MCExpr &Expr = LF.getValue();
- if (LF.isSigned() || !Expr.evaluateKnownAbsolute(Value, *Asm))
+ const MCExpr &Expr = LF.getLEBValue();
+ if (LF.isLEBSigned() || !Expr.evaluateKnownAbsolute(Value, *Asm))
return std::make_pair(false, false);
- LF.addFixup(MCFixup::create(0, &Expr, FK_Data_leb128));
+ LF.setVarFixups({MCFixup::create(0, &Expr, FK_Data_leb128)});
return std::make_pair(true, true);
}
-bool LoongArchAsmBackend::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF,
+bool LoongArchAsmBackend::relaxDwarfLineAddr(MCFragment &DF,
bool &WasRelaxed) const {
MCContext &C = getContext();
int64_t LineDelta = DF.getLineDelta();
const MCExpr &AddrDelta = DF.getAddrDelta();
SmallVector<MCFixup, 1> Fixups;
- size_t OldSize = DF.getContents().size();
+ size_t OldSize = DF.getVarSize();
int64_t Value;
if (AddrDelta.evaluateAsAbsolute(Value, *Asm))
@@ -349,17 +349,16 @@ bool LoongArchAsmBackend::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF,
OS << uint8_t(dwarf::DW_LNS_copy);
}
- DF.setContents(Data);
- DF.setFixups(Fixups);
+ DF.setVarContents(Data);
+ DF.setVarFixups(Fixups);
WasRelaxed = OldSize != Data.size();
return true;
}
-bool LoongArchAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF,
- bool &WasRelaxed) const {
- const MCExpr &AddrDelta = DF.getAddrDelta();
+bool LoongArchAsmBackend::relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const {
+ const MCExpr &AddrDelta = F.getAddrDelta();
SmallVector<MCFixup, 2> Fixups;
- size_t OldSize = DF.getContents().size();
+ size_t OldSize = F.getVarContents().size();
int64_t Value;
if (AddrDelta.evaluateAsAbsolute(Value, *Asm))
@@ -371,9 +370,9 @@ bool LoongArchAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF,
assert(getContext().getAsmInfo()->getMinInstAlignment() == 1 &&
"expected 1-byte alignment");
if (Value == 0) {
- DF.clearContents();
- DF.clearFixups();
- WasRelaxed = OldSize != DF.getContents().size();
+ F.clearVarContents();
+ F.clearVarFixups();
+ WasRelaxed = OldSize != 0;
return true;
}
@@ -405,8 +404,8 @@ bool LoongArchAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF,
} else {
llvm_unreachable("unsupported CFA encoding");
}
- DF.setContents(Data);
- DF.setFixups(Fixups);
+ F.setVarContents(Data);
+ F.setVarFixups(Fixups);
WasRelaxed = OldSize != Data.size();
return true;
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h
index 4446cadf11e22..b32ba067810ce 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h
@@ -59,11 +59,9 @@ class LoongArchAsmBackend : public MCAsmBackend {
MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override;
- bool relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF,
- bool &WasRelaxed) const override;
- bool relaxDwarfCFA(MCDwarfCallFrameFragment &DF,
- bool &WasRelaxed) const override;
- std::pair<bool, bool> relaxLEB128(MCLEBFragment &LF,
+ bool relaxDwarfLineAddr(MCFragment &F, bool &WasRelaxed) const override;
+ bool relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const override;
+ std::pair<bool, bool> relaxLEB128(MCFragment &F,
int64_t &Value) const override;
bool writeNopData(raw_ostream &OS, uint64_t Count,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 89a87798d71e4..48bc4c1f03166 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -103,7 +103,8 @@ MCFixupKindInfo RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
return Infos[Kind - FirstTargetFixupKind];
}
-bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
+bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFragment &,
+ const MCFixup &Fixup,
const MCValue &,
uint64_t Value,
bool Resolved) const {
@@ -267,14 +268,14 @@ void RISCVAsmBackend::relaxInstruction(MCInst &Inst,
Inst = std::move(Res);
}
-bool RISCVAsmBackend::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF,
+bool RISCVAsmBackend::relaxDwarfLineAddr(MCFragment &F,
bool &WasRelaxed) const {
MCContext &C = getContext();
- int64_t LineDelta = DF.getLineDelta();
- const MCExpr &AddrDelta = DF.getAddrDelta();
+ int64_t LineDelta = F.getLineDelta();
+ const MCExpr &AddrDelta = F.getAddrDelta();
SmallVector<MCFixup, 1> Fixups;
- size_t OldSize = DF.getContents().size();
+ size_t OldSize = F.getVarSize();
int64_t Value;
[[maybe_unused]] bool IsAbsolute =
@@ -327,17 +328,16 @@ bool RISCVAsmBackend::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF,
OS << uint8_t(dwarf::DW_LNS_copy);
}
- DF.setContents(Data);
- DF.setFixups(Fixups);
+ F.setVarContents(Data);
+ F.setVarFixups(Fixups);
WasRelaxed = OldSize != Data.size();
return true;
}
-bool RISCVAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF,
- bool &WasRelaxed) const {
- const MCExpr &AddrDelta = DF.getAddrDelta();
+bool RISCVAsmBackend::relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const {
+ const MCExpr &AddrDelta = F.getAddrDelta();
SmallVector<MCFixup, 2> Fixups;
- size_t OldSize = DF.getContents().size();
+ size_t OldSize = F.getVarSize();
int64_t Value;
if (AddrDelta.evaluateAsAbsolute(Value, *Asm))
@@ -349,9 +349,9 @@ bool RISCVAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF,
assert(getContext().getAsmInfo()->getMinInstAlignment() == 1 &&
"expected 1-byte alignment");
if (Value == 0) {
- DF.clearContents();
- DF.clearFixups();
- WasRelaxed = OldSize != DF.getContents().size();
+ F.clearVarContents();
+ F.clearVarFixups();
+ WasRelaxed = OldSize != 0;
return true;
}
@@ -382,20 +382,20 @@ bool RISCVAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF,
} else {
llvm_unreachable("unsupported CFA encoding");
}
- DF.setContents(Data);
- DF.setFixups(Fixups);
+ F.setVarContents(Data);
+ F.setVarFixups(Fixups);
WasRelaxed = OldSize != Data.size();
return true;
}
-std::pair<bool, bool> RISCVAsmBackend::relaxLEB128(MCLEBFragment &LF,
+std::pair<bool, bool> RISCVAsmBackend::relaxLEB128(MCFragment &LF,
int64_t &Value) const {
- if (LF.isSigned())
+ if (LF.isLEBSigned())
return std::make_pair(false, false);
- const MCExpr &Expr = LF.getValue();
+ const MCExpr &Expr = LF.getLEBValue();
if (ULEB128Reloc) {
- LF.addFixup(MCFixup::create(0, &Expr, FK_Data_leb128));
+ LF.setVarFixups({MCFixup::create(0, &Expr, FK_Data_leb128)});
}
return std::make_pair(Expr.evaluateKnownAbsolute(Value, *Asm), false);
}
@@ -620,14 +620,13 @@ static const MCFixup *getPCRelHiFixup(const MCSpecifierExpr &Expr,
const MCSymbol *AUIPCSymbol = AUIPCLoc.getAddSym();
if (!AUIPCSymbol)
return nullptr;
- const auto *DF = dyn_cast_or_null<MCDataFragment>(AUIPCSymbol->getFragment());
-
+ const auto *DF = AUIPCSymbol->getFragment();
if (!DF)
return nullptr;
uint64_t Offset = AUIPCSymbol->getOffset();
if (DF->getContents().size() == Offset) {
- DF = dyn_cast_or_null<MCDataFragment>(DF->getNext());
+ DF = DF->getNext();
if (!DF)
return nullptr;
Offset = 0;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
index 1f1a6f5fe31a0..8c10fbec3c8fc 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
@@ -60,7 +60,8 @@ class RISCVAsmBackend : public MCAsmBackend {
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override;
- bool fixupNeedsRelaxationAdvanced(const MCFixup &, const MCValue &, uint64_t,
+ bool fixupNeedsRelaxationAdvanced(const MCFragment &, const MCFixup &,
+ const MCValue &, uint64_t,
bool) const override;
std::optional<MCFixupKind> getFixupKind(StringRef Name) const override;
@@ -72,11 +73,9 @@ class RISCVAsmBackend : public MCAsmBackend {
void relaxInstruction(MCInst &Inst,
const MCSubtargetInfo &STI) const override;
- bool relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF,
- bool &WasRelaxed) const override;
- bool relaxDwarfCFA(MCDwarfCallFrameFragment &DF,
- bool &WasRelaxed) const override;
- std::pair<bool, bool> relaxLEB128(MCLEBFragment &LF,
+ bool relaxDwarfLineAddr(MCFragment &F, bool &WasRelaxed) const override;
+ bool relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const override;
+ std::pair<bool, bool> relaxLEB128(MCFragment &LF,
int64_t &Value) const override;
bool writeNopData(raw_ostream &OS, uint64_t Count,
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index ff2df3d5b192a..9023fc40d4ed8 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -26,6 +26,7 @@
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/TargetRegistry.h"
@@ -177,20 +178,20 @@ class X86AsmBackend : public MCAsmBackend {
bool mayNeedRelaxation(unsigned Opcode, ArrayRef<MCOperand> Operands,
const MCSubtargetInfo &STI) const override;
- bool fixupNeedsRelaxationAdvanced(const MCFixup &, const MCValue &, uint64_t,
+ bool fixupNeedsRelaxationAdvanced(const MCFragment &, const MCFixup &,
+ const MCValue &, uint64_t,
bool) const override;
void relaxInstruction(MCInst &Inst,
const MCSubtargetInfo &STI) const override;
- bool padInstructionViaRelaxation(MCRelaxableFragment &RF,
- MCCodeEmitter &Emitter,
+ bool padInstructionViaRelaxation(MCFragment &RF, MCCodeEmitter &Emitter,
unsigned &RemainingSize) const;
- bool padInstructionViaPrefix(MCRelaxableFragment &RF, MCCodeEmitter &Emitter,
+ bool padInstructionViaPrefix(MCFragment &RF, MCCodeEmitter &Emitter,
unsigned &RemainingSize) const;
- bool padInstructionEncoding(MCRelaxableFragment &RF, MCCodeEmitter &Emitter,
+ bool padInstructionEncoding(MCFragment &RF, MCCodeEmitter &Emitter,
unsigned &RemainingSize) const;
bool finishLayout(const MCAssembler &Asm) const override;
@@ -409,10 +410,9 @@ isRightAfterData(MCFragment *CurrentFragment,
// it, returns true.
// - Otherwise returns false.
// - If the fragment is not a DataFragment, returns false.
- if (auto *DF = dyn_cast_or_null<MCDataFragment>(F))
- return DF->getContents().size() &&
- (DF != PrevInstPosition.first ||
- DF->getContents().size() != PrevInstPosition.second);
+ if (F->getKind() == MCFragment::FT_Data)
+ return F->getFixedSize() && (F != PrevInstPosition.first ||
+ F->getFixedSize() != PrevInstPosition.second);
return false;
}
@@ -421,11 +421,7 @@ isRightAfterData(MCFragment *CurrentFragment,
static size_t getSizeForInstFragment(const MCFragment *F) {
if (!F || !F->hasInstructions())
return 0;
- // MCEncodedFragmentWithContents being templated makes this tricky.
- if (auto *DF = dyn_cast<MCEncodedFragment>(F))
- return DF->getContents().size();
- else
- llvm_unreachable("Unknown fragment with instructions!");
+ return F->getSize();
}
/// Return true if we can insert NOP or prefixes automatically before the
@@ -551,8 +547,8 @@ void X86AsmBackend::emitInstructionBegin(MCObjectStreamer &OS,
void X86AsmBackend::emitInstructionEnd(MCObjectStreamer &OS,
const MCInst &Inst) {
MCFragment *CF = OS.getCurrentFragment();
- if (auto *F = dyn_cast_or_null<MCRelaxableFragment>(CF))
- F->setAllowAutoPadding(canPadInst(Inst, OS));
+ if (CF->getKind() == MCFragment::FT_Relaxable)
+ CF->setAllowAutoPadding(canPadInst(Inst, OS));
// Update PrevInstOpcode here, canPadInst() reads that.
PrevInstOpcode = Inst.getOpcode();
@@ -756,7 +752,8 @@ bool X86AsmBackend::mayNeedRelaxation(unsigned Opcode,
Operands[Operands.size() - 1 - SkipOperands].isExpr());
}
-bool X86AsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
+bool X86AsmBackend::fixupNeedsRelaxationAdvanced(const MCFragment &,
+ const MCFixup &Fixup,
const MCValue &Target,
uint64_t Value,
bool Resolved) const {
@@ -785,7 +782,7 @@ void X86AsmBackend::relaxInstruction(MCInst &Inst,
Inst.setOpcode(RelaxedOp);
}
-bool X86AsmBackend::padInstructionViaPrefix(MCRelaxableFragment &RF,
+bool X86AsmBackend::padInstructionViaPrefix(MCFragment &RF,
MCCodeEmitter &Emitter,
unsigned &RemainingSize) const {
if (!RF.getAllowAutoPadding())
@@ -798,7 +795,7 @@ bool X86AsmBackend::padInstructionViaPrefix(MCRelaxableFragment &RF,
*RF.getSubtargetInfo()))
return false;
- const unsigned OldSize = RF.getContents().size();
+ const unsigned OldSize = RF.getVarContents().size();
if (OldSize == 15)
return false;
@@ -827,19 +824,18 @@ bool X86AsmBackend::padInstructionViaPrefix(MCRelaxableFragment &RF,
SmallString<256> Code;
Code.append(PrefixBytesToAdd, Prefix);
- Code.append(RF.getContents().begin(), RF.getContents().end());
- RF.setContents(Code);
+ Code.append(RF.getVarContents().begin(), RF.getVarContents().end());
+ RF.setVarContents(Code);
// Adjust the fixups for the change in offsets
- for (auto &F : RF.getFixups()) {
- F.setOffset(F.getOffset() + PrefixBytesToAdd);
- }
+ for (auto &F : RF.getVarFixups())
+ F.setOffset(PrefixBytesToAdd + F.getOffset());
RemainingSize -= PrefixBytesToAdd;
return true;
}
-bool X86AsmBackend::padInstructionViaRelaxation(MCRelaxableFragment &RF,
+bool X86AsmBackend::padInstructionViaRelaxation(MCFragment &RF,
MCCodeEmitter &Emitter,
unsigned &RemainingSize) const {
if (!mayNeedRelaxation(RF.getOpcode(), RF.getOperands(),
@@ -854,20 +850,20 @@ bool X86AsmBackend::padInstructionViaRelaxation(MCRelaxableFragment &RF,
SmallVector<MCFixup, 4> Fixups;
SmallString<15> Code;
Emitter.encodeInstruction(Relaxed, Code, Fixups, *RF.getSubtargetInfo());
- const unsigned OldSize = RF.getContents().size();
+ const unsigned OldSize = RF.getVarContents().size();
const unsigned NewSize = Code.size();
assert(NewSize >= OldSize && "size decrease during relaxation?");
unsigned Delta = NewSize - OldSize;
if (Delta > RemainingSize)
return false;
RF.setInst(Relaxed);
- RF.setContents(Code);
- RF.setFixups(Fixups);
+ RF.setVarContents(Code);
+ RF.setVarFixups(Fixups);
RemainingSize -= Delta;
return true;
}
-bool X86AsmBackend::padInstructionEncoding(MCRelaxableFragment &RF,
+bool X86AsmBackend::padInstructionEncoding(MCFragment &RF,
MCCodeEmitter &Emitter,
unsigned &RemainingSize) const {
bool Changed = false;
@@ -900,7 +896,7 @@ bool X86AsmBackend::finishLayout(const MCAssembler &Asm) const {
if (!Sec.isText())
continue;
- SmallVector<MCRelaxableFragment *, 4> Relaxable;
+ SmallVector<MCFragment *, 4> Relaxable;
for (MCSection::iterator I = Sec.begin(), IE = Sec.end(); I != IE; ++I) {
MCFragment &F = *I;
@@ -911,7 +907,7 @@ bool X86AsmBackend::finishLayout(const MCAssembler &Asm) const {
continue;
if (F.getKind() == MCFragment::FT_Relaxable) {
- auto &RF = cast<MCRelaxableFragment>(*I);
+ auto &RF = cast<MCFragment>(*I);
Relaxable.push_back(&RF);
continue;
}
diff --git a/llvm/test/MC/ELF/mc-dump.s b/llvm/test/MC/ELF/mc-dump.s
index 36d3a05768dc6..ee035ef5b0e35 100644
--- a/llvm/test/MC/ELF/mc-dump.s
+++ b/llvm/test/MC/ELF/mc-dump.s
@@ -11,40 +11,46 @@
# CHECK-NEXT:0 Align Align:4 Value:0 ValueSize:1 MaxBytesToEmit:4 Nops
# CHECK-NEXT:0 Data Size:0 []
# CHECK-NEXT: Symbol @0 _start
+# CHECK-NEXT: Symbol @0 Temporary
# CHECK-NEXT:0 Org Offset:3 Value:0
-# CHECK-NEXT:3 Relaxable Size:2 <MCInst #2001 <MCOperand Expr:.Ltmp0>>
+# CHECK-NEXT:3 Relaxable Size:0+2 [eb,00] <MCInst #[[#]] <MCOperand Expr:.Ltmp0>>
# CHECK-NEXT: Fixup @1 Value:.Ltmp0 Kind:4001
# CHECK-NEXT:5 Data Size:16 [48,8b,04,25,00,00,00,00,48,8b,04,25,00,00,00,00]
# CHECK-NEXT: Fixup @4 Value:f0@<variant 11> Kind:4017
# CHECK-NEXT: Fixup @12 Value:_start@<variant 11> Kind:4017
# CHECK-NEXT: Symbol @16 .Ltmp0 Temporary
+# CHECK-NEXT: Symbol @0 Temporary
+# CHECK-NEXT: Symbol @16 Temporary
# CHECK-NEXT:MCSection Name:.data
# CHECK-NEXT:0 Data Size:0 []
# CHECK-NEXT: Symbol @0 .data
# CHECK-NEXT:0 Align Align:4 Value:0 ValueSize:1 MaxBytesToEmit:4
# CHECK-NEXT:0 Data Size:4 [01,00,00,00]
# CHECK-NEXT:4 Fill Value:0 ValueSize:1 NumValues:1
-# CHECK-NEXT:5 LEB Value:.Ltmp0-_start Signed:0
-# CHECK-NEXT:]
+# CHECK-NEXT:5 LEB Size:0+1 [15] Value:.Ltmp0-_start Signed:0
+# CHECK:]
# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t -debug-only=mc-dump -save-temp-labels -g 2>&1 | FileCheck %s --check-prefix=CHECK2
# CHECK2:5 Data Size:16 [48,8b,04,25,00,00,00,00,48,8b,04,25,00,00,00,00]
# CHECK2-NEXT: Fixup @4 Value:f0@<variant 11> Kind:4017
# CHECK2-NEXT: Fixup @12 Value:_start@<variant 11> Kind:4017
-# CHECK2-NEXT: Symbol @16 .Ltmp1
-# CHECK2-NEXT: Symbol @0 .Ltmp3 Temporary
-# CHECK2-NEXT: Symbol @8 .Ltmp4 Temporary
-# CHECK2-NEXT: Symbol @16 .Ltmp5 Temporary
-# CHECK2-NEXT: Symbol @16 .Lsec_end0 Temporary
+# CHECK2-NEXT: Symbol @16 .Ltmp2
+# CHECK2-NEXT: Symbol @0 .Lcfi0 Temporary
+# CHECK2:MCSection Name:.eh_frame
+# CHECK2:24 DwarfCallFrame Size:17+1 [00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,45] AddrDelta:.Lcfi0-.Ltmp1
+# CHECK2-NEXT: Fixup @0 Value:.Ltmp12-.Ltmp11-0 Kind:4003
_start:
var = _start
+.cfi_startproc
.org 3
jmp 1f
+.cfi_offset %rbp, -24
movq f0 at GOTPCREL, %rax
movq _start at GOTPCREL, %rax
1:
+.cfi_endproc
.data
.p2align 2
More information about the llvm-commits
mailing list