blob: 14ef5147f32af146d6b8be8cdf11c1f16f20c505 [file] [log] [blame]
Eugene Zelenkoc8fbf6f2017-08-10 00:46:15 +00001//===- GCNIterativeScheduler.h - GCN Scheduler ------------------*- C++ -*-===//
Valery Pykhtinfd4c4102017-03-21 13:15:46 +00002//
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//===----------------------------------------------------------------------===//
Valery Pykhtinfd4c4102017-03-21 13:15:46 +00009
10#ifndef LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H
11#define LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H
12
13#include "GCNRegPressure.h"
Eugene Zelenkoc8fbf6f2017-08-10 00:46:15 +000014#include "llvm/ADT/ArrayRef.h"
15#include "llvm/CodeGen/MachineBasicBlock.h"
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000016#include "llvm/CodeGen/MachineScheduler.h"
Eugene Zelenkoc8fbf6f2017-08-10 00:46:15 +000017#include "llvm/Support/Allocator.h"
18#include <limits>
19#include <memory>
20#include <vector>
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000021
22namespace llvm {
23
Eugene Zelenkoc8fbf6f2017-08-10 00:46:15 +000024class MachineInstr;
25class SUnit;
26class raw_ostream;
27
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000028class GCNIterativeScheduler : public ScheduleDAGMILive {
Eugene Zelenkoc8fbf6f2017-08-10 00:46:15 +000029 using BaseClass = ScheduleDAGMILive;
30
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000031public:
32 enum StrategyKind {
33 SCHEDULE_MINREGONLY,
34 SCHEDULE_MINREGFORCED,
Valery Pykhtinf2fe9722017-11-20 14:35:53 +000035 SCHEDULE_LEGACYMAXOCCUPANCY,
36 SCHEDULE_ILP
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000037 };
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
51protected:
Eugene Zelenkoc8fbf6f2017-08-10 00:46:15 +000052 using ScheduleRef = ArrayRef<const SUnit *>;
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000053
54 struct TentativeSchedule {
Eugene Zelenkoc8fbf6f2017-08-10 00:46:15 +000055 std::vector<MachineInstr *> Schedule;
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000056 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
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);
Valery Pykhtinf2fe9722017-11-20 14:35:53 +0000112 void scheduleILP(bool TryMaximizeOccupancy = true);
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000113
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
Eugene Zelenkoc8fbf6f2017-08-10 00:46:15 +0000123} // end namespace llvm
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000124
125#endif // LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H