From 30d30824b4087b1716e5b6dbe2480029793a336f Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 27 Oct 2016 20:39:09 +0000 Subject: [PATCH] AMDGPU/SI: Handle s_setreg hazard in GCNHazardRecognizer Reviewers: arsenm Subscribers: kzhuravl, wdng, nhaehnle, yaxunl, llvm-commits, tony-tye Differential Revision: https://reviews.llvm.org/D25528 llvm-svn: 285338 --- llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp | 19 +++ llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h | 1 + .../CodeGen/MIR/AMDGPU/inserted-wait-states.mir | 142 ++++++++++++++------- 3 files changed, 113 insertions(+), 49 deletions(-) diff --git a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp index 9e9f190..100ea7e 100644 --- a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp +++ b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp @@ -76,6 +76,9 @@ GCNHazardRecognizer::getHazardType(SUnit *SU, int Stalls) { if (isSGetReg(MI->getOpcode()) && checkGetRegHazards(MI) > 0) return NoopHazard; + if (isSSetReg(MI->getOpcode()) && checkSetRegHazards(MI) > 0) + return NoopHazard; + return NoHazard; } @@ -99,6 +102,9 @@ unsigned GCNHazardRecognizer::PreEmitNoops(MachineInstr *MI) { if (isSGetReg(MI->getOpcode())) return std::max(0, checkGetRegHazards(MI)); + if (isSSetReg(MI->getOpcode())) + return std::max(0, checkSetRegHazards(MI)); + return 0; } @@ -331,3 +337,16 @@ int GCNHazardRecognizer::checkGetRegHazards(MachineInstr *GetRegInstr) { return GetRegWaitStates - WaitStatesNeeded; } + +int GCNHazardRecognizer::checkSetRegHazards(MachineInstr *SetRegInstr) { + const SIInstrInfo *TII = ST.getInstrInfo(); + unsigned HWReg = getHWReg(TII, *SetRegInstr); + + const int SetRegWaitStates = + ST.getGeneration() <= AMDGPUSubtarget::SEA_ISLANDS ? 1 : 2; + auto IsHazardFn = [TII, HWReg] (MachineInstr *MI) { + return HWReg == getHWReg(TII, *MI); + }; + int WaitStatesNeeded = getWaitStatesSinceSetReg(IsHazardFn); + return SetRegWaitStates - WaitStatesNeeded; +} diff --git a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h index dbcdde8..58831ad 100644 --- a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h +++ b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h @@ -46,6 +46,7 @@ class GCNHazardRecognizer final : public ScheduleHazardRecognizer { int checkDPPHazards(MachineInstr *DPP); int checkDivFMasHazards(MachineInstr *DivFMas); int checkGetRegHazards(MachineInstr *GetRegInstr); + int checkSetRegHazards(MachineInstr *SetRegInstr); public: GCNHazardRecognizer(const MachineFunction &MF); // We can only issue one instruction per cycle. diff --git a/llvm/test/CodeGen/MIR/AMDGPU/inserted-wait-states.mir b/llvm/test/CodeGen/MIR/AMDGPU/inserted-wait-states.mir index 1f283ab..f169474 100644 --- a/llvm/test/CodeGen/MIR/AMDGPU/inserted-wait-states.mir +++ b/llvm/test/CodeGen/MIR/AMDGPU/inserted-wait-states.mir @@ -1,40 +1,43 @@ -# RUN: llc -march=amdgcn -run-pass post-RA-hazard-rec %s -o - | FileCheck %s +# RUN: llc -march=amdgcn -mcpu=tahiti -run-pass post-RA-hazard-rec %s -o - | FileCheck %s -check-prefixes=GCN +# RUN: llc -march=amdgcn -mcpu=hawaii -run-pass post-RA-hazard-rec %s -o - | FileCheck %s -check-prefixes=GCN +# RUN: llc -march=amdgcn -mcpu=fiji -run-pass post-RA-hazard-rec %s -o - | FileCheck %s -check-prefixes=GCN,VI --- | define void @div_fmas() { ret void } define void @s_getreg() { ret void } + define void @s_setreg() { ret void } ... --- -# CHECK-LABEL: name: div_fmas - -# CHECK-LABEL: bb.0: -# CHECK: S_MOV_B64 -# CHECK-NOT: S_NOP -# CHECK: V_DIV_FMAS - -# CHECK-LABEL: bb.1: -# CHECK: V_CMP_EQ_I32 -# CHECK: S_NOP -# CHECK: S_NOP -# CHECK: S_NOP -# CHECK: S_NOP -# CHECK: V_DIV_FMAS_F32 - -# CHECK-LABEL: bb.2: -# CHECK: V_CMP_EQ_I32 -# CHECK: S_NOP -# CHECK: S_NOP -# CHECK: S_NOP -# CHECK: S_NOP -# CHECK: V_DIV_FMAS_F32 - -# CHECK-LABEL: bb.3: -# CHECK: V_DIV_SCALE_F32 -# CHECK: S_NOP -# CHECK: S_NOP -# CHECK: S_NOP -# CHECK: S_NOP -# CHECK: V_DIV_FMAS_F32 +# GCN-LABEL: name: div_fmas + +# GCN-LABEL: bb.0: +# GCN: S_MOV_B64 +# GCN-NOT: S_NOP +# GCN: V_DIV_FMAS + +# GCN-LABEL: bb.1: +# GCN: V_CMP_EQ_I32 +# GCN: S_NOP +# GCN: S_NOP +# GCN: S_NOP +# GCN: S_NOP +# GCN: V_DIV_FMAS_F32 + +# GCN-LABEL: bb.2: +# GCN: V_CMP_EQ_I32 +# GCN: S_NOP +# GCN: S_NOP +# GCN: S_NOP +# GCN: S_NOP +# GCN: V_DIV_FMAS_F32 + +# GCN-LABEL: bb.3: +# GCN: V_DIV_SCALE_F32 +# GCN: S_NOP +# GCN: S_NOP +# GCN: S_NOP +# GCN: S_NOP +# GCN: V_DIV_FMAS_F32 name: div_fmas body: | @@ -65,28 +68,28 @@ body: | ... --- -# CHECK-LABEL: name: s_getreg +# GCN-LABEL: name: s_getreg -# CHECK-LABEL: bb.0: -# CHECK: S_SETREG -# CHECK: S_NOP 0 -# CHECK: S_NOP 0 -# CHECK: S_GETREG +# GCN-LABEL: bb.0: +# GCN: S_SETREG +# GCN: S_NOP 0 +# GCN: S_NOP 0 +# GCN: S_GETREG -# CHECK-LABEL: bb.1: -# CHECK: S_SETREG_IMM32 -# CHECK: S_NOP 0 -# CHECK: S_NOP 0 -# CHECK: S_GETREG +# GCN-LABEL: bb.1: +# GCN: S_SETREG_IMM32 +# GCN: S_NOP 0 +# GCN: S_NOP 0 +# GCN: S_GETREG -# CHECK-LABEL: bb.2: -# CHECK: S_SETREG -# CHECK: S_NOP 0 -# CHECK: S_GETREG +# GCN-LABEL: bb.2: +# GCN: S_SETREG +# GCN: S_NOP 0 +# GCN: S_GETREG -# CHECK-LABEL: bb.3: -# CHECK: S_SETREG -# CHECK-NEXT: S_GETREG +# GCN-LABEL: bb.3: +# GCN: S_SETREG +# GCN-NEXT: S_GETREG name: s_getreg @@ -115,3 +118,44 @@ body: | %sgpr1 = S_GETREG_B32 1 S_ENDPGM ... + +... +--- +# GCN-LABEL: name: s_setreg + +# GCN-LABEL: bb.0: +# GCN: S_SETREG +# GCN: S_NOP 0 +# VI: S_NOP 0 +# GCN-NEXT: S_SETREG + +# GCN-LABEL: bb.1: +# GCN: S_SETREG +# GCN: S_NOP 0 +# VI: S_NOP 0 +# GCN-NEXT: S_SETREG + +# GCN-LABEL: bb.2: +# GCN: S_SETREG +# GCN-NEXT: S_SETREG + +name: s_setreg + +body: | + bb.0: + successors: %bb.1 + S_SETREG_B32 %sgpr0, 1 + S_SETREG_B32 %sgpr1, 1 + S_BRANCH %bb.1 + + bb.1: + successors: %bb.2 + S_SETREG_B32 %sgpr0, 64 + S_SETREG_B32 %sgpr1, 128 + S_BRANCH %bb.2 + + bb.2: + S_SETREG_B32 %sgpr0, 1 + S_SETREG_B32 %sgpr1, 0 + S_ENDPGM +... -- 2.7.4