LLVM  4.0.0
GCNHazardRecognizer.cpp
Go to the documentation of this file.
1 //===-- GCNHazardRecognizers.cpp - GCN Hazard Recognizer Impls ------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements hazard recognizers for scheduling on GCN processors.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "GCNHazardRecognizer.h"
15 #include "AMDGPUSubtarget.h"
16 #include "SIInstrInfo.h"
18 #include "llvm/Support/Debug.h"
19 
20 using namespace llvm;
21 
22 //===----------------------------------------------------------------------===//
23 // Hazard Recoginizer Implementation
24 //===----------------------------------------------------------------------===//
25 
27  CurrCycleInstr(nullptr),
28  MF(MF),
29  ST(MF.getSubtarget<SISubtarget>()) {
30  MaxLookAhead = 5;
31 }
32 
35 }
36 
38  CurrCycleInstr = MI;
39 }
40 
41 static bool isDivFMas(unsigned Opcode) {
42  return Opcode == AMDGPU::V_DIV_FMAS_F32 || Opcode == AMDGPU::V_DIV_FMAS_F64;
43 }
44 
45 static bool isSGetReg(unsigned Opcode) {
46  return Opcode == AMDGPU::S_GETREG_B32;
47 }
48 
49 static bool isSSetReg(unsigned Opcode) {
50  return Opcode == AMDGPU::S_SETREG_B32 || Opcode == AMDGPU::S_SETREG_IMM32_B32;
51 }
52 
53 static bool isRWLane(unsigned Opcode) {
54  return Opcode == AMDGPU::V_READLANE_B32 || Opcode == AMDGPU::V_WRITELANE_B32;
55 }
56 
57 static bool isRFE(unsigned Opcode) {
58  return Opcode == AMDGPU::S_RFE_B64;
59 }
60 
61 static unsigned getHWReg(const SIInstrInfo *TII, const MachineInstr &RegInstr) {
62 
63  const MachineOperand *RegOp = TII->getNamedOperand(RegInstr,
64  AMDGPU::OpName::simm16);
65  return RegOp->getImm() & AMDGPU::Hwreg::ID_MASK_;
66 }
67 
70  MachineInstr *MI = SU->getInstr();
71 
72  if (SIInstrInfo::isSMRD(*MI) && checkSMRDHazards(MI) > 0)
73  return NoopHazard;
74 
75  if (SIInstrInfo::isVMEM(*MI) && checkVMEMHazards(MI) > 0)
76  return NoopHazard;
77 
78  if (SIInstrInfo::isVALU(*MI) && checkVALUHazards(MI) > 0)
79  return NoopHazard;
80 
81  if (SIInstrInfo::isDPP(*MI) && checkDPPHazards(MI) > 0)
82  return NoopHazard;
83 
84  if (isDivFMas(MI->getOpcode()) && checkDivFMasHazards(MI) > 0)
85  return NoopHazard;
86 
87  if (isRWLane(MI->getOpcode()) && checkRWLaneHazards(MI) > 0)
88  return NoopHazard;
89 
90  if (isSGetReg(MI->getOpcode()) && checkGetRegHazards(MI) > 0)
91  return NoopHazard;
92 
93  if (isSSetReg(MI->getOpcode()) && checkSetRegHazards(MI) > 0)
94  return NoopHazard;
95 
96  if (isRFE(MI->getOpcode()) && checkRFEHazards(MI) > 0)
97  return NoopHazard;
98 
99  return NoHazard;
100 }
101 
103  return PreEmitNoops(SU->getInstr());
104 }
105 
107  if (SIInstrInfo::isSMRD(*MI))
108  return std::max(0, checkSMRDHazards(MI));
109 
110  if (SIInstrInfo::isVALU(*MI)) {
111  int WaitStates = std::max(0, checkVALUHazards(MI));
112 
113  if (SIInstrInfo::isVMEM(*MI))
114  WaitStates = std::max(WaitStates, checkVMEMHazards(MI));
115 
116  if (SIInstrInfo::isDPP(*MI))
117  WaitStates = std::max(WaitStates, checkDPPHazards(MI));
118 
119  if (isDivFMas(MI->getOpcode()))
120  WaitStates = std::max(WaitStates, checkDivFMasHazards(MI));
121 
122  if (isRWLane(MI->getOpcode()))
123  WaitStates = std::max(WaitStates, checkRWLaneHazards(MI));
124 
125  return WaitStates;
126  }
127 
128  if (isSGetReg(MI->getOpcode()))
129  return std::max(0, checkGetRegHazards(MI));
130 
131  if (isSSetReg(MI->getOpcode()))
132  return std::max(0, checkSetRegHazards(MI));
133 
134  if (isRFE(MI->getOpcode()))
135  return std::max(0, checkRFEHazards(MI));
136 
137  return 0;
138 }
139 
141  EmittedInstrs.push_front(nullptr);
142 }
143 
145 
146  // When the scheduler detects a stall, it will call AdvanceCycle() without
147  // emitting any instructions.
148  if (!CurrCycleInstr)
149  return;
150 
151  const SIInstrInfo *TII = ST.getInstrInfo();
152  unsigned NumWaitStates = TII->getNumWaitStates(*CurrCycleInstr);
153 
154  // Keep track of emitted instructions
155  EmittedInstrs.push_front(CurrCycleInstr);
156 
157  // Add a nullptr for each additional wait state after the first. Make sure
158  // not to add more than getMaxLookAhead() items to the list, since we
159  // truncate the list to that size right after this loop.
160  for (unsigned i = 1, e = std::min(NumWaitStates, getMaxLookAhead());
161  i < e; ++i) {
162  EmittedInstrs.push_front(nullptr);
163  }
164 
165  // getMaxLookahead() is the largest number of wait states we will ever need
166  // to insert, so there is no point in keeping track of more than that many
167  // wait states.
168  EmittedInstrs.resize(getMaxLookAhead());
169 
170  CurrCycleInstr = nullptr;
171 }
172 
174  llvm_unreachable("hazard recognizer does not support bottom-up scheduling.");
175 }
176 
177 //===----------------------------------------------------------------------===//
178 // Helper Functions
179 //===----------------------------------------------------------------------===//
180 
181 int GCNHazardRecognizer::getWaitStatesSince(
182  function_ref<bool(MachineInstr *)> IsHazard) {
183 
184  int WaitStates = -1;
185  for (MachineInstr *MI : EmittedInstrs) {
186  ++WaitStates;
187  if (!MI || !IsHazard(MI))
188  continue;
189  return WaitStates;
190  }
191  return std::numeric_limits<int>::max();
192 }
193 
194 int GCNHazardRecognizer::getWaitStatesSinceDef(
195  unsigned Reg, function_ref<bool(MachineInstr *)> IsHazardDef) {
196  const SIRegisterInfo *TRI = ST.getRegisterInfo();
197 
198  auto IsHazardFn = [IsHazardDef, TRI, Reg] (MachineInstr *MI) {
199  return IsHazardDef(MI) && MI->modifiesRegister(Reg, TRI);
200  };
201 
202  return getWaitStatesSince(IsHazardFn);
203 }
204 
205 int GCNHazardRecognizer::getWaitStatesSinceSetReg(
206  function_ref<bool(MachineInstr *)> IsHazard) {
207 
208  auto IsHazardFn = [IsHazard] (MachineInstr *MI) {
209  return isSSetReg(MI->getOpcode()) && IsHazard(MI);
210  };
211 
212  return getWaitStatesSince(IsHazardFn);
213 }
214 
215 //===----------------------------------------------------------------------===//
216 // No-op Hazard Detection
217 //===----------------------------------------------------------------------===//
218 
220  std::set<unsigned> &Set) {
221  for (const MachineOperand &Op : Ops) {
222  if (Op.isReg())
223  Set.insert(Op.getReg());
224  }
225 }
226 
227 int GCNHazardRecognizer::checkSMEMSoftClauseHazards(MachineInstr *SMEM) {
228  // SMEM soft clause are only present on VI+
229  if (ST.getGeneration() < SISubtarget::VOLCANIC_ISLANDS)
230  return 0;
231 
232  // A soft-clause is any group of consecutive SMEM instructions. The
233  // instructions in this group may return out of order and/or may be
234  // replayed (i.e. the same instruction issued more than once).
235  //
236  // In order to handle these situations correctly we need to make sure
237  // that when a clause has more than one instruction, no instruction in the
238  // clause writes to a register that is read another instruction in the clause
239  // (including itself). If we encounter this situaion, we need to break the
240  // clause by inserting a non SMEM instruction.
241 
242  std::set<unsigned> ClauseDefs;
243  std::set<unsigned> ClauseUses;
244 
245  for (MachineInstr *MI : EmittedInstrs) {
246 
247  // When we hit a non-SMEM instruction then we have passed the start of the
248  // clause and we can stop.
249  if (!MI || !SIInstrInfo::isSMRD(*MI))
250  break;
251 
252  addRegsToSet(MI->defs(), ClauseDefs);
253  addRegsToSet(MI->uses(), ClauseUses);
254  }
255 
256  if (ClauseDefs.empty())
257  return 0;
258 
259  // FIXME: When we support stores, we need to make sure not to put loads and
260  // stores in the same clause if they use the same address. For now, just
261  // start a new clause whenever we see a store.
262  if (SMEM->mayStore())
263  return 1;
264 
265  addRegsToSet(SMEM->defs(), ClauseDefs);
266  addRegsToSet(SMEM->uses(), ClauseUses);
267 
268  std::vector<unsigned> Result(std::max(ClauseDefs.size(), ClauseUses.size()));
269  std::vector<unsigned>::iterator End;
270 
271  End = std::set_intersection(ClauseDefs.begin(), ClauseDefs.end(),
272  ClauseUses.begin(), ClauseUses.end(), Result.begin());
273 
274  // If the set of defs and uses intersect then we cannot add this instruction
275  // to the clause, so we have a hazard.
276  if (End != Result.begin())
277  return 1;
278 
279  return 0;
280 }
281 
282 int GCNHazardRecognizer::checkSMRDHazards(MachineInstr *SMRD) {
283  const SISubtarget &ST = MF.getSubtarget<SISubtarget>();
284  const SIInstrInfo *TII = ST.getInstrInfo();
285  int WaitStatesNeeded = 0;
286 
287  WaitStatesNeeded = checkSMEMSoftClauseHazards(SMRD);
288 
289  // This SMRD hazard only affects SI.
291  return WaitStatesNeeded;
292 
293  // A read of an SGPR by SMRD instruction requires 4 wait states when the
294  // SGPR was written by a VALU instruction.
295  int SmrdSgprWaitStates = 4;
296  auto IsHazardDefFn = [TII] (MachineInstr *MI) { return TII->isVALU(*MI); };
297 
298  for (const MachineOperand &Use : SMRD->uses()) {
299  if (!Use.isReg())
300  continue;
301  int WaitStatesNeededForUse =
302  SmrdSgprWaitStates - getWaitStatesSinceDef(Use.getReg(), IsHazardDefFn);
303  WaitStatesNeeded = std::max(WaitStatesNeeded, WaitStatesNeededForUse);
304  }
305  return WaitStatesNeeded;
306 }
307 
308 int GCNHazardRecognizer::checkVMEMHazards(MachineInstr* VMEM) {
309  const SIInstrInfo *TII = ST.getInstrInfo();
310 
312  return 0;
313 
314  const SIRegisterInfo &TRI = TII->getRegisterInfo();
315 
316  // A read of an SGPR by a VMEM instruction requires 5 wait states when the
317  // SGPR was written by a VALU Instruction.
318  int VmemSgprWaitStates = 5;
319  int WaitStatesNeeded = 0;
320  auto IsHazardDefFn = [TII] (MachineInstr *MI) { return TII->isVALU(*MI); };
321 
322  for (const MachineOperand &Use : VMEM->uses()) {
323  if (!Use.isReg() || TRI.isVGPR(MF.getRegInfo(), Use.getReg()))
324  continue;
325 
326  int WaitStatesNeededForUse =
327  VmemSgprWaitStates - getWaitStatesSinceDef(Use.getReg(), IsHazardDefFn);
328  WaitStatesNeeded = std::max(WaitStatesNeeded, WaitStatesNeededForUse);
329  }
330  return WaitStatesNeeded;
331 }
332 
333 int GCNHazardRecognizer::checkDPPHazards(MachineInstr *DPP) {
334  const SIRegisterInfo *TRI = ST.getRegisterInfo();
335 
336  // Check for DPP VGPR read after VALU VGPR write.
337  int DppVgprWaitStates = 2;
338  int WaitStatesNeeded = 0;
339 
340  for (const MachineOperand &Use : DPP->uses()) {
341  if (!Use.isReg() || !TRI->isVGPR(MF.getRegInfo(), Use.getReg()))
342  continue;
343  int WaitStatesNeededForUse =
344  DppVgprWaitStates - getWaitStatesSinceDef(Use.getReg());
345  WaitStatesNeeded = std::max(WaitStatesNeeded, WaitStatesNeededForUse);
346  }
347 
348  return WaitStatesNeeded;
349 }
350 
351 int GCNHazardRecognizer::checkDivFMasHazards(MachineInstr *DivFMas) {
352  const SIInstrInfo *TII = ST.getInstrInfo();
353 
354  // v_div_fmas requires 4 wait states after a write to vcc from a VALU
355  // instruction.
356  const int DivFMasWaitStates = 4;
357  auto IsHazardDefFn = [TII] (MachineInstr *MI) { return TII->isVALU(*MI); };
358  int WaitStatesNeeded = getWaitStatesSinceDef(AMDGPU::VCC, IsHazardDefFn);
359 
360  return DivFMasWaitStates - WaitStatesNeeded;
361 }
362 
363 int GCNHazardRecognizer::checkGetRegHazards(MachineInstr *GetRegInstr) {
364  const SIInstrInfo *TII = ST.getInstrInfo();
365  unsigned GetRegHWReg = getHWReg(TII, *GetRegInstr);
366 
367  const int GetRegWaitStates = 2;
368  auto IsHazardFn = [TII, GetRegHWReg] (MachineInstr *MI) {
369  return GetRegHWReg == getHWReg(TII, *MI);
370  };
371  int WaitStatesNeeded = getWaitStatesSinceSetReg(IsHazardFn);
372 
373  return GetRegWaitStates - WaitStatesNeeded;
374 }
375 
376 int GCNHazardRecognizer::checkSetRegHazards(MachineInstr *SetRegInstr) {
377  const SIInstrInfo *TII = ST.getInstrInfo();
378  unsigned HWReg = getHWReg(TII, *SetRegInstr);
379 
380  const int SetRegWaitStates =
382  auto IsHazardFn = [TII, HWReg] (MachineInstr *MI) {
383  return HWReg == getHWReg(TII, *MI);
384  };
385  int WaitStatesNeeded = getWaitStatesSinceSetReg(IsHazardFn);
386  return SetRegWaitStates - WaitStatesNeeded;
387 }
388 
389 int GCNHazardRecognizer::createsVALUHazard(const MachineInstr &MI) {
390  if (!MI.mayStore())
391  return -1;
392 
393  const SIInstrInfo *TII = ST.getInstrInfo();
394  unsigned Opcode = MI.getOpcode();
395  const MCInstrDesc &Desc = MI.getDesc();
396 
397  int VDataIdx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::vdata);
398  int VDataRCID = -1;
399  if (VDataIdx != -1)
400  VDataRCID = Desc.OpInfo[VDataIdx].RegClass;
401 
402  if (TII->isMUBUF(MI) || TII->isMTBUF(MI)) {
403  // There is no hazard if the instruction does not use vector regs
404  // (like wbinvl1)
405  if (VDataIdx == -1)
406  return -1;
407  // For MUBUF/MTBUF instructions this hazard only exists if the
408  // instruction is not using a register in the soffset field.
409  const MachineOperand *SOffset =
410  TII->getNamedOperand(MI, AMDGPU::OpName::soffset);
411  // If we have no soffset operand, then assume this field has been
412  // hardcoded to zero.
413  if (AMDGPU::getRegBitWidth(VDataRCID) > 64 &&
414  (!SOffset || !SOffset->isReg()))
415  return VDataIdx;
416  }
417 
418  // MIMG instructions create a hazard if they don't use a 256-bit T# and
419  // the store size is greater than 8 bytes and they have more than two bits
420  // of their dmask set.
421  // All our MIMG definitions use a 256-bit T#, so we can skip checking for them.
422  if (TII->isMIMG(MI)) {
423  int SRsrcIdx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::srsrc);
424  assert(SRsrcIdx != -1 &&
425  AMDGPU::getRegBitWidth(Desc.OpInfo[SRsrcIdx].RegClass) == 256);
426  (void)SRsrcIdx;
427  }
428 
429  if (TII->isFLAT(MI)) {
430  int DataIdx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::vdata);
431  if (AMDGPU::getRegBitWidth(Desc.OpInfo[DataIdx].RegClass) > 64)
432  return DataIdx;
433  }
434 
435  return -1;
436 }
437 
438 int GCNHazardRecognizer::checkVALUHazards(MachineInstr *VALU) {
439  // This checks for the hazard where VMEM instructions that store more than
440  // 8 bytes can have there store data over written by the next instruction.
441  if (!ST.has12DWordStoreHazard())
442  return 0;
443 
444  const SIRegisterInfo *TRI = ST.getRegisterInfo();
445  const MachineRegisterInfo &MRI = VALU->getParent()->getParent()->getRegInfo();
446 
447  const int VALUWaitStates = 1;
448  int WaitStatesNeeded = 0;
449 
450  for (const MachineOperand &Def : VALU->defs()) {
451  if (!TRI->isVGPR(MRI, Def.getReg()))
452  continue;
453  unsigned Reg = Def.getReg();
454  auto IsHazardFn = [this, Reg, TRI] (MachineInstr *MI) {
455  int DataIdx = createsVALUHazard(*MI);
456  return DataIdx >= 0 &&
457  TRI->regsOverlap(MI->getOperand(DataIdx).getReg(), Reg);
458  };
459  int WaitStatesNeededForDef =
460  VALUWaitStates - getWaitStatesSince(IsHazardFn);
461  WaitStatesNeeded = std::max(WaitStatesNeeded, WaitStatesNeededForDef);
462  }
463  return WaitStatesNeeded;
464 }
465 
466 int GCNHazardRecognizer::checkRWLaneHazards(MachineInstr *RWLane) {
467  const SIInstrInfo *TII = ST.getInstrInfo();
468  const SIRegisterInfo *TRI = ST.getRegisterInfo();
469  const MachineRegisterInfo &MRI =
470  RWLane->getParent()->getParent()->getRegInfo();
471 
472  const MachineOperand *LaneSelectOp =
473  TII->getNamedOperand(*RWLane, AMDGPU::OpName::src1);
474 
475  if (!LaneSelectOp->isReg() || !TRI->isSGPRReg(MRI, LaneSelectOp->getReg()))
476  return 0;
477 
478  unsigned LaneSelectReg = LaneSelectOp->getReg();
479  auto IsHazardFn = [TII] (MachineInstr *MI) {
480  return TII->isVALU(*MI);
481  };
482 
483  const int RWLaneWaitStates = 4;
484  int WaitStatesSince = getWaitStatesSinceDef(LaneSelectReg, IsHazardFn);
485  return RWLaneWaitStates - WaitStatesSince;
486 }
487 
488 int GCNHazardRecognizer::checkRFEHazards(MachineInstr *RFE) {
489 
491  return 0;
492 
493  const SIInstrInfo *TII = ST.getInstrInfo();
494 
495  const int RFEWaitStates = 1;
496 
497  auto IsHazardFn = [TII] (MachineInstr *MI) {
498  return getHWReg(TII, *MI) == AMDGPU::Hwreg::ID_TRAPSTS;
499  };
500  int WaitStatesNeeded = getWaitStatesSinceSetReg(IsHazardFn);
501  return RFEWaitStates - WaitStatesNeeded;
502 }
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
AMDGPU specific subclass of TargetSubtarget.
size_t i
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
Definition: MachineInstr.h:334
bool isVGPR(const MachineRegisterInfo &MRI, unsigned Reg) const
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:163
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
Definition: MachineInstr.h:605
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
MachineInstr * getInstr() const
getInstr - Return the representative MachineInstr for this SUnit.
Definition: ScheduleDAG.h:389
const SIInstrInfo * getInstrInfo() const override
unsigned getRegBitWidth(unsigned RCID)
Get the size in bits of a register from the register class RC.
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:83
static bool isRFE(unsigned Opcode)
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:270
static bool isSMRD(const MachineInstr &MI)
Definition: SIInstrInfo.h:335
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
void EmitNoop() override
EmitNoop - This callback is invoked when a noop was added to the instruction stream.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static bool isFLAT(const MachineInstr &MI)
Definition: SIInstrInfo.h:367
const HexagonInstrInfo * TII
static bool isMIMG(const MachineInstr &MI)
Definition: SIInstrInfo.h:351
A Use represents the edge between a Value definition and its users.
Definition: Use.h:56
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_READONLY MachineOperand * getNamedOperand(MachineInstr &MI, unsigned OperandName) const
Returns the operand named Op.
Reg
All possible values of the reg field in the ModR/M byte.
static bool isVALU(const MachineInstr &MI)
Definition: SIInstrInfo.h:231
static bool isMUBUF(const MachineInstr &MI)
Definition: SIInstrInfo.h:319
static bool isSSetReg(unsigned Opcode)
unsigned PreEmitNoops(SUnit *SU) override
PreEmitNoops - This callback is invoked prior to emitting an instruction.
int64_t getImm() const
Generation getGeneration() const
const SIRegisterInfo & getRegisterInfo() const
Definition: SIInstrInfo.h:117
void RecedeCycle() override
RecedeCycle - This callback is invoked whenever the next bottom-up instruction to be scheduled cannot...
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
void EmitInstruction(SUnit *SU) override
EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:273
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:131
unsigned MaxLookAhead
MaxLookAhead - Indicate the number of cycles in the scoreboard state.
static bool isDPP(const MachineInstr &MI)
Definition: SIInstrInfo.h:415
static void addRegsToSet(iterator_range< MachineInstr::const_mop_iterator > Ops, std::set< unsigned > &Set)
unsigned const MachineRegisterInfo * MRI
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:279
iterator_range< mop_iterator > defs()
Returns a range over all explicit operands that are register definitions.
Definition: MachineInstr.h:323
static const unsigned End
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const SIRegisterInfo * getRegisterInfo() const override
HazardType getHazardType(SUnit *SU, int Stalls) override
getHazardType - Return the hazard type of emitting this node.
MachineOperand class - Representation of each machine instruction operand.
GCNHazardRecognizer(const MachineFunction &MF)
bool isSGPRReg(const MachineRegisterInfo &MRI, unsigned Reg) const
A range adaptor for a pair of iterators.
void AdvanceCycle() override
AdvanceCycle - This callback is invoked whenever the next top-down instruction to be scheduled cannot...
static bool isRWLane(unsigned Opcode)
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:52
Interface definition for SIInstrInfo.
static bool isMTBUF(const MachineInstr &MI)
Definition: SIInstrInfo.h:327
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
Definition: MCInstrDesc.h:76
unsigned getNumWaitStates(const MachineInstr &MI) const
Return the number of wait states that result from executing this instruction.
static bool isVMEM(const MachineInstr &MI)
Definition: SIInstrInfo.h:239
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isSGetReg(unsigned Opcode)
const MCOperandInfo * OpInfo
Definition: MCInstrDesc.h:174
IRTranslator LLVM IR MI
static unsigned getHWReg(const SIInstrInfo *TII, const MachineInstr &RegInstr)
SUnit - Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:244
bool has12DWordStoreHazard() const
static bool isDivFMas(unsigned Opcode)