[llvm] MC: Store MCRelaxableFragment MCInst out-of-line (PR #147229)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 7 21:14:13 PDT 2025
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/147229
>From baafbc01ecf6dbf2b319b19d1c07a92faad4c010 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
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<MCOperand> 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<MCOperand> getOperands() const { return Operands; }
void addOperand(const MCOperand Op) { Operands.push_back(Op); }
+ void setOperands(ArrayRef<MCOperand> Ops) {
+ Operands.assign(Ops.begin(), Ops.end());
+ }
using iterator = SmallVectorImpl<MCOperand>::iterator;
using const_iterator = SmallVectorImpl<MCOperand>::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<char, 0> ContentStorage;
SmallVector<MCFixup, 0> FixupStorage;
+ SmallVector<MCOperand, 0> 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<MCOperand> 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<MCRelaxableFragment>(Inst, STI);
+ getContext().allocFragment<MCRelaxableFragment>(STI);
insert(IF);
+ IF->setInst(Inst);
SmallVector<MCFixup, 1> 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<MCRelaxableFragment>(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<MCOperand> 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<MCOperand> 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<MCOperand>,
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<MCOperand> 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<MCOperand>,
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<MCOperand> 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 <MCInstrInfo> MCII;
std::unique_ptr <MCInst *> 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<MCOperand> 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<MCRelaxableFragment>(*Frags[K]);
- auto &Inst = const_cast<MCInst &>(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<char> Data, uint64_t Value,
bool IsResolved) override;
- bool mayNeedRelaxation(const MCInst &Inst,
+ bool mayNeedRelaxation(unsigned Opcode, ArrayRef<MCOperand> 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<MCOperand>,
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<MCOperand> 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<bool, bool> 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<MCOperand> 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<MCOperand> 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<char>, uint64_t Value,
bool IsResolved) override;
- bool mayNeedRelaxation(const MCInst &Inst,
+ bool mayNeedRelaxation(unsigned Opcode, ArrayRef<MCOperand> 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<char> Data, uint64_t Value,
bool IsResolved) override;
- bool mayNeedRelaxation(const MCInst &Inst,
+ bool mayNeedRelaxation(unsigned Opcode, ArrayRef<MCOperand> 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<MCOperand> 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<char> 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 <i at maskray.me>
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) {
More information about the llvm-commits
mailing list