summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2017-11-17 04:18:24 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2017-11-17 04:18:24 +0000
commit03c67d1eb28457367392c9322c62269fda9e7d8b (patch)
treeb55198573b7d52e0b47c07f322b3fb033b276621 /llvm/lib
parent11c0aab7556ae1b8938770acfaa022d11209a4c2 (diff)
downloadbcm5719-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.cpp54
-rw-r--r--llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h16
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,
OpenPOWER on IntegriCloud