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 relaxLEB128(MCLEBFragment &LF, + virtual std::pair 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 StringTable; /// The fragment that ultimately holds our strings. - MCDataFragment *StrTabFragment = nullptr; + MCFragment *StrTabFragment = nullptr; SmallVector 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); - 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 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 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); @@ -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 difference. + struct { + // The address difference between two labels. + 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; @@ -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 Contents); + void clearVarContents() { setVarContents({}); } + MutableArrayRef getVarContents() { + return MutableArrayRef(getParent()->ContentStorage) + .slice(VarContentStart, VarContentEnd - VarContentStart); + } + ArrayRef 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 Fixups); + void clearVarFixups() { setVarFixups({}); } + MutableArrayRef 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 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 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 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/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(&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(F).getContents().size(); + return F.getSize(); case MCFragment::FT_Fill: { auto &FF = cast(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(F); + const auto &EF = cast(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(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(&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(&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(&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(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 Data; SmallVector 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(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)); @@ -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(Data), Size}); + F.setVarContents({reinterpret_cast(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 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 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(F)); + return relaxInstruction(F); + case MCFragment::FT_LEB: + return relaxLEB(F); case MCFragment::FT_Dwarf: - return relaxDwarfLineAddr(cast(F)); + return relaxDwarfLineAddr(F); case MCFragment::FT_DwarfFrame: - return relaxDwarfCallFrameFragment(cast(F)); - case MCFragment::FT_LEB: - return relaxLEB(cast(F)); + return relaxDwarfCallFrameFragment(F); case MCFragment::FT_BoundaryAlign: return relaxBoundaryAlign(cast(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(); + StrTabFragment = Ctx.allocFragment(); 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(); + auto *F = allocFragment(); 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(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 difference 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(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(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(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, +static_assert(std::is_trivially_destructible_v, "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(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(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(this); - OS << " Size:" << F->getContents().size() << ' '; - F->getInst().dump_pretty(OS); - printFixups(F->getFixups()); - break; - } case MCFragment::FT_Org: { const auto *OF = cast(this); OS << " Offset:"; @@ -121,26 +155,6 @@ LLVM_DUMP_METHOD void MCFragment::dump() const { OS << " Value:" << static_cast(OF->getValue()); break; } - case MCFragment::FT_Dwarf: { - const auto *OF = cast(this); - OS << " AddrDelta:"; - OF->getAddrDelta().print(OS, nullptr); - OS << " LineDelta:" << OF->getLineDelta(); - break; - } - case MCFragment::FT_DwarfFrame: { - const auto *CF = cast(this); - OS << " AddrDelta:"; - CF->getAddrDelta().print(OS, nullptr); - break; - } - case MCFragment::FT_LEB: { - const auto *LF = cast(this); - OS << " Value:"; - LF->getValue().print(OS, nullptr); - OS << " Signed:" << LF->isSigned(); - break; - } case MCFragment::FT_BoundaryAlign: { const auto *BF = cast(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(Symbol)->isSymbolLinkerVisible()) - insert(getContext().allocFragment()); + insert(getContext().allocFragment()); 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(*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(AddrSigSection->curFragList()->Head); + auto *Frag = cast(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(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 absoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo) { assert(Hi && Lo); @@ -85,8 +86,11 @@ static std::optional 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(getCurrentFragment()); - if (!F || !canReuseDataFragment(*F, *Assembler, STI)) { - F = getContext().allocFragment(); + auto *F = getCurrentFragment(); + if (F->getKind() != MCFragment::FT_Data || + !canReuseDataFragment(*F, *Assembler, STI)) { + F = getContext().allocFragment(); 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(*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(*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(); + auto *F = getContext().allocFragment(); 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(STI); - insert(IF); - IF->setInst(Inst); - + auto *F = getOrCreateDataFragment(); + SmallVector Data; SmallVector 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(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(*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> 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(Fragment); + DF = cast(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(Fragment); + DF = cast(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(Fragment); + DF = cast(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 Contents) { +void MCFragment::setContents(ArrayRef Contents) { auto &S = getParent()->ContentStorage; if (ContentStart + Contents.size() > ContentEnd) { ContentStart = S.size(); @@ -70,9 +70,19 @@ void MCEncodedFragment::setContents(ArrayRef Contents) { llvm::copy(Contents, S.begin() + ContentStart); } -void MCEncodedFragment::addFixup(MCFixup Fixup) { appendFixups({Fixup}); } +void MCFragment::setVarContents(ArrayRef 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 Fixups) { +void MCFragment::appendFixups(ArrayRef 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 Fixups) { FixupEnd = S.size(); } -void MCEncodedFragment::setFixups(ArrayRef Fixups) { +void MCFragment::setFixups(ArrayRef Fixups) { auto &S = getParent()->FixupStorage; if (FixupStart + Fixups.size() > FixupEnd) { FixupStart = S.size(); @@ -95,3 +105,19 @@ void MCEncodedFragment::setFixups(ArrayRef Fixups) { FixupEnd = FixupStart + Fixups.size(); llvm::copy(Fixups, S.begin() + FixupStart); } + +void MCFragment::setVarFixups(ArrayRef 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(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 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(*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 &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(&Frag)) { - llvm::append_range(DataBytes, LEB->getContents()); } else { - llvm::append_range(DataBytes, cast(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(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(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(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(Ctx.getObjectFileInfo()->getTextSection()); bool Empty = true; for (auto &F : *Text) { - if (auto *DF = dyn_cast(&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(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(Ctx.getObjectFileInfo()->getTextSection()); for (auto &F : *Text) - if (auto *DF = dyn_cast(&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 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(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(*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 LoongArchAsmBackend::relaxLEB128(MCLEBFragment &LF, +std::pair 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 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 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 relaxLEB128(MCLEBFragment &LF, + bool relaxDwarfLineAddr(MCFragment &F, bool &WasRelaxed) const override; + bool relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const override; + std::pair 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 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 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 RISCVAsmBackend::relaxLEB128(MCLEBFragment &LF, +std::pair 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(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(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 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 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 relaxLEB128(MCLEBFragment &LF, + bool relaxDwarfLineAddr(MCFragment &F, bool &WasRelaxed) const override; + bool relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const override; + std::pair 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 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(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(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(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 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 Relaxable; + SmallVector 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(*I); + auto &RF = cast(*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 > +# CHECK-NEXT:3 Relaxable Size:0+2 [eb,00] > # 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@ Kind:4017 # CHECK-NEXT: Fixup @12 Value:_start@ 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@ Kind:4017 # CHECK2-NEXT: Fixup @12 Value:_start@ 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@GOTPCREL, %rax movq _start@GOTPCREL, %rax 1: +.cfi_endproc .data .p2align 2