14#define DEBUG_TYPE "machine-scheduler"
22void SystemZPreRASchedStrategy::initializeLatencyReduction() {
28 unsigned DAGHeight = 0;
29 for (
unsigned Idx = 0, End =
DAG->SUnits.size(); Idx != End; ++Idx)
30 DAGHeight = std::max(DAGHeight,
DAG->SUnits[Idx].getHeight());
32 DAG->SUnits.size() >= 3 * std::max(DAGHeight, 1u);
33 if ((HasDataSequences = !
RegionPolicy.DisableLatencyHeuristic)) {
34 unsigned CurrSequence = 0, NumSeqNodes = 0;
35 auto countSequence = [&CurrSequence, &NumSeqNodes]() {
36 if (CurrSequence >= 2)
37 NumSeqNodes += CurrSequence;
40 for (
unsigned Idx = 0, End =
DAG->SUnits.size(); Idx != End; ++Idx) {
41 const SUnit *SU = &
DAG->SUnits[Idx];
42 bool InDataSequence =
true;
44 unsigned NumPreds = 0;
45 for (
const SDep &Pred : SU->
Preds)
48 InDataSequence =
false;
50 unsigned NumSuccs = 0;
51 for (
const SDep &Succ : SU->
Succs)
54 InDataSequence =
false;
57 if (!InDataSequence || !NumPreds)
63 if (NumSeqNodes >= std::max(
size_t(4),
DAG->SUnits.size() / 4)) {
65 << NumSeqNodes <<
". ";);
67 HasDataSequences =
false;
71bool SystemZPreRASchedStrategy::definesCmp0Src(
const MachineInstr *
MI,
73 if (Cmp0SrcReg != SystemZ::NoRegister &&
MI->getNumOperands() &&
74 (
MI->getDesc().hasImplicitDefOfPhysReg(SystemZ::CC) || !CCDef)) {
75 const MachineOperand &MO0 =
MI->getOperand(0);
85 assert(Zone && !Zone->
isTop() &&
"Bottom-Up scheduling only.");
103 (HasDataSequences ||
Rem.IsAcyclicLatencyLimited))
104 if (
const SUnit *HigherSU =
155 Cmp0SrcReg = SystemZ::NoRegister;
157 initializeLatencyReduction();
158 LLVM_DEBUG(
dbgs() <<
"Latency scheduling " << (HasDataSequences ?
"" :
"not ")
159 <<
"enabled for data sequences.\n";);
167 if (
TII->isCompareZero(*
MI))
168 Cmp0SrcReg =
TII->getCompareSourceReg(*
MI);
169 else if (
MI->getDesc().hasImplicitDefOfPhysReg(SystemZ::CC) ||
170 definesCmp0Src(
MI,
false))
171 Cmp0SrcReg = SystemZ::NoRegister;
178void SystemZPostRASchedStrategy::SUSet::
181 for (
auto &SU : *
this) {
195 if (
MBB->pred_size() == 1)
196 PredMBB = *
MBB->pred_begin();
203 PredMBB = (Pred ==
MBB ? nullptr : Pred);
207 &&
"Loop MBB should not consider predecessor outside of loop.");
212void SystemZPostRASchedStrategy::
216 ((LastEmittedMI !=
nullptr && LastEmittedMI->getParent() == MBB) ?
217 std::next(LastEmittedMI) : MBB->begin());
219 for (;
I != NextBegin; ++
I) {
220 if (
I->isPosition() ||
I->isDebugInstr())
222 HazardRec->emitInstruction(&*
I);
232 assert ((SchedStates.find(NextMBB) == SchedStates.end()) &&
233 "Entering MBB twice?");
249 if (SinglePredMBB ==
nullptr)
251 auto It = SchedStates.find(SinglePredMBB);
252 if (It == SchedStates.end())
258 HazardRec->copyState(It->second);
265 bool TakenBranch = (
MI.isBranch() &&
266 (TII->getBranchInfo(
MI).isIndirect() ||
267 TII->getBranchInfo(
MI).getMBBTarget() == MBB));
268 HazardRec->emitInstruction(&
MI, TakenBranch);
279 advanceTo(MBB->getFirstTerminator());
286 (
C->MF->getSubtarget().getInstrInfo())),
287 MBB(nullptr), HazardRec(nullptr) {
294 for (
auto I : SchedStates) {
302 unsigned NumRegionInstrs) {
304 if (Begin->isTerminator())
316 if (Available.empty())
320 if (Available.size() == 1) {
322 HazardRec->dumpSU(*Available.begin(),
dbgs());
dbgs() <<
"\n";);
323 return *Available.begin();
327 LLVM_DEBUG(
dbgs() <<
"** Available: "; Available.dump(*HazardRec););
330 for (
auto *SU : Available) {
333 Candidate c(SU, *HazardRec);
336 if (Best.SU ==
nullptr || c < Best) {
350 assert (Best.SU !=
nullptr);
354SystemZPostRASchedStrategy::Candidate::
367bool SystemZPostRASchedStrategy::Candidate::
368operator<(
const Candidate &other) {
371 if (GroupingCost < other.GroupingCost)
373 if (GroupingCost > other.GroupingCost)
377 if (ResourcesCost < other.ResourcesCost)
379 if (ResourcesCost > other.ResourcesCost)
383 if (SU->
getHeight() > other.SU->getHeight())
385 if (SU->
getHeight() < other.SU->getHeight())
389 if (SU->
NodeNum < other.SU->NodeNum)
397 if (Available.size() == 1)
dbgs() <<
"(only one) ";
398 Candidate c(SU, *HazardRec); c.dumpCosts();
dbgs() <<
"\n";);
402 HazardRec->EmitInstruction(SU);
413 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.
Kind getKind() const
Returns an enum value representing the kind of the dependence.
@ Data
Regular data dependence (aka true-dependence).
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.
SmallVector< SDep, 4 > Succs
All sunit successors.
SmallVector< SDep, 4 > Preds
All sunit predecessors.
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.
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...