25 std::unique_ptr<Instruction> &Inst,
const MCInst &MCI) {
27 case AMDGPU::S_WAITCNT:
28 case AMDGPU::S_WAITCNT_soft:
29 case AMDGPU::S_WAITCNT_EXPCNT:
30 case AMDGPU::S_WAITCNT_LGKMCNT:
31 case AMDGPU::S_WAITCNT_VMCNT:
32 case AMDGPU::S_WAITCNT_VSCNT:
33 case AMDGPU::S_WAITCNT_VSCNT_soft:
34 case AMDGPU::S_WAITCNT_EXPCNT_gfx10:
35 case AMDGPU::S_WAITCNT_LGKMCNT_gfx10:
36 case AMDGPU::S_WAITCNT_VMCNT_gfx10:
37 case AMDGPU::S_WAITCNT_VSCNT_gfx10:
38 case AMDGPU::S_WAITCNT_gfx10:
39 case AMDGPU::S_WAITCNT_gfx6_gfx7:
40 case AMDGPU::S_WAITCNT_vi:
41 return processWaitCnt(Inst, MCI);
47void AMDGPUInstrPostProcess::processWaitCnt(std::unique_ptr<Instruction> &Inst,
54 }
else if (MCOp.
isImm()) {
66 generateWaitCntInfo();
81 case AMDGPU::S_WAITCNT:
82 case AMDGPU::S_WAITCNT_soft:
83 case AMDGPU::S_WAITCNT_EXPCNT:
84 case AMDGPU::S_WAITCNT_LGKMCNT:
85 case AMDGPU::S_WAITCNT_VMCNT:
86 case AMDGPU::S_WAITCNT_VSCNT:
87 case AMDGPU::S_WAITCNT_VSCNT_soft:
88 case AMDGPU::S_WAITCNT_EXPCNT_gfx10:
89 case AMDGPU::S_WAITCNT_LGKMCNT_gfx10:
90 case AMDGPU::S_WAITCNT_VMCNT_gfx10:
91 case AMDGPU::S_WAITCNT_VSCNT_gfx10:
92 case AMDGPU::S_WAITCNT_gfx10:
93 case AMDGPU::S_WAITCNT_gfx6_gfx7:
94 case AMDGPU::S_WAITCNT_vi:
99 return handleWaitCnt(IssuedInst,
IR);
112 unsigned Lgkmcnt = 31;
114 unsigned CurrVmcnt = 0;
115 unsigned CurrExpcnt = 0;
116 unsigned CurrLgkmcnt = 0;
117 unsigned CurrVscnt = 0;
118 unsigned CyclesToWaitVm = ~0U;
119 unsigned CyclesToWaitExp = ~0U;
120 unsigned CyclesToWaitLgkm = ~0U;
121 unsigned CyclesToWaitVs = ~0U;
123 computeWaitCnt(
IR, Vmcnt, Expcnt, Lgkmcnt, Vscnt);
127 for (
const InstRef &PrevIR : IssuedInst) {
128 const Instruction &PrevInst = *PrevIR.getInstruction();
129 const unsigned PrevInstIndex = PrevIR.getSourceIndex() %
SrcMgr.
size();
130 const WaitCntInfo &PrevInstWaitInfo = InstrWaitCntInfo[PrevInstIndex];
133 "We should know how many cycles are left for this instruction");
134 if (PrevInstWaitInfo.
VmCnt) {
136 if ((
unsigned)CyclesLeft < CyclesToWaitVm)
137 CyclesToWaitVm = CyclesLeft;
139 if (PrevInstWaitInfo.
ExpCnt) {
141 if ((
unsigned)CyclesLeft < CyclesToWaitExp)
142 CyclesToWaitExp = CyclesLeft;
144 if (PrevInstWaitInfo.
LgkmCnt) {
146 if ((
unsigned)CyclesLeft < CyclesToWaitLgkm)
147 CyclesToWaitLgkm = CyclesLeft;
149 if (PrevInstWaitInfo.
VsCnt) {
151 if ((
unsigned)CyclesLeft < CyclesToWaitVs)
152 CyclesToWaitVs = CyclesLeft;
156 unsigned CyclesToWait = ~0
U;
157 if (CurrVmcnt > Vmcnt && CyclesToWaitVm < CyclesToWait)
158 CyclesToWait = CyclesToWaitVm;
159 if (CurrExpcnt > Expcnt && CyclesToWaitExp < CyclesToWait)
160 CyclesToWait = CyclesToWaitExp;
161 if (CurrLgkmcnt > Lgkmcnt && CyclesToWaitLgkm < CyclesToWait)
162 CyclesToWait = CyclesToWaitLgkm;
163 if (CurrVscnt > Vscnt && CyclesToWaitVs < CyclesToWait)
164 CyclesToWait = CyclesToWaitVs;
172 if (CyclesToWait == ~0U)
177void AMDGPUCustomBehaviour::computeWaitCnt(
const InstRef &
IR,
unsigned &Vmcnt,
178 unsigned &Expcnt,
unsigned &Lgkmcnt,
185 case AMDGPU::S_WAITCNT_EXPCNT_gfx10:
186 case AMDGPU::S_WAITCNT_LGKMCNT_gfx10:
187 case AMDGPU::S_WAITCNT_VMCNT_gfx10:
188 case AMDGPU::S_WAITCNT_VSCNT_gfx10: {
194 assert(OpReg && OpReg->
isReg() &&
"First operand should be a register.");
195 assert(OpImm && OpImm->
isImm() &&
"Second operand should be an immediate.");
196 if (OpReg->
getReg() != AMDGPU::SGPR_NULL) {
202 <<
"ignored. So the wait may not be accurate.\n";
208 case AMDGPU::S_WAITCNT_EXPCNT_gfx10:
211 case AMDGPU::S_WAITCNT_LGKMCNT_gfx10:
212 Lgkmcnt = OpImm->
getImm();
214 case AMDGPU::S_WAITCNT_VMCNT_gfx10:
217 case AMDGPU::S_WAITCNT_VSCNT_gfx10:
223 case AMDGPU::S_WAITCNT_gfx10:
224 case AMDGPU::S_WAITCNT_gfx6_gfx7:
225 case AMDGPU::S_WAITCNT_vi:
226 unsigned WaitCnt = Inst.
getOperand(0)->getImm();
232void AMDGPUCustomBehaviour::generateWaitCntInfo() {
247 const std::unique_ptr<Instruction> &Inst = EN.value();
248 unsigned Index = EN.index();
249 unsigned Opcode = Inst->getOpcode();
253 InstrWaitCntInfo[
Index].LgkmCnt =
true;
254 if (isAlwaysGDS(Opcode) || hasModifiersSet(Inst, AMDGPU::OpName::gds))
255 InstrWaitCntInfo[
Index].ExpCnt =
true;
261 InstrWaitCntInfo[
Index].LgkmCnt =
true;
263 InstrWaitCntInfo[
Index].VmCnt =
true;
265 InstrWaitCntInfo[
Index].VmCnt =
true;
267 InstrWaitCntInfo[
Index].VsCnt =
true;
270 InstrWaitCntInfo[
Index].VmCnt =
true;
275 InstrWaitCntInfo[
Index].VmCnt =
true;
277 InstrWaitCntInfo[
Index].VsCnt =
true;
285 InstrWaitCntInfo[
Index].ExpCnt =
true;
287 InstrWaitCntInfo[
Index].LgkmCnt =
true;
289 InstrWaitCntInfo[
Index].ExpCnt =
true;
292 case AMDGPU::S_SENDMSG:
293 case AMDGPU::S_SENDMSGHALT:
294 case AMDGPU::S_MEMTIME:
295 case AMDGPU::S_MEMREALTIME:
296 InstrWaitCntInfo[
Index].LgkmCnt =
true;
304bool AMDGPUCustomBehaviour::isVMEM(
const MCInstrDesc &MCID) {
311bool AMDGPUCustomBehaviour::hasModifiersSet(
312 const std::unique_ptr<Instruction> &Inst,
unsigned OpName)
const {
318 if (
Op ==
nullptr || !
Op->isImm() || !
Op->getImm())
325bool AMDGPUCustomBehaviour::isGWS(
uint16_t Opcode)
const {
331bool AMDGPUCustomBehaviour::isAlwaysGDS(
uint16_t Opcode)
const {
332 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.