blob: 6fc14936caebe52fdfa80674053e8dec3b36fc4c [file] [log] [blame]
Dan Gohman343f0c02008-11-19 23:18:57 +00001//===---- 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"
Dan Gohman343f0c02008-11-19 23:18:57 +000020
21namespace llvm {
Dan Gohman343f0c02008-11-19 23:18:57 +000022 /// HazardRecognizer - This determines whether or not an instruction can be
23 /// issued this cycle, and whether or not a noop needs to be inserted to handle
24 /// the hazard.
25 class HazardRecognizer {
26 public:
27 virtual ~HazardRecognizer();
28
29 enum HazardType {
30 NoHazard, // This instruction can be emitted at this cycle.
31 Hazard, // This instruction can't be emitted at this cycle.
32 NoopHazard // This instruction can't be emitted, and needs noops.
33 };
34
35 /// getHazardType - Return the hazard type of emitting this node. There are
36 /// three possible results. Either:
37 /// * NoHazard: it is legal to issue this instruction on this cycle.
38 /// * Hazard: issuing this instruction would stall the machine. If some
39 /// other instruction is available, issue it first.
40 /// * NoopHazard: issuing this instruction would break the program. If
41 /// some other instruction can be issued, do so, otherwise issue a noop.
42 virtual HazardType getHazardType(SDNode *) {
43 return NoHazard;
44 }
45
46 /// EmitInstruction - This callback is invoked when an instruction is
47 /// emitted, to advance the hazard state.
48 virtual void EmitInstruction(SDNode *) {}
49
50 /// AdvanceCycle - This callback is invoked when no instructions can be
51 /// issued on this cycle without a hazard. This should increment the
52 /// internal state of the hazard recognizer so that previously "Hazard"
53 /// instructions will now not be hazards.
54 virtual void AdvanceCycle() {}
55
56 /// EmitNoop - This callback is invoked when a noop was added to the
57 /// instruction stream.
58 virtual void EmitNoop() {}
59 };
60
Dan Gohman983bbba2008-12-22 21:06:20 +000061 /// ScheduleDAGSDNodes - A ScheduleDAG for scheduling SDNode-based DAGs.
62 ///
63 /// Edges between SUnits are initially based on edges in the SelectionDAG,
64 /// and additional edges can be added by the schedulers as heuristics.
65 /// SDNodes such as Constants, Registers, and a few others that are not
66 /// interesting to schedulers are not allocated SUnits.
67 ///
68 /// SDNodes with MVT::Flag operands are grouped along with the flagged
69 /// nodes into a single SUnit so that they are scheduled together.
70 ///
71 /// SDNode-based scheduling graphs do not use SDep::Anti or SDep::Output
72 /// edges. Physical register dependence information is not carried in
73 /// the DAG and must be handled explicitly by schedulers.
74 ///
Dan Gohman343f0c02008-11-19 23:18:57 +000075 class ScheduleDAGSDNodes : public ScheduleDAG {
76 public:
Dan Gohman79ce2762009-01-15 19:20:50 +000077 explicit ScheduleDAGSDNodes(MachineFunction &mf);
Dan Gohman343f0c02008-11-19 23:18:57 +000078
79 virtual ~ScheduleDAGSDNodes() {}
80
81 /// isPassiveNode - Return true if the node is a non-scheduled leaf.
82 ///
83 static bool isPassiveNode(SDNode *Node) {
84 if (isa<ConstantSDNode>(Node)) return true;
85 if (isa<ConstantFPSDNode>(Node)) return true;
86 if (isa<RegisterSDNode>(Node)) return true;
87 if (isa<GlobalAddressSDNode>(Node)) return true;
88 if (isa<BasicBlockSDNode>(Node)) return true;
89 if (isa<FrameIndexSDNode>(Node)) return true;
90 if (isa<ConstantPoolSDNode>(Node)) return true;
91 if (isa<JumpTableSDNode>(Node)) return true;
92 if (isa<ExternalSymbolSDNode>(Node)) return true;
93 if (isa<MemOperandSDNode>(Node)) return true;
94 if (Node->getOpcode() == ISD::EntryToken) return true;
95 return false;
96 }
97
98 /// NewSUnit - Creates a new SUnit and return a ptr to it.
99 ///
100 SUnit *NewSUnit(SDNode *N) {
Dan Gohman983bbba2008-12-22 21:06:20 +0000101#ifndef NDEBUG
Bill Wendlingd5b207b2009-01-01 01:14:31 +0000102 const SUnit *Addr = 0;
103 if (SUnits.size() > 0)
104 Addr = &SUnits[0];
Dan Gohman983bbba2008-12-22 21:06:20 +0000105#endif
Dan Gohman343f0c02008-11-19 23:18:57 +0000106 SUnits.push_back(SUnit(N, (unsigned)SUnits.size()));
Bill Wendlingd5b207b2009-01-01 01:14:31 +0000107 assert((Addr == 0 || Addr == &SUnits[0]) &&
108 "SUnits std::vector reallocated on the fly!");
Dan Gohman343f0c02008-11-19 23:18:57 +0000109 SUnits.back().OrigNode = &SUnits.back();
110 return &SUnits.back();
111 }
112
113 /// Clone - Creates a clone of the specified SUnit. It does not copy the
114 /// predecessors / successors info nor the temporary scheduling states.
115 ///
116 SUnit *Clone(SUnit *N);
117
118 virtual SelectionDAG *getDAG() { return DAG; }
119
Dan Gohmanc9a5b9e2008-12-23 18:36:58 +0000120 /// BuildSchedGraph - Build the SUnit graph from the selection dag that we
121 /// are input. This SUnit graph is similar to the SelectionDAG, but
122 /// excludes nodes that aren't interesting to scheduling, and represents
123 /// flagged together nodes with a single SUnit.
124 virtual void BuildSchedGraph();
Dan Gohman343f0c02008-11-19 23:18:57 +0000125
126 /// ComputeLatency - Compute node latency.
127 ///
128 virtual void ComputeLatency(SUnit *SU);
129
130 /// CountResults - The results of target nodes have register or immediate
131 /// operands first, then an optional chain, and optional flag operands
132 /// (which do not go into the machine instrs.)
133 static unsigned CountResults(SDNode *Node);
134
135 /// CountOperands - The inputs to target nodes have any actual inputs first,
136 /// followed by special operands that describe memory references, then an
137 /// optional chain operand, then flag operands. Compute the number of
138 /// actual operands that will go into the resulting MachineInstr.
139 static unsigned CountOperands(SDNode *Node);
140
141 /// ComputeMemOperandsEnd - Find the index one past the last
142 /// MemOperandSDNode operand
143 static unsigned ComputeMemOperandsEnd(SDNode *Node);
144
145 /// EmitNode - Generate machine code for an node and needed dependencies.
146 /// VRBaseMap contains, for each already emitted node, the first virtual
147 /// register number for the results of the node.
148 ///
149 void EmitNode(SDNode *Node, bool IsClone,
150 DenseMap<SDValue, unsigned> &VRBaseMap);
151
152 virtual MachineBasicBlock *EmitSchedule();
153
154 /// Schedule - Order nodes according to selected style, filling
155 /// in the Sequence member.
156 ///
157 virtual void Schedule() = 0;
158
159 virtual void dumpNode(const SUnit *SU) const;
160
161 virtual std::string getGraphNodeLabel(const SUnit *SU) const;
162
163 virtual void getCustomGraphFeatures(GraphWriter<ScheduleDAG*> &GW) const;
164
165 private:
166 /// EmitSubregNode - Generate machine code for subreg nodes.
167 ///
168 void EmitSubregNode(SDNode *Node,
169 DenseMap<SDValue, unsigned> &VRBaseMap);
170
171 /// getVR - Return the virtual register corresponding to the specified result
172 /// of the specified node.
173 unsigned getVR(SDValue Op, DenseMap<SDValue, unsigned> &VRBaseMap);
174
175 /// getDstOfCopyToRegUse - If the only use of the specified result number of
176 /// node is a CopyToReg, return its destination register. Return 0 otherwise.
177 unsigned getDstOfOnlyCopyToRegUse(SDNode *Node, unsigned ResNo) const;
178
179 void AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum,
180 const TargetInstrDesc *II,
181 DenseMap<SDValue, unsigned> &VRBaseMap);
182
183 /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
184 /// implicit physical register output.
185 void EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone,
186 unsigned SrcReg,
187 DenseMap<SDValue, unsigned> &VRBaseMap);
188
189 void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
Evan Cheng5c3c5a42009-01-09 22:44:02 +0000190 const TargetInstrDesc &II, bool IsClone,
Dan Gohman343f0c02008-11-19 23:18:57 +0000191 DenseMap<SDValue, unsigned> &VRBaseMap);
Dan Gohmanc9a5b9e2008-12-23 18:36:58 +0000192
193 /// BuildSchedUnits, AddSchedEdges - Helper functions for BuildSchedGraph.
194 void BuildSchedUnits();
195 void AddSchedEdges();
Dan Gohman343f0c02008-11-19 23:18:57 +0000196 };
Dan Gohman343f0c02008-11-19 23:18:57 +0000197}
198
199#endif