Introducing plugable register allocators and instruction schedulers.
[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
20 #include <set>
21
22 namespace llvm {
23   struct InstrStage;
24   class MachineConstantPool;
25   class MachineDebugInfo;
26   class MachineInstr;
27   class MRegisterInfo;
28   class SelectionDAG;
29   class SSARegMap;
30   class TargetInstrInfo;
31   class TargetInstrDescriptor;
32   class TargetMachine;
33
34   /// HazardRecognizer - This determines whether or not an instruction can be
35   /// issued this cycle, and whether or not a noop needs to be inserted to handle
36   /// the hazard.
37   class HazardRecognizer {
38   public:
39     virtual ~HazardRecognizer();
40     
41     enum HazardType {
42       NoHazard,      // This instruction can be emitted at this cycle.
43       Hazard,        // This instruction can't be emitted at this cycle.
44       NoopHazard     // This instruction can't be emitted, and needs noops.
45     };
46     
47     /// getHazardType - Return the hazard type of emitting this node.  There are
48     /// three possible results.  Either:
49     ///  * NoHazard: it is legal to issue this instruction on this cycle.
50     ///  * Hazard: issuing this instruction would stall the machine.  If some
51     ///     other instruction is available, issue it first.
52     ///  * NoopHazard: issuing this instruction would break the program.  If
53     ///     some other instruction can be issued, do so, otherwise issue a noop.
54     virtual HazardType getHazardType(SDNode *Node) {
55       return NoHazard;
56     }
57     
58     /// EmitInstruction - This callback is invoked when an instruction is
59     /// emitted, to advance the hazard state.
60     virtual void EmitInstruction(SDNode *Node) {
61     }
62     
63     /// AdvanceCycle - This callback is invoked when no instructions can be
64     /// issued on this cycle without a hazard.  This should increment the
65     /// internal state of the hazard recognizer so that previously "Hazard"
66     /// instructions will now not be hazards.
67     virtual void AdvanceCycle() {
68     }
69     
70     /// EmitNoop - This callback is invoked when a noop was added to the
71     /// instruction stream.
72     virtual void EmitNoop() {
73     }
74   };
75   
76   /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
77   /// a group of nodes flagged together.
78   struct SUnit {
79     SDNode *Node;                       // Representative node.
80     std::vector<SDNode*> FlaggedNodes;  // All nodes flagged to Node.
81     
82     // Preds/Succs - The SUnits before/after us in the graph.  The boolean value
83     // is true if the edge is a token chain edge, false if it is a value edge. 
84     std::set<std::pair<SUnit*,bool> > Preds;  // All sunit predecessors.
85     std::set<std::pair<SUnit*,bool> > Succs;  // All sunit successors.
86
87     short NumPreds;                     // # of preds.
88     short NumSuccs;                     // # of sucss.
89     short NumPredsLeft;                 // # of preds not scheduled.
90     short NumSuccsLeft;                 // # of succs not scheduled.
91     short NumChainPredsLeft;            // # of chain preds not scheduled.
92     short NumChainSuccsLeft;            // # of chain succs not scheduled.
93     bool isTwoAddress     : 1;          // Is a two-address instruction.
94     bool isCommutable     : 1;          // Is a commutable instruction.
95     bool isPending        : 1;          // True once pending.
96     bool isAvailable      : 1;          // True once available.
97     bool isScheduled      : 1;          // True once scheduled.
98     unsigned short Latency;             // Node latency.
99     unsigned CycleBound;                // Upper/lower cycle to be scheduled at.
100     unsigned Cycle;                     // Once scheduled, the cycle of the op.
101     unsigned Depth;                     // Node depth;
102     unsigned Height;                    // Node height;
103     unsigned NodeNum;                   // Entry # of node in the node vector.
104     
105     SUnit(SDNode *node, unsigned nodenum)
106       : Node(node), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0),
107         NumChainPredsLeft(0), NumChainSuccsLeft(0),
108         isTwoAddress(false), isCommutable(false),
109         isPending(false), isAvailable(false), isScheduled(false),
110         Latency(0), CycleBound(0), Cycle(0), Depth(0), Height(0),
111         NodeNum(nodenum) {}
112     
113     void dump(const SelectionDAG *G) const;
114     void dumpAll(const SelectionDAG *G) const;
115   };
116
117   //===--------------------------------------------------------------------===//
118   /// SchedulingPriorityQueue - This interface is used to plug different
119   /// priorities computation algorithms into the list scheduler. It implements
120   /// the interface of a standard priority queue, where nodes are inserted in 
121   /// arbitrary order and returned in priority order.  The computation of the
122   /// priority and the representation of the queue are totally up to the
123   /// implementation to decide.
124   /// 
125   class SchedulingPriorityQueue {
126   public:
127     virtual ~SchedulingPriorityQueue() {}
128   
129     virtual void initNodes(const std::vector<SUnit> &SUnits) = 0;
130     virtual void releaseState() = 0;
131   
132     virtual bool empty() const = 0;
133     virtual void push(SUnit *U) = 0;
134   
135     virtual void push_all(const std::vector<SUnit *> &Nodes) = 0;
136     virtual SUnit *pop() = 0;
137
138     /// ScheduledNode - As each node is scheduled, this method is invoked.  This
139     /// allows the priority function to adjust the priority of node that have
140     /// already been emitted.
141     virtual void ScheduledNode(SUnit *Node) {}
142   };
143
144   class ScheduleDAG {
145   public:
146     SelectionDAG &DAG;                    // DAG of the current basic block
147     MachineBasicBlock *BB;                // Current basic block
148     const TargetMachine &TM;              // Target processor
149     const TargetInstrInfo *TII;           // Target instruction information
150     const MRegisterInfo *MRI;             // Target processor register info
151     SSARegMap *RegMap;                    // Virtual/real register map
152     MachineConstantPool *ConstPool;       // Target constant pool
153     std::vector<SUnit*> Sequence;         // The schedule. Null SUnit*'s
154                                           // represent noop instructions.
155     std::map<SDNode*, SUnit*> SUnitMap;   // SDNode to SUnit mapping (n -> 1).
156     std::vector<SUnit> SUnits;            // The scheduling units.
157     std::set<SDNode*> CommuteSet;         // Nodes the should be commuted.
158
159     ScheduleDAG(SelectionDAG &dag, MachineBasicBlock *bb,
160                 const TargetMachine &tm)
161       : DAG(dag), BB(bb), TM(tm) {}
162
163     virtual ~ScheduleDAG() {}
164
165     /// Run - perform scheduling.
166     ///
167     MachineBasicBlock *Run();
168
169     /// isPassiveNode - Return true if the node is a non-scheduled leaf.
170     ///
171     static bool isPassiveNode(SDNode *Node) {
172       if (isa<ConstantSDNode>(Node))       return true;
173       if (isa<RegisterSDNode>(Node))       return true;
174       if (isa<GlobalAddressSDNode>(Node))  return true;
175       if (isa<BasicBlockSDNode>(Node))     return true;
176       if (isa<FrameIndexSDNode>(Node))     return true;
177       if (isa<ConstantPoolSDNode>(Node))   return true;
178       if (isa<JumpTableSDNode>(Node))      return true;
179       if (isa<ExternalSymbolSDNode>(Node)) return true;
180       return false;
181     }
182
183     /// NewSUnit - Creates a new SUnit and return a ptr to it.
184     ///
185     SUnit *NewSUnit(SDNode *N) {
186       SUnits.push_back(SUnit(N, SUnits.size()));
187       return &SUnits.back();
188     }
189
190     /// BuildSchedUnits - Build SUnits from the selection dag that we are input.
191     /// This SUnit graph is similar to the SelectionDAG, but represents flagged
192     /// together nodes with a single SUnit.
193     void BuildSchedUnits();
194
195     /// CalculateDepths, CalculateHeights - Calculate node depth / height.
196     ///
197     void CalculateDepths();
198     void CalculateHeights();
199
200     /// EmitNode - Generate machine code for an node and needed dependencies.
201     /// VRBaseMap contains, for each already emitted node, the first virtual
202     /// register number for the results of the node.
203     ///
204     void EmitNode(SDNode *Node, std::map<SDNode*, unsigned> &VRBaseMap);
205     
206     /// EmitNoop - Emit a noop instruction.
207     ///
208     void EmitNoop();
209     
210     void EmitSchedule();
211
212     void dumpSchedule() const;
213
214     /// Schedule - Order nodes according to selected style.
215     ///
216     virtual void Schedule() {}
217
218   private:
219     void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum,
220                     const TargetInstrDescriptor *II,
221                     std::map<SDNode*, unsigned> &VRBaseMap);
222   };
223
224   /// createBFS_DAGScheduler - This creates a simple breadth first instruction
225   /// scheduler.
226   ScheduleDAG *createBFS_DAGScheduler(SelectionDAG *DAG, MachineBasicBlock *BB);
227   
228   /// createSimpleDAGScheduler - This creates a simple two pass instruction
229   /// scheduler using instruction itinerary.
230   ScheduleDAG* createSimpleDAGScheduler(SelectionDAG *DAG,
231                                         MachineBasicBlock *BB);
232
233   /// createNoItinsDAGScheduler - This creates a simple two pass instruction
234   /// scheduler without using instruction itinerary.
235   ScheduleDAG* createNoItinsDAGScheduler(SelectionDAG *DAG,
236                                          MachineBasicBlock *BB);
237
238   /// createBURRListDAGScheduler - This creates a bottom up register usage
239   /// reduction list scheduler.
240   ScheduleDAG* createBURRListDAGScheduler(SelectionDAG *DAG,
241                                           MachineBasicBlock *BB);
242   
243   /// createTDRRListDAGScheduler - This creates a top down register usage
244   /// reduction list scheduler.
245   ScheduleDAG* createTDRRListDAGScheduler(SelectionDAG *DAG,
246                                           MachineBasicBlock *BB);
247   
248   /// createTDListDAGScheduler - This creates a top-down list scheduler with
249   /// a hazard recognizer.
250   ScheduleDAG* createTDListDAGScheduler(SelectionDAG *DAG,
251                                         MachineBasicBlock *BB);
252                                         
253 }
254
255 #endif