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