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