Home | History | Annotate | Line # | Download | only in SystemZ
      1 //==- SystemZMachineScheduler.h - SystemZ Scheduler Interface ----*- C++ -*-==//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // -------------------------- Post RA scheduling ---------------------------- //
     10 // SystemZPostRASchedStrategy is a scheduling strategy which is plugged into
     11 // the MachineScheduler. It has a sorted Available set of SUs and a pickNode()
     12 // implementation that looks to optimize decoder grouping and balance the
     13 // usage of processor resources. Scheduler states are saved for the end
     14 // region of each MBB, so that a successor block can learn from it.
     15 //===----------------------------------------------------------------------===//
     16 
     17 #include "SystemZHazardRecognizer.h"
     18 #include "llvm/CodeGen/MachineScheduler.h"
     19 #include "llvm/CodeGen/ScheduleDAG.h"
     20 #include <set>
     21 
     22 #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZMACHINESCHEDULER_H
     23 #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZMACHINESCHEDULER_H
     24 
     25 using namespace llvm;
     26 
     27 namespace llvm {
     28 
     29 /// A MachineSchedStrategy implementation for SystemZ post RA scheduling.
     30 class SystemZPostRASchedStrategy : public MachineSchedStrategy {
     31 
     32   const MachineLoopInfo *MLI;
     33   const SystemZInstrInfo *TII;
     34 
     35   // A SchedModel is needed before any DAG is built while advancing past
     36   // non-scheduled instructions, so it would not always be possible to call
     37   // DAG->getSchedClass(SU).
     38   TargetSchedModel SchedModel;
     39 
     40   /// A candidate during instruction evaluation.
     41   struct Candidate {
     42     SUnit *SU = nullptr;
     43 
     44     /// The decoding cost.
     45     int GroupingCost = 0;
     46 
     47     /// The processor resources cost.
     48     int ResourcesCost = 0;
     49 
     50     Candidate() = default;
     51     Candidate(SUnit *SU_, SystemZHazardRecognizer &HazardRec);
     52 
     53     // Compare two candidates.
     54     bool operator<(const Candidate &other);
     55 
     56     // Check if this node is free of cost ("as good as any").
     57     bool noCost() const {
     58       return (GroupingCost <= 0 && !ResourcesCost);
     59     }
     60 
     61 #ifndef NDEBUG
     62     void dumpCosts() {
     63       if (GroupingCost != 0)
     64         dbgs() << "  Grouping cost:" << GroupingCost;
     65       if (ResourcesCost != 0)
     66         dbgs() << "  Resource cost:" << ResourcesCost;
     67     }
     68 #endif
     69   };
     70 
     71   // A sorter for the Available set that makes sure that SUs are considered
     72   // in the best order.
     73   struct SUSorter {
     74     bool operator() (SUnit *lhs, SUnit *rhs) const {
     75       if (lhs->isScheduleHigh && !rhs->isScheduleHigh)
     76         return true;
     77       if (!lhs->isScheduleHigh && rhs->isScheduleHigh)
     78         return false;
     79 
     80       if (lhs->getHeight() > rhs->getHeight())
     81         return true;
     82       else if (lhs->getHeight() < rhs->getHeight())
     83         return false;
     84 
     85       return (lhs->NodeNum < rhs->NodeNum);
     86     }
     87   };
     88   // A set of SUs with a sorter and dump method.
     89   struct SUSet : std::set<SUnit*, SUSorter> {
     90     #ifndef NDEBUG
     91     void dump(SystemZHazardRecognizer &HazardRec) const;
     92     #endif
     93   };
     94 
     95   /// The set of available SUs to schedule next.
     96   SUSet Available;
     97 
     98   /// Current MBB
     99   MachineBasicBlock *MBB;
    100 
    101   /// Maintain hazard recognizers for all blocks, so that the scheduler state
    102   /// can be maintained past BB boundaries when appropariate.
    103   typedef std::map<MachineBasicBlock*, SystemZHazardRecognizer*> MBB2HazRec;
    104   MBB2HazRec SchedStates;
    105 
    106   /// Pointer to the HazardRecognizer that tracks the scheduler state for
    107   /// the current region.
    108   SystemZHazardRecognizer *HazardRec;
    109 
    110   /// Update the scheduler state by emitting (non-scheduled) instructions
    111   /// up to, but not including, NextBegin.
    112   void advanceTo(MachineBasicBlock::iterator NextBegin);
    113 
    114 public:
    115   SystemZPostRASchedStrategy(const MachineSchedContext *C);
    116   virtual ~SystemZPostRASchedStrategy();
    117 
    118   /// Called for a region before scheduling.
    119   void initPolicy(MachineBasicBlock::iterator Begin,
    120                   MachineBasicBlock::iterator End,
    121                   unsigned NumRegionInstrs) override;
    122 
    123   /// PostRA scheduling does not track pressure.
    124   bool shouldTrackPressure() const override { return false; }
    125 
    126   // Process scheduling regions top-down so that scheduler states can be
    127   // transferrred over scheduling boundaries.
    128   bool doMBBSchedRegionsTopDown() const override { return true; }
    129 
    130   void initialize(ScheduleDAGMI *dag) override;
    131 
    132   /// Tell the strategy that MBB is about to be processed.
    133   void enterMBB(MachineBasicBlock *NextMBB) override;
    134 
    135   /// Tell the strategy that current MBB is done.
    136   void leaveMBB() override;
    137 
    138   /// Pick the next node to schedule, or return NULL.
    139   SUnit *pickNode(bool &IsTopNode) override;
    140 
    141   /// ScheduleDAGMI has scheduled an instruction - tell HazardRec
    142   /// about it.
    143   void schedNode(SUnit *SU, bool IsTopNode) override;
    144 
    145   /// SU has had all predecessor dependencies resolved. Put it into
    146   /// Available.
    147   void releaseTopNode(SUnit *SU) override;
    148 
    149   /// Currently only scheduling top-down, so this method is empty.
    150   void releaseBottomNode(SUnit *SU) override {};
    151 };
    152 
    153 } // end namespace llvm
    154 
    155 #endif // LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZMACHINESCHEDULER_H
    156