1 //===---- llvm/CodeGen/ScheduleDAGSDNodes.h - SDNode Scheduling -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the ScheduleDAGSDNodes class, which implements
11 // scheduling for an SDNode-based dependency graph.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CODEGEN_SCHEDULEDAGSDNODES_H
16 #define LLVM_CODEGEN_SCHEDULEDAGSDNODES_H
18 #include "llvm/CodeGen/ScheduleDAG.h"
19 #include "llvm/CodeGen/SelectionDAG.h"
20 #include "llvm/ADT/SmallSet.h"
24 class MachineConstantPool;
25 class MachineFunction;
26 class MachineModuleInfo;
27 class MachineRegisterInfo;
29 class TargetRegisterInfo;
32 class SelectionDAGISel;
33 class TargetInstrInfo;
34 class TargetInstrDesc;
37 class TargetRegisterClass;
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
42 class HazardRecognizer {
44 virtual ~HazardRecognizer();
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.
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 *) {
63 /// EmitInstruction - This callback is invoked when an instruction is
64 /// emitted, to advance the hazard state.
65 virtual void EmitInstruction(SDNode *) {}
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() {}
73 /// EmitNoop - This callback is invoked when a noop was added to the
74 /// instruction stream.
75 virtual void EmitNoop() {}
78 class ScheduleDAGSDNodes : public ScheduleDAG {
80 SmallSet<SDNode*, 16> CommuteSet; // Nodes that should be commuted.
82 ScheduleDAGSDNodes(SelectionDAG *dag, MachineBasicBlock *bb,
83 const TargetMachine &tm);
85 virtual ~ScheduleDAGSDNodes() {}
87 /// isPassiveNode - Return true if the node is a non-scheduled leaf.
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;
104 /// NewSUnit - Creates a new SUnit and return a ptr to it.
106 SUnit *NewSUnit(SDNode *N) {
107 SUnits.push_back(SUnit(N, (unsigned)SUnits.size()));
108 SUnits.back().OrigNode = &SUnits.back();
109 return &SUnits.back();
112 /// Clone - Creates a clone of the specified SUnit. It does not copy the
113 /// predecessors / successors info nor the temporary scheduling states.
115 SUnit *Clone(SUnit *N);
117 virtual SelectionDAG *getDAG() { return DAG; }
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();
124 /// ComputeLatency - Compute node latency.
126 virtual void ComputeLatency(SUnit *SU);
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);
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);
139 /// ComputeMemOperandsEnd - Find the index one past the last
140 /// MemOperandSDNode operand
141 static unsigned ComputeMemOperandsEnd(SDNode *Node);
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.
147 void EmitNode(SDNode *Node, bool IsClone,
148 DenseMap<SDValue, unsigned> &VRBaseMap);
150 virtual MachineBasicBlock *EmitSchedule();
152 /// Schedule - Order nodes according to selected style, filling
153 /// in the Sequence member.
155 virtual void Schedule() = 0;
157 virtual void dumpNode(const SUnit *SU) const;
159 virtual std::string getGraphNodeLabel(const SUnit *SU) const;
161 virtual void getCustomGraphFeatures(GraphWriter<ScheduleDAG*> &GW) const;
164 /// EmitSubregNode - Generate machine code for subreg nodes.
166 void EmitSubregNode(SDNode *Node,
167 DenseMap<SDValue, unsigned> &VRBaseMap);
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);
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;
177 void AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum,
178 const TargetInstrDesc *II,
179 DenseMap<SDValue, unsigned> &VRBaseMap);
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,
185 DenseMap<SDValue, unsigned> &VRBaseMap);
187 void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
188 const TargetInstrDesc &II,
189 DenseMap<SDValue, unsigned> &VRBaseMap);
192 /// createBURRListDAGScheduler - This creates a bottom up register usage
193 /// reduction list scheduler.
194 ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS,
196 const TargetMachine *TM,
197 MachineBasicBlock *BB,
200 /// createTDRRListDAGScheduler - This creates a top down register usage
201 /// reduction list scheduler.
202 ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS,
204 const TargetMachine *TM,
205 MachineBasicBlock *BB,
208 /// createTDListDAGScheduler - This creates a top-down list scheduler with
209 /// a hazard recognizer.
210 ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS,
212 const TargetMachine *TM,
213 MachineBasicBlock *BB,
216 /// createFastDAGScheduler - This creates a "fast" scheduler.
218 ScheduleDAG *createFastDAGScheduler(SelectionDAGISel *IS,
220 const TargetMachine *TM,
221 MachineBasicBlock *BB,
224 /// createDefaultScheduler - This creates an instruction scheduler appropriate
226 ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
228 const TargetMachine *TM,
229 MachineBasicBlock *BB,