25 std::unique_ptr<Instruction> &Inst,
const MCInst &MCI) {
27 case AMDGPU::S_WAITCNT:
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_EXPCNT_gfx10:
33 case AMDGPU::S_WAITCNT_LGKMCNT_gfx10:
34 case AMDGPU::S_WAITCNT_VMCNT_gfx10:
35 case AMDGPU::S_WAITCNT_VSCNT_gfx10:
36 case AMDGPU::S_WAITCNT_gfx10:
37 case AMDGPU::S_WAITCNT_gfx6_gfx7:
38 case AMDGPU::S_WAITCNT_vi:
39 return processWaitCnt(Inst, MCI);
45void AMDGPUInstrPostProcess::processWaitCnt(std::unique_ptr<Instruction> &Inst,
52 }
else if (MCOp.
isImm()) {
64 generateWaitCntInfo();
79 case AMDGPU::S_WAITCNT:
80 case AMDGPU::S_WAITCNT_EXPCNT:
81 case AMDGPU::S_WAITCNT_LGKMCNT:
82 case AMDGPU::S_WAITCNT_VMCNT:
83 case AMDGPU::S_WAITCNT_VSCNT:
84 case AMDGPU::S_WAITCNT_EXPCNT_gfx10:
85 case AMDGPU::S_WAITCNT_LGKMCNT_gfx10:
86 case AMDGPU::S_WAITCNT_VMCNT_gfx10:
87 case AMDGPU::S_WAITCNT_VSCNT_gfx10:
88 case AMDGPU::S_WAITCNT_gfx10:
89 case AMDGPU::S_WAITCNT_gfx6_gfx7:
90 case AMDGPU::S_WAITCNT_vi:
95 return handleWaitCnt(IssuedInst,
IR);
108 unsigned Lgkmcnt = 31;
110 unsigned CurrVmcnt = 0;
111 unsigned CurrExpcnt = 0;
112 unsigned CurrLgkmcnt = 0;
113 unsigned CurrVscnt = 0;
114 unsigned CyclesToWaitVm = ~0U;
115 unsigned CyclesToWaitExp = ~0U;
116 unsigned CyclesToWaitLgkm = ~0U;
117 unsigned CyclesToWaitVs = ~0U;
119 computeWaitCnt(
IR, Vmcnt, Expcnt, Lgkmcnt, Vscnt);
123 for (
const InstRef &PrevIR : IssuedInst) {
124 const Instruction &PrevInst = *PrevIR.getInstruction();
125 const unsigned PrevInstIndex = PrevIR.getSourceIndex() %
SrcMgr.
size();
126 const WaitCntInfo &PrevInstWaitInfo = InstrWaitCntInfo[PrevInstIndex];
129 "We should know how many cycles are left for this instruction");
130 if (PrevInstWaitInfo.
VmCnt) {
132 if ((
unsigned)CyclesLeft < CyclesToWaitVm)
133 CyclesToWaitVm = CyclesLeft;
135 if (PrevInstWaitInfo.
ExpCnt) {
137 if ((
unsigned)CyclesLeft < CyclesToWaitExp)
138 CyclesToWaitExp = CyclesLeft;
140 if (PrevInstWaitInfo.
LgkmCnt) {
142 if ((
unsigned)CyclesLeft < CyclesToWaitLgkm)
143 CyclesToWaitLgkm = CyclesLeft;
145 if (PrevInstWaitInfo.
VsCnt) {
147 if ((
unsigned)CyclesLeft < CyclesToWaitVs)
148 CyclesToWaitVs = CyclesLeft;
152 unsigned CyclesToWait = ~0
U;
153 if (CurrVmcnt > Vmcnt && CyclesToWaitVm < CyclesToWait)
154 CyclesToWait = CyclesToWaitVm;
155 if (CurrExpcnt > Expcnt && CyclesToWaitExp < CyclesToWait)
156 CyclesToWait = CyclesToWaitExp;
157 if (CurrLgkmcnt > Lgkmcnt && CyclesToWaitLgkm < CyclesToWait)
158 CyclesToWait = CyclesToWaitLgkm;
159 if (CurrVscnt > Vscnt && CyclesToWaitVs < CyclesToWait)
160 CyclesToWait = CyclesToWaitVs;
168 if (CyclesToWait == ~0U)
173void AMDGPUCustomBehaviour::computeWaitCnt(
const InstRef &
IR,
unsigned &Vmcnt,
174 unsigned &Expcnt,
unsigned &Lgkmcnt,
181 case AMDGPU::S_WAITCNT_EXPCNT_gfx10:
182 case AMDGPU::S_WAITCNT_LGKMCNT_gfx10:
183 case AMDGPU::S_WAITCNT_VMCNT_gfx10:
184 case AMDGPU::S_WAITCNT_VSCNT_gfx10: {
190 assert(OpReg && OpReg->
isReg() &&
"First operand should be a register.");
191 assert(OpImm && OpImm->
isImm() &&
"Second operand should be an immediate.");
192 if (OpReg->
getReg() != AMDGPU::SGPR_NULL) {
198 <<
"ignored. So the wait may not be accurate.\n";
204 case AMDGPU::S_WAITCNT_EXPCNT_gfx10:
207 case AMDGPU::S_WAITCNT_LGKMCNT_gfx10:
208 Lgkmcnt = OpImm->
getImm();
210 case AMDGPU::S_WAITCNT_VMCNT_gfx10:
213 case AMDGPU::S_WAITCNT_VSCNT_gfx10:
219 case AMDGPU::S_WAITCNT_gfx10:
220 case AMDGPU::S_WAITCNT_gfx6_gfx7:
221 case AMDGPU::S_WAITCNT_vi:
222 unsigned WaitCnt = Inst.
getOperand(0)->getImm();
228void AMDGPUCustomBehaviour::generateWaitCntInfo() {
243 const std::unique_ptr<Instruction> &Inst = EN.value();
244 unsigned Index = EN.index();
245 unsigned Opcode = Inst->getOpcode();
249 InstrWaitCntInfo[
Index].LgkmCnt =
true;
250 if (isAlwaysGDS(Opcode) || hasModifiersSet(Inst, AMDGPU::OpName::gds))
251 InstrWaitCntInfo[
Index].ExpCnt =
true;
257 InstrWaitCntInfo[
Index].LgkmCnt =
true;
259 InstrWaitCntInfo[
Index].VmCnt =
true;
261 InstrWaitCntInfo[
Index].VmCnt =
true;
263 InstrWaitCntInfo[
Index].VsCnt =
true;
266 InstrWaitCntInfo[
Index].VmCnt =
true;
271 InstrWaitCntInfo[
Index].VmCnt =
true;
273 InstrWaitCntInfo[
Index].VsCnt =
true;
281 InstrWaitCntInfo[
Index].ExpCnt =
true;
283 InstrWaitCntInfo[
Index].LgkmCnt =
true;
285 InstrWaitCntInfo[
Index].ExpCnt =
true;
288 case AMDGPU::S_SENDMSG:
289 case AMDGPU::S_SENDMSGHALT:
290 case AMDGPU::S_MEMTIME:
291 case AMDGPU::S_MEMREALTIME:
292 InstrWaitCntInfo[
Index].LgkmCnt =
true;
300bool AMDGPUCustomBehaviour::isVMEM(
const MCInstrDesc &MCID) {
307bool AMDGPUCustomBehaviour::hasModifiersSet(
308 const std::unique_ptr<Instruction> &Inst,
unsigned OpName)
const {
314 if (
Op ==
nullptr || !
Op->isImm() || !
Op->getImm())
321bool AMDGPUCustomBehaviour::isGWS(
uint16_t Opcode)
const {
327bool AMDGPUCustomBehaviour::isAlwaysGDS(
uint16_t Opcode)
const {
328 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.
unsigned 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 are tuples (A,...
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.