15 #define DEBUG_TYPE "misched"
25 SUnit* LastSequentialCall = NULL;
28 for (
unsigned su = 0, e =
SUnits.size(); su != e; ++su) {
30 if (
SUnits[su].getInstr()->isCall())
31 LastSequentialCall = &(
SUnits[su]);
33 else if (
SUnits[su].getInstr()->isCompare() && LastSequentialCall)
65 for (
unsigned i = 0, e = Packet.size(); i != e; ++i) {
66 if (Packet[i]->Succs.size() == 0)
69 E = Packet[i]->Succs.end();
I != E; ++
I) {
75 if (
I->getSUnit() == SU)
84 bool startNewCycle =
false;
117 Packet.push_back(SU);
120 DEBUG(
dbgs() <<
"Packet[" << TotalPackets <<
"]:\n");
121 for (
unsigned i = 0, e = Packet.size(); i != e; ++i) {
123 DEBUG(
dbgs() << Packet[i]->NodeNum <<
")\t");
134 startNewCycle =
true;
137 return startNewCycle;
145 <<
"********** MI Converging Scheduling VLIW BB#" <<
BB->
getNumber()
166 DEBUG(
unsigned maxH = 0;
167 for (
unsigned su = 0, e =
SUnits.size(); su != e; ++su)
168 if (
SUnits[su].getHeight() > maxH)
169 maxH =
SUnits[su].getHeight();
170 dbgs() <<
"Max Height " << maxH <<
"\n";);
171 DEBUG(
unsigned maxD = 0;
172 for (
unsigned su = 0, e =
SUnits.size(); su != e; ++su)
173 if (
SUnits[su].getDepth() > maxD)
174 maxD =
SUnits[su].getDepth();
175 dbgs() <<
"Max Depth " << maxD <<
"\n";);
176 DEBUG(
for (
unsigned su = 0, e =
SUnits.size(); su != e; ++su)
177 SUnits[su].dumpAll(
this));
181 bool IsTopNode =
false;
199 Top.init(DAG, SchedModel);
200 Bot.init(DAG, SchedModel);
206 delete Top.HazardRec;
207 delete Bot.HazardRec;
211 delete Top.ResourceModel;
212 delete Bot.ResourceModel;
217 "-misched-topdown incompatible with -misched-bottomup");
226 unsigned PredReadyCycle =
I->getSUnit()->TopReadyCycle;
227 unsigned MinLatency =
I->getLatency();
229 Top.MaxMinLatency = std::max(MinLatency, Top.MaxMinLatency);
241 assert(SU->
getInstr() &&
"Scheduled SUnit must have instr");
245 unsigned SuccReadyCycle =
I->getSUnit()->BotReadyCycle;
246 unsigned MinLatency =
I->getLatency();
248 Bot.MaxMinLatency = std::max(MinLatency, Bot.MaxMinLatency);
269 bool ConvergingVLIWScheduler::SchedBoundary::checkHazard(
SUnit *SU) {
270 if (HazardRec->isEnabled())
273 unsigned uops = SchedModel->getNumMicroOps(SU->
getInstr());
274 if (IssueCount + uops > SchedModel->getIssueWidth())
280 void ConvergingVLIWScheduler::SchedBoundary::releaseNode(
SUnit *SU,
281 unsigned ReadyCycle) {
282 if (ReadyCycle < MinReadyCycle)
283 MinReadyCycle = ReadyCycle;
287 if (ReadyCycle > CurrCycle || checkHazard(SU))
295 void ConvergingVLIWScheduler::SchedBoundary::bumpCycle() {
296 unsigned Width = SchedModel->getIssueWidth();
297 IssueCount = (IssueCount <= Width) ? 0 : IssueCount - Width;
299 assert(MinReadyCycle < UINT_MAX &&
"MinReadyCycle uninitialized");
300 unsigned NextCycle = std::max(CurrCycle + 1, MinReadyCycle);
302 if (!HazardRec->isEnabled()) {
304 CurrCycle = NextCycle;
307 for (; CurrCycle != NextCycle; ++CurrCycle) {
309 HazardRec->AdvanceCycle();
311 HazardRec->RecedeCycle();
316 DEBUG(
dbgs() <<
"*** " << Available.getName() <<
" cycle "
317 << CurrCycle <<
'\n');
321 void ConvergingVLIWScheduler::SchedBoundary::bumpNode(
SUnit *SU) {
322 bool startNewCycle =
false;
325 if (HazardRec->isEnabled()) {
326 if (!isTop() && SU->
isCall) {
331 HazardRec->EmitInstruction(SU);
335 startNewCycle = ResourceModel->reserveResources(SU);
339 IssueCount += SchedModel->getNumMicroOps(SU->
getInstr());
341 DEBUG(
dbgs() <<
"*** Max instrs at cycle " << CurrCycle <<
'\n');
345 DEBUG(
dbgs() <<
"*** IssueCount " << IssueCount
346 <<
" at cycle " << CurrCycle <<
'\n');
351 void ConvergingVLIWScheduler::SchedBoundary::releasePending() {
353 if (Available.empty())
354 MinReadyCycle = UINT_MAX;
358 for (
unsigned i = 0, e = Pending.size(); i != e; ++i) {
359 SUnit *SU = *(Pending.begin()+i);
362 if (ReadyCycle < MinReadyCycle)
363 MinReadyCycle = ReadyCycle;
365 if (ReadyCycle > CurrCycle)
372 Pending.remove(Pending.begin()+i);
375 CheckPending =
false;
379 void ConvergingVLIWScheduler::SchedBoundary::removeReady(
SUnit *SU) {
380 if (Available.isInQueue(SU))
381 Available.remove(Available.find(SU));
383 assert(Pending.isInQueue(SU) &&
"bad ready count");
384 Pending.remove(Pending.find(SU));
391 SUnit *ConvergingVLIWScheduler::SchedBoundary::pickOnlyChoice() {
395 for (
unsigned i = 0; Available.empty(); ++i) {
396 assert(i <= (HazardRec->getMaxLookAhead() + MaxMinLatency) &&
397 "permanent hazard"); (void)i;
398 ResourceModel->reserveResources(0);
402 if (Available.size() == 1)
403 return *Available.begin();
424 SUnit *OnlyAvailablePred = 0;
427 SUnit &Pred = *
I->getSUnit();
431 if (OnlyAvailablePred && OnlyAvailablePred != &Pred)
433 OnlyAvailablePred = &Pred;
436 return OnlyAvailablePred;
442 SUnit *OnlyAvailableSucc = 0;
445 SUnit &Succ = *
I->getSUnit();
449 if (OnlyAvailableSucc && OnlyAvailableSucc != &Succ)
451 OnlyAvailableSucc = &Succ;
454 return OnlyAvailableSucc;
467 SchedCandidate &Candidate,
487 if (Top.ResourceModel->isResourceAvailable(SU))
494 if (Bot.ResourceModel->isResourceAvailable(SU))
498 unsigned NumNodesBlocking = 0;
515 ResCount += (NumNodesBlocking *
ScaleTwo);
521 DEBUG(
if (verbose)
dbgs() <<
" Total(" << ResCount <<
")");
533 SchedCandidate &Candidate) {
540 CandResult FoundCandidate = NoCand;
543 TempTracker.getMaxPressureDelta((*I)->getInstr(), RPDelta,
552 Candidate.RPDelta = RPDelta;
553 Candidate.SCost = CurrentCost;
554 FoundCandidate = NodeOrder;
559 if (CurrentCost > Candidate.SCost) {
562 Candidate.RPDelta = RPDelta;
563 Candidate.SCost = CurrentCost;
564 FoundCandidate = BestCost;
570 if (FoundCandidate == NoCand)
573 return FoundCandidate;
580 if (
SUnit *SU = Bot.pickOnlyChoice()) {
584 if (
SUnit *SU = Top.pickOnlyChoice()) {
588 SchedCandidate BotCand;
592 assert(BotResult != NoCand &&
"failed to find the first candidate");
601 if (BotResult == SingleExcess || BotResult == SingleCritical) {
606 SchedCandidate TopCand;
609 assert(TopResult != NoCand &&
"failed to find the first candidate");
611 if (TopResult == SingleExcess || TopResult == SingleCritical) {
617 if (BotResult == SingleMax) {
621 if (TopResult == SingleMax) {
625 if (TopCand.SCost > BotCand.SCost) {
637 assert(Top.Available.empty() && Top.Pending.empty() &&
638 Bot.Available.empty() && Bot.Pending.empty() &&
"ReadyQ garbage");
643 SU = Top.pickOnlyChoice();
645 SchedCandidate TopCand;
646 CandResult TopResult =
648 assert(TopResult != NoCand &&
"failed to find the first candidate");
654 SU = Bot.pickOnlyChoice();
656 SchedCandidate BotCand;
657 CandResult BotResult =
659 assert(BotResult != NoCand &&
"failed to find the first candidate");
672 DEBUG(
dbgs() <<
"*** " << (IsTopNode ?
"Top" :
"Bottom")
673 <<
" Scheduling Instruction in cycle "
674 << (IsTopNode ? Top.CurrCycle : Bot.CurrCycle) <<
'\n';
bool canReserveResources(const llvm::MCInstrDesc *MID)
virtual ScheduleHazardRecognizer * CreateTargetMIHazardRecognizer(const InstrItineraryData *, const ScheduleDAG *DAG) const
const MachineFunction * getParent() const
virtual void initialize(ScheduleDAGMI *DAG)=0
Initialize the strategy after building the DAG for a new region.
virtual void initialize(ScheduleDAGMI *dag)
Initialize the strategy after building the DAG for a new region.
int SchedulingCost(ReadyQueue &Q, SUnit *SU, SchedCandidate &Candidate, RegPressureDelta &Delta, bool verbose)
MachineBasicBlock::iterator CurrentTop
The top of the unscheduled zone.
MachineInstr * getInstr() const
CandResult pickNodeFromQueue(ReadyQueue &Q, const RegPressureTracker &RPTracker, SchedCandidate &Candidate)
void buildDAGWithRegPressure()
Build the DAG and setup three register pressure trackers.
static SUnit * getSingleUnscheduledPred(SUnit *SU)
const Function * getFunction() const
MachineBasicBlock::iterator top() const
void updateQueues(SUnit *SU, bool IsTopNode)
Update scheduler DAG and queues after scheduling an instruction.
SmallVector< SDep, 4 > Preds
const RegPressureTracker & getTopRPTracker() const
StringRef getName() const
const TargetSchedModel * getSchedModel() const
Get the machine model for instruction scheduling.
unsigned getHeight() const
SUnit * pickNodeBidrectional(bool &IsTopNode)
Pick the best candidate node from either the top or bottom queue.
static const unsigned ScaleTwo
virtual const char * getRegPressureSetName(unsigned Idx) const =0
Get the name of this register unit pressure set.
static SUnit * getSingleUnscheduledSucc(SUnit *SU)
const MachineLoopInfo & MLI
void reserveResources(const llvm::MCInstrDesc *MID)
std::vector< SUnit * >::iterator iterator
MachineSchedStrategy * SchedImpl
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
const InstrItineraryData * getInstrItineraries() const
void findRootsAndBiasEdges(SmallVectorImpl< SUnit * > &TopRoots, SmallVectorImpl< SUnit * > &BotRoots)
bool isResourceAvailable(SUnit *SU)
static const unsigned FactorOne
void scheduleMI(SUnit *SU, bool IsTopNode)
Move an instruction and update register pressure.
An unknown scheduling barrier.
std::vector< unsigned > MaxSetPressure
Map of max reg pressure indexed by pressure set ID, not class ID.
virtual const TargetInstrInfo * getInstrInfo() const
void traceCandidate(const char *Label, const ReadyQueue &Q, SUnit *SU, PressureChange P=PressureChange())
virtual SUnit * pickNode(bool &IsTopNode)
Pick the best node to balance the schedule. Implements MachineSchedStrategy.
virtual void releaseBottomNode(SUnit *SU)
const std::vector< PressureChange > & getRegionCriticalPSets() const
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
StringRef getName() const
PressureChange CriticalMax
MachineBasicBlock::iterator bottom() const
const IntervalPressure & getRegPressure() const
Get register pressure for the entire scheduling region before scheduling.
unsigned getDepth() const
virtual SUnit * pickNode(bool &IsTopNode)=0
virtual void schedNode(SUnit *SU, bool IsTopNode)
const TargetRegisterInfo * TRI
static const unsigned PriorityOne
cl::opt< bool > ForceBottomUp
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
void postprocessDAG()
Perform platform specific DAG postprocessing.
const TargetMachine & getTarget() const
void placeDebugValues()
Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues.
bool reserveResources(SUnit *SU)
Keep track of available resources.
unsigned getLoopDepth(const MachineBasicBlock *BB) const
MachineBasicBlock::iterator CurrentBottom
The bottom of the unscheduled zone.
void initQueues(ArrayRef< SUnit * > TopRoots, ArrayRef< SUnit * > BotRoots)
Release ExitSU predecessors and setup scheduler queues.
static const unsigned PriorityTwo
virtual void releaseTopNode(SUnit *SU)
SmallVector< SDep, 4 > Succs
unsigned getIssueWidth() const
Maximum number of micro-ops that may be scheduled per cycle.
bool isBottomReady() const
StringRef getName() const
MachineBasicBlock * BB
The block in which to insert instructions.
const RegPressureTracker & getBotRPTracker() const
std::vector< SUnit > SUnits
void dump(const ScheduleDAG *G) const
SUnit - Scheduling unit. This is a node in the scheduling DAG.
cl::opt< bool > ForceTopDown