36 #define DEBUG_TYPE "machine-scheduler" 42 cl::desc(
"The OOO window for processor " 43 "resources during scheduling."),
46 unsigned SystemZHazardRecognizer::
47 getNumDecoderSlots(
SUnit *SU)
const {
53 "Only cracked instruction can have 2 uops.");
55 "Expanded instructions always group alone.");
57 "Expanded instructions fill the group(s).");
62 unsigned SystemZHazardRecognizer::getCurrCycleIdx(
SUnit *SU)
const {
63 unsigned Idx = CurrGroupSize;
67 if (SU !=
nullptr && !fitsIntoCurrentGroup(SU)) {
68 if (Idx == 1 || Idx == 2)
70 else if (Idx == 4 || Idx == 5)
84 CurrGroupHas4RegOps =
false;
85 clearProcResCounters();
87 LastFPdOpCycleIdx = UINT_MAX;
88 LastEmittedMI =
nullptr;
93 SystemZHazardRecognizer::fitsIntoCurrentGroup(
SUnit *SU)
const {
101 return (CurrGroupSize == 0);
104 assert ((CurrGroupSize < 2 || !CurrGroupHas4RegOps) &&
105 "Current decoder group is already full!");
106 if (CurrGroupSize == 2 && has4RegOps(SU->
getInstr()))
112 assert ((getNumDecoderSlots(SU) <= 1) && (CurrGroupSize < 3) &&
113 "Expected normal instruction to fit in non-full group!");
118 bool SystemZHazardRecognizer::has4RegOps(
const MachineInstr *
MI)
const {
135 void SystemZHazardRecognizer::nextGroup() {
136 if (CurrGroupSize == 0)
142 int NumGroups = ((CurrGroupSize > 3) ? (CurrGroupSize / 3) : 1);
143 assert((CurrGroupSize <= 3 || CurrGroupSize % 3 == 0) &&
144 "Current decoder group bad.");
148 CurrGroupHas4RegOps =
false;
154 ProcResourceCounters[i] = ((ProcResourceCounters[i] > NumGroups)
155 ? (ProcResourceCounters[i] - NumGroups)
159 if (CriticalResourceIdx != UINT_MAX &&
160 (ProcResourceCounters[CriticalResourceIdx] <=
162 CriticalResourceIdx = UINT_MAX;
167 #ifndef NDEBUG // Debug output 169 OS <<
"SU(" << SU->
NodeNum <<
"):";
181 std::string FU(PRD.
Name);
183 FU = FU.substr(FU.find(
"_") + 1);
184 size_t Pos = FU.find(
"Unit");
185 if (Pos != std::string::npos)
192 OS <<
"(" << PI->Cycles <<
"cyc)";
198 OS <<
"/GroupsAlone";
200 OS <<
"/BeginsGroup";
210 dbgs() <<
"++ " << Msg;
214 dbgs() <<
" <empty>\n";
217 dbgs() <<
" (" << CurrGroupSize <<
" decoder slot" 218 << (CurrGroupSize > 1 ?
"s":
"")
219 << (CurrGroupHas4RegOps ?
", 4RegOps" :
"")
228 if (ProcResourceCounters[i] > 0) {
236 dbgs() <<
"++ | Resource counters: ";
238 if (ProcResourceCounters[i] > 0)
240 <<
":" << ProcResourceCounters[i] <<
" ";
243 if (CriticalResourceIdx != UINT_MAX)
244 dbgs() <<
"++ | Critical resource: " 251 dbgs() <<
"++ | Current cycle index: " 252 << getCurrCycleIdx() <<
"\n";
254 if (LastFPdOpCycleIdx != UINT_MAX)
255 dbgs() <<
"++ | Last FPd cycle index: " << LastFPdOpCycleIdx <<
"\n";
260 void SystemZHazardRecognizer::clearProcResCounters() {
262 CriticalResourceIdx = UINT_MAX;
280 if (!fitsIntoCurrentGroup(SU))
304 ProcResourceCounters[PI->ProcResourceIdx];
305 CurrCounter += PI->Cycles;
308 (CriticalResourceIdx == UINT_MAX ||
309 (PI->ProcResourceIdx != CriticalResourceIdx &&
311 ProcResourceCounters[CriticalResourceIdx]))) {
313 dbgs() <<
"++ New critical resource: " 316 CriticalResourceIdx = PI->ProcResourceIdx;
322 LastFPdOpCycleIdx = getCurrCycleIdx(SU);
323 LLVM_DEBUG(
dbgs() <<
"++ Last FPd cycle index: " << LastFPdOpCycleIdx
329 CurrGroupSize += getNumDecoderSlots(SU);
330 CurrGroupHas4RegOps |= has4RegOps(SU->
getInstr());
331 unsigned GroupLim = (CurrGroupHas4RegOps ? 2 : 3);
332 assert((CurrGroupSize <= GroupLim || CurrGroupSize == getNumDecoderSlots(SU))
333 &&
"SU does not fit into decoder group!");
337 if (CurrGroupSize >= GroupLim || SC->
EndGroup)
350 return 3 - CurrGroupSize;
357 unsigned resultingGroupSize =
358 (CurrGroupSize + getNumDecoderSlots(SU));
359 if (resultingGroupSize < 3)
360 return (3 - resultingGroupSize);
365 if (CurrGroupSize == 2 && has4RegOps(SU->
getInstr()))
372 bool SystemZHazardRecognizer::isFPdOpPreferred_distance(
SUnit *SU)
const {
375 if (LastFPdOpCycleIdx == UINT_MAX)
381 unsigned SUCycleIdx = getCurrCycleIdx(SU);
382 if (LastFPdOpCycleIdx > SUCycleIdx)
383 return ((LastFPdOpCycleIdx - SUCycleIdx) == 3);
384 return ((SUCycleIdx - LastFPdOpCycleIdx) == 3);
398 Cost = (isFPdOpPreferred_distance(SU) ? INT_MIN : INT_MAX);
400 else if (CriticalResourceIdx != UINT_MAX) {
404 if (PI->ProcResourceIdx == CriticalResourceIdx)
435 unsigned GroupSizeBeforeEmit = CurrGroupSize;
440 if (GroupSizeBeforeEmit == 1)
444 if (TakenBranch && CurrGroupSize > 0)
448 "Scheduler: unhandled terminator!");
454 CurrGroupSize = Incoming->CurrGroupSize;
458 ProcResourceCounters = Incoming->ProcResourceCounters;
459 CriticalResourceIdx = Incoming->CriticalResourceIdx;
462 LastFPdOpCycleIdx = Incoming->LastFPdOpCycleIdx;
463 GrpCount = Incoming->GrpCount;
const SystemZRegisterInfo & getRegisterInfo() const
bool isCall(QueryType Type=AnyInBundle) const
ProcResIter getWriteProcResBegin(const MCSchedClassDesc *SC) const
This class represents lattice values for constants.
Describe properties that are true of each instruction in the target description file.
ProcResIter getWriteProcResEnd(const MCSchedClassDesc *SC) const
unsigned const TargetRegisterInfo * TRI
const MCSchedClassDesc * getSchedClass(SUnit *SU) const
Resolves and cache a resolved scheduling class for an SUnit.
void Reset() override
Reset - This callback is invoked when a new block of instructions is about to be schedule.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
int groupingCost(SUnit *SU) const
Return the cost of decoder grouping for SU.
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
void dumpProcResourceCounters() const
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static cl::opt< int > ProcResCostLim("procres-cost-lim", cl::Hidden, cl::desc("The OOO window for processor " "resources during scheduling."), cl::init(8))
void assign(size_type NumElts, const T &Elt)
SystemZHazardRecognizer maintains the state for one MBB during scheduling.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
bool hasReservedResource
Uses a reserved resource.
HazardType getHazardType(SUnit *m, int Stalls=0) override
getHazardType - Return the hazard type of emitting this node.
void EmitInstruction(SUnit *SU) override
EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...
bool isBranch(QueryType Type=AnyInBundle) const
Returns true if this is a conditional, unconditional, or indirect branch.
static bool isBranchRetTrap(MachineInstr *MI)
void copyState(SystemZHazardRecognizer *Incoming)
Copy counters from end of single predecessor.
bool isReturn(QueryType Type=AnyInBundle) const
bool isUnbuffered
Uses an unbuffered resource.
initializer< Ty > init(const Ty &Val)
bool isCall
Is a function call.
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
Identify one of the processor resource kinds consumed by a particular scheduling class for the specif...
Summarize the scheduling resources required for an instruction of a particular scheduling class...
int resourcesCost(SUnit *SU)
Return the cost of SU in regards to processor resources usage.
void dumpCurrGroup(std::string Msg="") const
void emitInstruction(MachineInstr *MI, bool TakenBranch=false)
Wrap a non-scheduled instruction in an SU and emit it.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specific constraint if it is set.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Define a kind of processor resource that will be modeled by the scheduler.
CHAIN = SC CHAIN, Imm128 - System call.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getNumProcResourceKinds() const
Get the number of kinds of resources for this target.
const MCSchedClassDesc * resolveSchedClass(const MachineInstr *MI) const
Return the MCSchedClassDesc for this instruction.
const MachineBasicBlock * getParent() const
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
unsigned NodeNum
Entry # of node in the node vector.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MCProcResourceDesc * getProcResource(unsigned PIdx) const
Get a processor resource by ID for convenience.
A raw_ostream that writes to an std::string.
This class implements an extremely fast bulk output stream that can only output to a stream...
void dumpSU(SUnit *SU, raw_ostream &OS) const
Scheduling unit. This is a node in the scheduling DAG.