diff options
| author | Tom Stellard <thomas.stellard@amd.com> | 2016-10-15 00:58:14 +0000 |
|---|---|---|
| committer | Tom Stellard <thomas.stellard@amd.com> | 2016-10-15 00:58:14 +0000 |
| commit | 961811c90661390431068d9e9d222e292620e0e0 (patch) | |
| tree | f74e79c9b700aa8b3a110b486a2600cd68e2212f /llvm/lib/Target/AMDGPU | |
| parent | 44264e1353916cbb5d447082c9e7a8ba1c56b9f3 (diff) | |
| download | bcm5719-llvm-961811c90661390431068d9e9d222e292620e0e0.tar.gz bcm5719-llvm-961811c90661390431068d9e9d222e292620e0e0.zip | |
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
llvm-svn: 284298
Diffstat (limited to 'llvm/lib/Target/AMDGPU')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp | 47 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h | 2 |
2 files changed, 49 insertions, 0 deletions
diff --git a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp index 78f91c06adf..9e9f1904b26 100644 --- a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp +++ b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp @@ -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 *SU, int Stalls) { 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::PreEmitNoops(MachineInstr *MI) { 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::getWaitStatesSinceDef( 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::checkDivFMasHazards(MachineInstr *DivFMas) { 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; +} diff --git a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h index 1d87f3a0583..dbcdde81725 100644 --- a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h +++ b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h @@ -38,12 +38,14 @@ class GCNHazardRecognizer final : public ScheduleHazardRecognizer { 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. |

