14#define DEBUG_TYPE "machine-scheduler"
22bool SystemZPreRASchedStrategy::definesCmp0Src(
const MachineInstr *
MI,
24 if (Cmp0SrcReg != SystemZ::NoRegister &&
MI->getNumOperands() &&
25 (
MI->getDesc().hasImplicitDefOfPhysReg(SystemZ::CC) || !CCDef)) {
26 const MachineOperand &MO0 =
MI->getOperand(0);
33bool SystemZPreRASchedStrategy::closesLiveRange(
const SUnit *SU,
41 int VR16PChange = 0, GRX32PChange = 0;
42 const PressureDiff &PDiff =
DAG->getPressureDiff(SU);
43 for (
const PressureChange &PC : PDiff) {
46 if (PC.getPSet() == SystemZ::VR16Bit)
47 VR16PChange = PC.getUnitInc();
48 else if (PC.getPSet() == SystemZ::GRX32Bit)
49 GRX32PChange = PC.getUnitInc();
54 return VR16PChange < 0 || (!VR16PChange && GRX32PChange < 0);
60 assert(Zone && !Zone->
isTop() &&
"Bottom-Up scheduling only.");
73 auto schedLow = [&](
const SUnit *SU) {
75 SU->
getHeight() < LivenessHeightCutOff && closesLiveRange(SU,
DAG);
78 if (
tryGreater(schedLow(TryCand.
SU), schedLow(Cand.
SU), TryCand, Cand,
90 if (
const SUnit *HigherSU =
129 static const unsigned TopRegionSUs = 36;
146 Cmp0SrcReg = SystemZ::NoRegister;
148 unsigned DAGHeight = 0;
149 for (
unsigned Idx = 0, End =
DAG->SUnits.size(); Idx != End; ++Idx)
150 DAGHeight = std::max(DAGHeight,
DAG->SUnits[Idx].getHeight());
153 LivenessHeightCutOff = DAGHeight / (
DAG->SUnits.size() < 50 ? 4 : 2);
158 DAG->SUnits.size() >= 3 * std::max(DAGHeight, 1u);
166 if (
TII->isCompareZero(*
MI))
167 Cmp0SrcReg =
TII->getCompareSourceReg(*
MI);
168 else if (
MI->getDesc().hasImplicitDefOfPhysReg(SystemZ::CC) ||
169 definesCmp0Src(
MI,
false))
170 Cmp0SrcReg = SystemZ::NoRegister;
177void SystemZPostRASchedStrategy::SUSet::
180 for (
auto &SU : *
this) {
194 if (
MBB->pred_size() == 1)
195 PredMBB = *
MBB->pred_begin();
202 PredMBB = (Pred ==
MBB ? nullptr : Pred);
206 &&
"Loop MBB should not consider predecessor outside of loop.");
211void SystemZPostRASchedStrategy::
215 ((LastEmittedMI !=
nullptr && LastEmittedMI->getParent() == MBB) ?
216 std::next(LastEmittedMI) : MBB->begin());
218 for (;
I != NextBegin; ++
I) {
219 if (
I->isPosition() ||
I->isDebugInstr())
221 HazardRec->emitInstruction(&*
I);
231 assert ((SchedStates.find(NextMBB) == SchedStates.end()) &&
232 "Entering MBB twice?");
248 if (SinglePredMBB ==
nullptr)
250 auto It = SchedStates.find(SinglePredMBB);
251 if (It == SchedStates.end())
257 HazardRec->copyState(It->second);
264 bool TakenBranch = (
MI.isBranch() &&
265 (TII->getBranchInfo(
MI).isIndirect() ||
266 TII->getBranchInfo(
MI).getMBBTarget() == MBB));
267 HazardRec->emitInstruction(&
MI, TakenBranch);
278 advanceTo(MBB->getFirstTerminator());
285 (
C->MF->getSubtarget().getInstrInfo())),
286 MBB(nullptr), HazardRec(nullptr) {
293 for (
auto I : SchedStates) {
301 unsigned NumRegionInstrs) {
303 if (Begin->isTerminator())
315 if (Available.empty())
319 if (Available.size() == 1) {
321 HazardRec->dumpSU(*Available.begin(),
dbgs());
dbgs() <<
"\n";);
322 return *Available.begin();
326 LLVM_DEBUG(
dbgs() <<
"** Available: "; Available.dump(*HazardRec););
329 for (
auto *SU : Available) {
332 Candidate c(SU, *HazardRec);
335 if (Best.SU ==
nullptr || c < Best) {
349 assert (Best.SU !=
nullptr);
353SystemZPostRASchedStrategy::Candidate::
366bool SystemZPostRASchedStrategy::Candidate::
367operator<(
const Candidate &other) {
370 if (GroupingCost < other.GroupingCost)
372 if (GroupingCost > other.GroupingCost)
376 if (ResourcesCost < other.ResourcesCost)
378 if (ResourcesCost > other.ResourcesCost)
382 if (SU->
getHeight() > other.SU->getHeight())
384 if (SU->
getHeight() < other.SU->getHeight())
388 if (SU->
NodeNum < other.SU->NodeNum)
396 if (Available.size() == 1)
dbgs() <<
"(only one) ";
397 Candidate c(SU, *HazardRec); c.dumpCosts();
dbgs() <<
"\n";);
401 HazardRec->EmitInstruction(SU);
412 Available.insert(SU);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const HexagonInstrInfo * TII
static MachineBasicBlock * getSingleSchedPred(MachineBasicBlock *MBB, const MachineLoop *Loop)
static bool isRegDef(const MachineOperand &MO)
Pre-RA scheduling ///.
MachineSchedPolicy RegionPolicy
void initialize(ScheduleDAGMI *dag) override
Initialize the strategy after building the DAG for a new region.
void schedNode(SUnit *SU, bool IsTopNode) override
Update the scheduler's state after scheduling a node.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
BlockT * getHeader() const
Represents a single loop in the control flow graph.
MachineInstrBundleIterator< MachineInstr > iterator
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
Scheduling unit. This is a node in the scheduling DAG.
unsigned NodeNum
Entry # of node in the node vector.
bool isUnbuffered
Uses an unbuffered resource.
unsigned getHeight() const
Returns the height of this node, which is the length of the maximum path down to any node which has n...
unsigned short Latency
Node latency.
bool isScheduleHigh
True if preferable to schedule high.
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
Each Scheduling boundary is associated with ready queues.
unsigned getScheduledLatency() const
Get the number of latency cycles "covered" by the scheduled instructions.
ScheduleDAGMILive is an implementation of ScheduleDAGInstrs that schedules machine instructions while...
ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...
SystemZHazardRecognizer maintains the state for one MBB during scheduling.
int groupingCost(SUnit *SU) const
Return the cost of decoder grouping for SU.
void dumpSU(SUnit *SU, raw_ostream &OS) const
int resourcesCost(SUnit *SU)
Return the cost of SU in regards to processor resources usage.
SUnit * pickNode(bool &IsTopNode) override
Pick the next node to schedule, or return NULL.
void leaveMBB() override
Tell the strategy that current MBB is done.
~SystemZPostRASchedStrategy() override
void initPolicy(MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, unsigned NumRegionInstrs) override
Called for a region before scheduling.
void schedNode(SUnit *SU, bool IsTopNode) override
ScheduleDAGMI has scheduled an instruction - tell HazardRec about it.
void initialize(ScheduleDAGMI *dag) override
Initialize the strategy after building the DAG for a new region.
void enterMBB(MachineBasicBlock *NextMBB) override
Tell the strategy that MBB is about to be processed.
SystemZPostRASchedStrategy(const MachineSchedContext *C)
void releaseTopNode(SUnit *SU) override
SU has had all predecessor dependencies resolved.
void schedNode(SUnit *SU, bool IsTopNode) override
Update the scheduler's state after scheduling a node.
void initPolicy(MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, unsigned NumRegionInstrs) override
Initialize the per-region scheduling policy.
void initialize(ScheduleDAGMI *dag) override
Initialize the strategy after building the DAG for a new region.
bool tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand, SchedBoundary *Zone) const override
Apply a set of heuristics to a new candidate.
TargetSubtargetInfo - Generic base class for all target subtargets.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI bool tryBiasPhysRegs(GenericSchedulerBase::SchedCandidate &TryCand, GenericSchedulerBase::SchedCandidate &Cand, SchedBoundary *Zone, bool BiasPRegsExtra)
LLVM_ABI bool tryGreater(int TryVal, int CandVal, GenericSchedulerBase::SchedCandidate &TryCand, GenericSchedulerBase::SchedCandidate &Cand, GenericSchedulerBase::CandReason Reason)
LLVM_ABI unsigned computeRemLatency(SchedBoundary &CurrZone)
Compute remaining latency.
LLVM_ABI bool tryLess(int TryVal, int CandVal, GenericSchedulerBase::SchedCandidate &TryCand, GenericSchedulerBase::SchedCandidate &Cand, GenericSchedulerBase::CandReason Reason)
Return true if this heuristic determines order.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Store the state used by GenericScheduler heuristics, required for the lifetime of one invocation of p...
Summarize the scheduling resources required for an instruction of a particular scheduling class.
MachineSchedContext provides enough context from the MachineScheduler pass for the target to instanti...