LLVM 22.0.0git
ScheduleDAGInstrs.h
Go to the documentation of this file.
1//===- ScheduleDAGInstrs.h - MachineInstr Scheduling ------------*- 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/// \file Implements the ScheduleDAGInstrs class, which implements scheduling
10/// for a MachineInstr-based dependency graph.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
15#define LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
16
17#include "llvm/ADT/DenseMap.h"
27#include "llvm/MC/LaneBitmask.h"
29#include <cassert>
30#include <cstdint>
31#include <list>
32#include <string>
33#include <utility>
34#include <vector>
35
36namespace llvm {
37
38 class AAResults;
39 class LiveIntervals;
40 class MachineFrameInfo;
41 class MachineFunction;
42 class MachineInstr;
43 class MachineLoopInfo;
44 class MachineOperand;
45 struct MCSchedClassDesc;
46 class PressureDiffs;
49 class UndefValue;
50 class Value;
51
52 /// An individual mapping from virtual register number to SUnit.
53 struct VReg2SUnit {
57
60
61 unsigned getSparseSetIndex() const {
62 return VirtReg.virtRegIndex();
63 }
64 };
65
66 /// Mapping from virtual register to SUnit including an operand index.
74
75 /// Record a physical register access.
76 /// For non-data-dependent uses, OpIdx == -1.
79 int OpIdx;
80 MCRegUnit RegUnit;
81
82 PhysRegSUOper(SUnit *su, int op, MCRegUnit R)
83 : SU(su), OpIdx(op), RegUnit(R) {}
84
85 unsigned getSparseSetIndex() const {
86 return static_cast<unsigned>(RegUnit);
87 }
88 };
89
90 /// Use a SparseMultiSet to track physical registers. Storage is only
91 /// allocated once for the pass. It can be cleared in constant time and reused
92 /// without any frees.
95
96 /// Track local uses of virtual registers. These uses are gathered by the DAG
97 /// builder and may be consulted by the scheduler to avoid iterating an entire
98 /// vreg use list.
101
104
106
107 struct UnderlyingObject : PointerIntPair<ValueType, 1, bool> {
108 UnderlyingObject(ValueType V, bool MayAlias)
109 : PointerIntPair<ValueType, 1, bool>(V, MayAlias) {}
110
111 ValueType getValue() const { return getPointer(); }
112 bool mayAlias() const { return getInt(); }
113 };
114
116
117 /// A ScheduleDAG for scheduling lists of MachineInstr.
119 protected:
120 const MachineLoopInfo *MLI = nullptr;
122
123 /// TargetSchedModel provides an interface to the machine model.
125
126 /// True if the DAG builder should remove kill flags (in preparation for
127 /// rescheduling).
129
130 /// True if regions with a single MI should be scheduled.
132
133 /// The standard DAG builder does not normally include terminators as DAG
134 /// nodes because it does not create the necessary dependencies to prevent
135 /// reordering. A specialized scheduler can override
136 /// TargetInstrInfo::isSchedulingBoundary then enable this flag to indicate
137 /// it has taken responsibility for scheduling the terminator correctly.
139
140 /// Whether lane masks should get tracked.
141 bool TrackLaneMasks = false;
142
143 // State specific to the current scheduling region.
144 // ------------------------------------------------
145
146 /// The block in which to insert instructions
148
149 /// The beginning of the range to be scheduled.
151
152 /// The end of the range to be scheduled.
154
155 /// Instructions in this region (distance(RegionBegin, RegionEnd)).
156 unsigned NumRegionInstrs = 0;
157
158 /// After calling BuildSchedGraph, each machine instruction in the current
159 /// scheduling region is mapped to an SUnit.
161
162 // State internal to DAG building.
163 // -------------------------------
164
165 /// Defs, Uses - Remember where defs and uses of each register are as we
166 /// iterate upward through the instructions. This is allocated here instead
167 /// of inside BuildSchedGraph to avoid the need for it to be initialized and
168 /// destructed for each block.
171
172 /// Tracks the last instruction(s) in this region defining each virtual
173 /// register. There may be multiple current definitions for a register with
174 /// disjunct lanemasks.
176 /// Tracks the last instructions in this region using each virtual register.
178
179 mutable std::optional<BatchAAResults> AAForDep;
180
181 /// Remember a generic side-effecting instruction as we proceed.
182 /// No other SU ever gets scheduled around it (except in the special
183 /// case of a huge region that gets reduced).
184 SUnit *BarrierChain = nullptr;
185
187
188 public:
189 /// A list of SUnits, used in Value2SUsMap, during DAG construction.
190 /// Note: to gain speed it might be worth investigating an optimized
191 /// implementation of this data structure, such as a singly linked list
192 /// with a memory pool (SmallVector was tried but slow and SparseSet is not
193 /// applicable).
194 using SUList = std::list<SUnit *>;
195
196 /// The direction that should be used to dump the scheduled Sequence.
203
205
206 protected:
208
209 /// A map from ValueType to SUList, used during DAG construction, as
210 /// a means of remembering which SUs depend on which memory locations.
211 class Value2SUsMap;
212
213 /// Returns a (possibly null) pointer to the current BatchAAResults.
215 if (AAForDep.has_value())
216 return &AAForDep.value();
217 return nullptr;
218 }
219
220 /// Reduces maps in FIFO order, by N SUs. This is better than turning
221 /// every Nth memory SU into BarrierChain in buildSchedGraph(), since
222 /// it avoids unnecessary edges between seen SUs above the new BarrierChain,
223 /// and those below it.
224 void reduceHugeMemNodeMaps(Value2SUsMap &stores,
225 Value2SUsMap &loads, unsigned N);
226
227 /// Adds a chain edge between SUa and SUb, but only if both
228 /// AAResults and Target fail to deny the dependency.
229 void addChainDependency(SUnit *SUa, SUnit *SUb,
230 unsigned Latency = 0);
231
232 /// Adds dependencies as needed from all SUs in list to SU.
233 void addChainDependencies(SUnit *SU, SUList &SUs, unsigned Latency) {
234 for (SUnit *Entry : SUs)
235 addChainDependency(SU, Entry, Latency);
236 }
237
238 /// Adds dependencies as needed from all SUs in map, to SU.
239 void addChainDependencies(SUnit *SU, Value2SUsMap &Val2SUsMap);
240
241 /// Adds dependencies as needed to SU, from all SUs mapped to V.
242 void addChainDependencies(SUnit *SU, Value2SUsMap &Val2SUsMap,
243 ValueType V);
244
245 /// Adds barrier chain edges from all SUs in map, and then clear the map.
246 /// This is equivalent to insertBarrierChain(), but optimized for the common
247 /// case where the new BarrierChain (a global memory object) has a higher
248 /// NodeNum than all SUs in map. It is assumed BarrierChain has been set
249 /// before calling this.
250 void addBarrierChain(Value2SUsMap &map);
251
252 /// Inserts a barrier chain in a huge region, far below current SU.
253 /// Adds barrier chain edges from all SUs in map with higher NodeNums than
254 /// this new BarrierChain, and remove them from map. It is assumed
255 /// BarrierChain has been set before calling this.
256 void insertBarrierChain(Value2SUsMap &map);
257
258 /// For an unanalyzable memory access, this Value is used in maps.
260
261
262 /// Topo - A topological ordering for SUnits which permits fast IsReachable
263 /// and similar queries.
265
267 std::vector<std::pair<MachineInstr *, MachineInstr *>>;
268 /// Remember instruction that precedes DBG_VALUE.
269 /// These are generated by buildSchedGraph but persist so they can be
270 /// referenced when emitting the final schedule.
273
274 /// Set of live physical registers for updating kill flags.
276
277 public:
279 const MachineLoopInfo *mli,
280 bool RemoveKillFlags = false);
281
282 ~ScheduleDAGInstrs() override = default;
283
284 /// Gets the machine model for instruction scheduling.
285 const TargetSchedModel *getSchedModel() const { return &SchedModel; }
286
287 /// Resolves and cache a resolved scheduling class for an SUnit.
289 if (!SU->SchedClass && SchedModel.hasInstrSchedModel())
290 SU->SchedClass = SchedModel.resolveSchedClass(SU->getInstr());
291 return SU->SchedClass;
292 }
293
294 /// IsReachable - Checks if SU is reachable from TargetSU.
295 bool IsReachable(SUnit *SU, SUnit *TargetSU) {
296 return Topo.IsReachable(SU, TargetSU);
297 }
298
299 /// Whether regions with a single MI should be scheduled.
303
304 /// Returns an iterator to the top of the current scheduling region.
306
307 /// Returns an iterator to the bottom of the current scheduling region.
309
310 /// Creates a new SUnit and return a ptr to it.
311 SUnit *newSUnit(MachineInstr *MI);
312
313 /// Returns an existing SUnit for this MI, or nullptr.
314 SUnit *getSUnit(MachineInstr *MI) const;
315
316 /// If this method returns true, handling of the scheduling regions
317 /// themselves (in case of a scheduling boundary in MBB) will be done
318 /// beginning with the topmost region of MBB.
319 virtual bool doMBBSchedRegionsTopDown() const { return false; }
320
321 /// Prepares to perform scheduling in the given block.
322 virtual void startBlock(MachineBasicBlock *BB);
323
324 /// Cleans up after scheduling in the given block.
325 virtual void finishBlock();
326
327 /// Initialize the DAG and common scheduler state for a new
328 /// scheduling region. This does not actually create the DAG, only clears
329 /// it. The scheduling driver may call BuildSchedGraph multiple times per
330 /// scheduling region.
331 virtual void enterRegion(MachineBasicBlock *bb,
334 unsigned regioninstrs);
335
336 /// Called when the scheduler has finished scheduling the current region.
337 virtual void exitRegion();
338
339 /// Builds SUnits for the current region.
340 /// If \p RPTracker is non-null, compute register pressure as a side effect.
341 /// The DAG builder is an efficient place to do it because it already visits
342 /// operands.
343 void buildSchedGraph(AAResults *AA,
344 RegPressureTracker *RPTracker = nullptr,
345 PressureDiffs *PDiffs = nullptr,
346 LiveIntervals *LIS = nullptr,
347 bool TrackLaneMasks = false);
348
349 /// Adds dependencies from instructions in the current list of
350 /// instructions being scheduled to scheduling barrier. We want to make sure
351 /// instructions which define registers that are either used by the
352 /// terminator or are live-out are properly scheduled. This is especially
353 /// important when the definition latency of the return value(s) are too
354 /// high to be hidden by the branch or when the liveout registers used by
355 /// instructions in the fallthrough block.
356 void addSchedBarrierDeps();
357
358 /// Orders nodes according to selected style.
359 ///
360 /// Typically, a scheduling algorithm will implement schedule() without
361 /// overriding enterRegion() or exitRegion().
362 virtual void schedule() = 0;
363
364 /// Allow targets to perform final scheduling actions at the level of the
365 /// whole MachineFunction. By default does nothing.
366 virtual void finalizeSchedule() {}
367
368 void dumpNode(const SUnit &SU) const override;
369 void dump() const override;
370
371 /// Returns a label for a DAG node that points to an instruction.
372 std::string getGraphNodeLabel(const SUnit *SU) const override;
373
374 /// Returns a label for the region of code covered by the DAG.
375 std::string getDAGName() const override;
376
377 /// Fixes register kill flags that scheduling has made invalid.
378 void fixupKills(MachineBasicBlock &MBB);
379
380 /// True if an edge can be added from PredSU to SuccSU without creating
381 /// a cycle.
382 bool canAddEdge(SUnit *SuccSU, SUnit *PredSU);
383
384 /// Add a DAG edge to the given SU with the given predecessor
385 /// dependence data.
386 ///
387 /// \returns true if the edge may be added without creating a cycle OR if an
388 /// equivalent edge already existed (false indicates failure).
389 bool addEdge(SUnit *SuccSU, const SDep &PredDep);
390
391 /// Returns the array of the clusters.
393
394 /// Get the specific cluster, return nullptr for InvalidClusterId.
395 ClusterInfo *getCluster(unsigned Idx) {
396 return Idx != InvalidClusterId ? &Clusters[Idx] : nullptr;
397 }
398
399 protected:
400 void initSUnits();
401 void addPhysRegDataDeps(SUnit *SU, unsigned OperIdx);
402 void addPhysRegDeps(SUnit *SU, unsigned OperIdx);
403 void addVRegDefDeps(SUnit *SU, unsigned OperIdx);
404 void addVRegUseDeps(SUnit *SU, unsigned OperIdx);
405
406 /// Returns a mask for which lanes get read/written by the given (register)
407 /// machine operand.
408 LaneBitmask getLaneMaskForMO(const MachineOperand &MO) const;
409
410 /// Returns true if the def register in \p MO has no uses.
411 bool deadDefHasNoUse(const MachineOperand &MO);
412 };
413
414 /// Creates a new SUnit and return a ptr to it.
416#ifndef NDEBUG
417 const SUnit *Addr = SUnits.empty() ? nullptr : &SUnits[0];
418#endif
419 SUnits.emplace_back(MI, (unsigned)SUnits.size());
420 assert((Addr == nullptr || Addr == &SUnits[0]) &&
421 "SUnits std::vector reallocated on the fly!");
422 return &SUnits.back();
423 }
424
425 /// Returns an existing SUnit for this MI, or nullptr.
427 return MISUnitMap.lookup(MI);
428 }
429
430} // end namespace llvm
431
432#endif // LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define LLVM_ABI
Definition Compiler.h:213
This file defines the DenseMap class.
#define op(i)
hexagon widen Hexagon Store false hexagon widen loads
hexagon widen stores
IRTranslator LLVM IR MI
A common definition of LaneBitmask for use in TableGen and CodeGen.
static void addEdge(SmallVectorImpl< LazyCallGraph::Edge > &Edges, DenseMap< LazyCallGraph::Node *, int > &EdgeIndexMap, LazyCallGraph::Node &N, LazyCallGraph::Edge::Kind EK)
A set of register units.
This file defines the PointerIntPair class.
This file defines the SmallVector class.
This file defines the SparseMultiSet class, which adds multiset behavior to the SparseSet.
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
A set of register units used to track register liveness.
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
Array of PressureDiffs.
Special value supplied for machine level alias analysis.
Track the current register pressure at some position in the instruction stream, and remember the high...
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Scheduling dependency.
Definition ScheduleDAG.h:51
Scheduling unit. This is a node in the scheduling DAG.
const MCSchedClassDesc * SchedClass
nullptr or resolved SchedClass.
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
LiveRegUnits LiveRegs
Set of live physical registers for updating kill flags.
DenseMap< MachineInstr *, SUnit * > MISUnitMap
After calling BuildSchedGraph, each machine instruction in the current scheduling region is mapped to...
SmallVector< ClusterInfo > & getClusters()
Returns the array of the clusters.
MachineBasicBlock::iterator end() const
Returns an iterator to the bottom of the current scheduling region.
MachineBasicBlock * BB
The block in which to insert instructions.
bool CanHandleTerminators
The standard DAG builder does not normally include terminators as DAG nodes because it does not creat...
bool ScheduleSingleMIRegions
True if regions with a single MI should be scheduled.
const TargetSchedModel * getSchedModel() const
Gets the machine model for instruction scheduling.
MachineBasicBlock::iterator RegionEnd
The end of the range to be scheduled.
VReg2SUnitOperIdxMultiMap CurrentVRegUses
Tracks the last instructions in this region using each virtual register.
void addChainDependencies(SUnit *SU, SUList &SUs, unsigned Latency)
Adds dependencies as needed from all SUs in list to SU.
const MCSchedClassDesc * getSchedClass(SUnit *SU) const
Resolves and cache a resolved scheduling class for an SUnit.
~ScheduleDAGInstrs() override=default
ScheduleDAGInstrs(MachineFunction &mf, const MachineLoopInfo *mli, bool RemoveKillFlags=false)
bool shouldScheduleSingleMIRegions() const
Whether regions with a single MI should be scheduled.
DbgValueVector DbgValues
Remember instruction that precedes DBG_VALUE.
std::vector< std::pair< MachineInstr *, MachineInstr * > > DbgValueVector
SUnit * newSUnit(MachineInstr *MI)
Creates a new SUnit and return a ptr to it.
virtual void finalizeSchedule()
Allow targets to perform final scheduling actions at the level of the whole MachineFunction.
ScheduleDAGTopologicalSort Topo
Topo - A topological ordering for SUnits which permits fast IsReachable and similar queries.
DumpDirection
The direction that should be used to dump the scheduled Sequence.
std::list< SUnit * > SUList
A list of SUnits, used in Value2SUsMap, during DAG construction.
SUnit * BarrierChain
Remember a generic side-effecting instruction as we proceed.
BatchAAResults * getAAForDep() const
Returns a (possibly null) pointer to the current BatchAAResults.
bool TrackLaneMasks
Whether lane masks should get tracked.
ClusterInfo * getCluster(unsigned Idx)
Get the specific cluster, return nullptr for InvalidClusterId.
bool IsReachable(SUnit *SU, SUnit *TargetSU)
IsReachable - Checks if SU is reachable from TargetSU.
RegUnit2SUnitsMap Defs
Defs, Uses - Remember where defs and uses of each register are as we iterate upward through the instr...
UndefValue * UnknownValue
For an unanalyzable memory access, this Value is used in maps.
VReg2SUnitMultiMap CurrentVRegDefs
Tracks the last instruction(s) in this region defining each virtual register.
MachineBasicBlock::iterator begin() const
Returns an iterator to the top of the current scheduling region.
SUnit * getSUnit(MachineInstr *MI) const
Returns an existing SUnit for this MI, or nullptr.
TargetSchedModel SchedModel
TargetSchedModel provides an interface to the machine model.
virtual void schedule()=0
Orders nodes according to selected style.
const MachineLoopInfo * MLI
bool RemoveKillFlags
True if the DAG builder should remove kill flags (in preparation for rescheduling).
std::optional< BatchAAResults > AAForDep
MachineBasicBlock::iterator RegionBegin
The beginning of the range to be scheduled.
void addChainDependency(SUnit *SUa, SUnit *SUb, unsigned Latency=0)
Adds a chain edge between SUa and SUb, but only if both AAResults and Target fail to deny the depende...
unsigned NumRegionInstrs
Instructions in this region (distance(RegionBegin, RegionEnd)).
const MachineFrameInfo & MFI
SmallVector< ClusterInfo > Clusters
virtual bool doMBBSchedRegionsTopDown() const
If this method returns true, handling of the scheduling regions themselves (in case of a scheduling b...
void setDumpDirection(DumpDirection D)
This class can compute a topological ordering for SUnits and provides methods for dynamically updatin...
std::vector< SUnit > SUnits
The scheduling units.
ScheduleDAG(const ScheduleDAG &)=delete
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Fast multiset implementation for objects that can be identified by small unsigned keys.
Provide an instruction scheduling machine model to CodeGen passes.
'undef' values are things that do not have specified contents.
Definition Constants.h:1420
LLVM Value Representation.
Definition Value.h:75
Abstract Attribute helper functions.
Definition Attributor.h:165
This is an optimization pass for GlobalISel generic memory operations.
SparseMultiSet< VReg2SUnitOperIdx, Register, VirtReg2IndexFunctor > VReg2SUnitOperIdxMultiMap
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
SparseMultiSet< VReg2SUnit, Register, VirtReg2IndexFunctor > VReg2SUnitMultiMap
Track local uses of virtual registers.
constexpr unsigned InvalidClusterId
SmallVector< UnderlyingObject, 4 > UnderlyingObjectsVector
SmallPtrSet< SUnit *, 8 > ClusterInfo
Keep record of which SUnit are in the same cluster group.
PointerUnion< const Value *, const PseudoSourceValue * > ValueType
SparseMultiSet< PhysRegSUOper, MCRegUnit, MCRegUnitToIndex, uint16_t > RegUnit2SUnitsMap
Use a SparseMultiSet to track physical registers.
#define N
Summarize the scheduling resources required for an instruction of a particular scheduling class.
Definition MCSchedule.h:123
unsigned getSparseSetIndex() const
PhysRegSUOper(SUnit *su, int op, MCRegUnit R)
UnderlyingObject(ValueType V, bool MayAlias)
ValueType getValue() const
VReg2SUnitOperIdx(Register VReg, LaneBitmask LaneMask, unsigned OperandIndex, SUnit *SU)
VReg2SUnit(Register VReg, LaneBitmask LaneMask, SUnit *SU)
unsigned getSparseSetIndex() const