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"
23 /// HazardRecognizer - This determines whether or not an instruction can be
24 /// issued this cycle, and whether or not a noop needs to be inserted to handle
26 class HazardRecognizer {
28 virtual ~HazardRecognizer();
31 NoHazard, // This instruction can be emitted at this cycle.
32 Hazard, // This instruction can't be emitted at this cycle.
33 NoopHazard // This instruction can't be emitted, and needs noops.
36 /// getHazardType - Return the hazard type of emitting this node. There are
37 /// three possible results. Either:
38 /// * NoHazard: it is legal to issue this instruction on this cycle.
39 /// * Hazard: issuing this instruction would stall the machine. If some
40 /// other instruction is available, issue it first.
41 /// * NoopHazard: issuing this instruction would break the program. If
42 /// some other instruction can be issued, do so, otherwise issue a noop.
43 virtual HazardType getHazardType(SDNode *) {
47 /// EmitInstruction - This callback is invoked when an instruction is
48 /// emitted, to advance the hazard state.
49 virtual void EmitInstruction(SDNode *) {}
51 /// AdvanceCycle - This callback is invoked when no instructions can be
52 /// issued on this cycle without a hazard. This should increment the
53 /// internal state of the hazard recognizer so that previously "Hazard"
54 /// instructions will now not be hazards.
55 virtual void AdvanceCycle() {}
57 /// EmitNoop - This callback is invoked when a noop was added to the
58 /// instruction stream.
59 virtual void EmitNoop() {}
62 /// ScheduleDAGSDNodes - A ScheduleDAG for scheduling SDNode-based DAGs.
64 /// Edges between SUnits are initially based on edges in the SelectionDAG,
65 /// and additional edges can be added by the schedulers as heuristics.
66 /// SDNodes such as Constants, Registers, and a few others that are not
67 /// interesting to schedulers are not allocated SUnits.
69 /// SDNodes with MVT::Flag operands are grouped along with the flagged
70 /// nodes into a single SUnit so that they are scheduled together.
72 /// SDNode-based scheduling graphs do not use SDep::Anti or SDep::Output
73 /// edges. Physical register dependence information is not carried in
74 /// the DAG and must be handled explicitly by schedulers.
76 class ScheduleDAGSDNodes : public ScheduleDAG {
78 SmallSet<SDNode*, 16> CommuteSet; // Nodes that should be commuted.
80 ScheduleDAGSDNodes(SelectionDAG *dag, MachineBasicBlock *bb,
81 const TargetMachine &tm);
83 virtual ~ScheduleDAGSDNodes() {}
85 /// isPassiveNode - Return true if the node is a non-scheduled leaf.
87 static bool isPassiveNode(SDNode *Node) {
88 if (isa<ConstantSDNode>(Node)) return true;
89 if (isa<ConstantFPSDNode>(Node)) return true;
90 if (isa<RegisterSDNode>(Node)) return true;
91 if (isa<GlobalAddressSDNode>(Node)) return true;
92 if (isa<BasicBlockSDNode>(Node)) return true;
93 if (isa<FrameIndexSDNode>(Node)) return true;
94 if (isa<ConstantPoolSDNode>(Node)) return true;
95 if (isa<JumpTableSDNode>(Node)) return true;
96 if (isa<ExternalSymbolSDNode>(Node)) return true;
97 if (isa<MemOperandSDNode>(Node)) return true;
98 if (Node->getOpcode() == ISD::EntryToken) return true;
102 /// NewSUnit - Creates a new SUnit and return a ptr to it.
104 SUnit *NewSUnit(SDNode *N) {
106 const SUnit *Addr = &SUnits[0];
108 SUnits.push_back(SUnit(N, (unsigned)SUnits.size()));
109 assert(Addr == &SUnits[0] && "SUnits std::vector reallocated on the fly!");
110 SUnits.back().OrigNode = &SUnits.back();
111 return &SUnits.back();
114 /// Clone - Creates a clone of the specified SUnit. It does not copy the
115 /// predecessors / successors info nor the temporary scheduling states.
117 SUnit *Clone(SUnit *N);
119 virtual SelectionDAG *getDAG() { return DAG; }
121 /// BuildSchedGraph - Build the SUnit graph from the selection dag that we
122 /// are input. This SUnit graph is similar to the SelectionDAG, but
123 /// excludes nodes that aren't interesting to scheduling, and represents
124 /// flagged together nodes with a single SUnit.
125 virtual void BuildSchedGraph();
127 /// ComputeLatency - Compute node latency.
129 virtual void ComputeLatency(SUnit *SU);
131 /// CountResults - The results of target nodes have register or immediate
132 /// operands first, then an optional chain, and optional flag operands
133 /// (which do not go into the machine instrs.)
134 static unsigned CountResults(SDNode *Node);
136 /// CountOperands - The inputs to target nodes have any actual inputs first,
137 /// followed by special operands that describe memory references, then an
138 /// optional chain operand, then flag operands. Compute the number of
139 /// actual operands that will go into the resulting MachineInstr.
140 static unsigned CountOperands(SDNode *Node);
142 /// ComputeMemOperandsEnd - Find the index one past the last
143 /// MemOperandSDNode operand
144 static unsigned ComputeMemOperandsEnd(SDNode *Node);
146 /// EmitNode - Generate machine code for an node and needed dependencies.
147 /// VRBaseMap contains, for each already emitted node, the first virtual
148 /// register number for the results of the node.
150 void EmitNode(SDNode *Node, bool IsClone,
151 DenseMap<SDValue, unsigned> &VRBaseMap);
153 virtual MachineBasicBlock *EmitSchedule();
155 /// Schedule - Order nodes according to selected style, filling
156 /// in the Sequence member.
158 virtual void Schedule() = 0;
160 virtual void dumpNode(const SUnit *SU) const;
162 virtual std::string getGraphNodeLabel(const SUnit *SU) const;
164 virtual void getCustomGraphFeatures(GraphWriter<ScheduleDAG*> &GW) const;
167 /// EmitSubregNode - Generate machine code for subreg nodes.
169 void EmitSubregNode(SDNode *Node,
170 DenseMap<SDValue, unsigned> &VRBaseMap);
172 /// getVR - Return the virtual register corresponding to the specified result
173 /// of the specified node.
174 unsigned getVR(SDValue Op, DenseMap<SDValue, unsigned> &VRBaseMap);
176 /// getDstOfCopyToRegUse - If the only use of the specified result number of
177 /// node is a CopyToReg, return its destination register. Return 0 otherwise.
178 unsigned getDstOfOnlyCopyToRegUse(SDNode *Node, unsigned ResNo) const;
180 void AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum,
181 const TargetInstrDesc *II,
182 DenseMap<SDValue, unsigned> &VRBaseMap);
184 /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
185 /// implicit physical register output.
186 void EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone,
188 DenseMap<SDValue, unsigned> &VRBaseMap);
190 void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
191 const TargetInstrDesc &II,
192 DenseMap<SDValue, unsigned> &VRBaseMap);
194 /// BuildSchedUnits, AddSchedEdges - Helper functions for BuildSchedGraph.
195 void BuildSchedUnits();
196 void AddSchedEdges();