#include "GCNHazardRecognizer.h"
#include "GCNSubtarget.h"
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
#include "SIMachineFunctionInfo.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/TargetParser/TargetParser.h"
usingnamespacellvm;
namespace {
struct MFMAPaddingRatioParser : public cl::parser<unsigned> { … };
}
static cl::opt<unsigned, false, MFMAPaddingRatioParser>
MFMAPaddingRatio("amdgpu-mfma-padding-ratio", cl::init(0), cl::Hidden,
cl::desc("Fill a percentage of the latency between "
"neighboring MFMA with s_nops."));
static cl::opt<unsigned> MaxExhaustiveHazardSearch(
"amdgpu-max-exhaustive-hazard-search", cl::init(128), cl::Hidden,
cl::desc("Maximum function size for exhausive hazard search"));
static bool shouldRunLdsBranchVmemWARHazardFixup(const MachineFunction &MF,
const GCNSubtarget &ST);
GCNHazardRecognizer::GCNHazardRecognizer(const MachineFunction &MF)
: … { … }
void GCNHazardRecognizer::Reset() { … }
void GCNHazardRecognizer::EmitInstruction(SUnit *SU) { … }
void GCNHazardRecognizer::EmitInstruction(MachineInstr *MI) { … }
static bool isDivFMas(unsigned Opcode) { … }
static bool isSGetReg(unsigned Opcode) { … }
static bool isSSetReg(unsigned Opcode) { … }
static bool isRWLane(unsigned Opcode) { … }
static bool isRFE(unsigned Opcode) { … }
static bool isSMovRel(unsigned Opcode) { … }
static bool isDGEMM(unsigned Opcode) { … }
static bool isXDL(const GCNSubtarget &ST, const MachineInstr &MI) { … }
static bool isSendMsgTraceDataOrGDS(const SIInstrInfo &TII,
const MachineInstr &MI) { … }
static bool isPermlane(const MachineInstr &MI) { … }
static bool isLdsDma(const MachineInstr &MI) { … }
static unsigned getHWReg(const SIInstrInfo *TII, const MachineInstr &RegInstr) { … }
ScheduleHazardRecognizer::HazardType
GCNHazardRecognizer::getHazardType(SUnit *SU, int Stalls) { … }
static void insertNoopsInBundle(MachineInstr *MI, const SIInstrInfo &TII,
unsigned Quantity) { … }
unsigned
GCNHazardRecognizer::getMFMAPipelineWaitStates(const MachineInstr &MI) const { … }
void GCNHazardRecognizer::processBundle() { … }
void GCNHazardRecognizer::runOnInstruction(MachineInstr *MI) { … }
unsigned GCNHazardRecognizer::PreEmitNoops(MachineInstr *MI) { … }
unsigned GCNHazardRecognizer::PreEmitNoopsCommon(MachineInstr *MI) { … }
void GCNHazardRecognizer::EmitNoop() { … }
void GCNHazardRecognizer::AdvanceCycle() { … }
void GCNHazardRecognizer::RecedeCycle() { … }
using HazardFnResult = enum { … };
IsExpiredFn;
GetNumWaitStatesFn;
template <typename StateT>
static bool
hasHazard(StateT State,
function_ref<HazardFnResult(StateT &, const MachineInstr &)> IsHazard,
function_ref<void(StateT &, const MachineInstr &)> UpdateState,
const MachineBasicBlock *MBB,
MachineBasicBlock::const_reverse_instr_iterator I,
DenseSet<const MachineBasicBlock *> &Visited) { … }
static int getWaitStatesSince(
GCNHazardRecognizer::IsHazardFn IsHazard, const MachineBasicBlock *MBB,
MachineBasicBlock::const_reverse_instr_iterator I, int WaitStates,
IsExpiredFn IsExpired, DenseSet<const MachineBasicBlock *> &Visited,
GetNumWaitStatesFn GetNumWaitStates = SIInstrInfo::getNumWaitStates) { … }
static int getWaitStatesSince(GCNHazardRecognizer::IsHazardFn IsHazard,
const MachineInstr *MI, IsExpiredFn IsExpired) { … }
int GCNHazardRecognizer::getWaitStatesSince(IsHazardFn IsHazard, int Limit) { … }
int GCNHazardRecognizer::getWaitStatesSinceDef(unsigned Reg,
IsHazardFn IsHazardDef,
int Limit) { … }
int GCNHazardRecognizer::getWaitStatesSinceSetReg(IsHazardFn IsHazard,
int Limit) { … }
static void addRegUnits(const SIRegisterInfo &TRI, BitVector &BV,
MCRegister Reg) { … }
static void addRegsToSet(const SIRegisterInfo &TRI,
iterator_range<MachineInstr::const_mop_iterator> Ops,
BitVector &DefSet, BitVector &UseSet) { … }
void GCNHazardRecognizer::addClauseInst(const MachineInstr &MI) { … }
static bool breaksSMEMSoftClause(MachineInstr *MI) { … }
static bool breaksVMEMSoftClause(MachineInstr *MI) { … }
int GCNHazardRecognizer::checkSoftClauseHazards(MachineInstr *MEM) { … }
int GCNHazardRecognizer::checkSMRDHazards(MachineInstr *SMRD) { … }
int GCNHazardRecognizer::checkVMEMHazards(MachineInstr* VMEM) { … }
int GCNHazardRecognizer::checkDPPHazards(MachineInstr *DPP) { … }
int GCNHazardRecognizer::checkDivFMasHazards(MachineInstr *DivFMas) { … }
int GCNHazardRecognizer::checkGetRegHazards(MachineInstr *GetRegInstr) { … }
int GCNHazardRecognizer::checkSetRegHazards(MachineInstr *SetRegInstr) { … }
int GCNHazardRecognizer::createsVALUHazard(const MachineInstr &MI) { … }
int
GCNHazardRecognizer::checkVALUHazardsHelper(const MachineOperand &Def,
const MachineRegisterInfo &MRI) { … }
static const MachineOperand *
getDstSelForwardingOperand(const MachineInstr &MI, const GCNSubtarget &ST) { … }
static bool consumesDstSelForwardingOperand(const MachineInstr *VALU,
const MachineOperand *Dst,
const SIRegisterInfo *TRI) { … }
int GCNHazardRecognizer::checkVALUHazards(MachineInstr *VALU) { … }
int GCNHazardRecognizer::checkInlineAsmHazards(MachineInstr *IA) { … }
int GCNHazardRecognizer::checkRWLaneHazards(MachineInstr *RWLane) { … }
int GCNHazardRecognizer::checkRFEHazards(MachineInstr *RFE) { … }
int GCNHazardRecognizer::checkReadM0Hazards(MachineInstr *MI) { … }
void GCNHazardRecognizer::fixHazards(MachineInstr *MI) { … }
bool GCNHazardRecognizer::fixVcmpxPermlaneHazards(MachineInstr *MI) { … }
bool GCNHazardRecognizer::fixVMEMtoScalarWriteHazards(MachineInstr *MI) { … }
bool GCNHazardRecognizer::fixSMEMtoVectorWriteHazards(MachineInstr *MI) { … }
bool GCNHazardRecognizer::fixVcmpxExecWARHazard(MachineInstr *MI) { … }
static bool shouldRunLdsBranchVmemWARHazardFixup(const MachineFunction &MF,
const GCNSubtarget &ST) { … }
static bool isStoreCountWaitZero(const MachineInstr &I) { … }
bool GCNHazardRecognizer::fixLdsBranchVmemWARHazard(MachineInstr *MI) { … }
bool GCNHazardRecognizer::fixLdsDirectVALUHazard(MachineInstr *MI) { … }
bool GCNHazardRecognizer::fixLdsDirectVMEMHazard(MachineInstr *MI) { … }
bool GCNHazardRecognizer::fixVALUPartialForwardingHazard(MachineInstr *MI) { … }
bool GCNHazardRecognizer::fixVALUTransUseHazard(MachineInstr *MI) { … }
bool GCNHazardRecognizer::fixWMMAHazards(MachineInstr *MI) { … }
bool GCNHazardRecognizer::fixShift64HighRegBug(MachineInstr *MI) { … }
int GCNHazardRecognizer::checkNSAtoVMEMHazard(MachineInstr *MI) { … }
int GCNHazardRecognizer::checkFPAtomicToDenormModeHazard(MachineInstr *MI) { … }
int GCNHazardRecognizer::checkMAIHazards(MachineInstr *MI) { … }
int GCNHazardRecognizer::checkMFMAPadding(MachineInstr *MI) { … }
int GCNHazardRecognizer::checkMAIHazards908(MachineInstr *MI) { … }
static int
GFX940_XDL_N_PassWritesVGPROverlappedSMFMASrcCWaitStates(int NumPasses) { … }
static int
GFX940_SMFMA_N_PassWritesVGPROverlappedSMFMASrcCWaitStates(int NumPasses) { … }
static int
GFX940_SMFMA_N_PassWritesVGPROverlappedSrcABWaitStates(int NumPasses) { … }
static int GFX940_XDL_N_PassWritesVGPROverlappedSrcABWaitStates(int NumPasses) { … }
int GCNHazardRecognizer::checkMAIHazards90A(MachineInstr *MI) { … }
int GCNHazardRecognizer::checkMAILdStHazards(MachineInstr *MI) { … }
static int GFX940_SMFMA_N_PassWriteVgprVALUWawWaitStates(int NumPasses) { … }
static int GFX940_XDL_N_PassWriteVgprVALUWawWaitStates(int NumPasses) { … }
static int GFX940_XDL_N_PassWriteVgprVALUMemExpReadWaitStates(int NumPasses) { … }
static int GFX940_SMFMA_N_PassWriteVgprVALUMemExpReadWaitStates(int NumPasses) { … }
int GCNHazardRecognizer::checkMAIVALUHazards(MachineInstr *MI) { … }
bool GCNHazardRecognizer::ShouldPreferAnother(SUnit *SU) { … }
static void updateGetPCBundle(MachineInstr *NewMI) { … }
bool GCNHazardRecognizer::fixVALUMaskWriteHazard(MachineInstr *MI) { … }
static std::optional<unsigned> sgprPairNumber(Register Reg,
const SIRegisterInfo &TRI) { … }
void GCNHazardRecognizer::computeVALUHazardSGPRs(MachineFunction *MMF) { … }
bool GCNHazardRecognizer::fixVALUReadSGPRHazard(MachineInstr *MI) { … }
static bool ensureEntrySetPrio(MachineFunction *MF, int Priority,
const SIInstrInfo &TII) { … }
bool GCNHazardRecognizer::fixRequiredExportPriority(MachineInstr *MI) { … }