14#define DEBUG_TYPE "machine-scheduler"
26void SystemZPreRASchedStrategy::initializeLatencyReduction() {
32 unsigned DAGHeight = 0;
33 for (
unsigned Idx = 0, End =
DAG->SUnits.size(); Idx != End; ++Idx)
34 DAGHeight = std::max(DAGHeight,
DAG->SUnits[Idx].getHeight());
36 DAG->SUnits.size() >= 3 * std::max(DAGHeight, 1u);
37 if ((HasDataSequences = !
RegionPolicy.DisableLatencyHeuristic)) {
38 unsigned CurrSequence = 0, NumSeqNodes = 0;
39 auto countSequence = [&CurrSequence, &NumSeqNodes]() {
40 if (CurrSequence >= 2)
41 NumSeqNodes += CurrSequence;
44 for (
unsigned Idx = 0, End =
DAG->SUnits.size(); Idx != End; ++Idx) {
45 const SUnit *SU = &
DAG->SUnits[Idx];
46 bool InDataSequence =
true;
48 unsigned NumPreds = 0;
49 for (
const SDep &Pred : SU->
Preds)
52 InDataSequence =
false;
54 unsigned NumSuccs = 0;
55 for (
const SDep &Succ : SU->
Succs)
58 InDataSequence =
false;
61 if (!InDataSequence || !NumPreds)
67 if (NumSeqNodes >= std::max(
size_t(4),
DAG->SUnits.size() / 4)) {
69 << NumSeqNodes <<
". ";);
71 HasDataSequences =
false;
75bool SystemZPreRASchedStrategy::definesCmp0Src(
const MachineInstr *
MI,
77 if (Cmp0SrcReg != SystemZ::NoRegister &&
MI->getNumOperands() &&
78 (
MI->getDesc().hasImplicitDefOfPhysReg(SystemZ::CC) || !CCDef)) {
79 const MachineOperand &MO0 =
MI->getOperand(0);
93 return MI->getNumOperands() && !
MI->isCopy() &&
100 assert(Zone && !Zone->
isTop() &&
"Bottom-Up scheduling only.");
113 if (TryCandPRegBias && CandPRegBias) {
125 (HasDataSequences ||
Rem.IsAcyclicLatencyLimited))
126 if (
const SUnit *HigherSU =
177 Cmp0SrcReg = SystemZ::NoRegister;
179 initializeLatencyReduction();
180 LLVM_DEBUG(
dbgs() <<
"Latency scheduling " << (HasDataSequences ?
"" :
"not ")
181 <<
"enabled for data sequences.\n";);
189 if (
TII->isCompareZero(*
MI))
190 Cmp0SrcReg =
TII->getCompareSourceReg(*
MI);
191 else if (
MI->getDesc().hasImplicitDefOfPhysReg(SystemZ::CC) ||
192 definesCmp0Src(
MI,
false))
193 Cmp0SrcReg = SystemZ::NoRegister;
200void SystemZPostRASchedStrategy::SUSet::
203 for (
auto &SU : *
this) {
217 if (
MBB->pred_size() == 1)
218 PredMBB = *
MBB->pred_begin();
225 PredMBB = (Pred ==
MBB ? nullptr : Pred);
229 &&
"Loop MBB should not consider predecessor outside of loop.");
234void SystemZPostRASchedStrategy::
238 ((LastEmittedMI !=
nullptr && LastEmittedMI->getParent() == MBB) ?
239 std::next(LastEmittedMI) : MBB->begin());
241 for (;
I != NextBegin; ++
I) {
242 if (
I->isPosition() ||
I->isDebugInstr())
244 HazardRec->emitInstruction(&*
I);
254 assert ((SchedStates.find(NextMBB) == SchedStates.end()) &&
255 "Entering MBB twice?");
271 if (SinglePredMBB ==
nullptr)
273 auto It = SchedStates.find(SinglePredMBB);
274 if (It == SchedStates.end())
280 HazardRec->copyState(It->second);
287 bool TakenBranch = (
MI.isBranch() &&
288 (TII->getBranchInfo(
MI).isIndirect() ||
289 TII->getBranchInfo(
MI).getMBBTarget() == MBB));
290 HazardRec->emitInstruction(&
MI, TakenBranch);
301 advanceTo(MBB->getFirstTerminator());
308 (
C->MF->getSubtarget().getInstrInfo())),
309 MBB(nullptr), HazardRec(nullptr) {
316 for (
auto I : SchedStates) {
324 unsigned NumRegionInstrs) {
326 if (Begin->isTerminator())
338 if (Available.empty())
342 if (Available.size() == 1) {
344 HazardRec->dumpSU(*Available.begin(),
dbgs());
dbgs() <<
"\n";);
345 return *Available.begin();
349 LLVM_DEBUG(
dbgs() <<
"** Available: "; Available.dump(*HazardRec););
352 for (
auto *SU : Available) {
355 Candidate c(SU, *HazardRec);
358 if (Best.SU ==
nullptr || c < Best) {
372 assert (Best.SU !=
nullptr);
376SystemZPostRASchedStrategy::Candidate::
389bool SystemZPostRASchedStrategy::Candidate::
390operator<(
const Candidate &other) {
393 if (GroupingCost < other.GroupingCost)
395 if (GroupingCost > other.GroupingCost)
399 if (ResourcesCost < other.ResourcesCost)
401 if (ResourcesCost > other.ResourcesCost)
405 if (SU->
getHeight() > other.SU->getHeight())
407 if (SU->
getHeight() < other.SU->getHeight())
411 if (SU->
NodeNum < other.SU->NodeNum)
419 if (Available.size() == 1)
dbgs() <<
"(only one) ";
420 Candidate c(SU, *HazardRec); c.dumpCosts();
dbgs() <<
"\n";);
424 HazardRec->EmitInstruction(SU);
435 Available.insert(SU);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const HexagonInstrInfo * TII
static int biasPhysRegExtra(const SUnit *SU)
static MachineBasicBlock * getSingleSchedPred(MachineBasicBlock *MBB, const MachineLoop *Loop)
static bool isRegDef(const MachineOperand &MO)
Pre-RA scheduling ///.
static bool isPhysRegDef(const MachineOperand &MO)
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.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
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 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.
LLVM_ABI int biasPhysReg(const SUnit *SU, bool isTop)
Minimize physical register live ranges.
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...