LLVM 24.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/STLExtras.h"
44#include "llvm/ADT/SetVector.h"
55
56#include <deque>
57
58namespace llvm {
59
60class AAResults;
61class LiveIntervals;
62class NodeSet;
63class SMSchedule;
64
67
68/// Software pipelining policy for a loop, which a target can customize by
69/// implementing TargetSubtargetInfo::overridePipelinerPolicy.
71 /// Limit the register pressure of the scheduled loop, retrying at a higher
72 /// II when a schedule needs too many registers.
74};
75
77public:
78 static char ID;
79
81
82 bool runOnMachineFunction(MachineFunction &MF) override;
83
84 void getAnalysisUsage(AnalysisUsage &AU) const override;
85};
86
88 : public OptionalPassInfoMixin<MachinePipelinerPass> {
89public:
92};
93
94/// Represents a dependence between two instruction.
96 SUnit *Dst = nullptr;
97 SDep Pred;
98 unsigned Distance = 0;
99 bool IsValidationOnly = false;
100
101public:
102 /// Creates an edge corresponding to an edge represented by \p PredOrSucc and
103 /// \p Dep in the original DAG. This pair has no information about the
104 /// direction of the edge, so we need to pass an additional argument \p
105 /// IsSucc.
106 SwingSchedulerDDGEdge(SUnit *PredOrSucc, const SDep &Dep, bool IsSucc,
107 bool IsValidationOnly)
108 : Dst(PredOrSucc), Pred(Dep), Distance(0u),
109 IsValidationOnly(IsValidationOnly) {
110 SUnit *Src = Dep.getSUnit();
111
112 if (IsSucc) {
113 std::swap(Src, Dst);
114 Pred.setSUnit(Src);
115 }
116
117 // An anti-dependence to PHI means loop-carried dependence.
118 if (Pred.getKind() == SDep::Anti && Src->getInstr()->isPHI()) {
119 Distance = 1;
120 std::swap(Src, Dst);
121 auto Reg = Pred.getReg();
122 Pred = SDep(Src, SDep::Kind::Data, Reg);
123 }
124 }
125
126 /// Returns the SUnit from which the edge comes (source node).
127 SUnit *getSrc() const { return Pred.getSUnit(); }
128
129 /// Returns the SUnit to which the edge points (destination node).
130 SUnit *getDst() const { return Dst; }
131
132 /// Returns the latency value for the edge.
133 unsigned getLatency() const { return Pred.getLatency(); }
134
135 /// Sets the latency for the edge.
136 void setLatency(unsigned Latency) { Pred.setLatency(Latency); }
137
138 /// Returns the distance value for the edge.
139 unsigned getDistance() const { return Distance; }
140
141 /// Sets the distance value for the edge.
142 void setDistance(unsigned D) { Distance = D; }
143
144 /// Returns the register associated with the edge.
145 Register getReg() const { return Pred.getReg(); }
146
147 /// Returns true if the edge represents anti dependence.
148 bool isAntiDep() const { return Pred.getKind() == SDep::Kind::Anti; }
149
150 /// Returns true if the edge represents output dependence.
151 bool isOutputDep() const { return Pred.getKind() == SDep::Kind::Output; }
152
153 /// Returns true if the edge represents a dependence that is not data, anti or
154 /// output dependence.
155 bool isOrderDep() const { return Pred.getKind() == SDep::Kind::Order; }
156
157 /// Returns true if the edge represents unknown scheduling barrier.
158 bool isBarrier() const { return Pred.isBarrier(); }
159
160 /// Returns true if the edge represents an artificial dependence.
161 bool isArtificial() const { return Pred.isArtificial(); }
162
163 /// Tests if this is a Data dependence that is associated with a register.
164 bool isAssignedRegDep() const { return Pred.isAssignedRegDep(); }
165
166 /// Returns true for DDG nodes that we ignore when computing the cost
167 /// functions. We ignore the back-edge recurrence in order to avoid unbounded
168 /// recursion in the calculation of the ASAP, ALAP, etc functions.
169 LLVM_ABI bool ignoreDependence(bool IgnoreAnti) const;
170
171 /// Returns true if this edge is intended to be used only for validating the
172 /// schedule.
173 bool isValidationOnly() const { return IsValidationOnly; }
174};
175
176/// Represents loop-carried dependencies. Because SwingSchedulerDAG doesn't
177/// assume cycle dependencies as the name suggests, such dependencies must be
178/// handled separately. After DAG construction is finished, these dependencies
179/// are added to SwingSchedulerDDG.
180/// TODO: Also handle output-dependencies introduced by physical registers.
184
186
188 auto Ite = OrderDeps.find(Key);
189 if (Ite == OrderDeps.end())
190 return nullptr;
191 return &Ite->second;
192 }
193
194 /// Adds some edges to the original DAG that correspond to loop-carried
195 /// dependencies. Historically, loop-carried edges are represented by using
196 /// non-loop-carried edges in the original DAG. This function appends such
197 /// edges to preserve the previous behavior.
198 LLVM_ABI void modifySUnits(std::vector<SUnit> &SUnits,
199 const TargetInstrInfo *TII);
200
201 LLVM_ABI void dump(SUnit *SU, const TargetRegisterInfo *TRI,
202 const MachineRegisterInfo *MRI) const;
203};
204
205/// This class provides APIs to retrieve edges from/to an SUnit node, with a
206/// particular focus on loop-carried dependencies. Since SUnit is not designed
207/// to represent such edges, handling them directly using its APIs has required
208/// non-trivial logic in the past. This class serves as a wrapper around SUnit,
209/// offering a simpler interface for managing these dependencies.
212
213 struct SwingSchedulerDDGEdges {
214 EdgesType Preds;
215 EdgesType Succs;
216
217 /// This field is a subset of ValidationOnlyEdges. These edges are used only
218 /// by specific heuristics, mainly for cycle detection. Although they are
219 /// unnecessary in theory (i.e., ignoring them should still yield a valid
220 /// schedule), they are retained to preserve the existing behavior. Since we
221 /// only need which extra edges exist from a given SUnit, we only store the
222 /// destination SUnits.
223 SmallVector<SUnit *, 4> ExtraSuccs;
224 };
225
226 void initEdges(SUnit *SU);
227
228 SUnit *EntrySU;
229 SUnit *ExitSU;
230
231 std::vector<SwingSchedulerDDGEdges> EdgesVec;
232 SwingSchedulerDDGEdges EntrySUEdges;
233 SwingSchedulerDDGEdges ExitSUEdges;
234
235 /// Edges that are used only when validating the schedule. These edges are
236 /// not considered to drive the optimization heuristics.
237 SmallVector<SwingSchedulerDDGEdge, 8> ValidationOnlyEdges;
238
239 /// Adds a NON-validation-only edge to the DDG. Assumes to be called only by
240 /// the ctor.
241 void addEdge(const SUnit *SU, const SwingSchedulerDDGEdge &Edge);
242
243 SwingSchedulerDDGEdges &getEdges(const SUnit *SU);
244 const SwingSchedulerDDGEdges &getEdges(const SUnit *SU) const;
245
246public:
247 LLVM_ABI SwingSchedulerDDG(std::vector<SUnit> &SUnits, SUnit *EntrySU,
248 SUnit *ExitSU, const LoopCarriedEdges &LCE);
249
250 LLVM_ABI const EdgesType &getInEdges(const SUnit *SU) const;
251
252 LLVM_ABI const EdgesType &getOutEdges(const SUnit *SU) const;
253
255
256 LLVM_ABI bool isValidSchedule(const SMSchedule &Schedule) const;
257};
258
259/// This class builds the dependence graph for the instructions in a loop,
260/// and attempts to schedule the instructions using the SMS algorithm.
263
264 std::unique_ptr<SwingSchedulerDDG> DDG;
265
266 /// The minimum initiation interval between iterations for this schedule.
267 unsigned MII = 0;
268 /// The maximum initiation interval between iterations for this schedule.
269 unsigned MAX_II = 0;
270 /// Set to true if a valid pipelined schedule is found for the loop.
271 bool Scheduled = false;
272 MachineLoop &Loop;
273 LiveIntervals &LIS;
274 const RegisterClassInfo &RegClassInfo;
275 unsigned II_setByPragma = 0;
276 TargetInstrInfo::PipelinerLoopInfo *LoopPipelinerInfo = nullptr;
277
278 /// Policy for this loop, after target and command line overrides.
280
281 /// A topological ordering of the SUnits, which is needed for changing
282 /// dependences and iterating over the SUnits.
284
285 struct NodeInfo {
286 int ASAP = 0;
287 int ALAP = 0;
288 int ZeroLatencyDepth = 0;
289 int ZeroLatencyHeight = 0;
290
291 NodeInfo() = default;
292 };
293 /// Computed properties for each node in the graph.
294 std::vector<NodeInfo> ScheduleInfo;
295
296 enum OrderKind { BottomUp = 0, TopDown = 1 };
297 /// Computed node ordering for scheduling.
298 SetVector<SUnit *> NodeOrder;
299
300 using NodeSetType = SmallVector<NodeSet, 8>;
301 using ValueMapTy = DenseMap<unsigned, unsigned>;
302 using MBBVectorTy = SmallVectorImpl<MachineBasicBlock *>;
304
305 /// Instructions to change when emitting the final schedule.
307
308 /// We may create a new instruction, so remember it because it
309 /// must be deleted when the pass is finished.
311
312 /// Ordered list of DAG postprocessing steps.
313 std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
314
315 /// Used to compute single-iteration dependencies (i.e., buildSchedGraph).
316 AliasAnalysis *AA;
317
318 /// Used to compute loop-carried dependencies (i.e.,
319 /// addLoopCarriedDependences).
320 BatchAAResults BAA;
321
322 /// Helper class to implement Johnson's circuit finding algorithm.
323 class Circuits {
324 std::vector<SUnit> &SUnits;
325 SetVector<SUnit *> Stack;
326 BitVector Blocked;
329 // Node to Index from ScheduleDAGTopologicalSort
330 std::vector<int> *Node2Idx;
331 unsigned NumPaths = 0u;
332 static unsigned MaxPaths;
333
334 public:
335 Circuits(std::vector<SUnit> &SUs, ScheduleDAGTopologicalSort &Topo)
336 : SUnits(SUs), Blocked(SUs.size()), B(SUs.size()), AdjK(SUs.size()) {
337 Node2Idx = new std::vector<int>(SUs.size());
338 unsigned Idx = 0;
339 for (const auto &NodeNum : Topo)
340 Node2Idx->at(NodeNum) = Idx++;
341 }
342 Circuits &operator=(const Circuits &other) = delete;
343 Circuits(const Circuits &other) = delete;
344 ~Circuits() { delete Node2Idx; }
345
346 /// Reset the data structures used in the circuit algorithm.
347 void reset() {
348 Stack.clear();
349 Blocked.reset();
350 B.assign(SUnits.size(), SmallPtrSet<SUnit *, 4>());
351 NumPaths = 0;
352 }
353
354 LLVM_ABI void createAdjacencyStructure(SwingSchedulerDDG *DDG);
355 LLVM_ABI bool circuit(int V, int S, NodeSetType &NodeSets,
356 const SwingSchedulerDAG *DAG,
357 bool HasBackedge = false);
358 LLVM_ABI void unblock(int U);
359 };
360
361 struct LLVM_ABI CopyToPhiMutation : public ScheduleDAGMutation {
362 void apply(ScheduleDAGInstrs *DAG) override;
363 };
364
365public:
368 LiveIntervals &lis, const RegisterClassInfo &rci,
370 AliasAnalysis *AA)
371 : ScheduleDAGInstrs(MF, MLI, false), ORE(ORE), Loop(L), LIS(lis),
372 RegClassInfo(rci), II_setByPragma(II), LoopPipelinerInfo(PLI),
373 Topo(SUnits, &ExitSU), AA(AA), BAA(*AA) {
374 initPolicy();
375 MF.getSubtarget().getSMSMutations(Mutations);
377 Mutations.push_back(std::make_unique<CopyToPhiMutation>());
378 BAA.enableCrossIterationMode();
379 }
380
381 void schedule() override;
382 void finishBlock() override;
383
384 /// Return true if the loop kernel has been scheduled.
385 bool hasNewSchedule() { return Scheduled; }
386
387 /// Return the earliest time an instruction may be scheduled.
388 int getASAP(SUnit *Node) { return ScheduleInfo[Node->NodeNum].ASAP; }
389
390 /// Return the latest time an instruction my be scheduled.
391 int getALAP(SUnit *Node) { return ScheduleInfo[Node->NodeNum].ALAP; }
392
393 /// The mobility function, which the number of slots in which
394 /// an instruction may be scheduled.
395 int getMOV(SUnit *Node) { return getALAP(Node) - getASAP(Node); }
396
397 /// The depth, in the dependence graph, for a node.
398 unsigned getDepth(SUnit *Node) { return Node->getDepth(); }
399
400 /// The maximum unweighted length of a path from an arbitrary node to the
401 /// given node in which each edge has latency 0
403 return ScheduleInfo[Node->NodeNum].ZeroLatencyDepth;
404 }
405
406 /// The height, in the dependence graph, for a node.
407 unsigned getHeight(SUnit *Node) { return Node->getHeight(); }
408
409 /// The maximum unweighted length of a path from the given node to an
410 /// arbitrary node in which each edge has latency 0
412 return ScheduleInfo[Node->NodeNum].ZeroLatencyHeight;
413 }
414
415 void applyInstrChange(MachineInstr *MI, SMSchedule &Schedule);
416
417 void fixupRegisterOverlaps(std::deque<SUnit *> &Instrs);
418
419 /// Return the new base register that was stored away for the changed
420 /// instruction.
423 InstrChanges.find(SU);
424 if (It != InstrChanges.end())
425 return It->second.first;
426 return Register();
427 }
428
429 void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation) {
430 Mutations.push_back(std::move(Mutation));
431 }
432
433 static bool classof(const ScheduleDAGInstrs *DAG) { return true; }
434
435 const SwingSchedulerDDG *getDDG() const { return DDG.get(); }
436
437 bool mayOverlapInLaterIter(const MachineInstr *BaseMI,
438 const MachineInstr *OtherMI) const;
439
440private:
441 /// Set the policy for this loop, allowing the target to override it.
442 void initPolicy();
443 LoopCarriedEdges addLoopCarriedDependences();
444 void updatePhiDependences();
445 void changeDependences();
446 unsigned calculateResMII();
447 unsigned calculateRecMII(NodeSetType &RecNodeSets);
448 void findCircuits(NodeSetType &NodeSets);
449 void fuseRecs(NodeSetType &NodeSets);
450 void removeDuplicateNodes(NodeSetType &NodeSets);
451 void computeNodeFunctions(NodeSetType &NodeSets);
452 void registerPressureFilter(NodeSetType &NodeSets);
453 void colocateNodeSets(NodeSetType &NodeSets);
454 void checkNodeSets(NodeSetType &NodeSets);
455 void groupRemainingNodes(NodeSetType &NodeSets);
456 void addConnectedNodes(SUnit *SU, NodeSet &NewSet,
457 SetVector<SUnit *> &NodesAdded);
458 void computeNodeOrder(NodeSetType &NodeSets);
459 void checkValidNodeOrder(const NodeSetType &Circuits) const;
460 bool schedulePipeline(SMSchedule &Schedule);
461 bool computeDelta(const MachineInstr &MI, int &Delta) const;
462 MachineInstr *findDefInLoop(Register Reg);
463 bool canUseLastOffsetValue(MachineInstr *MI, unsigned &BasePos,
464 unsigned &OffsetPos, Register &NewBase,
465 int64_t &NewOffset);
466 void postProcessDAG();
467 /// Set the Minimum Initiation Interval for this schedule attempt.
468 void setMII(unsigned ResMII, unsigned RecMII);
469 /// Set the Maximum Initiation Interval for this schedule attempt.
470 void setMAX_II();
471};
472
473/// A NodeSet contains a set of SUnit DAG nodes with additional information
474/// that assigns a priority to the set.
475class NodeSet {
476 SetVector<SUnit *> Nodes;
477 bool HasRecurrence = false;
478 unsigned RecMII = 0;
479 int MaxMOV = 0;
480 unsigned MaxDepth = 0;
481 unsigned Colocate = 0;
482 SUnit *ExceedPressure = nullptr;
483 unsigned Latency = 0;
484
485public:
487
488 NodeSet() = default;
490 : Nodes(S, E), HasRecurrence(true) {
491 // Calculate the latency of this node set.
492 // Example to demonstrate the calculation:
493 // Given: N0 -> N1 -> N2 -> N0
494 // Edges:
495 // (N0 -> N1, 3)
496 // (N0 -> N1, 5)
497 // (N1 -> N2, 2)
498 // (N2 -> N0, 1)
499 // The total latency which is a lower bound of the recurrence MII is the
500 // longest path from N0 back to N0 given only the edges of this node set.
501 // In this example, the latency is: 5 + 2 + 1 = 8.
502 //
503 // Hold a map from each SUnit in the circle to the maximum distance from the
504 // source node by only considering the nodes.
505 const SwingSchedulerDDG *DDG = DAG->getDDG();
506 DenseMap<SUnit *, unsigned> SUnitToDistance;
507 for (auto *Node : Nodes)
508 SUnitToDistance[Node] = 0;
509
510 for (unsigned I = 1, E = Nodes.size(); I <= E; ++I) {
511 SUnit *U = Nodes[I - 1];
512 SUnit *V = Nodes[I % Nodes.size()];
513 for (const SwingSchedulerDDGEdge &Succ : DDG->getOutEdges(U)) {
514 SUnit *SuccSUnit = Succ.getDst();
515 if (V != SuccSUnit)
516 continue;
517 unsigned &DU = SUnitToDistance[U];
518 unsigned &DV = SUnitToDistance[V];
519 if (DU + Succ.getLatency() > DV)
520 DV = DU + Succ.getLatency();
521 }
522 }
523 // Handle a back-edge in loop carried dependencies
524 SUnit *FirstNode = Nodes[0];
525 SUnit *LastNode = Nodes[Nodes.size() - 1];
526
527 for (SUnit *SU : DDG->getExtraOutEdges(LastNode)) {
528 // If we have an order dep that is potentially loop carried then a
529 // back-edge exists between the last node and the first node in extra
530 // edges. Handle it manually by adding 1 to the distance of the last node.
531 if (SU != FirstNode)
532 continue;
533 unsigned &First = SUnitToDistance[FirstNode];
534 unsigned Last = SUnitToDistance[LastNode];
535 First = std::max(First, Last + 1);
536 }
537
538 // The latency is the distance from the source node to itself.
539 Latency = SUnitToDistance[Nodes.front()];
540 }
541
542 bool insert(SUnit *SU) { return Nodes.insert(SU); }
543
544 void insert(iterator S, iterator E) { Nodes.insert(S, E); }
545
546 template <typename UnaryPredicate> bool remove_if(UnaryPredicate P) {
547 return Nodes.remove_if(P);
548 }
549
550 unsigned count(SUnit *SU) const { return Nodes.count(SU); }
551
552 bool hasRecurrence() { return HasRecurrence; };
553
554 unsigned size() const { return Nodes.size(); }
555
556 bool empty() const { return Nodes.empty(); }
557
558 SUnit *getNode(unsigned i) const { return Nodes[i]; };
559
560 void setRecMII(unsigned mii) { RecMII = mii; };
561
562 void setColocate(unsigned c) { Colocate = c; };
563
564 void setExceedPressure(SUnit *SU) { ExceedPressure = SU; }
565
566 bool isExceedSU(SUnit *SU) { return ExceedPressure == SU; }
567
568 int compareRecMII(NodeSet &RHS) { return RecMII - RHS.RecMII; }
569
570 int getRecMII() { return RecMII; }
571
572 /// Summarize node functions for the entire node set.
574 for (SUnit *SU : *this) {
575 MaxMOV = std::max(MaxMOV, SSD->getMOV(SU));
576 MaxDepth = std::max(MaxDepth, SSD->getDepth(SU));
577 }
578 }
579
580 unsigned getLatency() { return Latency; }
581
582 unsigned getMaxDepth() { return MaxDepth; }
583
584 void clear() {
585 Nodes.clear();
586 RecMII = 0;
587 HasRecurrence = false;
588 MaxMOV = 0;
589 MaxDepth = 0;
590 Colocate = 0;
591 ExceedPressure = nullptr;
592 }
593
594 operator SetVector<SUnit *> &() { return Nodes; }
595
596 /// Sort the node sets by importance. First, rank them by recurrence MII,
597 /// then by mobility (least mobile done first), and finally by depth.
598 /// Each node set may contain a colocate value which is used as the first
599 /// tie breaker, if it's set.
600 bool operator>(const NodeSet &RHS) const {
601 if (RecMII == RHS.RecMII) {
602 if (Colocate != 0 && RHS.Colocate != 0 && Colocate != RHS.Colocate)
603 return Colocate < RHS.Colocate;
604 if (MaxMOV == RHS.MaxMOV)
605 return MaxDepth > RHS.MaxDepth;
606 return MaxMOV < RHS.MaxMOV;
607 }
608 return RecMII > RHS.RecMII;
609 }
610
611 bool operator==(const NodeSet &RHS) const {
612 return RecMII == RHS.RecMII && MaxMOV == RHS.MaxMOV &&
613 MaxDepth == RHS.MaxDepth;
614 }
615
616 bool operator!=(const NodeSet &RHS) const { return !operator==(RHS); }
617
618 iterator begin() { return Nodes.begin(); }
619 iterator end() { return Nodes.end(); }
620 LLVM_ABI void print(raw_ostream &os) const;
621
622#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
623 LLVM_DUMP_METHOD void dump() const;
624#endif
625};
626
627// 16 was selected based on the number of ProcResource kinds for all
628// existing Subtargets, so that SmallVector don't need to resize too often.
629static const int DefaultProcResSize = 16;
630
632private:
633 const MCSubtargetInfo *STI;
634 const MCSchedModel &SM;
635 const TargetSubtargetInfo *ST;
636 const TargetInstrInfo *TII;
638 const bool UseDFA;
639 /// DFA resources for each slot
641 /// Modulo Reservation Table. When a resource with ID R is consumed in cycle
642 /// C, it is counted in MRT[C mod II][R]. (Used when UseDFA == F)
644 /// The number of scheduled micro operations for each slot. Micro operations
645 /// are assumed to be scheduled one per cycle, starting with the cycle in
646 /// which the instruction is scheduled.
647 llvm::SmallVector<int> NumScheduledMops;
648 /// Each processor resource is associated with a so-called processor resource
649 /// mask. This vector allows to correlate processor resource IDs with
650 /// processor resource masks. There is exactly one element per each processor
651 /// resource declared by the scheduling model.
653 int InitiationInterval = 0;
654 /// The number of micro operations that can be scheduled at a cycle.
655 int IssueWidth;
656
657 int calculateResMIIDFA() const;
658 /// Check if MRT is overbooked
659 bool isOverbooked() const;
660 /// Reserve resources on MRT
661 void reserveResources(const MCSchedClassDesc *SCDesc, int Cycle);
662 /// Unreserve resources on MRT
663 void unreserveResources(const MCSchedClassDesc *SCDesc, int Cycle);
664
665 /// Return M satisfying Dividend = Divisor * X + M, 0 < M < Divisor.
666 /// The slot on MRT to reserve a resource for the cycle C is positiveModulo(C,
667 /// II).
668 int positiveModulo(int Dividend, int Divisor) const {
669 assert(Divisor > 0);
670 int R = Dividend % Divisor;
671 if (R < 0)
672 R += Divisor;
673 return R;
674 }
675
676#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
677 LLVM_DUMP_METHOD void dumpMRT() const;
678#endif
679
680public:
682 : STI(ST), SM(ST->getSchedModel()), ST(ST), TII(ST->getInstrInfo()),
683 DAG(DAG), UseDFA(ST->useDFAforSMS()),
684 ProcResourceMasks(SM.getNumProcResourceKinds(), 0),
685 IssueWidth(SM.IssueWidth) {
686 initProcResourceVectors(SM, ProcResourceMasks);
687 if (IssueWidth <= 0)
688 // If IssueWidth is not specified, set a sufficiently large value
689 IssueWidth = 100;
690 if (SwpForceIssueWidth > 0)
691 IssueWidth = SwpForceIssueWidth;
692 }
693
694 LLVM_ABI void initProcResourceVectors(const MCSchedModel &SM,
696
697 /// Check if the resources occupied by a machine instruction are available
698 /// in the current state.
699 LLVM_ABI bool canReserveResources(SUnit &SU, int Cycle);
700
701 /// Reserve the resources occupied by a machine instruction and change the
702 /// current state to reflect that change.
703 LLVM_ABI void reserveResources(SUnit &SU, int Cycle);
704
705 LLVM_ABI int calculateResMII() const;
706
707 /// Initialize resources with the initiation interval II.
708 LLVM_ABI void init(int II);
709};
710
711/// This class represents the scheduled code. The main data structure is a
712/// map from scheduled cycle to instructions. During scheduling, the
713/// data structure explicitly represents all stages/iterations. When
714/// the algorithm finshes, the schedule is collapsed into a single stage,
715/// which represents instructions from different loop iterations.
716///
717/// The SMS algorithm allows negative values for cycles, so the first cycle
718/// in the schedule is the smallest cycle value.
720private:
721 /// Map from execution cycle to instructions.
722 DenseMap<int, std::deque<SUnit *>> ScheduledInstrs;
723
724 /// Map from instruction to execution cycle.
725 std::map<SUnit *, int> InstrToCycle;
726
727 /// Keep track of the first cycle value in the schedule. It starts
728 /// as zero, but the algorithm allows negative values.
729 int FirstCycle = 0;
730
731 /// Keep track of the last cycle value in the schedule.
732 int LastCycle = 0;
733
734 /// The initiation interval (II) for the schedule.
735 int InitiationInterval = 0;
736
737 /// Target machine information.
738 const TargetSubtargetInfo &ST;
739
740 /// Virtual register information.
742
743 ResourceManager ProcItinResources;
744
745public:
747 : ST(mf->getSubtarget()), MRI(mf->getRegInfo()),
748 ProcItinResources(&ST, DAG) {}
749
750 void reset() {
751 ScheduledInstrs.clear();
752 InstrToCycle.clear();
753 FirstCycle = 0;
754 LastCycle = 0;
755 InitiationInterval = 0;
756 }
757
758 /// Set the initiation interval for this schedule.
760 InitiationInterval = ii;
761 ProcItinResources.init(ii);
762 }
763
764 /// Return the initiation interval for this schedule.
765 int getInitiationInterval() const { return InitiationInterval; }
766
767 /// Return the first cycle in the completed schedule. This
768 /// can be a negative value.
769 int getFirstCycle() const { return FirstCycle; }
770
771 /// Return the last cycle in the finalized schedule.
772 int getFinalCycle() const { return FirstCycle + InitiationInterval - 1; }
773
774 LLVM_ABI void computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart,
775 int II, SwingSchedulerDAG *DAG);
776 LLVM_ABI bool insert(SUnit *SU, int StartCycle, int EndCycle, int II);
777
778 /// Iterators for the cycle to instruction map.
782
783 /// Return true if the instruction is scheduled at the specified stage.
784 bool isScheduledAtStage(SUnit *SU, unsigned StageNum) {
785 return (stageScheduled(SU) == (int)StageNum);
786 }
787
788 /// Return the stage for a scheduled instruction. Return -1 if
789 /// the instruction has not been scheduled.
790 int stageScheduled(SUnit *SU) const {
791 std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
792 if (it == InstrToCycle.end())
793 return -1;
794 return (it->second - FirstCycle) / InitiationInterval;
795 }
796
797 /// Return the cycle for a scheduled instruction. This function normalizes
798 /// the first cycle to be 0.
799 unsigned cycleScheduled(SUnit *SU) const {
800 std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
801 assert(it != InstrToCycle.end() && "Instruction hasn't been scheduled.");
802 return (it->second - FirstCycle) % InitiationInterval;
803 }
804
805 /// Return the maximum stage count needed for this schedule.
806 unsigned getMaxStageCount() {
807 return (LastCycle - FirstCycle) / InitiationInterval;
808 }
809
810 /// Return the instructions that are scheduled at the specified cycle.
811 std::deque<SUnit *> &getInstructions(int cycle) {
812 return ScheduledInstrs[cycle];
813 }
814
816 computeUnpipelineableNodes(SwingSchedulerDAG *SSD,
818
819 LLVM_ABI std::deque<SUnit *>
820 reorderInstructions(const SwingSchedulerDAG *SSD,
821 const std::deque<SUnit *> &Instrs) const;
822
823 LLVM_ABI bool
824 normalizeNonPipelinedInstructions(SwingSchedulerDAG *SSD,
826 LLVM_ABI bool isValidSchedule(SwingSchedulerDAG *SSD);
827 LLVM_ABI void finalizeSchedule(SwingSchedulerDAG *SSD);
828 LLVM_ABI void orderDependence(const SwingSchedulerDAG *SSD, SUnit *SU,
829 std::deque<SUnit *> &Insts) const;
830 LLVM_ABI bool isLoopCarried(const SwingSchedulerDAG *SSD,
831 MachineInstr &Phi) const;
832 LLVM_ABI bool isLoopCarriedDefOfUse(const SwingSchedulerDAG *SSD,
833 MachineInstr *Def,
834 MachineOperand &MO) const;
835
836 LLVM_ABI bool
837 onlyHasLoopCarriedOutputOrOrderPreds(SUnit *SU,
838 const SwingSchedulerDDG *DDG) const;
839 LLVM_ABI void print(raw_ostream &os) const;
840 LLVM_ABI void dump() const;
841};
842
843} // end namespace llvm
844
845#endif // LLVM_CODEGEN_MACHINEPIPELINER_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:686
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*-—===//
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
uint64_t IntrinsicInst * II
#define P(N)
PowerPC VSX FMA Mutation
This file contains some templates that are useful if you are working with the STL at all.
This file implements a set that has insertion order iteration characteristics.
Value * RHS
Represent the analysis usage information of a pass.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
BitVector & reset()
Reset all bits in the bitvector.
Definition BitVector.h:409
iterator end()
Definition DenseMap.h:702
Generic base class for all target subtargets.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
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
bool isExceedSU(SUnit *SU)
void insert(iterator S, iterator E)
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()
NodeSet(iterator S, iterator E, const SwingSchedulerDAG *DAG)
bool operator>(const NodeSet &RHS) const
Sort the node sets by importance.
int compareRecMII(NodeSet &RHS)
unsigned size() const
bool operator!=(const NodeSet &RHS) const
bool insert(SUnit *SU)
bool operator==(const NodeSet &RHS) const
bool remove_if(UnaryPredicate P)
bool empty() const
void setExceedPressure(SUnit *SU)
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
Wrapper class representing virtual and physical registers.
Definition Register.h:20
LLVM_ABI void initProcResourceVectors(const MCSchedModel &SM, SmallVectorImpl< uint64_t > &Masks)
ResourceManager(const TargetSubtargetInfo *ST, ScheduleDAGInstrs *DAG)
Scheduling dependency.
Definition ScheduleDAG.h:53
SUnit * getSUnit() const
@ Output
A register output-dependence (aka WAW).
Definition ScheduleDAG.h:59
@ Order
Any other ordering dependency.
Definition ScheduleDAG.h:60
@ Anti
A register anti-dependence (aka WAR).
Definition ScheduleDAG.h:58
This class represents the scheduled code.
void setInitiationInterval(int ii)
Set the initiation interval for this schedule.
unsigned getMaxStageCount()
Return the maximum stage count needed for this schedule.
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.
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.
DenseMap< int, std::deque< SUnit * > >::const_iterator const_sched_iterator
DenseMap< int, std::deque< SUnit * > >::iterator sched_iterator
Iterators for the cycle to instruction map.
unsigned cycleScheduled(SUnit *SU) const
Return the cycle for a scheduled instruction.
SMSchedule(MachineFunction *mf, SwingSchedulerDAG *DAG)
int getFinalCycle() const
Return the last cycle in the finalized schedule.
Scheduling unit. This is a node in the scheduling DAG.
A ScheduleDAG for scheduling lists of MachineInstr.
ScheduleDAGInstrs(MachineFunction &mf, const MachineLoopInfo *mli, bool RemoveKillFlags=false)
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...
std::vector< SUnit > SUnits
The scheduling units.
MachineFunction & MF
Machine function.
ScheduleDAG & operator=(const ScheduleDAG &)=delete
SUnit ExitSU
Special node for the region exit.
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
const value_type & front() const
Return the first element of the SetVector.
Definition SetVector.h:138
typename vector_type::const_iterator const_iterator
Definition SetVector.h:73
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:345
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
int getASAP(SUnit *Node)
Return the earliest time an instruction may be scheduled.
const SwingSchedulerDDG * getDDG() const
bool hasNewSchedule()
Return true if the loop kernel has been scheduled.
void addMutation(std::unique_ptr< ScheduleDAGMutation > Mutation)
int getZeroLatencyDepth(SUnit *Node)
The maximum unweighted length of a path from an arbitrary node to the given node in which each edge h...
SwingSchedulerDAG(MachineFunction &MF, const MachineLoopInfo *MLI, MachineOptimizationRemarkEmitter *ORE, MachineLoop &L, LiveIntervals &lis, const RegisterClassInfo &rci, unsigned II, TargetInstrInfo::PipelinerLoopInfo *PLI, AliasAnalysis *AA)
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...
Register getInstrBaseReg(SUnit *SU) const
Return the new base register that was stored away for the changed instruction.
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.
Represents a dependence between two instruction.
SUnit * getDst() const
Returns the SUnit to which the edge points (destination node).
Register getReg() const
Returns the register associated with the edge.
void setDistance(unsigned D)
Sets the distance value for the edge.
bool isBarrier() const
Returns true if the edge represents unknown scheduling barrier.
void setLatency(unsigned Latency)
Sets the latency for the edge.
SwingSchedulerDDGEdge(SUnit *PredOrSucc, const SDep &Dep, bool IsSucc, bool IsValidationOnly)
Creates an edge corresponding to an edge represented by PredOrSucc and Dep in the original DAG.
bool isAntiDep() const
Returns true if the edge represents anti dependence.
bool isAssignedRegDep() const
Tests if this is a Data dependence that is associated with a register.
bool isArtificial() const
Returns true if the edge represents an artificial dependence.
LLVM_ABI bool ignoreDependence(bool IgnoreAnti) const
Returns true for DDG nodes that we ignore when computing the cost functions.
bool isOrderDep() const
Returns true if the edge represents a dependence that is not data, anti or output dependence.
unsigned getLatency() const
Returns the latency value for the edge.
SUnit * getSrc() const
Returns the SUnit from which the edge comes (source node).
bool isValidationOnly() const
Returns true if this edge is intended to be used only for validating the schedule.
unsigned getDistance() const
Returns the distance value for the edge.
bool isOutputDep() const
Returns true if the edge represents output dependence.
This class provides APIs to retrieve edges from/to an SUnit node, with a particular focus on loop-car...
LLVM_ABI SwingSchedulerDDG(std::vector< SUnit > &SUnits, SUnit *EntrySU, SUnit *ExitSU, const LoopCarriedEdges &LCE)
LLVM_ABI ArrayRef< SUnit * > getExtraOutEdges(const SUnit *SU) const
LLVM_ABI const EdgesType & getInEdges(const SUnit *SU) const
LLVM_ABI bool isValidSchedule(const SMSchedule &Schedule) const
Check if Schedule doesn't violate the validation-only dependencies.
LLVM_ABI const EdgesType & getOutEdges(const SUnit *SU) const
Object returned by analyzeLoopForPipelining.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
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:53
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
static int64_t computeDelta(SectionEntry *A, SectionEntry *B)
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI cl::opt< bool > SwpEnableCopyToPhi
LLVM_ABI cl::opt< int > SwpForceIssueWidth
A command line argument to force pipeliner to use specified issue width.
static const int DefaultProcResSize
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
Represents loop-carried dependencies.
SmallSetVector< SUnit *, 8 > OrderDep
const OrderDep * getOrderDepOrNull(SUnit *Key) const
LLVM_ABI void modifySUnits(std::vector< SUnit > &SUnits, const TargetInstrInfo *TII)
Adds some edges to the original DAG that correspond to loop-carried dependencies.
LLVM_ABI void dump(SUnit *SU, const TargetRegisterInfo *TRI, const MachineRegisterInfo *MRI) const
DenseMap< SUnit *, OrderDep > OrderDepsType
Summarize the scheduling resources required for an instruction of a particular scheduling class.
Definition MCSchedule.h:129
Machine model for scheduling, bundling, and heuristics.
Definition MCSchedule.h:273
Software pipelining policy for a loop, which a target can customize by implementing TargetSubtargetIn...
bool ShouldLimitRegPressure
Limit the register pressure of the scheduled loop, retrying at a higher II when a schedule needs too ...
A CRTP mix-in for passes that can be skipped.