From 38e61122f27a8ca4ef0578eaf6dc5242880d2918 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Fri, 6 Sep 2013 17:32:34 +0000 Subject: [PATCH] Added MachineSchedPolicy. Allow subtargets to customize the generic scheduling strategy. This is convenient for targets that don't need to add new heuristics by specializing the strategy. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190176 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineScheduler.h | 28 +++++++- include/llvm/Target/TargetSubtargetInfo.h | 11 +++ lib/CodeGen/MachineScheduler.cpp | 88 +++++++++++++---------- 3 files changed, 89 insertions(+), 38 deletions(-) diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index e3768bc72bd..18744e71324 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -101,15 +101,39 @@ public: class ScheduleDAGMI; +/// Define a generic scheduling policy for targets that don't provide their own +/// MachineSchedStrategy. This can be overriden for each scheduling region +/// before building the DAG. +struct MachineSchedPolicy { + // Allow the scheduler to disable register pressure tracking. + bool ShouldTrackPressure; + + // Allow the scheduler to force top-down or bottom-up scheduling. If neither + // is true, the scheduler runs in both directions and converges. + bool OnlyTopDown; + bool OnlyBottomUp; + + MachineSchedPolicy(): + ShouldTrackPressure(false), OnlyTopDown(false), OnlyBottomUp(false) {} +}; + /// MachineSchedStrategy - Interface to the scheduling algorithm used by /// ScheduleDAGMI. +/// +/// Initialization sequence: +/// initPolicy -> shouldTrackPressure -> initialize(DAG) -> registerRoots class MachineSchedStrategy { public: virtual ~MachineSchedStrategy() {} + /// Optionally override the per-region scheduling policy. + virtual void initPolicy(MachineBasicBlock::iterator Begin, + MachineBasicBlock::iterator End, + unsigned NumRegionInstrs) {} + /// Check if pressure tracking is needed before building the DAG and - /// initializing this strategy. - virtual bool shouldTrackPressure(unsigned NumRegionInstrs) { return true; } + /// initializing this strategy. Called after initPolicy. + virtual bool shouldTrackPressure() const { return true; } /// Initialize the strategy after building the DAG for a new region. virtual void initialize(ScheduleDAGMI *DAG) = 0; diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h index 2092aba8a28..37365b2a9c7 100644 --- a/include/llvm/Target/TargetSubtargetInfo.h +++ b/include/llvm/Target/TargetSubtargetInfo.h @@ -25,6 +25,7 @@ class SDep; class SUnit; class TargetRegisterClass; class TargetSchedModel; +struct MachineSchedPolicy; template class SmallVectorImpl; //===----------------------------------------------------------------------===// @@ -62,6 +63,16 @@ public: /// scheduler. It does not yet disable the postRA scheduler. virtual bool enableMachineScheduler() const; + /// \brief Override generic scheduling policy within a region. + /// + /// This is a convenient way for targets that don't provide any custom + /// scheduling heuristics (no custom MachineSchedStrategy) to make + /// changes to the generic scheduling policy. + virtual void overrideSchedPolicy(MachineSchedPolicy &Policy, + MachineInstr *begin, + MachineInstr *end, + unsigned NumRegionInstrs) const {} + // enablePostRAScheduler - If the target can benefit from post-regalloc // scheduling and the specified optimization level meets the requirement // return true to enable post-register-allocation scheduling. In diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index 9600cb69430..b854a13f0aa 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -480,12 +480,13 @@ void ScheduleDAGMI::enterRegion(MachineBasicBlock *bb, { ScheduleDAGInstrs::enterRegion(bb, begin, end, regioninstrs); - ShouldTrackPressure = - EnableRegPressure && SchedImpl->shouldTrackPressure(regioninstrs); - // For convenience remember the end of the liveness region. LiveRegionEnd = (RegionEnd == bb->end()) ? RegionEnd : llvm::next(RegionEnd); + + SchedImpl->initPolicy(begin, end, regioninstrs); + + ShouldTrackPressure = SchedImpl->shouldTrackPressure(); } // Setup the register pressure trackers for the top scheduled top and bottom @@ -1594,12 +1595,7 @@ private: SchedBoundary Top; SchedBoundary Bot; - // Allow the driver to force top-down or bottom-up scheduling. If neither is - // true, the scheduler runs in both directions and converges. For generic - // targets, we default to bottom-up, because it's simpler and more - // compile-time optimizations have been implemented in that direction. - bool OnlyBottomUp; - bool OnlyTopDown; + MachineSchedPolicy RegionPolicy; public: /// SUnit::NodeQueueId: 0 (none), 1 (top), 2 (bot), 3 (both) enum { @@ -1610,10 +1606,13 @@ public: ConvergingScheduler(const MachineSchedContext *C): Context(C), DAG(0), SchedModel(0), TRI(0), - Top(TopQID, "TopQ"), Bot(BotQID, "BotQ"), - OnlyBottomUp(true), OnlyTopDown(false) {} + Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {} - virtual bool shouldTrackPressure(unsigned NumRegionInstrs); + virtual void initPolicy(MachineBasicBlock::iterator Begin, + MachineBasicBlock::iterator End, + unsigned NumRegionInstrs); + + bool shouldTrackPressure() const { return RegionPolicy.ShouldTrackPressure; } virtual void initialize(ScheduleDAGMI *dag); @@ -1681,14 +1680,46 @@ init(ScheduleDAGMI *dag, const TargetSchedModel *smodel, SchedRemainder *rem) { ExecutedResCounts.resize(SchedModel->getNumProcResourceKinds()); } -/// Avoid setting up the register pressure tracker for small regions to save -/// compile time. As a rough heuristic, only track pressure when the number -/// of schedulable instructions exceeds half the integer register file. -bool ConvergingScheduler::shouldTrackPressure(unsigned NumRegionInstrs) { - unsigned NIntRegs = Context->RegClassInfo->getNumAllocatableRegs( - Context->MF->getTarget().getTargetLowering()->getRegClassFor(MVT::i32)); +/// Initialize the per-region scheduling policy. +void ConvergingScheduler::initPolicy(MachineBasicBlock::iterator Begin, + MachineBasicBlock::iterator End, + unsigned NumRegionInstrs) { + const TargetMachine &TM = Context->MF->getTarget(); - return NumRegionInstrs > (NIntRegs / 2); + // Avoid setting up the register pressure tracker for small regions to save + // compile time. As a rough heuristic, only track pressure when the number of + // schedulable instructions exceeds half the integer register file. + unsigned NIntRegs = Context->RegClassInfo->getNumAllocatableRegs( + TM.getTargetLowering()->getRegClassFor(MVT::i32)); + + RegionPolicy.ShouldTrackPressure = NumRegionInstrs > (NIntRegs / 2); + + // For generic targets, we default to bottom-up, because it's simpler and more + // compile-time optimizations have been implemented in that direction. + RegionPolicy.OnlyBottomUp = true; + + // Allow the subtarget to override default policy. + const TargetSubtargetInfo &ST = TM.getSubtarget(); + ST.overrideSchedPolicy(RegionPolicy, Begin, End, NumRegionInstrs); + + // After subtarget overrides, apply command line options. + if (!EnableRegPressure) + RegionPolicy.ShouldTrackPressure = false; + + // Check -misched-topdown/bottomup can force or unforce scheduling direction. + // e.g. -misched-bottomup=false allows scheduling in both directions. + assert((!ForceTopDown || !ForceBottomUp) && + "-misched-topdown incompatible with -misched-bottomup"); + if (ForceBottomUp.getNumOccurrences() > 0) { + RegionPolicy.OnlyBottomUp = ForceBottomUp; + if (RegionPolicy.OnlyBottomUp) + RegionPolicy.OnlyTopDown = false; + } + if (ForceTopDown.getNumOccurrences() > 0) { + RegionPolicy.OnlyTopDown = ForceTopDown; + if (RegionPolicy.OnlyTopDown) + RegionPolicy.OnlyBottomUp = false; + } } void ConvergingScheduler::initialize(ScheduleDAGMI *dag) { @@ -1714,21 +1745,6 @@ void ConvergingScheduler::initialize(ScheduleDAGMI *dag) { Bot.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG); } - assert((!ForceTopDown || !ForceBottomUp) && - "-misched-topdown incompatible with -misched-bottomup"); - - // Check -misched-topdown/bottomup can force or unforce scheduling direction. - // e.g. -misched-bottomup=false allows scheduling in both directions. - if (ForceBottomUp.getNumOccurrences() > 0) { - OnlyBottomUp = ForceBottomUp; - if (OnlyBottomUp) - OnlyTopDown = false; - } - if (ForceTopDown.getNumOccurrences() > 0) { - OnlyTopDown = ForceTopDown; - if (OnlyTopDown) - OnlyBottomUp = false; - } } void ConvergingScheduler::releaseTopNode(SUnit *SU) { @@ -2694,7 +2710,7 @@ SUnit *ConvergingScheduler::pickNode(bool &IsTopNode) { } SUnit *SU; do { - if (OnlyTopDown) { + if (RegionPolicy.OnlyTopDown) { SU = Top.pickOnlyChoice(); if (!SU) { CandPolicy NoPolicy; @@ -2706,7 +2722,7 @@ SUnit *ConvergingScheduler::pickNode(bool &IsTopNode) { } IsTopNode = true; } - else if (OnlyBottomUp) { + else if (RegionPolicy.OnlyBottomUp) { SU = Bot.pickOnlyChoice(); if (!SU) { CandPolicy NoPolicy;