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,
84 if (
const SUnit *HigherSU =
123 static const unsigned TopRegionSUs = 36;
140 Cmp0SrcReg = SystemZ::NoRegister;
142 unsigned DAGHeight = 0;
143 for (
unsigned Idx = 0, End =
DAG->SUnits.size(); Idx != End; ++Idx)
144 DAGHeight = std::max(DAGHeight,
DAG->SUnits[Idx].getHeight());
147 LivenessHeightCutOff = DAGHeight / (
DAG->SUnits.size() < 50 ? 4 : 2);
152 DAG->SUnits.size() >= 3 * std::max(DAGHeight, 1u);
160 if (
TII->isCompareZero(*
MI))
161 Cmp0SrcReg =
TII->getCompareSourceReg(*
MI);
162 else if (
MI->getDesc().hasImplicitDefOfPhysReg(SystemZ::CC) ||
163 definesCmp0Src(
MI,
false))
164 Cmp0SrcReg = SystemZ::NoRegister;
171void SystemZPostRASchedStrategy::SUSet::
174 for (
auto &SU : *
this) {
188 if (
MBB->pred_size() == 1)
189 PredMBB = *
MBB->pred_begin();
196 PredMBB = (Pred ==
MBB ? nullptr : Pred);
200 &&
"Loop MBB should not consider predecessor outside of loop.");
205void SystemZPostRASchedStrategy::
209 ((LastEmittedMI !=
nullptr && LastEmittedMI->getParent() == MBB) ?
210 std::next(LastEmittedMI) : MBB->begin());
212 for (;
I != NextBegin; ++
I) {
213 if (
I->isPosition() ||
I->isDebugInstr())
215 HazardRec->emitInstruction(&*
I);
225 assert ((SchedStates.find(NextMBB) == SchedStates.end()) &&
226 "Entering MBB twice?");
242 if (SinglePredMBB ==
nullptr)
244 auto It = SchedStates.find(SinglePredMBB);
245 if (It == SchedStates.end())
251 HazardRec->copyState(It->second);
258 bool TakenBranch = (
MI.isBranch() &&
259 (TII->getBranchInfo(
MI).isIndirect() ||
260 TII->getBranchInfo(
MI).getMBBTarget() == MBB));
261 HazardRec->emitInstruction(&
MI, TakenBranch);
272 advanceTo(MBB->getFirstTerminator());
279 (
C->MF->getSubtarget().getInstrInfo())),
280 MBB(nullptr), HazardRec(nullptr) {
287 for (
auto I : SchedStates) {
295 unsigned NumRegionInstrs) {
297 if (Begin->isTerminator())
309 if (Available.empty())
313 if (Available.size() == 1) {
315 HazardRec->dumpSU(*Available.begin(),
dbgs());
dbgs() <<
"\n";);
316 return *Available.begin();
320 LLVM_DEBUG(
dbgs() <<
"** Available: "; Available.dump(*HazardRec););
323 for (
auto *SU : Available) {
326 Candidate c(SU, *HazardRec);
329 if (Best.SU ==
nullptr || c < Best) {
343 assert (Best.SU !=
nullptr);
347SystemZPostRASchedStrategy::Candidate::
360bool SystemZPostRASchedStrategy::Candidate::
361operator<(
const Candidate &other) {
364 if (GroupingCost < other.GroupingCost)
366 if (GroupingCost > other.GroupingCost)
370 if (ResourcesCost < other.ResourcesCost)
372 if (ResourcesCost > other.ResourcesCost)
376 if (SU->
getHeight() > other.SU->getHeight())
378 if (SU->
getHeight() < other.SU->getHeight())
382 if (SU->
NodeNum < other.SU->NodeNum)
390 if (Available.size() == 1)
dbgs() <<
"(only one) ";
391 Candidate c(SU, *HazardRec); c.dumpCosts();
dbgs() <<
"\n";);
395 HazardRec->EmitInstruction(SU);
406 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...
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...