blob: a5db12f8fbec078297112116c33b4c214e9c339d [file] [log] [blame]
Misha Brukman8baa01c2003-04-09 21:51:34 +00001//===- ModuloSchedGraph.cpp - Graph datastructure for Modulo Scheduling ---===//
2//
3//
4//===----------------------------------------------------------------------===//
5
Guochun Shif1c154f2003-03-27 17:57:44 +00006#include "llvm/CodeGen/InstrSelection.h"
Guochun Shif1c154f2003-03-27 17:57:44 +00007#include "llvm/Function.h"
Misha Brukman8baa01c2003-04-09 21:51:34 +00008#include "llvm/Instructions.h"
Guochun Shif1c154f2003-03-27 17:57:44 +00009#include "llvm/Type.h"
10#include "llvm/CodeGen/MachineCodeForInstruction.h"
11#include "llvm/CodeGen/MachineInstr.h"
Guochun Shi6fbe5fb2003-04-06 23:56:19 +000012#include "llvm/Target/TargetSchedInfo.h"
Misha Brukman8baa01c2003-04-09 21:51:34 +000013#include "Support/StringExtras.h"
14#include "Support/STLExtras.h"
Misha Brukman2c821cc2003-04-10 19:19:23 +000015#include "Support/hash_map"
16#include "Support/Statistic.h"
17#include "ModuloScheduling.h"
Misha Brukman8baa01c2003-04-09 21:51:34 +000018#include "ModuloSchedGraph.h"
19#include <algorithm>
Misha Brukman2c821cc2003-04-10 19:19:23 +000020#include <ostream>
21#include <vector>
22
23// FIXME: Should be using #include <cmath>
Misha Brukman8baa01c2003-04-09 21:51:34 +000024#include <math.h>
25//#include <swig.h>
Guochun Shif1c154f2003-03-27 17:57:44 +000026
27#define UNIDELAY 1
Guochun Shif1c154f2003-03-27 17:57:44 +000028
Misha Brukman2c821cc2003-04-10 19:19:23 +000029
Guochun Shif1c154f2003-03-27 17:57:44 +000030//*********************** Internal Data Structures *************************/
31
32// The following two types need to be classes, not typedefs, so we can use
33// opaque declarations in SchedGraph.h
34//
Misha Brukman2c821cc2003-04-10 19:19:23 +000035struct RefVec:public std::vector<std::pair<ModuloSchedGraphNode*,int> > {
Misha Brukman8baa01c2003-04-09 21:51:34 +000036 typedef std::vector<std::pair<ModuloSchedGraphNode*,
37 int> >::iterator iterator;
38 typedef std::vector<std::pair<ModuloSchedGraphNode*,
39 int> >::const_iterator const_iterator;
Guochun Shif1c154f2003-03-27 17:57:44 +000040};
41
Misha Brukman2c821cc2003-04-10 19:19:23 +000042struct RegToRefVecMap:public hash_map<int,RefVec> {
43 typedef hash_map<int,RefVec>::iterator iterator;
44 typedef hash_map<int,RefVec>::const_iterator const_iterator;
Guochun Shif1c154f2003-03-27 17:57:44 +000045};
46
Misha Brukman2c821cc2003-04-10 19:19:23 +000047struct ValueToDefVecMap:public hash_map<const Instruction*,RefVec> {
48 typedef hash_map<const Instruction*, RefVec>::iterator iterator;
49 typedef hash_map<const Instruction*,
Misha Brukman8baa01c2003-04-09 21:51:34 +000050 RefVec>::const_iterator const_iterator;
Guochun Shif1c154f2003-03-27 17:57:44 +000051};
52
Guochun Shif1c154f2003-03-27 17:57:44 +000053// class Modulo SchedGraphNode
54
55/*ctor*/
56ModuloSchedGraphNode::ModuloSchedGraphNode(unsigned int _nodeId,
Misha Brukman8baa01c2003-04-09 21:51:34 +000057 const BasicBlock * _bb,
58 const Instruction * _inst,
59 int indexInBB,
60 const TargetMachine & target)
61:SchedGraphNodeCommon(_nodeId, _bb, indexInBB), inst(_inst)
Guochun Shif1c154f2003-03-27 17:57:44 +000062{
Misha Brukman8baa01c2003-04-09 21:51:34 +000063 if (inst) {
64 //FIXME: find the latency
65 //currently setthe latency to zero
66 latency = 0;
67 }
Guochun Shif1c154f2003-03-27 17:57:44 +000068}
Misha Brukman8baa01c2003-04-09 21:51:34 +000069
Guochun Shif1c154f2003-03-27 17:57:44 +000070//class ModuloScheGraph
71
Misha Brukman8baa01c2003-04-09 21:51:34 +000072void ModuloSchedGraph::addDummyEdges()
Guochun Shif1c154f2003-03-27 17:57:44 +000073{
74 assert(graphRoot->outEdges.size() == 0);
Misha Brukman8baa01c2003-04-09 21:51:34 +000075
76 for (const_iterator I = begin(); I != end(); ++I) {
77 ModuloSchedGraphNode *node = (ModuloSchedGraphNode *) ((*I).second);
78 assert(node != graphRoot && node != graphLeaf);
79 if (node->beginInEdges() == node->endInEdges())
80 (void) new SchedGraphEdge(graphRoot, node, SchedGraphEdge::CtrlDep,
81 SchedGraphEdge::NonDataDep, 0);
82 if (node->beginOutEdges() == node->endOutEdges())
83 (void) new SchedGraphEdge(node, graphLeaf, SchedGraphEdge::CtrlDep,
84 SchedGraphEdge::NonDataDep, 0);
85 }
Guochun Shif1c154f2003-03-27 17:57:44 +000086}
87
Misha Brukman8baa01c2003-04-09 21:51:34 +000088bool isDefinition(const Instruction *I)
Guochun Shif1c154f2003-03-27 17:57:44 +000089{
90 //if(TerminatorInst::classof(I)||FreeInst::classof(I) || StoreInst::classof(I) || CallInst::classof(I))
Misha Brukman8baa01c2003-04-09 21:51:34 +000091 if (!I->hasName())
Guochun Shif1c154f2003-03-27 17:57:44 +000092 return false;
93 else
94 return true;
95}
96
Misha Brukman8baa01c2003-04-09 21:51:34 +000097void ModuloSchedGraph::addDefUseEdges(const BasicBlock *bb)
Guochun Shif1c154f2003-03-27 17:57:44 +000098{
99 //collect def instructions, store them in vector
Guochun Shi6fbe5fb2003-04-06 23:56:19 +0000100 // const TargetInstrInfo& mii = target.getInstrInfo();
Misha Brukman8baa01c2003-04-09 21:51:34 +0000101 const TargetInstrInfo & mii = target.getInstrInfo();
102
103 typedef std::vector < ModuloSchedGraphNode * >DefVec;
Guochun Shif1c154f2003-03-27 17:57:44 +0000104 DefVec defVec;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000105
Guochun Shif1c154f2003-03-27 17:57:44 +0000106 //find those def instructions
Misha Brukman8baa01c2003-04-09 21:51:34 +0000107 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E; ++I) {
108 if (I->getType() != Type::VoidTy) {
109 defVec.push_back(this->getGraphNodeForInst(I));
110 }
111 }
112
113 for (unsigned int i = 0; i < defVec.size(); i++) {
114 for (Value::use_const_iterator I = defVec[i]->getInst()->use_begin();
115 I != defVec[i]->getInst()->use_end(); I++) {
116 //for each use of a def, add a flow edge from the def instruction to the ref instruction
117
118
119 const Instruction *value = defVec[i]->getInst();
120 Instruction *inst = (Instruction *) (*I);
121 ModuloSchedGraphNode *node = NULL;
122
123 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end();
124 I != E; ++I)
125 if ((const Instruction *) I == inst) {
126 node = (*this)[inst];
127 break;
128 }
129
130 assert(inst != NULL && " Use not an Instruction ?");
131
132 if (node == NULL) //inst is not an instruction in this block
Guochun Shif1c154f2003-03-27 17:57:44 +0000133 {
Misha Brukman8baa01c2003-04-09 21:51:34 +0000134 } else {
135 // Add a flow edge from the def instruction to the ref instruction
136
137 // self loop will not happen in SSA form
138 assert(defVec[i] != node && "same node?");
139
140 // This is a true dependence, so the delay is equal to the delay of the
141 // pred node.
142 int delay = 0;
143 MachineCodeForInstruction & tempMvec =
144 MachineCodeForInstruction::get(value);
145 for (unsigned j = 0; j < tempMvec.size(); j++) {
146 MachineInstr *temp = tempMvec[j];
147 //delay +=mii.minLatency(temp->getOpCode());
148 delay = std::max(delay, mii.minLatency(temp->getOpCode()));
149 }
150
151 SchedGraphEdge *trueEdge =
152 new SchedGraphEdge(defVec[i], node, value,
153 SchedGraphEdge::TrueDep, delay);
154
155 // if the ref instruction is before the def instrution
156 // then the def instruction must be a phi instruction
157 // add an anti-dependence edge to from the ref instruction to the def
158 // instruction
159 if (node->getOrigIndexInBB() < defVec[i]->getOrigIndexInBB()) {
160 assert(PHINode::classof(inst)
161 && "the ref instruction befre def is not PHINode?");
162 trueEdge->setIteDiff(1);
163 }
164
Guochun Shif1c154f2003-03-27 17:57:44 +0000165 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000166
Misha Brukman8baa01c2003-04-09 21:51:34 +0000167 }
168 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000169}
170
Misha Brukman8baa01c2003-04-09 21:51:34 +0000171void ModuloSchedGraph::addCDEdges(const BasicBlock * bb) {
172 // find the last instruction in the basic block
173 // see if it is an branch instruction.
174 // If yes, then add an edge from each node expcept the last node to the last
175 // node
176 const Instruction *inst = &(bb->back());
177 ModuloSchedGraphNode *lastNode = (*this)[inst];
178 if (TerminatorInst::classof(inst))
179 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E;
180 I++) {
181 if (inst != I) {
182 ModuloSchedGraphNode *node = (*this)[I];
183 //use latency of 0
184 (void) new SchedGraphEdge(node, lastNode, SchedGraphEdge::CtrlDep,
185 SchedGraphEdge::NonDataDep, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000186 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000187
188 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000189}
190
Misha Brukman8baa01c2003-04-09 21:51:34 +0000191static const int SG_LOAD_REF = 0;
Guochun Shif1c154f2003-03-27 17:57:44 +0000192static const int SG_STORE_REF = 1;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000193static const int SG_CALL_REF = 2;
Guochun Shif1c154f2003-03-27 17:57:44 +0000194
195static const unsigned int SG_DepOrderArray[][3] = {
Misha Brukman8baa01c2003-04-09 21:51:34 +0000196 {SchedGraphEdge::NonDataDep,
197 SchedGraphEdge::AntiDep,
198 SchedGraphEdge::AntiDep},
199 {SchedGraphEdge::TrueDep,
200 SchedGraphEdge::OutputDep,
201 SchedGraphEdge::TrueDep | SchedGraphEdge::OutputDep},
202 {SchedGraphEdge::TrueDep,
203 SchedGraphEdge::AntiDep | SchedGraphEdge::OutputDep,
204 SchedGraphEdge::TrueDep | SchedGraphEdge::AntiDep
205 | SchedGraphEdge::OutputDep}
Guochun Shif1c154f2003-03-27 17:57:44 +0000206};
207
208
209// Add a dependence edge between every pair of machine load/store/call
210// instructions, where at least one is a store or a call.
211// Use latency 1 just to ensure that memory operations are ordered;
212// latency does not otherwise matter (true dependences enforce that).
213//
Misha Brukman8baa01c2003-04-09 21:51:34 +0000214void ModuloSchedGraph::addMemEdges(const BasicBlock * bb) {
215
216 std::vector<ModuloSchedGraphNode*> memNodeVec;
Guochun Shif1c154f2003-03-27 17:57:44 +0000217
218 //construct the memNodeVec
Misha Brukman8baa01c2003-04-09 21:51:34 +0000219 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E; ++I) {
220 if (LoadInst::classof(I) || StoreInst::classof(I)
221 || CallInst::classof(I)) {
222 ModuloSchedGraphNode *node = (*this)[(const Instruction *) I];
223 memNodeVec.push_back(node);
224 }
225 }
226
Guochun Shif1c154f2003-03-27 17:57:44 +0000227 // Instructions in memNodeVec are in execution order within the basic block,
228 // so simply look at all pairs <memNodeVec[i], memNodeVec[j: j > i]>.
229 //
Misha Brukman8baa01c2003-04-09 21:51:34 +0000230 for (unsigned im = 0, NM = memNodeVec.size(); im < NM; im++) {
231 const Instruction *fromInst = memNodeVec[im]->getInst();
232 int fromType = CallInst::classof(fromInst) ? SG_CALL_REF
233 : LoadInst::classof(fromInst) ? SG_LOAD_REF : SG_STORE_REF;
234 for (unsigned jm = im + 1; jm < NM; jm++) {
235 const Instruction *toInst = memNodeVec[jm]->getInst();
236 int toType = CallInst::classof(toInst) ? SG_CALL_REF
237 : LoadInst::classof(toInst) ? SG_LOAD_REF : SG_STORE_REF;
238 if (fromType != SG_LOAD_REF || toType != SG_LOAD_REF) {
239 (void) new SchedGraphEdge(memNodeVec[im], memNodeVec[jm],
240 SchedGraphEdge::MemoryDep,
241 SG_DepOrderArray[fromType][toType], 1);
242
243 SchedGraphEdge *edge =
244 new SchedGraphEdge(memNodeVec[jm], memNodeVec[im],
245 SchedGraphEdge::MemoryDep,
246 SG_DepOrderArray[toType][fromType], 1);
247 edge->setIteDiff(1);
248
249 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000250 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000251 }
252}
Guochun Shif1c154f2003-03-27 17:57:44 +0000253
254
255
Misha Brukman8baa01c2003-04-09 21:51:34 +0000256void ModuloSchedGraph::buildNodesforBB(const TargetMachine &target,
257 const BasicBlock *bb,
258 std::vector<ModuloSchedGraphNode*> &memNode,
259 RegToRefVecMap &regToRefVecMap,
260 ValueToDefVecMap &valueToDefVecMap)
Guochun Shif1c154f2003-03-27 17:57:44 +0000261{
Guochun Shi6fbe5fb2003-04-06 23:56:19 +0000262 //const TargetInstrInfo& mii=target.getInstrInfo();
Misha Brukman8baa01c2003-04-09 21:51:34 +0000263
Guochun Shif1c154f2003-03-27 17:57:44 +0000264 //Build graph nodes for each LLVM instruction and gather def/use info.
265 //Do both together in a single pass over all machine instructions.
Misha Brukman8baa01c2003-04-09 21:51:34 +0000266
267 int i = 0;
268 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E;
269 ++I) {
270 ModuloSchedGraphNode *node =
271 new ModuloSchedGraphNode(getNumNodes(), bb, I, i, target);
272 i++;
273 this->noteModuloSchedGraphNodeForInst(I, node);
274 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000275
276 //this function finds some info about instruction in basic block for later use
Misha Brukman8baa01c2003-04-09 21:51:34 +0000277 //findDefUseInfoAtInstr(target, node,
278 //memNode,regToRefVecMap,valueToDefVecMap);
Guochun Shif1c154f2003-03-27 17:57:44 +0000279}
280
281
Misha Brukman8baa01c2003-04-09 21:51:34 +0000282bool ModuloSchedGraph::isLoop(const BasicBlock *bb) {
Guochun Shif1c154f2003-03-27 17:57:44 +0000283 //only if the last instruction in the basicblock is branch instruction and
284 //there is at least an option to branch itself
285
Misha Brukman8baa01c2003-04-09 21:51:34 +0000286 const Instruction *inst = &(bb->back());
287 if (BranchInst::classof(inst)) {
288 for (unsigned i = 0; i < ((BranchInst *) inst)->getNumSuccessors();
289 i++) {
290 BasicBlock *sb = ((BranchInst *) inst)->getSuccessor(i);
291 if (sb == bb)
292 return true;
293 }
294 }
295
Guochun Shif1c154f2003-03-27 17:57:44 +0000296 return false;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000297
Guochun Shif1c154f2003-03-27 17:57:44 +0000298}
Misha Brukman8baa01c2003-04-09 21:51:34 +0000299
300bool ModuloSchedGraph::isLoop() {
Guochun Shif1c154f2003-03-27 17:57:44 +0000301 //only if the last instruction in the basicblock is branch instruction and
302 //there is at least an option to branch itself
Guochun Shif1c154f2003-03-27 17:57:44 +0000303
Misha Brukman8baa01c2003-04-09 21:51:34 +0000304 assert(bbVec.size() == 1 && "only 1 basicblock in a graph");
305 const BasicBlock *bb = bbVec[0];
306 const Instruction *inst = &(bb->back());
307 if (BranchInst::classof(inst))
308 for (unsigned i = 0; i < ((BranchInst *) inst)->getNumSuccessors();
309 i++) {
310 BasicBlock *sb = ((BranchInst *) inst)->getSuccessor(i);
311 if (sb == bb)
312 return true;
Guochun Shif1c154f2003-03-27 17:57:44 +0000313 }
314
Misha Brukman8baa01c2003-04-09 21:51:34 +0000315 return false;
316
317}
318
319void ModuloSchedGraph::computeNodeASAP(const BasicBlock *bb) {
320
321 //FIXME: now assume the only backward edges come from the edges from other
322 //nodes to the phi Node so i will ignore all edges to the phi node; after
323 //this, there shall be no recurrence.
324
325 unsigned numNodes = bb->size();
326 for (unsigned i = 2; i < numNodes + 2; i++) {
327 ModuloSchedGraphNode *node = getNode(i);
328 node->setPropertyComputed(false);
329 }
330
331 for (unsigned i = 2; i < numNodes + 2; i++) {
332 ModuloSchedGraphNode *node = getNode(i);
333 node->ASAP = 0;
334 if (i == 2 || node->getNumInEdges() == 0) {
Guochun Shif1c154f2003-03-27 17:57:44 +0000335 node->setPropertyComputed(true);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000336 continue;
Guochun Shif1c154f2003-03-27 17:57:44 +0000337 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000338 for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E =
339 node->endInEdges(); I != E; I++) {
340 SchedGraphEdge *edge = *I;
341 ModuloSchedGraphNode *pred =
342 (ModuloSchedGraphNode *) (edge->getSrc());
343 assert(pred->getPropertyComputed()
344 && "pred node property is not computed!");
345 int temp =
346 pred->ASAP + edge->getMinDelay() -
347 edge->getIteDiff() * this->MII;
348 node->ASAP = std::max(node->ASAP, temp);
349 }
350 node->setPropertyComputed(true);
351 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000352}
353
Misha Brukman8baa01c2003-04-09 21:51:34 +0000354void ModuloSchedGraph::computeNodeALAP(const BasicBlock *bb) {
355 unsigned numNodes = bb->size();
356 int maxASAP = 0;
357 for (unsigned i = numNodes + 1; i >= 2; i--) {
358 ModuloSchedGraphNode *node = getNode(i);
359 node->setPropertyComputed(false);
360 //cerr<< " maxASAP= " <<maxASAP<<" node->ASAP= "<< node->ASAP<<"\n";
361 maxASAP = std::max(maxASAP, node->ASAP);
362 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000363
364 //cerr<<"maxASAP is "<<maxASAP<<"\n";
Misha Brukman8baa01c2003-04-09 21:51:34 +0000365
366 for (unsigned i = numNodes + 1; i >= 2; i--) {
367 ModuloSchedGraphNode *node = getNode(i);
368 node->ALAP = maxASAP;
369 for (ModuloSchedGraphNode::const_iterator I =
370 node->beginOutEdges(), E = node->endOutEdges(); I != E; I++) {
371 SchedGraphEdge *edge = *I;
372 ModuloSchedGraphNode *succ =
373 (ModuloSchedGraphNode *) (edge->getSink());
374 if (PHINode::classof(succ->getInst()))
375 continue;
376 assert(succ->getPropertyComputed()
377 && "succ node property is not computed!");
378 int temp =
379 succ->ALAP - edge->getMinDelay() +
380 edge->getIteDiff() * this->MII;
381 node->ALAP = std::min(node->ALAP, temp);
382 }
383 node->setPropertyComputed(true);
384 }
385}
386
387void ModuloSchedGraph::computeNodeMov(const BasicBlock *bb)
388{
389 unsigned numNodes = bb->size();
390 for (unsigned i = 2; i < numNodes + 2; i++) {
391 ModuloSchedGraphNode *node = getNode(i);
392 node->mov = node->ALAP - node->ASAP;
393 assert(node->mov >= 0
394 && "move freedom for this node is less than zero? ");
395 }
396}
397
398
399void ModuloSchedGraph::computeNodeDepth(const BasicBlock * bb)
400{
401
402 unsigned numNodes = bb->size();
403 for (unsigned i = 2; i < numNodes + 2; i++) {
404 ModuloSchedGraphNode *node = getNode(i);
405 node->setPropertyComputed(false);
406 }
407
408 for (unsigned i = 2; i < numNodes + 2; i++) {
409 ModuloSchedGraphNode *node = getNode(i);
410 node->depth = 0;
411 if (i == 2 || node->getNumInEdges() == 0) {
Guochun Shif1c154f2003-03-27 17:57:44 +0000412 node->setPropertyComputed(true);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000413 continue;
Guochun Shif1c154f2003-03-27 17:57:44 +0000414 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000415 for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E =
416 node->endInEdges(); I != E; I++) {
417 SchedGraphEdge *edge = *I;
418 ModuloSchedGraphNode *pred =
419 (ModuloSchedGraphNode *) (edge->getSrc());
420 assert(pred->getPropertyComputed()
421 && "pred node property is not computed!");
422 int temp = pred->depth + edge->getMinDelay();
423 node->depth = std::max(node->depth, temp);
Guochun Shif1c154f2003-03-27 17:57:44 +0000424 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000425 node->setPropertyComputed(true);
426 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000427
428}
429
430
Misha Brukman8baa01c2003-04-09 21:51:34 +0000431void ModuloSchedGraph::computeNodeHeight(const BasicBlock *bb)
Guochun Shif1c154f2003-03-27 17:57:44 +0000432{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000433 unsigned numNodes = bb->size();
434 for (unsigned i = numNodes + 1; i >= 2; i--) {
435 ModuloSchedGraphNode *node = getNode(i);
436 node->setPropertyComputed(false);
437 }
438
439 for (unsigned i = numNodes + 1; i >= 2; i--) {
440 ModuloSchedGraphNode *node = getNode(i);
441 node->height = 0;
442 for (ModuloSchedGraphNode::const_iterator I =
443 node->beginOutEdges(), E = node->endOutEdges(); I != E; ++I) {
444 SchedGraphEdge *edge = *I;
445 ModuloSchedGraphNode *succ =
446 (ModuloSchedGraphNode *) (edge->getSink());
447 if (PHINode::classof(succ->getInst()))
448 continue;
449 assert(succ->getPropertyComputed()
450 && "succ node property is not computed!");
451 node->height = std::max(node->height, succ->height + edge->getMinDelay());
452
Guochun Shif1c154f2003-03-27 17:57:44 +0000453 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000454 node->setPropertyComputed(true);
455
456 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000457
458}
459
Misha Brukman8baa01c2003-04-09 21:51:34 +0000460void ModuloSchedGraph::computeNodeProperty(const BasicBlock * bb)
Guochun Shif1c154f2003-03-27 17:57:44 +0000461{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000462 //FIXME: now assume the only backward edges come from the edges from other
463 //nodes to the phi Node so i will ignore all edges to the phi node; after
464 //this, there shall be no recurrence.
465
Guochun Shif1c154f2003-03-27 17:57:44 +0000466 this->computeNodeASAP(bb);
467 this->computeNodeALAP(bb);
468 this->computeNodeMov(bb);
469 this->computeNodeDepth(bb);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000470 this->computeNodeHeight(bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000471}
472
473
474//do not consider the backedge in these two functions:
475// i.e. don't consider the edge with destination in phi node
Misha Brukman8baa01c2003-04-09 21:51:34 +0000476std::vector<ModuloSchedGraphNode*>
477ModuloSchedGraph::predSet(std::vector<ModuloSchedGraphNode*> set,
478 unsigned backEdgeSrc,
479 unsigned
480 backEdgeSink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000481{
482 std::vector<ModuloSchedGraphNode*> predS;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000483 for (unsigned i = 0; i < set.size(); i++) {
484 ModuloSchedGraphNode *node = set[i];
485 for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E =
486 node->endInEdges(); I != E; I++) {
487 SchedGraphEdge *edge = *I;
488 if (edge->getSrc()->getNodeId() == backEdgeSrc
489 && edge->getSink()->getNodeId() == backEdgeSink)
490 continue;
491 ModuloSchedGraphNode *pred =
492 (ModuloSchedGraphNode *) (edge->getSrc());
493 //if pred is not in the predSet, push it in vector
494 bool alreadyInset = false;
495 for (unsigned j = 0; j < predS.size(); ++j)
496 if (predS[j]->getNodeId() == pred->getNodeId()) {
497 alreadyInset = true;
498 break;
499 }
500
501 for (unsigned j = 0; j < set.size(); ++j)
502 if (set[j]->getNodeId() == pred->getNodeId()) {
503 alreadyInset = true;
504 break;
505 }
506
507 if (!alreadyInset)
508 predS.push_back(pred);
Guochun Shif1c154f2003-03-27 17:57:44 +0000509 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000510 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000511 return predS;
512}
513
514ModuloSchedGraph::NodeVec ModuloSchedGraph::predSet(NodeVec set)
515{
516 //node number increases from 2
Misha Brukman8baa01c2003-04-09 21:51:34 +0000517 return predSet(set, 0, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000518}
519
Misha Brukman8baa01c2003-04-09 21:51:34 +0000520std::vector <ModuloSchedGraphNode*>
521ModuloSchedGraph::predSet(ModuloSchedGraphNode *_node,
522 unsigned backEdgeSrc, unsigned backEdgeSink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000523{
Guochun Shif1c154f2003-03-27 17:57:44 +0000524 std::vector<ModuloSchedGraphNode*> set;
525 set.push_back(_node);
526 return predSet(set, backEdgeSrc, backEdgeSink);
Guochun Shif1c154f2003-03-27 17:57:44 +0000527}
528
Misha Brukman8baa01c2003-04-09 21:51:34 +0000529std::vector <ModuloSchedGraphNode*>
530ModuloSchedGraph::predSet(ModuloSchedGraphNode * _node)
Guochun Shif1c154f2003-03-27 17:57:44 +0000531{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000532 return predSet(_node, 0, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000533}
534
Misha Brukman8baa01c2003-04-09 21:51:34 +0000535std::vector<ModuloSchedGraphNode*>
536ModuloSchedGraph::succSet(std::vector<ModuloSchedGraphNode*> set,
537 unsigned src, unsigned sink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000538{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000539 std::vector<ModuloSchedGraphNode*> succS;
540 for (unsigned i = 0; i < set.size(); i++) {
541 ModuloSchedGraphNode *node = set[i];
542 for (ModuloSchedGraphNode::const_iterator I =
543 node->beginOutEdges(), E = node->endOutEdges(); I != E; I++) {
544 SchedGraphEdge *edge = *I;
545 if (edge->getSrc()->getNodeId() == src
546 && edge->getSink()->getNodeId() == sink)
547 continue;
548 ModuloSchedGraphNode *succ =
549 (ModuloSchedGraphNode *) (edge->getSink());
550 //if pred is not in the predSet, push it in vector
551 bool alreadyInset = false;
552 for (unsigned j = 0; j < succS.size(); j++)
553 if (succS[j]->getNodeId() == succ->getNodeId()) {
554 alreadyInset = true;
555 break;
556 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000557
Misha Brukman8baa01c2003-04-09 21:51:34 +0000558 for (unsigned j = 0; j < set.size(); j++)
559 if (set[j]->getNodeId() == succ->getNodeId()) {
560 alreadyInset = true;
561 break;
562 }
563 if (!alreadyInset)
564 succS.push_back(succ);
Guochun Shif1c154f2003-03-27 17:57:44 +0000565 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000566 }
567 return succS;
Guochun Shif1c154f2003-03-27 17:57:44 +0000568}
569
570ModuloSchedGraph::NodeVec ModuloSchedGraph::succSet(NodeVec set)
571{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000572 return succSet(set, 0, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000573}
574
575
Misha Brukman8baa01c2003-04-09 21:51:34 +0000576std::vector<ModuloSchedGraphNode*>
577ModuloSchedGraph::succSet(ModuloSchedGraphNode *_node,
578 unsigned src, unsigned sink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000579{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000580 std::vector<ModuloSchedGraphNode*>set;
Guochun Shif1c154f2003-03-27 17:57:44 +0000581 set.push_back(_node);
582 return succSet(set, src, sink);
Guochun Shif1c154f2003-03-27 17:57:44 +0000583}
584
Misha Brukman8baa01c2003-04-09 21:51:34 +0000585std::vector<ModuloSchedGraphNode*>
586ModuloSchedGraph::succSet(ModuloSchedGraphNode * _node)
Guochun Shif1c154f2003-03-27 17:57:44 +0000587{
588 return succSet(_node, 0, 0);
589}
590
Misha Brukman8baa01c2003-04-09 21:51:34 +0000591SchedGraphEdge *ModuloSchedGraph::getMaxDelayEdge(unsigned srcId,
592 unsigned sinkId)
Guochun Shif1c154f2003-03-27 17:57:44 +0000593{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000594 ModuloSchedGraphNode *node = getNode(srcId);
595 SchedGraphEdge *maxDelayEdge = NULL;
596 int maxDelay = -1;
597 for (ModuloSchedGraphNode::const_iterator I = node->beginOutEdges(), E =
598 node->endOutEdges(); I != E; I++) {
599 SchedGraphEdge *edge = *I;
600 if (edge->getSink()->getNodeId() == sinkId)
601 if (edge->getMinDelay() > maxDelay) {
602 maxDelayEdge = edge;
603 maxDelay = edge->getMinDelay();
604 }
605 }
606 assert(maxDelayEdge != NULL && "no edge between the srcId and sinkId?");
Guochun Shif1c154f2003-03-27 17:57:44 +0000607 return maxDelayEdge;
608}
609
610void ModuloSchedGraph::dumpCircuits()
611{
Misha Brukman2c821cc2003-04-10 19:19:23 +0000612 DEBUG(std::cerr << "dumping circuits for graph:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000613 int j = -1;
614 while (circuits[++j][0] != 0) {
615 int k = -1;
616 while (circuits[j][++k] != 0)
Misha Brukman2c821cc2003-04-10 19:19:23 +0000617 DEBUG(std::cerr << circuits[j][k] << "\t");
618 DEBUG(std::cerr << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +0000619 }
620}
621
Misha Brukman8baa01c2003-04-09 21:51:34 +0000622void ModuloSchedGraph::dumpSet(std::vector < ModuloSchedGraphNode * >set)
Guochun Shif1c154f2003-03-27 17:57:44 +0000623{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000624 for (unsigned i = 0; i < set.size(); i++)
Misha Brukman2c821cc2003-04-10 19:19:23 +0000625 DEBUG(std::cerr << set[i]->getNodeId() << "\t");
626 DEBUG(std::cerr << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +0000627}
628
Misha Brukman8baa01c2003-04-09 21:51:34 +0000629std::vector<ModuloSchedGraphNode*>
630ModuloSchedGraph::vectorUnion(std::vector<ModuloSchedGraphNode*> set1,
631 std::vector<ModuloSchedGraphNode*> set2)
Guochun Shif1c154f2003-03-27 17:57:44 +0000632{
633 std::vector<ModuloSchedGraphNode*> unionVec;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000634 for (unsigned i = 0; i < set1.size(); i++)
Guochun Shif1c154f2003-03-27 17:57:44 +0000635 unionVec.push_back(set1[i]);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000636 for (unsigned j = 0; j < set2.size(); j++) {
637 bool inset = false;
638 for (unsigned i = 0; i < unionVec.size(); i++)
639 if (set2[j] == unionVec[i])
640 inset = true;
641 if (!inset)
642 unionVec.push_back(set2[j]);
Guochun Shif1c154f2003-03-27 17:57:44 +0000643 }
644 return unionVec;
645}
Misha Brukman8baa01c2003-04-09 21:51:34 +0000646
647std::vector<ModuloSchedGraphNode*>
648ModuloSchedGraph::vectorConj(std::vector<ModuloSchedGraphNode*> set1,
649 std::vector<ModuloSchedGraphNode*> set2)
Guochun Shif1c154f2003-03-27 17:57:44 +0000650{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000651 std::vector<ModuloSchedGraphNode*> conjVec;
652 for (unsigned i = 0; i < set1.size(); i++)
653 for (unsigned j = 0; j < set2.size(); j++)
654 if (set1[i] == set2[j])
655 conjVec.push_back(set1[i]);
656 return conjVec;
Guochun Shif1c154f2003-03-27 17:57:44 +0000657}
658
Misha Brukman8baa01c2003-04-09 21:51:34 +0000659ModuloSchedGraph::NodeVec ModuloSchedGraph::vectorSub(NodeVec set1,
660 NodeVec set2)
Guochun Shif1c154f2003-03-27 17:57:44 +0000661{
662 NodeVec newVec;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000663 for (NodeVec::iterator I = set1.begin(); I != set1.end(); I++) {
664 bool inset = false;
665 for (NodeVec::iterator II = set2.begin(); II != set2.end(); II++)
666 if ((*I)->getNodeId() == (*II)->getNodeId()) {
667 inset = true;
668 break;
669 }
670 if (!inset)
671 newVec.push_back(*I);
Guochun Shif1c154f2003-03-27 17:57:44 +0000672 }
673 return newVec;
674}
Guochun Shif1c154f2003-03-27 17:57:44 +0000675
Misha Brukman8baa01c2003-04-09 21:51:34 +0000676void ModuloSchedGraph::orderNodes() {
677 oNodes.clear();
678
679 std::vector < ModuloSchedGraphNode * >set;
680 const BasicBlock *bb = bbVec[0];
681 unsigned numNodes = bb->size();
682
Misha Brukman2c821cc2003-04-10 19:19:23 +0000683 // first order all the sets
Misha Brukman8baa01c2003-04-09 21:51:34 +0000684 int j = -1;
685 int totalDelay = -1;
686 int preDelay = -1;
687 while (circuits[++j][0] != 0) {
688 int k = -1;
689 preDelay = totalDelay;
690
691 while (circuits[j][++k] != 0) {
692 ModuloSchedGraphNode *node = getNode(circuits[j][k]);
Guochun Shif1c154f2003-03-27 17:57:44 +0000693 unsigned nextNodeId;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000694 nextNodeId =
695 circuits[j][k + 1] != 0 ? circuits[j][k + 1] : circuits[j][0];
696 SchedGraphEdge *edge = getMaxDelayEdge(circuits[j][k], nextNodeId);
Guochun Shif1c154f2003-03-27 17:57:44 +0000697 totalDelay += edge->getMinDelay();
698 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000699 if (preDelay != -1 && totalDelay > preDelay) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000700 // swap circuits[j][] and cuicuits[j-1][]
Guochun Shif1c154f2003-03-27 17:57:44 +0000701 unsigned temp[MAXNODE];
Misha Brukman8baa01c2003-04-09 21:51:34 +0000702 for (int k = 0; k < MAXNODE; k++) {
703 temp[k] = circuits[j - 1][k];
704 circuits[j - 1][k] = circuits[j][k];
705 circuits[j][k] = temp[k];
Guochun Shif1c154f2003-03-27 17:57:44 +0000706 }
707 //restart
Misha Brukman8baa01c2003-04-09 21:51:34 +0000708 j = -1;
Guochun Shif1c154f2003-03-27 17:57:44 +0000709 }
710 }
711
Misha Brukman2c821cc2003-04-10 19:19:23 +0000712 // build the first set
Guochun Shif1c154f2003-03-27 17:57:44 +0000713 int backEdgeSrc;
714 int backEdgeSink;
Misha Brukman2c821cc2003-04-10 19:19:23 +0000715 if (ModuloScheduling::printScheduleProcess())
716 DEBUG(std::cerr << "building the first set" << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000717 int setSeq = -1;
718 int k = -1;
Guochun Shif1c154f2003-03-27 17:57:44 +0000719 setSeq++;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000720 while (circuits[setSeq][++k] != 0)
Guochun Shif1c154f2003-03-27 17:57:44 +0000721 set.push_back(getNode(circuits[setSeq][k]));
Misha Brukman8baa01c2003-04-09 21:51:34 +0000722 if (circuits[setSeq][0] != 0) {
723 backEdgeSrc = circuits[setSeq][k - 1];
724 backEdgeSink = circuits[setSeq][0];
Guochun Shif1c154f2003-03-27 17:57:44 +0000725 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000726 if (ModuloScheduling::printScheduleProcess()) {
727 DEBUG(std::cerr << "the first set is:");
Guochun Shif1c154f2003-03-27 17:57:44 +0000728 dumpSet(set);
729 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000730 // implement the ordering algorithm
Misha Brukman8baa01c2003-04-09 21:51:34 +0000731 enum OrderSeq { bottom_up, top_down };
Guochun Shif1c154f2003-03-27 17:57:44 +0000732 OrderSeq order;
733 std::vector<ModuloSchedGraphNode*> R;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000734 while (!set.empty()) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000735 std::vector<ModuloSchedGraphNode*> pset = predSet(oNodes);
736 std::vector<ModuloSchedGraphNode*> sset = succSet(oNodes);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000737
738 if (!pset.empty() && !vectorConj(pset, set).empty()) {
739 R = vectorConj(pset, set);
740 order = bottom_up;
741 } else if (!sset.empty() && !vectorConj(sset, set).empty()) {
742 R = vectorConj(sset, set);
743 order = top_down;
744 } else {
745 int maxASAP = -1;
746 int position = -1;
747 for (unsigned i = 0; i < set.size(); i++) {
748 int temp = set[i]->getASAP();
749 if (temp > maxASAP) {
750 maxASAP = temp;
751 position = i;
752 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000753 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000754 R.push_back(set[position]);
755 order = bottom_up;
756 }
757
758 while (!R.empty()) {
759 if (order == top_down) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000760 if (ModuloScheduling::printScheduleProcess())
761 DEBUG(std::cerr << "in top_down round\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000762 while (!R.empty()) {
763 int maxHeight = -1;
764 NodeVec::iterator chosenI;
765 for (NodeVec::iterator I = R.begin(); I != R.end(); I++) {
766 int temp = (*I)->height;
767 if ((temp > maxHeight)
768 || (temp == maxHeight && (*I)->mov <= (*chosenI)->mov)) {
769
770 if ((temp > maxHeight)
771 || (temp == maxHeight && (*I)->mov < (*chosenI)->mov)) {
772 maxHeight = temp;
773 chosenI = I;
774 continue;
775 }
776 //possible case: instruction A and B has the same height and mov,
777 //but A has dependence to B e.g B is the branch instruction in the
778 //end, or A is the phi instruction at the beginning
779 if ((*I)->mov == (*chosenI)->mov)
780 for (ModuloSchedGraphNode::const_iterator oe =
781 (*I)->beginOutEdges(), end = (*I)->endOutEdges();
782 oe != end; oe++) {
783 if ((*oe)->getSink() == (*chosenI)) {
784 maxHeight = temp;
785 chosenI = I;
786 continue;
787 }
788 }
789 }
790 }
791 ModuloSchedGraphNode *mu = *chosenI;
792 oNodes.push_back(mu);
793 R.erase(chosenI);
794 std::vector<ModuloSchedGraphNode*> succ_mu =
795 succSet(mu, backEdgeSrc, backEdgeSink);
796 std::vector<ModuloSchedGraphNode*> comm =
797 vectorConj(succ_mu, set);
798 comm = vectorSub(comm, oNodes);
799 R = vectorUnion(comm, R);
800 }
801 order = bottom_up;
802 R = vectorConj(predSet(oNodes), set);
803 } else {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000804 if (ModuloScheduling::printScheduleProcess())
805 DEBUG(std::cerr << "in bottom up round\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000806 while (!R.empty()) {
807 int maxDepth = -1;
808 NodeVec::iterator chosenI;
809 for (NodeVec::iterator I = R.begin(); I != R.end(); I++) {
810 int temp = (*I)->depth;
811 if ((temp > maxDepth)
812 || (temp == maxDepth && (*I)->mov < (*chosenI)->mov)) {
813 maxDepth = temp;
814 chosenI = I;
815 }
816 }
817 ModuloSchedGraphNode *mu = *chosenI;
818 oNodes.push_back(mu);
819 R.erase(chosenI);
820 std::vector<ModuloSchedGraphNode*> pred_mu =
821 predSet(mu, backEdgeSrc, backEdgeSink);
822 std::vector<ModuloSchedGraphNode*> comm =
823 vectorConj(pred_mu, set);
824 comm = vectorSub(comm, oNodes);
825 R = vectorUnion(comm, R);
826 }
827 order = top_down;
828 R = vectorConj(succSet(oNodes), set);
Guochun Shif1c154f2003-03-27 17:57:44 +0000829 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000830 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000831 if (ModuloScheduling::printScheduleProcess()) {
832 DEBUG(std::cerr << "order finished\n");
833 DEBUG(std::cerr << "dumping the ordered nodes:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000834 dumpSet(oNodes);
835 dumpCircuits();
836 }
837 //create a new set
838 //FIXME: the nodes between onodes and this circuit should also be include in
839 //this set
Misha Brukman2c821cc2003-04-10 19:19:23 +0000840 if (ModuloScheduling::printScheduleProcess())
841 DEBUG(std::cerr << "building the next set\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000842 set.clear();
843 int k = -1;
844 setSeq++;
845 while (circuits[setSeq][++k] != 0)
846 set.push_back(getNode(circuits[setSeq][k]));
847 if (circuits[setSeq][0] != 0) {
848 backEdgeSrc = circuits[setSeq][k - 1];
849 backEdgeSink = circuits[setSeq][0];
850 }
851 if (set.empty()) {
852 //no circuits any more
853 //collect all other nodes
Misha Brukman2c821cc2003-04-10 19:19:23 +0000854 if (ModuloScheduling::printScheduleProcess())
855 DEBUG(std::cerr << "no circuits any more, collect the rest nodes\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000856 for (unsigned i = 2; i < numNodes + 2; i++) {
857 bool inset = false;
858 for (unsigned j = 0; j < oNodes.size(); j++)
859 if (oNodes[j]->getNodeId() == i) {
860 inset = true;
861 break;
862 }
863 if (!inset)
864 set.push_back(getNode(i));
Guochun Shif1c154f2003-03-27 17:57:44 +0000865 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000866 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000867 if (ModuloScheduling::printScheduleProcess()) {
868 DEBUG(std::cerr << "next set is:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000869 dumpSet(set);
870 }
871 } //while(!set.empty())
872
Guochun Shif1c154f2003-03-27 17:57:44 +0000873}
874
875
876
Misha Brukman8baa01c2003-04-09 21:51:34 +0000877void ModuloSchedGraph::buildGraph(const TargetMachine & target)
Guochun Shif1c154f2003-03-27 17:57:44 +0000878{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000879 const BasicBlock *bb = bbVec[0];
Guochun Shif1c154f2003-03-27 17:57:44 +0000880
Misha Brukman8baa01c2003-04-09 21:51:34 +0000881 assert(bbVec.size() == 1 && "only handling a single basic block here");
Guochun Shif1c154f2003-03-27 17:57:44 +0000882
883 // Use this data structure to note all machine operands that compute
884 // ordinary LLVM values. These must be computed defs (i.e., instructions).
885 // Note that there may be multiple machine instructions that define
886 // each Value.
887 ValueToDefVecMap valueToDefVecMap;
888
889 // Use this data structure to note all memory instructions.
890 // We use this to add memory dependence edges without a second full walk.
891 //
892 // vector<const Instruction*> memVec;
Misha Brukman2c821cc2003-04-10 19:19:23 +0000893 std::vector<ModuloSchedGraphNode*> memNodeVec;
Guochun Shif1c154f2003-03-27 17:57:44 +0000894
Misha Brukman8baa01c2003-04-09 21:51:34 +0000895 // Use this data structure to note any uses or definitions of
Guochun Shif1c154f2003-03-27 17:57:44 +0000896 // machine registers so we can add edges for those later without
897 // extra passes over the nodes.
898 // The vector holds an ordered list of references to the machine reg,
899 // ordered according to control-flow order. This only works for a
900 // single basic block, hence the assertion. Each reference is identified
901 // by the pair: <node, operand-number>.
902 //
903 RegToRefVecMap regToRefVecMap;
Guochun Shif1c154f2003-03-27 17:57:44 +0000904
Misha Brukman8baa01c2003-04-09 21:51:34 +0000905 // Make a dummy root node. We'll add edges to the real roots later.
906 graphRoot = new ModuloSchedGraphNode(0, NULL, NULL, -1, target);
907 graphLeaf = new ModuloSchedGraphNode(1, NULL, NULL, -1, target);
908
909 //----------------------------------------------------------------
910 // First add nodes for all the LLVM instructions in the basic block because
911 // this greatly simplifies identifying which edges to add. Do this one VM
912 // instruction at a time since the ModuloSchedGraphNode needs that.
Guochun Shif1c154f2003-03-27 17:57:44 +0000913 // Also, remember the load/store instructions to add memory deps later.
914 //----------------------------------------------------------------
915
916 //FIXME:if there is call instruction, then we shall quit somewhere
917 // currently we leave call instruction and continue construct graph
918
919 //dump only the blocks which are from loops
920
921
Misha Brukman2c821cc2003-04-10 19:19:23 +0000922 if (ModuloScheduling::printScheduleProcess())
Guochun Shif1c154f2003-03-27 17:57:44 +0000923 this->dump(bb);
924
Misha Brukman8baa01c2003-04-09 21:51:34 +0000925 if (!isLoop(bb)) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000926 DEBUG(std::cerr << " dumping non-loop BB:\n");
Guochun Shif1c154f2003-03-27 17:57:44 +0000927 dump(bb);
928 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000929 if (isLoop(bb)) {
930 buildNodesforBB(target, bb, memNodeVec, regToRefVecMap,
931 valueToDefVecMap);
932
933 this->addDefUseEdges(bb);
934 this->addCDEdges(bb);
935 this->addMemEdges(bb);
936
937 //this->dump();
938
939 int ResII = this->computeResII(bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000940 if (ModuloScheduling::printScheduleProcess())
941 DEBUG(std::cerr << "ResII is " << ResII << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000942 int RecII = this->computeRecII(bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000943 if (ModuloScheduling::printScheduleProcess())
944 DEBUG(std::cerr << "RecII is " << RecII << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000945
946 this->MII = std::max(ResII, RecII);
947
948 this->computeNodeProperty(bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000949 if (ModuloScheduling::printScheduleProcess())
Misha Brukman8baa01c2003-04-09 21:51:34 +0000950 this->dumpNodeProperty();
951
952 this->orderNodes();
953
Misha Brukman2c821cc2003-04-10 19:19:23 +0000954 if (ModuloScheduling::printScheduleProcess())
Misha Brukman8baa01c2003-04-09 21:51:34 +0000955 this->dump();
956 //this->instrScheduling();
957
958 //this->dumpScheduling();
959 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000960}
961
Misha Brukman8baa01c2003-04-09 21:51:34 +0000962ModuloSchedGraphNode *ModuloSchedGraph::getNode(const unsigned nodeId) const
Guochun Shif1c154f2003-03-27 17:57:44 +0000963{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000964 for (const_iterator I = begin(), E = end(); I != E; I++)
965 if ((*I).second->getNodeId() == nodeId)
966 return (ModuloSchedGraphNode *) (*I).second;
Guochun Shif1c154f2003-03-27 17:57:44 +0000967 return NULL;
968}
969
Misha Brukman8baa01c2003-04-09 21:51:34 +0000970int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
Guochun Shif1c154f2003-03-27 17:57:44 +0000971{
972
Misha Brukman8baa01c2003-04-09 21:51:34 +0000973 int RecII = 0;
Guochun Shif1c154f2003-03-27 17:57:44 +0000974
975 //os<<"begining computerRecII()"<<"\n";
976
Misha Brukman8baa01c2003-04-09 21:51:34 +0000977 //FIXME: only deal with circuits starting at the first node: the phi node
978 //nodeId=2;
Guochun Shif1c154f2003-03-27 17:57:44 +0000979
980 //search all elementary circuits in the dependance graph
981 //assume maximum number of nodes is MAXNODE
Misha Brukman8baa01c2003-04-09 21:51:34 +0000982
Guochun Shif1c154f2003-03-27 17:57:44 +0000983 unsigned path[MAXNODE];
984 unsigned stack[MAXNODE][MAXNODE];
985
Misha Brukman8baa01c2003-04-09 21:51:34 +0000986 for (int j = 0; j < MAXNODE; j++) {
987 path[j] = 0;
988 for (int k = 0; k < MAXNODE; k++)
989 stack[j][k] = 0;
990 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000991 //in our graph, the node number starts at 2
992
993 //number of nodes, because each instruction will result in one node
Misha Brukman8baa01c2003-04-09 21:51:34 +0000994 const unsigned numNodes = bb->size();
Guochun Shif1c154f2003-03-27 17:57:44 +0000995
Misha Brukman8baa01c2003-04-09 21:51:34 +0000996 int i = 0;
997 path[i] = 2;
Guochun Shif1c154f2003-03-27 17:57:44 +0000998
Misha Brukman8baa01c2003-04-09 21:51:34 +0000999 ModuloSchedGraphNode *initNode = getNode(path[0]);
1000 unsigned initNodeId = initNode->getNodeId();
1001 ModuloSchedGraphNode *currentNode = initNode;
Guochun Shif1c154f2003-03-27 17:57:44 +00001002
Misha Brukman8baa01c2003-04-09 21:51:34 +00001003 while (currentNode != NULL) {
1004 unsigned currentNodeId = currentNode->getNodeId();
Misha Brukman2c821cc2003-04-10 19:19:23 +00001005 // DEBUG(std::cerr<<"current node is "<<currentNodeId<<"\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001006
Misha Brukman8baa01c2003-04-09 21:51:34 +00001007 ModuloSchedGraphNode *nextNode = NULL;
1008 for (ModuloSchedGraphNode::const_iterator I =
1009 currentNode->beginOutEdges(), E = currentNode->endOutEdges();
1010 I != E; I++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001011 //DEBUG(std::cerr <<" searching in outgoint edges of node
Misha Brukman8baa01c2003-04-09 21:51:34 +00001012 //"<<currentNodeId<<"\n";
1013 unsigned nodeId = ((SchedGraphEdge *) * I)->getSink()->getNodeId();
1014 bool inpath = false, instack = false;
1015 int k;
Guochun Shif1c154f2003-03-27 17:57:44 +00001016
Misha Brukman2c821cc2003-04-10 19:19:23 +00001017 //DEBUG(std::cerr<<"nodeId is "<<nodeId<<"\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001018
Misha Brukman8baa01c2003-04-09 21:51:34 +00001019 k = -1;
1020 while (path[++k] != 0)
1021 if (nodeId == path[k]) {
1022 inpath = true;
1023 break;
1024 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001025
Misha Brukman8baa01c2003-04-09 21:51:34 +00001026 k = -1;
1027 while (stack[i][++k] != 0)
1028 if (nodeId == stack[i][k]) {
1029 instack = true;
1030 break;
1031 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001032
Misha Brukman8baa01c2003-04-09 21:51:34 +00001033 if (nodeId > currentNodeId && !inpath && !instack) {
1034 nextNode =
1035 (ModuloSchedGraphNode *) ((SchedGraphEdge *) * I)->getSink();
1036 break;
1037 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001038 }
Misha Brukman8baa01c2003-04-09 21:51:34 +00001039
1040 if (nextNode != NULL) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001041 //DEBUG(std::cerr<<"find the next Node "<<nextNode->getNodeId()<<"\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001042
1043 int j = 0;
1044 while (stack[i][j] != 0)
1045 j++;
1046 stack[i][j] = nextNode->getNodeId();
1047
1048 i++;
1049 path[i] = nextNode->getNodeId();
1050 currentNode = nextNode;
1051 } else {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001052 //DEBUG(std::cerr<<"no expansion any more"<<"\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001053 //confirmCircuit();
1054 for (ModuloSchedGraphNode::const_iterator I =
1055 currentNode->beginOutEdges(), E = currentNode->endOutEdges();
1056 I != E; I++) {
1057 unsigned nodeId = ((SchedGraphEdge *) * I)->getSink()->getNodeId();
1058 if (nodeId == initNodeId) {
1059
1060 int j = -1;
1061 while (circuits[++j][0] != 0);
1062 for (int k = 0; k < MAXNODE; k++)
1063 circuits[j][k] = path[k];
1064
1065 }
1066 }
1067 //remove this node in the path and clear the corresponding entries in the
1068 //stack
1069 path[i] = 0;
1070 int j = 0;
1071 for (j = 0; j < MAXNODE; j++)
1072 stack[i][j] = 0;
1073 i--;
1074 currentNode = getNode(path[i]);
1075 }
1076 if (i == 0) {
1077
Misha Brukman2c821cc2003-04-10 19:19:23 +00001078 if (ModuloScheduling::printScheduleProcess())
1079 DEBUG(std::cerr << "circuits found are:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001080 int j = -1;
1081 while (circuits[++j][0] != 0) {
1082 int k = -1;
1083 while (circuits[j][++k] != 0)
Misha Brukman2c821cc2003-04-10 19:19:23 +00001084 if (ModuloScheduling::printScheduleProcess())
1085 DEBUG(std::cerr << circuits[j][k] << "\t");
1086 if (ModuloScheduling::printScheduleProcess())
1087 DEBUG(std::cerr << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001088
1089 //for this circuit, compute the sum of all edge delay
1090 int sumDelay = 0;
1091 k = -1;
1092 while (circuits[j][++k] != 0) {
1093 //ModuloSchedGraphNode* node =getNode(circuits[j][k]);
1094 unsigned nextNodeId;
1095 nextNodeId =
1096 circuits[j][k + 1] !=
1097 0 ? circuits[j][k + 1] : circuits[j][0];
1098
1099 /*
1100 for(ModuloSchedGraphNode::const_iterator I=node->beginOutEdges(),
1101 E=node->endOutEdges();I !=E; I++)
1102 {
1103 SchedGraphEdge* edge= *I;
1104 if(edge->getSink()->getNodeId() == nextNodeId)
1105 {sumDelay += edge->getMinDelay();break;}
1106 }
1107 */
1108
1109 sumDelay +=
1110 getMaxDelayEdge(circuits[j][k], nextNodeId)->getMinDelay();
1111
1112 }
1113 // assume we have distance 1, in this case the sumDelay is RecII
1114 // this is correct for SSA form only
1115 //
Misha Brukman2c821cc2003-04-10 19:19:23 +00001116 if (ModuloScheduling::printScheduleProcess())
1117 DEBUG(std::cerr << "The total Delay in the circuit is " << sumDelay
1118 << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001119
1120 RecII = RecII > sumDelay ? RecII : sumDelay;
1121
1122 }
1123 return RecII;
1124 }
1125
1126 }
1127
Guochun Shif1c154f2003-03-27 17:57:44 +00001128 return -1;
1129}
1130
Misha Brukman8baa01c2003-04-09 21:51:34 +00001131void ModuloSchedGraph::addResourceUsage(std::vector<std::pair<int,int> > &ruVec,
1132 int rid)
1133{
Misha Brukman2c821cc2003-04-10 19:19:23 +00001134 //DEBUG(std::cerr<<"\nadding a resouce , current resouceUsage vector size is
Misha Brukman8baa01c2003-04-09 21:51:34 +00001135 //"<<ruVec.size()<<"\n";
1136 bool alreadyExists = false;
1137 for (unsigned i = 0; i < ruVec.size(); i++) {
1138 if (rid == ruVec[i].first) {
Guochun Shif1c154f2003-03-27 17:57:44 +00001139 ruVec[i].second++;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001140 alreadyExists = true;
Guochun Shif1c154f2003-03-27 17:57:44 +00001141 break;
1142 }
1143 }
Misha Brukman8baa01c2003-04-09 21:51:34 +00001144 if (!alreadyExists)
1145 ruVec.push_back(std::make_pair(rid, 1));
Misha Brukman2c821cc2003-04-10 19:19:23 +00001146 //DEBUG(std::cerr<<"current resouceUsage vector size is "<<ruVec.size()<<"\n";
Guochun Shif1c154f2003-03-27 17:57:44 +00001147
1148}
Misha Brukman8baa01c2003-04-09 21:51:34 +00001149void ModuloSchedGraph::dumpResourceUsage(std::vector<std::pair<int,int> > &ru)
Guochun Shif1c154f2003-03-27 17:57:44 +00001150{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001151 TargetSchedInfo & msi = (TargetSchedInfo &) target.getSchedInfo();
1152
Misha Brukman2c821cc2003-04-10 19:19:23 +00001153 std::vector<std::pair<int,int> > resourceNumVector = msi.resourceNumVector;
1154 DEBUG(std::cerr << "resourceID\t" << "resourceNum\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001155 for (unsigned i = 0; i < resourceNumVector.size(); i++)
Misha Brukman2c821cc2003-04-10 19:19:23 +00001156 DEBUG(std::cerr << resourceNumVector[i].
1157 first << "\t" << resourceNumVector[i].second << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001158
Misha Brukman2c821cc2003-04-10 19:19:23 +00001159 DEBUG(std::cerr << " maxNumIssueTotal(issue slot in one cycle) = " << msi.
1160 maxNumIssueTotal << "\n");
1161 DEBUG(std::cerr << "resourceID\t resourceUsage\t ResourceNum\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001162 for (unsigned i = 0; i < ru.size(); i++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001163 DEBUG(std::cerr << ru[i].first << "\t" << ru[i].second);
Misha Brukman8baa01c2003-04-09 21:51:34 +00001164 const unsigned resNum = msi.getCPUResourceNum(ru[i].first);
Misha Brukman2c821cc2003-04-10 19:19:23 +00001165 DEBUG(std::cerr << "\t" << resNum << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001166 }
1167}
1168
Misha Brukman8baa01c2003-04-09 21:51:34 +00001169int ModuloSchedGraph::computeResII(const BasicBlock * bb)
Guochun Shif1c154f2003-03-27 17:57:44 +00001170{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001171
1172 const TargetInstrInfo & mii = target.getInstrInfo();
1173 const TargetSchedInfo & msi = target.getSchedInfo();
1174
Guochun Shif1c154f2003-03-27 17:57:44 +00001175 int ResII;
Misha Brukman2c821cc2003-04-10 19:19:23 +00001176 std::vector<std::pair<int,int> > resourceUsage;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001177 //pair<int resourceid, int resourceUsageTimes_in_the_whole_block>
1178
1179 //FIXME: number of functional units the target machine can provide should be
1180 //get from Target here I temporary hardcode it
1181
1182 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E;
1183 I++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001184 if (ModuloScheduling::printScheduleProcess()) {
1185 DEBUG(std::cerr << "machine instruction for llvm instruction( node " <<
1186 getGraphNodeForInst(I)->getNodeId() << ")\n");
1187 DEBUG(std::cerr << "\t" << *I);
Guochun Shif1c154f2003-03-27 17:57:44 +00001188 }
Misha Brukman8baa01c2003-04-09 21:51:34 +00001189 MachineCodeForInstruction & tempMvec =
1190 MachineCodeForInstruction::get(I);
Misha Brukman2c821cc2003-04-10 19:19:23 +00001191 if (ModuloScheduling::printScheduleProcess())
1192 DEBUG(std::cerr << "size =" << tempMvec.size() << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001193 for (unsigned i = 0; i < tempMvec.size(); i++) {
1194 MachineInstr *minstr = tempMvec[i];
1195
1196 unsigned minDelay = mii.minLatency(minstr->getOpCode());
1197 InstrRUsage rUsage = msi.getInstrRUsage(minstr->getOpCode());
1198 InstrClassRUsage classRUsage =
1199 msi.getClassRUsage(mii.getSchedClass(minstr->getOpCode()));
1200 unsigned totCycles = classRUsage.totCycles;
1201
Misha Brukman2c821cc2003-04-10 19:19:23 +00001202 std::vector<std::vector<resourceId_t> > resources=rUsage.resourcesByCycle;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001203 assert(totCycles == resources.size());
Misha Brukman2c821cc2003-04-10 19:19:23 +00001204 if (ModuloScheduling::printScheduleProcess())
1205 DEBUG(std::cerr << "resources Usage for this Instr(totCycles="
1206 << totCycles << ",mindLatency="
1207 << mii.minLatency(minstr->getOpCode()) << "): " << *minstr
1208 << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001209 for (unsigned j = 0; j < resources.size(); j++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001210 if (ModuloScheduling::printScheduleProcess())
1211 DEBUG(std::cerr << "cycle " << j << ": ");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001212 for (unsigned k = 0; k < resources[j].size(); k++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001213 if (ModuloScheduling::printScheduleProcess())
1214 DEBUG(std::cerr << "\t" << resources[j][k]);
Misha Brukman8baa01c2003-04-09 21:51:34 +00001215 addResourceUsage(resourceUsage, resources[j][k]);
1216 }
Misha Brukman2c821cc2003-04-10 19:19:23 +00001217 if (ModuloScheduling::printScheduleProcess())
1218 DEBUG(std::cerr << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001219 }
1220 }
1221 }
Misha Brukman2c821cc2003-04-10 19:19:23 +00001222 if (ModuloScheduling::printScheduleProcess())
Guochun Shif1c154f2003-03-27 17:57:44 +00001223 this->dumpResourceUsage(resourceUsage);
1224
1225 //compute ResII
Misha Brukman8baa01c2003-04-09 21:51:34 +00001226 ResII = 0;
1227 int issueSlots = msi.maxNumIssueTotal;
1228 for (unsigned i = 0; i < resourceUsage.size(); i++) {
1229 int resourceNum = msi.getCPUResourceNum(resourceUsage[i].first);
1230 int useNum = resourceUsage[i].second;
Guochun Shif1c154f2003-03-27 17:57:44 +00001231 double tempII;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001232 if (resourceNum <= issueSlots)
1233 tempII = ceil(1.0 * useNum / resourceNum);
Guochun Shif1c154f2003-03-27 17:57:44 +00001234 else
Misha Brukman8baa01c2003-04-09 21:51:34 +00001235 tempII = ceil(1.0 * useNum / issueSlots);
1236 ResII = std::max((int) tempII, ResII);
Guochun Shif1c154f2003-03-27 17:57:44 +00001237 }
1238 return ResII;
1239}
1240
Misha Brukman2c821cc2003-04-10 19:19:23 +00001241ModuloSchedGraphSet::ModuloSchedGraphSet(const Function *function,
1242 const TargetMachine &target)
Misha Brukman8baa01c2003-04-09 21:51:34 +00001243: method(function)
Guochun Shif1c154f2003-03-27 17:57:44 +00001244{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001245 buildGraphsForMethod(method, target);
Guochun Shif1c154f2003-03-27 17:57:44 +00001246}
1247
1248
1249ModuloSchedGraphSet::~ModuloSchedGraphSet()
1250{
1251 //delete all the graphs
Misha Brukman8baa01c2003-04-09 21:51:34 +00001252 for (iterator I = begin(), E = end(); I != E; ++I)
Guochun Shif1c154f2003-03-27 17:57:44 +00001253 delete *I;
1254}
1255
Misha Brukman8baa01c2003-04-09 21:51:34 +00001256void ModuloSchedGraphSet::dump() const
Guochun Shif1c154f2003-03-27 17:57:44 +00001257{
Misha Brukman2c821cc2003-04-10 19:19:23 +00001258 DEBUG(std::cerr << " ====== ModuloSched graphs for function `" <<
1259 method->getName() << "' =========\n\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001260 for (const_iterator I = begin(); I != end(); ++I)
Guochun Shif1c154f2003-03-27 17:57:44 +00001261 (*I)->dump();
Misha Brukman8baa01c2003-04-09 21:51:34 +00001262
Misha Brukman2c821cc2003-04-10 19:19:23 +00001263 DEBUG(std::cerr << "\n=========End graphs for function `" << method->getName()
1264 << "' ==========\n\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001265}
1266
Misha Brukman8baa01c2003-04-09 21:51:34 +00001267void ModuloSchedGraph::dump(const BasicBlock * bb)
Guochun Shif1c154f2003-03-27 17:57:44 +00001268{
Misha Brukman2c821cc2003-04-10 19:19:23 +00001269 DEBUG(std::cerr << "dumping basic block:");
1270 DEBUG(std::cerr << (bb->hasName()? bb->getName() : "block")
1271 << " (" << bb << ")" << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001272
1273}
1274
Misha Brukman8baa01c2003-04-09 21:51:34 +00001275void ModuloSchedGraph::dump(const BasicBlock * bb, std::ostream & os)
Guochun Shif1c154f2003-03-27 17:57:44 +00001276{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001277 os << "dumping basic block:";
1278 os << (bb->hasName()? bb->getName() : "block")
1279 << " (" << bb << ")" << "\n";
Guochun Shif1c154f2003-03-27 17:57:44 +00001280}
1281
Misha Brukman8baa01c2003-04-09 21:51:34 +00001282void ModuloSchedGraph::dump() const
Guochun Shif1c154f2003-03-27 17:57:44 +00001283{
Misha Brukman2c821cc2003-04-10 19:19:23 +00001284 DEBUG(std::cerr << " ModuloSchedGraph for basic Blocks:");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001285 for (unsigned i = 0, N = bbVec.size(); i < N; i++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001286 DEBUG(std::cerr << (bbVec[i]->hasName()? bbVec[i]->getName() : "block")
1287 << " (" << bbVec[i] << ")" << ((i == N - 1) ? "" : ", "));
Misha Brukman8baa01c2003-04-09 21:51:34 +00001288 }
1289
Misha Brukman2c821cc2003-04-10 19:19:23 +00001290 DEBUG(std::cerr << "\n\n Actual Root nodes : ");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001291 for (unsigned i = 0, N = graphRoot->outEdges.size(); i < N; i++)
Misha Brukman2c821cc2003-04-10 19:19:23 +00001292 DEBUG(std::cerr << graphRoot->outEdges[i]->getSink()->getNodeId()
1293 << ((i == N - 1) ? "" : ", "));
Guochun Shif1c154f2003-03-27 17:57:44 +00001294
Misha Brukman2c821cc2003-04-10 19:19:23 +00001295 DEBUG(std::cerr << "\n Graph Nodes:\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001296 //for (const_iterator I=begin(); I != end(); ++I)
Misha Brukman2c821cc2003-04-10 19:19:23 +00001297 //DEBUG(std::cerr << "\n" << *I->second;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001298 unsigned numNodes = bbVec[0]->size();
1299 for (unsigned i = 2; i < numNodes + 2; i++) {
1300 ModuloSchedGraphNode *node = getNode(i);
Misha Brukman2c821cc2003-04-10 19:19:23 +00001301 DEBUG(std::cerr << "\n" << *node);
Misha Brukman8baa01c2003-04-09 21:51:34 +00001302 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001303
Misha Brukman2c821cc2003-04-10 19:19:23 +00001304 DEBUG(std::cerr << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001305}
Misha Brukman8baa01c2003-04-09 21:51:34 +00001306
1307void ModuloSchedGraph::dumpNodeProperty() const
Guochun Shif1c154f2003-03-27 17:57:44 +00001308{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001309 const BasicBlock *bb = bbVec[0];
1310 unsigned numNodes = bb->size();
1311 for (unsigned i = 2; i < numNodes + 2; i++) {
1312 ModuloSchedGraphNode *node = getNode(i);
Misha Brukman2c821cc2003-04-10 19:19:23 +00001313 DEBUG(std::cerr << "NodeId " << node->getNodeId() << "\t");
1314 DEBUG(std::cerr << "ASAP " << node->getASAP() << "\t");
1315 DEBUG(std::cerr << "ALAP " << node->getALAP() << "\t");
1316 DEBUG(std::cerr << "mov " << node->getMov() << "\t");
1317 DEBUG(std::cerr << "depth " << node->getDepth() << "\t");
1318 DEBUG(std::cerr << "height " << node->getHeight() << "\t\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001319 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001320}
1321
Misha Brukman8baa01c2003-04-09 21:51:34 +00001322void ModuloSchedGraphSet::buildGraphsForMethod(const Function * F,
1323 const TargetMachine &
1324 target)
Guochun Shif1c154f2003-03-27 17:57:44 +00001325{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001326 for (Function::const_iterator BI = F->begin(); BI != F->end(); ++BI)
1327 addGraph(new ModuloSchedGraph(BI, target));
Guochun Shif1c154f2003-03-27 17:57:44 +00001328}
1329
Misha Brukman8baa01c2003-04-09 21:51:34 +00001330std::ostream & operator<<(std::ostream & os,
1331 const ModuloSchedGraphNode & node)
Guochun Shif1c154f2003-03-27 17:57:44 +00001332{
1333 os << std::string(8, ' ')
Misha Brukman8baa01c2003-04-09 21:51:34 +00001334 << "Node " << node.nodeId << " : "
1335 << "latency = " << node.latency << "\n" << std::string(12, ' ');
Guochun Shif1c154f2003-03-27 17:57:44 +00001336
1337 if (node.getInst() == NULL)
1338 os << "(Dummy node)\n";
Misha Brukman8baa01c2003-04-09 21:51:34 +00001339 else {
1340 os << *node.getInst() << "\n" << std::string(12, ' ');
1341 os << node.inEdges.size() << " Incoming Edges:\n";
1342 for (unsigned i = 0, N = node.inEdges.size(); i < N; i++)
1343 os << std::string(16, ' ') << *node.inEdges[i];
1344
1345 os << std::string(12, ' ') << node.outEdges.size()
1346 << " Outgoing Edges:\n";
1347 for (unsigned i = 0, N = node.outEdges.size(); i < N; i++)
1348 os << std::string(16, ' ') << *node.outEdges[i];
1349 }
1350
Guochun Shif1c154f2003-03-27 17:57:44 +00001351
1352 return os;
1353}