[llvm] 152c9d5 - MC: Sink FKF_IsAlignedDownTo32Bits to needed targets
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 5 11:11:11 PDT 2025
Author: Fangrui Song
Date: 2025-07-05T11:11:07-07:00
New Revision: 152c9d577c41ac45a85bc555b56a3c4a2046ec5b
URL: https://github.com/llvm/llvm-project/commit/152c9d577c41ac45a85bc555b56a3c4a2046ec5b
DIFF: https://github.com/llvm/llvm-project/commit/152c9d577c41ac45a85bc555b56a3c4a2046ec5b.diff
LOG: MC: Sink FKF_IsAlignedDownTo32Bits to needed targets
Utilize the generalized MCAsmBackend::evaluateFixup hook. This reduces
overhead for other targets (e.g., x86).
Now MCAsmBackend::getFixupKindInfo is only used by MCAsmStreamer
-show-encoding in the generic code.
Added:
Modified:
llvm/include/llvm/MC/MCAsmBackend.h
llvm/lib/MC/MCAssembler.cpp
llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h
index fae7fba8e8274..bfec916c9bf3a 100644
--- a/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/llvm/include/llvm/MC/MCAsmBackend.h
@@ -41,14 +41,6 @@ class raw_ostream;
/// Target independent information on a fixup kind.
struct MCFixupKindInfo {
- enum FixupKindFlags {
- /// Should this fixup kind force a 4-byte aligned effective PC value?
- FKF_IsAlignedDownTo32Bits = (1 << 1),
-
- /// Should this fixup be evaluated in a target dependent manner?
- FKF_IsTarget = (1 << 2),
- };
-
/// A target specific name for the fixup kind. The names will be unique for
/// distinct kinds on any given target.
const char *Name;
@@ -134,8 +126,8 @@ class LLVM_ABI MCAsmBackend {
// Evaluate a fixup, returning std::nullopt to use default handling for
// `Value` and `IsResolved`. Otherwise, returns `IsResolved` with the
// expectation that the hook updates `Value`.
- virtual std::optional<bool> evaluateFixup(MCFixup &Fixup, MCValue &Target,
- uint64_t &Value) {
+ virtual std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &,
+ MCValue &, uint64_t &) {
return {};
}
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index e02fcb1e77f92..ae41abd650f7a 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -161,38 +161,26 @@ bool MCAssembler::evaluateFixup(const MCFragment &F, MCFixup &Fixup,
return true;
}
- unsigned FixupFlags = getBackend().getFixupKindInfo(Fixup.getKind()).Flags;
bool IsResolved = false;
- if (auto State = getBackend().evaluateFixup(Fixup, Target, Value)) {
+ if (auto State = getBackend().evaluateFixup(F, Fixup, Target, Value)) {
IsResolved = *State;
} else {
const MCSymbol *Add = Target.getAddSym();
const MCSymbol *Sub = Target.getSubSym();
- Value = Target.getConstant();
+ Value += Target.getConstant();
if (Add && Add->isDefined())
Value += getSymbolOffset(*Add);
if (Sub && Sub->isDefined())
Value -= getSymbolOffset(*Sub);
- bool ShouldAlignPC =
- FixupFlags & MCFixupKindInfo::FKF_IsAlignedDownTo32Bits;
if (Fixup.isPCRel()) {
- uint64_t Offset = getFragmentOffset(F) + Fixup.getOffset();
-
- // A number of ARM fixups in Thumb mode require that the effective PC
- // address be determined as the 32-bit aligned version of the actual
- // offset.
- if (ShouldAlignPC)
- Offset &= ~0x3;
- Value -= Offset;
-
+ Value -= getFragmentOffset(F) + Fixup.getOffset();
if (Add && !Sub && !Add->isUndefined() && !Add->isAbsolute()) {
IsResolved = getWriter().isSymbolRefDifferenceFullyResolvedImpl(
*Add, F, false, true);
}
} else {
IsResolved = Target.isAbsolute();
- assert(!ShouldAlignPC && "FKF_IsAlignedDownTo32Bits must be PC-relative");
}
}
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index d360be8aa1759..ca6d59d63b625 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -71,19 +71,16 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
//
// Name Offset (bits) Size (bits) Flags
{"fixup_arm_ldst_pcrel_12", 0, 32, 0},
- {"fixup_t2_ldst_pcrel_12", 0, 32,
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_t2_ldst_pcrel_12", 0, 32, 0},
{"fixup_arm_pcrel_10_unscaled", 0, 32, 0},
{"fixup_arm_pcrel_10", 0, 32, 0},
- {"fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_t2_pcrel_10", 0, 32, 0},
{"fixup_arm_pcrel_9", 0, 32, 0},
- {"fixup_t2_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_t2_pcrel_9", 0, 32, 0},
{"fixup_arm_ldst_abs_12", 0, 32, 0},
- {"fixup_thumb_adr_pcrel_10", 0, 8,
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_thumb_adr_pcrel_10", 0, 8, 0},
{"fixup_arm_adr_pcrel_12", 0, 32, 0},
- {"fixup_t2_adr_pcrel_12", 0, 32,
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_t2_adr_pcrel_12", 0, 32, 0},
{"fixup_arm_condbranch", 0, 24, 0},
{"fixup_arm_uncondbranch", 0, 24, 0},
{"fixup_t2_condbranch", 0, 32, 0},
@@ -93,10 +90,9 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{"fixup_arm_condbl", 0, 24, 0},
{"fixup_arm_blx", 0, 24, 0},
{"fixup_arm_thumb_bl", 0, 32, 0},
- {"fixup_arm_thumb_blx", 0, 32,
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_arm_thumb_blx", 0, 32, 0},
{"fixup_arm_thumb_cb", 0, 16, 0},
- {"fixup_arm_thumb_cp", 0, 8, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_arm_thumb_cp", 0, 8, 0},
{"fixup_arm_thumb_bcc", 0, 8, 0},
// movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
// - 19.
@@ -124,19 +120,16 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
//
// Name Offset (bits) Size (bits) Flags
{"fixup_arm_ldst_pcrel_12", 0, 32, 0},
- {"fixup_t2_ldst_pcrel_12", 0, 32,
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_t2_ldst_pcrel_12", 0, 32, 0},
{"fixup_arm_pcrel_10_unscaled", 0, 32, 0},
{"fixup_arm_pcrel_10", 0, 32, 0},
- {"fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_t2_pcrel_10", 0, 32, 0},
{"fixup_arm_pcrel_9", 0, 32, 0},
- {"fixup_t2_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_t2_pcrel_9", 0, 32, 0},
{"fixup_arm_ldst_abs_12", 0, 32, 0},
- {"fixup_thumb_adr_pcrel_10", 8, 8,
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_thumb_adr_pcrel_10", 8, 8, 0},
{"fixup_arm_adr_pcrel_12", 0, 32, 0},
- {"fixup_t2_adr_pcrel_12", 0, 32,
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_t2_adr_pcrel_12", 0, 32, 0},
{"fixup_arm_condbranch", 8, 24, 0},
{"fixup_arm_uncondbranch", 8, 24, 0},
{"fixup_t2_condbranch", 0, 32, 0},
@@ -146,10 +139,9 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{"fixup_arm_condbl", 8, 24, 0},
{"fixup_arm_blx", 8, 24, 0},
{"fixup_arm_thumb_bl", 0, 32, 0},
- {"fixup_arm_thumb_blx", 0, 32,
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_arm_thumb_blx", 0, 32, 0},
{"fixup_arm_thumb_cb", 0, 16, 0},
- {"fixup_arm_thumb_cp", 8, 8, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_arm_thumb_cp", 8, 8, 0},
{"fixup_arm_thumb_bcc", 8, 8, 0},
// movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
// - 19.
@@ -1106,6 +1098,25 @@ static unsigned getFixupKindContainerSizeBytes(unsigned Kind) {
}
}
+std::optional<bool> ARMAsmBackend::evaluateFixup(const MCFragment &F,
+ MCFixup &Fixup, MCValue &,
+ uint64_t &Value) {
+ // For a few PC-relative fixups in Thumb mode, offsets need to be aligned
+ // down. We compensate here because the default handler's `Value` decrement
+ // doesn't account for this alignment.
+ switch (Fixup.getTargetKind()) {
+ case ARM::fixup_t2_ldst_pcrel_12:
+ case ARM::fixup_t2_pcrel_10:
+ case ARM::fixup_t2_pcrel_9:
+ case ARM::fixup_thumb_adr_pcrel_10:
+ case ARM::fixup_t2_adr_pcrel_12:
+ case ARM::fixup_arm_thumb_blx:
+ case ARM::fixup_arm_thumb_cp:
+ Value = (Asm->getFragmentOffset(F) + Fixup.getOffset()) % 4;
+ }
+ return {};
+}
+
void ARMAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
index fce97c4291c51..52279a3b6936f 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
@@ -37,6 +37,8 @@ class ARMAsmBackend : public MCAsmBackend {
bool IsResolved, MCContext &Ctx,
const MCSubtargetInfo *STI) const;
+ std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
+ uint64_t &) override;
void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) override;
diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
index 735d222c074fc..37c17e2ce5005 100644
--- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
+++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
@@ -34,11 +34,9 @@ MCFixupKindInfo CSKYAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{CSKY::Fixups::fixup_csky_pcrel_imm16_scale2,
{"fixup_csky_pcrel_imm16_scale2", 0, 32, 0}},
{CSKY::Fixups::fixup_csky_pcrel_uimm16_scale4,
- {"fixup_csky_pcrel_uimm16_scale4", 0, 32,
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
+ {"fixup_csky_pcrel_uimm16_scale4", 0, 32, 0}},
{CSKY::Fixups::fixup_csky_pcrel_uimm8_scale4,
- {"fixup_csky_pcrel_uimm8_scale4", 0, 32,
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
+ {"fixup_csky_pcrel_uimm8_scale4", 0, 32, 0}},
{CSKY::Fixups::fixup_csky_pcrel_imm26_scale2,
{"fixup_csky_pcrel_imm26_scale2", 0, 32, 0}},
{CSKY::Fixups::fixup_csky_pcrel_imm18_scale2,
@@ -54,8 +52,7 @@ MCFixupKindInfo CSKYAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{CSKY::Fixups::fixup_csky_pcrel_imm10_scale2,
{"fixup_csky_pcrel_imm10_scale2", 0, 16, 0}},
{CSKY::Fixups::fixup_csky_pcrel_uimm7_scale4,
- {"fixup_csky_pcrel_uimm7_scale4", 0, 16,
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
+ {"fixup_csky_pcrel_uimm7_scale4", 0, 16, 0}},
{CSKY::Fixups::fixup_csky_doffset_imm18,
{"fixup_csky_doffset_imm18", 0, 18, 0}},
{CSKY::Fixups::fixup_csky_doffset_imm18_scale2,
@@ -184,6 +181,21 @@ bool CSKYAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
}
}
+std::optional<bool> CSKYAsmBackend::evaluateFixup(const MCFragment &F,
+ MCFixup &Fixup, MCValue &,
+ uint64_t &Value) {
+ // For a few PC-relative fixups, offsets need to be aligned down. We
+ // compensate here because the default handler's `Value` decrement doesn't
+ // account for this alignment.
+ switch (Fixup.getTargetKind()) {
+ case CSKY::fixup_csky_pcrel_uimm16_scale4:
+ case CSKY::fixup_csky_pcrel_uimm8_scale4:
+ case CSKY::fixup_csky_pcrel_uimm7_scale4:
+ Value = (Asm->getFragmentOffset(F) + Fixup.getOffset()) % 4;
+ }
+ return {};
+}
+
void CSKYAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
index c0eff853d87bd..142c667a6175e 100644
--- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
+++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
@@ -22,6 +22,8 @@ class CSKYAsmBackend : public MCAsmBackend {
CSKYAsmBackend(const MCSubtargetInfo &STI, const MCTargetOptions &OP)
: MCAsmBackend(llvm::endianness::little) {}
+ std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
+ uint64_t &) override;
void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) override;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index ce0d030031cdb..1b7c2a934c497 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -655,7 +655,8 @@ static const MCFixup *getPCRelHiFixup(const MCSpecifierExpr &Expr,
return nullptr;
}
-std::optional<bool> RISCVAsmBackend::evaluateFixup(MCFixup &Fixup,
+std::optional<bool> RISCVAsmBackend::evaluateFixup(const MCFragment &,
+ MCFixup &Fixup,
MCValue &Target,
uint64_t &Value) {
const MCFixup *AUIPCFixup;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
index 292cacdbd45af..6f75fcae8c5c0 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
@@ -47,9 +47,8 @@ class RISCVAsmBackend : public MCAsmBackend {
bool shouldInsertFixupForCodeAlign(MCAssembler &Asm,
MCAlignFragment &AF) override;
- std::optional<bool> evaluateFixup(MCFixup &Fixup, MCValue &Target,
- uint64_t &Value) override;
-
+ std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
+ uint64_t &) override;
bool addReloc(const MCFragment &, const MCFixup &, const MCValue &,
uint64_t &FixedValue, bool IsResolved);
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
index 54861b7a0ad65..a2a418312f5de 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
@@ -16,6 +16,7 @@
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCValue.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -34,6 +35,8 @@ class XtensaAsmBackend : public MCAsmBackend {
IsLittleEndian(isLE) {}
MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override;
+ std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
+ uint64_t &) override;
void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) override;
@@ -57,10 +60,8 @@ MCFixupKindInfo XtensaAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{"fixup_xtensa_branch_8", 16, 8, 0},
{"fixup_xtensa_branch_12", 12, 12, 0},
{"fixup_xtensa_jump_18", 6, 18, 0},
- {"fixup_xtensa_call_18", 6, 18,
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
- {"fixup_xtensa_l32r_16", 8, 16,
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_xtensa_call_18", 6, 18, 0},
+ {"fixup_xtensa_l32r_16", 8, 16, 0},
{"fixup_xtensa_loop_8", 16, 8, 0},
};
@@ -142,6 +143,20 @@ static unsigned getSize(unsigned Kind) {
}
}
+std::optional<bool> XtensaAsmBackend::evaluateFixup(const MCFragment &F,
+ MCFixup &Fixup, MCValue &,
+ uint64_t &Value) {
+ // For a few PC-relative fixups, offsets need to be aligned down. We
+ // compensate here because the default handler's `Value` decrement doesn't
+ // account for this alignment.
+ switch (Fixup.getTargetKind()) {
+ case Xtensa::fixup_xtensa_call_18:
+ case Xtensa::fixup_xtensa_l32r_16:
+ Value = (Asm->getFragmentOffset(F) + Fixup.getOffset()) % 4;
+ }
+ return {};
+}
+
void XtensaAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
More information about the llvm-commits
mailing list