xref: /aosp_15_r20/external/llvm/lib/CodeGen/PostRASchedulerList.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===----- SchedulePostRAList.cpp - list 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 // This implements a top-down list scheduler, using standard algorithms.
11*9880d681SAndroid Build Coastguard Worker // The basic approach uses a priority queue of available nodes to schedule.
12*9880d681SAndroid Build Coastguard Worker // One at a time, nodes are taken from the priority queue (thus in priority
13*9880d681SAndroid Build Coastguard Worker // order), checked for legality to schedule, and emitted if legal.
14*9880d681SAndroid Build Coastguard Worker //
15*9880d681SAndroid Build Coastguard Worker // Nodes may not be legal to schedule either due to structural hazards (e.g.
16*9880d681SAndroid Build Coastguard Worker // pipeline or resource constraints) or because an input to the instruction has
17*9880d681SAndroid Build Coastguard Worker // not completed execution.
18*9880d681SAndroid Build Coastguard Worker //
19*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
20*9880d681SAndroid Build Coastguard Worker 
21*9880d681SAndroid Build Coastguard Worker #include "AggressiveAntiDepBreaker.h"
22*9880d681SAndroid Build Coastguard Worker #include "AntiDepBreaker.h"
23*9880d681SAndroid Build Coastguard Worker #include "CriticalAntiDepBreaker.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/AliasAnalysis.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LatencyPriorityQueue.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineDominators.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineLoopInfo.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/RegisterClassInfo.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/ScheduleDAGInstrs.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/ScheduleHazardRecognizer.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/SchedulerRegistry.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/TargetPassConfig.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
43*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetLowering.h"
44*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h"
45*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetSubtargetInfo.h"
46*9880d681SAndroid Build Coastguard Worker using namespace llvm;
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "post-RA-sched"
49*9880d681SAndroid Build Coastguard Worker 
50*9880d681SAndroid Build Coastguard Worker STATISTIC(NumNoops, "Number of noops inserted");
51*9880d681SAndroid Build Coastguard Worker STATISTIC(NumStalls, "Number of pipeline stalls");
52*9880d681SAndroid Build Coastguard Worker STATISTIC(NumFixedAnti, "Number of fixed anti-dependencies");
53*9880d681SAndroid Build Coastguard Worker 
54*9880d681SAndroid Build Coastguard Worker // Post-RA scheduling is enabled with
55*9880d681SAndroid Build Coastguard Worker // TargetSubtargetInfo.enablePostRAScheduler(). This flag can be used to
56*9880d681SAndroid Build Coastguard Worker // override the target.
57*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
58*9880d681SAndroid Build Coastguard Worker EnablePostRAScheduler("post-RA-scheduler",
59*9880d681SAndroid Build Coastguard Worker                        cl::desc("Enable scheduling after register allocation"),
60*9880d681SAndroid Build Coastguard Worker                        cl::init(false), cl::Hidden);
61*9880d681SAndroid Build Coastguard Worker static cl::opt<std::string>
62*9880d681SAndroid Build Coastguard Worker EnableAntiDepBreaking("break-anti-dependencies",
63*9880d681SAndroid Build Coastguard Worker                       cl::desc("Break post-RA scheduling anti-dependencies: "
64*9880d681SAndroid Build Coastguard Worker                                "\"critical\", \"all\", or \"none\""),
65*9880d681SAndroid Build Coastguard Worker                       cl::init("none"), cl::Hidden);
66*9880d681SAndroid Build Coastguard Worker 
67*9880d681SAndroid Build Coastguard Worker // If DebugDiv > 0 then only schedule MBB with (ID % DebugDiv) == DebugMod
68*9880d681SAndroid Build Coastguard Worker static cl::opt<int>
69*9880d681SAndroid Build Coastguard Worker DebugDiv("postra-sched-debugdiv",
70*9880d681SAndroid Build Coastguard Worker                       cl::desc("Debug control MBBs that are scheduled"),
71*9880d681SAndroid Build Coastguard Worker                       cl::init(0), cl::Hidden);
72*9880d681SAndroid Build Coastguard Worker static cl::opt<int>
73*9880d681SAndroid Build Coastguard Worker DebugMod("postra-sched-debugmod",
74*9880d681SAndroid Build Coastguard Worker                       cl::desc("Debug control MBBs that are scheduled"),
75*9880d681SAndroid Build Coastguard Worker                       cl::init(0), cl::Hidden);
76*9880d681SAndroid Build Coastguard Worker 
~AntiDepBreaker()77*9880d681SAndroid Build Coastguard Worker AntiDepBreaker::~AntiDepBreaker() { }
78*9880d681SAndroid Build Coastguard Worker 
79*9880d681SAndroid Build Coastguard Worker namespace {
80*9880d681SAndroid Build Coastguard Worker   class PostRAScheduler : public MachineFunctionPass {
81*9880d681SAndroid Build Coastguard Worker     const TargetInstrInfo *TII;
82*9880d681SAndroid Build Coastguard Worker     RegisterClassInfo RegClassInfo;
83*9880d681SAndroid Build Coastguard Worker 
84*9880d681SAndroid Build Coastguard Worker   public:
85*9880d681SAndroid Build Coastguard Worker     static char ID;
PostRAScheduler()86*9880d681SAndroid Build Coastguard Worker     PostRAScheduler() : MachineFunctionPass(ID) {}
87*9880d681SAndroid Build Coastguard Worker 
getAnalysisUsage(AnalysisUsage & AU) const88*9880d681SAndroid Build Coastguard Worker     void getAnalysisUsage(AnalysisUsage &AU) const override {
89*9880d681SAndroid Build Coastguard Worker       AU.setPreservesCFG();
90*9880d681SAndroid Build Coastguard Worker       AU.addRequired<AAResultsWrapperPass>();
91*9880d681SAndroid Build Coastguard Worker       AU.addRequired<TargetPassConfig>();
92*9880d681SAndroid Build Coastguard Worker       AU.addRequired<MachineDominatorTree>();
93*9880d681SAndroid Build Coastguard Worker       AU.addPreserved<MachineDominatorTree>();
94*9880d681SAndroid Build Coastguard Worker       AU.addRequired<MachineLoopInfo>();
95*9880d681SAndroid Build Coastguard Worker       AU.addPreserved<MachineLoopInfo>();
96*9880d681SAndroid Build Coastguard Worker       MachineFunctionPass::getAnalysisUsage(AU);
97*9880d681SAndroid Build Coastguard Worker     }
98*9880d681SAndroid Build Coastguard Worker 
getRequiredProperties() const99*9880d681SAndroid Build Coastguard Worker     MachineFunctionProperties getRequiredProperties() const override {
100*9880d681SAndroid Build Coastguard Worker       return MachineFunctionProperties().set(
101*9880d681SAndroid Build Coastguard Worker           MachineFunctionProperties::Property::AllVRegsAllocated);
102*9880d681SAndroid Build Coastguard Worker     }
103*9880d681SAndroid Build Coastguard Worker 
104*9880d681SAndroid Build Coastguard Worker     bool runOnMachineFunction(MachineFunction &Fn) override;
105*9880d681SAndroid Build Coastguard Worker 
106*9880d681SAndroid Build Coastguard Worker   private:
107*9880d681SAndroid Build Coastguard Worker     bool enablePostRAScheduler(
108*9880d681SAndroid Build Coastguard Worker         const TargetSubtargetInfo &ST, CodeGenOpt::Level OptLevel,
109*9880d681SAndroid Build Coastguard Worker         TargetSubtargetInfo::AntiDepBreakMode &Mode,
110*9880d681SAndroid Build Coastguard Worker         TargetSubtargetInfo::RegClassVector &CriticalPathRCs) const;
111*9880d681SAndroid Build Coastguard Worker   };
112*9880d681SAndroid Build Coastguard Worker   char PostRAScheduler::ID = 0;
113*9880d681SAndroid Build Coastguard Worker 
114*9880d681SAndroid Build Coastguard Worker   class SchedulePostRATDList : public ScheduleDAGInstrs {
115*9880d681SAndroid Build Coastguard Worker     /// AvailableQueue - The priority queue to use for the available SUnits.
116*9880d681SAndroid Build Coastguard Worker     ///
117*9880d681SAndroid Build Coastguard Worker     LatencyPriorityQueue AvailableQueue;
118*9880d681SAndroid Build Coastguard Worker 
119*9880d681SAndroid Build Coastguard Worker     /// PendingQueue - This contains all of the instructions whose operands have
120*9880d681SAndroid Build Coastguard Worker     /// been issued, but their results are not ready yet (due to the latency of
121*9880d681SAndroid Build Coastguard Worker     /// the operation).  Once the operands becomes available, the instruction is
122*9880d681SAndroid Build Coastguard Worker     /// added to the AvailableQueue.
123*9880d681SAndroid Build Coastguard Worker     std::vector<SUnit*> PendingQueue;
124*9880d681SAndroid Build Coastguard Worker 
125*9880d681SAndroid Build Coastguard Worker     /// HazardRec - The hazard recognizer to use.
126*9880d681SAndroid Build Coastguard Worker     ScheduleHazardRecognizer *HazardRec;
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker     /// AntiDepBreak - Anti-dependence breaking object, or NULL if none
129*9880d681SAndroid Build Coastguard Worker     AntiDepBreaker *AntiDepBreak;
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker     /// AA - AliasAnalysis for making memory reference queries.
132*9880d681SAndroid Build Coastguard Worker     AliasAnalysis *AA;
133*9880d681SAndroid Build Coastguard Worker 
134*9880d681SAndroid Build Coastguard Worker     /// The schedule. Null SUnit*'s represent noop instructions.
135*9880d681SAndroid Build Coastguard Worker     std::vector<SUnit*> Sequence;
136*9880d681SAndroid Build Coastguard Worker 
137*9880d681SAndroid Build Coastguard Worker     /// Ordered list of DAG postprocessing steps.
138*9880d681SAndroid Build Coastguard Worker     std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
139*9880d681SAndroid Build Coastguard Worker 
140*9880d681SAndroid Build Coastguard Worker     /// The index in BB of RegionEnd.
141*9880d681SAndroid Build Coastguard Worker     ///
142*9880d681SAndroid Build Coastguard Worker     /// This is the instruction number from the top of the current block, not
143*9880d681SAndroid Build Coastguard Worker     /// the SlotIndex. It is only used by the AntiDepBreaker.
144*9880d681SAndroid Build Coastguard Worker     unsigned EndIndex;
145*9880d681SAndroid Build Coastguard Worker 
146*9880d681SAndroid Build Coastguard Worker   public:
147*9880d681SAndroid Build Coastguard Worker     SchedulePostRATDList(
148*9880d681SAndroid Build Coastguard Worker         MachineFunction &MF, MachineLoopInfo &MLI, AliasAnalysis *AA,
149*9880d681SAndroid Build Coastguard Worker         const RegisterClassInfo &,
150*9880d681SAndroid Build Coastguard Worker         TargetSubtargetInfo::AntiDepBreakMode AntiDepMode,
151*9880d681SAndroid Build Coastguard Worker         SmallVectorImpl<const TargetRegisterClass *> &CriticalPathRCs);
152*9880d681SAndroid Build Coastguard Worker 
153*9880d681SAndroid Build Coastguard Worker     ~SchedulePostRATDList() override;
154*9880d681SAndroid Build Coastguard Worker 
155*9880d681SAndroid Build Coastguard Worker     /// startBlock - Initialize register live-range state for scheduling in
156*9880d681SAndroid Build Coastguard Worker     /// this block.
157*9880d681SAndroid Build Coastguard Worker     ///
158*9880d681SAndroid Build Coastguard Worker     void startBlock(MachineBasicBlock *BB) override;
159*9880d681SAndroid Build Coastguard Worker 
160*9880d681SAndroid Build Coastguard Worker     // Set the index of RegionEnd within the current BB.
setEndIndex(unsigned EndIdx)161*9880d681SAndroid Build Coastguard Worker     void setEndIndex(unsigned EndIdx) { EndIndex = EndIdx; }
162*9880d681SAndroid Build Coastguard Worker 
163*9880d681SAndroid Build Coastguard Worker     /// Initialize the scheduler state for the next scheduling region.
164*9880d681SAndroid Build Coastguard Worker     void enterRegion(MachineBasicBlock *bb,
165*9880d681SAndroid Build Coastguard Worker                      MachineBasicBlock::iterator begin,
166*9880d681SAndroid Build Coastguard Worker                      MachineBasicBlock::iterator end,
167*9880d681SAndroid Build Coastguard Worker                      unsigned regioninstrs) override;
168*9880d681SAndroid Build Coastguard Worker 
169*9880d681SAndroid Build Coastguard Worker     /// Notify that the scheduler has finished scheduling the current region.
170*9880d681SAndroid Build Coastguard Worker     void exitRegion() override;
171*9880d681SAndroid Build Coastguard Worker 
172*9880d681SAndroid Build Coastguard Worker     /// Schedule - Schedule the instruction range using list scheduling.
173*9880d681SAndroid Build Coastguard Worker     ///
174*9880d681SAndroid Build Coastguard Worker     void schedule() override;
175*9880d681SAndroid Build Coastguard Worker 
176*9880d681SAndroid Build Coastguard Worker     void EmitSchedule();
177*9880d681SAndroid Build Coastguard Worker 
178*9880d681SAndroid Build Coastguard Worker     /// Observe - Update liveness information to account for the current
179*9880d681SAndroid Build Coastguard Worker     /// instruction, which will not be scheduled.
180*9880d681SAndroid Build Coastguard Worker     ///
181*9880d681SAndroid Build Coastguard Worker     void Observe(MachineInstr &MI, unsigned Count);
182*9880d681SAndroid Build Coastguard Worker 
183*9880d681SAndroid Build Coastguard Worker     /// finishBlock - Clean up register live-range state.
184*9880d681SAndroid Build Coastguard Worker     ///
185*9880d681SAndroid Build Coastguard Worker     void finishBlock() override;
186*9880d681SAndroid Build Coastguard Worker 
187*9880d681SAndroid Build Coastguard Worker   private:
188*9880d681SAndroid Build Coastguard Worker     /// Apply each ScheduleDAGMutation step in order.
189*9880d681SAndroid Build Coastguard Worker     void postprocessDAG();
190*9880d681SAndroid Build Coastguard Worker 
191*9880d681SAndroid Build Coastguard Worker     void ReleaseSucc(SUnit *SU, SDep *SuccEdge);
192*9880d681SAndroid Build Coastguard Worker     void ReleaseSuccessors(SUnit *SU);
193*9880d681SAndroid Build Coastguard Worker     void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle);
194*9880d681SAndroid Build Coastguard Worker     void ListScheduleTopDown();
195*9880d681SAndroid Build Coastguard Worker 
196*9880d681SAndroid Build Coastguard Worker     void dumpSchedule() const;
197*9880d681SAndroid Build Coastguard Worker     void emitNoop(unsigned CurCycle);
198*9880d681SAndroid Build Coastguard Worker   };
199*9880d681SAndroid Build Coastguard Worker }
200*9880d681SAndroid Build Coastguard Worker 
201*9880d681SAndroid Build Coastguard Worker char &llvm::PostRASchedulerID = PostRAScheduler::ID;
202*9880d681SAndroid Build Coastguard Worker 
203*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(PostRAScheduler, "post-RA-sched",
204*9880d681SAndroid Build Coastguard Worker                 "Post RA top-down list latency scheduler", false, false)
205*9880d681SAndroid Build Coastguard Worker 
SchedulePostRATDList(MachineFunction & MF,MachineLoopInfo & MLI,AliasAnalysis * AA,const RegisterClassInfo & RCI,TargetSubtargetInfo::AntiDepBreakMode AntiDepMode,SmallVectorImpl<const TargetRegisterClass * > & CriticalPathRCs)206*9880d681SAndroid Build Coastguard Worker SchedulePostRATDList::SchedulePostRATDList(
207*9880d681SAndroid Build Coastguard Worker     MachineFunction &MF, MachineLoopInfo &MLI, AliasAnalysis *AA,
208*9880d681SAndroid Build Coastguard Worker     const RegisterClassInfo &RCI,
209*9880d681SAndroid Build Coastguard Worker     TargetSubtargetInfo::AntiDepBreakMode AntiDepMode,
210*9880d681SAndroid Build Coastguard Worker     SmallVectorImpl<const TargetRegisterClass *> &CriticalPathRCs)
211*9880d681SAndroid Build Coastguard Worker     : ScheduleDAGInstrs(MF, &MLI), AA(AA), EndIndex(0) {
212*9880d681SAndroid Build Coastguard Worker 
213*9880d681SAndroid Build Coastguard Worker   const InstrItineraryData *InstrItins =
214*9880d681SAndroid Build Coastguard Worker       MF.getSubtarget().getInstrItineraryData();
215*9880d681SAndroid Build Coastguard Worker   HazardRec =
216*9880d681SAndroid Build Coastguard Worker       MF.getSubtarget().getInstrInfo()->CreateTargetPostRAHazardRecognizer(
217*9880d681SAndroid Build Coastguard Worker           InstrItins, this);
218*9880d681SAndroid Build Coastguard Worker   MF.getSubtarget().getPostRAMutations(Mutations);
219*9880d681SAndroid Build Coastguard Worker 
220*9880d681SAndroid Build Coastguard Worker   assert((AntiDepMode == TargetSubtargetInfo::ANTIDEP_NONE ||
221*9880d681SAndroid Build Coastguard Worker           MRI.tracksLiveness()) &&
222*9880d681SAndroid Build Coastguard Worker          "Live-ins must be accurate for anti-dependency breaking");
223*9880d681SAndroid Build Coastguard Worker   AntiDepBreak =
224*9880d681SAndroid Build Coastguard Worker     ((AntiDepMode == TargetSubtargetInfo::ANTIDEP_ALL) ?
225*9880d681SAndroid Build Coastguard Worker      (AntiDepBreaker *)new AggressiveAntiDepBreaker(MF, RCI, CriticalPathRCs) :
226*9880d681SAndroid Build Coastguard Worker      ((AntiDepMode == TargetSubtargetInfo::ANTIDEP_CRITICAL) ?
227*9880d681SAndroid Build Coastguard Worker       (AntiDepBreaker *)new CriticalAntiDepBreaker(MF, RCI) : nullptr));
228*9880d681SAndroid Build Coastguard Worker }
229*9880d681SAndroid Build Coastguard Worker 
~SchedulePostRATDList()230*9880d681SAndroid Build Coastguard Worker SchedulePostRATDList::~SchedulePostRATDList() {
231*9880d681SAndroid Build Coastguard Worker   delete HazardRec;
232*9880d681SAndroid Build Coastguard Worker   delete AntiDepBreak;
233*9880d681SAndroid Build Coastguard Worker }
234*9880d681SAndroid Build Coastguard Worker 
235*9880d681SAndroid Build Coastguard Worker /// Initialize state associated with the next scheduling region.
enterRegion(MachineBasicBlock * bb,MachineBasicBlock::iterator begin,MachineBasicBlock::iterator end,unsigned regioninstrs)236*9880d681SAndroid Build Coastguard Worker void SchedulePostRATDList::enterRegion(MachineBasicBlock *bb,
237*9880d681SAndroid Build Coastguard Worker                  MachineBasicBlock::iterator begin,
238*9880d681SAndroid Build Coastguard Worker                  MachineBasicBlock::iterator end,
239*9880d681SAndroid Build Coastguard Worker                  unsigned regioninstrs) {
240*9880d681SAndroid Build Coastguard Worker   ScheduleDAGInstrs::enterRegion(bb, begin, end, regioninstrs);
241*9880d681SAndroid Build Coastguard Worker   Sequence.clear();
242*9880d681SAndroid Build Coastguard Worker }
243*9880d681SAndroid Build Coastguard Worker 
244*9880d681SAndroid Build Coastguard Worker /// Print the schedule before exiting the region.
exitRegion()245*9880d681SAndroid Build Coastguard Worker void SchedulePostRATDList::exitRegion() {
246*9880d681SAndroid Build Coastguard Worker   DEBUG({
247*9880d681SAndroid Build Coastguard Worker       dbgs() << "*** Final schedule ***\n";
248*9880d681SAndroid Build Coastguard Worker       dumpSchedule();
249*9880d681SAndroid Build Coastguard Worker       dbgs() << '\n';
250*9880d681SAndroid Build Coastguard Worker     });
251*9880d681SAndroid Build Coastguard Worker   ScheduleDAGInstrs::exitRegion();
252*9880d681SAndroid Build Coastguard Worker }
253*9880d681SAndroid Build Coastguard Worker 
254*9880d681SAndroid Build Coastguard Worker #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
255*9880d681SAndroid Build Coastguard Worker /// dumpSchedule - dump the scheduled Sequence.
dumpSchedule() const256*9880d681SAndroid Build Coastguard Worker void SchedulePostRATDList::dumpSchedule() const {
257*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
258*9880d681SAndroid Build Coastguard Worker     if (SUnit *SU = Sequence[i])
259*9880d681SAndroid Build Coastguard Worker       SU->dump(this);
260*9880d681SAndroid Build Coastguard Worker     else
261*9880d681SAndroid Build Coastguard Worker       dbgs() << "**** NOOP ****\n";
262*9880d681SAndroid Build Coastguard Worker   }
263*9880d681SAndroid Build Coastguard Worker }
264*9880d681SAndroid Build Coastguard Worker #endif
265*9880d681SAndroid Build Coastguard Worker 
enablePostRAScheduler(const TargetSubtargetInfo & ST,CodeGenOpt::Level OptLevel,TargetSubtargetInfo::AntiDepBreakMode & Mode,TargetSubtargetInfo::RegClassVector & CriticalPathRCs) const266*9880d681SAndroid Build Coastguard Worker bool PostRAScheduler::enablePostRAScheduler(
267*9880d681SAndroid Build Coastguard Worker     const TargetSubtargetInfo &ST,
268*9880d681SAndroid Build Coastguard Worker     CodeGenOpt::Level OptLevel,
269*9880d681SAndroid Build Coastguard Worker     TargetSubtargetInfo::AntiDepBreakMode &Mode,
270*9880d681SAndroid Build Coastguard Worker     TargetSubtargetInfo::RegClassVector &CriticalPathRCs) const {
271*9880d681SAndroid Build Coastguard Worker   Mode = ST.getAntiDepBreakMode();
272*9880d681SAndroid Build Coastguard Worker   ST.getCriticalPathRCs(CriticalPathRCs);
273*9880d681SAndroid Build Coastguard Worker 
274*9880d681SAndroid Build Coastguard Worker   // Check for explicit enable/disable of post-ra scheduling.
275*9880d681SAndroid Build Coastguard Worker   if (EnablePostRAScheduler.getPosition() > 0)
276*9880d681SAndroid Build Coastguard Worker     return EnablePostRAScheduler;
277*9880d681SAndroid Build Coastguard Worker 
278*9880d681SAndroid Build Coastguard Worker   return ST.enablePostRAScheduler() &&
279*9880d681SAndroid Build Coastguard Worker          OptLevel >= ST.getOptLevelToEnablePostRAScheduler();
280*9880d681SAndroid Build Coastguard Worker }
281*9880d681SAndroid Build Coastguard Worker 
runOnMachineFunction(MachineFunction & Fn)282*9880d681SAndroid Build Coastguard Worker bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) {
283*9880d681SAndroid Build Coastguard Worker   if (skipFunction(*Fn.getFunction()))
284*9880d681SAndroid Build Coastguard Worker     return false;
285*9880d681SAndroid Build Coastguard Worker 
286*9880d681SAndroid Build Coastguard Worker   TII = Fn.getSubtarget().getInstrInfo();
287*9880d681SAndroid Build Coastguard Worker   MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>();
288*9880d681SAndroid Build Coastguard Worker   AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
289*9880d681SAndroid Build Coastguard Worker   TargetPassConfig *PassConfig = &getAnalysis<TargetPassConfig>();
290*9880d681SAndroid Build Coastguard Worker 
291*9880d681SAndroid Build Coastguard Worker   RegClassInfo.runOnMachineFunction(Fn);
292*9880d681SAndroid Build Coastguard Worker 
293*9880d681SAndroid Build Coastguard Worker   TargetSubtargetInfo::AntiDepBreakMode AntiDepMode =
294*9880d681SAndroid Build Coastguard Worker     TargetSubtargetInfo::ANTIDEP_NONE;
295*9880d681SAndroid Build Coastguard Worker   SmallVector<const TargetRegisterClass*, 4> CriticalPathRCs;
296*9880d681SAndroid Build Coastguard Worker 
297*9880d681SAndroid Build Coastguard Worker   // Check that post-RA scheduling is enabled for this target.
298*9880d681SAndroid Build Coastguard Worker   // This may upgrade the AntiDepMode.
299*9880d681SAndroid Build Coastguard Worker   if (!enablePostRAScheduler(Fn.getSubtarget(), PassConfig->getOptLevel(),
300*9880d681SAndroid Build Coastguard Worker                              AntiDepMode, CriticalPathRCs))
301*9880d681SAndroid Build Coastguard Worker     return false;
302*9880d681SAndroid Build Coastguard Worker 
303*9880d681SAndroid Build Coastguard Worker   // Check for antidep breaking override...
304*9880d681SAndroid Build Coastguard Worker   if (EnableAntiDepBreaking.getPosition() > 0) {
305*9880d681SAndroid Build Coastguard Worker     AntiDepMode = (EnableAntiDepBreaking == "all")
306*9880d681SAndroid Build Coastguard Worker       ? TargetSubtargetInfo::ANTIDEP_ALL
307*9880d681SAndroid Build Coastguard Worker       : ((EnableAntiDepBreaking == "critical")
308*9880d681SAndroid Build Coastguard Worker          ? TargetSubtargetInfo::ANTIDEP_CRITICAL
309*9880d681SAndroid Build Coastguard Worker          : TargetSubtargetInfo::ANTIDEP_NONE);
310*9880d681SAndroid Build Coastguard Worker   }
311*9880d681SAndroid Build Coastguard Worker 
312*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "PostRAScheduler\n");
313*9880d681SAndroid Build Coastguard Worker 
314*9880d681SAndroid Build Coastguard Worker   SchedulePostRATDList Scheduler(Fn, MLI, AA, RegClassInfo, AntiDepMode,
315*9880d681SAndroid Build Coastguard Worker                                  CriticalPathRCs);
316*9880d681SAndroid Build Coastguard Worker 
317*9880d681SAndroid Build Coastguard Worker   // Loop over all of the basic blocks
318*9880d681SAndroid Build Coastguard Worker   for (auto &MBB : Fn) {
319*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
320*9880d681SAndroid Build Coastguard Worker     // If DebugDiv > 0 then only schedule MBB with (ID % DebugDiv) == DebugMod
321*9880d681SAndroid Build Coastguard Worker     if (DebugDiv > 0) {
322*9880d681SAndroid Build Coastguard Worker       static int bbcnt = 0;
323*9880d681SAndroid Build Coastguard Worker       if (bbcnt++ % DebugDiv != DebugMod)
324*9880d681SAndroid Build Coastguard Worker         continue;
325*9880d681SAndroid Build Coastguard Worker       dbgs() << "*** DEBUG scheduling " << Fn.getName()
326*9880d681SAndroid Build Coastguard Worker              << ":BB#" << MBB.getNumber() << " ***\n";
327*9880d681SAndroid Build Coastguard Worker     }
328*9880d681SAndroid Build Coastguard Worker #endif
329*9880d681SAndroid Build Coastguard Worker 
330*9880d681SAndroid Build Coastguard Worker     // Initialize register live-range state for scheduling in this block.
331*9880d681SAndroid Build Coastguard Worker     Scheduler.startBlock(&MBB);
332*9880d681SAndroid Build Coastguard Worker 
333*9880d681SAndroid Build Coastguard Worker     // Schedule each sequence of instructions not interrupted by a label
334*9880d681SAndroid Build Coastguard Worker     // or anything else that effectively needs to shut down scheduling.
335*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator Current = MBB.end();
336*9880d681SAndroid Build Coastguard Worker     unsigned Count = MBB.size(), CurrentCount = Count;
337*9880d681SAndroid Build Coastguard Worker     for (MachineBasicBlock::iterator I = Current; I != MBB.begin();) {
338*9880d681SAndroid Build Coastguard Worker       MachineInstr &MI = *std::prev(I);
339*9880d681SAndroid Build Coastguard Worker       --Count;
340*9880d681SAndroid Build Coastguard Worker       // Calls are not scheduling boundaries before register allocation, but
341*9880d681SAndroid Build Coastguard Worker       // post-ra we don't gain anything by scheduling across calls since we
342*9880d681SAndroid Build Coastguard Worker       // don't need to worry about register pressure.
343*9880d681SAndroid Build Coastguard Worker       if (MI.isCall() || TII->isSchedulingBoundary(MI, &MBB, Fn)) {
344*9880d681SAndroid Build Coastguard Worker         Scheduler.enterRegion(&MBB, I, Current, CurrentCount - Count);
345*9880d681SAndroid Build Coastguard Worker         Scheduler.setEndIndex(CurrentCount);
346*9880d681SAndroid Build Coastguard Worker         Scheduler.schedule();
347*9880d681SAndroid Build Coastguard Worker         Scheduler.exitRegion();
348*9880d681SAndroid Build Coastguard Worker         Scheduler.EmitSchedule();
349*9880d681SAndroid Build Coastguard Worker         Current = &MI;
350*9880d681SAndroid Build Coastguard Worker         CurrentCount = Count;
351*9880d681SAndroid Build Coastguard Worker         Scheduler.Observe(MI, CurrentCount);
352*9880d681SAndroid Build Coastguard Worker       }
353*9880d681SAndroid Build Coastguard Worker       I = MI;
354*9880d681SAndroid Build Coastguard Worker       if (MI.isBundle())
355*9880d681SAndroid Build Coastguard Worker         Count -= MI.getBundleSize();
356*9880d681SAndroid Build Coastguard Worker     }
357*9880d681SAndroid Build Coastguard Worker     assert(Count == 0 && "Instruction count mismatch!");
358*9880d681SAndroid Build Coastguard Worker     assert((MBB.begin() == Current || CurrentCount != 0) &&
359*9880d681SAndroid Build Coastguard Worker            "Instruction count mismatch!");
360*9880d681SAndroid Build Coastguard Worker     Scheduler.enterRegion(&MBB, MBB.begin(), Current, CurrentCount);
361*9880d681SAndroid Build Coastguard Worker     Scheduler.setEndIndex(CurrentCount);
362*9880d681SAndroid Build Coastguard Worker     Scheduler.schedule();
363*9880d681SAndroid Build Coastguard Worker     Scheduler.exitRegion();
364*9880d681SAndroid Build Coastguard Worker     Scheduler.EmitSchedule();
365*9880d681SAndroid Build Coastguard Worker 
366*9880d681SAndroid Build Coastguard Worker     // Clean up register live-range state.
367*9880d681SAndroid Build Coastguard Worker     Scheduler.finishBlock();
368*9880d681SAndroid Build Coastguard Worker 
369*9880d681SAndroid Build Coastguard Worker     // Update register kills
370*9880d681SAndroid Build Coastguard Worker     Scheduler.fixupKills(&MBB);
371*9880d681SAndroid Build Coastguard Worker   }
372*9880d681SAndroid Build Coastguard Worker 
373*9880d681SAndroid Build Coastguard Worker   return true;
374*9880d681SAndroid Build Coastguard Worker }
375*9880d681SAndroid Build Coastguard Worker 
376*9880d681SAndroid Build Coastguard Worker /// StartBlock - Initialize register live-range state for scheduling in
377*9880d681SAndroid Build Coastguard Worker /// this block.
378*9880d681SAndroid Build Coastguard Worker ///
startBlock(MachineBasicBlock * BB)379*9880d681SAndroid Build Coastguard Worker void SchedulePostRATDList::startBlock(MachineBasicBlock *BB) {
380*9880d681SAndroid Build Coastguard Worker   // Call the superclass.
381*9880d681SAndroid Build Coastguard Worker   ScheduleDAGInstrs::startBlock(BB);
382*9880d681SAndroid Build Coastguard Worker 
383*9880d681SAndroid Build Coastguard Worker   // Reset the hazard recognizer and anti-dep breaker.
384*9880d681SAndroid Build Coastguard Worker   HazardRec->Reset();
385*9880d681SAndroid Build Coastguard Worker   if (AntiDepBreak)
386*9880d681SAndroid Build Coastguard Worker     AntiDepBreak->StartBlock(BB);
387*9880d681SAndroid Build Coastguard Worker }
388*9880d681SAndroid Build Coastguard Worker 
389*9880d681SAndroid Build Coastguard Worker /// Schedule - Schedule the instruction range using list scheduling.
390*9880d681SAndroid Build Coastguard Worker ///
schedule()391*9880d681SAndroid Build Coastguard Worker void SchedulePostRATDList::schedule() {
392*9880d681SAndroid Build Coastguard Worker   // Build the scheduling graph.
393*9880d681SAndroid Build Coastguard Worker   buildSchedGraph(AA);
394*9880d681SAndroid Build Coastguard Worker 
395*9880d681SAndroid Build Coastguard Worker   if (AntiDepBreak) {
396*9880d681SAndroid Build Coastguard Worker     unsigned Broken =
397*9880d681SAndroid Build Coastguard Worker       AntiDepBreak->BreakAntiDependencies(SUnits, RegionBegin, RegionEnd,
398*9880d681SAndroid Build Coastguard Worker                                           EndIndex, DbgValues);
399*9880d681SAndroid Build Coastguard Worker 
400*9880d681SAndroid Build Coastguard Worker     if (Broken != 0) {
401*9880d681SAndroid Build Coastguard Worker       // We made changes. Update the dependency graph.
402*9880d681SAndroid Build Coastguard Worker       // Theoretically we could update the graph in place:
403*9880d681SAndroid Build Coastguard Worker       // When a live range is changed to use a different register, remove
404*9880d681SAndroid Build Coastguard Worker       // the def's anti-dependence *and* output-dependence edges due to
405*9880d681SAndroid Build Coastguard Worker       // that register, and add new anti-dependence and output-dependence
406*9880d681SAndroid Build Coastguard Worker       // edges based on the next live range of the register.
407*9880d681SAndroid Build Coastguard Worker       ScheduleDAG::clearDAG();
408*9880d681SAndroid Build Coastguard Worker       buildSchedGraph(AA);
409*9880d681SAndroid Build Coastguard Worker 
410*9880d681SAndroid Build Coastguard Worker       NumFixedAnti += Broken;
411*9880d681SAndroid Build Coastguard Worker     }
412*9880d681SAndroid Build Coastguard Worker   }
413*9880d681SAndroid Build Coastguard Worker 
414*9880d681SAndroid Build Coastguard Worker   postprocessDAG();
415*9880d681SAndroid Build Coastguard Worker 
416*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "********** List Scheduling **********\n");
417*9880d681SAndroid Build Coastguard Worker   DEBUG(
418*9880d681SAndroid Build Coastguard Worker     for (const SUnit &SU : SUnits) {
419*9880d681SAndroid Build Coastguard Worker       SU.dumpAll(this);
420*9880d681SAndroid Build Coastguard Worker       dbgs() << '\n';
421*9880d681SAndroid Build Coastguard Worker     }
422*9880d681SAndroid Build Coastguard Worker   );
423*9880d681SAndroid Build Coastguard Worker 
424*9880d681SAndroid Build Coastguard Worker   AvailableQueue.initNodes(SUnits);
425*9880d681SAndroid Build Coastguard Worker   ListScheduleTopDown();
426*9880d681SAndroid Build Coastguard Worker   AvailableQueue.releaseState();
427*9880d681SAndroid Build Coastguard Worker }
428*9880d681SAndroid Build Coastguard Worker 
429*9880d681SAndroid Build Coastguard Worker /// Observe - Update liveness information to account for the current
430*9880d681SAndroid Build Coastguard Worker /// instruction, which will not be scheduled.
431*9880d681SAndroid Build Coastguard Worker ///
Observe(MachineInstr & MI,unsigned Count)432*9880d681SAndroid Build Coastguard Worker void SchedulePostRATDList::Observe(MachineInstr &MI, unsigned Count) {
433*9880d681SAndroid Build Coastguard Worker   if (AntiDepBreak)
434*9880d681SAndroid Build Coastguard Worker     AntiDepBreak->Observe(MI, Count, EndIndex);
435*9880d681SAndroid Build Coastguard Worker }
436*9880d681SAndroid Build Coastguard Worker 
437*9880d681SAndroid Build Coastguard Worker /// FinishBlock - Clean up register live-range state.
438*9880d681SAndroid Build Coastguard Worker ///
finishBlock()439*9880d681SAndroid Build Coastguard Worker void SchedulePostRATDList::finishBlock() {
440*9880d681SAndroid Build Coastguard Worker   if (AntiDepBreak)
441*9880d681SAndroid Build Coastguard Worker     AntiDepBreak->FinishBlock();
442*9880d681SAndroid Build Coastguard Worker 
443*9880d681SAndroid Build Coastguard Worker   // Call the superclass.
444*9880d681SAndroid Build Coastguard Worker   ScheduleDAGInstrs::finishBlock();
445*9880d681SAndroid Build Coastguard Worker }
446*9880d681SAndroid Build Coastguard Worker 
447*9880d681SAndroid Build Coastguard Worker /// Apply each ScheduleDAGMutation step in order.
postprocessDAG()448*9880d681SAndroid Build Coastguard Worker void SchedulePostRATDList::postprocessDAG() {
449*9880d681SAndroid Build Coastguard Worker   for (auto &M : Mutations)
450*9880d681SAndroid Build Coastguard Worker     M->apply(this);
451*9880d681SAndroid Build Coastguard Worker }
452*9880d681SAndroid Build Coastguard Worker 
453*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
454*9880d681SAndroid Build Coastguard Worker //  Top-Down Scheduling
455*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
456*9880d681SAndroid Build Coastguard Worker 
457*9880d681SAndroid Build Coastguard Worker /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to
458*9880d681SAndroid Build Coastguard Worker /// the PendingQueue if the count reaches zero.
ReleaseSucc(SUnit * SU,SDep * SuccEdge)459*9880d681SAndroid Build Coastguard Worker void SchedulePostRATDList::ReleaseSucc(SUnit *SU, SDep *SuccEdge) {
460*9880d681SAndroid Build Coastguard Worker   SUnit *SuccSU = SuccEdge->getSUnit();
461*9880d681SAndroid Build Coastguard Worker 
462*9880d681SAndroid Build Coastguard Worker   if (SuccEdge->isWeak()) {
463*9880d681SAndroid Build Coastguard Worker     --SuccSU->WeakPredsLeft;
464*9880d681SAndroid Build Coastguard Worker     return;
465*9880d681SAndroid Build Coastguard Worker   }
466*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
467*9880d681SAndroid Build Coastguard Worker   if (SuccSU->NumPredsLeft == 0) {
468*9880d681SAndroid Build Coastguard Worker     dbgs() << "*** Scheduling failed! ***\n";
469*9880d681SAndroid Build Coastguard Worker     SuccSU->dump(this);
470*9880d681SAndroid Build Coastguard Worker     dbgs() << " has been released too many times!\n";
471*9880d681SAndroid Build Coastguard Worker     llvm_unreachable(nullptr);
472*9880d681SAndroid Build Coastguard Worker   }
473*9880d681SAndroid Build Coastguard Worker #endif
474*9880d681SAndroid Build Coastguard Worker   --SuccSU->NumPredsLeft;
475*9880d681SAndroid Build Coastguard Worker 
476*9880d681SAndroid Build Coastguard Worker   // Standard scheduler algorithms will recompute the depth of the successor
477*9880d681SAndroid Build Coastguard Worker   // here as such:
478*9880d681SAndroid Build Coastguard Worker   //   SuccSU->setDepthToAtLeast(SU->getDepth() + SuccEdge->getLatency());
479*9880d681SAndroid Build Coastguard Worker   //
480*9880d681SAndroid Build Coastguard Worker   // However, we lazily compute node depth instead. Note that
481*9880d681SAndroid Build Coastguard Worker   // ScheduleNodeTopDown has already updated the depth of this node which causes
482*9880d681SAndroid Build Coastguard Worker   // all descendents to be marked dirty. Setting the successor depth explicitly
483*9880d681SAndroid Build Coastguard Worker   // here would cause depth to be recomputed for all its ancestors. If the
484*9880d681SAndroid Build Coastguard Worker   // successor is not yet ready (because of a transitively redundant edge) then
485*9880d681SAndroid Build Coastguard Worker   // this causes depth computation to be quadratic in the size of the DAG.
486*9880d681SAndroid Build Coastguard Worker 
487*9880d681SAndroid Build Coastguard Worker   // If all the node's predecessors are scheduled, this node is ready
488*9880d681SAndroid Build Coastguard Worker   // to be scheduled. Ignore the special ExitSU node.
489*9880d681SAndroid Build Coastguard Worker   if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU)
490*9880d681SAndroid Build Coastguard Worker     PendingQueue.push_back(SuccSU);
491*9880d681SAndroid Build Coastguard Worker }
492*9880d681SAndroid Build Coastguard Worker 
493*9880d681SAndroid Build Coastguard Worker /// ReleaseSuccessors - Call ReleaseSucc on each of SU's successors.
ReleaseSuccessors(SUnit * SU)494*9880d681SAndroid Build Coastguard Worker void SchedulePostRATDList::ReleaseSuccessors(SUnit *SU) {
495*9880d681SAndroid Build Coastguard Worker   for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
496*9880d681SAndroid Build Coastguard Worker        I != E; ++I) {
497*9880d681SAndroid Build Coastguard Worker     ReleaseSucc(SU, &*I);
498*9880d681SAndroid Build Coastguard Worker   }
499*9880d681SAndroid Build Coastguard Worker }
500*9880d681SAndroid Build Coastguard Worker 
501*9880d681SAndroid Build Coastguard Worker /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending
502*9880d681SAndroid Build Coastguard Worker /// count of its successors. If a successor pending count is zero, add it to
503*9880d681SAndroid Build Coastguard Worker /// the Available queue.
ScheduleNodeTopDown(SUnit * SU,unsigned CurCycle)504*9880d681SAndroid Build Coastguard Worker void SchedulePostRATDList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) {
505*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "*** Scheduling [" << CurCycle << "]: ");
506*9880d681SAndroid Build Coastguard Worker   DEBUG(SU->dump(this));
507*9880d681SAndroid Build Coastguard Worker 
508*9880d681SAndroid Build Coastguard Worker   Sequence.push_back(SU);
509*9880d681SAndroid Build Coastguard Worker   assert(CurCycle >= SU->getDepth() &&
510*9880d681SAndroid Build Coastguard Worker          "Node scheduled above its depth!");
511*9880d681SAndroid Build Coastguard Worker   SU->setDepthToAtLeast(CurCycle);
512*9880d681SAndroid Build Coastguard Worker 
513*9880d681SAndroid Build Coastguard Worker   ReleaseSuccessors(SU);
514*9880d681SAndroid Build Coastguard Worker   SU->isScheduled = true;
515*9880d681SAndroid Build Coastguard Worker   AvailableQueue.scheduledNode(SU);
516*9880d681SAndroid Build Coastguard Worker }
517*9880d681SAndroid Build Coastguard Worker 
518*9880d681SAndroid Build Coastguard Worker /// emitNoop - Add a noop to the current instruction sequence.
emitNoop(unsigned CurCycle)519*9880d681SAndroid Build Coastguard Worker void SchedulePostRATDList::emitNoop(unsigned CurCycle) {
520*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "*** Emitting noop in cycle " << CurCycle << '\n');
521*9880d681SAndroid Build Coastguard Worker   HazardRec->EmitNoop();
522*9880d681SAndroid Build Coastguard Worker   Sequence.push_back(nullptr);   // NULL here means noop
523*9880d681SAndroid Build Coastguard Worker   ++NumNoops;
524*9880d681SAndroid Build Coastguard Worker }
525*9880d681SAndroid Build Coastguard Worker 
526*9880d681SAndroid Build Coastguard Worker /// ListScheduleTopDown - The main loop of list scheduling for top-down
527*9880d681SAndroid Build Coastguard Worker /// schedulers.
ListScheduleTopDown()528*9880d681SAndroid Build Coastguard Worker void SchedulePostRATDList::ListScheduleTopDown() {
529*9880d681SAndroid Build Coastguard Worker   unsigned CurCycle = 0;
530*9880d681SAndroid Build Coastguard Worker 
531*9880d681SAndroid Build Coastguard Worker   // We're scheduling top-down but we're visiting the regions in
532*9880d681SAndroid Build Coastguard Worker   // bottom-up order, so we don't know the hazards at the start of a
533*9880d681SAndroid Build Coastguard Worker   // region. So assume no hazards (this should usually be ok as most
534*9880d681SAndroid Build Coastguard Worker   // blocks are a single region).
535*9880d681SAndroid Build Coastguard Worker   HazardRec->Reset();
536*9880d681SAndroid Build Coastguard Worker 
537*9880d681SAndroid Build Coastguard Worker   // Release any successors of the special Entry node.
538*9880d681SAndroid Build Coastguard Worker   ReleaseSuccessors(&EntrySU);
539*9880d681SAndroid Build Coastguard Worker 
540*9880d681SAndroid Build Coastguard Worker   // Add all leaves to Available queue.
541*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
542*9880d681SAndroid Build Coastguard Worker     // It is available if it has no predecessors.
543*9880d681SAndroid Build Coastguard Worker     if (!SUnits[i].NumPredsLeft && !SUnits[i].isAvailable) {
544*9880d681SAndroid Build Coastguard Worker       AvailableQueue.push(&SUnits[i]);
545*9880d681SAndroid Build Coastguard Worker       SUnits[i].isAvailable = true;
546*9880d681SAndroid Build Coastguard Worker     }
547*9880d681SAndroid Build Coastguard Worker   }
548*9880d681SAndroid Build Coastguard Worker 
549*9880d681SAndroid Build Coastguard Worker   // In any cycle where we can't schedule any instructions, we must
550*9880d681SAndroid Build Coastguard Worker   // stall or emit a noop, depending on the target.
551*9880d681SAndroid Build Coastguard Worker   bool CycleHasInsts = false;
552*9880d681SAndroid Build Coastguard Worker 
553*9880d681SAndroid Build Coastguard Worker   // While Available queue is not empty, grab the node with the highest
554*9880d681SAndroid Build Coastguard Worker   // priority. If it is not ready put it back.  Schedule the node.
555*9880d681SAndroid Build Coastguard Worker   std::vector<SUnit*> NotReady;
556*9880d681SAndroid Build Coastguard Worker   Sequence.reserve(SUnits.size());
557*9880d681SAndroid Build Coastguard Worker   while (!AvailableQueue.empty() || !PendingQueue.empty()) {
558*9880d681SAndroid Build Coastguard Worker     // Check to see if any of the pending instructions are ready to issue.  If
559*9880d681SAndroid Build Coastguard Worker     // so, add them to the available queue.
560*9880d681SAndroid Build Coastguard Worker     unsigned MinDepth = ~0u;
561*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) {
562*9880d681SAndroid Build Coastguard Worker       if (PendingQueue[i]->getDepth() <= CurCycle) {
563*9880d681SAndroid Build Coastguard Worker         AvailableQueue.push(PendingQueue[i]);
564*9880d681SAndroid Build Coastguard Worker         PendingQueue[i]->isAvailable = true;
565*9880d681SAndroid Build Coastguard Worker         PendingQueue[i] = PendingQueue.back();
566*9880d681SAndroid Build Coastguard Worker         PendingQueue.pop_back();
567*9880d681SAndroid Build Coastguard Worker         --i; --e;
568*9880d681SAndroid Build Coastguard Worker       } else if (PendingQueue[i]->getDepth() < MinDepth)
569*9880d681SAndroid Build Coastguard Worker         MinDepth = PendingQueue[i]->getDepth();
570*9880d681SAndroid Build Coastguard Worker     }
571*9880d681SAndroid Build Coastguard Worker 
572*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "\n*** Examining Available\n"; AvailableQueue.dump(this));
573*9880d681SAndroid Build Coastguard Worker 
574*9880d681SAndroid Build Coastguard Worker     SUnit *FoundSUnit = nullptr, *NotPreferredSUnit = nullptr;
575*9880d681SAndroid Build Coastguard Worker     bool HasNoopHazards = false;
576*9880d681SAndroid Build Coastguard Worker     while (!AvailableQueue.empty()) {
577*9880d681SAndroid Build Coastguard Worker       SUnit *CurSUnit = AvailableQueue.pop();
578*9880d681SAndroid Build Coastguard Worker 
579*9880d681SAndroid Build Coastguard Worker       ScheduleHazardRecognizer::HazardType HT =
580*9880d681SAndroid Build Coastguard Worker         HazardRec->getHazardType(CurSUnit, 0/*no stalls*/);
581*9880d681SAndroid Build Coastguard Worker       if (HT == ScheduleHazardRecognizer::NoHazard) {
582*9880d681SAndroid Build Coastguard Worker         if (HazardRec->ShouldPreferAnother(CurSUnit)) {
583*9880d681SAndroid Build Coastguard Worker           if (!NotPreferredSUnit) {
584*9880d681SAndroid Build Coastguard Worker             // If this is the first non-preferred node for this cycle, then
585*9880d681SAndroid Build Coastguard Worker             // record it and continue searching for a preferred node. If this
586*9880d681SAndroid Build Coastguard Worker             // is not the first non-preferred node, then treat it as though
587*9880d681SAndroid Build Coastguard Worker             // there had been a hazard.
588*9880d681SAndroid Build Coastguard Worker             NotPreferredSUnit = CurSUnit;
589*9880d681SAndroid Build Coastguard Worker             continue;
590*9880d681SAndroid Build Coastguard Worker           }
591*9880d681SAndroid Build Coastguard Worker         } else {
592*9880d681SAndroid Build Coastguard Worker           FoundSUnit = CurSUnit;
593*9880d681SAndroid Build Coastguard Worker           break;
594*9880d681SAndroid Build Coastguard Worker         }
595*9880d681SAndroid Build Coastguard Worker       }
596*9880d681SAndroid Build Coastguard Worker 
597*9880d681SAndroid Build Coastguard Worker       // Remember if this is a noop hazard.
598*9880d681SAndroid Build Coastguard Worker       HasNoopHazards |= HT == ScheduleHazardRecognizer::NoopHazard;
599*9880d681SAndroid Build Coastguard Worker 
600*9880d681SAndroid Build Coastguard Worker       NotReady.push_back(CurSUnit);
601*9880d681SAndroid Build Coastguard Worker     }
602*9880d681SAndroid Build Coastguard Worker 
603*9880d681SAndroid Build Coastguard Worker     // If we have a non-preferred node, push it back onto the available list.
604*9880d681SAndroid Build Coastguard Worker     // If we did not find a preferred node, then schedule this first
605*9880d681SAndroid Build Coastguard Worker     // non-preferred node.
606*9880d681SAndroid Build Coastguard Worker     if (NotPreferredSUnit) {
607*9880d681SAndroid Build Coastguard Worker       if (!FoundSUnit) {
608*9880d681SAndroid Build Coastguard Worker         DEBUG(dbgs() << "*** Will schedule a non-preferred instruction...\n");
609*9880d681SAndroid Build Coastguard Worker         FoundSUnit = NotPreferredSUnit;
610*9880d681SAndroid Build Coastguard Worker       } else {
611*9880d681SAndroid Build Coastguard Worker         AvailableQueue.push(NotPreferredSUnit);
612*9880d681SAndroid Build Coastguard Worker       }
613*9880d681SAndroid Build Coastguard Worker 
614*9880d681SAndroid Build Coastguard Worker       NotPreferredSUnit = nullptr;
615*9880d681SAndroid Build Coastguard Worker     }
616*9880d681SAndroid Build Coastguard Worker 
617*9880d681SAndroid Build Coastguard Worker     // Add the nodes that aren't ready back onto the available list.
618*9880d681SAndroid Build Coastguard Worker     if (!NotReady.empty()) {
619*9880d681SAndroid Build Coastguard Worker       AvailableQueue.push_all(NotReady);
620*9880d681SAndroid Build Coastguard Worker       NotReady.clear();
621*9880d681SAndroid Build Coastguard Worker     }
622*9880d681SAndroid Build Coastguard Worker 
623*9880d681SAndroid Build Coastguard Worker     // If we found a node to schedule...
624*9880d681SAndroid Build Coastguard Worker     if (FoundSUnit) {
625*9880d681SAndroid Build Coastguard Worker       // If we need to emit noops prior to this instruction, then do so.
626*9880d681SAndroid Build Coastguard Worker       unsigned NumPreNoops = HazardRec->PreEmitNoops(FoundSUnit);
627*9880d681SAndroid Build Coastguard Worker       for (unsigned i = 0; i != NumPreNoops; ++i)
628*9880d681SAndroid Build Coastguard Worker         emitNoop(CurCycle);
629*9880d681SAndroid Build Coastguard Worker 
630*9880d681SAndroid Build Coastguard Worker       // ... schedule the node...
631*9880d681SAndroid Build Coastguard Worker       ScheduleNodeTopDown(FoundSUnit, CurCycle);
632*9880d681SAndroid Build Coastguard Worker       HazardRec->EmitInstruction(FoundSUnit);
633*9880d681SAndroid Build Coastguard Worker       CycleHasInsts = true;
634*9880d681SAndroid Build Coastguard Worker       if (HazardRec->atIssueLimit()) {
635*9880d681SAndroid Build Coastguard Worker         DEBUG(dbgs() << "*** Max instructions per cycle " << CurCycle << '\n');
636*9880d681SAndroid Build Coastguard Worker         HazardRec->AdvanceCycle();
637*9880d681SAndroid Build Coastguard Worker         ++CurCycle;
638*9880d681SAndroid Build Coastguard Worker         CycleHasInsts = false;
639*9880d681SAndroid Build Coastguard Worker       }
640*9880d681SAndroid Build Coastguard Worker     } else {
641*9880d681SAndroid Build Coastguard Worker       if (CycleHasInsts) {
642*9880d681SAndroid Build Coastguard Worker         DEBUG(dbgs() << "*** Finished cycle " << CurCycle << '\n');
643*9880d681SAndroid Build Coastguard Worker         HazardRec->AdvanceCycle();
644*9880d681SAndroid Build Coastguard Worker       } else if (!HasNoopHazards) {
645*9880d681SAndroid Build Coastguard Worker         // Otherwise, we have a pipeline stall, but no other problem,
646*9880d681SAndroid Build Coastguard Worker         // just advance the current cycle and try again.
647*9880d681SAndroid Build Coastguard Worker         DEBUG(dbgs() << "*** Stall in cycle " << CurCycle << '\n');
648*9880d681SAndroid Build Coastguard Worker         HazardRec->AdvanceCycle();
649*9880d681SAndroid Build Coastguard Worker         ++NumStalls;
650*9880d681SAndroid Build Coastguard Worker       } else {
651*9880d681SAndroid Build Coastguard Worker         // Otherwise, we have no instructions to issue and we have instructions
652*9880d681SAndroid Build Coastguard Worker         // that will fault if we don't do this right.  This is the case for
653*9880d681SAndroid Build Coastguard Worker         // processors without pipeline interlocks and other cases.
654*9880d681SAndroid Build Coastguard Worker         emitNoop(CurCycle);
655*9880d681SAndroid Build Coastguard Worker       }
656*9880d681SAndroid Build Coastguard Worker 
657*9880d681SAndroid Build Coastguard Worker       ++CurCycle;
658*9880d681SAndroid Build Coastguard Worker       CycleHasInsts = false;
659*9880d681SAndroid Build Coastguard Worker     }
660*9880d681SAndroid Build Coastguard Worker   }
661*9880d681SAndroid Build Coastguard Worker 
662*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
663*9880d681SAndroid Build Coastguard Worker   unsigned ScheduledNodes = VerifyScheduledDAG(/*isBottomUp=*/false);
664*9880d681SAndroid Build Coastguard Worker   unsigned Noops = 0;
665*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = Sequence.size(); i != e; ++i)
666*9880d681SAndroid Build Coastguard Worker     if (!Sequence[i])
667*9880d681SAndroid Build Coastguard Worker       ++Noops;
668*9880d681SAndroid Build Coastguard Worker   assert(Sequence.size() - Noops == ScheduledNodes &&
669*9880d681SAndroid Build Coastguard Worker          "The number of nodes scheduled doesn't match the expected number!");
670*9880d681SAndroid Build Coastguard Worker #endif // NDEBUG
671*9880d681SAndroid Build Coastguard Worker }
672*9880d681SAndroid Build Coastguard Worker 
673*9880d681SAndroid Build Coastguard Worker // EmitSchedule - Emit the machine code in scheduled order.
EmitSchedule()674*9880d681SAndroid Build Coastguard Worker void SchedulePostRATDList::EmitSchedule() {
675*9880d681SAndroid Build Coastguard Worker   RegionBegin = RegionEnd;
676*9880d681SAndroid Build Coastguard Worker 
677*9880d681SAndroid Build Coastguard Worker   // If first instruction was a DBG_VALUE then put it back.
678*9880d681SAndroid Build Coastguard Worker   if (FirstDbgValue)
679*9880d681SAndroid Build Coastguard Worker     BB->splice(RegionEnd, BB, FirstDbgValue);
680*9880d681SAndroid Build Coastguard Worker 
681*9880d681SAndroid Build Coastguard Worker   // Then re-insert them according to the given schedule.
682*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
683*9880d681SAndroid Build Coastguard Worker     if (SUnit *SU = Sequence[i])
684*9880d681SAndroid Build Coastguard Worker       BB->splice(RegionEnd, BB, SU->getInstr());
685*9880d681SAndroid Build Coastguard Worker     else
686*9880d681SAndroid Build Coastguard Worker       // Null SUnit* is a noop.
687*9880d681SAndroid Build Coastguard Worker       TII->insertNoop(*BB, RegionEnd);
688*9880d681SAndroid Build Coastguard Worker 
689*9880d681SAndroid Build Coastguard Worker     // Update the Begin iterator, as the first instruction in the block
690*9880d681SAndroid Build Coastguard Worker     // may have been scheduled later.
691*9880d681SAndroid Build Coastguard Worker     if (i == 0)
692*9880d681SAndroid Build Coastguard Worker       RegionBegin = std::prev(RegionEnd);
693*9880d681SAndroid Build Coastguard Worker   }
694*9880d681SAndroid Build Coastguard Worker 
695*9880d681SAndroid Build Coastguard Worker   // Reinsert any remaining debug_values.
696*9880d681SAndroid Build Coastguard Worker   for (std::vector<std::pair<MachineInstr *, MachineInstr *> >::iterator
697*9880d681SAndroid Build Coastguard Worker          DI = DbgValues.end(), DE = DbgValues.begin(); DI != DE; --DI) {
698*9880d681SAndroid Build Coastguard Worker     std::pair<MachineInstr *, MachineInstr *> P = *std::prev(DI);
699*9880d681SAndroid Build Coastguard Worker     MachineInstr *DbgValue = P.first;
700*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator OrigPrivMI = P.second;
701*9880d681SAndroid Build Coastguard Worker     BB->splice(++OrigPrivMI, BB, DbgValue);
702*9880d681SAndroid Build Coastguard Worker   }
703*9880d681SAndroid Build Coastguard Worker   DbgValues.clear();
704*9880d681SAndroid Build Coastguard Worker   FirstDbgValue = nullptr;
705*9880d681SAndroid Build Coastguard Worker }
706