Index: llvm/include/llvm/CodeGen/MachineScheduler.h =================================================================== --- llvm/include/llvm/CodeGen/MachineScheduler.h +++ llvm/include/llvm/CodeGen/MachineScheduler.h @@ -215,11 +215,6 @@ /// This has to be enabled in combination with shouldTrackPressure(). virtual bool shouldTrackLaneMasks() const { return false; } - // If this method returns true, handling of the scheduling regions - // themselves (in case of a scheduling boundary in MBB) will be done - // beginning with the topmost region of MBB. - virtual bool doMBBSchedRegionsTopDown() const { return false; } - /// Initialize the strategy after building the DAG for a new region. virtual void initialize(ScheduleDAGMI *DAG) = 0; @@ -229,6 +224,16 @@ /// Tell the strategy that current MBB is done. virtual void leaveMBB() {}; + /// Return true if save the scheduled state before leaving the MBB + /// successfully. + virtual bool saveScheduledState(MachineBasicBlock *MBB) { return false; } + + /// Return true if restore the scheduled state from pred MBB successfully. + virtual bool restoreScheduledState(MachineBasicBlock *MBB) { return false; } + + /// Return the single pred MBB if it has. + virtual MachineBasicBlock *getScheduledPredMBB(MachineBasicBlock *MBB); + /// Notify this strategy that all roots have been released (including those /// that depend on EntrySU or ExitSU). virtual void registerRoots() {} @@ -296,7 +301,7 @@ /// themselves (in case of a scheduling boundary in MBB) will be done /// beginning with the topmost region of MBB. bool doMBBSchedRegionsTopDown() const override { - return SchedImpl->doMBBSchedRegionsTopDown(); + return MF.getSubtarget().forwardScheduledState(); } // Returns LiveIntervals instance for use in DAG mutators and such. Index: llvm/include/llvm/CodeGen/TargetSubtargetInfo.h =================================================================== --- llvm/include/llvm/CodeGen/TargetSubtargetInfo.h +++ llvm/include/llvm/CodeGen/TargetSubtargetInfo.h @@ -193,6 +193,9 @@ /// for preRA scheduling with the source level scheduler. virtual bool enableMachineSchedDefaultSched() const { return true; } + /// Return true if scheduled state is forwarded between MBBs. + virtual bool forwardScheduledState() const { return false; } + /// True if the subtarget should enable joining global copies. /// /// By default this is enabled if the machine scheduler is enabled, but Index: llvm/lib/CodeGen/MachineScheduler.cpp =================================================================== --- llvm/lib/CodeGen/MachineScheduler.cpp +++ llvm/lib/CodeGen/MachineScheduler.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/PriorityQueue.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/LiveInterval.h" @@ -72,6 +73,8 @@ #define DEBUG_TYPE "machine-scheduler" +STATISTIC(NumFwdSchedState, "Number of scheduled state forwarded"); + namespace llvm { cl::opt ForceTopDown("misched-topdown", cl::Hidden, @@ -145,6 +148,11 @@ delete RegClassInfo; } +MachineBasicBlock *MachineSchedStrategy::getScheduledPredMBB( + MachineBasicBlock *MBB) { + return MBB->pred_size() == 1 ? *MBB->pred_begin() : nullptr; +} + namespace { /// Base class for a machine scheduler class that can run at any point. @@ -685,9 +693,22 @@ void ScheduleDAGMI::startBlock(MachineBasicBlock *bb) { ScheduleDAGInstrs::startBlock(bb); SchedImpl->enterMBB(bb); + + // If current BB has single pred MBB, forward its scheduled + // state to current MBB. + if (MF.getSubtarget().forwardScheduledState()) { + MachineBasicBlock *PredMBB = SchedImpl->getScheduledPredMBB(bb); + if (PredMBB && SchedImpl->restoreScheduledState(PredMBB)) { + NumFwdSchedState ++; + LLVM_DEBUG(dbgs() << "** Initialize scheduled state from " + << printMBBReference(*PredMBB) << "\n";); + } + } } void ScheduleDAGMI::finishBlock() { + if (MF.getSubtarget().forwardScheduledState()) + SchedImpl->saveScheduledState(BB); SchedImpl->leaveMBB(); ScheduleDAGInstrs::finishBlock(); } Index: llvm/lib/Target/SystemZ/SystemZMachineScheduler.h =================================================================== --- llvm/lib/Target/SystemZ/SystemZMachineScheduler.h +++ llvm/lib/Target/SystemZ/SystemZMachineScheduler.h @@ -123,10 +123,6 @@ /// PostRA scheduling does not track pressure. bool shouldTrackPressure() const override { return false; } - // Process scheduling regions top-down so that scheduler states can be - // transferrred over scheduling boundaries. - bool doMBBSchedRegionsTopDown() const override { return true; } - void initialize(ScheduleDAGMI *dag) override; /// Tell the strategy that MBB is about to be processed. Index: llvm/lib/Target/SystemZ/SystemZSubtarget.h =================================================================== --- llvm/lib/Target/SystemZ/SystemZSubtarget.h +++ llvm/lib/Target/SystemZ/SystemZSubtarget.h @@ -95,6 +95,9 @@ // "source" order scheduler. bool enableMachineScheduler() const override { return true; } + // Copy & continue the scheduler states over scheduling boundaries. + bool forwardScheduledState() const override { return true; } + // This is important for reducing register pressure in vector code. bool useAA() const override { return true; }