-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[LoongArch] Add relax feature and keep relocations #72191
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
Conversation
Add relax feature. To support linker relocation, we should make relocation with a symbol rather than section plus offset, and keep all relocations with non-abs symbol.
@llvm/pr-subscribers-mc Author: Jinyang He (MQ-mengqing) ChangesAdd relax feature. To support linker relocation, we should make relocation with a symbol rather than section plus offset, and keep all relocations with non-abs symbol. Full diff: https://github.com/llvm/llvm-project/pull/72191.diff 6 Files Affected:
diff --git a/llvm/lib/Target/LoongArch/LoongArch.td b/llvm/lib/Target/LoongArch/LoongArch.td
index 0675caa3b60145d..75b65fe69f26291 100644
--- a/llvm/lib/Target/LoongArch/LoongArch.td
+++ b/llvm/lib/Target/LoongArch/LoongArch.td
@@ -102,6 +102,10 @@ def FeatureUAL
: SubtargetFeature<"ual", "HasUAL", "true",
"Allow memory accesses to be unaligned">;
+def FeatureRelax
+ : SubtargetFeature<"relax", "HasLinkerRelax", "true",
+ "Enable Linker relaxation">;
+
//===----------------------------------------------------------------------===//
// Registers, instruction descriptions ...
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/LoongArch/LoongArchSubtarget.h b/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
index 0fbe23f2f62d9d4..5c173675cca4ccb 100644
--- a/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
+++ b/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
@@ -43,6 +43,7 @@ class LoongArchSubtarget : public LoongArchGenSubtargetInfo {
bool HasLaGlobalWithAbs = false;
bool HasLaLocalWithAbs = false;
bool HasUAL = false;
+ bool HasLinkerRelax = false;
unsigned GRLen = 32;
MVT GRLenVT = MVT::i32;
LoongArchABI::ABI TargetABI = LoongArchABI::ABI_Unknown;
@@ -100,6 +101,7 @@ class LoongArchSubtarget : public LoongArchGenSubtargetInfo {
bool hasLaGlobalWithAbs() const { return HasLaGlobalWithAbs; }
bool hasLaLocalWithAbs() const { return HasLaLocalWithAbs; }
bool hasUAL() const { return HasUAL; }
+ bool hasLinkerRelax() const { return HasLinkerRelax; }
MVT getGRLenVT() const { return GRLenVT; }
unsigned getGRLen() const { return GRLen; }
LoongArchABI::ABI getTargetABI() const { return TargetABI; }
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
index 8744bcb45f75f30..a35916d2ad2197d 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
@@ -167,7 +167,7 @@ bool LoongArchAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
return true;
switch (Fixup.getTargetKind()) {
default:
- return false;
+ return STI.hasFeature(LoongArch::FeatureRelax);
case FK_Data_1:
case FK_Data_2:
case FK_Data_4:
@@ -192,7 +192,8 @@ bool LoongArchAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
std::unique_ptr<MCObjectTargetWriter>
LoongArchAsmBackend::createObjectTargetWriter() const {
- return createLoongArchELFObjectWriter(OSABI, Is64Bit);
+ return createLoongArchELFObjectWriter(
+ OSABI, Is64Bit, STI.hasFeature(LoongArch::FeatureRelax));
}
MCAsmBackend *llvm::createLoongArchAsmBackend(const Target &T,
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp
index a6b9c0652639fbc..8a464b894265146 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp
@@ -20,19 +20,27 @@ using namespace llvm;
namespace {
class LoongArchELFObjectWriter : public MCELFObjectTargetWriter {
public:
- LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit);
+ LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool EnableRelax);
~LoongArchELFObjectWriter() override;
+ bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
+ unsigned Type) const override {
+ return EnableRelax;
+ }
+
protected:
unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
const MCFixup &Fixup, bool IsPCRel) const override;
+ bool EnableRelax;
};
} // end namespace
-LoongArchELFObjectWriter::LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit)
+LoongArchELFObjectWriter::LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit,
+ bool EnableRelax)
: MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_LOONGARCH,
- /*HasRelocationAddend*/ true) {}
+ /*HasRelocationAddend*/ true),
+ EnableRelax(EnableRelax) {}
LoongArchELFObjectWriter::~LoongArchELFObjectWriter() {}
@@ -87,6 +95,6 @@ unsigned LoongArchELFObjectWriter::getRelocType(MCContext &Ctx,
}
std::unique_ptr<MCObjectTargetWriter>
-llvm::createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit) {
- return std::make_unique<LoongArchELFObjectWriter>(OSABI, Is64Bit);
+llvm::createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool Relax) {
+ return std::make_unique<LoongArchELFObjectWriter>(OSABI, Is64Bit, Relax);
}
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h
index ab35a0096c8a2a2..bb05baa9b717c2c 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h
@@ -36,7 +36,7 @@ MCAsmBackend *createLoongArchAsmBackend(const Target &T,
const MCTargetOptions &Options);
std::unique_ptr<MCObjectTargetWriter>
-createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit);
+createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool Relax);
} // end namespace llvm
diff --git a/llvm/test/MC/LoongArch/Relocations/relax-attr.s b/llvm/test/MC/LoongArch/Relocations/relax-attr.s
new file mode 100644
index 000000000000000..b1e648d850bb908
--- /dev/null
+++ b/llvm/test/MC/LoongArch/Relocations/relax-attr.s
@@ -0,0 +1,32 @@
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s -o %t
+# RUN: llvm-readobj -r %t | FileCheck %s
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=+relax %s -o %t
+# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=CHECKR
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section ({{.*}}) .rela.data {
+# CHECK-NEXT: 0x0 R_LARCH_64 .text 0x4
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+# CHECKR: Relocations [
+# CHECKR-NEXT: Section ({{.*}}) .rela.text {
+# CHECKR-NEXT: 0x8 R_LARCH_B21 .L1 0x0
+# CHECKR-NEXT: 0xC R_LARCH_B16 .L1 0x0
+# CHECKR-NEXT: 0x10 R_LARCH_B26 .L1 0x0
+# CHECKR-NEXT: }
+# CHECKR-NEXT: Section ({{.*}}) .rela.data {
+# CHECKR-NEXT: 0x0 R_LARCH_64 .L1 0x0
+# CHECKR-NEXT: }
+# CHECKR-NEXT: ]
+
+.text
+ nop
+.L1:
+ nop
+ beqz $a0, .L1
+ blt $a0, $a1, .L1
+ b .L1
+
+.data
+.dword .L1
|
@llvm/pr-subscribers-backend-loongarch Author: Jinyang He (MQ-mengqing) ChangesAdd relax feature. To support linker relocation, we should make relocation with a symbol rather than section plus offset, and keep all relocations with non-abs symbol. Full diff: https://github.com/llvm/llvm-project/pull/72191.diff 6 Files Affected:
diff --git a/llvm/lib/Target/LoongArch/LoongArch.td b/llvm/lib/Target/LoongArch/LoongArch.td
index 0675caa3b60145d..75b65fe69f26291 100644
--- a/llvm/lib/Target/LoongArch/LoongArch.td
+++ b/llvm/lib/Target/LoongArch/LoongArch.td
@@ -102,6 +102,10 @@ def FeatureUAL
: SubtargetFeature<"ual", "HasUAL", "true",
"Allow memory accesses to be unaligned">;
+def FeatureRelax
+ : SubtargetFeature<"relax", "HasLinkerRelax", "true",
+ "Enable Linker relaxation">;
+
//===----------------------------------------------------------------------===//
// Registers, instruction descriptions ...
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/LoongArch/LoongArchSubtarget.h b/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
index 0fbe23f2f62d9d4..5c173675cca4ccb 100644
--- a/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
+++ b/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
@@ -43,6 +43,7 @@ class LoongArchSubtarget : public LoongArchGenSubtargetInfo {
bool HasLaGlobalWithAbs = false;
bool HasLaLocalWithAbs = false;
bool HasUAL = false;
+ bool HasLinkerRelax = false;
unsigned GRLen = 32;
MVT GRLenVT = MVT::i32;
LoongArchABI::ABI TargetABI = LoongArchABI::ABI_Unknown;
@@ -100,6 +101,7 @@ class LoongArchSubtarget : public LoongArchGenSubtargetInfo {
bool hasLaGlobalWithAbs() const { return HasLaGlobalWithAbs; }
bool hasLaLocalWithAbs() const { return HasLaLocalWithAbs; }
bool hasUAL() const { return HasUAL; }
+ bool hasLinkerRelax() const { return HasLinkerRelax; }
MVT getGRLenVT() const { return GRLenVT; }
unsigned getGRLen() const { return GRLen; }
LoongArchABI::ABI getTargetABI() const { return TargetABI; }
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
index 8744bcb45f75f30..a35916d2ad2197d 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
@@ -167,7 +167,7 @@ bool LoongArchAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
return true;
switch (Fixup.getTargetKind()) {
default:
- return false;
+ return STI.hasFeature(LoongArch::FeatureRelax);
case FK_Data_1:
case FK_Data_2:
case FK_Data_4:
@@ -192,7 +192,8 @@ bool LoongArchAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
std::unique_ptr<MCObjectTargetWriter>
LoongArchAsmBackend::createObjectTargetWriter() const {
- return createLoongArchELFObjectWriter(OSABI, Is64Bit);
+ return createLoongArchELFObjectWriter(
+ OSABI, Is64Bit, STI.hasFeature(LoongArch::FeatureRelax));
}
MCAsmBackend *llvm::createLoongArchAsmBackend(const Target &T,
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp
index a6b9c0652639fbc..8a464b894265146 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp
@@ -20,19 +20,27 @@ using namespace llvm;
namespace {
class LoongArchELFObjectWriter : public MCELFObjectTargetWriter {
public:
- LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit);
+ LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool EnableRelax);
~LoongArchELFObjectWriter() override;
+ bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
+ unsigned Type) const override {
+ return EnableRelax;
+ }
+
protected:
unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
const MCFixup &Fixup, bool IsPCRel) const override;
+ bool EnableRelax;
};
} // end namespace
-LoongArchELFObjectWriter::LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit)
+LoongArchELFObjectWriter::LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit,
+ bool EnableRelax)
: MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_LOONGARCH,
- /*HasRelocationAddend*/ true) {}
+ /*HasRelocationAddend*/ true),
+ EnableRelax(EnableRelax) {}
LoongArchELFObjectWriter::~LoongArchELFObjectWriter() {}
@@ -87,6 +95,6 @@ unsigned LoongArchELFObjectWriter::getRelocType(MCContext &Ctx,
}
std::unique_ptr<MCObjectTargetWriter>
-llvm::createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit) {
- return std::make_unique<LoongArchELFObjectWriter>(OSABI, Is64Bit);
+llvm::createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool Relax) {
+ return std::make_unique<LoongArchELFObjectWriter>(OSABI, Is64Bit, Relax);
}
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h
index ab35a0096c8a2a2..bb05baa9b717c2c 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h
@@ -36,7 +36,7 @@ MCAsmBackend *createLoongArchAsmBackend(const Target &T,
const MCTargetOptions &Options);
std::unique_ptr<MCObjectTargetWriter>
-createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit);
+createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool Relax);
} // end namespace llvm
diff --git a/llvm/test/MC/LoongArch/Relocations/relax-attr.s b/llvm/test/MC/LoongArch/Relocations/relax-attr.s
new file mode 100644
index 000000000000000..b1e648d850bb908
--- /dev/null
+++ b/llvm/test/MC/LoongArch/Relocations/relax-attr.s
@@ -0,0 +1,32 @@
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s -o %t
+# RUN: llvm-readobj -r %t | FileCheck %s
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=+relax %s -o %t
+# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=CHECKR
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section ({{.*}}) .rela.data {
+# CHECK-NEXT: 0x0 R_LARCH_64 .text 0x4
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+# CHECKR: Relocations [
+# CHECKR-NEXT: Section ({{.*}}) .rela.text {
+# CHECKR-NEXT: 0x8 R_LARCH_B21 .L1 0x0
+# CHECKR-NEXT: 0xC R_LARCH_B16 .L1 0x0
+# CHECKR-NEXT: 0x10 R_LARCH_B26 .L1 0x0
+# CHECKR-NEXT: }
+# CHECKR-NEXT: Section ({{.*}}) .rela.data {
+# CHECKR-NEXT: 0x0 R_LARCH_64 .L1 0x0
+# CHECKR-NEXT: }
+# CHECKR-NEXT: ]
+
+.text
+ nop
+.L1:
+ nop
+ beqz $a0, .L1
+ blt $a0, $a1, .L1
+ b .L1
+
+.data
+.dword .L1
|
Add: @SixWeining @wangleiat @xen0n @xry111 @MaskRay . |
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.
LGTM. But you can wait for others if you don't mind.
I am expecting to see something more complete. There is no rush in adding linker relaxation support, and if not careful, can end up needing more efforts to clean up. This is what happened to RISC-V's assembler support, and I finally fixed them after https://reviews.llvm.org/D153097 https://reviews.llvm.org/D155357 . At the very least, this patch needs more tests, like the tests I improved when improving the two tests. |
Frankly, I am glad that I managed to fix the RISC-V assembler issues before you folks add the LoongArch side support... Because otherwise some assembler issue would be more difficult to fix once LoongArch builds dependency on the brittle basis... |
Thank you for the linker relaxation works on RISCV. This allows me to have a reference when I port it on LoongArch. I noticed these fixes. I think commit [1] relies on both of them. When I supported DwarfLine and DwarfCFA, I found that DwarfCFA did not generate ADD/SUB relocations. Luckily you fixed it for RISCV before. [1] MQ-mengqing@bdcea9b |
: MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_LOONGARCH, | ||
/*HasRelocationAddend*/ true) {} | ||
/*HasRelocationAddend*/ true), |
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.
The canonical comment style is /*HasRelocationAddend=*/true
Add relax feature. To support linker relocation, we should make relocation with a symbol rather than section plus offset, and keep all relocations with non-abs symbol.
Add relax feature. To support linker relocation, we should make relocation with a symbol rather than section plus offset, and keep all relocations with non-abs symbol. (cherry picked from commit f5bfc83) Change-Id: Ief38b480016175f2cc9939b74a84d9444559ffd6
Add relax feature. To support linker relocation, we should make relocation with a symbol rather than section plus offset, and keep all relocations with non-abs symbol.