24 std::unique_ptr<Instruction> &Inst,
const MCInst &MCI) {
26 case AMDGPU::S_WAITCNT:
27 case AMDGPU::S_WAITCNT_soft:
28 case AMDGPU::S_WAITCNT_EXPCNT:
29 case AMDGPU::S_WAITCNT_LGKMCNT:
30 case AMDGPU::S_WAITCNT_VMCNT:
31 case AMDGPU::S_WAITCNT_VSCNT:
32 case AMDGPU::S_WAITCNT_VSCNT_soft:
33 case AMDGPU::S_WAITCNT_EXPCNT_gfx10:
34 case AMDGPU::S_WAITCNT_LGKMCNT_gfx10:
35 case AMDGPU::S_WAITCNT_VMCNT_gfx10:
36 case AMDGPU::S_WAITCNT_VSCNT_gfx10:
37 case AMDGPU::S_WAITCNT_gfx10:
38 case AMDGPU::S_WAITCNT_gfx6_gfx7:
39 case AMDGPU::S_WAITCNT_vi:
40 return processWaitCnt(Inst, MCI);
46void AMDGPUInstrPostProcess::processWaitCnt(std::unique_ptr<Instruction> &Inst,
53 }
else if (MCOp.
isImm()) {
65 generateWaitCntInfo();
80 case AMDGPU::S_WAITCNT:
81 case AMDGPU::S_WAITCNT_soft:
82 case AMDGPU::S_WAITCNT_EXPCNT:
83 case AMDGPU::S_WAITCNT_LGKMCNT:
84 case AMDGPU::S_WAITCNT_VMCNT:
85 case AMDGPU::S_WAITCNT_VSCNT:
86 case AMDGPU::S_WAITCNT_VSCNT_soft:
87 case AMDGPU::S_WAITCNT_EXPCNT_gfx10:
88 case AMDGPU::S_WAITCNT_LGKMCNT_gfx10:
89 case AMDGPU::S_WAITCNT_VMCNT_gfx10:
90 case AMDGPU::S_WAITCNT_VSCNT_gfx10:
91 case AMDGPU::S_WAITCNT_gfx10:
92 case AMDGPU::S_WAITCNT_gfx6_gfx7:
93 case AMDGPU::S_WAITCNT_vi:
98 return handleWaitCnt(IssuedInst,
IR);
111 unsigned Lgkmcnt = 31;
113 unsigned CurrVmcnt = 0;
114 unsigned CurrExpcnt = 0;
115 unsigned CurrLgkmcnt = 0;
116 unsigned CurrVscnt = 0;
117 unsigned CyclesToWaitVm = ~0U;
118 unsigned CyclesToWaitExp = ~0U;
119 unsigned CyclesToWaitLgkm = ~0U;
120 unsigned CyclesToWaitVs = ~0U;
122 computeWaitCnt(
IR, Vmcnt, Expcnt, Lgkmcnt, Vscnt);
126 for (
const InstRef &PrevIR : IssuedInst) {
127 const Instruction &PrevInst = *PrevIR.getInstruction();
128 const unsigned PrevInstIndex = PrevIR.getSourceIndex() %
SrcMgr.
size();
129 const WaitCntInfo &PrevInstWaitInfo = InstrWaitCntInfo[PrevInstIndex];
132 "We should know how many cycles are left for this instruction");
133 if (PrevInstWaitInfo.
VmCnt) {
135 if ((
unsigned)CyclesLeft < CyclesToWaitVm)
136 CyclesToWaitVm = CyclesLeft;
138 if (PrevInstWaitInfo.
ExpCnt) {
140 if ((
unsigned)CyclesLeft < CyclesToWaitExp)
141 CyclesToWaitExp = CyclesLeft;
143 if (PrevInstWaitInfo.
LgkmCnt) {
145 if ((
unsigned)CyclesLeft < CyclesToWaitLgkm)
146 CyclesToWaitLgkm = CyclesLeft;
148 if (PrevInstWaitInfo.
VsCnt) {
150 if ((
unsigned)CyclesLeft < CyclesToWaitVs)
151 CyclesToWaitVs = CyclesLeft;
155 unsigned CyclesToWait = ~0
U;
156 if (CurrVmcnt > Vmcnt && CyclesToWaitVm < CyclesToWait)
157 CyclesToWait = CyclesToWaitVm;
158 if (CurrExpcnt > Expcnt && CyclesToWaitExp < CyclesToWait)
159 CyclesToWait = CyclesToWaitExp;
160 if (CurrLgkmcnt > Lgkmcnt && CyclesToWaitLgkm < CyclesToWait)
161 CyclesToWait = CyclesToWaitLgkm;
162 if (CurrVscnt > Vscnt && CyclesToWaitVs < CyclesToWait)
163 CyclesToWait = CyclesToWaitVs;
171 if (CyclesToWait == ~0U)
176void AMDGPUCustomBehaviour::computeWaitCnt(
const InstRef &
IR,
unsigned &Vmcnt,
177 unsigned &Expcnt,
unsigned &Lgkmcnt,
184 case AMDGPU::S_WAITCNT_EXPCNT_gfx10:
185 case AMDGPU::S_WAITCNT_LGKMCNT_gfx10:
186 case AMDGPU::S_WAITCNT_VMCNT_gfx10:
187 case AMDGPU::S_WAITCNT_VSCNT_gfx10: {
193 assert(OpReg && OpReg->
isReg() &&
"First operand should be a register.");
194 assert(OpImm && OpImm->
isImm() &&
"Second operand should be an immediate.");
195 if (OpReg->
getReg() != AMDGPU::SGPR_NULL) {
201 <<
"ignored. So the wait may not be accurate.\n";
207 case AMDGPU::S_WAITCNT_EXPCNT_gfx10:
210 case AMDGPU::S_WAITCNT_LGKMCNT_gfx10:
211 Lgkmcnt = OpImm->
getImm();
213 case AMDGPU::S_WAITCNT_VMCNT_gfx10:
216 case AMDGPU::S_WAITCNT_VSCNT_gfx10:
222 case AMDGPU::S_WAITCNT_gfx10:
223 case AMDGPU::S_WAITCNT_gfx6_gfx7:
224 case AMDGPU::S_WAITCNT_vi:
225 unsigned WaitCnt = Inst.
getOperand(0)->getImm();
231void AMDGPUCustomBehaviour::generateWaitCntInfo() {
246 const std::unique_ptr<Instruction> &Inst = EN.value();
247 unsigned Index = EN.index();
248 unsigned Opcode = Inst->getOpcode();
252 InstrWaitCntInfo[
Index].LgkmCnt =
true;
253 if (isAlwaysGDS(Opcode) || hasModifiersSet(Inst, AMDGPU::OpName::gds))
254 InstrWaitCntInfo[
Index].ExpCnt =
true;
260 InstrWaitCntInfo[
Index].LgkmCnt =
true;
262 InstrWaitCntInfo[
Index].VmCnt =
true;
264 InstrWaitCntInfo[
Index].VmCnt =
true;
266 InstrWaitCntInfo[
Index].VsCnt =
true;
269 InstrWaitCntInfo[
Index].VmCnt =
true;
274 InstrWaitCntInfo[
Index].VmCnt =
true;
276 InstrWaitCntInfo[
Index].VsCnt =
true;
284 InstrWaitCntInfo[
Index].ExpCnt =
true;
286 InstrWaitCntInfo[
Index].LgkmCnt =
true;
288 InstrWaitCntInfo[
Index].ExpCnt =
true;
291 case AMDGPU::S_SENDMSG:
292 case AMDGPU::S_SENDMSGHALT:
293 case AMDGPU::S_MEMTIME:
294 case AMDGPU::S_MEMREALTIME:
295 InstrWaitCntInfo[
Index].LgkmCnt =
true;
303bool AMDGPUCustomBehaviour::isVMEM(
const MCInstrDesc &MCID) {
310bool AMDGPUCustomBehaviour::hasModifiersSet(
311 const std::unique_ptr<Instruction> &Inst,
unsigned OpName)
const {
317 if (
Op ==
nullptr || !
Op->isImm() || !
Op->getImm())
324bool AMDGPUCustomBehaviour::isGWS(
uint16_t Opcode)
const {
330bool AMDGPUCustomBehaviour::isAlwaysGDS(
uint16_t Opcode)
const {
331 return Opcode == AMDGPU::DS_ORDERED_COUNT || isGWS(Opcode);
static CustomBehaviour * createAMDGPUCustomBehaviour(const MCSubtargetInfo &STI, const mca::SourceMgr &SrcMgr, const MCInstrInfo &MCII)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUTargetMCA()
Extern function to initialize the targets for the AMDGPU backend.
static InstrPostProcess * createAMDGPUInstrPostProcess(const MCSubtargetInfo &STI, const MCInstrInfo &MCII)
This file defines the AMDGPUCustomBehaviour class which inherits from CustomBehaviour.
Provides AMDGPU specific target descriptions.
#define LLVM_EXTERNAL_VISIBILITY
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Legalize the Machine IR a function s Machine IR
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const uint32_t IV[8]
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This class represents an Operation in the Expression.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Instances of this class represent a single low-level machine instruction.
unsigned getOpcode() const
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool mayLoad() const
Return true if this instruction could possibly read memory.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
Instances of this class represent operands of the MCInst class.
MCRegister getReg() const
Returns the register number.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
Value * getOperand(unsigned i) const
static raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
unsigned checkCustomHazard(ArrayRef< InstRef > IssuedInst, const InstRef &IR) override
This method is used to determine if an instruction should be allowed to be dispatched.
AMDGPUCustomBehaviour(const MCSubtargetInfo &STI, const mca::SourceMgr &SrcMgr, const MCInstrInfo &MCII)
void postProcessInstruction(std::unique_ptr< Instruction > &Inst, const MCInst &MCI) override
This method can be overriden by targets to modify the mca::Instruction object after it has been lower...
Class which can be overriden by targets to enforce instruction dependencies and behaviours that aren'...
const mca::SourceMgr & SrcMgr
const MCSubtargetInfo & STI
An InstRef contains both a SourceMgr index and Instruction pair.
Class which can be overriden by targets to modify the mca::Instruction objects before the pipeline st...
unsigned getOpcode() const
An instruction propagated through the simulated instruction pipeline.
int getCyclesLeft() const
A representation of an mca::Instruction operand for use in mca::CustomBehaviour.
unsigned getReg() const
Returns the register number.
static MCAOperand createImm(int64_t Val)
static MCAOperand createReg(unsigned Reg)
void decodeWaitcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned &Vmcnt, unsigned &Expcnt, unsigned &Lgkmcnt)
Decodes Vmcnt, Expcnt and Lgkmcnt from given Waitcnt for given isa Version, and writes decoded values...
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
IsaVersion getIsaVersion(StringRef GPU)
bool getMUBUFIsBufferInv(unsigned Opc)
constexpr int UNKNOWN_CYCLES
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Target & getTheR600Target()
The target for R600 GPUs.
Target & getTheGCNTarget()
The target for GCN GPUs.
DWARFExpression::Operation Op
Instruction set architecture version.
static void RegisterInstrPostProcess(Target &T, Target::InstrPostProcessCtorTy Fn)
RegisterInstrPostProcess - Register an InstrPostProcess implementation for the given target.
static void RegisterCustomBehaviour(Target &T, Target::CustomBehaviourCtorTy Fn)
RegisterCustomBehaviour - Register a CustomBehaviour implementation for the given target.
Abstracting the input code sequence (a sequence of MCInst) and assigning unique identifiers to every ...
virtual size_t size() const
(Fixed) Number of UniqueInst.
virtual ArrayRef< UniqueInst > getInstructions() const =0
Provides a fixed range of UniqueInst to iterate.