summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKoakuma <koachan@protonmail.com>2024-01-10 21:40:12 +0700
committerKoakuma <koachan@protonmail.com>2024-01-10 21:40:12 +0700
commit0c8531249989651c5274149e437184a3362d7677 (patch)
tree4b1ebdaebc332ccf2b3e1a866fbdd1d03df02bed
parentfe29e4f003c69409f9bc4c39bbabbcf721448316 (diff)
parent72990df072a56996612169f07c5752a6924288bb (diff)
Implement suggestions & clarify comment on RDPC emission
Created using spr 1.3.4
-rw-r--r--llvm/lib/Target/Sparc/SparcAsmPrinter.cpp8
-rw-r--r--llvm/lib/Target/Sparc/SparcSubtarget.cpp10
-rw-r--r--llvm/lib/Target/Sparc/SparcSubtarget.h5
-rw-r--r--llvm/lib/Target/Sparc/SparcTargetMachine.cpp2
-rw-r--r--llvm/test/CodeGen/SPARC/getpcx-call.ll59
-rw-r--r--llvm/test/CodeGen/SPARC/getpcx-rdpc.ll59
-rw-r--r--llvm/test/CodeGen/SPARC/tune-getpcx.ll18
7 files changed, 131 insertions, 30 deletions
diff --git a/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp b/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp
index 97abf10b1854..215a8ea83190 100644
--- a/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp
+++ b/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp
@@ -236,7 +236,7 @@ void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
MCOperand RegO7 = MCOperand::createReg(SP::O7);
// <StartLabel>:
- // call <EndLabel>
+ // <GET-PC> // This will be either `call <EndLabel>` or `rd %pc, %o7`.
// <SethiLabel>:
// sethi %hi(_GLOBAL_OFFSET_TABLE_+(<SethiLabel>-<StartLabel>)), <MO>
// <EndLabel>:
@@ -249,8 +249,10 @@ void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
MCOperand Callee = createPCXCallOP(EndLabel, OutContext);
EmitCall(*OutStreamer, Callee, STI);
} else {
- // TODO make it possible to store PC in other registers
- // so that leaf function optimization becomes possible.
+ // TODO find out whether it is possible to store PC
+ // in other registers, to enable leaf function optimization.
+ // (On the other hand, approx. over 97.8% of GETPCXes happen
+ // in non-leaf functions, so would this be worth the effort?)
EmitRDPC(*OutStreamer, RegO7, STI);
}
OutStreamer->emitLabel(SethiLabel);
diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.cpp b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
index a5d196c502cd..6b09904ca5e8 100644
--- a/llvm/lib/Target/Sparc/SparcSubtarget.cpp
+++ b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
@@ -12,6 +12,7 @@
#include "SparcSubtarget.h"
#include "Sparc.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/MathExtras.h"
@@ -45,12 +46,11 @@ SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(
return *this;
}
-SparcSubtarget::SparcSubtarget(const Triple &TT, const std::string &CPU,
- const std::string &TuneCPU,
- const std::string &FS, const TargetMachine &TM,
+SparcSubtarget::SparcSubtarget(const StringRef &CPU, const StringRef &TuneCPU,
+ const StringRef &FS, const TargetMachine &TM,
bool is64Bit)
- : SparcGenSubtargetInfo(TT, CPU, TuneCPU, FS), TargetTriple(TT),
- Is64Bit(is64Bit),
+ : SparcGenSubtargetInfo(TM.getTargetTriple(), CPU, TuneCPU, FS),
+ TargetTriple(TM.getTargetTriple()), Is64Bit(is64Bit),
InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)),
TLInfo(TM, *this), FrameLowering(*this) {}
diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.h b/llvm/lib/Target/Sparc/SparcSubtarget.h
index 4363942c0d62..cdb210f67482 100644
--- a/llvm/lib/Target/Sparc/SparcSubtarget.h
+++ b/llvm/lib/Target/Sparc/SparcSubtarget.h
@@ -44,9 +44,8 @@ class SparcSubtarget : public SparcGenSubtargetInfo {
SparcFrameLowering FrameLowering;
public:
- SparcSubtarget(const Triple &TT, const std::string &CPU,
- const std::string &TuneCPU, const std::string &FS,
- const TargetMachine &TM, bool is64bit);
+ SparcSubtarget(const StringRef &CPU, const StringRef &TuneCPU,
+ const StringRef &FS, const TargetMachine &TM, bool is64bit);
const SparcInstrInfo *getInstrInfo() const override { return &InstrInfo; }
const TargetFrameLowering *getFrameLowering() const override {
diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
index ae7bbcecc6c7..b408af2ea594 100644
--- a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
+++ b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
@@ -140,7 +140,7 @@ SparcTargetMachine::getSubtargetImpl(const Function &F) const {
// creation will depend on the TM and the code generation flags on the
// function that reside in TargetOptions.
resetTargetOptions(F);
- I = std::make_unique<SparcSubtarget>(TargetTriple, CPU, TuneCPU, FS, *this,
+ I = std::make_unique<SparcSubtarget>(CPU, TuneCPU, FS, *this,
this->is64Bit);
}
return I.get();
diff --git a/llvm/test/CodeGen/SPARC/getpcx-call.ll b/llvm/test/CodeGen/SPARC/getpcx-call.ll
new file mode 100644
index 000000000000..63d6649f89c4
--- /dev/null
+++ b/llvm/test/CodeGen/SPARC/getpcx-call.ll
@@ -0,0 +1,59 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -relocation-model=pic -mtriple=sparc | FileCheck --check-prefix=SPARC %s
+; RUN: llc < %s -relocation-model=pic -mtriple=sparcv9 | FileCheck --check-prefix=SPARC64 %s
+
+;; SPARC32 and SPARC64 for classic UltraSPARCs implement GETPCX
+;; with a fake `call`.
+;; All other SPARC64 targets implement it with `rd %pc, %o7`.
+;; Need to do the tests in separate files because apparently `tune-cpu`
+;; attribute applies to the entire file at once.
+
+@value = external global i32
+
+define i32 @testCall() #0 {
+; SPARC-LABEL: testCall:
+; SPARC: .cfi_startproc
+; SPARC-NEXT: ! %bb.0:
+; SPARC-NEXT: save %sp, -96, %sp
+; SPARC-NEXT: .cfi_def_cfa_register %fp
+; SPARC-NEXT: .cfi_window_save
+; SPARC-NEXT: .cfi_register %o7, %i7
+; SPARC-NEXT: .Ltmp0:
+; SPARC-NEXT: call .Ltmp1
+; SPARC-NEXT: .Ltmp2:
+; SPARC-NEXT: sethi %hi(_GLOBAL_OFFSET_TABLE_+(.Ltmp2-.Ltmp0)), %i0
+; SPARC-NEXT: .Ltmp1:
+; SPARC-NEXT: or %i0, %lo(_GLOBAL_OFFSET_TABLE_+(.Ltmp1-.Ltmp0)), %i0
+; SPARC-NEXT: add %i0, %o7, %i0
+; SPARC-NEXT: sethi %hi(value), %i1
+; SPARC-NEXT: add %i1, %lo(value), %i1
+; SPARC-NEXT: ld [%i0+%i1], %i0
+; SPARC-NEXT: ld [%i0], %i0
+; SPARC-NEXT: ret
+; SPARC-NEXT: restore
+;
+; SPARC64-LABEL: testCall:
+; SPARC64: .cfi_startproc
+; SPARC64-NEXT: ! %bb.0:
+; SPARC64-NEXT: save %sp, -128, %sp
+; SPARC64-NEXT: .cfi_def_cfa_register %fp
+; SPARC64-NEXT: .cfi_window_save
+; SPARC64-NEXT: .cfi_register %o7, %i7
+; SPARC64-NEXT: .Ltmp0:
+; SPARC64-NEXT: call .Ltmp1
+; SPARC64-NEXT: .Ltmp2:
+; SPARC64-NEXT: sethi %hi(_GLOBAL_OFFSET_TABLE_+(.Ltmp2-.Ltmp0)), %i0
+; SPARC64-NEXT: .Ltmp1:
+; SPARC64-NEXT: or %i0, %lo(_GLOBAL_OFFSET_TABLE_+(.Ltmp1-.Ltmp0)), %i0
+; SPARC64-NEXT: add %i0, %o7, %i0
+; SPARC64-NEXT: sethi %hi(value), %i1
+; SPARC64-NEXT: add %i1, %lo(value), %i1
+; SPARC64-NEXT: ldx [%i0+%i1], %i0
+; SPARC64-NEXT: ld [%i0], %i0
+; SPARC64-NEXT: ret
+; SPARC64-NEXT: restore
+ %1 = load i32, i32* @value
+ ret i32 %1
+}
+
+attributes #0 = { "tune-cpu"="ultrasparc" }
diff --git a/llvm/test/CodeGen/SPARC/getpcx-rdpc.ll b/llvm/test/CodeGen/SPARC/getpcx-rdpc.ll
new file mode 100644
index 000000000000..4596d8d68241
--- /dev/null
+++ b/llvm/test/CodeGen/SPARC/getpcx-rdpc.ll
@@ -0,0 +1,59 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -relocation-model=pic -mtriple=sparc | FileCheck --check-prefix=SPARC %s
+; RUN: llc < %s -relocation-model=pic -mtriple=sparcv9 | FileCheck --check-prefix=SPARC64 %s
+
+;; SPARC32 and SPARC64 for classic UltraSPARCs implement GETPCX
+;; with a fake `call`.
+;; All other SPARC64 targets implement it with `rd %pc, %o7`.
+;; Need to do the tests in separate files because apparently `tune-cpu`
+;; attribute applies to the entire file at once.
+
+@value = external global i32
+
+define i32 @testRdpc() #0 {
+; SPARC-LABEL: testRdpc:
+; SPARC: .cfi_startproc
+; SPARC-NEXT: ! %bb.0:
+; SPARC-NEXT: save %sp, -96, %sp
+; SPARC-NEXT: .cfi_def_cfa_register %fp
+; SPARC-NEXT: .cfi_window_save
+; SPARC-NEXT: .cfi_register %o7, %i7
+; SPARC-NEXT: .Ltmp0:
+; SPARC-NEXT: call .Ltmp1
+; SPARC-NEXT: .Ltmp2:
+; SPARC-NEXT: sethi %hi(_GLOBAL_OFFSET_TABLE_+(.Ltmp2-.Ltmp0)), %i0
+; SPARC-NEXT: .Ltmp1:
+; SPARC-NEXT: or %i0, %lo(_GLOBAL_OFFSET_TABLE_+(.Ltmp1-.Ltmp0)), %i0
+; SPARC-NEXT: add %i0, %o7, %i0
+; SPARC-NEXT: sethi %hi(value), %i1
+; SPARC-NEXT: add %i1, %lo(value), %i1
+; SPARC-NEXT: ld [%i0+%i1], %i0
+; SPARC-NEXT: ld [%i0], %i0
+; SPARC-NEXT: ret
+; SPARC-NEXT: restore
+;
+; SPARC64-LABEL: testRdpc:
+; SPARC64: .cfi_startproc
+; SPARC64-NEXT: ! %bb.0:
+; SPARC64-NEXT: save %sp, -128, %sp
+; SPARC64-NEXT: .cfi_def_cfa_register %fp
+; SPARC64-NEXT: .cfi_window_save
+; SPARC64-NEXT: .cfi_register %o7, %i7
+; SPARC64-NEXT: .Ltmp0:
+; SPARC64-NEXT: rd %pc, %o7
+; SPARC64-NEXT: .Ltmp2:
+; SPARC64-NEXT: sethi %hi(_GLOBAL_OFFSET_TABLE_+(.Ltmp2-.Ltmp0)), %i0
+; SPARC64-NEXT: .Ltmp1:
+; SPARC64-NEXT: or %i0, %lo(_GLOBAL_OFFSET_TABLE_+(.Ltmp1-.Ltmp0)), %i0
+; SPARC64-NEXT: add %i0, %o7, %i0
+; SPARC64-NEXT: sethi %hi(value), %i1
+; SPARC64-NEXT: add %i1, %lo(value), %i1
+; SPARC64-NEXT: ldx [%i0+%i1], %i0
+; SPARC64-NEXT: ld [%i0], %i0
+; SPARC64-NEXT: ret
+; SPARC64-NEXT: restore
+ %1 = load i32, i32* @value
+ ret i32 %1
+}
+
+attributes #0 = { "tune-cpu"="niagara" }
diff --git a/llvm/test/CodeGen/SPARC/tune-getpcx.ll b/llvm/test/CodeGen/SPARC/tune-getpcx.ll
deleted file mode 100644
index 7454fea0e38d..000000000000
--- a/llvm/test/CodeGen/SPARC/tune-getpcx.ll
+++ /dev/null
@@ -1,18 +0,0 @@
-; RUN: llc < %s -relocation-model=pic -mtriple=sparc | FileCheck --check-prefix=CALL %s
-; RUN: llc < %s -relocation-model=pic -mtriple=sparcv9 -mcpu=ultrasparc | FileCheck --check-prefix=CALL %s
-; RUN: llc < %s -relocation-model=pic -mtriple=sparcv9 | FileCheck --check-prefix=RDPC %s
-
-;; SPARC32 and SPARC64 for classic UltraSPARCs implement GETPCX
-;; with a fake `call`.
-;; All other SPARC64 targets implement it with `rd %pc, %o7`.
-
-@value = external global i32
-
-; CALL: call
-; CALL-NOT: rd %pc
-; RDPC: rd %pc
-; RDPC-not: call
-define i32 @test() {
- %1 = load i32, i32* @value
- ret i32 %1
-}