blob: e6a8d13c2f5dce27f77701bb00e008e2e490444d [file] [log] [blame]
Dan Gohmand27a0e02008-11-19 23:18:57 +00001//===---- ScheduleDAG.cpp - Implement the ScheduleDAG class ---------------===//
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 implements the ScheduleDAG class, which is a base class used by
11// scheduling implementation classes.
12//
13//===----------------------------------------------------------------------===//
14
15#define DEBUG_TYPE "pre-RA-sched"
16#include "llvm/CodeGen/ScheduleDAG.h"
17#include "llvm/Target/TargetMachine.h"
18#include "llvm/Target/TargetInstrInfo.h"
19#include "llvm/Target/TargetRegisterInfo.h"
20#include "llvm/Support/Debug.h"
21using namespace llvm;
22
23ScheduleDAG::ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb,
24 const TargetMachine &tm)
25 : DAG(dag), BB(bb), TM(tm), MRI(BB->getParent()->getRegInfo()) {
26 TII = TM.getInstrInfo();
27 MF = BB->getParent();
28 TRI = TM.getRegisterInfo();
29 TLI = TM.getTargetLowering();
30 ConstPool = MF->getConstantPool();
31}
32
33ScheduleDAG::~ScheduleDAG() {}
34
35/// CalculateDepths - compute depths using algorithms for the longest
36/// paths in the DAG
37void ScheduleDAG::CalculateDepths() {
38 unsigned DAGSize = SUnits.size();
39 std::vector<SUnit*> WorkList;
40 WorkList.reserve(DAGSize);
41
42 // Initialize the data structures
43 for (unsigned i = 0, e = DAGSize; i != e; ++i) {
44 SUnit *SU = &SUnits[i];
45 unsigned Degree = SU->Preds.size();
46 // Temporarily use the Depth field as scratch space for the degree count.
47 SU->Depth = Degree;
48
49 // Is it a node without dependencies?
50 if (Degree == 0) {
51 assert(SU->Preds.empty() && "SUnit should have no predecessors");
52 // Collect leaf nodes
53 WorkList.push_back(SU);
54 }
55 }
56
57 // Process nodes in the topological order
58 while (!WorkList.empty()) {
59 SUnit *SU = WorkList.back();
60 WorkList.pop_back();
61 unsigned SUDepth = 0;
62
63 // Use dynamic programming:
64 // When current node is being processed, all of its dependencies
65 // are already processed.
66 // So, just iterate over all predecessors and take the longest path
67 for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
68 I != E; ++I) {
69 unsigned PredDepth = I->Dep->Depth;
70 if (PredDepth+1 > SUDepth) {
71 SUDepth = PredDepth + 1;
72 }
73 }
74
75 SU->Depth = SUDepth;
76
77 // Update degrees of all nodes depending on current SUnit
78 for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
79 I != E; ++I) {
80 SUnit *SU = I->Dep;
81 if (!--SU->Depth)
82 // If all dependencies of the node are processed already,
83 // then the longest path for the node can be computed now
84 WorkList.push_back(SU);
85 }
86 }
87}
88
89/// CalculateHeights - compute heights using algorithms for the longest
90/// paths in the DAG
91void ScheduleDAG::CalculateHeights() {
92 unsigned DAGSize = SUnits.size();
93 std::vector<SUnit*> WorkList;
94 WorkList.reserve(DAGSize);
95
96 // Initialize the data structures
97 for (unsigned i = 0, e = DAGSize; i != e; ++i) {
98 SUnit *SU = &SUnits[i];
99 unsigned Degree = SU->Succs.size();
100 // Temporarily use the Height field as scratch space for the degree count.
101 SU->Height = Degree;
102
103 // Is it a node without dependencies?
104 if (Degree == 0) {
105 assert(SU->Succs.empty() && "Something wrong");
106 assert(WorkList.empty() && "Should be empty");
107 // Collect leaf nodes
108 WorkList.push_back(SU);
109 }
110 }
111
112 // Process nodes in the topological order
113 while (!WorkList.empty()) {
114 SUnit *SU = WorkList.back();
115 WorkList.pop_back();
116 unsigned SUHeight = 0;
117
118 // Use dynamic programming:
119 // When current node is being processed, all of its dependencies
120 // are already processed.
121 // So, just iterate over all successors and take the longest path
122 for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
123 I != E; ++I) {
124 unsigned SuccHeight = I->Dep->Height;
125 if (SuccHeight+1 > SUHeight) {
126 SUHeight = SuccHeight + 1;
127 }
128 }
129
130 SU->Height = SUHeight;
131
132 // Update degrees of all nodes depending on current SUnit
133 for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
134 I != E; ++I) {
135 SUnit *SU = I->Dep;
136 if (!--SU->Height)
137 // If all dependencies of the node are processed already,
138 // then the longest path for the node can be computed now
139 WorkList.push_back(SU);
140 }
141 }
142}
143
144/// dump - dump the schedule.
145void ScheduleDAG::dumpSchedule() const {
146 for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
147 if (SUnit *SU = Sequence[i])
148 SU->dump(this);
149 else
150 cerr << "**** NOOP ****\n";
151 }
152}
153
154
155/// Run - perform scheduling.
156///
157void ScheduleDAG::Run() {
158 Schedule();
159
160 DOUT << "*** Final schedule ***\n";
161 DEBUG(dumpSchedule());
162 DOUT << "\n";
163}
164
165/// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
166/// a group of nodes flagged together.
167void SUnit::dump(const ScheduleDAG *G) const {
168 cerr << "SU(" << NodeNum << "): ";
169 G->dumpNode(this);
170}
171
172void SUnit::dumpAll(const ScheduleDAG *G) const {
173 dump(G);
174
175 cerr << " # preds left : " << NumPredsLeft << "\n";
176 cerr << " # succs left : " << NumSuccsLeft << "\n";
177 cerr << " Latency : " << Latency << "\n";
178 cerr << " Depth : " << Depth << "\n";
179 cerr << " Height : " << Height << "\n";
180
181 if (Preds.size() != 0) {
182 cerr << " Predecessors:\n";
183 for (SUnit::const_succ_iterator I = Preds.begin(), E = Preds.end();
184 I != E; ++I) {
185 if (I->isCtrl)
186 cerr << " ch #";
187 else
188 cerr << " val #";
189 cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")";
190 if (I->isSpecial)
191 cerr << " *";
192 cerr << "\n";
193 }
194 }
195 if (Succs.size() != 0) {
196 cerr << " Successors:\n";
197 for (SUnit::const_succ_iterator I = Succs.begin(), E = Succs.end();
198 I != E; ++I) {
199 if (I->isCtrl)
200 cerr << " ch #";
201 else
202 cerr << " val #";
203 cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")";
204 if (I->isSpecial)
205 cerr << " *";
206 cerr << "\n";
207 }
208 }
209 cerr << "\n";
210}