Skip to content

Commit 152c9d5

Browse files
committed
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.
1 parent 3f4be89 commit 152c9d5

File tree

9 files changed

+83
-61
lines changed

9 files changed

+83
-61
lines changed

llvm/include/llvm/MC/MCAsmBackend.h

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,6 @@ class raw_ostream;
4141

4242
/// Target independent information on a fixup kind.
4343
struct MCFixupKindInfo {
44-
enum FixupKindFlags {
45-
/// Should this fixup kind force a 4-byte aligned effective PC value?
46-
FKF_IsAlignedDownTo32Bits = (1 << 1),
47-
48-
/// Should this fixup be evaluated in a target dependent manner?
49-
FKF_IsTarget = (1 << 2),
50-
};
51-
5244
/// A target specific name for the fixup kind. The names will be unique for
5345
/// distinct kinds on any given target.
5446
const char *Name;
@@ -134,8 +126,8 @@ class LLVM_ABI MCAsmBackend {
134126
// Evaluate a fixup, returning std::nullopt to use default handling for
135127
// `Value` and `IsResolved`. Otherwise, returns `IsResolved` with the
136128
// expectation that the hook updates `Value`.
137-
virtual std::optional<bool> evaluateFixup(MCFixup &Fixup, MCValue &Target,
138-
uint64_t &Value) {
129+
virtual std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &,
130+
MCValue &, uint64_t &) {
139131
return {};
140132
}
141133

llvm/lib/MC/MCAssembler.cpp

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -161,38 +161,26 @@ bool MCAssembler::evaluateFixup(const MCFragment &F, MCFixup &Fixup,
161161
return true;
162162
}
163163

164-
unsigned FixupFlags = getBackend().getFixupKindInfo(Fixup.getKind()).Flags;
165164
bool IsResolved = false;
166-
if (auto State = getBackend().evaluateFixup(Fixup, Target, Value)) {
165+
if (auto State = getBackend().evaluateFixup(F, Fixup, Target, Value)) {
167166
IsResolved = *State;
168167
} else {
169168
const MCSymbol *Add = Target.getAddSym();
170169
const MCSymbol *Sub = Target.getSubSym();
171-
Value = Target.getConstant();
170+
Value += Target.getConstant();
172171
if (Add && Add->isDefined())
173172
Value += getSymbolOffset(*Add);
174173
if (Sub && Sub->isDefined())
175174
Value -= getSymbolOffset(*Sub);
176175

177-
bool ShouldAlignPC =
178-
FixupFlags & MCFixupKindInfo::FKF_IsAlignedDownTo32Bits;
179176
if (Fixup.isPCRel()) {
180-
uint64_t Offset = getFragmentOffset(F) + Fixup.getOffset();
181-
182-
// A number of ARM fixups in Thumb mode require that the effective PC
183-
// address be determined as the 32-bit aligned version of the actual
184-
// offset.
185-
if (ShouldAlignPC)
186-
Offset &= ~0x3;
187-
Value -= Offset;
188-
177+
Value -= getFragmentOffset(F) + Fixup.getOffset();
189178
if (Add && !Sub && !Add->isUndefined() && !Add->isAbsolute()) {
190179
IsResolved = getWriter().isSymbolRefDifferenceFullyResolvedImpl(
191180
*Add, F, false, true);
192181
}
193182
} else {
194183
IsResolved = Target.isAbsolute();
195-
assert(!ShouldAlignPC && "FKF_IsAlignedDownTo32Bits must be PC-relative");
196184
}
197185
}
198186

llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,16 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
7171
//
7272
// Name Offset (bits) Size (bits) Flags
7373
{"fixup_arm_ldst_pcrel_12", 0, 32, 0},
74-
{"fixup_t2_ldst_pcrel_12", 0, 32,
75-
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
74+
{"fixup_t2_ldst_pcrel_12", 0, 32, 0},
7675
{"fixup_arm_pcrel_10_unscaled", 0, 32, 0},
7776
{"fixup_arm_pcrel_10", 0, 32, 0},
78-
{"fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
77+
{"fixup_t2_pcrel_10", 0, 32, 0},
7978
{"fixup_arm_pcrel_9", 0, 32, 0},
80-
{"fixup_t2_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
79+
{"fixup_t2_pcrel_9", 0, 32, 0},
8180
{"fixup_arm_ldst_abs_12", 0, 32, 0},
82-
{"fixup_thumb_adr_pcrel_10", 0, 8,
83-
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
81+
{"fixup_thumb_adr_pcrel_10", 0, 8, 0},
8482
{"fixup_arm_adr_pcrel_12", 0, 32, 0},
85-
{"fixup_t2_adr_pcrel_12", 0, 32,
86-
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
83+
{"fixup_t2_adr_pcrel_12", 0, 32, 0},
8784
{"fixup_arm_condbranch", 0, 24, 0},
8885
{"fixup_arm_uncondbranch", 0, 24, 0},
8986
{"fixup_t2_condbranch", 0, 32, 0},
@@ -93,10 +90,9 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
9390
{"fixup_arm_condbl", 0, 24, 0},
9491
{"fixup_arm_blx", 0, 24, 0},
9592
{"fixup_arm_thumb_bl", 0, 32, 0},
96-
{"fixup_arm_thumb_blx", 0, 32,
97-
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
93+
{"fixup_arm_thumb_blx", 0, 32, 0},
9894
{"fixup_arm_thumb_cb", 0, 16, 0},
99-
{"fixup_arm_thumb_cp", 0, 8, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
95+
{"fixup_arm_thumb_cp", 0, 8, 0},
10096
{"fixup_arm_thumb_bcc", 0, 8, 0},
10197
// movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
10298
// - 19.
@@ -124,19 +120,16 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
124120
//
125121
// Name Offset (bits) Size (bits) Flags
126122
{"fixup_arm_ldst_pcrel_12", 0, 32, 0},
127-
{"fixup_t2_ldst_pcrel_12", 0, 32,
128-
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
123+
{"fixup_t2_ldst_pcrel_12", 0, 32, 0},
129124
{"fixup_arm_pcrel_10_unscaled", 0, 32, 0},
130125
{"fixup_arm_pcrel_10", 0, 32, 0},
131-
{"fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
126+
{"fixup_t2_pcrel_10", 0, 32, 0},
132127
{"fixup_arm_pcrel_9", 0, 32, 0},
133-
{"fixup_t2_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
128+
{"fixup_t2_pcrel_9", 0, 32, 0},
134129
{"fixup_arm_ldst_abs_12", 0, 32, 0},
135-
{"fixup_thumb_adr_pcrel_10", 8, 8,
136-
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
130+
{"fixup_thumb_adr_pcrel_10", 8, 8, 0},
137131
{"fixup_arm_adr_pcrel_12", 0, 32, 0},
138-
{"fixup_t2_adr_pcrel_12", 0, 32,
139-
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
132+
{"fixup_t2_adr_pcrel_12", 0, 32, 0},
140133
{"fixup_arm_condbranch", 8, 24, 0},
141134
{"fixup_arm_uncondbranch", 8, 24, 0},
142135
{"fixup_t2_condbranch", 0, 32, 0},
@@ -146,10 +139,9 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
146139
{"fixup_arm_condbl", 8, 24, 0},
147140
{"fixup_arm_blx", 8, 24, 0},
148141
{"fixup_arm_thumb_bl", 0, 32, 0},
149-
{"fixup_arm_thumb_blx", 0, 32,
150-
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
142+
{"fixup_arm_thumb_blx", 0, 32, 0},
151143
{"fixup_arm_thumb_cb", 0, 16, 0},
152-
{"fixup_arm_thumb_cp", 8, 8, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
144+
{"fixup_arm_thumb_cp", 8, 8, 0},
153145
{"fixup_arm_thumb_bcc", 8, 8, 0},
154146
// movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
155147
// - 19.
@@ -1106,6 +1098,25 @@ static unsigned getFixupKindContainerSizeBytes(unsigned Kind) {
11061098
}
11071099
}
11081100

1101+
std::optional<bool> ARMAsmBackend::evaluateFixup(const MCFragment &F,
1102+
MCFixup &Fixup, MCValue &,
1103+
uint64_t &Value) {
1104+
// For a few PC-relative fixups in Thumb mode, offsets need to be aligned
1105+
// down. We compensate here because the default handler's `Value` decrement
1106+
// doesn't account for this alignment.
1107+
switch (Fixup.getTargetKind()) {
1108+
case ARM::fixup_t2_ldst_pcrel_12:
1109+
case ARM::fixup_t2_pcrel_10:
1110+
case ARM::fixup_t2_pcrel_9:
1111+
case ARM::fixup_thumb_adr_pcrel_10:
1112+
case ARM::fixup_t2_adr_pcrel_12:
1113+
case ARM::fixup_arm_thumb_blx:
1114+
case ARM::fixup_arm_thumb_cp:
1115+
Value = (Asm->getFragmentOffset(F) + Fixup.getOffset()) % 4;
1116+
}
1117+
return {};
1118+
}
1119+
11091120
void ARMAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
11101121
const MCValue &Target,
11111122
MutableArrayRef<char> Data, uint64_t Value,

llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class ARMAsmBackend : public MCAsmBackend {
3737
bool IsResolved, MCContext &Ctx,
3838
const MCSubtargetInfo *STI) const;
3939

40+
std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
41+
uint64_t &) override;
4042
void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
4143
MutableArrayRef<char> Data, uint64_t Value,
4244
bool IsResolved) override;

llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,9 @@ MCFixupKindInfo CSKYAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
3434
{CSKY::Fixups::fixup_csky_pcrel_imm16_scale2,
3535
{"fixup_csky_pcrel_imm16_scale2", 0, 32, 0}},
3636
{CSKY::Fixups::fixup_csky_pcrel_uimm16_scale4,
37-
{"fixup_csky_pcrel_uimm16_scale4", 0, 32,
38-
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
37+
{"fixup_csky_pcrel_uimm16_scale4", 0, 32, 0}},
3938
{CSKY::Fixups::fixup_csky_pcrel_uimm8_scale4,
40-
{"fixup_csky_pcrel_uimm8_scale4", 0, 32,
41-
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
39+
{"fixup_csky_pcrel_uimm8_scale4", 0, 32, 0}},
4240
{CSKY::Fixups::fixup_csky_pcrel_imm26_scale2,
4341
{"fixup_csky_pcrel_imm26_scale2", 0, 32, 0}},
4442
{CSKY::Fixups::fixup_csky_pcrel_imm18_scale2,
@@ -54,8 +52,7 @@ MCFixupKindInfo CSKYAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
5452
{CSKY::Fixups::fixup_csky_pcrel_imm10_scale2,
5553
{"fixup_csky_pcrel_imm10_scale2", 0, 16, 0}},
5654
{CSKY::Fixups::fixup_csky_pcrel_uimm7_scale4,
57-
{"fixup_csky_pcrel_uimm7_scale4", 0, 16,
58-
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
55+
{"fixup_csky_pcrel_uimm7_scale4", 0, 16, 0}},
5956
{CSKY::Fixups::fixup_csky_doffset_imm18,
6057
{"fixup_csky_doffset_imm18", 0, 18, 0}},
6158
{CSKY::Fixups::fixup_csky_doffset_imm18_scale2,
@@ -184,6 +181,21 @@ bool CSKYAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
184181
}
185182
}
186183

184+
std::optional<bool> CSKYAsmBackend::evaluateFixup(const MCFragment &F,
185+
MCFixup &Fixup, MCValue &,
186+
uint64_t &Value) {
187+
// For a few PC-relative fixups, offsets need to be aligned down. We
188+
// compensate here because the default handler's `Value` decrement doesn't
189+
// account for this alignment.
190+
switch (Fixup.getTargetKind()) {
191+
case CSKY::fixup_csky_pcrel_uimm16_scale4:
192+
case CSKY::fixup_csky_pcrel_uimm8_scale4:
193+
case CSKY::fixup_csky_pcrel_uimm7_scale4:
194+
Value = (Asm->getFragmentOffset(F) + Fixup.getOffset()) % 4;
195+
}
196+
return {};
197+
}
198+
187199
void CSKYAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
188200
const MCValue &Target,
189201
MutableArrayRef<char> Data, uint64_t Value,

llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class CSKYAsmBackend : public MCAsmBackend {
2222
CSKYAsmBackend(const MCSubtargetInfo &STI, const MCTargetOptions &OP)
2323
: MCAsmBackend(llvm::endianness::little) {}
2424

25+
std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
26+
uint64_t &) override;
2527
void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
2628
MutableArrayRef<char> Data, uint64_t Value,
2729
bool IsResolved) override;

llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,8 @@ static const MCFixup *getPCRelHiFixup(const MCSpecifierExpr &Expr,
655655
return nullptr;
656656
}
657657

658-
std::optional<bool> RISCVAsmBackend::evaluateFixup(MCFixup &Fixup,
658+
std::optional<bool> RISCVAsmBackend::evaluateFixup(const MCFragment &,
659+
MCFixup &Fixup,
659660
MCValue &Target,
660661
uint64_t &Value) {
661662
const MCFixup *AUIPCFixup;

llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,8 @@ class RISCVAsmBackend : public MCAsmBackend {
4747
bool shouldInsertFixupForCodeAlign(MCAssembler &Asm,
4848
MCAlignFragment &AF) override;
4949

50-
std::optional<bool> evaluateFixup(MCFixup &Fixup, MCValue &Target,
51-
uint64_t &Value) override;
52-
50+
std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
51+
uint64_t &) override;
5352
bool addReloc(const MCFragment &, const MCFixup &, const MCValue &,
5453
uint64_t &FixedValue, bool IsResolved);
5554

llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "llvm/MC/MCInst.h"
1717
#include "llvm/MC/MCObjectWriter.h"
1818
#include "llvm/MC/MCSubtargetInfo.h"
19+
#include "llvm/MC/MCValue.h"
1920
#include "llvm/Support/raw_ostream.h"
2021

2122
using namespace llvm;
@@ -34,6 +35,8 @@ class XtensaAsmBackend : public MCAsmBackend {
3435
IsLittleEndian(isLE) {}
3536

3637
MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override;
38+
std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
39+
uint64_t &) override;
3740
void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
3841
MutableArrayRef<char> Data, uint64_t Value,
3942
bool IsResolved) override;
@@ -57,10 +60,8 @@ MCFixupKindInfo XtensaAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
5760
{"fixup_xtensa_branch_8", 16, 8, 0},
5861
{"fixup_xtensa_branch_12", 12, 12, 0},
5962
{"fixup_xtensa_jump_18", 6, 18, 0},
60-
{"fixup_xtensa_call_18", 6, 18,
61-
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
62-
{"fixup_xtensa_l32r_16", 8, 16,
63-
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
63+
{"fixup_xtensa_call_18", 6, 18, 0},
64+
{"fixup_xtensa_l32r_16", 8, 16, 0},
6465
{"fixup_xtensa_loop_8", 16, 8, 0},
6566
};
6667

@@ -142,6 +143,20 @@ static unsigned getSize(unsigned Kind) {
142143
}
143144
}
144145

146+
std::optional<bool> XtensaAsmBackend::evaluateFixup(const MCFragment &F,
147+
MCFixup &Fixup, MCValue &,
148+
uint64_t &Value) {
149+
// For a few PC-relative fixups, offsets need to be aligned down. We
150+
// compensate here because the default handler's `Value` decrement doesn't
151+
// account for this alignment.
152+
switch (Fixup.getTargetKind()) {
153+
case Xtensa::fixup_xtensa_call_18:
154+
case Xtensa::fixup_xtensa_l32r_16:
155+
Value = (Asm->getFragmentOffset(F) + Fixup.getOffset()) % 4;
156+
}
157+
return {};
158+
}
159+
145160
void XtensaAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
146161
const MCValue &Target,
147162
MutableArrayRef<char> Data, uint64_t Value,

0 commit comments

Comments
 (0)