[llvm] r284298 - AMDGPU/SI: Handle s_getreg hazard in GCNHazardRecognizer
Tom Stellard via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 14 17:58:14 PDT 2016
Author: tstellar
Date: Fri Oct 14 19:58:14 2016
New Revision: 284298
URL: http://llvm.org/viewvc/llvm-project?rev=284298&view=rev
Log:
AMDGPU/SI: Handle s_getreg hazard in GCNHazardRecognizer
Reviewers: arsenm
Subscribers: kzhuravl, wdng, nhaehnle, yaxunl, llvm-commits, tony-tye
Differential Revision: https://reviews.llvm.org/D25526
Modified:
llvm/trunk/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
llvm/trunk/lib/Target/AMDGPU/GCNHazardRecognizer.h
llvm/trunk/test/CodeGen/MIR/AMDGPU/inserted-wait-states.mir
Modified: llvm/trunk/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/GCNHazardRecognizer.cpp?rev=284298&r1=284297&r2=284298&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/GCNHazardRecognizer.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/GCNHazardRecognizer.cpp Fri Oct 14 19:58:14 2016
@@ -42,6 +42,21 @@ static bool isDivFMas(unsigned Opcode) {
return Opcode == AMDGPU::V_DIV_FMAS_F32 || Opcode == AMDGPU::V_DIV_FMAS_F64;
}
+static bool isSGetReg(unsigned Opcode) {
+ return Opcode == AMDGPU::S_GETREG_B32;
+}
+
+static bool isSSetReg(unsigned Opcode) {
+ return Opcode == AMDGPU::S_SETREG_B32 || Opcode == AMDGPU::S_SETREG_IMM32_B32;
+}
+
+static unsigned getHWReg(const SIInstrInfo *TII, const MachineInstr &RegInstr) {
+
+ const MachineOperand *RegOp = TII->getNamedOperand(RegInstr,
+ AMDGPU::OpName::simm16);
+ return RegOp->getImm() & AMDGPU::Hwreg::ID_MASK_;
+}
+
ScheduleHazardRecognizer::HazardType
GCNHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
MachineInstr *MI = SU->getInstr();
@@ -58,6 +73,9 @@ GCNHazardRecognizer::getHazardType(SUnit
if (isDivFMas(MI->getOpcode()) && checkDivFMasHazards(MI) > 0)
return NoopHazard;
+ if (isSGetReg(MI->getOpcode()) && checkGetRegHazards(MI) > 0)
+ return NoopHazard;
+
return NoHazard;
}
@@ -78,6 +96,9 @@ unsigned GCNHazardRecognizer::PreEmitNoo
if (isDivFMas(MI->getOpcode()))
return std::max(0, checkDivFMasHazards(MI));
+ if (isSGetReg(MI->getOpcode()))
+ return std::max(0, checkGetRegHazards(MI));
+
return 0;
}
@@ -137,6 +158,19 @@ int GCNHazardRecognizer::getWaitStatesSi
return std::numeric_limits<int>::max();
}
+int GCNHazardRecognizer::getWaitStatesSinceSetReg(
+ function_ref<bool(MachineInstr *)> IsHazard) {
+
+ int WaitStates = -1;
+ for (MachineInstr *MI : EmittedInstrs) {
+ ++WaitStates;
+ if (!MI || !isSSetReg(MI->getOpcode()) || !IsHazard(MI))
+ continue;
+ return WaitStates;
+ }
+ return std::numeric_limits<int>::max();
+}
+
//===----------------------------------------------------------------------===//
// No-op Hazard Detection
//===----------------------------------------------------------------------===//
@@ -284,3 +318,16 @@ int GCNHazardRecognizer::checkDivFMasHaz
return DivFMasWaitStates - WaitStatesNeeded;
}
+
+int GCNHazardRecognizer::checkGetRegHazards(MachineInstr *GetRegInstr) {
+ const SIInstrInfo *TII = ST.getInstrInfo();
+ unsigned GetRegHWReg = getHWReg(TII, *GetRegInstr);
+
+ const int GetRegWaitStates = 2;
+ auto IsHazardFn = [TII, GetRegHWReg] (MachineInstr *MI) {
+ return GetRegHWReg == getHWReg(TII, *MI);
+ };
+ int WaitStatesNeeded = getWaitStatesSinceSetReg(IsHazardFn);
+
+ return GetRegWaitStates - WaitStatesNeeded;
+}
Modified: llvm/trunk/lib/Target/AMDGPU/GCNHazardRecognizer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/GCNHazardRecognizer.h?rev=284298&r1=284297&r2=284298&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/GCNHazardRecognizer.h (original)
+++ llvm/trunk/lib/Target/AMDGPU/GCNHazardRecognizer.h Fri Oct 14 19:58:14 2016
@@ -38,12 +38,14 @@ class GCNHazardRecognizer final : public
int getWaitStatesSinceDef(unsigned Reg,
function_ref<bool(MachineInstr *)> IsHazardDef =
[](MachineInstr *) { return true; });
+ int getWaitStatesSinceSetReg(function_ref<bool(MachineInstr *)> IsHazard);
int checkSMEMSoftClauseHazards(MachineInstr *SMEM);
int checkSMRDHazards(MachineInstr *SMRD);
int checkVMEMHazards(MachineInstr* VMEM);
int checkDPPHazards(MachineInstr *DPP);
int checkDivFMasHazards(MachineInstr *DivFMas);
+ int checkGetRegHazards(MachineInstr *GetRegInstr);
public:
GCNHazardRecognizer(const MachineFunction &MF);
// We can only issue one instruction per cycle.
Modified: llvm/trunk/test/CodeGen/MIR/AMDGPU/inserted-wait-states.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/AMDGPU/inserted-wait-states.mir?rev=284298&r1=284297&r2=284298&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/AMDGPU/inserted-wait-states.mir (original)
+++ llvm/trunk/test/CodeGen/MIR/AMDGPU/inserted-wait-states.mir Fri Oct 14 19:58:14 2016
@@ -1,5 +1,12 @@
# RUN: llc -march=amdgcn -run-pass post-RA-hazard-rec %s -o - | FileCheck %s
+--- |
+ define void @div_fmas() { ret void }
+ define void @s_getreg() { ret void }
+...
+---
+# CHECK-LABEL: name: div_fmas
+
# CHECK-LABEL: bb.0:
# CHECK: S_MOV_B64
# CHECK-NOT: S_NOP
@@ -28,11 +35,7 @@
# CHECK: S_NOP
# CHECK: S_NOP
# CHECK: V_DIV_FMAS_F32
---- |
- define void @test0() { ret void }
-...
----
-name: test0
+name: div_fmas
body: |
bb.0:
@@ -57,4 +60,58 @@ body: |
%vgpr4, %vcc = V_DIV_SCALE_F32 0, %vgpr1, 0, %vgpr1, 0, %vgpr3, 0, 0, implicit %exec
%vgpr0 = V_DIV_FMAS_F32 0, %vgpr1, 0, %vgpr2, 0, %vgpr3, 0, 0, implicit %vcc, implicit %exec
S_ENDPGM
+
+...
+
+...
+---
+# CHECK-LABEL: name: s_getreg
+
+# CHECK-LABEL: bb.0:
+# CHECK: S_SETREG
+# CHECK: S_NOP 0
+# CHECK: S_NOP 0
+# CHECK: S_GETREG
+
+# CHECK-LABEL: bb.1:
+# CHECK: S_SETREG_IMM32
+# CHECK: S_NOP 0
+# CHECK: S_NOP 0
+# CHECK: S_GETREG
+
+# CHECK-LABEL: bb.2:
+# CHECK: S_SETREG
+# CHECK: S_NOP 0
+# CHECK: S_GETREG
+
+# CHECK-LABEL: bb.3:
+# CHECK: S_SETREG
+# CHECK-NEXT: S_GETREG
+
+name: s_getreg
+
+body: |
+ bb.0:
+ successors: %bb.1
+ S_SETREG_B32 %sgpr0, 1
+ %sgpr1 = S_GETREG_B32 1
+ S_BRANCH %bb.1
+
+ bb.1:
+ successors: %bb.2
+ S_SETREG_IMM32_B32 0, 1
+ %sgpr1 = S_GETREG_B32 1
+ S_BRANCH %bb.2
+
+ bb.2:
+ successors: %bb.3
+ S_SETREG_B32 %sgpr0, 1
+ %sgpr1 = S_MOV_B32 0
+ %sgpr2 = S_GETREG_B32 1
+ S_BRANCH %bb.3
+
+ bb.3:
+ S_SETREG_B32 %sgpr0, 0
+ %sgpr1 = S_GETREG_B32 1
+ S_ENDPGM
...
More information about the llvm-commits
mailing list