Add an option, -view-sunit-dags, for viewing the actual SUnit DAGs used by
[oota-llvm.git] / include / llvm / CodeGen / ScheduleDAG.h
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
23 namespace 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