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