llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-sparc Author: Koakuma (koachan) <details> <summary>Changes</summary> On 64-bit target, prefer usng RDPC over CALL to get the value of %pc. This is faster on modern processors (Niagara T1 and newer) and avoids polluting the processor's predictor state. The old behavior of using a fake CALL is still done when tuning for classic UltraSPARC processors, since RDPC is much slower there. A quick pgbench test on a SPARC T4 shows about 2% speedup on SELECT loads, and about 7% speedup on INSERT/UPDATE loads. --- Full diff: https://github.com/llvm/llvm-project/pull/77196.diff 3 Files Affected: - (modified) llvm/lib/Target/Sparc/Sparc.td (+14-4) - (modified) llvm/lib/Target/Sparc/SparcAsmPrinter.cpp (+19-2) - (added) llvm/test/CodeGen/SPARC/tune-getpcx.ll (+18) ``````````diff diff --git a/llvm/lib/Target/Sparc/Sparc.td b/llvm/lib/Target/Sparc/Sparc.td index 1a71cfed3128f0..7b103395652433 100644 --- a/llvm/lib/Target/Sparc/Sparc.td +++ b/llvm/lib/Target/Sparc/Sparc.td @@ -62,6 +62,13 @@ def UsePopc : SubtargetFeature<"popc", "UsePopc", "true", def FeatureSoftFloat : SubtargetFeature<"soft-float", "UseSoftFloat", "true", "Use software emulation for floating point">; +//===----------------------------------------------------------------------===// +// SPARC Subtarget tuning features. +// + +def TuneSlowRDPC : SubtargetFeature<"slow-rdpc", "HasSlowRDPC", "true", + "rd %pc, %XX is slow", [FeatureV9]>; + //==== Features added predmoninantly for LEON subtarget support include "LeonFeatures.td" @@ -89,8 +96,9 @@ def SparcAsmParserVariant : AsmParserVariant { // SPARC processors supported. //===----------------------------------------------------------------------===// -class Proc<string Name, list<SubtargetFeature> Features> - : Processor<Name, NoItineraries, Features>; +class Proc<string Name, list<SubtargetFeature> Features, + list<SubtargetFeature> TuneFeatures = []> + : Processor<Name, NoItineraries, Features, TuneFeatures>; def : Proc<"generic", []>; def : Proc<"v7", [FeatureSoftMulDiv, FeatureNoFSMULD]>; @@ -118,9 +126,11 @@ def : Proc<"ma2480", [FeatureLeon, LeonCASA]>; def : Proc<"ma2485", [FeatureLeon, LeonCASA]>; def : Proc<"ma2x8x", [FeatureLeon, LeonCASA]>; def : Proc<"v9", [FeatureV9]>; -def : Proc<"ultrasparc", [FeatureV9, FeatureV8Deprecated, FeatureVIS]>; +def : Proc<"ultrasparc", [FeatureV9, FeatureV8Deprecated, FeatureVIS], + [TuneSlowRDPC]>; def : Proc<"ultrasparc3", [FeatureV9, FeatureV8Deprecated, FeatureVIS, - FeatureVIS2]>; + FeatureVIS2], + [TuneSlowRDPC]>; def : Proc<"niagara", [FeatureV9, FeatureV8Deprecated, FeatureVIS, FeatureVIS2]>; def : Proc<"niagara2", [FeatureV9, FeatureV8Deprecated, UsePopc, diff --git a/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp b/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp index cca624e0926796..97abf10b18540d 100644 --- a/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp +++ b/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp @@ -13,6 +13,7 @@ #include "MCTargetDesc/SparcInstPrinter.h" #include "MCTargetDesc/SparcMCExpr.h" +#include "MCTargetDesc/SparcMCTargetDesc.h" #include "MCTargetDesc/SparcTargetStreamer.h" #include "Sparc.h" #include "SparcInstrInfo.h" @@ -111,6 +112,15 @@ static void EmitCall(MCStreamer &OutStreamer, OutStreamer.emitInstruction(CallInst, STI); } +static void EmitRDPC(MCStreamer &OutStreamer, MCOperand &RD, + const MCSubtargetInfo &STI) { + MCInst RDPCInst; + RDPCInst.setOpcode(SP::RDASR); + RDPCInst.addOperand(RD); + RDPCInst.addOperand(MCOperand::createReg(SP::ASR5)); + OutStreamer.emitInstruction(RDPCInst, STI); +} + static void EmitSETHI(MCStreamer &OutStreamer, MCOperand &Imm, MCOperand &RD, const MCSubtargetInfo &STI) @@ -234,8 +244,15 @@ void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI, // add <MO>, %o7, <MO> OutStreamer->emitLabel(StartLabel); - MCOperand Callee = createPCXCallOP(EndLabel, OutContext); - EmitCall(*OutStreamer, Callee, STI); + if (!STI.getTargetTriple().isSPARC64() || + STI.hasFeature(Sparc::TuneSlowRDPC)) { + 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. + EmitRDPC(*OutStreamer, RegO7, STI); + } OutStreamer->emitLabel(SethiLabel); MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_PC22, GOTLabel, StartLabel, SethiLabel, diff --git a/llvm/test/CodeGen/SPARC/tune-getpcx.ll b/llvm/test/CodeGen/SPARC/tune-getpcx.ll new file mode 100644 index 00000000000000..7454fea0e38d57 --- /dev/null +++ b/llvm/test/CodeGen/SPARC/tune-getpcx.ll @@ -0,0 +1,18 @@ +; 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 +} `````````` </details> https://github.com/llvm/llvm-project/pull/77196 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits