Index: llvm/include/llvm/CodeGen/MachineScheduler.h =================================================================== --- llvm/include/llvm/CodeGen/MachineScheduler.h +++ llvm/include/llvm/CodeGen/MachineScheduler.h @@ -691,18 +691,18 @@ /// PendingFlag set. SchedBoundary(unsigned ID, const Twine &Name): Available(ID, Name+".A"), Pending(ID << LogMaxQID, Name+".P") { - reset(); + reset(SchedState()); } ~SchedBoundary(); - void reset(); + void reset(const SchedState &S); const SchedState &getState() const { return State; } void setState(const SchedState &State) { this->State = State; } void init(ScheduleDAGMI *dag, const TargetSchedModel *smodel, - SchedRemainder *rem); + SchedRemainder *rem, const SchedState *State); bool isTop() const { return Available.getID() == TopQID; @@ -1021,11 +1021,13 @@ SchedBoundary Top; SmallVector BotRoots; + typedef DenseMap MBB2StateRec; + MBB2StateRec SchedStates; public: PostGenericScheduler(const MachineSchedContext *C): GenericSchedulerBase(C), Top(SchedBoundary::TopQID, "TopQ") {} - ~PostGenericScheduler() override = default; + ~PostGenericScheduler() override; void initPolicy(MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, @@ -1059,6 +1061,11 @@ BotRoots.push_back(SU); } + bool saveScheduledState(MachineBasicBlock *MBB) override; + + bool restoreScheduledState(MachineBasicBlock *MBB) override; + + void enterMBB(MachineBasicBlock *MBB) override; protected: void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand); Index: llvm/lib/CodeGen/MachineScheduler.cpp =================================================================== --- llvm/lib/CodeGen/MachineScheduler.cpp +++ llvm/lib/CodeGen/MachineScheduler.cpp @@ -1880,7 +1880,7 @@ return (int)(Count - (Latency * LFactor)) > (int)LFactor; } -void SchedBoundary::reset() { +void SchedBoundary::reset(const SchedState &S) { // A new HazardRec is created for each DAG and owned by SchedBoundary. // Destroying and reconstructing it is very expensive though. So keep // invalid, placeholder HazardRecs. @@ -1892,7 +1892,7 @@ Pending.clear(); CheckPending = false; - State = SchedState(); + State = S; } void SchedRemainder:: @@ -1916,8 +1916,9 @@ } void SchedBoundary:: -init(ScheduleDAGMI *dag, const TargetSchedModel *smodel, SchedRemainder *rem) { - reset(); +init(ScheduleDAGMI *dag, const TargetSchedModel *smodel, SchedRemainder *rem, + const SchedState *SS) { + reset(SS ? *SS : SchedState()); DAG = dag; SchedModel = smodel; Rem = rem; @@ -2700,8 +2701,8 @@ TRI = DAG->TRI; Rem.init(DAG, SchedModel); - Top.init(DAG, SchedModel, &Rem); - Bot.init(DAG, SchedModel, &Rem); + Top.init(DAG, SchedModel, &Rem, nullptr); + Bot.init(DAG, SchedModel, &Rem, nullptr); // Initialize resource counts. @@ -3301,13 +3302,20 @@ // PostGenericScheduler - Generic PostRA implementation of MachineSchedStrategy. //===----------------------------------------------------------------------===// +// Check if this is the first region of the MBB topdown. +static bool isFirstRegion(ScheduleDAGMI *DAG) { + return DAG->begin() == DAG->begin()->getParent()->begin(); +} + void PostGenericScheduler::initialize(ScheduleDAGMI *Dag) { DAG = Dag; SchedModel = DAG->getSchedModel(); TRI = DAG->TRI; Rem.init(DAG, SchedModel); - Top.init(DAG, SchedModel, &Rem); + // The sched state in first region has been intialized when enter the MBB. + Top.init(DAG, SchedModel, &Rem, + isFirstRegion(DAG) ? &Top.getState() : nullptr); BotRoots.clear(); // Initialize the HazardRecognizers. If itineraries don't exist, are empty, @@ -3423,6 +3431,28 @@ return SU; } +PostGenericScheduler::~PostGenericScheduler() { + for (auto State : SchedStates) + delete State.second; +} + +bool PostGenericScheduler::saveScheduledState(MachineBasicBlock *MBB) { + SchedStates[MBB] = new SchedState(Top.getState()); + return true; +} + +bool PostGenericScheduler::restoreScheduledState(MachineBasicBlock *MBB) { + if (SchedStates.find(MBB) != SchedStates.end()) { + Top.setState(*SchedStates[MBB]); + return true; + } + return false; +} + +void PostGenericScheduler::enterMBB(MachineBasicBlock *MBB) { + Top.setState(SchedState()); +} + /// Called after ScheduleDAGMI has scheduled an instruction and updated /// scheduled/remaining flags in the DAG nodes. void PostGenericScheduler::schedNode(SUnit *SU, bool IsTopNode) { Index: llvm/lib/Target/PowerPC/PPCSubtarget.h =================================================================== --- llvm/lib/Target/PowerPC/PPCSubtarget.h +++ llvm/lib/Target/PowerPC/PPCSubtarget.h @@ -319,6 +319,8 @@ /// but may expand the ISEL instruction later. bool enableEarlyIfConversion() const override { return true; } + bool forwardScheduledState() const override { return true; } + // Scheduling customization. bool enableMachineScheduler() const override; // This overrides the PostRAScheduler bit in the SchedModel for each CPU.