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