xref: /aosp_15_r20/external/llvm/lib/Target/Hexagon/HexagonMachineScheduler.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- HexagonMachineScheduler.h - Custom Hexagon MI scheduler.      ----===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // Custom Hexagon MI scheduler.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONMACHINESCHEDULER_H
15*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_TARGET_HEXAGON_HEXAGONMACHINESCHEDULER_H
16*9880d681SAndroid Build Coastguard Worker 
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/PriorityQueue.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/AliasAnalysis.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LiveIntervalAnalysis.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineScheduler.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/RegisterClassInfo.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/RegisterPressure.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/ResourcePriorityQueue.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/ScheduleDAGInstrs.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/ScheduleHazardRecognizer.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
31*9880d681SAndroid Build Coastguard Worker 
32*9880d681SAndroid Build Coastguard Worker using namespace llvm;
33*9880d681SAndroid Build Coastguard Worker 
34*9880d681SAndroid Build Coastguard Worker namespace llvm {
35*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
36*9880d681SAndroid Build Coastguard Worker // ConvergingVLIWScheduler - Implementation of the standard
37*9880d681SAndroid Build Coastguard Worker // MachineSchedStrategy.
38*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
39*9880d681SAndroid Build Coastguard Worker 
40*9880d681SAndroid Build Coastguard Worker class VLIWResourceModel {
41*9880d681SAndroid Build Coastguard Worker   /// ResourcesModel - Represents VLIW state.
42*9880d681SAndroid Build Coastguard Worker   /// Not limited to VLIW targets per say, but assumes
43*9880d681SAndroid Build Coastguard Worker   /// definition of DFA by a target.
44*9880d681SAndroid Build Coastguard Worker   DFAPacketizer *ResourcesModel;
45*9880d681SAndroid Build Coastguard Worker 
46*9880d681SAndroid Build Coastguard Worker   const TargetSchedModel *SchedModel;
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker   /// Local packet/bundle model. Purely
49*9880d681SAndroid Build Coastguard Worker   /// internal to the MI schedulre at the time.
50*9880d681SAndroid Build Coastguard Worker   std::vector<SUnit*> Packet;
51*9880d681SAndroid Build Coastguard Worker 
52*9880d681SAndroid Build Coastguard Worker   /// Total packets created.
53*9880d681SAndroid Build Coastguard Worker   unsigned TotalPackets;
54*9880d681SAndroid Build Coastguard Worker 
55*9880d681SAndroid Build Coastguard Worker public:
VLIWResourceModel(const TargetSubtargetInfo & STI,const TargetSchedModel * SM)56*9880d681SAndroid Build Coastguard Worker   VLIWResourceModel(const TargetSubtargetInfo &STI, const TargetSchedModel *SM)
57*9880d681SAndroid Build Coastguard Worker       : SchedModel(SM), TotalPackets(0) {
58*9880d681SAndroid Build Coastguard Worker   ResourcesModel = STI.getInstrInfo()->CreateTargetScheduleState(STI);
59*9880d681SAndroid Build Coastguard Worker 
60*9880d681SAndroid Build Coastguard Worker     // This hard requirement could be relaxed,
61*9880d681SAndroid Build Coastguard Worker     // but for now do not let it proceed.
62*9880d681SAndroid Build Coastguard Worker     assert(ResourcesModel && "Unimplemented CreateTargetScheduleState.");
63*9880d681SAndroid Build Coastguard Worker 
64*9880d681SAndroid Build Coastguard Worker     Packet.resize(SchedModel->getIssueWidth());
65*9880d681SAndroid Build Coastguard Worker     Packet.clear();
66*9880d681SAndroid Build Coastguard Worker     ResourcesModel->clearResources();
67*9880d681SAndroid Build Coastguard Worker   }
68*9880d681SAndroid Build Coastguard Worker 
~VLIWResourceModel()69*9880d681SAndroid Build Coastguard Worker   ~VLIWResourceModel() {
70*9880d681SAndroid Build Coastguard Worker     delete ResourcesModel;
71*9880d681SAndroid Build Coastguard Worker   }
72*9880d681SAndroid Build Coastguard Worker 
resetPacketState()73*9880d681SAndroid Build Coastguard Worker   void resetPacketState() {
74*9880d681SAndroid Build Coastguard Worker     Packet.clear();
75*9880d681SAndroid Build Coastguard Worker   }
76*9880d681SAndroid Build Coastguard Worker 
resetDFA()77*9880d681SAndroid Build Coastguard Worker   void resetDFA() {
78*9880d681SAndroid Build Coastguard Worker     ResourcesModel->clearResources();
79*9880d681SAndroid Build Coastguard Worker   }
80*9880d681SAndroid Build Coastguard Worker 
reset()81*9880d681SAndroid Build Coastguard Worker   void reset() {
82*9880d681SAndroid Build Coastguard Worker     Packet.clear();
83*9880d681SAndroid Build Coastguard Worker     ResourcesModel->clearResources();
84*9880d681SAndroid Build Coastguard Worker   }
85*9880d681SAndroid Build Coastguard Worker 
86*9880d681SAndroid Build Coastguard Worker   bool isResourceAvailable(SUnit *SU);
87*9880d681SAndroid Build Coastguard Worker   bool reserveResources(SUnit *SU);
getTotalPackets()88*9880d681SAndroid Build Coastguard Worker   unsigned getTotalPackets() const { return TotalPackets; }
89*9880d681SAndroid Build Coastguard Worker };
90*9880d681SAndroid Build Coastguard Worker 
91*9880d681SAndroid Build Coastguard Worker /// Extend the standard ScheduleDAGMI to provide more context and override the
92*9880d681SAndroid Build Coastguard Worker /// top-level schedule() driver.
93*9880d681SAndroid Build Coastguard Worker class VLIWMachineScheduler : public ScheduleDAGMILive {
94*9880d681SAndroid Build Coastguard Worker public:
VLIWMachineScheduler(MachineSchedContext * C,std::unique_ptr<MachineSchedStrategy> S)95*9880d681SAndroid Build Coastguard Worker   VLIWMachineScheduler(MachineSchedContext *C,
96*9880d681SAndroid Build Coastguard Worker                        std::unique_ptr<MachineSchedStrategy> S)
97*9880d681SAndroid Build Coastguard Worker       : ScheduleDAGMILive(C, std::move(S)) {}
98*9880d681SAndroid Build Coastguard Worker 
99*9880d681SAndroid Build Coastguard Worker   /// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
100*9880d681SAndroid Build Coastguard Worker   /// time to do some work.
101*9880d681SAndroid Build Coastguard Worker   void schedule() override;
102*9880d681SAndroid Build Coastguard Worker   /// Perform platform-specific DAG postprocessing.
103*9880d681SAndroid Build Coastguard Worker   void postprocessDAG();
104*9880d681SAndroid Build Coastguard Worker };
105*9880d681SAndroid Build Coastguard Worker 
106*9880d681SAndroid Build Coastguard Worker /// ConvergingVLIWScheduler shrinks the unscheduled zone using heuristics
107*9880d681SAndroid Build Coastguard Worker /// to balance the schedule.
108*9880d681SAndroid Build Coastguard Worker class ConvergingVLIWScheduler : public MachineSchedStrategy {
109*9880d681SAndroid Build Coastguard Worker 
110*9880d681SAndroid Build Coastguard Worker   /// Store the state used by ConvergingVLIWScheduler heuristics, required
111*9880d681SAndroid Build Coastguard Worker   ///  for the lifetime of one invocation of pickNode().
112*9880d681SAndroid Build Coastguard Worker   struct SchedCandidate {
113*9880d681SAndroid Build Coastguard Worker     // The best SUnit candidate.
114*9880d681SAndroid Build Coastguard Worker     SUnit *SU;
115*9880d681SAndroid Build Coastguard Worker 
116*9880d681SAndroid Build Coastguard Worker     // Register pressure values for the best candidate.
117*9880d681SAndroid Build Coastguard Worker     RegPressureDelta RPDelta;
118*9880d681SAndroid Build Coastguard Worker 
119*9880d681SAndroid Build Coastguard Worker     // Best scheduling cost.
120*9880d681SAndroid Build Coastguard Worker     int SCost;
121*9880d681SAndroid Build Coastguard Worker 
SchedCandidateSchedCandidate122*9880d681SAndroid Build Coastguard Worker     SchedCandidate(): SU(nullptr), SCost(0) {}
123*9880d681SAndroid Build Coastguard Worker   };
124*9880d681SAndroid Build Coastguard Worker   /// Represent the type of SchedCandidate found within a single queue.
125*9880d681SAndroid Build Coastguard Worker   enum CandResult {
126*9880d681SAndroid Build Coastguard Worker     NoCand, NodeOrder, SingleExcess, SingleCritical, SingleMax, MultiPressure,
127*9880d681SAndroid Build Coastguard Worker     BestCost};
128*9880d681SAndroid Build Coastguard Worker 
129*9880d681SAndroid Build Coastguard Worker   /// Each Scheduling boundary is associated with ready queues. It tracks the
130*9880d681SAndroid Build Coastguard Worker   /// current cycle in whichever direction at has moved, and maintains the state
131*9880d681SAndroid Build Coastguard Worker   /// of "hazards" and other interlocks at the current cycle.
132*9880d681SAndroid Build Coastguard Worker   struct VLIWSchedBoundary {
133*9880d681SAndroid Build Coastguard Worker     VLIWMachineScheduler *DAG;
134*9880d681SAndroid Build Coastguard Worker     const TargetSchedModel *SchedModel;
135*9880d681SAndroid Build Coastguard Worker 
136*9880d681SAndroid Build Coastguard Worker     ReadyQueue Available;
137*9880d681SAndroid Build Coastguard Worker     ReadyQueue Pending;
138*9880d681SAndroid Build Coastguard Worker     bool CheckPending;
139*9880d681SAndroid Build Coastguard Worker 
140*9880d681SAndroid Build Coastguard Worker     ScheduleHazardRecognizer *HazardRec;
141*9880d681SAndroid Build Coastguard Worker     VLIWResourceModel *ResourceModel;
142*9880d681SAndroid Build Coastguard Worker 
143*9880d681SAndroid Build Coastguard Worker     unsigned CurrCycle;
144*9880d681SAndroid Build Coastguard Worker     unsigned IssueCount;
145*9880d681SAndroid Build Coastguard Worker 
146*9880d681SAndroid Build Coastguard Worker     /// MinReadyCycle - Cycle of the soonest available instruction.
147*9880d681SAndroid Build Coastguard Worker     unsigned MinReadyCycle;
148*9880d681SAndroid Build Coastguard Worker 
149*9880d681SAndroid Build Coastguard Worker     // Remember the greatest min operand latency.
150*9880d681SAndroid Build Coastguard Worker     unsigned MaxMinLatency;
151*9880d681SAndroid Build Coastguard Worker 
152*9880d681SAndroid Build Coastguard Worker     /// Pending queues extend the ready queues with the same ID and the
153*9880d681SAndroid Build Coastguard Worker     /// PendingFlag set.
VLIWSchedBoundaryVLIWSchedBoundary154*9880d681SAndroid Build Coastguard Worker     VLIWSchedBoundary(unsigned ID, const Twine &Name):
155*9880d681SAndroid Build Coastguard Worker       DAG(nullptr), SchedModel(nullptr), Available(ID, Name+".A"),
156*9880d681SAndroid Build Coastguard Worker       Pending(ID << ConvergingVLIWScheduler::LogMaxQID, Name+".P"),
157*9880d681SAndroid Build Coastguard Worker       CheckPending(false), HazardRec(nullptr), ResourceModel(nullptr),
158*9880d681SAndroid Build Coastguard Worker       CurrCycle(0), IssueCount(0),
159*9880d681SAndroid Build Coastguard Worker       MinReadyCycle(UINT_MAX), MaxMinLatency(0) {}
160*9880d681SAndroid Build Coastguard Worker 
~VLIWSchedBoundaryVLIWSchedBoundary161*9880d681SAndroid Build Coastguard Worker     ~VLIWSchedBoundary() {
162*9880d681SAndroid Build Coastguard Worker       delete ResourceModel;
163*9880d681SAndroid Build Coastguard Worker       delete HazardRec;
164*9880d681SAndroid Build Coastguard Worker     }
165*9880d681SAndroid Build Coastguard Worker 
initVLIWSchedBoundary166*9880d681SAndroid Build Coastguard Worker     void init(VLIWMachineScheduler *dag, const TargetSchedModel *smodel) {
167*9880d681SAndroid Build Coastguard Worker       DAG = dag;
168*9880d681SAndroid Build Coastguard Worker       SchedModel = smodel;
169*9880d681SAndroid Build Coastguard Worker     }
170*9880d681SAndroid Build Coastguard Worker 
isTopVLIWSchedBoundary171*9880d681SAndroid Build Coastguard Worker     bool isTop() const {
172*9880d681SAndroid Build Coastguard Worker       return Available.getID() == ConvergingVLIWScheduler::TopQID;
173*9880d681SAndroid Build Coastguard Worker     }
174*9880d681SAndroid Build Coastguard Worker 
175*9880d681SAndroid Build Coastguard Worker     bool checkHazard(SUnit *SU);
176*9880d681SAndroid Build Coastguard Worker 
177*9880d681SAndroid Build Coastguard Worker     void releaseNode(SUnit *SU, unsigned ReadyCycle);
178*9880d681SAndroid Build Coastguard Worker 
179*9880d681SAndroid Build Coastguard Worker     void bumpCycle();
180*9880d681SAndroid Build Coastguard Worker 
181*9880d681SAndroid Build Coastguard Worker     void bumpNode(SUnit *SU);
182*9880d681SAndroid Build Coastguard Worker 
183*9880d681SAndroid Build Coastguard Worker     void releasePending();
184*9880d681SAndroid Build Coastguard Worker 
185*9880d681SAndroid Build Coastguard Worker     void removeReady(SUnit *SU);
186*9880d681SAndroid Build Coastguard Worker 
187*9880d681SAndroid Build Coastguard Worker     SUnit *pickOnlyChoice();
188*9880d681SAndroid Build Coastguard Worker   };
189*9880d681SAndroid Build Coastguard Worker 
190*9880d681SAndroid Build Coastguard Worker   VLIWMachineScheduler *DAG;
191*9880d681SAndroid Build Coastguard Worker   const TargetSchedModel *SchedModel;
192*9880d681SAndroid Build Coastguard Worker 
193*9880d681SAndroid Build Coastguard Worker   // State of the top and bottom scheduled instruction boundaries.
194*9880d681SAndroid Build Coastguard Worker   VLIWSchedBoundary Top;
195*9880d681SAndroid Build Coastguard Worker   VLIWSchedBoundary Bot;
196*9880d681SAndroid Build Coastguard Worker 
197*9880d681SAndroid Build Coastguard Worker public:
198*9880d681SAndroid Build Coastguard Worker   /// SUnit::NodeQueueId: 0 (none), 1 (top), 2 (bot), 3 (both)
199*9880d681SAndroid Build Coastguard Worker   enum {
200*9880d681SAndroid Build Coastguard Worker     TopQID = 1,
201*9880d681SAndroid Build Coastguard Worker     BotQID = 2,
202*9880d681SAndroid Build Coastguard Worker     LogMaxQID = 2
203*9880d681SAndroid Build Coastguard Worker   };
204*9880d681SAndroid Build Coastguard Worker 
ConvergingVLIWScheduler()205*9880d681SAndroid Build Coastguard Worker   ConvergingVLIWScheduler()
206*9880d681SAndroid Build Coastguard Worker     : DAG(nullptr), SchedModel(nullptr), Top(TopQID, "TopQ"),
207*9880d681SAndroid Build Coastguard Worker       Bot(BotQID, "BotQ") {}
208*9880d681SAndroid Build Coastguard Worker 
209*9880d681SAndroid Build Coastguard Worker   void initialize(ScheduleDAGMI *dag) override;
210*9880d681SAndroid Build Coastguard Worker 
211*9880d681SAndroid Build Coastguard Worker   SUnit *pickNode(bool &IsTopNode) override;
212*9880d681SAndroid Build Coastguard Worker 
213*9880d681SAndroid Build Coastguard Worker   void schedNode(SUnit *SU, bool IsTopNode) override;
214*9880d681SAndroid Build Coastguard Worker 
215*9880d681SAndroid Build Coastguard Worker   void releaseTopNode(SUnit *SU) override;
216*9880d681SAndroid Build Coastguard Worker 
217*9880d681SAndroid Build Coastguard Worker   void releaseBottomNode(SUnit *SU) override;
218*9880d681SAndroid Build Coastguard Worker 
ReportPackets()219*9880d681SAndroid Build Coastguard Worker   unsigned ReportPackets() {
220*9880d681SAndroid Build Coastguard Worker     return Top.ResourceModel->getTotalPackets() +
221*9880d681SAndroid Build Coastguard Worker            Bot.ResourceModel->getTotalPackets();
222*9880d681SAndroid Build Coastguard Worker   }
223*9880d681SAndroid Build Coastguard Worker 
224*9880d681SAndroid Build Coastguard Worker protected:
225*9880d681SAndroid Build Coastguard Worker   SUnit *pickNodeBidrectional(bool &IsTopNode);
226*9880d681SAndroid Build Coastguard Worker 
227*9880d681SAndroid Build Coastguard Worker   int SchedulingCost(ReadyQueue &Q,
228*9880d681SAndroid Build Coastguard Worker                      SUnit *SU, SchedCandidate &Candidate,
229*9880d681SAndroid Build Coastguard Worker                      RegPressureDelta &Delta, bool verbose);
230*9880d681SAndroid Build Coastguard Worker 
231*9880d681SAndroid Build Coastguard Worker   CandResult pickNodeFromQueue(ReadyQueue &Q,
232*9880d681SAndroid Build Coastguard Worker                                const RegPressureTracker &RPTracker,
233*9880d681SAndroid Build Coastguard Worker                                SchedCandidate &Candidate);
234*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
235*9880d681SAndroid Build Coastguard Worker   void traceCandidate(const char *Label, const ReadyQueue &Q, SUnit *SU,
236*9880d681SAndroid Build Coastguard Worker                       PressureChange P = PressureChange());
237*9880d681SAndroid Build Coastguard Worker #endif
238*9880d681SAndroid Build Coastguard Worker };
239*9880d681SAndroid Build Coastguard Worker 
240*9880d681SAndroid Build Coastguard Worker } // namespace
241*9880d681SAndroid Build Coastguard Worker 
242*9880d681SAndroid Build Coastguard Worker 
243*9880d681SAndroid Build Coastguard Worker #endif
244