27 CurrCycleInstr(nullptr),
42 return Opcode == AMDGPU::V_DIV_FMAS_F32 || Opcode == AMDGPU::V_DIV_FMAS_F64;
46 return Opcode == AMDGPU::S_GETREG_B32;
50 return Opcode == AMDGPU::S_SETREG_B32 || Opcode == AMDGPU::S_SETREG_IMM32_B32;
54 return Opcode == AMDGPU::V_READLANE_B32 || Opcode == AMDGPU::V_WRITELANE_B32;
57 static bool isRFE(
unsigned Opcode) {
58 return Opcode == AMDGPU::S_RFE_B64;
64 AMDGPU::OpName::simm16);
108 return std::max(0, checkSMRDHazards(MI));
111 int WaitStates = std::max(0, checkVALUHazards(MI));
114 WaitStates = std::max(WaitStates, checkVMEMHazards(MI));
117 WaitStates = std::max(WaitStates, checkDPPHazards(MI));
120 WaitStates = std::max(WaitStates, checkDivFMasHazards(MI));
123 WaitStates = std::max(WaitStates, checkRWLaneHazards(MI));
129 return std::max(0, checkGetRegHazards(MI));
132 return std::max(0, checkSetRegHazards(MI));
135 return std::max(0, checkRFEHazards(MI));
141 EmittedInstrs.push_front(
nullptr);
155 EmittedInstrs.push_front(CurrCycleInstr);
162 EmittedInstrs.push_front(
nullptr);
170 CurrCycleInstr =
nullptr;
174 llvm_unreachable(
"hazard recognizer does not support bottom-up scheduling.");
181 int GCNHazardRecognizer::getWaitStatesSince(
187 if (!
MI || !IsHazard(
MI))
191 return std::numeric_limits<int>::max();
194 int GCNHazardRecognizer::getWaitStatesSinceDef(
199 return IsHazardDef(
MI) &&
MI->modifiesRegister(Reg, TRI);
202 return getWaitStatesSince(IsHazardFn);
205 int GCNHazardRecognizer::getWaitStatesSinceSetReg(
212 return getWaitStatesSince(IsHazardFn);
220 std::set<unsigned> &Set) {
223 Set.insert(
Op.getReg());
227 int GCNHazardRecognizer::checkSMEMSoftClauseHazards(
MachineInstr *SMEM) {
242 std::set<unsigned> ClauseDefs;
243 std::set<unsigned> ClauseUses;
256 if (ClauseDefs.empty())
268 std::vector<unsigned> Result(std::max(ClauseDefs.size(), ClauseUses.size()));
269 std::vector<unsigned>::iterator
End;
271 End = std::set_intersection(ClauseDefs.begin(), ClauseDefs.end(),
272 ClauseUses.begin(), ClauseUses.end(), Result.begin());
276 if (End != Result.begin())
285 int WaitStatesNeeded = 0;
287 WaitStatesNeeded = checkSMEMSoftClauseHazards(SMRD);
291 return WaitStatesNeeded;
295 int SmrdSgprWaitStates = 4;
301 int WaitStatesNeededForUse =
302 SmrdSgprWaitStates - getWaitStatesSinceDef(
Use.getReg(), IsHazardDefFn);
303 WaitStatesNeeded = std::max(WaitStatesNeeded, WaitStatesNeededForUse);
305 return WaitStatesNeeded;
308 int GCNHazardRecognizer::checkVMEMHazards(
MachineInstr* VMEM) {
318 int VmemSgprWaitStates = 5;
319 int WaitStatesNeeded = 0;
326 int WaitStatesNeededForUse =
327 VmemSgprWaitStates - getWaitStatesSinceDef(
Use.getReg(), IsHazardDefFn);
328 WaitStatesNeeded = std::max(WaitStatesNeeded, WaitStatesNeededForUse);
330 return WaitStatesNeeded;
337 int DppVgprWaitStates = 2;
338 int WaitStatesNeeded = 0;
343 int WaitStatesNeededForUse =
344 DppVgprWaitStates - getWaitStatesSinceDef(
Use.getReg());
345 WaitStatesNeeded = std::max(WaitStatesNeeded, WaitStatesNeededForUse);
348 return WaitStatesNeeded;
351 int GCNHazardRecognizer::checkDivFMasHazards(
MachineInstr *DivFMas) {
356 const int DivFMasWaitStates = 4;
358 int WaitStatesNeeded = getWaitStatesSinceDef(AMDGPU::VCC, IsHazardDefFn);
360 return DivFMasWaitStates - WaitStatesNeeded;
363 int GCNHazardRecognizer::checkGetRegHazards(
MachineInstr *GetRegInstr) {
365 unsigned GetRegHWReg =
getHWReg(TII, *GetRegInstr);
367 const int GetRegWaitStates = 2;
371 int WaitStatesNeeded = getWaitStatesSinceSetReg(IsHazardFn);
373 return GetRegWaitStates - WaitStatesNeeded;
376 int GCNHazardRecognizer::checkSetRegHazards(
MachineInstr *SetRegInstr) {
378 unsigned HWReg =
getHWReg(TII, *SetRegInstr);
380 const int SetRegWaitStates =
385 int WaitStatesNeeded = getWaitStatesSinceSetReg(IsHazardFn);
386 return SetRegWaitStates - WaitStatesNeeded;
389 int GCNHazardRecognizer::createsVALUHazard(
const MachineInstr &
MI) {
414 (!SOffset || !SOffset->
isReg()))
447 const int VALUWaitStates = 1;
448 int WaitStatesNeeded = 0;
453 unsigned Reg =
Def.getReg();
455 int DataIdx = createsVALUHazard(*MI);
456 return DataIdx >= 0 &&
459 int WaitStatesNeededForDef =
460 VALUWaitStates - getWaitStatesSince(IsHazardFn);
461 WaitStatesNeeded = std::max(WaitStatesNeeded, WaitStatesNeededForDef);
463 return WaitStatesNeeded;
466 int GCNHazardRecognizer::checkRWLaneHazards(
MachineInstr *RWLane) {
478 unsigned LaneSelectReg = LaneSelectOp->
getReg();
483 const int RWLaneWaitStates = 4;
484 int WaitStatesSince = getWaitStatesSinceDef(LaneSelectReg, IsHazardFn);
485 return RWLaneWaitStates - WaitStatesSince;
488 int GCNHazardRecognizer::checkRFEHazards(
MachineInstr *RFE) {
495 const int RFEWaitStates = 1;
500 int WaitStatesNeeded = getWaitStatesSinceSetReg(IsHazardFn);
501 return RFEWaitStates - WaitStatesNeeded;
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
AMDGPU specific subclass of TargetSubtarget.
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
bool isVGPR(const MachineRegisterInfo &MRI, unsigned Reg) const
Describe properties that are true of each instruction in the target description file.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
MachineInstr * getInstr() const
getInstr - Return the representative MachineInstr for this SUnit.
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.
static bool isRFE(unsigned Opcode)
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
static bool isSMRD(const MachineInstr &MI)
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)
const HexagonInstrInfo * TII
static bool isMIMG(const MachineInstr &MI)
A Use represents the edge between a Value definition and its users.
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.
unsigned getMaxLookAhead() const
static bool isVALU(const MachineInstr &MI)
static bool isMUBUF(const MachineInstr &MI)
static bool isSSetReg(unsigned Opcode)
unsigned PreEmitNoops(SUnit *SU) override
PreEmitNoops - This callback is invoked prior to emitting an instruction.
Generation getGeneration() const
const SIRegisterInfo & getRegisterInfo() const
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.
const MachineBasicBlock * getParent() const
unsigned MaxLookAhead
MaxLookAhead - Indicate the number of cycles in the scoreboard state.
static bool isDPP(const MachineInstr &MI)
static void addRegsToSet(iterator_range< MachineInstr::const_mop_iterator > Ops, std::set< unsigned > &Set)
unsigned const MachineRegisterInfo * MRI
const MachineOperand & getOperand(unsigned i) const
iterator_range< mop_iterator > defs()
Returns a range over all explicit operands that are register definitions.
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.
Interface definition for SIInstrInfo.
static bool isMTBUF(const MachineInstr &MI)
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.
unsigned getNumWaitStates(const MachineInstr &MI) const
Return the number of wait states that result from executing this instruction.
static bool isVMEM(const MachineInstr &MI)
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isSGetReg(unsigned Opcode)
const MCOperandInfo * OpInfo
static unsigned getHWReg(const SIInstrInfo *TII, const MachineInstr &RegInstr)
SUnit - Scheduling unit. This is a node in the scheduling DAG.
bool has12DWordStoreHazard() const
static bool isDivFMas(unsigned Opcode)