1 //===- GCNIterativeScheduler.h - GCN Scheduler ------------------*- 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 #ifndef LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H
11 #define LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H
12 
13 #include "GCNRegPressure.h"
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/CodeGen/MachineBasicBlock.h"
16 #include "llvm/CodeGen/MachineScheduler.h"
17 #include "llvm/Support/Allocator.h"
18 #include <limits>
19 #include <memory>
20 #include <vector>
21 
22 namespace llvm {
23 
24 class MachineInstr;
25 class SUnit;
26 class raw_ostream;
27 
28 class GCNIterativeScheduler : public ScheduleDAGMILive {
29   using BaseClass = ScheduleDAGMILive;
30 
31 public:
32   enum StrategyKind {
33     SCHEDULE_MINREGONLY,
34     SCHEDULE_MINREGFORCED,
35     SCHEDULE_LEGACYMAXOCCUPANCY,
36     SCHEDULE_ILP
37   };
38 
39   GCNIterativeScheduler(MachineSchedContext *C,
40                         StrategyKind S);
41 
42   void schedule() override;
43 
44   void enterRegion(MachineBasicBlock *BB,
45                    MachineBasicBlock::iterator Begin,
46                    MachineBasicBlock::iterator End,
47                    unsigned RegionInstrs) override;
48 
49   void finalizeSchedule() override;
50 
51 protected:
52   using ScheduleRef = ArrayRef<const SUnit *>;
53 
54   struct TentativeSchedule {
55     std::vector<MachineInstr *> Schedule;
56     GCNRegPressure MaxPressure;
57   };
58 
59   struct Region {
60     // Fields except for BestSchedule are supposed to reflect current IR state
61     // `const` fields are to emphasize they shouldn't change for any schedule.
62     MachineBasicBlock::iterator Begin;
63     // End is either a boundary instruction or end of basic block
64     const MachineBasicBlock::iterator End;
65     const unsigned NumRegionInstrs;
66     GCNRegPressure MaxPressure;
67 
68     // best schedule for the region so far (not scheduled yet)
69     std::unique_ptr<TentativeSchedule> BestSchedule;
70   };
71 
72   SpecificBumpPtrAllocator<Region> Alloc;
73   std::vector<Region*> Regions;
74 
75   MachineSchedContext *Context;
76   const StrategyKind Strategy;
77   mutable GCNUpwardRPTracker UPTracker;
78 
79   class BuildDAG;
80   class OverrideLegacyStrategy;
81 
82   template <typename Range>
83   GCNRegPressure getSchedulePressure(const Region &R,
84                                      Range &&Schedule) const;
85 
86   GCNRegPressure getRegionPressure(MachineBasicBlock::iterator Begin,
87                                    MachineBasicBlock::iterator End) const;
88 
getRegionPressure(const Region & R)89   GCNRegPressure getRegionPressure(const Region &R) const {
90     return getRegionPressure(R.Begin, R.End);
91   }
92 
93   void setBestSchedule(Region &R,
94                        ScheduleRef Schedule,
95                        const GCNRegPressure &MaxRP = GCNRegPressure());
96 
97   void scheduleBest(Region &R);
98 
99   std::vector<MachineInstr*> detachSchedule(ScheduleRef Schedule) const;
100 
101   void sortRegionsByPressure(unsigned TargetOcc);
102 
103   template <typename Range>
104   void scheduleRegion(Region &R, Range &&Schedule,
105                       const GCNRegPressure &MaxRP = GCNRegPressure());
106 
107   unsigned tryMaximizeOccupancy(unsigned TargetOcc =
108                                 std::numeric_limits<unsigned>::max());
109 
110   void scheduleLegacyMaxOccupancy(bool TryMaximizeOccupancy = true);
111   void scheduleMinReg(bool force = false);
112   void scheduleILP(bool TryMaximizeOccupancy = true);
113 
114   void printRegions(raw_ostream &OS) const;
115   void printSchedResult(raw_ostream &OS,
116                         const Region *R,
117                         const GCNRegPressure &RP) const;
118   void printSchedRP(raw_ostream &OS,
119                     const GCNRegPressure &Before,
120                     const GCNRegPressure &After) const;
121 };
122 
123 } // end namespace llvm
124 
125 #endif // LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H
126