blob: c2e217523850a2b2a0af8e9386441c6c75fbfaee [file] [log] [blame]
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001//===---- ScheduleDAG.cpp - Implement the ScheduleDAG class ---------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner081ce942007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Dan Gohmanf17a25c2007-07-18 16:29:46 +00007//
8//===----------------------------------------------------------------------===//
9//
Dan Gohmane39d9902008-07-11 22:39:58 +000010// This implements the ScheduleDAG class, which is a base class used by
11// scheduling implementation classes.
Dan Gohmanf17a25c2007-07-18 16:29:46 +000012//
13//===----------------------------------------------------------------------===//
14
15#define DEBUG_TYPE "pre-RA-sched"
Dan Gohmanf17a25c2007-07-18 16:29:46 +000016#include "llvm/CodeGen/ScheduleDAG.h"
Dan Gohmanf17a25c2007-07-18 16:29:46 +000017#include "llvm/Target/TargetMachine.h"
18#include "llvm/Target/TargetInstrInfo.h"
Dan Gohmanc3861152008-09-03 16:01:59 +000019#include "llvm/Target/TargetRegisterInfo.h"
Dan Gohmanf17a25c2007-07-18 16:29:46 +000020#include "llvm/Support/Debug.h"
Dan Gohman60e43792008-11-19 21:32:03 +000021#include "llvm/Support/raw_ostream.h"
Dan Gohmanf17a25c2007-07-18 16:29:46 +000022using namespace llvm;
23
Dan Gohman96c2ad22008-11-13 21:21:28 +000024ScheduleDAG::ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb,
Chris Lattner1b989192007-12-31 04:13:23 +000025 const TargetMachine &tm)
Evan Cheng8725a112008-03-12 22:19:41 +000026 : DAG(dag), BB(bb), TM(tm), MRI(BB->getParent()->getRegInfo()) {
Evan Cheng19da42d2008-04-03 16:36:07 +000027 TII = TM.getInstrInfo();
Dan Gohmanfa603902008-11-11 21:31:56 +000028 MF = BB->getParent();
Evan Cheng19da42d2008-04-03 16:36:07 +000029 TRI = TM.getRegisterInfo();
Dan Gohmanfa603902008-11-11 21:31:56 +000030 TLI = TM.getTargetLowering();
31 ConstPool = MF->getConstantPool();
Chris Lattner1b989192007-12-31 04:13:23 +000032}
Evan Cheng93f143e2007-09-25 01:54:36 +000033
Evan Cheng93f143e2007-09-25 01:54:36 +000034/// CheckForPhysRegDependency - Check if the dependency between def and use of
35/// a specified operand is a physical register dependency. If so, returns the
36/// register and the cost of copying the register.
Dan Gohman0c97f1d2008-07-27 20:43:25 +000037static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
Dan Gohman1e57df32008-02-10 18:45:23 +000038 const TargetRegisterInfo *TRI,
Evan Cheng93f143e2007-09-25 01:54:36 +000039 const TargetInstrInfo *TII,
40 unsigned &PhysReg, int &Cost) {
Dan Gohman0c97f1d2008-07-27 20:43:25 +000041 if (Op != 2 || User->getOpcode() != ISD::CopyToReg)
Evan Cheng93f143e2007-09-25 01:54:36 +000042 return;
43
Dan Gohman0c97f1d2008-07-27 20:43:25 +000044 unsigned Reg = cast<RegisterSDNode>(User->getOperand(1))->getReg();
Dan Gohman1e57df32008-02-10 18:45:23 +000045 if (TargetRegisterInfo::isVirtualRegister(Reg))
Evan Cheng93f143e2007-09-25 01:54:36 +000046 return;
47
Gabor Greif46bf5472008-08-26 22:36:50 +000048 unsigned ResNo = User->getOperand(2).getResNo();
Dan Gohmanbd68c792008-07-17 19:10:17 +000049 if (Def->isMachineOpcode()) {
50 const TargetInstrDesc &II = TII->get(Def->getMachineOpcode());
Chris Lattner0c2a4f32008-01-07 03:13:06 +000051 if (ResNo >= II.getNumDefs() &&
52 II.ImplicitDefs[ResNo - II.getNumDefs()] == Reg) {
Evan Cheng93f143e2007-09-25 01:54:36 +000053 PhysReg = Reg;
54 const TargetRegisterClass *RC =
Evan Cheng14cc83f2008-03-11 07:19:34 +000055 TRI->getPhysicalRegisterRegClass(Reg, Def->getValueType(ResNo));
Evan Cheng93f143e2007-09-25 01:54:36 +000056 Cost = RC->getCopyCost();
57 }
58 }
59}
60
61SUnit *ScheduleDAG::Clone(SUnit *Old) {
Dan Gohmanf26ca4b2008-11-13 21:36:12 +000062 SUnit *SU = NewSUnit(Old->getNode());
Dan Gohmanab162912008-06-21 15:52:51 +000063 SU->OrigNode = Old->OrigNode;
Evan Cheng93f143e2007-09-25 01:54:36 +000064 SU->Latency = Old->Latency;
65 SU->isTwoAddress = Old->isTwoAddress;
66 SU->isCommutable = Old->isCommutable;
Evan Chengba597da2007-09-28 22:32:30 +000067 SU->hasPhysRegDefs = Old->hasPhysRegDefs;
Evan Cheng93f143e2007-09-25 01:54:36 +000068 return SU;
69}
70
Evan Chengdd3f8b92007-10-05 01:39:18 +000071
Dan Gohmanf17a25c2007-07-18 16:29:46 +000072/// BuildSchedUnits - Build SUnits from the selection dag that we are input.
73/// This SUnit graph is similar to the SelectionDAG, but represents flagged
74/// together nodes with a single SUnit.
75void ScheduleDAG::BuildSchedUnits() {
Dan Gohmancd414582008-11-14 21:47:58 +000076 // For post-regalloc scheduling, build the SUnits from the MachineInstrs
77 // in the MachineBasicBlock.
78 if (!DAG) {
79 BuildSchedUnitsFromMBB();
80 return;
81 }
82
Dan Gohmanf17a25c2007-07-18 16:29:46 +000083 // Reserve entries in the vector for each of the SUnits we are creating. This
84 // ensure that reallocation of the vector won't happen, so SUnit*'s won't get
85 // invalidated.
Dan Gohman96c2ad22008-11-13 21:21:28 +000086 SUnits.reserve(DAG->allnodes_size());
Dan Gohmanf17a25c2007-07-18 16:29:46 +000087
Dan Gohman018d7b72008-06-21 19:18:17 +000088 // During scheduling, the NodeId field of SDNode is used to map SDNodes
89 // to their associated SUnits by holding SUnits table indices. A value
90 // of -1 means the SDNode does not yet have an associated SUnit.
Dan Gohman96c2ad22008-11-13 21:21:28 +000091 for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(),
92 E = DAG->allnodes_end(); NI != E; ++NI)
Dan Gohman018d7b72008-06-21 19:18:17 +000093 NI->setNodeId(-1);
94
Dan Gohman96c2ad22008-11-13 21:21:28 +000095 for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(),
96 E = DAG->allnodes_end(); NI != E; ++NI) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +000097 if (isPassiveNode(NI)) // Leaf node, e.g. a TargetImmediate.
98 continue;
99
100 // If this node has already been processed, stop now.
Dan Gohman018d7b72008-06-21 19:18:17 +0000101 if (NI->getNodeId() != -1) continue;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000102
103 SUnit *NodeSUnit = NewSUnit(NI);
104
105 // See if anything is flagged to this node, if so, add them to flagged
106 // nodes. Nodes can have at most one flag input and one flag output. Flags
107 // are required the be the last operand and result of a node.
108
Dan Gohman40ae0f02008-11-13 23:24:17 +0000109 // Scan up to find flagged preds.
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000110 SDNode *N = NI;
111 if (N->getNumOperands() &&
112 N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) {
113 do {
Gabor Greif1c80d112008-08-28 21:40:38 +0000114 N = N->getOperand(N->getNumOperands()-1).getNode();
Dan Gohman018d7b72008-06-21 19:18:17 +0000115 assert(N->getNodeId() == -1 && "Node already inserted!");
116 N->setNodeId(NodeSUnit->NodeNum);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000117 } while (N->getNumOperands() &&
118 N->getOperand(N->getNumOperands()-1).getValueType()== MVT::Flag);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000119 }
120
Dan Gohman40ae0f02008-11-13 23:24:17 +0000121 // Scan down to find any flagged succs.
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000122 N = NI;
123 while (N->getValueType(N->getNumValues()-1) == MVT::Flag) {
Dan Gohman8181bd12008-07-27 21:46:04 +0000124 SDValue FlagVal(N, N->getNumValues()-1);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000125
126 // There are either zero or one users of the Flag result.
127 bool HasFlagUse = false;
128 for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end();
129 UI != E; ++UI)
Dan Gohman0c97f1d2008-07-27 20:43:25 +0000130 if (FlagVal.isOperandOf(*UI)) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000131 HasFlagUse = true;
Dan Gohman018d7b72008-06-21 19:18:17 +0000132 assert(N->getNodeId() == -1 && "Node already inserted!");
133 N->setNodeId(NodeSUnit->NodeNum);
Dan Gohman0c97f1d2008-07-27 20:43:25 +0000134 N = *UI;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000135 break;
136 }
137 if (!HasFlagUse) break;
138 }
139
Dan Gohman40ae0f02008-11-13 23:24:17 +0000140 // If there are flag operands involved, N is now the bottom-most node
141 // of the sequence of nodes that are flagged together.
142 // Update the SUnit.
Dan Gohmanf26ca4b2008-11-13 21:36:12 +0000143 NodeSUnit->setNode(N);
Dan Gohman018d7b72008-06-21 19:18:17 +0000144 assert(N->getNodeId() == -1 && "Node already inserted!");
145 N->setNodeId(NodeSUnit->NodeNum);
Evan Chengdd3f8b92007-10-05 01:39:18 +0000146
147 ComputeLatency(NodeSUnit);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000148 }
149
150 // Pass 2: add the preds, succs, etc.
151 for (unsigned su = 0, e = SUnits.size(); su != e; ++su) {
152 SUnit *SU = &SUnits[su];
Dan Gohmanf26ca4b2008-11-13 21:36:12 +0000153 SDNode *MainNode = SU->getNode();
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000154
Dan Gohmanbd68c792008-07-17 19:10:17 +0000155 if (MainNode->isMachineOpcode()) {
156 unsigned Opc = MainNode->getMachineOpcode();
Chris Lattner5b930372008-01-07 07:27:27 +0000157 const TargetInstrDesc &TID = TII->get(Opc);
Chris Lattner0c2a4f32008-01-07 03:13:06 +0000158 for (unsigned i = 0; i != TID.getNumOperands(); ++i) {
Evan Cheng93f143e2007-09-25 01:54:36 +0000159 if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000160 SU->isTwoAddress = true;
161 break;
162 }
163 }
Chris Lattnerd8529ab2008-01-07 06:42:05 +0000164 if (TID.isCommutable())
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000165 SU->isCommutable = true;
166 }
167
168 // Find all predecessors and successors of the group.
Dan Gohman40ae0f02008-11-13 23:24:17 +0000169 for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) {
Dan Gohmanbd68c792008-07-17 19:10:17 +0000170 if (N->isMachineOpcode() &&
171 TII->get(N->getMachineOpcode()).getImplicitDefs() &&
172 CountResults(N) > TII->get(N->getMachineOpcode()).getNumDefs())
Evan Chengba597da2007-09-28 22:32:30 +0000173 SU->hasPhysRegDefs = true;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000174
175 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
Gabor Greif1c80d112008-08-28 21:40:38 +0000176 SDNode *OpN = N->getOperand(i).getNode();
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000177 if (isPassiveNode(OpN)) continue; // Not scheduled.
Dan Gohman018d7b72008-06-21 19:18:17 +0000178 SUnit *OpSU = &SUnits[OpN->getNodeId()];
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000179 assert(OpSU && "Node has no SUnit!");
180 if (OpSU == SU) continue; // In the same group.
181
Duncan Sands92c43912008-06-06 12:08:01 +0000182 MVT OpVT = N->getOperand(i).getValueType();
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000183 assert(OpVT != MVT::Flag && "Flagged nodes should be in same sunit!");
184 bool isChain = OpVT == MVT::Other;
Evan Cheng93f143e2007-09-25 01:54:36 +0000185
186 unsigned PhysReg = 0;
187 int Cost = 1;
188 // Determine if this is a physical register dependency.
Dan Gohman1e57df32008-02-10 18:45:23 +0000189 CheckForPhysRegDependency(OpN, N, i, TRI, TII, PhysReg, Cost);
Evan Cheng93f143e2007-09-25 01:54:36 +0000190 SU->addPred(OpSU, isChain, false, PhysReg, Cost);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000191 }
192 }
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000193 }
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000194}
195
Dan Gohmancd414582008-11-14 21:47:58 +0000196void ScheduleDAG::BuildSchedUnitsFromMBB() {
197 SUnits.clear();
198 SUnits.reserve(BB->size());
199
200 std::vector<SUnit *> PendingLoads;
201 SUnit *Terminator = 0;
202 SUnit *Chain = 0;
203 SUnit *Defs[TargetRegisterInfo::FirstVirtualRegister] = {};
204 std::vector<SUnit *> Uses[TargetRegisterInfo::FirstVirtualRegister] = {};
205 int Cost = 1; // FIXME
206
207 for (MachineBasicBlock::iterator MII = BB->end(), MIE = BB->begin();
208 MII != MIE; --MII) {
209 MachineInstr *MI = prior(MII);
210 SUnit *SU = NewSUnit(MI);
211
212 for (unsigned j = 0, n = MI->getNumOperands(); j != n; ++j) {
213 const MachineOperand &MO = MI->getOperand(j);
214 if (!MO.isReg()) continue;
215 unsigned Reg = MO.getReg();
216 if (Reg == 0) continue;
217
218 assert(TRI->isPhysicalRegister(Reg) && "Virtual register encountered!");
219 std::vector<SUnit *> &UseList = Uses[Reg];
220 SUnit *&Def = Defs[Reg];
221 // Optionally add output and anti dependences
222 if (Def && Def != SU)
223 Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false,
224 /*PhyReg=*/Reg, Cost);
225 for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
226 SUnit *&Def = Defs[*Alias];
227 if (Def && Def != SU)
228 Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false,
229 /*PhyReg=*/*Alias, Cost);
230 }
231
232 if (MO.isDef()) {
233 // Add any data dependencies.
234 for (unsigned i = 0, e = UseList.size(); i != e; ++i)
235 if (UseList[i] != SU)
236 UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false,
237 /*PhysReg=*/Reg, Cost);
238 for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
239 std::vector<SUnit *> &UseList = Uses[*Alias];
240 for (unsigned i = 0, e = UseList.size(); i != e; ++i)
241 if (UseList[i] != SU)
242 UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false,
243 /*PhysReg=*/*Alias, Cost);
244 }
245
246 UseList.clear();
247 Def = SU;
248 } else {
249 UseList.push_back(SU);
250 }
251 }
252 bool False = false;
253 bool True = true;
254 if (!MI->isSafeToMove(TII, False)) {
255 if (Chain)
256 Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
257 for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k)
258 PendingLoads[k]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
259 PendingLoads.clear();
260 Chain = SU;
261 } else if (!MI->isSafeToMove(TII, True)) {
262 if (Chain)
263 Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
264 PendingLoads.push_back(SU);
265 }
266 if (Terminator && SU->Succs.empty())
267 Terminator->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
268 if (MI->getDesc().isTerminator())
269 Terminator = SU;
270 }
271}
272
Evan Chengdd3f8b92007-10-05 01:39:18 +0000273void ScheduleDAG::ComputeLatency(SUnit *SU) {
274 const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
275
276 // Compute the latency for the node. We use the sum of the latencies for
277 // all nodes flagged together into this SUnit.
278 if (InstrItins.isEmpty()) {
279 // No latency information.
280 SU->Latency = 1;
Evan Chengf2639ba2008-07-02 09:23:51 +0000281 return;
282 }
283
284 SU->Latency = 0;
Dan Gohman40ae0f02008-11-13 23:24:17 +0000285 for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) {
286 if (N->isMachineOpcode()) {
287 unsigned SchedClass = TII->get(N->getMachineOpcode()).getSchedClass();
Dan Gohman12300e12008-03-25 21:45:14 +0000288 const InstrStage *S = InstrItins.begin(SchedClass);
289 const InstrStage *E = InstrItins.end(SchedClass);
Evan Chengdd3f8b92007-10-05 01:39:18 +0000290 for (; S != E; ++S)
291 SU->Latency += S->Cycles;
292 }
Evan Chengdd3f8b92007-10-05 01:39:18 +0000293 }
294}
295
Roman Levenstein1db9b822008-03-04 11:19:43 +0000296/// CalculateDepths - compute depths using algorithms for the longest
297/// paths in the DAG
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000298void ScheduleDAG::CalculateDepths() {
Roman Levenstein1db9b822008-03-04 11:19:43 +0000299 unsigned DAGSize = SUnits.size();
Roman Levenstein1db9b822008-03-04 11:19:43 +0000300 std::vector<SUnit*> WorkList;
301 WorkList.reserve(DAGSize);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000302
Roman Levenstein1db9b822008-03-04 11:19:43 +0000303 // Initialize the data structures
304 for (unsigned i = 0, e = DAGSize; i != e; ++i) {
305 SUnit *SU = &SUnits[i];
Roman Levenstein1db9b822008-03-04 11:19:43 +0000306 unsigned Degree = SU->Preds.size();
Dan Gohman4c43d5a2008-08-27 16:27:25 +0000307 // Temporarily use the Depth field as scratch space for the degree count.
308 SU->Depth = Degree;
Roman Levenstein1db9b822008-03-04 11:19:43 +0000309
310 // Is it a node without dependencies?
311 if (Degree == 0) {
312 assert(SU->Preds.empty() && "SUnit should have no predecessors");
313 // Collect leaf nodes
314 WorkList.push_back(SU);
315 }
316 }
317
318 // Process nodes in the topological order
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000319 while (!WorkList.empty()) {
Roman Levenstein1db9b822008-03-04 11:19:43 +0000320 SUnit *SU = WorkList.back();
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000321 WorkList.pop_back();
Dan Gohman4c43d5a2008-08-27 16:27:25 +0000322 unsigned SUDepth = 0;
Roman Levenstein1db9b822008-03-04 11:19:43 +0000323
324 // Use dynamic programming:
325 // When current node is being processed, all of its dependencies
326 // are already processed.
327 // So, just iterate over all predecessors and take the longest path
328 for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
329 I != E; ++I) {
330 unsigned PredDepth = I->Dep->Depth;
331 if (PredDepth+1 > SUDepth) {
332 SUDepth = PredDepth + 1;
333 }
334 }
335
Dan Gohman4c43d5a2008-08-27 16:27:25 +0000336 SU->Depth = SUDepth;
337
338 // Update degrees of all nodes depending on current SUnit
Roman Levenstein1db9b822008-03-04 11:19:43 +0000339 for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
340 I != E; ++I) {
341 SUnit *SU = I->Dep;
Dan Gohman4c43d5a2008-08-27 16:27:25 +0000342 if (!--SU->Depth)
Roman Levenstein1db9b822008-03-04 11:19:43 +0000343 // If all dependencies of the node are processed already,
344 // then the longest path for the node can be computed now
345 WorkList.push_back(SU);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000346 }
347 }
348}
349
Roman Levenstein1db9b822008-03-04 11:19:43 +0000350/// CalculateHeights - compute heights using algorithms for the longest
351/// paths in the DAG
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000352void ScheduleDAG::CalculateHeights() {
Roman Levenstein1db9b822008-03-04 11:19:43 +0000353 unsigned DAGSize = SUnits.size();
Roman Levenstein1db9b822008-03-04 11:19:43 +0000354 std::vector<SUnit*> WorkList;
355 WorkList.reserve(DAGSize);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000356
Roman Levenstein1db9b822008-03-04 11:19:43 +0000357 // Initialize the data structures
358 for (unsigned i = 0, e = DAGSize; i != e; ++i) {
359 SUnit *SU = &SUnits[i];
Roman Levenstein1db9b822008-03-04 11:19:43 +0000360 unsigned Degree = SU->Succs.size();
Dan Gohman4c43d5a2008-08-27 16:27:25 +0000361 // Temporarily use the Height field as scratch space for the degree count.
362 SU->Height = Degree;
Roman Levenstein1db9b822008-03-04 11:19:43 +0000363
364 // Is it a node without dependencies?
365 if (Degree == 0) {
366 assert(SU->Succs.empty() && "Something wrong");
367 assert(WorkList.empty() && "Should be empty");
368 // Collect leaf nodes
369 WorkList.push_back(SU);
370 }
371 }
372
373 // Process nodes in the topological order
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000374 while (!WorkList.empty()) {
Roman Levenstein1db9b822008-03-04 11:19:43 +0000375 SUnit *SU = WorkList.back();
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000376 WorkList.pop_back();
Dan Gohman4c43d5a2008-08-27 16:27:25 +0000377 unsigned SUHeight = 0;
Roman Levenstein1db9b822008-03-04 11:19:43 +0000378
379 // Use dynamic programming:
380 // When current node is being processed, all of its dependencies
381 // are already processed.
382 // So, just iterate over all successors and take the longest path
383 for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
384 I != E; ++I) {
385 unsigned SuccHeight = I->Dep->Height;
386 if (SuccHeight+1 > SUHeight) {
387 SUHeight = SuccHeight + 1;
388 }
389 }
390
Dan Gohman4c43d5a2008-08-27 16:27:25 +0000391 SU->Height = SUHeight;
392
393 // Update degrees of all nodes depending on current SUnit
Roman Levenstein1db9b822008-03-04 11:19:43 +0000394 for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
395 I != E; ++I) {
396 SUnit *SU = I->Dep;
Dan Gohman4c43d5a2008-08-27 16:27:25 +0000397 if (!--SU->Height)
Roman Levenstein1db9b822008-03-04 11:19:43 +0000398 // If all dependencies of the node are processed already,
399 // then the longest path for the node can be computed now
400 WorkList.push_back(SU);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000401 }
402 }
403}
404
405/// CountResults - The results of target nodes have register or immediate
406/// operands first, then an optional chain, and optional flag operands (which do
Dan Gohman0256f1e2008-02-11 19:00:03 +0000407/// not go into the resulting MachineInstr).
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000408unsigned ScheduleDAG::CountResults(SDNode *Node) {
409 unsigned N = Node->getNumValues();
410 while (N && Node->getValueType(N - 1) == MVT::Flag)
411 --N;
412 if (N && Node->getValueType(N - 1) == MVT::Other)
413 --N; // Skip over chain result.
414 return N;
415}
416
Dan Gohman12a9c082008-02-06 22:27:42 +0000417/// CountOperands - The inputs to target nodes have any actual inputs first,
Dan Gohmance256462008-02-16 00:36:48 +0000418/// followed by special operands that describe memory references, then an
Dan Gohmanf175ade2008-10-25 17:51:24 +0000419/// optional chain operand, then an optional flag operand. Compute the number
420/// of actual operands that will go into the resulting MachineInstr.
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000421unsigned ScheduleDAG::CountOperands(SDNode *Node) {
Dan Gohmance256462008-02-16 00:36:48 +0000422 unsigned N = ComputeMemOperandsEnd(Node);
Gabor Greif1c80d112008-08-28 21:40:38 +0000423 while (N && isa<MemOperandSDNode>(Node->getOperand(N - 1).getNode()))
Dan Gohman1fad9e62008-04-07 19:35:22 +0000424 --N; // Ignore MEMOPERAND nodes
Dan Gohman12a9c082008-02-06 22:27:42 +0000425 return N;
426}
427
Dan Gohmance256462008-02-16 00:36:48 +0000428/// ComputeMemOperandsEnd - Find the index one past the last MemOperandSDNode
429/// operand
430unsigned ScheduleDAG::ComputeMemOperandsEnd(SDNode *Node) {
Dan Gohman12a9c082008-02-06 22:27:42 +0000431 unsigned N = Node->getNumOperands();
432 while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag)
433 --N;
434 if (N && Node->getOperand(N - 1).getValueType() == MVT::Other)
435 --N; // Ignore chain if it exists.
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000436 return N;
437}
438
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000439
440/// dump - dump the schedule.
441void ScheduleDAG::dumpSchedule() const {
442 for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
443 if (SUnit *SU = Sequence[i])
Dan Gohman2fd868d2008-11-18 02:06:40 +0000444 SU->dump(this);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000445 else
446 cerr << "**** NOOP ****\n";
447 }
448}
449
450
451/// Run - perform scheduling.
452///
Dan Gohman368a08b2008-07-14 18:19:29 +0000453void ScheduleDAG::Run() {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000454 Schedule();
Dan Gohman368a08b2008-07-14 18:19:29 +0000455
456 DOUT << "*** Final schedule ***\n";
457 DEBUG(dumpSchedule());
458 DOUT << "\n";
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000459}
460
461/// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
462/// a group of nodes flagged together.
Dan Gohman60e43792008-11-19 21:32:03 +0000463void SUnit::print(raw_ostream &O, const ScheduleDAG *G) const {
464 O << "SU(" << NodeNum << "): ";
Dan Gohmana52aeb92008-11-19 00:04:44 +0000465 if (getNode()) {
466 SmallVector<SDNode *, 4> FlaggedNodes;
467 for (SDNode *N = getNode(); N; N = N->getFlaggedNode())
468 FlaggedNodes.push_back(N);
469 while (!FlaggedNodes.empty()) {
Dan Gohman60e43792008-11-19 21:32:03 +0000470 O << " ";
Dan Gohmand7177102008-11-19 22:09:45 +0000471 FlaggedNodes.back()->print(O, G->DAG);
Dan Gohman60e43792008-11-19 21:32:03 +0000472 O << "\n";
Dan Gohmana52aeb92008-11-19 00:04:44 +0000473 FlaggedNodes.pop_back();
474 }
475 } else {
Dan Gohman60e43792008-11-19 21:32:03 +0000476 O << "CROSS RC COPY\n";
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000477 }
Dan Gohman60e43792008-11-19 21:32:03 +0000478}
479
480void SUnit::dump(const ScheduleDAG *G) const {
481 print(errs(), G);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000482}
483
Dan Gohman2fd868d2008-11-18 02:06:40 +0000484void SUnit::dumpAll(const ScheduleDAG *G) const {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000485 dump(G);
486
487 cerr << " # preds left : " << NumPredsLeft << "\n";
488 cerr << " # succs left : " << NumSuccsLeft << "\n";
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000489 cerr << " Latency : " << Latency << "\n";
490 cerr << " Depth : " << Depth << "\n";
491 cerr << " Height : " << Height << "\n";
492
493 if (Preds.size() != 0) {
494 cerr << " Predecessors:\n";
495 for (SUnit::const_succ_iterator I = Preds.begin(), E = Preds.end();
496 I != E; ++I) {
Evan Chenge7959472007-09-19 01:38:40 +0000497 if (I->isCtrl)
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000498 cerr << " ch #";
499 else
500 cerr << " val #";
Evan Cheng93f143e2007-09-25 01:54:36 +0000501 cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")";
502 if (I->isSpecial)
503 cerr << " *";
504 cerr << "\n";
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000505 }
506 }
507 if (Succs.size() != 0) {
508 cerr << " Successors:\n";
509 for (SUnit::const_succ_iterator I = Succs.begin(), E = Succs.end();
510 I != E; ++I) {
Evan Chenge7959472007-09-19 01:38:40 +0000511 if (I->isCtrl)
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000512 cerr << " ch #";
513 else
514 cerr << " val #";
Evan Cheng93f143e2007-09-25 01:54:36 +0000515 cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")";
516 if (I->isSpecial)
517 cerr << " *";
518 cerr << "\n";
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000519 }
520 }
521 cerr << "\n";
522}