summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AMDGPU
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2016-10-15 00:58:14 +0000
committerTom Stellard <thomas.stellard@amd.com>2016-10-15 00:58:14 +0000
commit961811c90661390431068d9e9d222e292620e0e0 (patch)
treef74e79c9b700aa8b3a110b486a2600cd68e2212f /llvm/lib/Target/AMDGPU
parent44264e1353916cbb5d447082c9e7a8ba1c56b9f3 (diff)
downloadbcm5719-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.cpp47
-rw-r--r--llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h2
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.
OpenPOWER on IntegriCloud