1303231Sdim//===-- GCNHazardRecognizers.h - GCN Hazard Recognizers ---------*- C++ -*-===// 2303231Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6303231Sdim// 7303231Sdim//===----------------------------------------------------------------------===// 8303231Sdim// 9303231Sdim// This file defines hazard recognizers for scheduling on GCN processors. 10303231Sdim// 11303231Sdim//===----------------------------------------------------------------------===// 12303231Sdim 13303231Sdim#ifndef LLVM_LIB_TARGET_AMDGPUHAZARDRECOGNIZERS_H 14303231Sdim#define LLVM_LIB_TARGET_AMDGPUHAZARDRECOGNIZERS_H 15303231Sdim 16327952Sdim#include "llvm/ADT/BitVector.h" 17303231Sdim#include "llvm/ADT/STLExtras.h" 18303231Sdim#include "llvm/CodeGen/ScheduleHazardRecognizer.h" 19353358Sdim#include "llvm/CodeGen/TargetSchedule.h" 20303231Sdim#include <list> 21303231Sdim 22303231Sdimnamespace llvm { 23303231Sdim 24303231Sdimclass MachineFunction; 25303231Sdimclass MachineInstr; 26327952Sdimclass MachineOperand; 27327952Sdimclass MachineRegisterInfo; 28303231Sdimclass ScheduleDAG; 29303231Sdimclass SIInstrInfo; 30327952Sdimclass SIRegisterInfo; 31341825Sdimclass GCNSubtarget; 32303231Sdim 33303231Sdimclass GCNHazardRecognizer final : public ScheduleHazardRecognizer { 34353358Sdimpublic: 35353358Sdim typedef function_ref<bool(MachineInstr *)> IsHazardFn; 36353358Sdim 37353358Sdimprivate: 38353358Sdim // Distinguish if we are called from scheduler or hazard recognizer 39353358Sdim bool IsHazardRecognizerMode; 40353358Sdim 41303231Sdim // This variable stores the instruction that has been emitted this cycle. It 42303231Sdim // will be added to EmittedInstrs, when AdvanceCycle() or RecedeCycle() is 43303231Sdim // called. 44303231Sdim MachineInstr *CurrCycleInstr; 45303231Sdim std::list<MachineInstr*> EmittedInstrs; 46303231Sdim const MachineFunction &MF; 47341825Sdim const GCNSubtarget &ST; 48321369Sdim const SIInstrInfo &TII; 49327952Sdim const SIRegisterInfo &TRI; 50353358Sdim TargetSchedModel TSchedModel; 51303231Sdim 52327952Sdim /// RegUnits of uses in the current soft memory clause. 53327952Sdim BitVector ClauseUses; 54327952Sdim 55327952Sdim /// RegUnits of defs in the current soft memory clause. 56327952Sdim BitVector ClauseDefs; 57327952Sdim 58327952Sdim void resetClause() { 59327952Sdim ClauseUses.reset(); 60327952Sdim ClauseDefs.reset(); 61327952Sdim } 62327952Sdim 63327952Sdim void addClauseInst(const MachineInstr &MI); 64327952Sdim 65353358Sdim // Advance over a MachineInstr bundle. Look for hazards in the bundled 66353358Sdim // instructions. 67353358Sdim void processBundle(); 68303231Sdim 69353358Sdim int getWaitStatesSince(IsHazardFn IsHazard, int Limit); 70353358Sdim int getWaitStatesSinceDef(unsigned Reg, IsHazardFn IsHazardDef, int Limit); 71353358Sdim int getWaitStatesSinceSetReg(IsHazardFn IsHazard, int Limit); 72353358Sdim 73327952Sdim int checkSoftClauseHazards(MachineInstr *SMEM); 74303231Sdim int checkSMRDHazards(MachineInstr *SMRD); 75303231Sdim int checkVMEMHazards(MachineInstr* VMEM); 76303231Sdim int checkDPPHazards(MachineInstr *DPP); 77314564Sdim int checkDivFMasHazards(MachineInstr *DivFMas); 78314564Sdim int checkGetRegHazards(MachineInstr *GetRegInstr); 79314564Sdim int checkSetRegHazards(MachineInstr *SetRegInstr); 80314564Sdim int createsVALUHazard(const MachineInstr &MI); 81314564Sdim int checkVALUHazards(MachineInstr *VALU); 82327952Sdim int checkVALUHazardsHelper(const MachineOperand &Def, const MachineRegisterInfo &MRI); 83314564Sdim int checkRWLaneHazards(MachineInstr *RWLane); 84314564Sdim int checkRFEHazards(MachineInstr *RFE); 85327952Sdim int checkInlineAsmHazards(MachineInstr *IA); 86321369Sdim int checkAnyInstHazards(MachineInstr *MI); 87321369Sdim int checkReadM0Hazards(MachineInstr *SMovRel); 88353358Sdim int checkNSAtoVMEMHazard(MachineInstr *MI); 89353358Sdim int checkFPAtomicToDenormModeHazard(MachineInstr *MI); 90353358Sdim void fixHazards(MachineInstr *MI); 91353358Sdim bool fixVcmpxPermlaneHazards(MachineInstr *MI); 92353358Sdim bool fixVMEMtoScalarWriteHazards(MachineInstr *MI); 93353358Sdim bool fixSMEMtoVectorWriteHazards(MachineInstr *MI); 94353358Sdim bool fixVcmpxExecWARHazard(MachineInstr *MI); 95353358Sdim bool fixLdsBranchVmemWARHazard(MachineInstr *MI); 96353358Sdim 97353358Sdim int checkMAIHazards(MachineInstr *MI); 98353358Sdim int checkMAILdStHazards(MachineInstr *MI); 99353358Sdim 100303231Sdimpublic: 101303231Sdim GCNHazardRecognizer(const MachineFunction &MF); 102303231Sdim // We can only issue one instruction per cycle. 103303231Sdim bool atIssueLimit() const override { return true; } 104303231Sdim void EmitInstruction(SUnit *SU) override; 105303231Sdim void EmitInstruction(MachineInstr *MI) override; 106303231Sdim HazardType getHazardType(SUnit *SU, int Stalls) override; 107303231Sdim void EmitNoop() override; 108303231Sdim unsigned PreEmitNoops(SUnit *SU) override; 109303231Sdim unsigned PreEmitNoops(MachineInstr *) override; 110353358Sdim unsigned PreEmitNoopsCommon(MachineInstr *); 111303231Sdim void AdvanceCycle() override; 112303231Sdim void RecedeCycle() override; 113303231Sdim}; 114303231Sdim 115303231Sdim} // end namespace llvm 116303231Sdim 117303231Sdim#endif //LLVM_LIB_TARGET_AMDGPUHAZARDRECOGNIZERS_H 118