35#define DEBUG_TYPE "machine-scheduler"
41 cl::desc(
"The OOO window for processor "
42 "resources during scheduling."),
45unsigned SystemZHazardRecognizer::
46getNumDecoderSlots(
SUnit *SU)
const {
52 "Only cracked instruction can have 2 uops.");
54 "Expanded instructions always group alone.");
56 "Expanded instructions fill the group(s).");
61unsigned SystemZHazardRecognizer::getCurrCycleIdx(
SUnit *SU)
const {
62 unsigned Idx = CurrGroupSize;
66 if (SU !=
nullptr && !fitsIntoCurrentGroup(SU)) {
67 if (Idx == 1 || Idx == 2)
69 else if (Idx == 4 || Idx == 5)
83 CurrGroupHas4RegOps =
false;
84 clearProcResCounters();
86 LastFPdOpCycleIdx = UINT_MAX;
87 LastEmittedMI =
nullptr;
92SystemZHazardRecognizer::fitsIntoCurrentGroup(
SUnit *SU)
const {
100 return (CurrGroupSize == 0);
103 assert ((CurrGroupSize < 2 || !CurrGroupHas4RegOps) &&
104 "Current decoder group is already full!");
105 if (CurrGroupSize == 2 && has4RegOps(SU->
getInstr()))
111 assert ((getNumDecoderSlots(SU) <= 1) && (CurrGroupSize < 3) &&
112 "Expected normal instruction to fit in non-full group!");
117bool SystemZHazardRecognizer::has4RegOps(
const MachineInstr *
MI)
const {
133void SystemZHazardRecognizer::nextGroup() {
134 if (CurrGroupSize == 0)
140 int NumGroups = ((CurrGroupSize > 3) ? (CurrGroupSize / 3) : 1);
141 assert((CurrGroupSize <= 3 || CurrGroupSize % 3 == 0) &&
142 "Current decoder group bad.");
146 CurrGroupHas4RegOps =
false;
148 GrpCount += ((unsigned) NumGroups);
151 for (
unsigned i = 0; i < SchedModel->getNumProcResourceKinds(); ++i)
152 ProcResourceCounters[i] = ((ProcResourceCounters[i] > NumGroups)
153 ? (ProcResourceCounters[i] - NumGroups)
157 if (CriticalResourceIdx != UINT_MAX &&
158 (ProcResourceCounters[CriticalResourceIdx] <=
160 CriticalResourceIdx = UINT_MAX;
167 OS <<
"SU(" << SU->
NodeNum <<
"):";
175 PI = SchedModel->getWriteProcResBegin(SC),
176 PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI) {
178 *SchedModel->getProcResource(PI->ProcResourceIdx);
179 std::string FU(PRD.
Name);
181 FU = FU.substr(FU.find(
'_') + 1);
182 size_t Pos = FU.find(
"Unit");
183 if (Pos != std::string::npos)
189 if (PI->ReleaseAtCycle> 1)
190 OS <<
"(" << PI->ReleaseAtCycle <<
"cyc)";
196 OS <<
"/GroupsAlone";
198 OS <<
"/BeginsGroup";
208 dbgs() <<
"++ " << Msg;
212 dbgs() <<
" <empty>\n";
215 dbgs() <<
" (" << CurrGroupSize <<
" decoder slot"
216 << (CurrGroupSize > 1 ?
"s":
"")
217 << (CurrGroupHas4RegOps ?
", 4RegOps" :
"")
225 for (
unsigned i = 0; i < SchedModel->getNumProcResourceKinds(); ++i)
226 if (ProcResourceCounters[i] > 0) {
234 dbgs() <<
"++ | Resource counters: ";
235 for (
unsigned i = 0; i < SchedModel->getNumProcResourceKinds(); ++i)
236 if (ProcResourceCounters[i] > 0)
237 dbgs() << SchedModel->getProcResource(i)->Name
238 <<
":" << ProcResourceCounters[i] <<
" ";
241 if (CriticalResourceIdx != UINT_MAX)
242 dbgs() <<
"++ | Critical resource: "
243 << SchedModel->getProcResource(CriticalResourceIdx)->Name
249 dbgs() <<
"++ | Current cycle index: "
250 << getCurrCycleIdx() <<
"\n";
252 if (LastFPdOpCycleIdx != UINT_MAX)
253 dbgs() <<
"++ | Last FPd cycle index: " << LastFPdOpCycleIdx <<
"\n";
258void SystemZHazardRecognizer::clearProcResCounters() {
260 CriticalResourceIdx = UINT_MAX;
264 return (
MI->isBranch() ||
MI->isReturn() ||
265 MI->getOpcode() == SystemZ::CondTrap);
278 if (!fitsIntoCurrentGroup(SU))
296 PI = SchedModel->getWriteProcResBegin(SC),
297 PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI) {
299 if (SchedModel->getProcResource(PI->ProcResourceIdx)->BufferSize == 1)
302 ProcResourceCounters[PI->ProcResourceIdx];
303 CurrCounter += PI->ReleaseAtCycle;
306 (CriticalResourceIdx == UINT_MAX ||
307 (PI->ProcResourceIdx != CriticalResourceIdx &&
309 ProcResourceCounters[CriticalResourceIdx]))) {
311 dbgs() <<
"++ New critical resource: "
312 << SchedModel->getProcResource(PI->ProcResourceIdx)->Name
314 CriticalResourceIdx = PI->ProcResourceIdx;
320 LastFPdOpCycleIdx = getCurrCycleIdx(SU);
321 LLVM_DEBUG(
dbgs() <<
"++ Last FPd cycle index: " << LastFPdOpCycleIdx
327 CurrGroupSize += getNumDecoderSlots(SU);
328 CurrGroupHas4RegOps |= has4RegOps(SU->
getInstr());
329 unsigned GroupLim = (CurrGroupHas4RegOps ? 2 : 3);
330 assert((CurrGroupSize <= GroupLim || CurrGroupSize == getNumDecoderSlots(SU))
331 &&
"SU does not fit into decoder group!");
335 if (CurrGroupSize >= GroupLim || SC->
EndGroup)
348 return 3 - CurrGroupSize;
355 unsigned resultingGroupSize =
356 (CurrGroupSize + getNumDecoderSlots(SU));
357 if (resultingGroupSize < 3)
358 return (3 - resultingGroupSize);
363 if (CurrGroupSize == 2 && has4RegOps(SU->
getInstr()))
370bool SystemZHazardRecognizer::isFPdOpPreferred_distance(
SUnit *SU)
const {
373 if (LastFPdOpCycleIdx == UINT_MAX)
379 unsigned SUCycleIdx = getCurrCycleIdx(SU);
380 if (LastFPdOpCycleIdx > SUCycleIdx)
381 return ((LastFPdOpCycleIdx - SUCycleIdx) == 3);
382 return ((SUCycleIdx - LastFPdOpCycleIdx) == 3);
396 Cost = (isFPdOpPreferred_distance(SU) ? INT_MIN : INT_MAX);
398 else if (CriticalResourceIdx != UINT_MAX) {
400 PI = SchedModel->getWriteProcResBegin(SC),
401 PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI)
402 if (PI->ProcResourceIdx == CriticalResourceIdx)
403 Cost = PI->ReleaseAtCycle;
419 make_range(SchedModel->getWriteProcResBegin(SC),
420 SchedModel->getWriteProcResEnd(SC))) {
421 switch (SchedModel->getProcResource(PRE.ProcResourceIdx)->BufferSize) {
433 unsigned GroupSizeBeforeEmit = CurrGroupSize;
438 if (GroupSizeBeforeEmit == 1)
442 if (TakenBranch && CurrGroupSize > 0)
446 "Scheduler: unhandled terminator!");
452 CurrGroupSize =
Incoming->CurrGroupSize;
456 ProcResourceCounters =
Incoming->ProcResourceCounters;
457 CriticalResourceIdx =
Incoming->CriticalResourceIdx;
460 LastFPdOpCycleIdx =
Incoming->LastFPdOpCycleIdx;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
MachineInstr unsigned OpIdx
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
static bool isBranchRetTrap(MachineInstr *MI)
static cl::opt< int > ProcResCostLim("procres-cost-lim", cl::Hidden, cl::desc("The OOO window for processor " "resources during scheduling."), cl::init(8))
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Scheduling unit. This is a node in the scheduling DAG.
bool isCall
Is a function call.
unsigned NodeNum
Entry # of node in the node vector.
bool isUnbuffered
Uses an unbuffered resource.
bool hasReservedResource
Uses a reserved resource.
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
void assign(size_type NumElts, ValueParamT Elt)
int groupingCost(SUnit *SU) const
Return the cost of decoder grouping for SU.
void dumpProcResourceCounters() const
void emitInstruction(MachineInstr *MI, bool TakenBranch=false)
Wrap a non-scheduled instruction in an SU and emit it.
const MCSchedClassDesc * getSchedClass(SUnit *SU) const
Resolves and cache a resolved scheduling class for an SUnit.
void copyState(SystemZHazardRecognizer *Incoming)
Copy counters from end of single predecessor.
void Reset() override
Reset - This callback is invoked when a new block of instructions is about to be schedule.
void dumpSU(SUnit *SU, raw_ostream &OS) const
HazardType getHazardType(SUnit *SU, int Stalls=0) override
getHazardType - Return the hazard type of emitting this node.
void dumpCurrGroup(std::string Msg="") const
int resourcesCost(SUnit *SU)
Return the cost of SU in regards to processor resources usage.
void EmitInstruction(SUnit *SU) override
EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...
SystemZHazardRecognizer(const SystemZInstrInfo *tii, const TargetSchedModel *SM)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const MCWriteProcResEntry * ProcResIter
unsigned getNumProcResourceKinds() const
Get the number of kinds of resources for this target.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Count
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
Define a kind of processor resource that will be modeled by the scheduler.
Summarize the scheduling resources required for an instruction of a particular scheduling class.
Identify one of the processor resource kinds consumed by a particular scheduling class for the specif...