ScheduleDAG.h revision 3e1a7aef17575d9c7058a035449d57e3c7295ed0
1//===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file was developed by Evan Cheng and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the ScheduleDAG class, which is used as the common
11// base class for SelectionDAG-based instruction scheduler.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CODEGEN_SCHEDULEDAG_H
16#define LLVM_CODEGEN_SCHEDULEDAG_H
17
18#include "llvm/CodeGen/SelectionDAG.h"
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/GraphTraits.h"
21#include "llvm/ADT/SmallSet.h"
22
23namespace llvm {
24  struct InstrStage;
25  class MachineConstantPool;
26  class MachineModuleInfo;
27  class MachineInstr;
28  class MRegisterInfo;
29  class SelectionDAG;
30  class SelectionDAGISel;
31  class SSARegMap;
32  class TargetInstrInfo;
33  class TargetInstrDescriptor;
34  class TargetMachine;
35
36  /// HazardRecognizer - This determines whether or not an instruction can be
37  /// issued this cycle, and whether or not a noop needs to be inserted to handle
38  /// the hazard.
39  class HazardRecognizer {
40  public:
41    virtual ~HazardRecognizer();
42
43    enum HazardType {
44      NoHazard,      // This instruction can be emitted at this cycle.
45      Hazard,        // This instruction can't be emitted at this cycle.
46      NoopHazard     // This instruction can't be emitted, and needs noops.
47    };
48
49    /// getHazardType - Return the hazard type of emitting this node.  There are
50    /// three possible results.  Either:
51    ///  * NoHazard: it is legal to issue this instruction on this cycle.
52    ///  * Hazard: issuing this instruction would stall the machine.  If some
53    ///     other instruction is available, issue it first.
54    ///  * NoopHazard: issuing this instruction would break the program.  If
55    ///     some other instruction can be issued, do so, otherwise issue a noop.
56    virtual HazardType getHazardType(SDNode *Node) {
57      return NoHazard;
58    }
59
60    /// EmitInstruction - This callback is invoked when an instruction is
61    /// emitted, to advance the hazard state.
62    virtual void EmitInstruction(SDNode *Node) {
63    }
64
65    /// AdvanceCycle - This callback is invoked when no instructions can be
66    /// issued on this cycle without a hazard.  This should increment the
67    /// internal state of the hazard recognizer so that previously "Hazard"
68    /// instructions will now not be hazards.
69    virtual void AdvanceCycle() {
70    }
71
72    /// EmitNoop - This callback is invoked when a noop was added to the
73    /// instruction stream.
74    virtual void EmitNoop() {
75    }
76  };
77
78  /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
79  /// a group of nodes flagged together.
80  struct SUnit {
81    SDNode *Node;                       // Representative node.
82    SmallVector<SDNode*,4> FlaggedNodes;// All nodes flagged to Node.
83
84    // Preds/Succs - The SUnits before/after us in the graph.  The boolean value
85    // is true if the edge is a token chain edge, false if it is a value edge.
86    SmallVector<std::pair<SUnit*,bool>, 4> Preds;  // All sunit predecessors.
87    SmallVector<std::pair<SUnit*,bool>, 4> Succs;  // All sunit successors.
88
89    typedef SmallVector<std::pair<SUnit*,bool>, 4>::iterator pred_iterator;
90    typedef SmallVector<std::pair<SUnit*,bool>, 4>::iterator succ_iterator;
91    typedef SmallVector<std::pair<SUnit*,bool>, 4>::const_iterator
92      const_pred_iterator;
93    typedef SmallVector<std::pair<SUnit*,bool>, 4>::const_iterator
94      const_succ_iterator;
95
96    short NumPreds;                     // # of preds.
97    short NumSuccs;                     // # of sucss.
98    short NumPredsLeft;                 // # of preds not scheduled.
99    short NumSuccsLeft;                 // # of succs not scheduled.
100    short NumChainPredsLeft;            // # of chain preds not scheduled.
101    short NumChainSuccsLeft;            // # of chain succs not scheduled.
102    bool isTwoAddress     : 1;          // Is a two-address instruction.
103    bool isCommutable     : 1;          // Is a commutable instruction.
104    bool isPending        : 1;          // True once pending.
105    bool isAvailable      : 1;          // True once available.
106    bool isScheduled      : 1;          // True once scheduled.
107    unsigned short Latency;             // Node latency.
108    unsigned CycleBound;                // Upper/lower cycle to be scheduled at.
109    unsigned Cycle;                     // Once scheduled, the cycle of the op.
110    unsigned Depth;                     // Node depth;
111    unsigned Height;                    // Node height;
112    unsigned NodeNum;                   // Entry # of node in the node vector.
113
114    SUnit(SDNode *node, unsigned nodenum)
115      : Node(node), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0),
116        NumChainPredsLeft(0), NumChainSuccsLeft(0),
117        isTwoAddress(false), isCommutable(false),
118        isPending(false), isAvailable(false), isScheduled(false),
119        Latency(0), CycleBound(0), Cycle(0), Depth(0), Height(0),
120        NodeNum(nodenum) {}
121
122    /// addPred - This adds the specified node as a pred of the current node if
123    /// not already.  This returns true if this is a new pred.
124    bool addPred(SUnit *N, bool isChain) {
125      for (unsigned i = 0, e = Preds.size(); i != e; ++i)
126        if (Preds[i].first == N && Preds[i].second == isChain)
127          return false;
128      Preds.push_back(std::make_pair(N, isChain));
129      return true;
130    }
131
132    /// addSucc - This adds the specified node as a succ of the current node if
133    /// not already.  This returns true if this is a new succ.
134    bool addSucc(SUnit *N, bool isChain) {
135      for (unsigned i = 0, e = Succs.size(); i != e; ++i)
136        if (Succs[i].first == N && Succs[i].second == isChain)
137          return false;
138      Succs.push_back(std::make_pair(N, isChain));
139      return true;
140    }
141
142    void dump(const SelectionDAG *G) const;
143    void dumpAll(const SelectionDAG *G) const;
144  };
145
146  //===--------------------------------------------------------------------===//
147  /// SchedulingPriorityQueue - This interface is used to plug different
148  /// priorities computation algorithms into the list scheduler. It implements
149  /// the interface of a standard priority queue, where nodes are inserted in
150  /// arbitrary order and returned in priority order.  The computation of the
151  /// priority and the representation of the queue are totally up to the
152  /// implementation to decide.
153  ///
154  class SchedulingPriorityQueue {
155  public:
156    virtual ~SchedulingPriorityQueue() {}
157
158    virtual void initNodes(DenseMap<SDNode*, SUnit*> &SUMap,
159                           std::vector<SUnit> &SUnits) = 0;
160    virtual void releaseState() = 0;
161
162    virtual bool empty() const = 0;
163    virtual void push(SUnit *U) = 0;
164
165    virtual void push_all(const std::vector<SUnit *> &Nodes) = 0;
166    virtual SUnit *pop() = 0;
167
168    /// ScheduledNode - As each node is scheduled, this method is invoked.  This
169    /// allows the priority function to adjust the priority of node that have
170    /// already been emitted.
171    virtual void ScheduledNode(SUnit *Node) {}
172  };
173
174  class ScheduleDAG {
175  public:
176    SelectionDAG &DAG;                    // DAG of the current basic block
177    MachineBasicBlock *BB;                // Current basic block
178    const TargetMachine &TM;              // Target processor
179    const TargetInstrInfo *TII;           // Target instruction information
180    const MRegisterInfo *MRI;             // Target processor register info
181    SSARegMap *RegMap;                    // Virtual/real register map
182    MachineConstantPool *ConstPool;       // Target constant pool
183    std::vector<SUnit*> Sequence;         // The schedule. Null SUnit*'s
184                                          // represent noop instructions.
185    DenseMap<SDNode*, SUnit*> SUnitMap;   // SDNode to SUnit mapping (n -> 1).
186    std::vector<SUnit> SUnits;            // The scheduling units.
187    SmallSet<SDNode*, 16> CommuteSet;     // Nodes the should be commuted.
188
189    ScheduleDAG(SelectionDAG &dag, MachineBasicBlock *bb,
190                const TargetMachine &tm)
191      : DAG(dag), BB(bb), TM(tm) {}
192
193    virtual ~ScheduleDAG() {}
194
195    /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
196    /// using 'dot'.
197    ///
198    void viewGraph();
199
200    /// Run - perform scheduling.
201    ///
202    MachineBasicBlock *Run();
203
204    /// isPassiveNode - Return true if the node is a non-scheduled leaf.
205    ///
206    static bool isPassiveNode(SDNode *Node) {
207      if (isa<ConstantSDNode>(Node))       return true;
208      if (isa<RegisterSDNode>(Node))       return true;
209      if (isa<GlobalAddressSDNode>(Node))  return true;
210      if (isa<BasicBlockSDNode>(Node))     return true;
211      if (isa<FrameIndexSDNode>(Node))     return true;
212      if (isa<ConstantPoolSDNode>(Node))   return true;
213      if (isa<JumpTableSDNode>(Node))      return true;
214      if (isa<ExternalSymbolSDNode>(Node)) return true;
215      return false;
216    }
217
218    /// NewSUnit - Creates a new SUnit and return a ptr to it.
219    ///
220    SUnit *NewSUnit(SDNode *N) {
221      SUnits.push_back(SUnit(N, SUnits.size()));
222      return &SUnits.back();
223    }
224
225    /// BuildSchedUnits - Build SUnits from the selection dag that we are input.
226    /// This SUnit graph is similar to the SelectionDAG, but represents flagged
227    /// together nodes with a single SUnit.
228    void BuildSchedUnits();
229
230    /// CalculateDepths, CalculateHeights - Calculate node depth / height.
231    ///
232    void CalculateDepths();
233    void CalculateHeights();
234
235    /// CountResults - The results of target nodes have register or immediate
236    /// operands first, then an optional chain, and optional flag operands
237    /// (which do not go into the machine instrs.)
238    static unsigned CountResults(SDNode *Node);
239
240    /// CountOperands  The inputs to target nodes have any actual inputs first,
241    /// followed by an optional chain operand, then flag operands.  Compute the
242    /// number of actual operands that  will go into the machine instr.
243    static unsigned CountOperands(SDNode *Node);
244
245    /// EmitNode - Generate machine code for an node and needed dependencies.
246    /// VRBaseMap contains, for each already emitted node, the first virtual
247    /// register number for the results of the node.
248    ///
249    void EmitNode(SDNode *Node, DenseMap<SDOperand, unsigned> &VRBaseMap);
250
251    /// EmitNoop - Emit a noop instruction.
252    ///
253    void EmitNoop();
254
255    /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
256    /// implicit physical register output.
257    void EmitCopyFromReg(SDNode *Node, unsigned ResNo, unsigned SrcReg,
258                         DenseMap<SDOperand, unsigned> &VRBaseMap);
259
260    void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
261                                const TargetInstrDescriptor &II,
262                                DenseMap<SDOperand, unsigned> &VRBaseMap);
263
264    void EmitSchedule();
265
266    void dumpSchedule() const;
267
268    /// Schedule - Order nodes according to selected style.
269    ///
270    virtual void Schedule() {}
271
272  private:
273    /// EmitSubregNode - Generate machine code for subreg nodes.
274    ///
275    void EmitSubregNode(SDNode *Node,
276                        DenseMap<SDOperand, unsigned> &VRBaseMap);
277
278    void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum,
279                    const TargetInstrDescriptor *II,
280                    DenseMap<SDOperand, unsigned> &VRBaseMap);
281  };
282
283  /// createBFS_DAGScheduler - This creates a simple breadth first instruction
284  /// scheduler.
285  ScheduleDAG *createBFS_DAGScheduler(SelectionDAGISel *IS,
286                                      SelectionDAG *DAG,
287                                      MachineBasicBlock *BB);
288
289  /// createSimpleDAGScheduler - This creates a simple two pass instruction
290  /// scheduler using instruction itinerary.
291  ScheduleDAG* createSimpleDAGScheduler(SelectionDAGISel *IS,
292                                        SelectionDAG *DAG,
293                                        MachineBasicBlock *BB);
294
295  /// createNoItinsDAGScheduler - This creates a simple two pass instruction
296  /// scheduler without using instruction itinerary.
297  ScheduleDAG* createNoItinsDAGScheduler(SelectionDAGISel *IS,
298                                         SelectionDAG *DAG,
299                                         MachineBasicBlock *BB);
300
301  /// createBURRListDAGScheduler - This creates a bottom up register usage
302  /// reduction list scheduler.
303  ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS,
304                                          SelectionDAG *DAG,
305                                          MachineBasicBlock *BB);
306
307  /// createTDRRListDAGScheduler - This creates a top down register usage
308  /// reduction list scheduler.
309  ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS,
310                                          SelectionDAG *DAG,
311                                          MachineBasicBlock *BB);
312
313  /// createTDListDAGScheduler - This creates a top-down list scheduler with
314  /// a hazard recognizer.
315  ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS,
316                                        SelectionDAG *DAG,
317                                        MachineBasicBlock *BB);
318
319  /// createDefaultScheduler - This creates an instruction scheduler appropriate
320  /// for the target.
321  ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
322                                      SelectionDAG *DAG,
323                                      MachineBasicBlock *BB);
324
325  class SUnitIterator : public forward_iterator<SUnit, ptrdiff_t> {
326    SUnit *Node;
327    unsigned Operand;
328
329    SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
330  public:
331    bool operator==(const SUnitIterator& x) const {
332      return Operand == x.Operand;
333    }
334    bool operator!=(const SUnitIterator& x) const { return !operator==(x); }
335
336    const SUnitIterator &operator=(const SUnitIterator &I) {
337      assert(I.Node == Node && "Cannot assign iterators to two different nodes!");
338      Operand = I.Operand;
339      return *this;
340    }
341
342    pointer operator*() const {
343      return Node->Preds[Operand].first;
344    }
345    pointer operator->() const { return operator*(); }
346
347    SUnitIterator& operator++() {                // Preincrement
348      ++Operand;
349      return *this;
350    }
351    SUnitIterator operator++(int) { // Postincrement
352      SUnitIterator tmp = *this; ++*this; return tmp;
353    }
354
355    static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); }
356    static SUnitIterator end  (SUnit *N) {
357      return SUnitIterator(N, N->Preds.size());
358    }
359
360    unsigned getOperand() const { return Operand; }
361    const SUnit *getNode() const { return Node; }
362    bool isChain() const { return Node->Preds[Operand].second; }
363  };
364
365  template <> struct GraphTraits<SUnit*> {
366    typedef SUnit NodeType;
367    typedef SUnitIterator ChildIteratorType;
368    static inline NodeType *getEntryNode(SUnit *N) { return N; }
369    static inline ChildIteratorType child_begin(NodeType *N) {
370      return SUnitIterator::begin(N);
371    }
372    static inline ChildIteratorType child_end(NodeType *N) {
373      return SUnitIterator::end(N);
374    }
375  };
376
377  template <> struct GraphTraits<ScheduleDAG*> : public GraphTraits<SUnit*> {
378    typedef std::vector<SUnit>::iterator nodes_iterator;
379    static nodes_iterator nodes_begin(ScheduleDAG *G) {
380      return G->SUnits.begin();
381    }
382    static nodes_iterator nodes_end(ScheduleDAG *G) {
383      return G->SUnits.end();
384    }
385  };
386}
387
388#endif
389