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_LIB_CODEGEN_MACHINEPIPELINER_H
41 #define LLVM_LIB_CODEGEN_MACHINEPIPELINER_H
42 
43 #include "llvm/Analysis/AliasAnalysis.h"
44 
45 #include "llvm/CodeGen/MachineDominators.h"
46 #include "llvm/CodeGen/RegisterClassInfo.h"
47 #include "llvm/CodeGen/ScheduleDAGInstrs.h"
48 #include "llvm/CodeGen/TargetInstrInfo.h"
49 #include "llvm/InitializePasses.h"
50 
51 namespace llvm {
52 
53 class NodeSet;
54 class SMSchedule;
55 
56 extern cl::opt<bool> SwpEnableCopyToPhi;
57 
58 /// The main class in the implementation of the target independent
59 /// software pipeliner pass.
60 class MachinePipeliner : public MachineFunctionPass {
61 public:
62   MachineFunction *MF = nullptr;
63   const MachineLoopInfo *MLI = nullptr;
64   const MachineDominatorTree *MDT = nullptr;
65   const InstrItineraryData *InstrItins;
66   const TargetInstrInfo *TII = nullptr;
67   RegisterClassInfo RegClassInfo;
68   bool disabledByPragma = false;
69   unsigned II_setByPragma = 0;
70 
71 #ifndef NDEBUG
72   static int NumTries;
73 #endif
74 
75   /// Cache the target analysis information about the loop.
76   struct LoopInfo {
77     MachineBasicBlock *TBB = nullptr;
78     MachineBasicBlock *FBB = nullptr;
79     SmallVector<MachineOperand, 4> BrCond;
80     MachineInstr *LoopInductionVar = nullptr;
81     MachineInstr *LoopCompare = nullptr;
82   };
83   LoopInfo LI;
84 
85   static char ID;
86 
87   MachinePipeliner() : MachineFunctionPass(ID) {
88     initializeMachinePipelinerPass(*PassRegistry::getPassRegistry());
89   }
90 
91   bool runOnMachineFunction(MachineFunction &MF) override;
92 
93   void getAnalysisUsage(AnalysisUsage &AU) const override {
94     AU.addRequired<AAResultsWrapperPass>();
95     AU.addPreserved<AAResultsWrapperPass>();
96     AU.addRequired<MachineLoopInfo>();
97     AU.addRequired<MachineDominatorTree>();
98     AU.addRequired<LiveIntervals>();
99     MachineFunctionPass::getAnalysisUsage(AU);
100   }
101 
102 private:
103   void preprocessPhiNodes(MachineBasicBlock &B);
104   bool canPipelineLoop(MachineLoop &L);
105   bool scheduleLoop(MachineLoop &L);
106   bool swingModuloScheduler(MachineLoop &L);
107   void setPragmaPipelineOptions(MachineLoop &L);
108 };
109 
110 /// This class builds the dependence graph for the instructions in a loop,
111 /// and attempts to schedule the instructions using the SMS algorithm.
112 class SwingSchedulerDAG : public ScheduleDAGInstrs {
113   MachinePipeliner &Pass;
114   /// The minimum initiation interval between iterations for this schedule.
115   unsigned MII = 0;
116   /// The maximum initiation interval between iterations for this schedule.
117   unsigned MAX_II = 0;
118   /// Set to true if a valid pipelined schedule is found for the loop.
119   bool Scheduled = false;
120   MachineLoop &Loop;
121   LiveIntervals &LIS;
122   const RegisterClassInfo &RegClassInfo;
123   unsigned II_setByPragma = 0;
124 
125   /// A toplogical ordering of the SUnits, which is needed for changing
126   /// dependences and iterating over the SUnits.
127   ScheduleDAGTopologicalSort Topo;
128 
129   struct NodeInfo {
130     int ASAP = 0;
131     int ALAP = 0;
132     int ZeroLatencyDepth = 0;
133     int ZeroLatencyHeight = 0;
134 
135     NodeInfo() = default;
136   };
137   /// Computed properties for each node in the graph.
138   std::vector<NodeInfo> ScheduleInfo;
139 
140   enum OrderKind { BottomUp = 0, TopDown = 1 };
141   /// Computed node ordering for scheduling.
142   SetVector<SUnit *> NodeOrder;
143 
144   using NodeSetType = SmallVector<NodeSet, 8>;
145   using ValueMapTy = DenseMap<unsigned, unsigned>;
146   using MBBVectorTy = SmallVectorImpl<MachineBasicBlock *>;
147   using InstrMapTy = DenseMap<MachineInstr *, MachineInstr *>;
148 
149   /// Instructions to change when emitting the final schedule.
150   DenseMap<SUnit *, std::pair<unsigned, int64_t>> InstrChanges;
151 
152   /// We may create a new instruction, so remember it because it
153   /// must be deleted when the pass is finished.
154   DenseMap<MachineInstr*, MachineInstr *> NewMIs;
155 
156   /// Ordered list of DAG postprocessing steps.
157   std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
158 
159   /// Helper class to implement Johnson's circuit finding algorithm.
160   class Circuits {
161     std::vector<SUnit> &SUnits;
162     SetVector<SUnit *> Stack;
163     BitVector Blocked;
164     SmallVector<SmallPtrSet<SUnit *, 4>, 10> B;
165     SmallVector<SmallVector<int, 4>, 16> AdjK;
166     // Node to Index from ScheduleDAGTopologicalSort
167     std::vector<int> *Node2Idx;
168     unsigned NumPaths;
169     static unsigned MaxPaths;
170 
171   public:
172     Circuits(std::vector<SUnit> &SUs, ScheduleDAGTopologicalSort &Topo)
173         : SUnits(SUs), Blocked(SUs.size()), B(SUs.size()), AdjK(SUs.size()) {
174       Node2Idx = new std::vector<int>(SUs.size());
175       unsigned Idx = 0;
176       for (const auto &NodeNum : Topo)
177         Node2Idx->at(NodeNum) = Idx++;
178     }
179 
180     ~Circuits() { delete Node2Idx; }
181 
182     /// Reset the data structures used in the circuit algorithm.
183     void reset() {
184       Stack.clear();
185       Blocked.reset();
186       B.assign(SUnits.size(), SmallPtrSet<SUnit *, 4>());
187       NumPaths = 0;
188     }
189 
190     void createAdjacencyStructure(SwingSchedulerDAG *DAG);
191     bool circuit(int V, int S, NodeSetType &NodeSets, bool HasBackedge = false);
192     void unblock(int U);
193   };
194 
195   struct CopyToPhiMutation : public ScheduleDAGMutation {
196     void apply(ScheduleDAGInstrs *DAG) override;
197   };
198 
199 public:
200   SwingSchedulerDAG(MachinePipeliner &P, MachineLoop &L, LiveIntervals &lis,
201                     const RegisterClassInfo &rci, unsigned II)
202       : ScheduleDAGInstrs(*P.MF, P.MLI, false), Pass(P), Loop(L), LIS(lis),
203         RegClassInfo(rci), II_setByPragma(II), Topo(SUnits, &ExitSU) {
204     P.MF->getSubtarget().getSMSMutations(Mutations);
205     if (SwpEnableCopyToPhi)
206       Mutations.push_back(std::make_unique<CopyToPhiMutation>());
207   }
208 
209   void schedule() override;
210   void finishBlock() override;
211 
212   /// Return true if the loop kernel has been scheduled.
213   bool hasNewSchedule() { return Scheduled; }
214 
215   /// Return the earliest time an instruction may be scheduled.
216   int getASAP(SUnit *Node) { return ScheduleInfo[Node->NodeNum].ASAP; }
217 
218   /// Return the latest time an instruction my be scheduled.
219   int getALAP(SUnit *Node) { return ScheduleInfo[Node->NodeNum].ALAP; }
220 
221   /// The mobility function, which the number of slots in which
222   /// an instruction may be scheduled.
223   int getMOV(SUnit *Node) { return getALAP(Node) - getASAP(Node); }
224 
225   /// The depth, in the dependence graph, for a node.
226   unsigned getDepth(SUnit *Node) { return Node->getDepth(); }
227 
228   /// The maximum unweighted length of a path from an arbitrary node to the
229   /// given node in which each edge has latency 0
230   int getZeroLatencyDepth(SUnit *Node) {
231     return ScheduleInfo[Node->NodeNum].ZeroLatencyDepth;
232   }
233 
234   /// The height, in the dependence graph, for a node.
235   unsigned getHeight(SUnit *Node) { return Node->getHeight(); }
236 
237   /// The maximum unweighted length of a path from the given node to an
238   /// arbitrary node in which each edge has latency 0
239   int getZeroLatencyHeight(SUnit *Node) {
240     return ScheduleInfo[Node->NodeNum].ZeroLatencyHeight;
241   }
242 
243   /// Return true if the dependence is a back-edge in the data dependence graph.
244   /// Since the DAG doesn't contain cycles, we represent a cycle in the graph
245   /// using an anti dependence from a Phi to an instruction.
246   bool isBackedge(SUnit *Source, const SDep &Dep) {
247     if (Dep.getKind() != SDep::Anti)
248       return false;
249     return Source->getInstr()->isPHI() || Dep.getSUnit()->getInstr()->isPHI();
250   }
251 
252   bool isLoopCarriedDep(SUnit *Source, const SDep &Dep, bool isSucc = true);
253 
254   /// The distance function, which indicates that operation V of iteration I
255   /// depends on operations U of iteration I-distance.
256   unsigned getDistance(SUnit *U, SUnit *V, const SDep &Dep) {
257     // Instructions that feed a Phi have a distance of 1. Computing larger
258     // values for arrays requires data dependence information.
259     if (V->getInstr()->isPHI() && Dep.getKind() == SDep::Anti)
260       return 1;
261     return 0;
262   }
263 
264   void applyInstrChange(MachineInstr *MI, SMSchedule &Schedule);
265 
266   void fixupRegisterOverlaps(std::deque<SUnit *> &Instrs);
267 
268   /// Return the new base register that was stored away for the changed
269   /// instruction.
270   unsigned getInstrBaseReg(SUnit *SU) {
271     DenseMap<SUnit *, std::pair<unsigned, int64_t>>::iterator It =
272         InstrChanges.find(SU);
273     if (It != InstrChanges.end())
274       return It->second.first;
275     return 0;
276   }
277 
278   void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation) {
279     Mutations.push_back(std::move(Mutation));
280   }
281 
282   static bool classof(const ScheduleDAGInstrs *DAG) { return true; }
283 
284 private:
285   void addLoopCarriedDependences(AliasAnalysis *AA);
286   void updatePhiDependences();
287   void changeDependences();
288   unsigned calculateResMII();
289   unsigned calculateRecMII(NodeSetType &RecNodeSets);
290   void findCircuits(NodeSetType &NodeSets);
291   void fuseRecs(NodeSetType &NodeSets);
292   void removeDuplicateNodes(NodeSetType &NodeSets);
293   void computeNodeFunctions(NodeSetType &NodeSets);
294   void registerPressureFilter(NodeSetType &NodeSets);
295   void colocateNodeSets(NodeSetType &NodeSets);
296   void checkNodeSets(NodeSetType &NodeSets);
297   void groupRemainingNodes(NodeSetType &NodeSets);
298   void addConnectedNodes(SUnit *SU, NodeSet &NewSet,
299                          SetVector<SUnit *> &NodesAdded);
300   void computeNodeOrder(NodeSetType &NodeSets);
301   void checkValidNodeOrder(const NodeSetType &Circuits) const;
302   bool schedulePipeline(SMSchedule &Schedule);
303   bool computeDelta(MachineInstr &MI, unsigned &Delta);
304   MachineInstr *findDefInLoop(unsigned Reg);
305   bool canUseLastOffsetValue(MachineInstr *MI, unsigned &BasePos,
306                              unsigned &OffsetPos, unsigned &NewBase,
307                              int64_t &NewOffset);
308   void postprocessDAG();
309   /// Set the Minimum Initiation Interval for this schedule attempt.
310   void setMII(unsigned ResMII, unsigned RecMII);
311   /// Set the Maximum Initiation Interval for this schedule attempt.
312   void setMAX_II();
313 };
314 
315 /// A NodeSet contains a set of SUnit DAG nodes with additional information
316 /// that assigns a priority to the set.
317 class NodeSet {
318   SetVector<SUnit *> Nodes;
319   bool HasRecurrence = false;
320   unsigned RecMII = 0;
321   int MaxMOV = 0;
322   unsigned MaxDepth = 0;
323   unsigned Colocate = 0;
324   SUnit *ExceedPressure = nullptr;
325   unsigned Latency = 0;
326 
327 public:
328   using iterator = SetVector<SUnit *>::const_iterator;
329 
330   NodeSet() = default;
331   NodeSet(iterator S, iterator E) : Nodes(S, E), HasRecurrence(true) {
332     Latency = 0;
333     for (unsigned i = 0, e = Nodes.size(); i < e; ++i)
334       for (const SDep &Succ : Nodes[i]->Succs)
335         if (Nodes.count(Succ.getSUnit()))
336           Latency += Succ.getLatency();
337   }
338 
339   bool insert(SUnit *SU) { return Nodes.insert(SU); }
340 
341   void insert(iterator S, iterator E) { Nodes.insert(S, E); }
342 
343   template <typename UnaryPredicate> bool remove_if(UnaryPredicate P) {
344     return Nodes.remove_if(P);
345   }
346 
347   unsigned count(SUnit *SU) const { return Nodes.count(SU); }
348 
349   bool hasRecurrence() { return HasRecurrence; };
350 
351   unsigned size() const { return Nodes.size(); }
352 
353   bool empty() const { return Nodes.empty(); }
354 
355   SUnit *getNode(unsigned i) const { return Nodes[i]; };
356 
357   void setRecMII(unsigned mii) { RecMII = mii; };
358 
359   void setColocate(unsigned c) { Colocate = c; };
360 
361   void setExceedPressure(SUnit *SU) { ExceedPressure = SU; }
362 
363   bool isExceedSU(SUnit *SU) { return ExceedPressure == SU; }
364 
365   int compareRecMII(NodeSet &RHS) { return RecMII - RHS.RecMII; }
366 
367   int getRecMII() { return RecMII; }
368 
369   /// Summarize node functions for the entire node set.
370   void computeNodeSetInfo(SwingSchedulerDAG *SSD) {
371     for (SUnit *SU : *this) {
372       MaxMOV = std::max(MaxMOV, SSD->getMOV(SU));
373       MaxDepth = std::max(MaxDepth, SSD->getDepth(SU));
374     }
375   }
376 
377   unsigned getLatency() { return Latency; }
378 
379   unsigned getMaxDepth() { return MaxDepth; }
380 
381   void clear() {
382     Nodes.clear();
383     RecMII = 0;
384     HasRecurrence = false;
385     MaxMOV = 0;
386     MaxDepth = 0;
387     Colocate = 0;
388     ExceedPressure = nullptr;
389   }
390 
391   operator SetVector<SUnit *> &() { return Nodes; }
392 
393   /// Sort the node sets by importance. First, rank them by recurrence MII,
394   /// then by mobility (least mobile done first), and finally by depth.
395   /// Each node set may contain a colocate value which is used as the first
396   /// tie breaker, if it's set.
397   bool operator>(const NodeSet &RHS) const {
398     if (RecMII == RHS.RecMII) {
399       if (Colocate != 0 && RHS.Colocate != 0 && Colocate != RHS.Colocate)
400         return Colocate < RHS.Colocate;
401       if (MaxMOV == RHS.MaxMOV)
402         return MaxDepth > RHS.MaxDepth;
403       return MaxMOV < RHS.MaxMOV;
404     }
405     return RecMII > RHS.RecMII;
406   }
407 
408   bool operator==(const NodeSet &RHS) const {
409     return RecMII == RHS.RecMII && MaxMOV == RHS.MaxMOV &&
410            MaxDepth == RHS.MaxDepth;
411   }
412 
413   bool operator!=(const NodeSet &RHS) const { return !operator==(RHS); }
414 
415   iterator begin() { return Nodes.begin(); }
416   iterator end() { return Nodes.end(); }
417   void print(raw_ostream &os) const;
418 
419 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
420   LLVM_DUMP_METHOD void dump() const;
421 #endif
422 };
423 
424 // 16 was selected based on the number of ProcResource kinds for all
425 // existing Subtargets, so that SmallVector don't need to resize too often.
426 static const int DefaultProcResSize = 16;
427 
428 class ResourceManager {
429 private:
430   const MCSubtargetInfo *STI;
431   const MCSchedModel &SM;
432   const bool UseDFA;
433   std::unique_ptr<DFAPacketizer> DFAResources;
434   /// Each processor resource is associated with a so-called processor resource
435   /// mask. This vector allows to correlate processor resource IDs with
436   /// processor resource masks. There is exactly one element per each processor
437   /// resource declared by the scheduling model.
438   llvm::SmallVector<uint64_t, DefaultProcResSize> ProcResourceMasks;
439 
440   llvm::SmallVector<uint64_t, DefaultProcResSize> ProcResourceCount;
441 
442 public:
443   ResourceManager(const TargetSubtargetInfo *ST)
444       : STI(ST), SM(ST->getSchedModel()), UseDFA(ST->useDFAforSMS()),
445         ProcResourceMasks(SM.getNumProcResourceKinds(), 0),
446         ProcResourceCount(SM.getNumProcResourceKinds(), 0) {
447     if (UseDFA)
448       DFAResources.reset(ST->getInstrInfo()->CreateTargetScheduleState(*ST));
449     initProcResourceVectors(SM, ProcResourceMasks);
450   }
451 
452   void initProcResourceVectors(const MCSchedModel &SM,
453                                SmallVectorImpl<uint64_t> &Masks);
454   /// Check if the resources occupied by a MCInstrDesc are available in
455   /// the current state.
456   bool canReserveResources(const MCInstrDesc *MID) const;
457 
458   /// Reserve the resources occupied by a MCInstrDesc and change the current
459   /// state to reflect that change.
460   void reserveResources(const MCInstrDesc *MID);
461 
462   /// Check if the resources occupied by a machine instruction are available
463   /// in the current state.
464   bool canReserveResources(const MachineInstr &MI) const;
465 
466   /// Reserve the resources occupied by a machine instruction and change the
467   /// current state to reflect that change.
468   void reserveResources(const MachineInstr &MI);
469 
470   /// Reset the state
471   void clearResources();
472 };
473 
474 /// This class represents the scheduled code.  The main data structure is a
475 /// map from scheduled cycle to instructions.  During scheduling, the
476 /// data structure explicitly represents all stages/iterations.   When
477 /// the algorithm finshes, the schedule is collapsed into a single stage,
478 /// which represents instructions from different loop iterations.
479 ///
480 /// The SMS algorithm allows negative values for cycles, so the first cycle
481 /// in the schedule is the smallest cycle value.
482 class SMSchedule {
483 private:
484   /// Map from execution cycle to instructions.
485   DenseMap<int, std::deque<SUnit *>> ScheduledInstrs;
486 
487   /// Map from instruction to execution cycle.
488   std::map<SUnit *, int> InstrToCycle;
489 
490   /// Keep track of the first cycle value in the schedule.  It starts
491   /// as zero, but the algorithm allows negative values.
492   int FirstCycle = 0;
493 
494   /// Keep track of the last cycle value in the schedule.
495   int LastCycle = 0;
496 
497   /// The initiation interval (II) for the schedule.
498   int InitiationInterval = 0;
499 
500   /// Target machine information.
501   const TargetSubtargetInfo &ST;
502 
503   /// Virtual register information.
504   MachineRegisterInfo &MRI;
505 
506   ResourceManager ProcItinResources;
507 
508 public:
509   SMSchedule(MachineFunction *mf)
510       : ST(mf->getSubtarget()), MRI(mf->getRegInfo()), ProcItinResources(&ST) {}
511 
512   void reset() {
513     ScheduledInstrs.clear();
514     InstrToCycle.clear();
515     FirstCycle = 0;
516     LastCycle = 0;
517     InitiationInterval = 0;
518   }
519 
520   /// Set the initiation interval for this schedule.
521   void setInitiationInterval(int ii) { InitiationInterval = ii; }
522 
523   /// Return the first cycle in the completed schedule.  This
524   /// can be a negative value.
525   int getFirstCycle() const { return FirstCycle; }
526 
527   /// Return the last cycle in the finalized schedule.
528   int getFinalCycle() const { return FirstCycle + InitiationInterval - 1; }
529 
530   /// Return the cycle of the earliest scheduled instruction in the dependence
531   /// chain.
532   int earliestCycleInChain(const SDep &Dep);
533 
534   /// Return the cycle of the latest scheduled instruction in the dependence
535   /// chain.
536   int latestCycleInChain(const SDep &Dep);
537 
538   void computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart,
539                     int *MinEnd, int *MaxStart, int II, SwingSchedulerDAG *DAG);
540   bool insert(SUnit *SU, int StartCycle, int EndCycle, int II);
541 
542   /// Iterators for the cycle to instruction map.
543   using sched_iterator = DenseMap<int, std::deque<SUnit *>>::iterator;
544   using const_sched_iterator =
545       DenseMap<int, std::deque<SUnit *>>::const_iterator;
546 
547   /// Return true if the instruction is scheduled at the specified stage.
548   bool isScheduledAtStage(SUnit *SU, unsigned StageNum) {
549     return (stageScheduled(SU) == (int)StageNum);
550   }
551 
552   /// Return the stage for a scheduled instruction.  Return -1 if
553   /// the instruction has not been scheduled.
554   int stageScheduled(SUnit *SU) const {
555     std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
556     if (it == InstrToCycle.end())
557       return -1;
558     return (it->second - FirstCycle) / InitiationInterval;
559   }
560 
561   /// Return the cycle for a scheduled instruction. This function normalizes
562   /// the first cycle to be 0.
563   unsigned cycleScheduled(SUnit *SU) const {
564     std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
565     assert(it != InstrToCycle.end() && "Instruction hasn't been scheduled.");
566     return (it->second - FirstCycle) % InitiationInterval;
567   }
568 
569   /// Return the maximum stage count needed for this schedule.
570   unsigned getMaxStageCount() {
571     return (LastCycle - FirstCycle) / InitiationInterval;
572   }
573 
574   /// Return the instructions that are scheduled at the specified cycle.
575   std::deque<SUnit *> &getInstructions(int cycle) {
576     return ScheduledInstrs[cycle];
577   }
578 
579   bool isValidSchedule(SwingSchedulerDAG *SSD);
580   void finalizeSchedule(SwingSchedulerDAG *SSD);
581   void orderDependence(SwingSchedulerDAG *SSD, SUnit *SU,
582                        std::deque<SUnit *> &Insts);
583   bool isLoopCarried(SwingSchedulerDAG *SSD, MachineInstr &Phi);
584   bool isLoopCarriedDefOfUse(SwingSchedulerDAG *SSD, MachineInstr *Def,
585                              MachineOperand &MO);
586   void print(raw_ostream &os) const;
587   void dump() const;
588 };
589 
590 } // end namespace llvm
591 
592 #endif // LLVM_LIB_CODEGEN_MACHINEPIPELINER_H
593