50 typedef Counters RegCounters[512];
51 typedef std::pair<unsigned, unsigned> RegInterval;
62 static const Counters WaitCounts;
65 static const Counters ZeroCounts;
77 RegCounters DefinedRegs;
80 unsigned ExpInstrTypesSeen;
85 bool LastInstWritesM0;
103 const Counters &Counts);
119 ExpInstrTypesSeen(0) { }
123 const char *getPassName()
const override {
124 return "SI insert wait instructions";
133 const Counters SIInsertWaits::WaitCounts = { { 15, 7, 7 } };
134 const Counters SIInsertWaits::ZeroCounts = { { 0, 0, 0 } };
137 return new SIInsertWaits(tm);
157 assert(Op.
isReg() &&
"First LGKM operand must be a register!");
160 unsigned Size = TRI->getMinimalPhysRegClass(Reg)->getSize();
161 Result.Named.LGKM = Size > 4 ? 2 : 1;
165 Result.Named.LGKM = 1;
169 Result.Named.LGKM = 0;
220 if (
I->isReg() &&
I->isUse())
229 if (!Op.
isReg() || !TRI->isInAllocatableClass(Op.
getReg()))
230 return std::make_pair(0, 0);
232 unsigned Reg = Op.
getReg();
233 unsigned Size = TRI->getMinimalPhysRegClass(Reg)->getSize();
238 Result.first = TRI->getEncodingValue(Reg);
239 Result.second = Result.first + Size / 4;
248 Counters Increment = getHwCounts(*I);
251 for (
unsigned i = 0; i < 3; ++i) {
252 LastIssued.Array[i] += Increment.Array[i];
253 Sum += Increment.Array[i];
258 LastOpcodeType = OTHER;
273 if ((LastOpcodeType == SMEM &&
TII->isSMRD(I->getOpcode())) ||
274 (LastOpcodeType == VMEM && Increment.Named.VM)) {
278 LastInstWritesM0 =
false;
281 if (
TII->isSMRD(I->getOpcode()))
282 LastOpcodeType = SMEM;
283 else if (Increment.Named.VM)
284 LastOpcodeType = VMEM;
288 if (Increment.Named.EXP) {
289 ExpInstrTypesSeen |= I->getOpcode() == AMDGPU::EXP ? 1 : 2;
292 for (
unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
295 if (!isOpRelevant(Op))
298 RegInterval
Interval = getRegInterval(Op);
299 for (
unsigned j = Interval.first; j < Interval.second; ++j) {
303 DefinedRegs[j] = LastIssued;
307 UsedRegs[j] = LastIssued;
317 if (I != MBB.
end() && I->getOpcode() == AMDGPU::S_ENDPGM)
327 Ordered[1] = ExpInstrTypesSeen == 3;
333 Counters Counts = WaitCounts;
336 bool NeedWait =
false;
338 for (
unsigned i = 0; i < 3; ++i) {
340 if (Required.Array[i] <= WaitedOn.Array[i])
346 unsigned Value = LastIssued.Array[i] - Required.Array[i];
349 Counts.Array[i] =
std::min(Value, WaitCounts.Array[i]);
355 WaitedOn.Array[i] = LastIssued.Array[i] - Counts.Array[i];
362 if (Counts.Named.EXP == 0)
363 ExpInstrTypesSeen = 0;
367 .addImm((Counts.Named.VM & 0xF) |
368 ((Counts.Named.EXP & 0x7) << 4) |
369 ((Counts.Named.LGKM & 0x7) << 8));
371 LastOpcodeType = OTHER;
372 LastInstWritesM0 =
false;
379 for (
unsigned i = 0; i < 3; ++i)
380 Dst.Array[i] = std::max(Dst.Array[i], Src.Array[i]);
383 Counters SIInsertWaits::handleOperands(
MachineInstr &MI) {
385 Counters Result = ZeroCounts;
398 RegInterval Interval = getRegInterval(Op);
399 for (
unsigned j = Interval.first; j < Interval.second; ++j) {
421 if (LastInstWritesM0 && I->getOpcode() == AMDGPU::S_SENDMSG) {
423 LastInstWritesM0 =
false;
428 LastInstWritesM0 =
false;
430 unsigned NumOperands = I->getNumOperands();
431 for (
unsigned i = 0; i < NumOperands; i++) {
435 LastInstWritesM0 =
true;
442 bool Changes =
false;
450 WaitedOn = ZeroCounts;
451 LastIssued = ZeroCounts;
452 LastOpcodeType = OTHER;
453 LastInstWritesM0 =
false;
455 memset(&UsedRegs, 0,
sizeof(UsedRegs));
456 memset(&DefinedRegs, 0,
sizeof(DefinedRegs));
466 if (I->getOpcode() == AMDGPU::S_BARRIER)
467 Changes |= insertWait(MBB, I, LastIssued);
469 Changes |= insertWait(MBB, I, handleOperands(*I));
471 pushInstruction(MBB, I);
472 handleSendMsg(MBB, I);
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
mop_iterator operands_end()
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
AMDGPU specific subclass of TargetSubtarget.
Interval Class - An Interval is a set of nodes defined such that every node in the interval has all o...
bool mayStore() const
Return true if this instruction could possibly modify memory.
iterator getFirstTerminator()
getFirstTerminator - returns an iterator to the first terminator instruction of this basic block...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
FunctionPass * createSIInsertWaits(TargetMachine &tm)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Reg
All possible values of the reg field in the ModR/M byte.
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
unsigned getNumOperands() const
Access to explicit operands of the instruction.
static void increaseCounters(Counters &Dst, const Counters &Src)
helper function for handleOperands
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bundle_iterator< MachineInstr, instr_iterator > iterator
const MachineOperand & getOperand(unsigned i) const
FunctionPass class - This class is used to implement most global optimizations.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Interface definition for SIInstrInfo.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
unsigned getReg() const
getReg - Returns the register number.
virtual const TargetInstrInfo * getInstrInfo() const
LLVM Value Representation.
mop_iterator operands_begin()
BasicBlockListType::iterator iterator
Primary interface to the complete machine description for the target machine.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
bool isIdenticalTo(const MachineOperand &Other) const
isIdenticalTo - Return true if this operand is identical to the specified operand.