[llvm] dc3a4c0 - MC: Restructure MCFragment as a fixed part and a variable tail
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 15 21:56:59 PDT 2025
Author: Fangrui Song
Date: 2025-07-15T21:56:55-07:00
New Revision: dc3a4c0fcf4953645bc81ae99db10e48acd4961f
URL: https://github.com/llvm/llvm-project/commit/dc3a4c0fcf4953645bc81ae99db10e48acd4961f
DIFF: https://github.com/llvm/llvm-project/commit/dc3a4c0fcf4953645bc81ae99db10e48acd4961f.diff
LOG: MC: Restructure MCFragment as a fixed part and a variable tail
Refactor the fragment representation of `push rax; jmp foo; nop; jmp foo`,
previously encoded as
`MCDataFragment(nop); MCRelaxableFragment(jmp foo); MCDataFragment(nop); MCRelaxableFragment(jmp foo)`,
to
```
MCFragment(fixed: push rax, variable: jmp foo)
MCFragment(fixed: nop, variable: jmp foo)
```
Changes:
* Eliminate MCEncodedFragment, moving content and fixup storage to MCFragment.
* The new MCFragment contains a fixed-size content (similar to previous
MCDataFragment) and an optional variable-size tail.
* The variable-size tail supports FT_Relaxable, FT_LEB, FT_Dwarf, and
FT_DwarfFrame, with plans to extend to other fragment types.
dyn_cast/isa should be avoided for the converted fragment subclasses.
* In `setVarFixups`, source fixup offsets are relative to the variable part's start.
Stored fixup (in `FixupStorage`) offsets are relative to the fixed part's start.
A lot of code does `getFragmentOffset(Frag) + Fixup.getOffset()`,
expecting the fixup offset to be relative to the fixed part's start.
* HexagonAsmBackend::fixupNeedsRelaxationAdvanced needs to know the
associated instruction for a fixup. We have to add a `const MCFragment &` parameter.
* In MCObjectStreamer, extend `absoluteSymbolDiff` to apply to
FT_Relaxable as otherwise there would be many more FT_DwarfFrame
fragments in -g compilations.
https://llvm-compile-time-tracker.com/compare.php?from=28e1473e8e523150914e8c7ea50b44fb0d2a8d65&to=778d68ad1d48e7f111ea853dd249912c601bee89&stat=instructions:u
```
stage2-O0-g instructins:u geomeon (-0.07%)
stage1-ReleaseLTO-g (link only) max-rss geomean (-0.39%)
```
```
% /t/clang-old -g -c sqlite3.i -w -mllvm -debug-only=mc-dump &| awk '/^[0-9]+/{s[$2]++;tot++} END{print "Total",tot; n=asorti(s, si); for(i=1;i<=n;i++) print si[i],s[si[i]]}'
Total 59675
Align 2215
Data 29700
Dwarf 12044
DwarfCallFrame 4216
Fill 92
LEB 12
Relaxable 11396
% /t/clang-new -g -c sqlite3.i -w -mllvm -debug-only=mc-dump &| awk '/^[0-9]+/{s[$2]++;tot++} END{print "Total",tot; n=asorti(s, si); for(i=1;i<=n;i++) print si[i],s[si[i]]}'
Total 32287
Align 2215
Data 2312
Dwarf 12044
DwarfCallFrame 4216
Fill 92
LEB 12
Relaxable 11396
```
Pull Request: https://github.com/llvm/llvm-project/pull/148544
Added:
Modified:
llvm/include/llvm/MC/MCAsmBackend.h
llvm/include/llvm/MC/MCAssembler.h
llvm/include/llvm/MC/MCCodeView.h
llvm/include/llvm/MC/MCContext.h
llvm/include/llvm/MC/MCELFStreamer.h
llvm/include/llvm/MC/MCObjectStreamer.h
llvm/include/llvm/MC/MCSection.h
llvm/include/llvm/MC/MCWasmStreamer.h
llvm/lib/MC/MCAsmBackend.cpp
llvm/lib/MC/MCAssembler.cpp
llvm/lib/MC/MCCodeView.cpp
llvm/lib/MC/MCContext.cpp
llvm/lib/MC/MCELFStreamer.cpp
llvm/lib/MC/MCExpr.cpp
llvm/lib/MC/MCFragment.cpp
llvm/lib/MC/MCMachOStreamer.cpp
llvm/lib/MC/MCObjectStreamer.cpp
llvm/lib/MC/MCSection.cpp
llvm/lib/MC/MCSymbol.cpp
llvm/lib/MC/MCWasmStreamer.cpp
llvm/lib/MC/MCWin64EH.cpp
llvm/lib/MC/MCWinCOFFStreamer.cpp
llvm/lib/MC/MCXCOFFStreamer.cpp
llvm/lib/MC/MachObjectWriter.cpp
llvm/lib/MC/WasmObjectWriter.cpp
llvm/lib/MC/WinCOFFObjectWriter.cpp
llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp
llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h
llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
llvm/test/MC/ELF/mc-dump.s
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h
index 6b81bdba25e67..e5f931cb9e4bc 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);
}
@@ -228,7 +224,7 @@ class LLVM_ABI MCAsmBackend {
bool isDarwinCanonicalPersonality(const MCSymbol *Sym) const;
- // Return STI for fragments of type MCRelaxableFragment and MCDataFragment
+ // Return STI for fragments of type MCRelaxableFragment and MCFragment
// with hasInstructions() == true.
static const MCSubtargetInfo *getSubtargetInfo(const MCFragment &F);
};
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h
index 6b0d1b202e8c2..aa396efa9f018 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;
@@ -102,7 +99,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
@@ -111,11 +108,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);
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 cf931e99acce1..ad0961c8bcf97 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 5990d70a076f5..e2a77b809b6ca 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;
@@ -92,10 +92,10 @@ class MCObjectStreamer : public MCStreamer {
}
/// Get a data fragment to write into, creating a new one if the current
- /// fragment is not a data fragment.
+ /// fragment is not FT_Data.
/// Optionally a \p STI can be passed in so that a new fragment is created
/// if the Subtarget
diff ers from the current fragment.
- MCDataFragment *getOrCreateDataFragment(const MCSubtargetInfo* STI = nullptr);
+ MCFragment *getOrCreateDataFragment(const MCSubtargetInfo *STI = nullptr);
protected:
bool changeSectionImpl(MCSection *Section, uint32_t Subsection);
@@ -109,7 +109,7 @@ class MCObjectStreamer : public MCStreamer {
/// @{
void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
- virtual void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCDataFragment &F,
+ virtual void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment &F,
uint64_t Offset);
void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
void emitConditionalAssignment(MCSymbol *Symbol,
diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h
index 01ce3842cd368..49570c927e393 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 {
@@ -236,54 +234,50 @@ 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 {
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;
+ // Used by .debug_frame and .debug_line to encode an address
diff erence.
+ struct {
+ // The address
diff erence between two labels.
+ const MCExpr *AddrDelta;
+ // The value of the
diff erence 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;
@@ -299,6 +293,24 @@ class MCEncodedFragment : public MCFragment {
}
}
+ 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; }
+
+ LLVM_ABI void dump() const;
+
/// Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
/// Guaranteed to be non-null if hasInstructions() == true
const MCSubtargetInfo *getSubtargetInfo() const { return STI; }
@@ -310,6 +322,9 @@ 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; }
@@ -349,7 +364,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);
@@ -364,65 +396,100 @@ 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) {
+ assert(Kind == FT_LEB);
+ u.leb.Value = Expr;
+ }
+ bool isLEBSigned() const {
+ assert(Kind == FT_LEB);
+ return u.leb.IsSigned;
+ }
+ void setLEBSigned(bool S) {
+ assert(Kind == FT_LEB);
+ u.leb.IsSigned = S;
}
+
+ //== FT_DwarfFrame functions
+ const MCExpr &getDwarfAddrDelta() const {
+ assert(Kind == FT_Dwarf || Kind == FT_DwarfFrame);
+ return *u.dwarf.AddrDelta;
+ }
+ void setDwarfAddrDelta(const MCExpr *E) {
+ assert(Kind == FT_Dwarf || Kind == FT_DwarfFrame);
+ u.dwarf.AddrDelta = E;
+ }
+ int64_t getDwarfLineDelta() const {
+ assert(Kind == FT_Dwarf);
+ return u.dwarf.LineDelta;
+ }
+ void setDwarfLineDelta(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 {
/// Flag to indicate that (optimal) NOPs should be emitted instead
/// of using the provided value. The exact interpretation of this flag is
@@ -554,67 +621,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
diff erence between the two line numbers
- /// between two .loc dwarf directives.
- int64_t LineDelta;
-
- /// The expression for the
diff erence 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
diff erence 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/include/llvm/MC/MCWasmStreamer.h b/llvm/include/llvm/MC/MCWasmStreamer.h
index 2598c261ea02a..e8a71975c5d62 100644
--- a/llvm/include/llvm/MC/MCWasmStreamer.h
+++ b/llvm/include/llvm/MC/MCWasmStreamer.h
@@ -42,7 +42,7 @@ class MCWasmStreamer : public MCObjectStreamer {
void changeSection(MCSection *Section, uint32_t Subsection) 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;
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
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 7f01e272a323e..77741a60d0408 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -202,7 +202,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;
@@ -426,8 +426,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: {
@@ -592,11 +593,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() +
@@ -649,7 +649,7 @@ void MCAssembler::layout() {
// Chain together fragments from all subsections.
if (Sec.Subsections.size() > 1) {
- MCDataFragment Dummy;
+ MCFragment Dummy;
MCFragment *Tail = &Dummy;
for (auto &[_, List] : Sec.Subsections) {
assert(List.Head);
@@ -697,17 +697,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())
@@ -727,18 +738,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
@@ -749,7 +760,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)
@@ -757,7 +768,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());
@@ -767,30 +778,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
diff erent
// 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));
@@ -803,11 +814,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;
}
@@ -872,48 +883,45 @@ 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.getDwarfAddrDelta().evaluateKnownAbsolute(AddrDelta, *this);
assert(Abs && "We created a line delta with an invalid expression");
(void)Abs;
- int64_t LineDelta;
- LineDelta = DF.getLineDelta();
SmallVector<char, 8> Data;
-
- MCDwarfLineAddr::encode(Context, getDWARFLinetableParams(), LineDelta,
- AddrDelta, Data);
- DF.setContents(Data);
- DF.clearFixups();
+ MCDwarfLineAddr::encode(Context, getDWARFLinetableParams(),
+ F.getDwarfLineDelta(), AddrDelta, Data);
+ 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.getDwarfAddrDelta().evaluateAsAbsolute(Value, *this);
if (!Abs) {
- reportError(DF.getAddrDelta().getLoc(),
+ reportError(F.getDwarfAddrDelta().getLoc(),
"invalid CFI advance_loc expression");
- DF.setAddrDelta(MCConstantExpr::create(0, Context));
+ F.setDwarfAddrDelta(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();
}
@@ -960,13 +968,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/MCCodeView.cpp b/llvm/lib/MC/MCCodeView.cpp
index 5d7914396e09f..1f9825185175a 100644
--- a/llvm/lib/MC/MCCodeView.cpp
+++ b/llvm/lib/MC/MCCodeView.cpp
@@ -166,7 +166,7 @@ void CodeViewContext::emitStringTable(MCObjectStreamer &OS) {
// somewhere else. If somebody wants two string tables in their .s file, one
// will just be empty.
if (!StrTabFragment) {
- StrTabFragment = Ctx.allocFragment<MCDataFragment>();
+ StrTabFragment = Ctx.allocFragment<MCFragment>();
OS.insert(StrTabFragment);
}
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 890184db1d1ef..070be621a4b2c 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -200,10 +200,10 @@ MCInst *MCContext::createMCInst() {
return new (MCInstAllocator.Allocate()) MCInst;
}
-// Allocate the initial MCDataFragment for the begin symbol.
-MCDataFragment *MCContext::allocInitialFragment(MCSection &Sec) {
+// Allocate the initial MCFragment for the begin symbol.
+MCFragment *MCContext::allocInitialFragment(MCSection &Sec) {
assert(!Sec.curFragList()->Head);
- auto *F = allocFragment<MCDataFragment>();
+ auto *F = allocFragment<MCFragment>();
F->setParent(&Sec);
Sec.curFragList()->Head = F;
Sec.curFragList()->Tail = F;
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index ecc77c6705267..ffc57227cff16 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -68,7 +68,7 @@ void MCELFStreamer::emitLabel(MCSymbol *S, SMLoc Loc) {
Symbol->setType(ELF::STT_TLS);
}
-void MCELFStreamer::emitLabelAtPos(MCSymbol *S, SMLoc Loc, MCDataFragment &F,
+void MCELFStreamer::emitLabelAtPos(MCSymbol *S, SMLoc Loc, MCFragment &F,
uint64_t Offset) {
auto *Symbol = cast<MCSymbolELF>(S);
MCObjectStreamer::emitLabelAtPos(Symbol, Loc, F, Offset);
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index a196591744099..22dff497911de 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -324,7 +324,7 @@ static void attemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,
// symbols is limited to specific cases where the fragments between two
// symbols (including the fragments the symbols are defined in) are
// fixed-size fragments so the
diff erence can be calculated. For example,
- // this is important when the Subtarget is changed and a new MCDataFragment
+ // this is important when the Subtarget is changed and a new MCFragment
// is created in the case of foo: instr; .arch_extension ext; instr .if . -
// foo.
if (SA.isVariable() || SB.isVariable())
@@ -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 c62abac2793e4..49760a69a44cc 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), LinkerRelaxable(false),
- AllowAutoPadding(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);
@@ -79,18 +82,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:";
+ getDwarfAddrDelta().print(OS, nullptr);
+ OS << " LineDelta:" << getDwarfLineDelta();
+ break;
+ case MCFragment::FT_DwarfFrame:
+ OS << " AddrDelta:";
+ getDwarfAddrDelta().print(OS, nullptr);
+ break;
+ default:
+ llvm_unreachable("");
+ }
+ printFixups(getFixups());
+ printFixups(getVarFixups());
break;
}
case MCFragment::FT_Fill: {
@@ -107,13 +148,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:";
@@ -121,26 +155,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/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp
index a54dfb9cbaea1..43598ef038b96 100644
--- a/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/llvm/lib/MC/MCMachOStreamer.cpp
@@ -161,7 +161,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 (cast<MCSymbolMachO>(Symbol)->isSymbolLinkerVisible())
- insert(getContext().allocFragment<MCDataFragment>());
+ insert(getContext().allocFragment<MCFragment>());
MCObjectStreamer::emitLabel(Symbol, Loc);
@@ -483,8 +483,7 @@ void MCMachOStreamer::finalizeCGProfile() {
// For each entry, reserve space for 2 32-bit indices and a 64-bit count.
size_t SectionBytes =
W.getCGProfile().size() * (2 * sizeof(uint32_t) + sizeof(uint64_t));
- cast<MCDataFragment>(*CGProfileSection->begin())
- .appendContents(SectionBytes, 0);
+ (*CGProfileSection->begin()).appendContents(SectionBytes, 0);
}
MCStreamer *llvm::createMachOStreamer(MCContext &Context,
@@ -513,7 +512,7 @@ void MCMachOStreamer::createAddrSigSection() {
MCSection *AddrSigSection =
Asm.getContext().getObjectFileInfo()->getAddrSigSection();
changeSection(AddrSigSection);
- auto *Frag = cast<MCDataFragment>(AddrSigSection->curFragList()->Head);
+ auto *Frag = cast<MCFragment>(AddrSigSection->curFragList()->Head);
// 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/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 4ab5e3e5d4b47..c0cef0f06c57a 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())
@@ -146,11 +150,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;
@@ -169,7 +174,7 @@ void MCObjectStreamer::emitCFISections(bool EH, bool Debug) {
void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
SMLoc Loc) {
MCStreamer::emitValueImpl(Value, Size, Loc);
- MCDataFragment *DF = getOrCreateDataFragment();
+ MCFragment *DF = getOrCreateDataFragment();
MCDwarfLineEntry::make(this, getCurrentSectionOnly());
@@ -218,7 +223,7 @@ void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
// If there is a current fragment, mark the symbol as pointing into it.
// Otherwise queue the label and set its fragment pointer when we emit the
// next fragment.
- MCDataFragment *F = getOrCreateDataFragment();
+ MCFragment *F = getOrCreateDataFragment();
Symbol->setFragment(F);
Symbol->setOffset(F->getContents().size());
@@ -238,7 +243,7 @@ void MCObjectStreamer::emitPendingAssignments(MCSymbol *Symbol) {
// Emit a label at a previously emitted fragment/offset position. This must be
// within the currently-active section.
void MCObjectStreamer::emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc,
- MCDataFragment &F, uint64_t Offset) {
+ MCFragment &F, uint64_t Offset) {
assert(F.getParent() == getCurrentSectionOnly());
MCStreamer::emitLabel(Symbol, Loc);
getAssembler().registerSymbol(*Symbol);
@@ -252,7 +257,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) {
@@ -261,7 +269,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,
@@ -285,7 +296,7 @@ bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
// If the subsection number is not in the sorted Subsections list, create a
// new fragment list.
if (I == E || Subsections[I].first != Subsection) {
- auto *F = getContext().allocFragment<MCDataFragment>();
+ auto *F = getContext().allocFragment<MCFragment>();
F->setParent(Section);
Subsections.insert(Subsections.begin() + I,
{Subsection, MCSection::FragList{F, F}});
@@ -365,13 +376,12 @@ void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst,
return;
}
- // Otherwise emit to a separate fragment.
emitInstToFragment(Inst, STI);
}
void MCObjectStreamer::emitInstToData(const MCInst &Inst,
const MCSubtargetInfo &STI) {
- MCDataFragment *F = getOrCreateDataFragment(&STI);
+ MCFragment *F = getOrCreateDataFragment();
// Append the instruction to the data fragment.
size_t FixupStartIndex = F->getFixups().size();
@@ -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);
}
void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
@@ -469,9 +478,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->setDwarfAddrDelta(buildSymbolDiff(*this, Label, LastLabel, SMLoc()));
+ F->setDwarfLineDelta(LineDelta);
}
void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section,
@@ -499,8 +509,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->setDwarfAddrDelta(buildSymbolDiff(*this, Label, LastLabel, Loc));
}
void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
@@ -559,7 +570,7 @@ void MCObjectStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) {
void MCObjectStreamer::emitBytes(StringRef Data) {
MCDwarfLineEntry::make(this, getCurrentSectionOnly());
- MCDataFragment *DF = getOrCreateDataFragment();
+ MCFragment *DF = getOrCreateDataFragment();
DF->appendContents(ArrayRef(Data.data(), Data.size()));
}
@@ -598,7 +609,7 @@ void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
static std::optional<std::pair<bool, std::string>>
getOffsetAndDataFragment(const MCSymbol &Symbol, uint32_t &RelocOffset,
- MCDataFragment *&DF) {
+ MCFragment *&DF) {
if (Symbol.isVariable()) {
const MCExpr *SymbolExpr = Symbol.getVariableValue();
MCValue OffsetVal;
@@ -615,7 +626,7 @@ getOffsetAndDataFragment(const MCSymbol &Symbol, uint32_t &RelocOffset,
return std::make_pair(false,
std::string("symbol in offset has no data "
"fragment"));
- DF = cast<MCDataFragment>(Fragment);
+ DF = cast<MCFragment>(Fragment);
return std::nullopt;
}
@@ -643,7 +654,7 @@ getOffsetAndDataFragment(const MCSymbol &Symbol, uint32_t &RelocOffset,
std::string("symbol in offset has no data "
"fragment"));
RelocOffset = SA.getOffset() + OffsetVal.getConstant();
- DF = cast<MCDataFragment>(Fragment);
+ DF = cast<MCFragment>(Fragment);
} else {
RelocOffset = Symbol.getOffset();
MCFragment *Fragment = Symbol.getFragment();
@@ -653,7 +664,7 @@ getOffsetAndDataFragment(const MCSymbol &Symbol, uint32_t &RelocOffset,
return std::make_pair(false,
std::string("symbol in offset has no data "
"fragment"));
- DF = cast<MCDataFragment>(Fragment);
+ DF = cast<MCFragment>(Fragment);
}
return std::nullopt;
}
@@ -674,7 +685,7 @@ MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
Expr =
MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
- MCDataFragment *DF = getOrCreateDataFragment(&STI);
+ MCFragment *DF = getOrCreateDataFragment(&STI);
MCValue OffsetVal;
if (!Offset.evaluateAsRelocatable(OffsetVal, nullptr))
return std::make_pair(false,
diff --git a/llvm/lib/MC/MCSection.cpp b/llvm/lib/MC/MCSection.cpp
index f1c81e90a0fe5..93671450c0c2f 100644
--- a/llvm/lib/MC/MCSection.cpp
+++ b/llvm/lib/MC/MCSection.cpp
@@ -60,7 +60,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();
@@ -70,9 +70,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
@@ -86,7 +96,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();
@@ -95,3 +105,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/MCSymbol.cpp b/llvm/lib/MC/MCSymbol.cpp
index baf1ff89c0188..8192896eeb6bb 100644
--- a/llvm/lib/MC/MCSymbol.cpp
+++ b/llvm/lib/MC/MCSymbol.cpp
@@ -21,7 +21,7 @@
using namespace llvm;
// Only the address of this fragment is ever actually used.
-static MCDataFragment SentinelFragment;
+static MCFragment SentinelFragment;
// Sentinel value for the absolute pseudo fragment.
MCFragment *MCSymbol::AbsolutePseudoFragment = &SentinelFragment;
diff --git a/llvm/lib/MC/MCWasmStreamer.cpp b/llvm/lib/MC/MCWasmStreamer.cpp
index 44d98acdb31f1..5891420c0727d 100644
--- a/llvm/lib/MC/MCWasmStreamer.cpp
+++ b/llvm/lib/MC/MCWasmStreamer.cpp
@@ -45,7 +45,7 @@ void MCWasmStreamer::emitLabel(MCSymbol *S, SMLoc Loc) {
Symbol->setTLS();
}
-void MCWasmStreamer::emitLabelAtPos(MCSymbol *S, SMLoc Loc, MCDataFragment &F,
+void MCWasmStreamer::emitLabelAtPos(MCSymbol *S, SMLoc Loc, MCFragment &F,
uint64_t Offset) {
auto *Symbol = cast<MCSymbolWasm>(S);
MCObjectStreamer::emitLabelAtPos(Symbol, Loc, F, Offset);
diff --git a/llvm/lib/MC/MCWin64EH.cpp b/llvm/lib/MC/MCWin64EH.cpp
index 8cc74db9beea4..e8b26bf291ee4 100644
--- a/llvm/lib/MC/MCWin64EH.cpp
+++ b/llvm/lib/MC/MCWin64EH.cpp
@@ -318,7 +318,7 @@ static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) {
// Emit the epilog instructions.
if (EnableUnwindV2) {
- MCDataFragment *DF = OS->getOrCreateDataFragment();
+ MCFragment *DF = OS->getOrCreateDataFragment();
bool IsLast = true;
for (const auto &Epilog : llvm::reverse(info->EpilogMap)) {
diff --git a/llvm/lib/MC/MCWinCOFFStreamer.cpp b/llvm/lib/MC/MCWinCOFFStreamer.cpp
index 0c0866f9e36a4..3398775df3f91 100644
--- a/llvm/lib/MC/MCWinCOFFStreamer.cpp
+++ b/llvm/lib/MC/MCWinCOFFStreamer.cpp
@@ -278,7 +278,7 @@ void MCWinCOFFStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {
void MCWinCOFFStreamer::emitCOFFSectionIndex(const MCSymbol *Symbol) {
visitUsedSymbol(*Symbol);
- MCDataFragment *DF = getOrCreateDataFragment();
+ MCFragment *DF = getOrCreateDataFragment();
const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext());
MCFixup Fixup = MCFixup::create(DF->getContents().size(), SRE, FK_SecRel_2);
DF->addFixup(Fixup);
@@ -288,7 +288,7 @@ void MCWinCOFFStreamer::emitCOFFSectionIndex(const MCSymbol *Symbol) {
void MCWinCOFFStreamer::emitCOFFSecRel32(const MCSymbol *Symbol,
uint64_t Offset) {
visitUsedSymbol(*Symbol);
- MCDataFragment *DF = getOrCreateDataFragment();
+ MCFragment *DF = getOrCreateDataFragment();
// Create Symbol A for the relocation relative reference.
const MCExpr *MCE = MCSymbolRefExpr::create(Symbol, getContext());
// Add the constant offset, if given.
@@ -306,7 +306,7 @@ void MCWinCOFFStreamer::emitCOFFSecRel32(const MCSymbol *Symbol,
void MCWinCOFFStreamer::emitCOFFImgRel32(const MCSymbol *Symbol,
int64_t Offset) {
visitUsedSymbol(*Symbol);
- MCDataFragment *DF = getOrCreateDataFragment();
+ MCFragment *DF = getOrCreateDataFragment();
// Create Symbol A for the relocation relative reference.
const MCExpr *MCE = MCSymbolRefExpr::create(
Symbol, MCSymbolRefExpr::VK_COFF_IMGREL32, getContext());
@@ -324,7 +324,7 @@ void MCWinCOFFStreamer::emitCOFFImgRel32(const MCSymbol *Symbol,
void MCWinCOFFStreamer::emitCOFFSecNumber(MCSymbol const *Symbol) {
visitUsedSymbol(*Symbol);
- MCDataFragment *DF = getOrCreateDataFragment();
+ MCFragment *DF = getOrCreateDataFragment();
// Create Symbol for section number.
const MCExpr *MCE = MCCOFFSectionNumberTargetExpr::create(
*Symbol, this->getWriter(), getContext());
@@ -338,7 +338,7 @@ void MCWinCOFFStreamer::emitCOFFSecNumber(MCSymbol const *Symbol) {
void MCWinCOFFStreamer::emitCOFFSecOffset(MCSymbol const *Symbol) {
visitUsedSymbol(*Symbol);
- MCDataFragment *DF = getOrCreateDataFragment();
+ MCFragment *DF = getOrCreateDataFragment();
// Create Symbol for section offset.
const MCExpr *MCE =
MCCOFFSectionOffsetTargetExpr::create(*Symbol, getContext());
diff --git a/llvm/lib/MC/MCXCOFFStreamer.cpp b/llvm/lib/MC/MCXCOFFStreamer.cpp
index 12e6680bcf074..4d4529653aba9 100644
--- a/llvm/lib/MC/MCXCOFFStreamer.cpp
+++ b/llvm/lib/MC/MCXCOFFStreamer.cpp
@@ -89,7 +89,7 @@ void MCXCOFFStreamer::emitXCOFFSymbolLinkageWithVisibility(
void MCXCOFFStreamer::emitXCOFFRefDirective(const MCSymbol *Symbol) {
// Add a Fixup here to later record a relocation of type R_REF to prevent the
// ref symbol from being garbage collected (by the binder).
- MCDataFragment *DF = getOrCreateDataFragment();
+ MCFragment *DF = getOrCreateDataFragment();
const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext());
std::optional<MCFixupKind> MaybeKind =
getAssembler().getBackend().getFixupKind("R_REF");
diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp
index fb8e1fdf62f50..3291dd774c1e0 100644
--- a/llvm/lib/MC/MachObjectWriter.cpp
+++ b/llvm/lib/MC/MachObjectWriter.cpp
@@ -799,7 +799,7 @@ uint64_t MachObjectWriter::writeObject() {
if (!CGProfile.empty()) {
MCSection *CGProfileSection = getContext().getMachOSection(
"__LLVM", "__cg_profile", 0, SectionKind::getMetadata());
- auto &Frag = cast<MCDataFragment>(*CGProfileSection->begin());
+ auto &Frag = *CGProfileSection->begin();
Frag.clearContents();
raw_svector_ostream OS(Frag.getContentsForAppending());
for (const MCObjectWriter::CGProfileEntry &CGPE : CGProfile) {
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index 4c226d4420e1d..7af240a73f952 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -711,10 +711,12 @@ 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());
+ if (Frag.getKind() == MCFragment::FT_LEB)
+ llvm::append_range(DataBytes, Frag.getVarContents());
+ else
+ assert(Frag.getKind() == MCFragment::FT_Data);
}
}
@@ -1884,7 +1886,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/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index c2ef430984ed4..ee4d957fe9d87 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -1069,7 +1069,7 @@ uint64_t WinCOFFWriter::writeObject() {
if (Mode != DwoOnly && OWriter.getEmitAddrsigSection()) {
auto *Sec = getContext().getCOFFSection(".llvm_addrsig",
COFF::IMAGE_SCN_LNK_REMOVE);
- auto *Frag = cast<MCDataFragment>(Sec->curFragList()->Head);
+ auto *Frag = Sec->curFragList()->Head;
raw_svector_ostream OS(Frag->getContentsForAppending());
for (const MCSymbol *S : OWriter.AddrsigSyms) {
if (!S->isRegistered())
@@ -1092,7 +1092,7 @@ uint64_t WinCOFFWriter::writeObject() {
if (Mode != DwoOnly && !OWriter.getCGProfile().empty()) {
auto *Sec = getContext().getCOFFSection(".llvm.call-graph-profile",
COFF::IMAGE_SCN_LNK_REMOVE);
- auto *Frag = cast<MCDataFragment>(Sec->curFragList()->Head);
+ auto *Frag = Sec->curFragList()->Head;
raw_svector_ostream OS(Frag->getContentsForAppending());
for (const auto &CGPE : OWriter.getCGProfile()) {
uint32_t FromIndex = CGPE.From->getSymbol().getIndex();
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 164acdec4544b..146fc6704c6da 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 062b4356420ab..694d9eab9694b 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 287bdc5bfd4d4..7d3074ba6b5d2 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 3dbf7683cdade..7b9f1156f9102 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 &F,
int64_t &Value) const {
- const MCExpr &Expr = LF.getValue();
- if (LF.isSigned() || !Expr.evaluateKnownAbsolute(Value, *Asm))
+ const MCExpr &Expr = F.getLEBValue();
+ if (F.isLEBSigned() || !Expr.evaluateKnownAbsolute(Value, *Asm))
return std::make_pair(false, false);
- LF.addFixup(MCFixup::create(0, &Expr, FK_Data_leb128));
+ F.setVarFixups({MCFixup::create(0, &Expr, FK_Data_leb128)});
return std::make_pair(true, true);
}
-bool LoongArchAsmBackend::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF,
+bool LoongArchAsmBackend::relaxDwarfLineAddr(MCFragment &F,
bool &WasRelaxed) const {
MCContext &C = getContext();
- int64_t LineDelta = DF.getLineDelta();
- const MCExpr &AddrDelta = DF.getAddrDelta();
+ int64_t LineDelta = F.getDwarfLineDelta();
+ const MCExpr &AddrDelta = F.getDwarfAddrDelta();
SmallVector<MCFixup, 1> Fixups;
- size_t OldSize = DF.getContents().size();
+ size_t OldSize = F.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);
+ F.setVarContents(Data);
+ F.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.getDwarfAddrDelta();
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 e42d6c539a349..f76f8b3060d2a 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -104,7 +104,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 {
@@ -301,14 +302,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.getDwarfLineDelta();
+ const MCExpr &AddrDelta = F.getDwarfAddrDelta();
SmallVector<MCFixup, 1> Fixups;
- size_t OldSize = DF.getContents().size();
+ size_t OldSize = F.getVarSize();
int64_t Value;
[[maybe_unused]] bool IsAbsolute =
@@ -361,17 +362,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.getDwarfAddrDelta();
SmallVector<MCFixup, 2> Fixups;
- size_t OldSize = DF.getContents().size();
+ size_t OldSize = F.getVarSize();
int64_t Value;
if (AddrDelta.evaluateAsAbsolute(Value, *Asm))
@@ -383,9 +383,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;
}
@@ -416,20 +416,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);
}
@@ -662,14 +662,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 a94b2df617911..8ab76487ebec3 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
@@ -547,8 +543,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();
@@ -752,7 +748,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 {
@@ -781,7 +778,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())
@@ -794,7 +791,7 @@ bool X86AsmBackend::padInstructionViaPrefix(MCRelaxableFragment &RF,
*RF.getSubtargetInfo()))
return false;
- const unsigned OldSize = RF.getContents().size();
+ const unsigned OldSize = RF.getVarSize();
if (OldSize == 15)
return false;
@@ -823,19 +820,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(),
@@ -850,20 +846,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;
@@ -896,7 +892,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;
@@ -907,7 +903,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 9cf15a7ddee46..5cc2e9fa50179 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 Fill:0 FillLen: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 Fill:0 FillLen: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