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