diff options
Diffstat (limited to 'llvm/lib/CodeGen/MachineScheduler.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineScheduler.cpp | 128 |
1 files changed, 95 insertions, 33 deletions
diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp index 265d3ac..3bbd126 100644 --- a/llvm/lib/CodeGen/MachineScheduler.cpp +++ b/llvm/lib/CodeGen/MachineScheduler.cpp @@ -81,6 +81,22 @@ cl::opt<bool> ForceTopDown("misched-topdown", cl::Hidden, cl::desc("Force top-down list scheduling")); cl::opt<bool> ForceBottomUp("misched-bottomup", cl::Hidden, cl::desc("Force bottom-up list scheduling")); +namespace MISchedPostRASched { +enum Direction { + TopDown, + BottomUp, +}; +} // end namespace MISchedPostRASched +cl::opt<MISchedPostRASched::Direction> PostRADirection( + "misched-postra-direction", cl::Hidden, + cl::desc("Post reg-alloc list scheduling direction"), + // Default to top-down because it was implemented first and existing targets + // expect that behavior by default. + cl::init(MISchedPostRASched::TopDown), + cl::values(clEnumValN(MISchedPostRASched::TopDown, "topdown", + "Force top-down post reg-alloc list scheduling"), + clEnumValN(MISchedPostRASched::BottomUp, "bottomup", + "Force bottom-up post reg-alloc list scheduling"))); cl::opt<bool> DumpCriticalPathLength("misched-dcpl", cl::Hidden, cl::desc("Print critical path length to stdout")); @@ -440,14 +456,14 @@ bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) { // Instantiate the selected scheduler for this target, function, and // optimization level. std::unique_ptr<ScheduleDAGInstrs> Scheduler(createMachineScheduler()); - ScheduleDAGMI::DumpDirection Dir; + ScheduleDAGMI::DumpDirection D; if (ForceTopDown) - Dir = ScheduleDAGMI::DumpDirection::TopDown; + D = ScheduleDAGMI::DumpDirection::TopDown; else if (ForceBottomUp) - Dir = ScheduleDAGMI::DumpDirection::BottomUp; + D = ScheduleDAGMI::DumpDirection::BottomUp; else - Dir = ScheduleDAGMI::DumpDirection::Bidirectional; - Scheduler->setDumpDirection(Dir); + D = ScheduleDAGMI::DumpDirection::Bidirectional; + Scheduler->setDumpDirection(D); scheduleRegions(*Scheduler, false); LLVM_DEBUG(LIS->dump()); @@ -481,9 +497,12 @@ bool PostMachineScheduler::runOnMachineFunction(MachineFunction &mf) { // Instantiate the selected scheduler for this target, function, and // optimization level. std::unique_ptr<ScheduleDAGInstrs> Scheduler(createPostMachineScheduler()); - Scheduler->setDumpDirection(PostRADirection == MISchedPostRASched::TopDown - ? ScheduleDAGMI::DumpDirection::TopDown - : ScheduleDAGMI::DumpDirection::BottomUp); + ScheduleDAGMI::DumpDirection D; + if (PostRADirection == MISchedPostRASched::TopDown) + D = ScheduleDAGMI::DumpDirection::TopDown; + else + D = ScheduleDAGMI::DumpDirection::BottomUp; + Scheduler->setDumpDirection(D); scheduleRegions(*Scheduler, true); if (VerifyScheduling) @@ -1136,11 +1155,11 @@ LLVM_DUMP_METHOD void ScheduleDAGMI::dumpScheduleTraceBottomUp() const { #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void ScheduleDAGMI::dumpSchedule() const { if (MISchedDumpScheduleTrace) { - if (DumpDir == TopDown) + if (DumpDir == DumpDirection::TopDown) dumpScheduleTraceTopDown(); - else if (DumpDir == BottomUp) + else if (DumpDir == DumpDirection::BottomUp) dumpScheduleTraceBottomUp(); - else if (DumpDir == BottomUp) { + else if (DumpDir == DumpDirection::Bidirectional) { dbgs() << "* Schedule table (Bidirectional): not implemented\n"; } else { dbgs() << "* Schedule table: DumpDirection not set.\n"; @@ -3845,7 +3864,7 @@ void PostGenericScheduler::initialize(ScheduleDAGMI *Dag) { Rem.init(DAG, SchedModel); Top.init(DAG, SchedModel, &Rem); - BotRoots.clear(); + Bot.init(DAG, SchedModel, &Rem); // Initialize the HazardRecognizers. If itineraries don't exist, are empty, // or are disabled, then these HazardRecs will be disabled. @@ -3862,11 +3881,23 @@ void PostGenericScheduler::initialize(ScheduleDAGMI *Dag) { } } +void PostGenericScheduler::initPolicy(MachineBasicBlock::iterator Begin, + MachineBasicBlock::iterator End, + unsigned NumRegionInstrs) { + if (PostRADirection == MISchedPostRASched::TopDown) { + RegionPolicy.OnlyTopDown = true; + RegionPolicy.OnlyBottomUp = false; + } else if (PostRADirection == MISchedPostRASched::BottomUp) { + RegionPolicy.OnlyTopDown = false; + RegionPolicy.OnlyBottomUp = true; + } +} + void PostGenericScheduler::registerRoots() { Rem.CriticalPath = DAG->ExitSU.getDepth(); // Some roots may not feed into ExitSU. Check all of them in case. - for (const SUnit *SU : BotRoots) { + for (const SUnit *SU : Bot.Available) { if (SU->getDepth() > Rem.CriticalPath) Rem.CriticalPath = SU->getDepth(); } @@ -3923,12 +3954,13 @@ bool PostGenericScheduler::tryCandidate(SchedCandidate &Cand, return false; } -void PostGenericScheduler::pickNodeFromQueue(SchedCandidate &Cand) { - ReadyQueue &Q = Top.Available; +void PostGenericScheduler::pickNodeFromQueue(SchedBoundary &Zone, + SchedCandidate &Cand) { + ReadyQueue &Q = Zone.Available; for (SUnit *SU : Q) { SchedCandidate TryCand(Cand.Policy); TryCand.SU = SU; - TryCand.AtTop = true; + TryCand.AtTop = Zone.isTop(); TryCand.initResourceDelta(DAG, SchedModel); if (tryCandidate(Cand, TryCand)) { Cand.setBest(TryCand); @@ -3940,29 +3972,54 @@ void PostGenericScheduler::pickNodeFromQueue(SchedCandidate &Cand) { /// Pick the next node to schedule. SUnit *PostGenericScheduler::pickNode(bool &IsTopNode) { if (DAG->top() == DAG->bottom()) { - assert(Top.Available.empty() && Top.Pending.empty() && "ReadyQ garbage"); + assert(Top.Available.empty() && Top.Pending.empty() && + Bot.Available.empty() && Bot.Pending.empty() && "ReadyQ garbage"); return nullptr; } SUnit *SU; do { - SU = Top.pickOnlyChoice(); - if (SU) { - tracePick(Only1, true); + if (RegionPolicy.OnlyBottomUp) { + assert(!RegionPolicy.OnlyTopDown); + SU = Bot.pickOnlyChoice(); + if (SU) { + tracePick(Only1, true); + } else { + CandPolicy NoPolicy; + SchedCandidate BotCand(NoPolicy); + // Set the bottom-up policy based on the state of the current bottom + // zone and the instructions outside the zone, including the top zone. + setPolicy(BotCand.Policy, /*IsPostRA=*/true, Bot, nullptr); + pickNodeFromQueue(Bot, BotCand); + assert(BotCand.Reason != NoCand && "failed to find a candidate"); + tracePick(BotCand); + SU = BotCand.SU; + } + IsTopNode = false; } else { - CandPolicy NoPolicy; - SchedCandidate TopCand(NoPolicy); - // Set the top-down policy based on the state of the current top zone and - // the instructions outside the zone, including the bottom zone. - setPolicy(TopCand.Policy, /*IsPostRA=*/true, Top, nullptr); - pickNodeFromQueue(TopCand); - assert(TopCand.Reason != NoCand && "failed to find a candidate"); - tracePick(TopCand); - SU = TopCand.SU; + + assert(RegionPolicy.OnlyTopDown); + SU = Top.pickOnlyChoice(); + if (SU) { + tracePick(Only1, true); + } else { + CandPolicy NoPolicy; + SchedCandidate TopCand(NoPolicy); + // Set the top-down policy based on the state of the current top zone + // and the instructions outside the zone, including the bottom zone. + setPolicy(TopCand.Policy, /*IsPostRA=*/true, Top, nullptr); + pickNodeFromQueue(Top, TopCand); + assert(TopCand.Reason != NoCand && "failed to find a candidate"); + tracePick(TopCand); + SU = TopCand.SU; + } + IsTopNode = true; } } while (SU->isScheduled); - IsTopNode = true; - Top.removeReady(SU); + if (SU->isTopReady()) + Top.removeReady(SU); + if (SU->isBottomReady()) + Bot.removeReady(SU); LLVM_DEBUG(dbgs() << "Scheduling SU(" << SU->NodeNum << ") " << *SU->getInstr()); @@ -3972,8 +4029,13 @@ SUnit *PostGenericScheduler::pickNode(bool &IsTopNode) { /// Called after ScheduleDAGMI has scheduled an instruction and updated /// scheduled/remaining flags in the DAG nodes. void PostGenericScheduler::schedNode(SUnit *SU, bool IsTopNode) { - SU->TopReadyCycle = std::max(SU->TopReadyCycle, Top.getCurrCycle()); - Top.bumpNode(SU); + if (IsTopNode) { + SU->TopReadyCycle = std::max(SU->TopReadyCycle, Top.getCurrCycle()); + Top.bumpNode(SU); + } else { + SU->BotReadyCycle = std::max(SU->BotReadyCycle, Bot.getCurrCycle()); + Bot.bumpNode(SU); + } } ScheduleDAGMI *llvm::createGenericSchedPostRA(MachineSchedContext *C) { |