e795649153d6bf7669dc0ffda3cc6a33714fb680
[oota-llvm.git] / include / llvm / CodeGen / ScheduleDAGSDNodes.h
1 //===---- llvm/CodeGen/ScheduleDAGSDNodes.h - SDNode Scheduling -*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the ScheduleDAGSDNodes class, which implements
11 // scheduling for an SDNode-based dependency graph.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CODEGEN_SCHEDULEDAGSDNODES_H
16 #define LLVM_CODEGEN_SCHEDULEDAGSDNODES_H
17
18 #include "llvm/CodeGen/ScheduleDAG.h"
19 #include "llvm/CodeGen/SelectionDAG.h"
20 #include "llvm/ADT/SmallSet.h"
21
22 namespace llvm {
23   struct SUnit;
24   class MachineConstantPool;
25   class MachineFunction;
26   class MachineModuleInfo;
27   class MachineRegisterInfo;
28   class MachineInstr;
29   class TargetRegisterInfo;
30   class ScheduleDAG;
31   class SelectionDAG;
32   class SelectionDAGISel;
33   class TargetInstrInfo;
34   class TargetInstrDesc;
35   class TargetLowering;
36   class TargetMachine;
37   class TargetRegisterClass;
38
39   /// HazardRecognizer - This determines whether or not an instruction can be
40   /// issued this cycle, and whether or not a noop needs to be inserted to handle
41   /// the hazard.
42   class HazardRecognizer {
43   public:
44     virtual ~HazardRecognizer();
45     
46     enum HazardType {
47       NoHazard,      // This instruction can be emitted at this cycle.
48       Hazard,        // This instruction can't be emitted at this cycle.
49       NoopHazard     // This instruction can't be emitted, and needs noops.
50     };
51     
52     /// getHazardType - Return the hazard type of emitting this node.  There are
53     /// three possible results.  Either:
54     ///  * NoHazard: it is legal to issue this instruction on this cycle.
55     ///  * Hazard: issuing this instruction would stall the machine.  If some
56     ///     other instruction is available, issue it first.
57     ///  * NoopHazard: issuing this instruction would break the program.  If
58     ///     some other instruction can be issued, do so, otherwise issue a noop.
59     virtual HazardType getHazardType(SDNode *) {
60       return NoHazard;
61     }
62     
63     /// EmitInstruction - This callback is invoked when an instruction is
64     /// emitted, to advance the hazard state.
65     virtual void EmitInstruction(SDNode *) {}
66     
67     /// AdvanceCycle - This callback is invoked when no instructions can be
68     /// issued on this cycle without a hazard.  This should increment the
69     /// internal state of the hazard recognizer so that previously "Hazard"
70     /// instructions will now not be hazards.
71     virtual void AdvanceCycle() {}
72     
73     /// EmitNoop - This callback is invoked when a noop was added to the
74     /// instruction stream.
75     virtual void EmitNoop() {}
76   };
77
78   class ScheduleDAGSDNodes : public ScheduleDAG {
79   public:
80     SmallSet<SDNode*, 16> CommuteSet;     // Nodes that should be commuted.
81
82     ScheduleDAGSDNodes(SelectionDAG *dag, MachineBasicBlock *bb,
83                        const TargetMachine &tm);
84
85     virtual ~ScheduleDAGSDNodes() {}
86
87     /// isPassiveNode - Return true if the node is a non-scheduled leaf.
88     ///
89     static bool isPassiveNode(SDNode *Node) {
90       if (isa<ConstantSDNode>(Node))       return true;
91       if (isa<ConstantFPSDNode>(Node))     return true;
92       if (isa<RegisterSDNode>(Node))       return true;
93       if (isa<GlobalAddressSDNode>(Node))  return true;
94       if (isa<BasicBlockSDNode>(Node))     return true;
95       if (isa<FrameIndexSDNode>(Node))     return true;
96       if (isa<ConstantPoolSDNode>(Node))   return true;
97       if (isa<JumpTableSDNode>(Node))      return true;
98       if (isa<ExternalSymbolSDNode>(Node)) return true;
99       if (isa<MemOperandSDNode>(Node))     return true;
100       if (Node->getOpcode() == ISD::EntryToken) return true;
101       return false;
102     }
103
104     /// NewSUnit - Creates a new SUnit and return a ptr to it.
105     ///
106     SUnit *NewSUnit(SDNode *N) {
107       SUnits.push_back(SUnit(N, (unsigned)SUnits.size()));
108       SUnits.back().OrigNode = &SUnits.back();
109       return &SUnits.back();
110     }
111
112     /// Clone - Creates a clone of the specified SUnit. It does not copy the
113     /// predecessors / successors info nor the temporary scheduling states.
114     ///
115     SUnit *Clone(SUnit *N);
116     
117     virtual SelectionDAG *getDAG() { return DAG; }
118
119     /// BuildSchedUnits - Build SUnits from the selection dag that we are input.
120     /// This SUnit graph is similar to the SelectionDAG, but represents flagged
121     /// together nodes with a single SUnit.
122     virtual void BuildSchedUnits();
123
124     /// ComputeLatency - Compute node latency.
125     ///
126     virtual void ComputeLatency(SUnit *SU);
127
128     /// CountResults - The results of target nodes have register or immediate
129     /// operands first, then an optional chain, and optional flag operands
130     /// (which do not go into the machine instrs.)
131     static unsigned CountResults(SDNode *Node);
132
133     /// CountOperands - The inputs to target nodes have any actual inputs first,
134     /// followed by special operands that describe memory references, then an
135     /// optional chain operand, then flag operands.  Compute the number of
136     /// actual operands that will go into the resulting MachineInstr.
137     static unsigned CountOperands(SDNode *Node);
138
139     /// ComputeMemOperandsEnd - Find the index one past the last
140     /// MemOperandSDNode operand
141     static unsigned ComputeMemOperandsEnd(SDNode *Node);
142
143     /// EmitNode - Generate machine code for an node and needed dependencies.
144     /// VRBaseMap contains, for each already emitted node, the first virtual
145     /// register number for the results of the node.
146     ///
147     void EmitNode(SDNode *Node, bool IsClone,
148                   DenseMap<SDValue, unsigned> &VRBaseMap);
149     
150     virtual MachineBasicBlock *EmitSchedule();
151
152     /// Schedule - Order nodes according to selected style, filling
153     /// in the Sequence member.
154     ///
155     virtual void Schedule() = 0;
156
157     virtual void dumpNode(const SUnit *SU) const;
158
159     virtual std::string getGraphNodeLabel(const SUnit *SU) const;
160
161     virtual void getCustomGraphFeatures(GraphWriter<ScheduleDAG*> &GW) const;
162
163   private:
164     /// EmitSubregNode - Generate machine code for subreg nodes.
165     ///
166     void EmitSubregNode(SDNode *Node, 
167                         DenseMap<SDValue, unsigned> &VRBaseMap);
168
169     /// getVR - Return the virtual register corresponding to the specified result
170     /// of the specified node.
171     unsigned getVR(SDValue Op, DenseMap<SDValue, unsigned> &VRBaseMap);
172   
173     /// getDstOfCopyToRegUse - If the only use of the specified result number of
174     /// node is a CopyToReg, return its destination register. Return 0 otherwise.
175     unsigned getDstOfOnlyCopyToRegUse(SDNode *Node, unsigned ResNo) const;
176
177     void AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum,
178                     const TargetInstrDesc *II,
179                     DenseMap<SDValue, unsigned> &VRBaseMap);
180
181     /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
182     /// implicit physical register output.
183     void EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone,
184                          unsigned SrcReg,
185                          DenseMap<SDValue, unsigned> &VRBaseMap);
186     
187     void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
188                                 const TargetInstrDesc &II,
189                                 DenseMap<SDValue, unsigned> &VRBaseMap);
190   };
191 }
192
193 #endif