diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2017-11-17 04:18:24 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2017-11-17 04:18:24 +0000 |
commit | 03c67d1eb28457367392c9322c62269fda9e7d8b (patch) | |
tree | b55198573b7d52e0b47c07f322b3fb033b276621 /llvm/lib | |
parent | 11c0aab7556ae1b8938770acfaa022d11209a4c2 (diff) | |
download | bcm5719-llvm-03c67d1eb28457367392c9322c62269fda9e7d8b.tar.gz bcm5719-llvm-03c67d1eb28457367392c9322c62269fda9e7d8b.zip |
AMDGPU: Fix breaking SMEM clauses
This was completely ignoring subregisters,
so was not very useful. Also only break them
if xnack is actually enabled.
llvm-svn: 318505
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp | 54 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h | 16 |
2 files changed, 45 insertions, 25 deletions
diff --git a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp index 3f54f8b8143..2b73108bd06 100644 --- a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp +++ b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp @@ -40,7 +40,10 @@ GCNHazardRecognizer::GCNHazardRecognizer(const MachineFunction &MF) : CurrCycleInstr(nullptr), MF(MF), ST(MF.getSubtarget<SISubtarget>()), - TII(*ST.getInstrInfo()) { + TII(*ST.getInstrInfo()), + TRI(TII.getRegisterInfo()), + ClauseUses(TRI.getNumRegUnits()), + ClauseDefs(TRI.getNumRegUnits()) { MaxLookAhead = 5; } @@ -258,19 +261,35 @@ int GCNHazardRecognizer::getWaitStatesSinceSetReg( // No-op Hazard Detection //===----------------------------------------------------------------------===// -static void addRegsToSet(iterator_range<MachineInstr::const_mop_iterator> Ops, - std::set<unsigned> &Set) { +static void addRegUnits(const SIRegisterInfo &TRI, + BitVector &BV, unsigned Reg) { + for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) + BV.set(*RUI); +} + +static void addRegsToSet(const SIRegisterInfo &TRI, + iterator_range<MachineInstr::const_mop_iterator> Ops, + BitVector &Set) { for (const MachineOperand &Op : Ops) { if (Op.isReg()) - Set.insert(Op.getReg()); + addRegUnits(TRI, Set, Op.getReg()); } } +void GCNHazardRecognizer::addClauseInst(const MachineInstr &MI) { + // XXX: Do we need to worry about implicit operands + addRegsToSet(TRI, MI.defs(), ClauseDefs); + addRegsToSet(TRI, MI.uses(), ClauseUses); +} + int GCNHazardRecognizer::checkSMEMSoftClauseHazards(MachineInstr *SMEM) { - // SMEM soft clause are only present on VI+ - if (ST.getGeneration() < SISubtarget::VOLCANIC_ISLANDS) + // SMEM soft clause are only present on VI+, and only matter if xnack is + // enabled. + if (!ST.isXNACKEnabled()) return 0; + resetClause(); + // A soft-clause is any group of consecutive SMEM instructions. The // instructions in this group may return out of order and/or may be // replayed (i.e. the same instruction issued more than once). @@ -281,21 +300,16 @@ int GCNHazardRecognizer::checkSMEMSoftClauseHazards(MachineInstr *SMEM) { // (including itself). If we encounter this situaion, we need to break the // clause by inserting a non SMEM instruction. - std::set<unsigned> ClauseDefs; - std::set<unsigned> ClauseUses; - for (MachineInstr *MI : EmittedInstrs) { - // When we hit a non-SMEM instruction then we have passed the start of the // clause and we can stop. if (!MI || !SIInstrInfo::isSMRD(*MI)) break; - addRegsToSet(MI->defs(), ClauseDefs); - addRegsToSet(MI->uses(), ClauseUses); + addClauseInst(*MI); } - if (ClauseDefs.empty()) + if (ClauseDefs.none()) return 0; // FIXME: When we support stores, we need to make sure not to put loads and @@ -304,21 +318,11 @@ int GCNHazardRecognizer::checkSMEMSoftClauseHazards(MachineInstr *SMEM) { if (SMEM->mayStore()) return 1; - addRegsToSet(SMEM->defs(), ClauseDefs); - addRegsToSet(SMEM->uses(), ClauseUses); - - std::vector<unsigned> Result(std::max(ClauseDefs.size(), ClauseUses.size())); - std::vector<unsigned>::iterator End; - - End = std::set_intersection(ClauseDefs.begin(), ClauseDefs.end(), - ClauseUses.begin(), ClauseUses.end(), Result.begin()); + addClauseInst(*SMEM); // If the set of defs and uses intersect then we cannot add this instruction // to the clause, so we have a hazard. - if (End != Result.begin()) - return 1; - - return 0; + return ClauseDefs.anyCommon(ClauseUses) ? 1 : 0; } int GCNHazardRecognizer::checkSMRDHazards(MachineInstr *SMRD) { diff --git a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h index 5680c3de6a1..eb382cc8c77 100644 --- a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h +++ b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h @@ -14,6 +14,7 @@ #ifndef LLVM_LIB_TARGET_AMDGPUHAZARDRECOGNIZERS_H #define LLVM_LIB_TARGET_AMDGPUHAZARDRECOGNIZERS_H +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/ScheduleHazardRecognizer.h" #include <list> @@ -24,6 +25,7 @@ class MachineFunction; class MachineInstr; class ScheduleDAG; class SIInstrInfo; +class SIRegisterInfo; class SISubtarget; class GCNHazardRecognizer final : public ScheduleHazardRecognizer { @@ -35,6 +37,20 @@ class GCNHazardRecognizer final : public ScheduleHazardRecognizer { const MachineFunction &MF; const SISubtarget &ST; const SIInstrInfo &TII; + const SIRegisterInfo &TRI; + + /// RegUnits of uses in the current soft memory clause. + BitVector ClauseUses; + + /// RegUnits of defs in the current soft memory clause. + BitVector ClauseDefs; + + void resetClause() { + ClauseUses.reset(); + ClauseDefs.reset(); + } + + void addClauseInst(const MachineInstr &MI); int getWaitStatesSince(function_ref<bool(MachineInstr *)> IsHazard); int getWaitStatesSinceDef(unsigned Reg, |