-
Notifications
You must be signed in to change notification settings - Fork 13.5k
RISCV,LoongArch: Encode RELAX relocation implicitly #140494
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RISCV,LoongArch: Encode RELAX relocation implicitly #140494
Conversation
Created using spr 1.3.5-bogner
@llvm/pr-subscribers-backend-loongarch @llvm/pr-subscribers-mc Author: Fangrui Song (MaskRay) ChangesWhen linker relaxation is enabled, relaxable relocations are followed by This patch introduces MCFixup::NeedsRelax to encode the RELAX relocation implicitly. Full diff: https://github.com/llvm/llvm-project/pull/140494.diff 8 Files Affected:
diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h
index 105614fb55212..27fdd23c88cf3 100644
--- a/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/llvm/include/llvm/MC/MCAsmBackend.h
@@ -41,7 +41,7 @@ class raw_ostream;
/// Generic interface to target specific assembler backends.
class MCAsmBackend {
protected: // Can only create subclasses.
- MCAsmBackend(llvm::endianness Endian, unsigned RelaxFixupKind = 0);
+ MCAsmBackend(llvm::endianness Endian, bool LinkerRelaxation = false);
public:
MCAsmBackend(const MCAsmBackend &) = delete;
@@ -50,10 +50,9 @@ class MCAsmBackend {
const llvm::endianness Endian;
- /// Fixup kind used for linker relaxation. Currently only used by RISC-V
- /// and LoongArch.
- const unsigned RelaxFixupKind;
- bool allowLinkerRelaxation() const { return RelaxFixupKind != 0; }
+ /// True for RISC-V and LoongArch. Relaxable relocations are marked with a
+ /// RELAX relocation.
+ bool allowLinkerRelaxation() const { return LinkerRelaxation; }
/// Return true if this target might automatically pad instructions and thus
/// need to emit padding enable/disable directives around sensative code.
@@ -217,6 +216,9 @@ class MCAsmBackend {
}
bool isDarwinCanonicalPersonality(const MCSymbol *Sym) const;
+
+private:
+ const bool LinkerRelaxation;
};
} // end namespace llvm
diff --git a/llvm/include/llvm/MC/MCFixup.h b/llvm/include/llvm/MC/MCFixup.h
index f6e4051dbbd22..b52124437ff0d 100644
--- a/llvm/include/llvm/MC/MCFixup.h
+++ b/llvm/include/llvm/MC/MCFixup.h
@@ -73,6 +73,12 @@ class MCFixup {
/// determine how the operand value should be encoded into the instruction.
MCFixupKind Kind = FK_NONE;
+ /// Used by RISC-V style linker relaxation. If the fixup is unresolved,
+ /// whether a RELAX relocation should follow.
+ bool NeedsRelax = false;
+
+ /// Consider bit fields if we need more flags.
+
/// The source location which gave rise to the fixup, if any.
SMLoc Loc;
public:
@@ -99,6 +105,9 @@ class MCFixup {
const MCExpr *getValue() const { return Value; }
+ bool needsRelax() const { return NeedsRelax; }
+ void setNeedsRelax() { NeedsRelax = true; }
+
/// Return the generic fixup kind for a value with the given size. It
/// is an error to pass an unsupported size.
static MCFixupKind getKindForSize(unsigned Size, bool IsPCRel) {
diff --git a/llvm/lib/MC/MCAsmBackend.cpp b/llvm/lib/MC/MCAsmBackend.cpp
index 9bab0d0e7e78c..0c43b2e473559 100644
--- a/llvm/lib/MC/MCAsmBackend.cpp
+++ b/llvm/lib/MC/MCAsmBackend.cpp
@@ -24,8 +24,8 @@
using namespace llvm;
-MCAsmBackend::MCAsmBackend(llvm::endianness Endian, unsigned RelaxFixupKind)
- : Endian(Endian), RelaxFixupKind(RelaxFixupKind) {}
+MCAsmBackend::MCAsmBackend(llvm::endianness Endian, bool LinkerRelaxation)
+ : Endian(Endian), LinkerRelaxation(LinkerRelaxation) {}
MCAsmBackend::~MCAsmBackend() = default;
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 7006ac9dda7c2..9adb1a83fa257 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -35,6 +35,7 @@
#include "llvm/Support/LEB128.h"
#include <cassert>
#include <cstdint>
+#include <type_traits>
using namespace llvm;
@@ -448,13 +449,13 @@ void MCELFStreamer::emitInstToData(const MCInst &Inst,
DF->getFixups(), STI);
auto Fixups = MutableArrayRef(DF->getFixups()).slice(FixupStartIndex);
- for (auto &Fixup : Fixups)
+ for (auto &Fixup : Fixups) {
Fixup.setOffset(Fixup.getOffset() + CodeOffset);
+ if (Fixup.needsRelax())
+ DF->setLinkerRelaxable();
+ }
DF->setHasInstructions(STI);
- if (!Fixups.empty() && Fixups.back().getTargetKind() ==
- getAssembler().getBackend().RelaxFixupKind)
- DF->setLinkerRelaxable();
}
void MCELFStreamer::emitBundleAlignMode(Align Alignment) {
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
index 7c95cf78215e0..91c40a63a4e50 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
@@ -31,8 +31,8 @@ using namespace llvm;
LoongArchAsmBackend::LoongArchAsmBackend(const MCSubtargetInfo &STI,
uint8_t OSABI, bool Is64Bit,
const MCTargetOptions &Options)
- : MCAsmBackend(llvm::endianness::little, ELF::R_LARCH_RELAX), STI(STI),
- OSABI(OSABI), Is64Bit(Is64Bit), TargetOptions(Options) {}
+ : MCAsmBackend(llvm::endianness::little, /*LinkerRelaxation=*/true),
+ STI(STI), OSABI(OSABI), Is64Bit(Is64Bit), TargetOptions(Options) {}
std::optional<MCFixupKind>
LoongArchAsmBackend::getFixupKind(StringRef Name) const {
@@ -444,60 +444,72 @@ bool LoongArchAsmBackend::addReloc(MCAssembler &Asm, const MCFragment &F,
return MCAsmBackend::addReloc(Asm, F, Fixup, Target, FixedValue, IsResolved,
CurSTI);
};
- if (!Target.getSubSym())
- return Fallback();
- assert(Target.getSpecifier() == 0 &&
- "relocatable SymA-SymB cannot have relocation specifier");
- std::pair<MCFixupKind, MCFixupKind> FK;
uint64_t FixedValueA, FixedValueB;
- const MCSymbol &SA = *Target.getAddSym();
- const MCSymbol &SB = *Target.getSubSym();
-
- bool force = !SA.isInSection() || !SB.isInSection();
- if (!force) {
- const MCSection &SecA = SA.getSection();
- const MCSection &SecB = SB.getSection();
-
- // We need record relocation if SecA != SecB. Usually SecB is same as the
- // section of Fixup, which will be record the relocation as PCRel. If SecB
- // is not same as the section of Fixup, it will report error. Just return
- // false and then this work can be finished by handleFixup.
- if (&SecA != &SecB)
- return Fallback();
-
- // In SecA == SecB case. If the linker relaxation is enabled, we need record
- // the ADD, SUB relocations. Otherwise the FixedValue has already been calc-
- // ulated out in evaluateFixup, return true and avoid record relocations.
- if (!STI.hasFeature(LoongArch::FeatureRelax))
- return true;
+ if (Target.getSubSym()) {
+ assert(Target.getSpecifier() == 0 &&
+ "relocatable SymA-SymB cannot have relocation specifier");
+ std::pair<MCFixupKind, MCFixupKind> FK;
+ const MCSymbol &SA = *Target.getAddSym();
+ const MCSymbol &SB = *Target.getSubSym();
+
+ bool force = !SA.isInSection() || !SB.isInSection();
+ if (!force) {
+ const MCSection &SecA = SA.getSection();
+ const MCSection &SecB = SB.getSection();
+
+ // We need record relocation if SecA != SecB. Usually SecB is same as the
+ // section of Fixup, which will be record the relocation as PCRel. If SecB
+ // is not same as the section of Fixup, it will report error. Just return
+ // false and then this work can be finished by handleFixup.
+ if (&SecA != &SecB)
+ return Fallback();
+
+ // In SecA == SecB case. If the linker relaxation is enabled, we need
+ // record the ADD, SUB relocations. Otherwise the FixedValue has already
+ // been calc- ulated out in evaluateFixup, return true and avoid record
+ // relocations.
+ if (!STI.hasFeature(LoongArch::FeatureRelax))
+ return true;
+ }
+
+ switch (Fixup.getKind()) {
+ case llvm::FK_Data_1:
+ FK = getRelocPairForSize(8);
+ break;
+ case llvm::FK_Data_2:
+ FK = getRelocPairForSize(16);
+ break;
+ case llvm::FK_Data_4:
+ FK = getRelocPairForSize(32);
+ break;
+ case llvm::FK_Data_8:
+ FK = getRelocPairForSize(64);
+ break;
+ case llvm::FK_Data_leb128:
+ FK = getRelocPairForSize(128);
+ break;
+ default:
+ llvm_unreachable("unsupported fixup size");
+ }
+ MCValue A = MCValue::get(Target.getAddSym(), nullptr, Target.getConstant());
+ MCValue B = MCValue::get(Target.getSubSym());
+ auto FA = MCFixup::create(Fixup.getOffset(), nullptr, std::get<0>(FK));
+ auto FB = MCFixup::create(Fixup.getOffset(), nullptr, std::get<1>(FK));
+ Asm.getWriter().recordRelocation(Asm, &F, FA, A, FixedValueA);
+ Asm.getWriter().recordRelocation(Asm, &F, FB, B, FixedValueB);
+ FixedValue = FixedValueA - FixedValueB;
+ return false;
}
- switch (Fixup.getKind()) {
- case llvm::FK_Data_1:
- FK = getRelocPairForSize(8);
- break;
- case llvm::FK_Data_2:
- FK = getRelocPairForSize(16);
- break;
- case llvm::FK_Data_4:
- FK = getRelocPairForSize(32);
- break;
- case llvm::FK_Data_8:
- FK = getRelocPairForSize(64);
- break;
- case llvm::FK_Data_leb128:
- FK = getRelocPairForSize(128);
- break;
- default:
- llvm_unreachable("unsupported fixup size");
+ IsResolved = Fallback();
+ // If linker relaxation is enabled and supported by the current relocation,
+ // append a RELAX relocation.
+ if (Fixup.needsRelax()) {
+ auto FA = MCFixup::create(Fixup.getOffset(), nullptr, ELF::R_LARCH_RELAX);
+ Asm.getWriter().recordRelocation(Asm, &F, FA, MCValue::get(nullptr),
+ FixedValueA);
}
- MCValue A = MCValue::get(Target.getAddSym(), nullptr, Target.getConstant());
- MCValue B = MCValue::get(Target.getSubSym());
- auto FA = MCFixup::create(Fixup.getOffset(), nullptr, std::get<0>(FK));
- auto FB = MCFixup::create(Fixup.getOffset(), nullptr, std::get<1>(FK));
- Asm.getWriter().recordRelocation(Asm, &F, FA, A, FixedValueA);
- Asm.getWriter().recordRelocation(Asm, &F, FB, B, FixedValueB);
- FixedValue = FixedValueA - FixedValueB;
+
return true;
}
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
index 5770a76b9f214..1fb6b9b0e319d 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
@@ -199,14 +199,11 @@ LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
Fixups.push_back(
MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc()));
-
- // Emit an R_LARCH_RELAX if linker relaxation is enabled and LAExpr has relax
- // hint.
- if (EnableRelax && RelaxCandidate) {
- const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx);
- Fixups.push_back(
- MCFixup::create(0, Dummy, ELF::R_LARCH_RELAX, MI.getLoc()));
- }
+ // If linker relaxation is enabled and supported by this relocation, set
+ // a bit so that if fixup is unresolved, a R_LARCH_RELAX relocation will be
+ // appended.
+ if (EnableRelax && RelaxCandidate)
+ Fixups.back().setNeedsRelax();
return 0;
}
@@ -256,13 +253,8 @@ void LoongArchMCCodeEmitter::expandAddTPRel(const MCInst &MI,
// Emit the correct %le_add_r relocation for the symbol.
Fixups.push_back(
MCFixup::create(0, Expr, ELF::R_LARCH_TLS_LE_ADD_R, MI.getLoc()));
-
- // Emit R_LARCH_RELAX for %le_add_r when the relax feature is enabled.
- if (STI.hasFeature(LoongArch::FeatureRelax)) {
- const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx);
- Fixups.push_back(
- MCFixup::create(0, Dummy, ELF::R_LARCH_RELAX, MI.getLoc()));
- }
+ if (STI.hasFeature(LoongArch::FeatureRelax))
+ Fixups.back().setNeedsRelax();
// Emit a normal ADD instruction with the given operands.
unsigned ADD = MI.getOpcode() == LoongArch::PseudoAddTPRel_D
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 368a4fe4864f9..bcab114c0ecf0 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -36,8 +36,8 @@ static cl::opt<bool> ULEB128Reloc(
RISCVAsmBackend::RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI,
bool Is64Bit, const MCTargetOptions &Options)
- : MCAsmBackend(llvm::endianness::little, ELF::R_RISCV_RELAX), STI(STI),
- OSABI(OSABI), Is64Bit(Is64Bit), TargetOptions(Options) {
+ : MCAsmBackend(llvm::endianness::little, /*LinkerRelaxation=*/true),
+ STI(STI), OSABI(OSABI), Is64Bit(Is64Bit), TargetOptions(Options) {
RISCVFeatures::validate(STI.getTargetTriple(), STI.getFeatureBits());
}
@@ -620,45 +620,56 @@ bool RISCVAsmBackend::addReloc(MCAssembler &Asm, const MCFragment &F,
const MCFixup &Fixup, const MCValue &Target,
uint64_t &FixedValue, bool IsResolved,
const MCSubtargetInfo *STI) {
- if (!Target.getSubSym())
- return MCAsmBackend::addReloc(Asm, F, Fixup, Target, FixedValue, IsResolved,
- STI);
- assert(Target.getSpecifier() == 0 &&
- "relocatable SymA-SymB cannot have relocation specifier");
uint64_t FixedValueA, FixedValueB;
- unsigned TA = 0, TB = 0;
- switch (Fixup.getKind()) {
- case llvm::FK_Data_1:
- TA = ELF::R_RISCV_ADD8;
- TB = ELF::R_RISCV_SUB8;
- break;
- case llvm::FK_Data_2:
- TA = ELF::R_RISCV_ADD16;
- TB = ELF::R_RISCV_SUB16;
- break;
- case llvm::FK_Data_4:
- TA = ELF::R_RISCV_ADD32;
- TB = ELF::R_RISCV_SUB32;
- break;
- case llvm::FK_Data_8:
- TA = ELF::R_RISCV_ADD64;
- TB = ELF::R_RISCV_SUB64;
- break;
- case llvm::FK_Data_leb128:
- TA = ELF::R_RISCV_SET_ULEB128;
- TB = ELF::R_RISCV_SUB_ULEB128;
- break;
- default:
- llvm_unreachable("unsupported fixup size");
+ if (Target.getSubSym()) {
+ assert(Target.getSpecifier() == 0 &&
+ "relocatable SymA-SymB cannot have relocation specifier");
+ unsigned TA = 0, TB = 0;
+ switch (Fixup.getKind()) {
+ case llvm::FK_Data_1:
+ TA = ELF::R_RISCV_ADD8;
+ TB = ELF::R_RISCV_SUB8;
+ break;
+ case llvm::FK_Data_2:
+ TA = ELF::R_RISCV_ADD16;
+ TB = ELF::R_RISCV_SUB16;
+ break;
+ case llvm::FK_Data_4:
+ TA = ELF::R_RISCV_ADD32;
+ TB = ELF::R_RISCV_SUB32;
+ break;
+ case llvm::FK_Data_8:
+ TA = ELF::R_RISCV_ADD64;
+ TB = ELF::R_RISCV_SUB64;
+ break;
+ case llvm::FK_Data_leb128:
+ TA = ELF::R_RISCV_SET_ULEB128;
+ TB = ELF::R_RISCV_SUB_ULEB128;
+ break;
+ default:
+ llvm_unreachable("unsupported fixup size");
+ }
+ MCValue A = MCValue::get(Target.getAddSym(), nullptr, Target.getConstant());
+ MCValue B = MCValue::get(Target.getSubSym());
+ auto FA = MCFixup::create(Fixup.getOffset(), nullptr, TA);
+ auto FB = MCFixup::create(Fixup.getOffset(), nullptr, TB);
+ Asm.getWriter().recordRelocation(Asm, &F, FA, A, FixedValueA);
+ Asm.getWriter().recordRelocation(Asm, &F, FB, B, FixedValueB);
+ FixedValue = FixedValueA - FixedValueB;
+ return false;
}
- MCValue A = MCValue::get(Target.getAddSym(), nullptr, Target.getConstant());
- MCValue B = MCValue::get(Target.getSubSym());
- auto FA = MCFixup::create(Fixup.getOffset(), nullptr, TA);
- auto FB = MCFixup::create(Fixup.getOffset(), nullptr, TB);
- Asm.getWriter().recordRelocation(Asm, &F, FA, A, FixedValueA);
- Asm.getWriter().recordRelocation(Asm, &F, FB, B, FixedValueB);
- FixedValue = FixedValueA - FixedValueB;
- return true;
+
+ IsResolved = MCAsmBackend::addReloc(Asm, F, Fixup, Target, FixedValue,
+ IsResolved, STI);
+ // If linker relaxation is enabled and supported by the current relocation,
+ // append a RELAX relocation.
+ if (Fixup.needsRelax()) {
+ auto FA = MCFixup::create(Fixup.getOffset(), nullptr, ELF::R_RISCV_RELAX);
+ Asm.getWriter().recordRelocation(Asm, &F, FA, MCValue::get(nullptr),
+ FixedValueA);
+ }
+
+ return false;
}
void RISCVAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index 23f7a6025daf1..5c29e1a55f986 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -209,16 +209,10 @@ void RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI,
assert(Expr && Expr->getSpecifier() == ELF::R_RISCV_TPREL_ADD &&
"Expected tprel_add relocation on TP-relative symbol");
- // Emit the correct tprel_add relocation for the symbol.
Fixups.push_back(
MCFixup::create(0, Expr, ELF::R_RISCV_TPREL_ADD, MI.getLoc()));
-
- // Emit R_RISCV_RELAX for tprel_add where the relax feature is enabled.
- if (STI.hasFeature(RISCV::FeatureRelax)) {
- const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx);
- Fixups.push_back(
- MCFixup::create(0, Dummy, ELF::R_RISCV_RELAX, MI.getLoc()));
- }
+ if (STI.hasFeature(RISCV::FeatureRelax))
+ Fixups.back().setNeedsRelax();
// Emit a normal ADD instruction with the given operands.
MCInst TmpInst = MCInstBuilder(RISCV::ADD)
@@ -655,20 +649,14 @@ uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
assert(FixupKind != RISCV::fixup_riscv_invalid && "Unhandled expression!");
- Fixups.push_back(
- MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc()));
+ Fixups.push_back(MCFixup::create(0, Expr, FixupKind, MI.getLoc()));
+ // If linker relaxation is enabled and supported by this relocation, set
+ // a bit so that if fixup is unresolved, a R_RISCV_RELAX relocation will be
+ // appended.
+ if (EnableRelax && RelaxCandidate)
+ Fixups.back().setNeedsRelax();
++MCNumFixups;
- // Ensure an R_RISCV_RELAX relocation will be emitted if linker relaxation is
- // enabled and the current fixup will result in a relocation that may be
- // relaxed.
- if (EnableRelax && RelaxCandidate) {
- const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx);
- Fixups.push_back(
- MCFixup::create(0, Dummy, ELF::R_RISCV_RELAX, MI.getLoc()));
- ++MCNumFixups;
- }
-
return 0;
}
|
break; | ||
default: | ||
llvm_unreachable("unsupported fixup size"); | ||
if (Target.getSubSym()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indenting this code block is intentional. The next code paths will become complex when we support VENDOR for #135400
// record the ADD, SUB relocations. Otherwise the FixedValue has already | ||
// been calc- ulated out in evaluateFixup, return true and avoid record | ||
// relocations. | ||
if (!STI.hasFeature(LoongArch::FeatureRelax)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LoongArch-specific: We should use the argument STI instead of the member variable STI. But I do not intend to fix this in this PR. It's unclear why this code block is more complex than the RISCV counterpart.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking much better, and easier to extend than the previous structure, thanks.
I think there's still a bunch of complexity around forcing relocations in relax mode, for instance in the top of RISCVAsmParser::parseInstruction
and equivalently in RISCVTargetELFStreamer::RISCVTargetELFStreamer
, but maybe the work to mark a specific fragment needing relaxation can help simplify this.
When linker relaxation is enabled, relaxable relocations are followed by a R_RISCV_RELAX/R_LARCH_RELAX relocation. They are encoded as two fixups by CodeEmitter and expected to have the same `IsResolved` value within MCAssembler::evaluateFixup (they must lead to either 0 or 2 relocations). This scheme wasite space and requires RISCVAsmBackend::shouldForceRelocation to be conservative. This patch introduces MCFixup::NeedsRelax to encode the RELAX relocation implicitly. The fixup will lead to either 0 or 2 relocations. Pull Request: llvm/llvm-project#140494
I have just tested that the code in In MCAssembler.cpp, |
RISCVAsmBackend::ForceRelocs is a workaround shouldForceRelocation Follow-up to llvm#140494
RISCVAsmBackend::ForceRelocs is introduced to create required relocations in mixed relax/norelax code. However, it also leads to redundant relocations. Consider the example adapted from llvm#77436 ``` .option norelax j label // For assembly input, RISCVAsmParser::ParseInstruction sets ForceRelocs (https://reviews.llvm.org/D46423). // For direct object emission, RISCVELFStreamer sets ForceRelocs (llvm#77436) .option relax call foo // linker-relaxable .option norelax j label // redundant relocation due to ForceRelocs .option relax label: ``` Follow-up to llvm#140494
When linker relaxation is enabled, relaxable relocations are followed by
a R_RISCV_RELAX/R_LARCH_RELAX relocation. They are encoded as two fixups by
CodeEmitter and expected to have the same
IsResolved
value withinMCAssembler::evaluateFixup (they must lead to either 0 or 2
relocations). This scheme wasite space and requires RISCVAsmBackend::shouldForceRelocation
to be conservative.
This patch introduces MCFixup::NeedsRelax to encode the RELAX relocation implicitly.
The fixup will lead to either 0 or 2 relocations.