Lines Matching +full:pressure +full:- +full:max
1 //===- VLIWMachineScheduler.cpp - VLIW-Focused Scheduling Pass ------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
12 //===----------------------------------------------------------------------===//
42 #define DEBUG_TYPE "machine-scheduler"
44 static cl::opt<bool> IgnoreBBRegPressure("ignore-bb-reg-pressure", cl::Hidden,
47 static cl::opt<bool> UseNewerCandidate("use-newer-candidate", cl::Hidden,
50 static cl::opt<unsigned> SchedDebugVerboseLevel("misched-verbose-level",
54 // early due to a zero-latency dependence.
55 static cl::opt<bool> CheckEarlyAvail("check-early-avail", cl::Hidden,
58 // This value is used to determine if a register class is a high pressure set.
61 static cl::opt<float> RPThreshold("vliw-misched-reg-pressure", cl::Hidden,
63 cl::desc("High register pressure threhold."));
74 Packet.reserve(SchedModel->getIssueWidth()); in VLIWResourceModel()
76 ResourcesModel->clearResources(); in VLIWResourceModel()
81 ResourcesModel->clearResources(); in reset()
88 if (SUd->Succs.size() == 0) in hasDependence()
91 for (const auto &S : SUd->Succs) { in hasDependence()
109 if (!SU || !SU->getInstr()) in isResourceAvailable()
114 switch (SU->getInstr()->getOpcode()) { in isResourceAvailable()
116 if (!ResourcesModel->canReserveResources(*SU->getInstr())) in isResourceAvailable()
156 Packet.size() >= SchedModel->getIssueWidth()) { in reserveResources()
162 switch (SU->getInstr()->getOpcode()) { in reserveResources()
164 ResourcesModel->reserveResources(*SU->getInstr()); in reserveResources()
185 LLVM_DEBUG(dbgs() << Packet[i]->NodeNum << ")\t"); in reserveResources()
186 LLVM_DEBUG(Packet[i]->getInstr()->dump()); in reserveResources()
195 return STI.getInstrInfo()->CreateTargetScheduleState(STI); in createPacketizer()
198 /// schedule - Called back from MachineScheduler::runOnMachineFunction
203 << printMBBReference(*BB) << " " << BB->getName() in schedule()
204 << " in_func " << BB->getParent()->getName() in schedule()
205 << " at loop depth " << MLI->getLoopDepth(BB) << " \n"); in schedule()
211 // Postprocess the DAG to add platform-specific artificial dependencies. in schedule()
218 SchedImpl->initialize(this); in schedule()
225 dbgs() << "Max Height " << maxH << "\n"; in schedule()
232 dbgs() << "Max Depth " << maxD << "\n"; in schedule()
244 SUnit *SU = SchedImpl->pickNode(IsTopNode); in schedule()
254 SchedImpl->schedNode(SU, IsTopNode); in schedule()
264 << printMBBReference(*begin()->getParent()) << " ***\n"; in schedule()
272 SchedModel = DAG->getSchedModel(); in initialize()
279 const InstrItineraryData *Itin = DAG->getSchedModel()->getInstrItineraries(); in initialize()
280 const TargetSubtargetInfo &STI = DAG->MF.getSubtarget(); in initialize()
284 Top.HazardRec = TII->CreateTargetMIHazardRecognizer(Itin, DAG); in initialize()
285 Bot.HazardRec = TII->CreateTargetMIHazardRecognizer(Itin, DAG); in initialize()
289 Top.ResourceModel = createVLIWResourceModel(STI, DAG->getSchedModel()); in initialize()
290 Bot.ResourceModel = createVLIWResourceModel(STI, DAG->getSchedModel()); in initialize()
293 DAG->getRegPressure().MaxSetPressure; in initialize()
296 unsigned Limit = DAG->getRegClassInfo()->getRegPressureSetLimit(i); in initialize()
302 "-misched-topdown incompatible with -misched-bottomup"); in initialize()
311 for (const SDep &PI : SU->Preds) { in releaseTopNode()
312 unsigned PredReadyCycle = PI.getSUnit()->TopReadyCycle; in releaseTopNode()
315 Top.MaxMinLatency = std::max(MinLatency, Top.MaxMinLatency); in releaseTopNode()
317 if (SU->TopReadyCycle < PredReadyCycle + MinLatency) in releaseTopNode()
318 SU->TopReadyCycle = PredReadyCycle + MinLatency; in releaseTopNode()
321 if (!SU->isScheduled) in releaseTopNode()
322 Top.releaseNode(SU, SU->TopReadyCycle); in releaseTopNode()
326 assert(SU->getInstr() && "Scheduled SUnit must have instr"); in releaseBottomNode()
328 for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; in releaseBottomNode()
330 unsigned SuccReadyCycle = I->getSUnit()->BotReadyCycle; in releaseBottomNode()
331 unsigned MinLatency = I->getLatency(); in releaseBottomNode()
333 Bot.MaxMinLatency = std::max(MinLatency, Bot.MaxMinLatency); in releaseBottomNode()
335 if (SU->BotReadyCycle < SuccReadyCycle + MinLatency) in releaseBottomNode()
336 SU->BotReadyCycle = SuccReadyCycle + MinLatency; in releaseBottomNode()
339 if (!SU->isScheduled) in releaseBottomNode()
340 Bot.releaseNode(SU, SU->BotReadyCycle); in releaseBottomNode()
352 /// supports highly complicated in-order reservation tables
353 /// (ScoreboardHazardRecognizer) and arbitrary target-specific logic.
357 /// for instruction dispatch limitations, including the number of micro-ops that
362 if (HazardRec->isEnabled()) in checkHazard()
363 return HazardRec->getHazardType(SU) != ScheduleHazardRecognizer::NoHazard; in checkHazard()
365 unsigned uops = SchedModel->getNumMicroOps(SU->getInstr()); in checkHazard()
366 if (IssueCount + uops > SchedModel->getIssueWidth()) in checkHazard()
388 unsigned Width = SchedModel->getIssueWidth(); in bumpCycle()
389 IssueCount = (IssueCount <= Width) ? 0 : IssueCount - Width; in bumpCycle()
391 assert(MinReadyCycle < std::numeric_limits<unsigned>::max() && in bumpCycle()
393 unsigned NextCycle = std::max(CurrCycle + 1, MinReadyCycle); in bumpCycle()
395 if (!HazardRec->isEnabled()) { in bumpCycle()
402 HazardRec->AdvanceCycle(); in bumpCycle()
404 HazardRec->RecedeCycle(); in bumpCycle()
418 if (HazardRec->isEnabled()) { in bumpNode()
419 if (!isTop() && SU->isCall) { in bumpNode()
420 // Calls are scheduled with their preceding instructions. For bottom-up in bumpNode()
422 HazardRec->Reset(); in bumpNode()
424 HazardRec->EmitInstruction(SU); in bumpNode()
428 startNewCycle = ResourceModel->reserveResources(SU, isTop()); in bumpNode()
432 IssueCount += SchedModel->getNumMicroOps(SU->getInstr()); in bumpNode()
434 LLVM_DEBUG(dbgs() << "*** Max instrs at cycle " << CurrCycle << '\n'); in bumpNode()
446 MinReadyCycle = std::numeric_limits<unsigned>::max(); in releasePending()
452 unsigned ReadyCycle = isTop() ? SU->TopReadyCycle : SU->BotReadyCycle; in releasePending()
465 --i; in releasePending()
466 --e; in releasePending()
492 return !ResourceModel->isResourceAvailable(*Available.begin(), isTop()) || in pickOnlyChoice()
497 assert(i <= (HazardRec->getMaxLookAhead() + MaxMinLatency) && in pickOnlyChoice()
500 ResourceModel->reserveResources(nullptr, isTop()); in pickOnlyChoice()
515 dbgs() << DAG->TRI->getRegPressureSetName(P.getPSet()) << ":" in traceCandidate()
520 DAG->dumpNode(*SU); in traceCandidate()
532 TempTracker.getMaxPressureDelta((*I)->getInstr(), RPDelta, in readyQueueVerboseDump()
533 DAG->getRegionCriticalPSets(), in readyQueueVerboseDump()
534 DAG->getRegPressure().MaxSetPressure); in readyQueueVerboseDump()
536 dbgstr << "SU(" << std::setw(3) << (*I)->NodeNum << ")"; in readyQueueVerboseDump()
540 (*I)->getInstr()->dump(); in readyQueueVerboseDump()
546 /// isSingleUnscheduledPred - If SU2 is the only unscheduled predecessor
549 if (SU->NumPredsLeft == 0) in isSingleUnscheduledPred()
552 for (auto &Pred : SU->Preds) { in isSingleUnscheduledPred()
554 if (!Pred.getSUnit()->isScheduled && (Pred.getSUnit() != SU2)) in isSingleUnscheduledPred()
561 /// isSingleUnscheduledSucc - If SU2 is the only unscheduled successor
564 if (SU->NumSuccsLeft == 0) in isSingleUnscheduledSucc()
567 for (auto &Succ : SU->Succs) { in isSingleUnscheduledSucc()
569 if (!Succ.getSUnit()->isScheduled && (Succ.getSUnit() != SU2)) in isSingleUnscheduledSucc()
575 /// Check if the instruction changes the register pressure of a register in the
576 /// high pressure set. The function returns a negative value if the pressure
577 /// decreases and a positive value is the pressure increases. If the instruction
578 /// doesn't use a high pressure register or doesn't change the register
579 /// pressure, then return 0.
581 PressureDiff &PD = DAG->getPressureDiff(SU); in pressureChange()
585 // The pressure differences are computed bottom-up, so the comparison for in pressureChange()
587 // top-down direction. in pressureChange()
589 return (isBotUp ? P.getUnitInc() : -P.getUnitInc()); in pressureChange()
604 if (!SU || SU->isScheduled) in SchedulingCost()
610 if (SU->isScheduleHigh) { in SchedulingCost()
620 ResCount += (SU->getHeight() * ScaleTwo); in SchedulingCost()
625 dbgstr << "h" << std::setw(3) << SU->getHeight() << "|"; in SchedulingCost()
631 if (Top.ResourceModel->isResourceAvailable(SU, true)) { in SchedulingCost()
640 ResCount += (SU->getDepth() * ScaleTwo); in SchedulingCost()
645 dbgstr << "d" << std::setw(3) << SU->getDepth() << "|"; in SchedulingCost()
651 if (Bot.ResourceModel->isResourceAvailable(SU, false)) { in SchedulingCost()
666 for (const SDep &SI : SU->Succs) in SchedulingCost()
672 for (const SDep &PI : SU->Preds) in SchedulingCost()
684 // Factor in reg pressure as a heuristic. in SchedulingCost()
686 // Decrease priority by the amount that register pressure exceeds the limit. in SchedulingCost()
687 ResCount -= (Delta.Excess.getUnitInc() * PriorityOne); in SchedulingCost()
688 // Decrease priority if register pressure exceeds the limit. in SchedulingCost()
689 ResCount -= (Delta.CriticalMax.getUnitInc() * PriorityOne); in SchedulingCost()
690 // Decrease priority slightly if register pressure would increase over the in SchedulingCost()
692 ResCount -= (Delta.CurrentMax.getUnitInc() * PriorityTwo); in SchedulingCost()
693 // If there are register pressure issues, then we remove the value added for in SchedulingCost()
699 ResCount -= IsAvailableAmt; in SchedulingCost()
710 for (const SDep &PI : SU->Preds) { in SchedulingCost()
711 if (!PI.getSUnit()->getInstr()->isPseudo() && PI.isAssignedRegDep() && in SchedulingCost()
713 Top.ResourceModel->isInPacket(PI.getSUnit())) { in SchedulingCost()
719 for (const SDep &SI : SU->Succs) { in SchedulingCost()
720 if (!SI.getSUnit()->getInstr()->isPseudo() && SI.isAssignedRegDep() && in SchedulingCost()
722 Bot.ResourceModel->isInPacket(SI.getSUnit())) { in SchedulingCost()
729 // If the instruction has a non-zero latency dependence with an instruction in in SchedulingCost()
736 for (const auto &PI : SU->Preds) { in SchedulingCost()
738 Top.ResourceModel->isInPacket(PI.getSUnit())) { in SchedulingCost()
739 ResCount -= PriorityOne; in SchedulingCost()
744 for (const auto &SI : SU->Succs) { in SchedulingCost()
746 Bot.ResourceModel->isInPacket(SI.getSUnit())) { in SchedulingCost()
747 ResCount -= PriorityOne; in SchedulingCost()
767 /// maintain the number of vreg uses remaining to be top-scheduled.
784 TempTracker.getMaxPressureDelta((*I)->getInstr(), RPDelta, in pickNodeFromQueue()
785 DAG->getRegionCriticalPSets(), in pickNodeFromQueue()
786 DAG->getRegPressure().MaxSetPressure); in pickNodeFromQueue()
803 if ((Q.getID() == TopQID && (*I)->NodeNum < Candidate.SU->NodeNum) || in pickNodeFromQueue()
804 (Q.getID() == BotQID && (*I)->NodeNum > Candidate.SU->NodeNum)) { in pickNodeFromQueue()
841 CurrSize = (*I)->Succs.size(); in pickNodeFromQueue()
842 CandSize = Candidate.SU->Succs.size(); in pickNodeFromQueue()
844 CurrSize = (*I)->Preds.size(); in pickNodeFromQueue()
845 CandSize = Candidate.SU->Preds.size(); in pickNodeFromQueue()
864 if ((Q.getID() == TopQID && (*I)->NodeNum < Candidate.SU->NodeNum) || in pickNodeFromQueue()
865 (Q.getID() == BotQID && (*I)->NodeNum > Candidate.SU->NodeNum)) { in pickNodeFromQueue()
900 pickNodeFromQueue(Bot, DAG->getBotRPTracker(), BotCand); in pickNodeBidrectional()
904 // Excess pressure, we can immediately schedule from that Q. in pickNodeBidrectional()
906 // RegionCriticalPSets summarizes the pressure within the scheduled region and in pickNodeBidrectional()
908 // increase pressure for one of the excess PSets, then schedule in that in pickNodeBidrectional()
918 pickNodeFromQueue(Top, DAG->getTopRPTracker(), TopCand); in pickNodeBidrectional()
926 // If either Q has a single candidate that minimizes pressure above the in pickNodeBidrectional()
927 // original region's pressure pick it. in pickNodeBidrectional()
951 if (DAG->top() == DAG->bottom()) { in pickNode()
962 pickNodeFromQueue(Top, DAG->getTopRPTracker(), TopCand); in pickNode()
973 pickNodeFromQueue(Bot, DAG->getBotRPTracker(), BotCand); in pickNode()
982 if (SU->isTopReady()) in pickNode()
984 if (SU->isBottomReady()) in pickNode()
991 DAG->dumpNode(*SU)); in pickNode()
1002 SU->TopReadyCycle = Top.CurrCycle; in schedNode()
1005 SU->BotReadyCycle = Bot.CurrCycle; in schedNode()