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