From baafbc01ecf6dbf2b319b19d1c07a92faad4c010 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 6 Jul 2025 18:42:15 -0700 Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?= =?UTF-8?q?itial=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.5-bogner --- llvm/include/llvm/MC/MCAsmBackend.h | 10 ++--- llvm/include/llvm/MC/MCInst.h | 5 +++ llvm/include/llvm/MC/MCSection.h | 37 ++++++++++++++++--- llvm/lib/MC/MCAssembler.cpp | 5 ++- llvm/lib/MC/MCObjectStreamer.cpp | 8 ++-- llvm/lib/MC/MCSection.cpp | 12 ------ .../AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp | 9 +++-- .../Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 6 +-- .../Target/ARM/MCTargetDesc/ARMAsmBackend.h | 2 +- .../CSKY/MCTargetDesc/CSKYAsmBackend.cpp | 4 +- .../Target/CSKY/MCTargetDesc/CSKYAsmBackend.h | 5 +-- .../MCTargetDesc/HexagonAsmBackend.cpp | 16 ++++---- .../M68k/MCTargetDesc/M68kAsmBackend.cpp | 6 +-- .../RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 20 +++++----- .../RISCV/MCTargetDesc/RISCVAsmBackend.h | 3 +- .../Target/VE/MCTargetDesc/VEAsmBackend.cpp | 2 +- .../Target/X86/MCTargetDesc/X86AsmBackend.cpp | 17 +++++---- .../Xtensa/MCTargetDesc/XtensaAsmBackend.cpp | 7 ---- 18 files changed, 94 insertions(+), 80 deletions(-) diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h index ebc98ebfce9f7..6b81bdba25e67 100644 --- a/llvm/include/llvm/MC/MCAsmBackend.h +++ b/llvm/include/llvm/MC/MCAsmBackend.h @@ -32,6 +32,7 @@ class MCInst; class MCObjectStreamer; class MCObjectTargetWriter; class MCObjectWriter; +class MCOperand; class MCSubtargetInfo; class MCValue; class raw_pwrite_stream; @@ -147,12 +148,9 @@ class LLVM_ABI MCAsmBackend { /// \name Target Relaxation Interfaces /// @{ - /// Check whether the given instruction may need relaxation. - /// - /// \param Inst - The instruction to test. - /// \param STI - The MCSubtargetInfo in effect when the instruction was - /// encoded. - virtual bool mayNeedRelaxation(const MCInst &Inst, + /// Check whether the given instruction (encoded as Opcode+Operands) may need + /// relaxation. + virtual bool mayNeedRelaxation(unsigned Opcode, ArrayRef Operands, const MCSubtargetInfo &STI) const { return false; } diff --git a/llvm/include/llvm/MC/MCInst.h b/llvm/include/llvm/MC/MCInst.h index f26af88d92140..b0db6b8408da5 100644 --- a/llvm/include/llvm/MC/MCInst.h +++ b/llvm/include/llvm/MC/MCInst.h @@ -15,6 +15,7 @@ #ifndef LLVM_MC_MCINST_H #define LLVM_MC_MCINST_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/bit.h" @@ -210,7 +211,11 @@ class MCInst { MCOperand &getOperand(unsigned i) { return Operands[i]; } unsigned getNumOperands() const { return Operands.size(); } + ArrayRef getOperands() const { return Operands; } void addOperand(const MCOperand Op) { Operands.push_back(Op); } + void setOperands(ArrayRef Ops) { + Operands.assign(Ops.begin(), Ops.end()); + } using iterator = SmallVectorImpl::iterator; using const_iterator = SmallVectorImpl::const_iterator; diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h index 3abe5e0fe3c6f..f6f62d017dd6a 100644 --- a/llvm/include/llvm/MC/MCSection.h +++ b/llvm/include/llvm/MC/MCSection.h @@ -133,6 +133,7 @@ class LLVM_ABI MCSection { friend MCAssembler; friend MCObjectStreamer; friend class MCEncodedFragment; + friend class MCRelaxableFragment; static constexpr unsigned NonUniqueID = ~0U; enum SectionVariant { @@ -213,6 +214,7 @@ class LLVM_ABI MCSection { // Content and fixup storage for fragments SmallVector ContentStorage; SmallVector FixupStorage; + SmallVector MCOperandStorage; protected: // TODO Make Name private when possible. @@ -221,7 +223,8 @@ class LLVM_ABI MCSection { MCSection(SectionVariant V, StringRef Name, bool IsText, bool IsVirtual, MCSymbol *Begin); - ~MCSection(); + // Protected non-virtual dtor prevents destroy through a base class pointer. + ~MCSection() {} public: MCSection(const MCSection &) = delete; @@ -431,16 +434,38 @@ class MCDataFragment : public MCEncodedFragment { /// class MCRelaxableFragment : public MCEncodedFragment { /// The instruction this is a fragment for. - MCInst Inst; + unsigned Opcode = 0; + uint32_t OperandStart = 0; + uint32_t OperandSize = 0; public: - MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI) - : MCEncodedFragment(FT_Relaxable, true), Inst(Inst) { + MCRelaxableFragment(const MCSubtargetInfo &STI) + : MCEncodedFragment(FT_Relaxable, true) { this->STI = &STI; } - const MCInst &getInst() const { return Inst; } - void setInst(const MCInst &Value) { Inst = Value; } + unsigned getOpcode() const { return Opcode; } + ArrayRef getOperands() const { + return MutableArrayRef(getParent()->MCOperandStorage) + .slice(OperandStart, OperandSize); + } + MCInst getInst() const { + MCInst Inst; + Inst.setOpcode(Opcode); + Inst.setOperands(ArrayRef(getParent()->MCOperandStorage) + .slice(OperandStart, OperandSize)); + return Inst; + } + void setInst(const MCInst &Inst) { + Opcode = Inst.getOpcode(); + auto &S = getParent()->MCOperandStorage; + if (Inst.getNumOperands() > OperandSize) { + OperandStart = S.size(); + S.resize_for_overwrite(S.size() + Inst.getNumOperands()); + } + OperandSize = Inst.getNumOperands(); + llvm::copy(Inst, S.begin() + OperandStart); + } bool getAllowAutoPadding() const { return AllowAutoPadding; } void setAllowAutoPadding(bool V) { AllowAutoPadding = V; } diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index 496d66b1876b2..480e6fe027beb 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -869,7 +869,8 @@ bool MCAssembler::relaxInstruction(MCRelaxableFragment &F) { // If this inst doesn't ever need relaxation, ignore it. This occurs when we // are intentionally pushing out inst fragments, or because we relaxed a // previous instruction to one that doesn't need relaxation. - if (!getBackend().mayNeedRelaxation(F.getInst(), *F.getSubtargetInfo())) + if (!getBackend().mayNeedRelaxation(F.getOpcode(), F.getOperands(), + *F.getSubtargetInfo())) return false; bool DoRelax = false; @@ -881,6 +882,8 @@ bool MCAssembler::relaxInstruction(MCRelaxableFragment &F) { ++stats::RelaxedInstructions; + // TODO Refactor relaxInstruction to accept MCRelaxableFragment and remove + // `setInst`. MCInst Relaxed = F.getInst(); getBackend().relaxInstruction(Relaxed, *F.getSubtargetInfo()); diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index bd1a77467679b..5cc9bed2669d4 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -352,7 +352,7 @@ void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst, // If this instruction doesn't need relaxation, just emit it as data. MCAssembler &Assembler = getAssembler(); MCAsmBackend &Backend = Assembler.getBackend(); - if (!(Backend.mayNeedRelaxation(Inst, STI) || + if (!(Backend.mayNeedRelaxation(Inst.getOpcode(), Inst.getOperands(), STI) || Backend.allowEnhancedRelaxation())) { emitInstToData(Inst, STI); return; @@ -366,7 +366,8 @@ void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst, if (Assembler.getRelaxAll() || (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) { MCInst Relaxed = Inst; - while (Backend.mayNeedRelaxation(Relaxed, STI)) + while (Backend.mayNeedRelaxation(Relaxed.getOpcode(), Relaxed.getOperands(), + STI)) Backend.relaxInstruction(Relaxed, STI); emitInstToData(Relaxed, STI); return; @@ -397,8 +398,9 @@ void MCObjectStreamer::emitInstToFragment(const MCInst &Inst, // Always create a new, separate fragment here, because its size can change // during relaxation. MCRelaxableFragment *IF = - getContext().allocFragment(Inst, STI); + getContext().allocFragment(STI); insert(IF); + IF->setInst(Inst); SmallVector Fixups; getAssembler().getEmitter().encodeInstruction( diff --git a/llvm/lib/MC/MCSection.cpp b/llvm/lib/MC/MCSection.cpp index 09d09e8f997e6..56450033529bc 100644 --- a/llvm/lib/MC/MCSection.cpp +++ b/llvm/lib/MC/MCSection.cpp @@ -36,18 +36,6 @@ MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) { bool MCSection::hasEnded() const { return End && End->isInSection(); } -MCSection::~MCSection() { - // If ~MCRelaxableFragment becomes trivial (no longer store a MCInst member), - // this dtor can be made empty. - for (auto &[_, Chain] : Subsections) { - for (MCFragment *X = Chain.Head, *Y; X; X = Y) { - Y = X->Next; - if (auto *F = dyn_cast(X)) - F->~MCRelaxableFragment(); - } - } -} - void MCSection::setBundleLockState(BundleLockStateType NewState) { if (NewState == NotBundleLocked) { if (BundleLockNestingDepth == 0) { diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp index b333c97ecc378..8f89168754180 100644 --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp @@ -40,7 +40,7 @@ class AMDGPUAsmBackend : public MCAsmBackend { void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const override; - bool mayNeedRelaxation(const MCInst &Inst, + bool mayNeedRelaxation(unsigned Opcode, ArrayRef Operands, const MCSubtargetInfo &STI) const override; unsigned getMinimumNopSize() const override; @@ -70,12 +70,13 @@ bool AMDGPUAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, return (((int64_t(Value)/4)-1) == 0x3f); } -bool AMDGPUAsmBackend::mayNeedRelaxation(const MCInst &Inst, - const MCSubtargetInfo &STI) const { +bool AMDGPUAsmBackend::mayNeedRelaxation(unsigned Opcode, + ArrayRef Operands, + const MCSubtargetInfo &STI) const { if (!STI.hasFeature(AMDGPU::FeatureOffset3fBug)) return false; - if (AMDGPU::getSOPPWithRelaxation(Inst.getOpcode()) >= 0) + if (AMDGPU::getSOPPWithRelaxation(Opcode) >= 0) return true; return false; diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index fc9a32072a627..376bddb120d5f 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -201,11 +201,9 @@ unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op, } } -bool ARMAsmBackend::mayNeedRelaxation(const MCInst &Inst, +bool ARMAsmBackend::mayNeedRelaxation(unsigned Opcode, ArrayRef, const MCSubtargetInfo &STI) const { - if (getRelaxedOpcode(Inst.getOpcode(), STI) != Inst.getOpcode()) - return true; - return false; + return getRelaxedOpcode(Opcode, STI) != Opcode; } static const char *checkPCRelOffset(uint64_t Value, int64_t Min, int64_t Max) { diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h index 52279a3b6936f..877e3afdb1d57 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h @@ -45,7 +45,7 @@ class ARMAsmBackend : public MCAsmBackend { unsigned getRelaxedOpcode(unsigned Op, const MCSubtargetInfo &STI) const; - bool mayNeedRelaxation(const MCInst &Inst, + bool mayNeedRelaxation(unsigned Opcode, ArrayRef Operands, const MCSubtargetInfo &STI) const override; const char *reasonForFixupRelaxation(const MCFixup &Fixup, diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp index 0922d037149e5..ce1da6e58b9cd 100644 --- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp +++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp @@ -239,9 +239,9 @@ void CSKYAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup, } } -bool CSKYAsmBackend::mayNeedRelaxation(const MCInst &Inst, +bool CSKYAsmBackend::mayNeedRelaxation(unsigned Opcode, ArrayRef, const MCSubtargetInfo &STI) const { - switch (Inst.getOpcode()) { + switch (Opcode) { default: return false; case CSKY::JBR32: diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h index 142c667a6175e..1d3a22c2bbbb4 100644 --- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h +++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h @@ -33,12 +33,11 @@ class CSKYAsmBackend : public MCAsmBackend { bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value) const override; + bool mayNeedRelaxation(unsigned Opcode, ArrayRef Operands, + const MCSubtargetInfo &STI) const override; void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const override; - bool mayNeedRelaxation(const MCInst &Inst, - const MCSubtargetInfo &STI) const override; - bool fixupNeedsRelaxationAdvanced(const MCFixup &, const MCValue &, uint64_t, bool) const override; diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp index 847895f84ca9d..de7bd5d4b2c66 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp @@ -40,7 +40,7 @@ class HexagonAsmBackend : public MCAsmBackend { uint8_t OSABI; StringRef CPU; mutable uint64_t relaxedCnt; - mutable const MCInst *RelaxedMCB = nullptr; + mutable MCInst RelaxedMCB; std::unique_ptr MCII; std::unique_ptr RelaxTarget; MCInst * Extender; @@ -428,13 +428,11 @@ class HexagonAsmBackend : public MCAsmBackend { return Relaxable; } - /// MayNeedRelaxation - Check whether the given instruction may need - /// relaxation. - /// - /// \param Inst - The instruction to test. - bool mayNeedRelaxation(MCInst const &Inst, + bool mayNeedRelaxation(unsigned Opcode, ArrayRef Operands, const MCSubtargetInfo &STI) const override { - RelaxedMCB = &Inst; + RelaxedMCB.clear(); + RelaxedMCB.setOpcode(Opcode); + RelaxedMCB.setOperands(Operands); return true; } @@ -443,7 +441,7 @@ class HexagonAsmBackend : public MCAsmBackend { bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, const MCValue &, uint64_t Value, bool Resolved) const override { - MCInst const &MCB = *RelaxedMCB; + MCInst const &MCB = RelaxedMCB; assert(HexagonMCInstrInfo::isBundle(MCB)); *RelaxTarget = nullptr; @@ -598,7 +596,7 @@ class HexagonAsmBackend : public MCAsmBackend { case MCFragment::FT_Relaxable: { MCContext &Context = getContext(); auto &RF = cast(*Frags[K]); - auto &Inst = const_cast(RF.getInst()); + MCInst Inst = RF.getInst(); const bool WouldTraverseLabel = llvm::any_of( Asm.symbols(), [&Asm, &RF, &Inst](MCSymbol const &sym) { diff --git a/llvm/lib/Target/M68k/MCTargetDesc/M68kAsmBackend.cpp b/llvm/lib/Target/M68k/MCTargetDesc/M68kAsmBackend.cpp index f0c3728ec0eea..5e039033704f9 100644 --- a/llvm/lib/Target/M68k/MCTargetDesc/M68kAsmBackend.cpp +++ b/llvm/lib/Target/M68k/MCTargetDesc/M68kAsmBackend.cpp @@ -56,7 +56,7 @@ class M68kAsmBackend : public MCAsmBackend { MutableArrayRef Data, uint64_t Value, bool IsResolved) override; - bool mayNeedRelaxation(const MCInst &Inst, + bool mayNeedRelaxation(unsigned Opcode, ArrayRef Operands, const MCSubtargetInfo &STI) const override; bool fixupNeedsRelaxation(const MCFixup &Fixup, @@ -183,10 +183,10 @@ static unsigned getRelaxedOpcode(unsigned Opcode) { return getRelaxedOpcodeBranch(Opcode); } -bool M68kAsmBackend::mayNeedRelaxation(const MCInst &Inst, +bool M68kAsmBackend::mayNeedRelaxation(unsigned Opcode, ArrayRef, const MCSubtargetInfo &STI) const { // Branches can always be relaxed in either mode. - return getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode(); + return getRelaxedOpcode(Opcode) != Opcode; // NOTE will change for x20 mem } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp index f88e4d8fc8c71..89a87798d71e4 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -140,9 +140,9 @@ bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, // Given a compressed control flow instruction this function returns // the expanded instruction, or the original instruction code if no // expansion is available. -static unsigned getRelaxedOpcode(const MCInst &Inst, +static unsigned getRelaxedOpcode(unsigned Opcode, ArrayRef Operands, const MCSubtargetInfo &STI) { - switch (Inst.getOpcode()) { + switch (Opcode) { case RISCV::C_BEQZ: return RISCV::BEQ; case RISCV::C_BNEZ: @@ -158,7 +158,7 @@ static unsigned getRelaxedOpcode(const MCInst &Inst, break; // And only if it is using X0 or X1 for rd. - MCRegister Reg = Inst.getOperand(0).getReg(); + MCRegister Reg = Operands[0].getReg(); if (Reg == RISCV::X0) return RISCV::QC_E_J; if (Reg == RISCV::X1) @@ -205,7 +205,7 @@ static unsigned getRelaxedOpcode(const MCInst &Inst, } // Returning the original opcode means we cannot relax the instruction. - return Inst.getOpcode(); + return Opcode; } void RISCVAsmBackend::relaxInstruction(MCInst &Inst, @@ -223,7 +223,8 @@ void RISCVAsmBackend::relaxInstruction(MCInst &Inst, case RISCV::C_JAL: { [[maybe_unused]] bool Success = RISCVRVC::uncompress(Res, Inst, STI); assert(Success && "Can't uncompress instruction"); - assert(Res.getOpcode() == getRelaxedOpcode(Inst, STI) && + assert(Res.getOpcode() == + getRelaxedOpcode(Inst.getOpcode(), Inst.getOperands(), STI) && "Branch Relaxation Error"); break; } @@ -235,7 +236,7 @@ void RISCVAsmBackend::relaxInstruction(MCInst &Inst, assert((Inst.getOperand(0).getReg() == RISCV::X0 || Inst.getOperand(0).getReg() == RISCV::X1) && "JAL only relaxable with rd=x0 or rd=x1"); - Res.setOpcode(getRelaxedOpcode(Inst, STI)); + Res.setOpcode(getRelaxedOpcode(Inst.getOpcode(), Inst.getOperands(), STI)); Res.addOperand(Inst.getOperand(1)); break; } @@ -257,7 +258,7 @@ void RISCVAsmBackend::relaxInstruction(MCInst &Inst, case RISCV::QC_E_BGEI: case RISCV::QC_E_BLTUI: case RISCV::QC_E_BGEUI: - Res.setOpcode(getRelaxedOpcode(Inst, STI)); + Res.setOpcode(getRelaxedOpcode(Inst.getOpcode(), Inst.getOperands(), STI)); Res.addOperand(Inst.getOperand(0)); Res.addOperand(Inst.getOperand(1)); Res.addOperand(Inst.getOperand(2)); @@ -399,7 +400,8 @@ std::pair RISCVAsmBackend::relaxLEB128(MCLEBFragment &LF, return std::make_pair(Expr.evaluateKnownAbsolute(Value, *Asm), false); } -bool RISCVAsmBackend::mayNeedRelaxation(const MCInst &Inst, +bool RISCVAsmBackend::mayNeedRelaxation(unsigned Opcode, + ArrayRef Operands, const MCSubtargetInfo &STI) const { // This function has access to two STIs, the member of the AsmBackend, and the // one passed as an argument. The latter is more specific, so we query it for @@ -407,7 +409,7 @@ bool RISCVAsmBackend::mayNeedRelaxation(const MCInst &Inst, if (STI.hasFeature(RISCV::FeatureExactAssembly)) return false; - return getRelaxedOpcode(Inst, STI) != Inst.getOpcode(); + return getRelaxedOpcode(Opcode, Operands, STI) != Opcode; } bool RISCVAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h index 305240af88ec5..1f1a6f5fe31a0 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h @@ -67,9 +67,8 @@ class RISCVAsmBackend : public MCAsmBackend { MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override; - bool mayNeedRelaxation(const MCInst &Inst, + bool mayNeedRelaxation(unsigned Opcode, ArrayRef Operands, const MCSubtargetInfo &STI) const override; - void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const override; diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEAsmBackend.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEAsmBackend.cpp index 270c1e08397bd..e09a916d48c90 100644 --- a/llvm/lib/Target/VE/MCTargetDesc/VEAsmBackend.cpp +++ b/llvm/lib/Target/VE/MCTargetDesc/VEAsmBackend.cpp @@ -115,7 +115,7 @@ class VEAsmBackend : public MCAsmBackend { MutableArrayRef, uint64_t Value, bool IsResolved) override; - bool mayNeedRelaxation(const MCInst &Inst, + bool mayNeedRelaxation(unsigned Opcode, ArrayRef Operands, const MCSubtargetInfo &STI) const override { // Not implemented yet. For example, if we have a branch with // lager than SIMM32 immediate value, we want to relaxation such diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index 8f667ad232a12..17a1b4ac6c12f 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -174,7 +174,7 @@ class X86AsmBackend : public MCAsmBackend { MutableArrayRef Data, uint64_t Value, bool IsResolved) override; - bool mayNeedRelaxation(const MCInst &Inst, + bool mayNeedRelaxation(unsigned Opcode, ArrayRef Operands, const MCSubtargetInfo &STI) const override; bool fixupNeedsRelaxationAdvanced(const MCFixup &, const MCValue &, uint64_t, @@ -720,13 +720,13 @@ void X86AsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup, Data[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8)); } -bool X86AsmBackend::mayNeedRelaxation(const MCInst &MI, +bool X86AsmBackend::mayNeedRelaxation(unsigned Opcode, + ArrayRef Operands, const MCSubtargetInfo &STI) const { - unsigned Opcode = MI.getOpcode(); unsigned SkipOperands = X86::isCCMPCC(Opcode) ? 2 : 0; return isRelaxableBranch(Opcode) || (X86::getOpcodeForLongImmediateForm(Opcode) != Opcode && - MI.getOperand(MI.getNumOperands() - 1 - SkipOperands).isExpr()); + Operands[Operands.size() - 1 - SkipOperands].isExpr()); } bool X86AsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, @@ -767,7 +767,8 @@ bool X86AsmBackend::padInstructionViaPrefix(MCRelaxableFragment &RF, // larger value for one of the fixups then can be encoded. The outer loop // will also catch this before moving to the next instruction, but we need to // prevent padding this single instruction as well. - if (mayNeedRelaxation(RF.getInst(), *RF.getSubtargetInfo())) + if (mayNeedRelaxation(RF.getOpcode(), RF.getOperands(), + *RF.getSubtargetInfo())) return false; const unsigned OldSize = RF.getContents().size(); @@ -814,7 +815,8 @@ bool X86AsmBackend::padInstructionViaPrefix(MCRelaxableFragment &RF, bool X86AsmBackend::padInstructionViaRelaxation(MCRelaxableFragment &RF, MCCodeEmitter &Emitter, unsigned &RemainingSize) const { - if (!mayNeedRelaxation(RF.getInst(), *RF.getSubtargetInfo())) + if (!mayNeedRelaxation(RF.getOpcode(), RF.getOperands(), + *RF.getSubtargetInfo())) // TODO: There are lots of other tricks we could apply for increasing // encoding size without impacting performance. return false; @@ -923,7 +925,8 @@ bool X86AsmBackend::finishLayout(const MCAssembler &Asm) const { // We don't need to worry about larger positive offsets as none of the // possible offsets between this and our align are visible, and the // ones afterwards aren't changing. - if (mayNeedRelaxation(RF.getInst(), *RF.getSubtargetInfo())) + if (mayNeedRelaxation(RF.getOpcode(), RF.getOperands(), + *RF.getSubtargetInfo())) break; } Relaxable.clear(); diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp index 8ae48d51891e5..671f1d04daf23 100644 --- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp +++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp @@ -39,8 +39,6 @@ class XtensaAsmBackend : public MCAsmBackend { void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target, MutableArrayRef Data, uint64_t Value, bool IsResolved) override; - bool mayNeedRelaxation(const MCInst &Inst, - const MCSubtargetInfo &STI) const override; bool writeNopData(raw_ostream &OS, uint64_t Count, const MCSubtargetInfo *STI) const override; @@ -178,11 +176,6 @@ void XtensaAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup, } } -bool XtensaAsmBackend::mayNeedRelaxation(const MCInst &Inst, - const MCSubtargetInfo &STI) const { - return false; -} - bool XtensaAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, const MCSubtargetInfo *STI) const { uint64_t NumNops24b = Count / 3; From 0cbaab679c4ad763666c1ced624216784ba6deb9 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 7 Jul 2025 09:27:32 -0700 Subject: [PATCH 2/2] add assert Created using spr 1.3.5-bogner --- llvm/include/llvm/MC/MCSection.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h index 85f190914b671..c092cba0a825b 100644 --- a/llvm/include/llvm/MC/MCSection.h +++ b/llvm/include/llvm/MC/MCSection.h @@ -451,6 +451,10 @@ class MCRelaxableFragment : public MCEncodedFragment { return Inst; } void setInst(const MCInst &Inst) { + // If we ever support Flags in relaxable fragments, revisit the data + // structure. + assert(Inst.getFlags() == 0 && "relaxable fragment doesn't support flags"); + Opcode = Inst.getOpcode(); auto &S = getParent()->MCOperandStorage; if (Inst.getNumOperands() > OperandSize) {