Line data Source code
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 0 : struct TentativeSchedule {
55 : std::vector<MachineInstr *> Schedule;
56 : GCNRegPressure MaxPressure;
57 : };
58 :
59 8 : 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 :
89 0 : GCNRegPressure getRegionPressure(const Region &R) const {
90 4 : 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
|