X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FHexagon%2FHexagonMachineScheduler.cpp;h=35f732cd6207fbaa40cef53cf6daf820df29ad01;hb=c413998d28c4e201e265b0bdbe90ddc2747856c4;hp=ced17b3c0a45cf0d8efbbecdc2d9dd6184b3b4b4;hpb=ecb8c2ba6029f02b01b20b110cc1b3b3ea2e1f1c;p=oota-llvm.git diff --git a/lib/Target/Hexagon/HexagonMachineScheduler.cpp b/lib/Target/Hexagon/HexagonMachineScheduler.cpp index ced17b3c0a4..35f732cd620 100644 --- a/lib/Target/Hexagon/HexagonMachineScheduler.cpp +++ b/lib/Target/Hexagon/HexagonMachineScheduler.cpp @@ -12,16 +12,17 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "misched" - #include "HexagonMachineScheduler.h" -#include +#include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/IR/Function.h" using namespace llvm; -/// Platform specific modifications to DAG. +#define DEBUG_TYPE "misched" + +/// Platform-specific modifications to DAG. void VLIWMachineScheduler::postprocessDAG() { - SUnit* LastSequentialCall = NULL; + SUnit* LastSequentialCall = nullptr; // Currently we only catch the situation when compare gets scheduled // before preceding call. for (unsigned su = 0, e = SUnits.size(); su != e; ++su) { @@ -107,7 +108,7 @@ bool VLIWResourceModel::reserveResources(SUnit *SU) { case TargetOpcode::REG_SEQUENCE: case TargetOpcode::IMPLICIT_DEF: case TargetOpcode::KILL: - case TargetOpcode::PROLOG_LABEL: + case TargetOpcode::CFI_INSTRUCTION: case TargetOpcode::EH_LABEL: case TargetOpcode::COPY: case TargetOpcode::INLINEASM: @@ -144,12 +145,12 @@ void VLIWMachineScheduler::schedule() { << "********** MI Converging Scheduling VLIW BB#" << BB->getNumber() << " " << BB->getName() << " in_func " << BB->getParent()->getFunction()->getName() - << " at loop depth " << MLI.getLoopDepth(BB) + << " at loop depth " << MLI->getLoopDepth(BB) << " \n"); buildDAGWithRegPressure(); - // Postprocess the DAG to add platform specific artificial dependencies. + // Postprocess the DAG to add platform-specific artificial dependencies. postprocessDAG(); SmallVector TopRoots, BotRoots; @@ -159,6 +160,9 @@ void VLIWMachineScheduler::schedule() { SchedImpl->initialize(this); // To view Height/Depth correctly, they should be accessed at least once. + // + // FIXME: SUnit::dumpAll always recompute depth and height now. The max + // depth/height could be computed directly from the roots and leaves. DEBUG(unsigned maxH = 0; for (unsigned su = 0, e = SUnits.size(); su != e; ++su) if (SUnits[su].getHeight() > maxH) @@ -182,6 +186,9 @@ void VLIWMachineScheduler::schedule() { scheduleMI(SU, IsTopNode); updateQueues(SU, IsTopNode); + + // Notify the scheduling strategy after updating the DAG. + SchedImpl->schedNode(SU, IsTopNode); } assert(CurrentTop == CurrentBottom && "Nonempty unscheduled zone."); @@ -191,7 +198,6 @@ void VLIWMachineScheduler::schedule() { void ConvergingVLIWScheduler::initialize(ScheduleDAGMI *dag) { DAG = static_cast(dag); SchedModel = DAG->getSchedModel(); - TRI = DAG->TRI; Top.init(DAG, SchedModel); Bot.init(DAG, SchedModel); @@ -199,14 +205,17 @@ void ConvergingVLIWScheduler::initialize(ScheduleDAGMI *dag) { // Initialize the HazardRecognizers. If itineraries don't exist, are empty, or // are disabled, then these HazardRecs will be disabled. const InstrItineraryData *Itin = DAG->getSchedModel()->getInstrItineraries(); - const TargetMachine &TM = DAG->MF.getTarget(); + const TargetSubtargetInfo &STI = DAG->MF.getSubtarget(); + const TargetInstrInfo *TII = STI.getInstrInfo(); delete Top.HazardRec; delete Bot.HazardRec; - Top.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG); - Bot.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG); + Top.HazardRec = TII->CreateTargetMIHazardRecognizer(Itin, DAG); + Bot.HazardRec = TII->CreateTargetMIHazardRecognizer(Itin, DAG); - Top.ResourceModel = new VLIWResourceModel(TM, DAG->getSchedModel()); - Bot.ResourceModel = new VLIWResourceModel(TM, DAG->getSchedModel()); + delete Top.ResourceModel; + delete Bot.ResourceModel; + Top.ResourceModel = new VLIWResourceModel(STI, DAG->getSchedModel()); + Bot.ResourceModel = new VLIWResourceModel(STI, DAG->getSchedModel()); assert((!llvm::ForceTopDown || !llvm::ForceBottomUp) && "-misched-topdown incompatible with -misched-bottomup"); @@ -219,7 +228,7 @@ void ConvergingVLIWScheduler::releaseTopNode(SUnit *SU) { for (SUnit::succ_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { unsigned PredReadyCycle = I->getSUnit()->TopReadyCycle; - unsigned MinLatency = I->getMinLatency(); + unsigned MinLatency = I->getLatency(); #ifndef NDEBUG Top.MaxMinLatency = std::max(MinLatency, Top.MaxMinLatency); #endif @@ -238,7 +247,7 @@ void ConvergingVLIWScheduler::releaseBottomNode(SUnit *SU) { for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { unsigned SuccReadyCycle = I->getSUnit()->BotReadyCycle; - unsigned MinLatency = I->getMinLatency(); + unsigned MinLatency = I->getLatency(); #ifndef NDEBUG Bot.MaxMinLatency = std::max(MinLatency, Bot.MaxMinLatency); #endif @@ -261,7 +270,7 @@ void ConvergingVLIWScheduler::releaseBottomNode(SUnit *SU) { /// can dispatch per cycle. /// /// TODO: Also check whether the SU must start a new group. -bool ConvergingVLIWScheduler::SchedBoundary::checkHazard(SUnit *SU) { +bool ConvergingVLIWScheduler::VLIWSchedBoundary::checkHazard(SUnit *SU) { if (HazardRec->isEnabled()) return HazardRec->getHazardType(SU) != ScheduleHazardRecognizer::NoHazard; @@ -272,7 +281,7 @@ bool ConvergingVLIWScheduler::SchedBoundary::checkHazard(SUnit *SU) { return false; } -void ConvergingVLIWScheduler::SchedBoundary::releaseNode(SUnit *SU, +void ConvergingVLIWScheduler::VLIWSchedBoundary::releaseNode(SUnit *SU, unsigned ReadyCycle) { if (ReadyCycle < MinReadyCycle) MinReadyCycle = ReadyCycle; @@ -287,7 +296,7 @@ void ConvergingVLIWScheduler::SchedBoundary::releaseNode(SUnit *SU, } /// Move the boundary of scheduled code by one cycle. -void ConvergingVLIWScheduler::SchedBoundary::bumpCycle() { +void ConvergingVLIWScheduler::VLIWSchedBoundary::bumpCycle() { unsigned Width = SchedModel->getIssueWidth(); IssueCount = (IssueCount <= Width) ? 0 : IssueCount - Width; @@ -313,7 +322,7 @@ void ConvergingVLIWScheduler::SchedBoundary::bumpCycle() { } /// Move the boundary of scheduled code by one SUnit. -void ConvergingVLIWScheduler::SchedBoundary::bumpNode(SUnit *SU) { +void ConvergingVLIWScheduler::VLIWSchedBoundary::bumpNode(SUnit *SU) { bool startNewCycle = false; // Update the reservation table. @@ -343,7 +352,7 @@ void ConvergingVLIWScheduler::SchedBoundary::bumpNode(SUnit *SU) { /// Release pending ready nodes in to the available queue. This makes them /// visible to heuristics. -void ConvergingVLIWScheduler::SchedBoundary::releasePending() { +void ConvergingVLIWScheduler::VLIWSchedBoundary::releasePending() { // If the available queue is empty, it is safe to reset MinReadyCycle. if (Available.empty()) MinReadyCycle = UINT_MAX; @@ -371,7 +380,7 @@ void ConvergingVLIWScheduler::SchedBoundary::releasePending() { } /// Remove SU from the ready set for this boundary. -void ConvergingVLIWScheduler::SchedBoundary::removeReady(SUnit *SU) { +void ConvergingVLIWScheduler::VLIWSchedBoundary::removeReady(SUnit *SU) { if (Available.isInQueue(SU)) Available.remove(Available.find(SU)); else { @@ -383,30 +392,30 @@ void ConvergingVLIWScheduler::SchedBoundary::removeReady(SUnit *SU) { /// If this queue only has one ready candidate, return it. As a side effect, /// advance the cycle until at least one node is ready. If multiple instructions /// are ready, return NULL. -SUnit *ConvergingVLIWScheduler::SchedBoundary::pickOnlyChoice() { +SUnit *ConvergingVLIWScheduler::VLIWSchedBoundary::pickOnlyChoice() { if (CheckPending) releasePending(); for (unsigned i = 0; Available.empty(); ++i) { assert(i <= (HazardRec->getMaxLookAhead() + MaxMinLatency) && "permanent hazard"); (void)i; - ResourceModel->reserveResources(0); + ResourceModel->reserveResources(nullptr); bumpCycle(); releasePending(); } if (Available.size() == 1) return *Available.begin(); - return NULL; + return nullptr; } #ifndef NDEBUG void ConvergingVLIWScheduler::traceCandidate(const char *Label, const ReadyQueue &Q, - SUnit *SU, PressureElement P) { + SUnit *SU, PressureChange P) { dbgs() << Label << " " << Q.getName() << " "; if (P.isValid()) - dbgs() << TRI->getRegPressureSetName(P.PSetID) << ":" << P.UnitIncrease - << " "; + dbgs() << DAG->TRI->getRegPressureSetName(P.getPSet()) << ":" + << P.getUnitInc() << " "; else dbgs() << " "; SU->dump(DAG); @@ -416,7 +425,7 @@ void ConvergingVLIWScheduler::traceCandidate(const char *Label, /// getSingleUnscheduledPred - If there is exactly one unscheduled predecessor /// of SU, return it, otherwise return null. static SUnit *getSingleUnscheduledPred(SUnit *SU) { - SUnit *OnlyAvailablePred = 0; + SUnit *OnlyAvailablePred = nullptr; for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { SUnit &Pred = *I->getSUnit(); @@ -424,7 +433,7 @@ static SUnit *getSingleUnscheduledPred(SUnit *SU) { // We found an available, but not scheduled, predecessor. If it's the // only one we have found, keep track of it... otherwise give up. if (OnlyAvailablePred && OnlyAvailablePred != &Pred) - return 0; + return nullptr; OnlyAvailablePred = &Pred; } } @@ -434,7 +443,7 @@ static SUnit *getSingleUnscheduledPred(SUnit *SU) { /// getSingleUnscheduledSucc - If there is exactly one unscheduled successor /// of SU, return it, otherwise return null. static SUnit *getSingleUnscheduledSucc(SUnit *SU) { - SUnit *OnlyAvailableSucc = 0; + SUnit *OnlyAvailableSucc = nullptr; for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { SUnit &Succ = *I->getSUnit(); @@ -442,7 +451,7 @@ static SUnit *getSingleUnscheduledSucc(SUnit *SU) { // We found an available, but not scheduled, successor. If it's the // only one we have found, keep track of it... otherwise give up. if (OnlyAvailableSucc && OnlyAvailableSucc != &Succ) - return 0; + return nullptr; OnlyAvailableSucc = &Succ; } } @@ -452,9 +461,7 @@ static SUnit *getSingleUnscheduledSucc(SUnit *SU) { // Constants used to denote relative importance of // heuristic components for cost computation. static const unsigned PriorityOne = 200; -static const unsigned PriorityTwo = 100; -static const unsigned PriorityThree = 50; -static const unsigned PriorityFour = 20; +static const unsigned PriorityTwo = 50; static const unsigned ScaleTwo = 10; static const unsigned FactorOne = 2; @@ -512,8 +519,8 @@ int ConvergingVLIWScheduler::SchedulingCost(ReadyQueue &Q, SUnit *SU, ResCount += (NumNodesBlocking * ScaleTwo); // Factor in reg pressure as a heuristic. - ResCount -= (Delta.Excess.UnitIncrease*PriorityThree); - ResCount -= (Delta.CriticalMax.UnitIncrease*PriorityThree); + ResCount -= (Delta.Excess.getUnitInc()*PriorityTwo); + ResCount -= (Delta.CriticalMax.getUnitInc()*PriorityTwo); DEBUG(if (verbose) dbgs() << " Total(" << ResCount << ")"); @@ -633,7 +640,7 @@ SUnit *ConvergingVLIWScheduler::pickNode(bool &IsTopNode) { if (DAG->top() == DAG->bottom()) { assert(Top.Available.empty() && Top.Pending.empty() && Bot.Available.empty() && Bot.Pending.empty() && "ReadyQ garbage"); - return NULL; + return nullptr; } SUnit *SU; if (llvm::ForceTopDown) {