diff options
author | Matthias Braun <matze@braunis.de> | 2016-06-25 02:03:36 +0000 |
---|---|---|
committer | Matthias Braun <matze@braunis.de> | 2016-06-25 02:03:36 +0000 |
commit | cc676c47a328aaabab9b4d67b2b2f1b48f2cb15e (patch) | |
tree | 081bc385e4c26e2ed30bad0c6a697b851e8e9799 | |
parent | b164a9843bedf4edf6c27c8f575c05933efddca4 (diff) | |
download | bcm5719-llvm-cc676c47a328aaabab9b4d67b2b2f1b48f2cb15e.tar.gz bcm5719-llvm-cc676c47a328aaabab9b4d67b2b2f1b48f2cb15e.zip |
MachineScheduler: Remember top/bottom choice in bidirectional scheduling
Remember the last choice for the top/bottom scheduling boundary in
bidirectional scheduling mode. The top choice should not change if we
schedule at the bottom and vice versa.
This allows us to improve compiletime: We only recalculate the best pick
for one border and re-use the cached top-pick from the other border.
Differential Revision: http://reviews.llvm.org/D19350
llvm-svn: 273766
-rw-r--r-- | llvm/include/llvm/CodeGen/MachineScheduler.h | 29 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MachineScheduler.cpp | 59 |
2 files changed, 77 insertions, 11 deletions
diff --git a/llvm/include/llvm/CodeGen/MachineScheduler.h b/llvm/include/llvm/CodeGen/MachineScheduler.h index 5676fb5ec59..ceadc18a94c 100644 --- a/llvm/include/llvm/CodeGen/MachineScheduler.h +++ b/llvm/include/llvm/CodeGen/MachineScheduler.h @@ -779,6 +779,15 @@ public: unsigned DemandResIdx; CandPolicy(): ReduceLatency(false), ReduceResIdx(0), DemandResIdx(0) {} + + bool operator==(const CandPolicy &RHS) const { + return ReduceLatency == RHS.ReduceLatency && + ReduceResIdx == RHS.ReduceResIdx && + DemandResIdx == RHS.DemandResIdx; + } + bool operator!=(const CandPolicy &RHS) const { + return !(*this == RHS); + } }; /// Status of an instruction's critical resource consumption. @@ -820,8 +829,17 @@ public: // Critical resource consumption of the best candidate. SchedResourceDelta ResDelta; - SchedCandidate(const CandPolicy &policy) - : Policy(policy), SU(nullptr), Reason(NoCand), AtTop(false) {} + SchedCandidate() { reset(CandPolicy()); } + SchedCandidate(const CandPolicy &Policy) { reset(Policy); } + + void reset(const CandPolicy &NewPolicy) { + Policy = NewPolicy; + SU = nullptr; + Reason = NoCand; + AtTop = false; + RPDelta = RegPressureDelta(); + ResDelta = SchedResourceDelta(); + } bool isValid() const { return SU; } @@ -866,6 +884,11 @@ class GenericScheduler : public GenericSchedulerBase { SchedBoundary Top; SchedBoundary Bot; + /// Candidate last picked from Top boundary. + SchedCandidate TopCand; + /// Candidate last picked from Bot boundary. + SchedCandidate BotCand; + MachineSchedPolicy RegionPolicy; public: GenericScheduler(const MachineSchedContext *C): @@ -894,10 +917,12 @@ public: void releaseTopNode(SUnit *SU) override { Top.releaseTopNode(SU); + TopCand.SU = nullptr; } void releaseBottomNode(SUnit *SU) override { Bot.releaseBottomNode(SU); + BotCand.SU = nullptr; } void registerRoots() override; diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp index 59f5607cb68..d8b04202c70 100644 --- a/llvm/lib/CodeGen/MachineScheduler.cpp +++ b/llvm/lib/CodeGen/MachineScheduler.cpp @@ -2557,6 +2557,8 @@ void GenericScheduler::initialize(ScheduleDAGMI *dag) { DAG->MF.getSubtarget().getInstrInfo()->CreateTargetMIHazardRecognizer( Itin, DAG); } + TopCand.SU = nullptr; + BotCand.SU = nullptr; } /// Initialize the per-region scheduling policy. @@ -2954,17 +2956,56 @@ SUnit *GenericScheduler::pickNodeBidirectional(bool &IsTopNode) { CandPolicy TopPolicy; setPolicy(TopPolicy, /*IsPostRA=*/false, Top, &Bot); - // Prefer bottom scheduling when heuristics are silent. - CandPolicy NoPolicy; - SchedCandidate Cand(NoPolicy); + // See if BotCand is still valid (because we previously scheduled from Top). DEBUG(dbgs() << "Picking from Bot:\n"); - pickNodeFromQueue(Bot, BotPolicy, DAG->getBotRPTracker(), Cand); - assert(Cand.Reason != NoCand && "failed to find the first candidate"); + if (!BotCand.isValid() || BotCand.SU->isScheduled || + BotCand.Policy != BotPolicy) { + BotCand.reset(CandPolicy()); + pickNodeFromQueue(Bot, BotPolicy, DAG->getBotRPTracker(), BotCand); + assert(BotCand.Reason != NoCand && "failed to find the first candidate"); + } else { + DEBUG(traceCandidate(BotCand)); +#ifndef NDEBUG + if (VerifyScheduling) { + SchedCandidate TCand; + TCand.reset(CandPolicy()); + pickNodeFromQueue(Bot, BotPolicy, DAG->getBotRPTracker(), TCand); + assert(TCand.SU == BotCand.SU && + "Last pick result should correspond to re-picking right now"); + } +#endif + } // Check if the top Q has a better candidate. DEBUG(dbgs() << "Picking from Top:\n"); - pickNodeFromQueue(Top, TopPolicy, DAG->getTopRPTracker(), Cand); - assert(Cand.Reason != NoCand && "failed to find the first candidate"); + if (!TopCand.isValid() || TopCand.SU->isScheduled || + TopCand.Policy != TopPolicy) { + TopCand.reset(CandPolicy()); + pickNodeFromQueue(Top, TopPolicy, DAG->getTopRPTracker(), TopCand); + assert(TopCand.Reason != NoCand && "failed to find the first candidate"); + } else { + DEBUG(traceCandidate(TopCand)); +#ifndef NDEBUG + if (VerifyScheduling) { + SchedCandidate TCand; + TCand.reset(CandPolicy()); + pickNodeFromQueue(Top, TopPolicy, DAG->getTopRPTracker(), TCand); + assert(TCand.SU == TopCand.SU && + "Last pick result should correspond to re-picking right now"); + } +#endif + } + + // Pick best from BotCand and TopCand. + assert(BotCand.isValid()); + assert(TopCand.isValid()); + SchedCandidate Cand = BotCand; + TopCand.Reason = NoCand; + tryCandidate(Cand, TopCand, nullptr); + if (TopCand.Reason != NoCand) { + Cand.setBest(TopCand); + DEBUG(traceCandidate(Cand)); + } IsTopNode = Cand.AtTop; tracePick(Cand); @@ -2984,7 +3025,7 @@ SUnit *GenericScheduler::pickNode(bool &IsTopNode) { SU = Top.pickOnlyChoice(); if (!SU) { CandPolicy NoPolicy; - SchedCandidate TopCand(NoPolicy); + TopCand.reset(NoPolicy); pickNodeFromQueue(Top, NoPolicy, DAG->getTopRPTracker(), TopCand); assert(TopCand.Reason != NoCand && "failed to find a candidate"); tracePick(TopCand); @@ -2995,7 +3036,7 @@ SUnit *GenericScheduler::pickNode(bool &IsTopNode) { SU = Bot.pickOnlyChoice(); if (!SU) { CandPolicy NoPolicy; - SchedCandidate BotCand(NoPolicy); + BotCand.reset(NoPolicy); pickNodeFromQueue(Bot, NoPolicy, DAG->getBotRPTracker(), BotCand); assert(BotCand.Reason != NoCand && "failed to find a candidate"); tracePick(BotCand); |