diff options
author | Koakuma <koachan@protonmail.com> | 2024-01-10 21:40:12 +0700 |
---|---|---|
committer | Koakuma <koachan@protonmail.com> | 2024-01-10 21:40:12 +0700 |
commit | 0c8531249989651c5274149e437184a3362d7677 (patch) | |
tree | 4b1ebdaebc332ccf2b3e1a866fbdd1d03df02bed | |
parent | fe29e4f003c69409f9bc4c39bbabbcf721448316 (diff) | |
parent | 72990df072a56996612169f07c5752a6924288bb (diff) |
Implement suggestions & clarify comment on RDPC emission
Created using spr 1.3.4
-rw-r--r-- | llvm/lib/Target/Sparc/SparcAsmPrinter.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Target/Sparc/SparcSubtarget.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/Target/Sparc/SparcSubtarget.h | 5 | ||||
-rw-r--r-- | llvm/lib/Target/Sparc/SparcTargetMachine.cpp | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/SPARC/getpcx-call.ll | 59 | ||||
-rw-r--r-- | llvm/test/CodeGen/SPARC/getpcx-rdpc.ll | 59 | ||||
-rw-r--r-- | llvm/test/CodeGen/SPARC/tune-getpcx.ll | 18 |
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 -} |