LLVM 17.0.0git
MachinePipeliner.h
Go to the documentation of this file.
1//===- MachinePipeliner.h - Machine Software Pipeliner Pass -------------===//
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// An implementation of the Swing Modulo Scheduling (SMS) software pipeliner.
10//
11// Software pipelining (SWP) is an instruction scheduling technique for loops
12// that overlap loop iterations and exploits ILP via a compiler transformation.
13//
14// Swing Modulo Scheduling is an implementation of software pipelining
15// that generates schedules that are near optimal in terms of initiation
16// interval, register requirements, and stage count. See the papers:
17//
18// "Swing Modulo Scheduling: A Lifetime-Sensitive Approach", by J. Llosa,
19// A. Gonzalez, E. Ayguade, and M. Valero. In PACT '96 Proceedings of the 1996
20// Conference on Parallel Architectures and Compilation Techiniques.
21//
22// "Lifetime-Sensitive Modulo Scheduling in a Production Environment", by J.
23// Llosa, E. Ayguade, A. Gonzalez, M. Valero, and J. Eckhardt. In IEEE
24// Transactions on Computers, Vol. 50, No. 3, 2001.
25//
26// "An Implementation of Swing Modulo Scheduling With Extensions for
27// Superblocks", by T. Lattner, Master's Thesis, University of Illinois at
28// Urbana-Champaign, 2005.
29//
30//
31// The SMS algorithm consists of three main steps after computing the minimal
32// initiation interval (MII).
33// 1) Analyze the dependence graph and compute information about each
34// instruction in the graph.
35// 2) Order the nodes (instructions) by priority based upon the heuristics
36// described in the algorithm.
37// 3) Attempt to schedule the nodes in the specified order using the MII.
38//
39//===----------------------------------------------------------------------===//
40#ifndef LLVM_CODEGEN_MACHINEPIPELINER_H
41#define LLVM_CODEGEN_MACHINEPIPELINER_H
42
43#include "llvm/ADT/SetVector.h"
52
53#include <deque>
54
55namespace llvm {
56
57class AAResults;
58class NodeSet;
59class SMSchedule;
60
61extern cl::opt<bool> SwpEnableCopyToPhi;
62extern cl::opt<int> SwpForceIssueWidth;
63
64/// The main class in the implementation of the target independent
65/// software pipeliner pass.
67public:
68 MachineFunction *MF = nullptr;
70 const MachineLoopInfo *MLI = nullptr;
71 const MachineDominatorTree *MDT = nullptr;
73 const TargetInstrInfo *TII = nullptr;
75 bool disabledByPragma = false;
76 unsigned II_setByPragma = 0;
77
78#ifndef NDEBUG
79 static int NumTries;
80#endif
81
82 /// Cache the target analysis information about the loop.
83 struct LoopInfo {
89 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo> LoopPipelinerInfo =
90 nullptr;
91 };
93
94 static char ID;
95
98 }
99
101
102 void getAnalysisUsage(AnalysisUsage &AU) const override;
103
104private:
105 void preprocessPhiNodes(MachineBasicBlock &B);
106 bool canPipelineLoop(MachineLoop &L);
107 bool scheduleLoop(MachineLoop &L);
108 bool swingModuloScheduler(MachineLoop &L);
109 void setPragmaPipelineOptions(MachineLoop &L);
110};
111
112/// This class builds the dependence graph for the instructions in a loop,
113/// and attempts to schedule the instructions using the SMS algorithm.
116 /// The minimum initiation interval between iterations for this schedule.
117 unsigned MII = 0;
118 /// The maximum initiation interval between iterations for this schedule.
119 unsigned MAX_II = 0;
120 /// Set to true if a valid pipelined schedule is found for the loop.
121 bool Scheduled = false;
123 LiveIntervals &LIS;
124 const RegisterClassInfo &RegClassInfo;
125 unsigned II_setByPragma = 0;
126 TargetInstrInfo::PipelinerLoopInfo *LoopPipelinerInfo = nullptr;
127
128 /// A toplogical ordering of the SUnits, which is needed for changing
129 /// dependences and iterating over the SUnits.
131
132 struct NodeInfo {
133 int ASAP = 0;
134 int ALAP = 0;
135 int ZeroLatencyDepth = 0;
136 int ZeroLatencyHeight = 0;
137
138 NodeInfo() = default;
139 };
140 /// Computed properties for each node in the graph.
141 std::vector<NodeInfo> ScheduleInfo;
142
143 enum OrderKind { BottomUp = 0, TopDown = 1 };
144 /// Computed node ordering for scheduling.
145 SetVector<SUnit *> NodeOrder;
146
151
152 /// Instructions to change when emitting the final schedule.
154
155 /// We may create a new instruction, so remember it because it
156 /// must be deleted when the pass is finished.
158
159 /// Ordered list of DAG postprocessing steps.
160 std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
161
162 /// Helper class to implement Johnson's circuit finding algorithm.
163 class Circuits {
164 std::vector<SUnit> &SUnits;
165 SetVector<SUnit *> Stack;
166 BitVector Blocked;
169 // Node to Index from ScheduleDAGTopologicalSort
170 std::vector<int> *Node2Idx;
171 unsigned NumPaths;
172 static unsigned MaxPaths;
173
174 public:
175 Circuits(std::vector<SUnit> &SUs, ScheduleDAGTopologicalSort &Topo)
176 : SUnits(SUs), Blocked(SUs.size()), B(SUs.size()), AdjK(SUs.size()) {
177 Node2Idx = new std::vector<int>(SUs.size());
178 unsigned Idx = 0;
179 for (const auto &NodeNum : Topo)
180 Node2Idx->at(NodeNum) = Idx++;
181 }
182
183 ~Circuits() { delete Node2Idx; }
184
185 /// Reset the data structures used in the circuit algorithm.
186 void reset() {
187 Stack.clear();
188 Blocked.reset();
189 B.assign(SUnits.size(), SmallPtrSet<SUnit *, 4>());
190 NumPaths = 0;
191 }
192
193 void createAdjacencyStructure(SwingSchedulerDAG *DAG);
194 bool circuit(int V, int S, NodeSetType &NodeSets, bool HasBackedge = false);
195 void unblock(int U);
196 };
197
198 struct CopyToPhiMutation : public ScheduleDAGMutation {
199 void apply(ScheduleDAGInstrs *DAG) override;
200 };
201
202public:
204 const RegisterClassInfo &rci, unsigned II,
206 : ScheduleDAGInstrs(*P.MF, P.MLI, false), Pass(P), Loop(L), LIS(lis),
207 RegClassInfo(rci), II_setByPragma(II), LoopPipelinerInfo(PLI),
208 Topo(SUnits, &ExitSU) {
209 P.MF->getSubtarget().getSMSMutations(Mutations);
211 Mutations.push_back(std::make_unique<CopyToPhiMutation>());
212 }
213
214 void schedule() override;
215 void finishBlock() override;
216
217 /// Return true if the loop kernel has been scheduled.
218 bool hasNewSchedule() { return Scheduled; }
219
220 /// Return the earliest time an instruction may be scheduled.
221 int getASAP(SUnit *Node) { return ScheduleInfo[Node->NodeNum].ASAP; }
222
223 /// Return the latest time an instruction my be scheduled.
224 int getALAP(SUnit *Node) { return ScheduleInfo[Node->NodeNum].ALAP; }
225
226 /// The mobility function, which the number of slots in which
227 /// an instruction may be scheduled.
228 int getMOV(SUnit *Node) { return getALAP(Node) - getASAP(Node); }
229
230 /// The depth, in the dependence graph, for a node.
231 unsigned getDepth(SUnit *Node) { return Node->getDepth(); }
232
233 /// The maximum unweighted length of a path from an arbitrary node to the
234 /// given node in which each edge has latency 0
236 return ScheduleInfo[Node->NodeNum].ZeroLatencyDepth;
237 }
238
239 /// The height, in the dependence graph, for a node.
240 unsigned getHeight(SUnit *Node) { return Node->getHeight(); }
241
242 /// The maximum unweighted length of a path from the given node to an
243 /// arbitrary node in which each edge has latency 0
245 return ScheduleInfo[Node->NodeNum].ZeroLatencyHeight;
246 }
247
248 /// Return true if the dependence is a back-edge in the data dependence graph.
249 /// Since the DAG doesn't contain cycles, we represent a cycle in the graph
250 /// using an anti dependence from a Phi to an instruction.
251 bool isBackedge(SUnit *Source, const SDep &Dep) {
252 if (Dep.getKind() != SDep::Anti)
253 return false;
254 return Source->getInstr()->isPHI() || Dep.getSUnit()->getInstr()->isPHI();
255 }
256
257 bool isLoopCarriedDep(SUnit *Source, const SDep &Dep, bool isSucc = true);
258
259 /// The distance function, which indicates that operation V of iteration I
260 /// depends on operations U of iteration I-distance.
261 unsigned getDistance(SUnit *U, SUnit *V, const SDep &Dep) {
262 // Instructions that feed a Phi have a distance of 1. Computing larger
263 // values for arrays requires data dependence information.
264 if (V->getInstr()->isPHI() && Dep.getKind() == SDep::Anti)
265 return 1;
266 return 0;
267 }
268
269 void applyInstrChange(MachineInstr *MI, SMSchedule &Schedule);
270
271 void fixupRegisterOverlaps(std::deque<SUnit *> &Instrs);
272
273 /// Return the new base register that was stored away for the changed
274 /// instruction.
275 unsigned getInstrBaseReg(SUnit *SU) {
277 InstrChanges.find(SU);
278 if (It != InstrChanges.end())
279 return It->second.first;
280 return 0;
281 }
282
283 void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation) {
284 Mutations.push_back(std::move(Mutation));
285 }
286
287 static bool classof(const ScheduleDAGInstrs *DAG) { return true; }
288
289private:
290 void addLoopCarriedDependences(AAResults *AA);
291 void updatePhiDependences();
292 void changeDependences();
293 unsigned calculateResMII();
294 unsigned calculateRecMII(NodeSetType &RecNodeSets);
295 void findCircuits(NodeSetType &NodeSets);
296 void fuseRecs(NodeSetType &NodeSets);
297 void removeDuplicateNodes(NodeSetType &NodeSets);
298 void computeNodeFunctions(NodeSetType &NodeSets);
299 void registerPressureFilter(NodeSetType &NodeSets);
300 void colocateNodeSets(NodeSetType &NodeSets);
301 void checkNodeSets(NodeSetType &NodeSets);
302 void groupRemainingNodes(NodeSetType &NodeSets);
303 void addConnectedNodes(SUnit *SU, NodeSet &NewSet,
304 SetVector<SUnit *> &NodesAdded);
305 void computeNodeOrder(NodeSetType &NodeSets);
306 void checkValidNodeOrder(const NodeSetType &Circuits) const;
307 bool schedulePipeline(SMSchedule &Schedule);
308 bool computeDelta(MachineInstr &MI, unsigned &Delta);
309 MachineInstr *findDefInLoop(Register Reg);
310 bool canUseLastOffsetValue(MachineInstr *MI, unsigned &BasePos,
311 unsigned &OffsetPos, unsigned &NewBase,
312 int64_t &NewOffset);
313 void postprocessDAG();
314 /// Set the Minimum Initiation Interval for this schedule attempt.
315 void setMII(unsigned ResMII, unsigned RecMII);
316 /// Set the Maximum Initiation Interval for this schedule attempt.
317 void setMAX_II();
318};
319
320/// A NodeSet contains a set of SUnit DAG nodes with additional information
321/// that assigns a priority to the set.
322class NodeSet {
323 SetVector<SUnit *> Nodes;
324 bool HasRecurrence = false;
325 unsigned RecMII = 0;
326 int MaxMOV = 0;
327 unsigned MaxDepth = 0;
328 unsigned Colocate = 0;
329 SUnit *ExceedPressure = nullptr;
330 unsigned Latency = 0;
331
332public:
334
335 NodeSet() = default;
336 NodeSet(iterator S, iterator E) : Nodes(S, E), HasRecurrence(true) {
337 Latency = 0;
338 for (const SUnit *Node : Nodes) {
339 DenseMap<SUnit *, unsigned> SuccSUnitLatency;
340 for (const SDep &Succ : Node->Succs) {
341 auto SuccSUnit = Succ.getSUnit();
342 if (!Nodes.count(SuccSUnit))
343 continue;
344 unsigned CurLatency = Succ.getLatency();
345 unsigned MaxLatency = 0;
346 if (SuccSUnitLatency.count(SuccSUnit))
347 MaxLatency = SuccSUnitLatency[SuccSUnit];
348 if (CurLatency > MaxLatency)
349 SuccSUnitLatency[SuccSUnit] = CurLatency;
350 }
351 for (auto SUnitLatency : SuccSUnitLatency)
352 Latency += SUnitLatency.second;
353 }
354 }
355
356 bool insert(SUnit *SU) { return Nodes.insert(SU); }
357
358 void insert(iterator S, iterator E) { Nodes.insert(S, E); }
359
360 template <typename UnaryPredicate> bool remove_if(UnaryPredicate P) {
361 return Nodes.remove_if(P);
362 }
363
364 unsigned count(SUnit *SU) const { return Nodes.count(SU); }
365
366 bool hasRecurrence() { return HasRecurrence; };
367
368 unsigned size() const { return Nodes.size(); }
369
370 bool empty() const { return Nodes.empty(); }
371
372 SUnit *getNode(unsigned i) const { return Nodes[i]; };
373
374 void setRecMII(unsigned mii) { RecMII = mii; };
375
376 void setColocate(unsigned c) { Colocate = c; };
377
378 void setExceedPressure(SUnit *SU) { ExceedPressure = SU; }
379
380 bool isExceedSU(SUnit *SU) { return ExceedPressure == SU; }
381
382 int compareRecMII(NodeSet &RHS) { return RecMII - RHS.RecMII; }
383
384 int getRecMII() { return RecMII; }
385
386 /// Summarize node functions for the entire node set.
388 for (SUnit *SU : *this) {
389 MaxMOV = std::max(MaxMOV, SSD->getMOV(SU));
390 MaxDepth = std::max(MaxDepth, SSD->getDepth(SU));
391 }
392 }
393
394 unsigned getLatency() { return Latency; }
395
396 unsigned getMaxDepth() { return MaxDepth; }
397
398 void clear() {
399 Nodes.clear();
400 RecMII = 0;
401 HasRecurrence = false;
402 MaxMOV = 0;
403 MaxDepth = 0;
404 Colocate = 0;
405 ExceedPressure = nullptr;
406 }
407
408 operator SetVector<SUnit *> &() { return Nodes; }
409
410 /// Sort the node sets by importance. First, rank them by recurrence MII,
411 /// then by mobility (least mobile done first), and finally by depth.
412 /// Each node set may contain a colocate value which is used as the first
413 /// tie breaker, if it's set.
414 bool operator>(const NodeSet &RHS) const {
415 if (RecMII == RHS.RecMII) {
416 if (Colocate != 0 && RHS.Colocate != 0 && Colocate != RHS.Colocate)
417 return Colocate < RHS.Colocate;
418 if (MaxMOV == RHS.MaxMOV)
419 return MaxDepth > RHS.MaxDepth;
420 return MaxMOV < RHS.MaxMOV;
421 }
422 return RecMII > RHS.RecMII;
423 }
424
425 bool operator==(const NodeSet &RHS) const {
426 return RecMII == RHS.RecMII && MaxMOV == RHS.MaxMOV &&
427 MaxDepth == RHS.MaxDepth;
428 }
429
430 bool operator!=(const NodeSet &RHS) const { return !operator==(RHS); }
431
432 iterator begin() { return Nodes.begin(); }
433 iterator end() { return Nodes.end(); }
434 void print(raw_ostream &os) const;
435
436#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
437 LLVM_DUMP_METHOD void dump() const;
438#endif
439};
440
441// 16 was selected based on the number of ProcResource kinds for all
442// existing Subtargets, so that SmallVector don't need to resize too often.
443static const int DefaultProcResSize = 16;
444
446private:
447 const MCSubtargetInfo *STI;
448 const MCSchedModel &SM;
449 const TargetSubtargetInfo *ST;
450 const TargetInstrInfo *TII;
452 const bool UseDFA;
453 /// DFA resources for each slot
455 /// Modulo Reservation Table. When a resource with ID R is consumed in cycle
456 /// C, it is counted in MRT[C mod II][R]. (Used when UseDFA == F)
458 /// The number of scheduled micro operations for each slot. Micro operations
459 /// are assumed to be scheduled one per cycle, starting with the cycle in
460 /// which the instruction is scheduled.
461 llvm::SmallVector<int> NumScheduledMops;
462 /// Each processor resource is associated with a so-called processor resource
463 /// mask. This vector allows to correlate processor resource IDs with
464 /// processor resource masks. There is exactly one element per each processor
465 /// resource declared by the scheduling model.
467 int InitiationInterval;
468 /// The number of micro operations that can be scheduled at a cycle.
469 int IssueWidth;
470
471 int calculateResMIIDFA() const;
472 /// Check if MRT is overbooked
473 bool isOverbooked() const;
474 /// Reserve resources on MRT
475 void reserveResources(const MCSchedClassDesc *SCDesc, int Cycle);
476 /// Unreserve resources on MRT
477 void unreserveResources(const MCSchedClassDesc *SCDesc, int Cycle);
478
479 /// Return M satisfying Dividend = Divisor * X + M, 0 < M < Divisor.
480 /// The slot on MRT to reserve a resource for the cycle C is positiveModulo(C,
481 /// II).
482 int positiveModulo(int Dividend, int Divisor) const {
483 assert(Divisor > 0);
484 int R = Dividend % Divisor;
485 if (R < 0)
486 R += Divisor;
487 return R;
488 }
489
490#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
491 LLVM_DUMP_METHOD void dumpMRT() const;
492#endif
493
494public:
496 : STI(ST), SM(ST->getSchedModel()), ST(ST), TII(ST->getInstrInfo()),
497 DAG(DAG), UseDFA(ST->useDFAforSMS()),
498 ProcResourceMasks(SM.getNumProcResourceKinds(), 0),
499 IssueWidth(SM.IssueWidth) {
500 initProcResourceVectors(SM, ProcResourceMasks);
501 if (IssueWidth <= 0)
502 // If IssueWidth is not specified, set a sufficiently large value
503 IssueWidth = 100;
504 if (SwpForceIssueWidth > 0)
505 IssueWidth = SwpForceIssueWidth;
506 }
507
510
511 /// Check if the resources occupied by a machine instruction are available
512 /// in the current state.
513 bool canReserveResources(SUnit &SU, int Cycle);
514
515 /// Reserve the resources occupied by a machine instruction and change the
516 /// current state to reflect that change.
517 void reserveResources(SUnit &SU, int Cycle);
518
519 int calculateResMII() const;
520
521 /// Initialize resources with the initiation interval II.
522 void init(int II);
523};
524
525/// This class represents the scheduled code. The main data structure is a
526/// map from scheduled cycle to instructions. During scheduling, the
527/// data structure explicitly represents all stages/iterations. When
528/// the algorithm finshes, the schedule is collapsed into a single stage,
529/// which represents instructions from different loop iterations.
530///
531/// The SMS algorithm allows negative values for cycles, so the first cycle
532/// in the schedule is the smallest cycle value.
534private:
535 /// Map from execution cycle to instructions.
536 DenseMap<int, std::deque<SUnit *>> ScheduledInstrs;
537
538 /// Map from instruction to execution cycle.
539 std::map<SUnit *, int> InstrToCycle;
540
541 /// Keep track of the first cycle value in the schedule. It starts
542 /// as zero, but the algorithm allows negative values.
543 int FirstCycle = 0;
544
545 /// Keep track of the last cycle value in the schedule.
546 int LastCycle = 0;
547
548 /// The initiation interval (II) for the schedule.
549 int InitiationInterval = 0;
550
551 /// Target machine information.
552 const TargetSubtargetInfo &ST;
553
554 /// Virtual register information.
556
557 ResourceManager ProcItinResources;
558
559public:
561 : ST(mf->getSubtarget()), MRI(mf->getRegInfo()),
562 ProcItinResources(&ST, DAG) {}
563
564 void reset() {
565 ScheduledInstrs.clear();
566 InstrToCycle.clear();
567 FirstCycle = 0;
568 LastCycle = 0;
569 InitiationInterval = 0;
570 }
571
572 /// Set the initiation interval for this schedule.
574 InitiationInterval = ii;
575 ProcItinResources.init(ii);
576 }
577
578 /// Return the initiation interval for this schedule.
579 int getInitiationInterval() const { return InitiationInterval; }
580
581 /// Return the first cycle in the completed schedule. This
582 /// can be a negative value.
583 int getFirstCycle() const { return FirstCycle; }
584
585 /// Return the last cycle in the finalized schedule.
586 int getFinalCycle() const { return FirstCycle + InitiationInterval - 1; }
587
588 /// Return the cycle of the earliest scheduled instruction in the dependence
589 /// chain.
590 int earliestCycleInChain(const SDep &Dep);
591
592 /// Return the cycle of the latest scheduled instruction in the dependence
593 /// chain.
594 int latestCycleInChain(const SDep &Dep);
595
596 void computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart,
597 int *MinEnd, int *MaxStart, int II, SwingSchedulerDAG *DAG);
598 bool insert(SUnit *SU, int StartCycle, int EndCycle, int II);
599
600 /// Iterators for the cycle to instruction map.
604
605 /// Return true if the instruction is scheduled at the specified stage.
606 bool isScheduledAtStage(SUnit *SU, unsigned StageNum) {
607 return (stageScheduled(SU) == (int)StageNum);
608 }
609
610 /// Return the stage for a scheduled instruction. Return -1 if
611 /// the instruction has not been scheduled.
612 int stageScheduled(SUnit *SU) const {
613 std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
614 if (it == InstrToCycle.end())
615 return -1;
616 return (it->second - FirstCycle) / InitiationInterval;
617 }
618
619 /// Return the cycle for a scheduled instruction. This function normalizes
620 /// the first cycle to be 0.
621 unsigned cycleScheduled(SUnit *SU) const {
622 std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
623 assert(it != InstrToCycle.end() && "Instruction hasn't been scheduled.");
624 return (it->second - FirstCycle) % InitiationInterval;
625 }
626
627 /// Return the maximum stage count needed for this schedule.
628 unsigned getMaxStageCount() {
629 return (LastCycle - FirstCycle) / InitiationInterval;
630 }
631
632 /// Return the instructions that are scheduled at the specified cycle.
633 std::deque<SUnit *> &getInstructions(int cycle) {
634 return ScheduledInstrs[cycle];
635 }
636
640
641 bool
647 std::deque<SUnit *> &Insts);
650 MachineOperand &MO);
651 void print(raw_ostream &os) const;
652 void dump() const;
653};
654
655} // end namespace llvm
656
657#endif // LLVM_CODEGEN_MACHINEPIPELINER_H
unsigned const MachineRegisterInfo * MRI
basic Basic Alias true
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:492
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*-—===//
unsigned Reg
#define P(N)
PowerPC VSX FMA Mutation
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
Value * RHS
Represent the analysis usage information of a pass.
BitVector & reset()
Definition: BitVector.h:385
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:155
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:151
iterator end()
Definition: DenseMap.h:84
A possibly irreducible generalization of a Loop.
Itinerary data supplied by a subtarget to be used by a target.
Represents a single loop in the control flow graph.
Definition: LoopInfo.h:547
Generic base class for all target subtargets.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Representation of each machine instruction.
Definition: MachineInstr.h:68
bool isPHI() const
MachineOperand class - Representation of each machine instruction operand.
The main class in the implementation of the target independent software pipeliner pass.
const TargetInstrInfo * TII
bool runOnMachineFunction(MachineFunction &MF) override
The "main" function for implementing Swing Modulo Scheduling.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MachineFunction * MF
const MachineDominatorTree * MDT
const MachineLoopInfo * MLI
MachineOptimizationRemarkEmitter * ORE
RegisterClassInfo RegClassInfo
const InstrItineraryData * InstrItins
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A NodeSet contains a set of SUnit DAG nodes with additional information that assigns a priority to th...
SUnit * getNode(unsigned i) const
SetVector< SUnit * >::const_iterator iterator
void print(raw_ostream &os) const
bool isExceedSU(SUnit *SU)
void insert(iterator S, iterator E)
iterator begin()
void setRecMII(unsigned mii)
void computeNodeSetInfo(SwingSchedulerDAG *SSD)
Summarize node functions for the entire node set.
unsigned getMaxDepth()
unsigned count(SUnit *SU) const
NodeSet()=default
void setColocate(unsigned c)
unsigned getLatency()
bool operator>(const NodeSet &RHS) const
Sort the node sets by importance.
int compareRecMII(NodeSet &RHS)
unsigned size() const
NodeSet(iterator S, iterator E)
bool operator!=(const NodeSet &RHS) const
bool insert(SUnit *SU)
LLVM_DUMP_METHOD void dump() const
bool operator==(const NodeSet &RHS) const
bool remove_if(UnaryPredicate P)
bool empty() const
void setExceedPressure(SUnit *SU)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
void initProcResourceVectors(const MCSchedModel &SM, SmallVectorImpl< uint64_t > &Masks)
ResourceManager(const TargetSubtargetInfo *ST, SwingSchedulerDAG *DAG)
void init(int II)
Initialize resources with the initiation interval II.
bool canReserveResources(SUnit &SU, int Cycle)
Check if the resources occupied by a machine instruction are available in the current state.
Scheduling dependency.
Definition: ScheduleDAG.h:49
SUnit * getSUnit() const
Definition: ScheduleDAG.h:480
Kind getKind() const
Returns an enum value representing the kind of the dependence.
Definition: ScheduleDAG.h:486
@ Anti
A register anti-dependence (aka WAR).
Definition: ScheduleDAG.h:54
unsigned getLatency() const
Returns the latency value for this edge, which roughly means the minimum number of cycles that must e...
Definition: ScheduleDAG.h:142
This class represents the scheduled code.
int earliestCycleInChain(const SDep &Dep)
Return the cycle of the earliest scheduled instruction in the dependence chain.
void setInitiationInterval(int ii)
Set the initiation interval for this schedule.
SmallSet< SUnit *, 8 > computeUnpipelineableNodes(SwingSchedulerDAG *SSD, TargetInstrInfo::PipelinerLoopInfo *PLI)
Determine transitive dependences of unpipelineable instructions.
bool isLoopCarriedDefOfUse(SwingSchedulerDAG *SSD, MachineInstr *Def, MachineOperand &MO)
Return true if the instruction is a definition that is loop carried and defines the use on the next i...
void dump() const
Utility function used for debugging to print the schedule.
bool insert(SUnit *SU, int StartCycle, int EndCycle, int II)
Try to schedule the node at the specified StartCycle and continue until the node is schedule or the E...
unsigned getMaxStageCount()
Return the maximum stage count needed for this schedule.
void print(raw_ostream &os) const
Print the schedule information to the given output.
int latestCycleInChain(const SDep &Dep)
Return the cycle of the latest scheduled instruction in the dependence chain.
int stageScheduled(SUnit *SU) const
Return the stage for a scheduled instruction.
bool isScheduledAtStage(SUnit *SU, unsigned StageNum)
Return true if the instruction is scheduled at the specified stage.
void computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart, int *MinEnd, int *MaxStart, int II, SwingSchedulerDAG *DAG)
Compute the scheduling start slot for the instruction.
bool isValidSchedule(SwingSchedulerDAG *SSD)
int getInitiationInterval() const
Return the initiation interval for this schedule.
std::deque< SUnit * > & getInstructions(int cycle)
Return the instructions that are scheduled at the specified cycle.
int getFirstCycle() const
Return the first cycle in the completed schedule.
unsigned cycleScheduled(SUnit *SU) const
Return the cycle for a scheduled instruction.
bool isLoopCarried(SwingSchedulerDAG *SSD, MachineInstr &Phi)
Return true if the scheduled Phi has a loop carried operand.
SMSchedule(MachineFunction *mf, SwingSchedulerDAG *DAG)
bool normalizeNonPipelinedInstructions(SwingSchedulerDAG *SSD, TargetInstrInfo::PipelinerLoopInfo *PLI)
int getFinalCycle() const
Return the last cycle in the finalized schedule.
void orderDependence(SwingSchedulerDAG *SSD, SUnit *SU, std::deque< SUnit * > &Insts)
Order the instructions within a cycle so that the definitions occur before the uses.
void finalizeSchedule(SwingSchedulerDAG *SSD)
After the schedule has been formed, call this function to combine the instructions from the different...
Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:242
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
Definition: ScheduleDAG.h:373
A ScheduleDAG for scheduling lists of MachineInstr.
const MachineLoopInfo * MLI
Mutate the DAG as a postpass after normal DAG building.
This class can compute a topological ordering for SUnits and provides methods for dynamically updatin...
Definition: ScheduleDAG.h:693
std::vector< SUnit > SUnits
The scheduling units.
Definition: ScheduleDAG.h:561
MachineFunction & MF
Machine function.
Definition: ScheduleDAG.h:559
SUnit ExitSU
Special node for the region exit.
Definition: ScheduleDAG.h:563
A vector that has set insertion semantics.
Definition: SetVector.h:40
size_type size() const
Determine the number of elements in the SetVector.
Definition: SetVector.h:77
typename vector_type::const_iterator const_iterator
Definition: SetVector.h:49
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
Definition: SetVector.h:208
bool remove_if(UnaryPredicate P)
Remove items from the set vector based on a predicate function.
Definition: SetVector.h:192
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:141
void clear()
Completely clear the SetVector.
Definition: SetVector.h:213
bool empty() const
Determine if the SetVector is empty or not.
Definition: SetVector.h:72
iterator begin()
Get an iterator to the beginning of the SetVector.
Definition: SetVector.h:82
iterator end()
Get an iterator to the end of the SetVector.
Definition: SetVector.h:92
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:450
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:135
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
This class builds the dependence graph for the instructions in a loop, and attempts to schedule the i...
unsigned getDepth(SUnit *Node)
The depth, in the dependence graph, for a node.
unsigned getInstrBaseReg(SUnit *SU)
Return the new base register that was stored away for the changed instruction.
int getASAP(SUnit *Node)
Return the earliest time an instruction may be scheduled.
void applyInstrChange(MachineInstr *MI, SMSchedule &Schedule)
Apply changes to the instruction if needed.
void finishBlock() override
Clean up after the software pipeliner runs.
void fixupRegisterOverlaps(std::deque< SUnit * > &Instrs)
Attempt to fix the degenerate cases when the instruction serialization causes the register lifetimes ...
bool hasNewSchedule()
Return true if the loop kernel has been scheduled.
void addMutation(std::unique_ptr< ScheduleDAGMutation > Mutation)
SwingSchedulerDAG(MachinePipeliner &P, MachineLoop &L, LiveIntervals &lis, const RegisterClassInfo &rci, unsigned II, TargetInstrInfo::PipelinerLoopInfo *PLI)
int getZeroLatencyDepth(SUnit *Node)
The maximum unweighted length of a path from an arbitrary node to the given node in which each edge h...
bool isLoopCarriedDep(SUnit *Source, const SDep &Dep, bool isSucc=true)
Return true for an order or output dependence that is loop carried potentially.
unsigned getDistance(SUnit *U, SUnit *V, const SDep &Dep)
The distance function, which indicates that operation V of iteration I depends on operations U of ite...
void schedule() override
We override the schedule function in ScheduleDAGInstrs to implement the scheduling part of the Swing ...
int getMOV(SUnit *Node)
The mobility function, which the number of slots in which an instruction may be scheduled.
int getZeroLatencyHeight(SUnit *Node)
The maximum unweighted length of a path from the given node to an arbitrary node in which each edge h...
bool isBackedge(SUnit *Source, const SDep &Dep)
Return true if the dependence is a back-edge in the data dependence graph.
static bool classof(const ScheduleDAGInstrs *DAG)
unsigned getHeight(SUnit *Node)
The height, in the dependence graph, for a node.
int getALAP(SUnit *Node)
Return the latest time an instruction my be scheduled.
Object returned by analyzeLoopForPipelining.
TargetInstrInfo - Interface to description of machine instruction set.
TargetSubtargetInfo - Generic base class for all target subtargets.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
std::set< NodeId > NodeSet
Definition: RDFGraph.h:514
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void initializeMachinePipelinerPass(PassRegistry &)
cl::opt< bool > SwpEnableCopyToPhi
static const int DefaultProcResSize
cl::opt< int > SwpForceIssueWidth
A command line argument to force pipeliner to use specified issue width.
Summarize the scheduling resources required for an instruction of a particular scheduling class.
Definition: MCSchedule.h:109
Machine model for scheduling, bundling, and heuristics.
Definition: MCSchedule.h:244
Cache the target analysis information about the loop.
SmallVector< MachineOperand, 4 > BrCond
std::unique_ptr< TargetInstrInfo::PipelinerLoopInfo > LoopPipelinerInfo