1//-- SystemZMachineScheduler.cpp - SystemZ Scheduler Interface -*- C++ -*---==// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 9// -------------------------- Post RA scheduling ---------------------------- // 10// SystemZPostRASchedStrategy is a scheduling strategy which is plugged into 11// the MachineScheduler. It has a sorted Available set of SUs and a pickNode() 12// implementation that looks to optimize decoder grouping and balance the 13// usage of processor resources. Scheduler states are saved for the end 14// region of each MBB, so that a successor block can learn from it. 15//===----------------------------------------------------------------------===// 22#define DEBUG_TYPE "machine-scheduler" 25// Print the set of SUs 26void SystemZPostRASchedStrategy::SUSet::
29for (
auto &SU : *
this) {
38// Try to find a single predecessor that would be interesting for the 39// scheduler in the top-most region of MBB. 46// The loop header has two predecessors, return the latch, but not for a 51 PredMBB = (Pred ==
MBB ? nullptr : Pred);
55 &&
"Loop MBB should not consider predecessor outside of loop.");
60void SystemZPostRASchedStrategy::
64 ((LastEmittedMI !=
nullptr && LastEmittedMI->getParent() == MBB) ?
65 std::next(LastEmittedMI) : MBB->
begin());
67for (;
I != NextBegin; ++
I) {
68if (
I->isPosition() ||
I->isDebugInstr())
75 Available.clear();
// -misched-cutoff. 80assert ((SchedStates.find(NextMBB) == SchedStates.end()) &&
81"Entering MBB twice?");
86 /// Create a HazardRec for MBB, save it in SchedStates and set HazardRec to 93// Try to take over the state from a single predecessor, if it has been 94// scheduled. If this is not possible, we are done. 97if (SinglePredMBB ==
nullptr ||
98 SchedStates.find(SinglePredMBB) == SchedStates.end())
104 HazardRec->
copyState(SchedStates[SinglePredMBB]);
107// Emit incoming terminator(s). Be optimistic and assume that branch 108// prediction will generally do "the right thing". 111bool TakenBranch = (
MI.isBranch() &&
123// Advance to first terminator. The successor block will handle terminators 124// dependent on CFG layout (T/NT branch etc). 132 (
C->MF->getSubtarget().getInstrInfo())),
133MBB(nullptr), HazardRec(nullptr) {
139// Delete hazard recognizers kept around for each MBB. 140for (
autoI : SchedStates) {
148unsigned NumRegionInstrs) {
149// Don't emit the terminators. 150if (Begin->isTerminator())
153// Emit any instructions before start of region. 157// Pick the next node to schedule. 159// Only scheduling top-down. 162if (Available.empty())
165// If only one choice, return it. 166if (Available.size() == 1) {
169return *Available.begin();
172// All nodes that are possible to schedule are stored in the Available set. 173LLVM_DEBUG(
dbgs() <<
"** Available: "; Available.dump(*HazardRec););
176for (
auto *SU : Available) {
178// SU is the next candidate to be compared against current Best. 179 Candidate c(SU, *HazardRec);
181// Remeber which SU is the best candidate. 182if (Best.SU ==
nullptr || c < Best) {
188dbgs() <<
" Height:" << c.SU->getHeight();
dbgs() <<
"\n";);
190// Once we know we have seen all SUs that affect grouping or use unbuffered 191// resources, we can stop iterating if Best looks good. 192if (!SU->isScheduleHigh && Best.noCost())
196assert (Best.SU !=
nullptr);
200SystemZPostRASchedStrategy::Candidate::
204// Check the grouping cost. For a node that must begin / end a 205// group, it is positive if it would do so prematurely, or negative 206// if it would fit naturally into the schedule. 209// Check the resources cost for this SU. 213bool SystemZPostRASchedStrategy::Candidate::
214operator<(
const Candidate &other) {
216// Check decoder grouping. 217if (GroupingCost < other.GroupingCost)
219if (GroupingCost > other.GroupingCost)
222// Compare the use of resources. 223if (ResourcesCost < other.ResourcesCost)
225if (ResourcesCost > other.ResourcesCost)
228// Higher SU is otherwise generally better. 229if (SU->getHeight() > other.SU->getHeight())
231if (SU->getHeight() < other.SU->getHeight())
234// If all same, fall back to original order. 235if (SU->NodeNum < other.SU->NodeNum)
243if (Available.size() == 1)
dbgs() <<
"(only one) ";
244 Candidate c(SU, *HazardRec); c.dumpCosts();
dbgs() <<
"\n";);
246// Remove SU from Available set and update HazardRec. 252// Set isScheduleHigh flag on all SUs that we want to consider first in 255bool AffectsGrouping = (SC->isValid() && (SC->BeginGroup || SC->EndGroup));
258// Put all released SUs in the Available set. 259 Available.insert(SU);
const HexagonInstrInfo * TII
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static MachineBasicBlock * getSingleSchedPred(MachineBasicBlock *MBB, const MachineLoop *Loop)
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
BlockT * getHeader() const
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Represents a single loop in the control flow graph.
unsigned pred_size() const
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
pred_iterator pred_begin()
iterator_range< pred_iterator > predecessors()
Representation of each machine instruction.
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.
bool isScheduleHigh
True if preferable to schedule high.
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 emitInstruction(MachineInstr *MI, bool TakenBranch=false)
Wrap a non-scheduled instruction in an SU and emit it.
const MCSchedClassDesc * getSchedClass(SUnit *SU) const
Resolves and cache a resolved scheduling class for an SUnit.
void copyState(SystemZHazardRecognizer *Incoming)
Copy counters from end of single predecessor.
void dumpSU(SUnit *SU, raw_ostream &OS) const
MachineBasicBlock::iterator getLastEmittedMI()
int resourcesCost(SUnit *SU)
Return the cost of SU in regards to processor resources usage.
void EmitInstruction(SUnit *SU) override
EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...
MachineBasicBlock * getMBBTarget()
SystemZII::Branch getBranchInfo(const MachineInstr &MI) const
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.
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.
virtual ~SystemZPostRASchedStrategy()
SystemZPostRASchedStrategy(const MachineSchedContext *C)
void releaseTopNode(SUnit *SU) override
SU has had all predecessor dependencies resolved.
void init(const TargetSubtargetInfo *TSInfo)
Initialize the machine model for instruction scheduling.
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
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...