LLVM 24.0.0git
VLIWMachineScheduler.h
Go to the documentation of this file.
1//===- VLIWMachineScheduler.h - VLIW-Focused Scheduling Pass ----*- 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//===----------------------------------------------------------------------===//
10
11#ifndef LLVM_CODEGEN_VLIWMACHINESCHEDULER_H
12#define LLVM_CODEGEN_VLIWMACHINESCHEDULER_H
13
15#include "llvm/ADT/Twine.h"
18#include <iterator>
19#include <limits>
20#include <memory>
21#include <utility>
22
23namespace llvm {
24
25class DFAPacketizer;
28class SUnit;
29class TargetInstrInfo;
31
33protected:
35
36 /// ResourcesModel - Represents VLIW state.
37 /// Not limited to VLIW targets per se, but assumes definition of resource
38 /// model by a target.
40
42
43 /// Local packet/bundle model. Purely
44 /// internal to the MI scheduler at the time.
46
47 /// Total packets created.
48 unsigned TotalPackets = 0;
49
50public:
53 VLIWResourceModel(const VLIWResourceModel &other) = delete;
54 virtual ~VLIWResourceModel();
55
56 virtual void reset();
57
58 virtual bool hasDependence(const SUnit *SUd, const SUnit *SUu);
59 virtual bool isResourceAvailable(SUnit *SU, bool IsTop);
60 virtual bool reserveResources(SUnit *SU, bool IsTop);
61 unsigned getTotalPackets() const { return TotalPackets; }
62 size_t getPacketInstCount() const { return Packet.size(); }
63 bool isInPacket(SUnit *SU) const { return is_contained(Packet, SU); }
64
65protected:
66 virtual DFAPacketizer *createPacketizer(const TargetSubtargetInfo &STI) const;
67};
68
69/// Extend the standard ScheduleDAGMILive to provide more context and override
70/// the top-level schedule() driver.
72public:
74 std::unique_ptr<MachineSchedStrategy> S)
75 : ScheduleDAGMILive(C, std::move(S)) {}
76
77 /// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
78 /// time to do some work.
79 void schedule() override;
80
82 unsigned getBBSize() const {
83 auto NonDebugInstrs = instructionsWithoutDebug(
84 BB->instr_begin(), BB->instr_end(), /*SkipPseudoOp=*/false);
85 return std::distance(NonDebugInstrs.begin(), NonDebugInstrs.end());
86 }
87};
88
89//===----------------------------------------------------------------------===//
90// ConvergingVLIWScheduler - Implementation of a VLIW-aware
91// MachineSchedStrategy.
92//===----------------------------------------------------------------------===//
93
95protected:
96 /// Store the state used by ConvergingVLIWScheduler heuristics, required
97 /// for the lifetime of one invocation of pickNode().
99 // The best SUnit candidate.
100 SUnit *SU = nullptr;
101
102 // Register pressure values for the best candidate.
104
105 // Best scheduling cost.
106 int SCost = 0;
107
108 SchedCandidate() = default;
109 };
110 /// Represent the type of SchedCandidate found within a single queue.
121
122 // Constants used to denote relative importance of
123 // heuristic components for cost computation.
124 static constexpr unsigned PriorityOne = 200;
125 static constexpr unsigned PriorityTwo = 50;
126 static constexpr unsigned PriorityThree = 75;
127 static constexpr unsigned ScaleTwo = 10;
128
129 /// Each Scheduling boundary is associated with ready queues. It tracks the
130 /// current cycle in whichever direction at has moved, and maintains the state
131 /// of "hazards" and other interlocks at the current cycle.
134 const TargetSchedModel *SchedModel = nullptr;
135
138 bool CheckPending = false;
139
142
143 unsigned CurrCycle = 0;
144 unsigned IssueCount = 0;
145 unsigned CriticalPathLength = 0;
146
147 /// MinReadyCycle - Cycle of the soonest available instruction.
148 unsigned MinReadyCycle = std::numeric_limits<unsigned>::max();
149
150 // Remember the greatest min operand latency.
151 unsigned MaxMinLatency = 0;
152
153 /// Pending queues extend the ready queues with the same ID and the
154 /// PendingFlag set.
155 VLIWSchedBoundary(unsigned ID, const Twine &Name)
156 : Available(ID, Name + ".A"),
157 Pending(ID << ConvergingVLIWScheduler::LogMaxQID, Name + ".P") {}
158
161 VLIWSchedBoundary(const VLIWSchedBoundary &other) = delete;
162
163 void init(VLIWMachineScheduler *dag, const TargetSchedModel *smodel) {
164 DAG = dag;
165 SchedModel = smodel;
166 CurrCycle = 0;
167 IssueCount = 0;
168 // Initialize the critical path length limit, which used by the scheduling
169 // cost model to determine the value for scheduling an instruction. We use
170 // a slightly different heuristic for small and large functions. For small
171 // functions, it's important to use the height/depth of the instruction.
172 // For large functions, prioritizing by height or depth increases spills.
173 const auto BBSize = DAG->getBBSize();
174 CriticalPathLength = BBSize / SchedModel->getIssueWidth();
175 if (BBSize < 50)
176 // We divide by two as a cheap and simple heuristic to reduce the
177 // critcal path length, which increases the priority of using the graph
178 // height/depth in the scheduler's cost computation.
179 CriticalPathLength >>= 1;
180 else {
181 // For large basic blocks, we prefer a larger critical path length to
182 // decrease the priority of using the graph height/depth.
183 unsigned MaxPath = 0;
184 for (auto &SU : DAG->SUnits)
185 MaxPath = std::max(MaxPath, isTop() ? SU.getHeight() : SU.getDepth());
186 CriticalPathLength = std::max(CriticalPathLength, MaxPath) + 1;
187 }
188 }
189
190 bool isTop() const {
192 }
193
194 LLVM_ABI bool checkHazard(SUnit *SU);
195
196 LLVM_ABI void releaseNode(SUnit *SU, unsigned ReadyCycle);
197
198 LLVM_ABI void bumpCycle();
199
200 LLVM_ABI void bumpNode(SUnit *SU);
201
202 LLVM_ABI void releasePending();
203
204 LLVM_ABI void removeReady(SUnit *SU);
205
207
210 return true;
211 unsigned PathLength = isTop() ? SU->getHeight() : SU->getDepth();
212 return CriticalPathLength - CurrCycle <= PathLength;
213 }
214 };
215
217 const TargetSchedModel *SchedModel = nullptr;
218
219 // State of the top and bottom scheduled instruction boundaries.
222
223 /// List of pressure sets that have a high pressure level in the region.
225
226public:
227 /// SUnit::NodeQueueId: 0 (none), 1 (top), 2 (bot), 3 (both)
228 enum { TopQID = 1, BotQID = 2, LogMaxQID = 2 };
229
230 ConvergingVLIWScheduler() : Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {}
231 ~ConvergingVLIWScheduler() override = default;
232
233 void initialize(ScheduleDAGMI *dag) override;
234
235 SUnit *pickNode(bool &IsTopNode) override;
236
237 void schedNode(SUnit *SU, bool IsTopNode) override;
238
239 void releaseTopNode(SUnit *SU) override;
240
241 void releaseBottomNode(SUnit *SU) override;
242
243 unsigned reportPackets() {
244 return Top.ResourceModel->getTotalPackets() +
245 Bot.ResourceModel->getTotalPackets();
246 }
247
248protected:
249 virtual VLIWResourceModel *
250 createVLIWResourceModel(const TargetSubtargetInfo &STI,
251 const TargetSchedModel *SchedModel) const;
252
253 SUnit *pickNodeBidrectional(bool &IsTopNode);
254
255 int pressureChange(const SUnit *SU, bool isBotUp);
256
257 virtual int SchedulingCost(ReadyQueue &Q, SUnit *SU,
258 SchedCandidate &Candidate, RegPressureDelta &Delta,
259 bool verbose);
260
261 CandResult pickNodeFromQueue(VLIWSchedBoundary &Zone,
262 const RegPressureTracker &RPTracker,
263 SchedCandidate &Candidate);
264#ifndef NDEBUG
265 void traceCandidate(const char *Label, const ReadyQueue &Q, SUnit *SU,
267
268 void readyQueueVerboseDump(const RegPressureTracker &RPTracker,
269 SchedCandidate &Candidate, ReadyQueue &Q);
270#endif
271};
272
273} // end namespace llvm
274
275#endif // LLVM_CODEGEN_VLIWMACHINESCHEDULER_H
static SUnit * pickOnlyChoice(SchedBoundary &Zone)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
#define LLVM_ABI
Definition Compiler.h:211
#define P(N)
This file defines the SmallVector class.
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
~ConvergingVLIWScheduler() override=default
void releaseBottomNode(SUnit *SU) override
When all successor dependencies have been resolved, free this node for bottom-up scheduling.
static constexpr unsigned PriorityOne
SUnit * pickNode(bool &IsTopNode) override
Pick the best node to balance the schedule. Implements MachineSchedStrategy.
SmallVector< bool > HighPressureSets
List of pressure sets that have a high pressure level in the region.
static constexpr unsigned ScaleTwo
void schedNode(SUnit *SU, bool IsTopNode) override
Update the scheduler's state after scheduling a node.
void releaseTopNode(SUnit *SU) override
When all predecessor dependencies have been resolved, free this node for top-down scheduling.
static constexpr unsigned PriorityTwo
static constexpr unsigned PriorityThree
const TargetSchedModel * SchedModel
CandResult
Represent the type of SchedCandidate found within a single queue.
MachineSchedStrategy - Interface to the scheduling algorithm used by ScheduleDAGMI.
Capture a change in pressure for a single pressure set.
Helpers for implementing custom MachineSchedStrategy classes.
Track the current register pressure at some position in the instruction stream, and remember the high...
Scheduling unit. This is a node in the scheduling DAG.
unsigned getHeight() const
Returns the height of this node, which is the length of the maximum path down to any node which has n...
unsigned getDepth() const
Returns the depth of this node, which is the length of the maximum path up to any node which has no p...
MachineBasicBlock * BB
The block in which to insert instructions.
ScheduleDAGMILive(MachineSchedContext *C, std::unique_ptr< MachineSchedStrategy > S)
RegisterClassInfo * RegClassInfo
ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...
HazardRecognizer - This determines whether or not an instruction can be issued this cycle,...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
Provide an instruction scheduling machine model to CodeGen passes.
TargetSubtargetInfo - Generic base class for all target subtargets.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
Extend the standard ScheduleDAGMILive to provide more context and override the top-level schedule() d...
VLIWMachineScheduler(MachineSchedContext *C, std::unique_ptr< MachineSchedStrategy > S)
RegisterClassInfo * getRegClassInfo()
unsigned TotalPackets
Total packets created.
virtual bool hasDependence(const SUnit *SUd, const SUnit *SUu)
Return true if there is a dependence between SUd and SUu.
virtual bool reserveResources(SUnit *SU, bool IsTop)
Keep track of available resources.
VLIWResourceModel & operator=(const VLIWResourceModel &other)=delete
bool isInPacket(SUnit *SU) const
DFAPacketizer * ResourcesModel
ResourcesModel - Represents VLIW state.
SmallVector< SUnit * > Packet
Local packet/bundle model.
const TargetSchedModel * SchedModel
VLIWResourceModel(const VLIWResourceModel &other)=delete
VLIWResourceModel(const TargetSubtargetInfo &STI, const TargetSchedModel *SM)
virtual bool isResourceAvailable(SUnit *SU, bool IsTop)
Check if scheduling of this SU is possible in the current packet.
const TargetInstrInfo * TII
This is an optimization pass for GlobalISel generic memory operations.
InstructionCost Cost
auto instructionsWithoutDebug(IterT It, IterT End, bool SkipPseudoOp=true)
Construct a range iterator which begins at It and moves forwards until End is reached,...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
Each Scheduling boundary is associated with ready queues.
VLIWSchedBoundary(unsigned ID, const Twine &Name)
Pending queues extend the ready queues with the same ID and the PendingFlag set.
VLIWSchedBoundary & operator=(const VLIWSchedBoundary &other)=delete
unsigned MinReadyCycle
MinReadyCycle - Cycle of the soonest available instruction.
void init(VLIWMachineScheduler *dag, const TargetSchedModel *smodel)
VLIWSchedBoundary(const VLIWSchedBoundary &other)=delete
MachineSchedContext provides enough context from the MachineScheduler pass for the target to instanti...
Store the effects of a change in pressure on things that MI scheduler cares about.