blob: b25b65c9321d962a4c1e24859c7c9ee7af3fcc45 [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>
Misha Brukman8baa01c2003-04-09 21:51:34 +000022#include <math.h>
Guochun Shif1c154f2003-03-27 17:57:44 +000023
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000024
Guochun Shif1c154f2003-03-27 17:57:44 +000025#define UNIDELAY 1
Guochun Shif1c154f2003-03-27 17:57:44 +000026
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000027using std::cerr;
28using std::endl;
29using std::vector;
Guochun Shif1c154f2003-03-27 17:57:44 +000030
Guochun Shif1c154f2003-03-27 17:57:44 +000031
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000032/***********member functions for ModuloSchedGraphNode*********/
Guochun Shif1c154f2003-03-27 17:57:44 +000033
Guochun Shif1c154f2003-03-27 17:57:44 +000034
Guochun Shi099b0642003-06-02 17:48:56 +000035ModuloSchedGraphNode::ModuloSchedGraphNode(unsigned int in_nodeId,
36 const BasicBlock * in_bb,
37 const Instruction * in_inst,
Misha Brukman8baa01c2003-04-09 21:51:34 +000038 int indexInBB,
39 const TargetMachine & target)
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000040 :SchedGraphNodeCommon(in_nodeId, indexInBB), inst(in_inst){
41
Misha Brukman8baa01c2003-04-09 21:51:34 +000042 if (inst) {
43 //FIXME: find the latency
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000044 //currently set the latency to zero
Misha Brukman8baa01c2003-04-09 21:51:34 +000045 latency = 0;
46 }
Guochun Shif1c154f2003-03-27 17:57:44 +000047}
Misha Brukman8baa01c2003-04-09 21:51:34 +000048
Guochun Shif1c154f2003-03-27 17:57:44 +000049
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000050/***********member functions for ModuloSchedGraph*********/
Misha Brukman8baa01c2003-04-09 21:51:34 +000051
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000052void
53ModuloSchedGraph::addDefUseEdges(const BasicBlock *bb){
54
Guochun Shif1c154f2003-03-27 17:57:44 +000055 //collect def instructions, store them in vector
Misha Brukman8baa01c2003-04-09 21:51:34 +000056 const TargetInstrInfo & mii = target.getInstrInfo();
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000057 vector < ModuloSchedGraphNode * > defVec;
58
59
Guochun Shif1c154f2003-03-27 17:57:44 +000060 //find those def instructions
Misha Brukman8baa01c2003-04-09 21:51:34 +000061 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E; ++I) {
62 if (I->getType() != Type::VoidTy) {
63 defVec.push_back(this->getGraphNodeForInst(I));
64 }
65 }
66
67 for (unsigned int i = 0; i < defVec.size(); i++) {
68 for (Value::use_const_iterator I = defVec[i]->getInst()->use_begin();
69 I != defVec[i]->getInst()->use_end(); I++) {
Misha Brukman63e04f32003-04-22 23:00:08 +000070 //for each use of a def, add a flow edge from the def instruction to the
71 //ref instruction
Misha Brukman8baa01c2003-04-09 21:51:34 +000072
73 const Instruction *value = defVec[i]->getInst();
74 Instruction *inst = (Instruction *) (*I);
75 ModuloSchedGraphNode *node = NULL;
76
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000077 for (BasicBlock::const_iterator ins = bb->begin(), E = bb->end();
78 ins != E; ++ins)
79 if ((const Instruction *) ins == inst) {
Misha Brukman8baa01c2003-04-09 21:51:34 +000080 node = (*this)[inst];
81 break;
82 }
83
Misha Brukman8baa01c2003-04-09 21:51:34 +000084
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000085 if (node == NULL){
86
87 //inst is not an instruction in this block
88 //do nothing
89
Misha Brukman8baa01c2003-04-09 21:51:34 +000090 } else {
91 // Add a flow edge from the def instruction to the ref instruction
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000092 // This is a true dependence, so the delay is equal to the
93 //delay of the preceding node.
94
95 int delay = 0;
96
Misha Brukman8baa01c2003-04-09 21:51:34 +000097 // self loop will not happen in SSA form
98 assert(defVec[i] != node && "same node?");
99
Misha Brukman8baa01c2003-04-09 21:51:34 +0000100 MachineCodeForInstruction & tempMvec =
101 MachineCodeForInstruction::get(value);
102 for (unsigned j = 0; j < tempMvec.size(); j++) {
103 MachineInstr *temp = tempMvec[j];
Misha Brukman8baa01c2003-04-09 21:51:34 +0000104 delay = std::max(delay, mii.minLatency(temp->getOpCode()));
105 }
106
107 SchedGraphEdge *trueEdge =
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000108 new SchedGraphEdge(defVec[i], node, value,
Misha Brukman8baa01c2003-04-09 21:51:34 +0000109 SchedGraphEdge::TrueDep, delay);
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000110
Misha Brukman8baa01c2003-04-09 21:51:34 +0000111 // if the ref instruction is before the def instrution
112 // then the def instruction must be a phi instruction
113 // add an anti-dependence edge to from the ref instruction to the def
114 // instruction
115 if (node->getOrigIndexInBB() < defVec[i]->getOrigIndexInBB()) {
116 assert(PHINode::classof(inst)
117 && "the ref instruction befre def is not PHINode?");
118 trueEdge->setIteDiff(1);
119 }
120
Guochun Shif1c154f2003-03-27 17:57:44 +0000121 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000122
Misha Brukman8baa01c2003-04-09 21:51:34 +0000123 }
124 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000125}
126
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000127void
128ModuloSchedGraph::addCDEdges(const BasicBlock * bb) {
129
Misha Brukman8baa01c2003-04-09 21:51:34 +0000130 // find the last instruction in the basic block
131 // see if it is an branch instruction.
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000132 // If yes, then add an edge from each node expcept the last node
133 //to the last node
134
Misha Brukman8baa01c2003-04-09 21:51:34 +0000135 const Instruction *inst = &(bb->back());
136 ModuloSchedGraphNode *lastNode = (*this)[inst];
137 if (TerminatorInst::classof(inst))
138 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E;
139 I++) {
140 if (inst != I) {
141 ModuloSchedGraphNode *node = (*this)[I];
142 //use latency of 0
143 (void) new SchedGraphEdge(node, lastNode, SchedGraphEdge::CtrlDep,
144 SchedGraphEdge::NonDataDep, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000145 }
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000146
Misha Brukman8baa01c2003-04-09 21:51:34 +0000147 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000148}
149
Misha Brukman8baa01c2003-04-09 21:51:34 +0000150static const int SG_LOAD_REF = 0;
Guochun Shif1c154f2003-03-27 17:57:44 +0000151static const int SG_STORE_REF = 1;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000152static const int SG_CALL_REF = 2;
Guochun Shif1c154f2003-03-27 17:57:44 +0000153
154static const unsigned int SG_DepOrderArray[][3] = {
Misha Brukman8baa01c2003-04-09 21:51:34 +0000155 {SchedGraphEdge::NonDataDep,
156 SchedGraphEdge::AntiDep,
157 SchedGraphEdge::AntiDep},
158 {SchedGraphEdge::TrueDep,
159 SchedGraphEdge::OutputDep,
160 SchedGraphEdge::TrueDep | SchedGraphEdge::OutputDep},
161 {SchedGraphEdge::TrueDep,
162 SchedGraphEdge::AntiDep | SchedGraphEdge::OutputDep,
163 SchedGraphEdge::TrueDep | SchedGraphEdge::AntiDep
164 | SchedGraphEdge::OutputDep}
Guochun Shif1c154f2003-03-27 17:57:44 +0000165};
166
167
168// Add a dependence edge between every pair of machine load/store/call
169// instructions, where at least one is a store or a call.
170// Use latency 1 just to ensure that memory operations are ordered;
171// latency does not otherwise matter (true dependences enforce that).
172//
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000173void
174ModuloSchedGraph::addMemEdges(const BasicBlock * bb) {
Misha Brukman8baa01c2003-04-09 21:51:34 +0000175
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000176 vector<ModuloSchedGraphNode*> memNodeVec;
177
Guochun Shif1c154f2003-03-27 17:57:44 +0000178 //construct the memNodeVec
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000179 for (BasicBlock::const_iterator I = bb->begin(),
180 E = bb->end(); I != E; ++I) {
181
Misha Brukman8baa01c2003-04-09 21:51:34 +0000182 if (LoadInst::classof(I) || StoreInst::classof(I)
183 || CallInst::classof(I)) {
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000184
Misha Brukman8baa01c2003-04-09 21:51:34 +0000185 ModuloSchedGraphNode *node = (*this)[(const Instruction *) I];
186 memNodeVec.push_back(node);
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000187
Misha Brukman8baa01c2003-04-09 21:51:34 +0000188 }
189 }
190
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000191 // Instructions in memNodeVec are in execution order within the
192 // basic block, so simply look at all pairs
193 // <memNodeVec[i], memNodeVec[j: j > i]>.
194
Misha Brukman8baa01c2003-04-09 21:51:34 +0000195 for (unsigned im = 0, NM = memNodeVec.size(); im < NM; im++) {
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000196
197 const Instruction *fromInst,*toInst;
198 int toType, fromType;
199
200 //get the first mem instruction and instruction type
201 fromInst = memNodeVec[im]->getInst();
202 fromType = CallInst::classof(fromInst) ? SG_CALL_REF
203 : LoadInst::classof(fromInst) ? SG_LOAD_REF : SG_STORE_REF;
204
Misha Brukman8baa01c2003-04-09 21:51:34 +0000205 for (unsigned jm = im + 1; jm < NM; jm++) {
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000206
207 //get the second mem instruction and instruction type
208 toInst = memNodeVec[jm]->getInst();
209 toType = CallInst::classof(toInst) ? SG_CALL_REF
Misha Brukman8baa01c2003-04-09 21:51:34 +0000210 : LoadInst::classof(toInst) ? SG_LOAD_REF : SG_STORE_REF;
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000211
212 //add two edges if not both of them are LOAD instructions
Misha Brukman8baa01c2003-04-09 21:51:34 +0000213 if (fromType != SG_LOAD_REF || toType != SG_LOAD_REF) {
214 (void) new SchedGraphEdge(memNodeVec[im], memNodeVec[jm],
215 SchedGraphEdge::MemoryDep,
216 SG_DepOrderArray[fromType][toType], 1);
217
218 SchedGraphEdge *edge =
219 new SchedGraphEdge(memNodeVec[jm], memNodeVec[im],
220 SchedGraphEdge::MemoryDep,
221 SG_DepOrderArray[toType][fromType], 1);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000222
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000223 //set the iteration difference for this edge to 1.
224 edge->setIteDiff(1);
225
Misha Brukman8baa01c2003-04-09 21:51:34 +0000226 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000227 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000228 }
229}
Guochun Shif1c154f2003-03-27 17:57:44 +0000230
231
232
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000233void
234ModuloSchedGraph::buildNodesforBB(const TargetMachine &target,
235 const BasicBlock *bb){
236
Misha Brukman8baa01c2003-04-09 21:51:34 +0000237 int i = 0;
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000238 ModuloSchedGraphNode *node;
239
240 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end();
241 I != E; ++I) {
242
243 node=new ModuloSchedGraphNode(getNumNodes(), bb, I, i, target);
244
Misha Brukman8baa01c2003-04-09 21:51:34 +0000245 i++;
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000246
247 this->addHash(I, node);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000248 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000249
Guochun Shif1c154f2003-03-27 17:57:44 +0000250}
251
252
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000253bool
254ModuloSchedGraph::isLoop(const BasicBlock *bb) {
255
Guochun Shif1c154f2003-03-27 17:57:44 +0000256 //only if the last instruction in the basicblock is branch instruction and
257 //there is at least an option to branch itself
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000258
Misha Brukman8baa01c2003-04-09 21:51:34 +0000259 const Instruction *inst = &(bb->back());
260 if (BranchInst::classof(inst)) {
261 for (unsigned i = 0; i < ((BranchInst *) inst)->getNumSuccessors();
262 i++) {
263 BasicBlock *sb = ((BranchInst *) inst)->getSuccessor(i);
264 if (sb == bb)
265 return true;
266 }
267 }
268
Guochun Shif1c154f2003-03-27 17:57:44 +0000269 return false;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000270
Guochun Shif1c154f2003-03-27 17:57:44 +0000271}
Misha Brukman8baa01c2003-04-09 21:51:34 +0000272
Misha Brukman8baa01c2003-04-09 21:51:34 +0000273void ModuloSchedGraph::computeNodeASAP(const BasicBlock *bb) {
274
275 //FIXME: now assume the only backward edges come from the edges from other
276 //nodes to the phi Node so i will ignore all edges to the phi node; after
277 //this, there shall be no recurrence.
278
279 unsigned numNodes = bb->size();
280 for (unsigned i = 2; i < numNodes + 2; i++) {
281 ModuloSchedGraphNode *node = getNode(i);
282 node->setPropertyComputed(false);
283 }
284
285 for (unsigned i = 2; i < numNodes + 2; i++) {
286 ModuloSchedGraphNode *node = getNode(i);
287 node->ASAP = 0;
288 if (i == 2 || node->getNumInEdges() == 0) {
Guochun Shif1c154f2003-03-27 17:57:44 +0000289 node->setPropertyComputed(true);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000290 continue;
Guochun Shif1c154f2003-03-27 17:57:44 +0000291 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000292 for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E =
293 node->endInEdges(); I != E; I++) {
294 SchedGraphEdge *edge = *I;
295 ModuloSchedGraphNode *pred =
296 (ModuloSchedGraphNode *) (edge->getSrc());
297 assert(pred->getPropertyComputed()
298 && "pred node property is not computed!");
299 int temp =
300 pred->ASAP + edge->getMinDelay() -
301 edge->getIteDiff() * this->MII;
302 node->ASAP = std::max(node->ASAP, temp);
303 }
304 node->setPropertyComputed(true);
305 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000306}
307
Misha Brukman8baa01c2003-04-09 21:51:34 +0000308void ModuloSchedGraph::computeNodeALAP(const BasicBlock *bb) {
309 unsigned numNodes = bb->size();
310 int maxASAP = 0;
311 for (unsigned i = numNodes + 1; i >= 2; i--) {
312 ModuloSchedGraphNode *node = getNode(i);
313 node->setPropertyComputed(false);
314 //cerr<< " maxASAP= " <<maxASAP<<" node->ASAP= "<< node->ASAP<<"\n";
315 maxASAP = std::max(maxASAP, node->ASAP);
316 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000317
318 //cerr<<"maxASAP is "<<maxASAP<<"\n";
Misha Brukman8baa01c2003-04-09 21:51:34 +0000319
320 for (unsigned i = numNodes + 1; i >= 2; i--) {
321 ModuloSchedGraphNode *node = getNode(i);
322 node->ALAP = maxASAP;
323 for (ModuloSchedGraphNode::const_iterator I =
324 node->beginOutEdges(), E = node->endOutEdges(); I != E; I++) {
325 SchedGraphEdge *edge = *I;
326 ModuloSchedGraphNode *succ =
327 (ModuloSchedGraphNode *) (edge->getSink());
328 if (PHINode::classof(succ->getInst()))
329 continue;
330 assert(succ->getPropertyComputed()
331 && "succ node property is not computed!");
332 int temp =
333 succ->ALAP - edge->getMinDelay() +
334 edge->getIteDiff() * this->MII;
335 node->ALAP = std::min(node->ALAP, temp);
336 }
337 node->setPropertyComputed(true);
338 }
339}
340
341void ModuloSchedGraph::computeNodeMov(const BasicBlock *bb)
342{
343 unsigned numNodes = bb->size();
344 for (unsigned i = 2; i < numNodes + 2; i++) {
345 ModuloSchedGraphNode *node = getNode(i);
346 node->mov = node->ALAP - node->ASAP;
347 assert(node->mov >= 0
348 && "move freedom for this node is less than zero? ");
349 }
350}
351
352
353void ModuloSchedGraph::computeNodeDepth(const BasicBlock * bb)
354{
355
356 unsigned numNodes = bb->size();
357 for (unsigned i = 2; i < numNodes + 2; i++) {
358 ModuloSchedGraphNode *node = getNode(i);
359 node->setPropertyComputed(false);
360 }
361
362 for (unsigned i = 2; i < numNodes + 2; i++) {
363 ModuloSchedGraphNode *node = getNode(i);
364 node->depth = 0;
365 if (i == 2 || node->getNumInEdges() == 0) {
Guochun Shif1c154f2003-03-27 17:57:44 +0000366 node->setPropertyComputed(true);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000367 continue;
Guochun Shif1c154f2003-03-27 17:57:44 +0000368 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000369 for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E =
370 node->endInEdges(); I != E; I++) {
371 SchedGraphEdge *edge = *I;
372 ModuloSchedGraphNode *pred =
373 (ModuloSchedGraphNode *) (edge->getSrc());
374 assert(pred->getPropertyComputed()
375 && "pred node property is not computed!");
376 int temp = pred->depth + edge->getMinDelay();
377 node->depth = std::max(node->depth, temp);
Guochun Shif1c154f2003-03-27 17:57:44 +0000378 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000379 node->setPropertyComputed(true);
380 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000381
382}
383
384
Misha Brukman8baa01c2003-04-09 21:51:34 +0000385void ModuloSchedGraph::computeNodeHeight(const BasicBlock *bb)
Guochun Shif1c154f2003-03-27 17:57:44 +0000386{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000387 unsigned numNodes = bb->size();
388 for (unsigned i = numNodes + 1; i >= 2; i--) {
389 ModuloSchedGraphNode *node = getNode(i);
390 node->setPropertyComputed(false);
391 }
392
393 for (unsigned i = numNodes + 1; i >= 2; i--) {
394 ModuloSchedGraphNode *node = getNode(i);
395 node->height = 0;
396 for (ModuloSchedGraphNode::const_iterator I =
397 node->beginOutEdges(), E = node->endOutEdges(); I != E; ++I) {
398 SchedGraphEdge *edge = *I;
399 ModuloSchedGraphNode *succ =
400 (ModuloSchedGraphNode *) (edge->getSink());
401 if (PHINode::classof(succ->getInst()))
402 continue;
403 assert(succ->getPropertyComputed()
404 && "succ node property is not computed!");
405 node->height = std::max(node->height, succ->height + edge->getMinDelay());
406
Guochun Shif1c154f2003-03-27 17:57:44 +0000407 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000408 node->setPropertyComputed(true);
409
410 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000411
412}
413
Misha Brukman8baa01c2003-04-09 21:51:34 +0000414void ModuloSchedGraph::computeNodeProperty(const BasicBlock * bb)
Guochun Shif1c154f2003-03-27 17:57:44 +0000415{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000416 //FIXME: now assume the only backward edges come from the edges from other
417 //nodes to the phi Node so i will ignore all edges to the phi node; after
418 //this, there shall be no recurrence.
419
Guochun Shif1c154f2003-03-27 17:57:44 +0000420 this->computeNodeASAP(bb);
421 this->computeNodeALAP(bb);
422 this->computeNodeMov(bb);
423 this->computeNodeDepth(bb);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000424 this->computeNodeHeight(bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000425}
426
427
428//do not consider the backedge in these two functions:
429// i.e. don't consider the edge with destination in phi node
Misha Brukman8baa01c2003-04-09 21:51:34 +0000430std::vector<ModuloSchedGraphNode*>
431ModuloSchedGraph::predSet(std::vector<ModuloSchedGraphNode*> set,
432 unsigned backEdgeSrc,
433 unsigned
434 backEdgeSink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000435{
436 std::vector<ModuloSchedGraphNode*> predS;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000437 for (unsigned i = 0; i < set.size(); i++) {
438 ModuloSchedGraphNode *node = set[i];
439 for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E =
440 node->endInEdges(); I != E; I++) {
441 SchedGraphEdge *edge = *I;
442 if (edge->getSrc()->getNodeId() == backEdgeSrc
443 && edge->getSink()->getNodeId() == backEdgeSink)
444 continue;
445 ModuloSchedGraphNode *pred =
446 (ModuloSchedGraphNode *) (edge->getSrc());
447 //if pred is not in the predSet, push it in vector
448 bool alreadyInset = false;
449 for (unsigned j = 0; j < predS.size(); ++j)
450 if (predS[j]->getNodeId() == pred->getNodeId()) {
451 alreadyInset = true;
452 break;
453 }
454
455 for (unsigned j = 0; j < set.size(); ++j)
456 if (set[j]->getNodeId() == pred->getNodeId()) {
457 alreadyInset = true;
458 break;
459 }
460
461 if (!alreadyInset)
462 predS.push_back(pred);
Guochun Shif1c154f2003-03-27 17:57:44 +0000463 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000464 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000465 return predS;
466}
467
468ModuloSchedGraph::NodeVec ModuloSchedGraph::predSet(NodeVec set)
469{
470 //node number increases from 2
Misha Brukman8baa01c2003-04-09 21:51:34 +0000471 return predSet(set, 0, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000472}
473
Misha Brukman8baa01c2003-04-09 21:51:34 +0000474std::vector <ModuloSchedGraphNode*>
475ModuloSchedGraph::predSet(ModuloSchedGraphNode *_node,
476 unsigned backEdgeSrc, unsigned backEdgeSink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000477{
Guochun Shif1c154f2003-03-27 17:57:44 +0000478 std::vector<ModuloSchedGraphNode*> set;
479 set.push_back(_node);
480 return predSet(set, backEdgeSrc, backEdgeSink);
Guochun Shif1c154f2003-03-27 17:57:44 +0000481}
482
Misha Brukman8baa01c2003-04-09 21:51:34 +0000483std::vector <ModuloSchedGraphNode*>
484ModuloSchedGraph::predSet(ModuloSchedGraphNode * _node)
Guochun Shif1c154f2003-03-27 17:57:44 +0000485{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000486 return predSet(_node, 0, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000487}
488
Misha Brukman8baa01c2003-04-09 21:51:34 +0000489std::vector<ModuloSchedGraphNode*>
490ModuloSchedGraph::succSet(std::vector<ModuloSchedGraphNode*> set,
491 unsigned src, unsigned sink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000492{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000493 std::vector<ModuloSchedGraphNode*> succS;
494 for (unsigned i = 0; i < set.size(); i++) {
495 ModuloSchedGraphNode *node = set[i];
496 for (ModuloSchedGraphNode::const_iterator I =
497 node->beginOutEdges(), E = node->endOutEdges(); I != E; I++) {
498 SchedGraphEdge *edge = *I;
499 if (edge->getSrc()->getNodeId() == src
500 && edge->getSink()->getNodeId() == sink)
501 continue;
502 ModuloSchedGraphNode *succ =
503 (ModuloSchedGraphNode *) (edge->getSink());
504 //if pred is not in the predSet, push it in vector
505 bool alreadyInset = false;
506 for (unsigned j = 0; j < succS.size(); j++)
507 if (succS[j]->getNodeId() == succ->getNodeId()) {
508 alreadyInset = true;
509 break;
510 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000511
Misha Brukman8baa01c2003-04-09 21:51:34 +0000512 for (unsigned j = 0; j < set.size(); j++)
513 if (set[j]->getNodeId() == succ->getNodeId()) {
514 alreadyInset = true;
515 break;
516 }
517 if (!alreadyInset)
518 succS.push_back(succ);
Guochun Shif1c154f2003-03-27 17:57:44 +0000519 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000520 }
521 return succS;
Guochun Shif1c154f2003-03-27 17:57:44 +0000522}
523
524ModuloSchedGraph::NodeVec ModuloSchedGraph::succSet(NodeVec set)
525{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000526 return succSet(set, 0, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000527}
528
529
Misha Brukman8baa01c2003-04-09 21:51:34 +0000530std::vector<ModuloSchedGraphNode*>
531ModuloSchedGraph::succSet(ModuloSchedGraphNode *_node,
532 unsigned src, unsigned sink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000533{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000534 std::vector<ModuloSchedGraphNode*>set;
Guochun Shif1c154f2003-03-27 17:57:44 +0000535 set.push_back(_node);
536 return succSet(set, src, sink);
Guochun Shif1c154f2003-03-27 17:57:44 +0000537}
538
Misha Brukman8baa01c2003-04-09 21:51:34 +0000539std::vector<ModuloSchedGraphNode*>
540ModuloSchedGraph::succSet(ModuloSchedGraphNode * _node)
Guochun Shif1c154f2003-03-27 17:57:44 +0000541{
542 return succSet(_node, 0, 0);
543}
544
Misha Brukman8baa01c2003-04-09 21:51:34 +0000545SchedGraphEdge *ModuloSchedGraph::getMaxDelayEdge(unsigned srcId,
546 unsigned sinkId)
Guochun Shif1c154f2003-03-27 17:57:44 +0000547{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000548 ModuloSchedGraphNode *node = getNode(srcId);
549 SchedGraphEdge *maxDelayEdge = NULL;
550 int maxDelay = -1;
551 for (ModuloSchedGraphNode::const_iterator I = node->beginOutEdges(), E =
552 node->endOutEdges(); I != E; I++) {
553 SchedGraphEdge *edge = *I;
554 if (edge->getSink()->getNodeId() == sinkId)
555 if (edge->getMinDelay() > maxDelay) {
556 maxDelayEdge = edge;
557 maxDelay = edge->getMinDelay();
558 }
559 }
560 assert(maxDelayEdge != NULL && "no edge between the srcId and sinkId?");
Guochun Shif1c154f2003-03-27 17:57:44 +0000561 return maxDelayEdge;
562}
563
564void ModuloSchedGraph::dumpCircuits()
565{
Guochun Shi33280522003-06-08 20:40:47 +0000566 DEBUG_PRINT(std::cerr << "dumping circuits for graph:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000567 int j = -1;
568 while (circuits[++j][0] != 0) {
569 int k = -1;
570 while (circuits[j][++k] != 0)
Guochun Shi33280522003-06-08 20:40:47 +0000571 DEBUG_PRINT(std::cerr << circuits[j][k] << "\t");
572 DEBUG_PRINT(std::cerr << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +0000573 }
574}
575
Misha Brukman8baa01c2003-04-09 21:51:34 +0000576void ModuloSchedGraph::dumpSet(std::vector < ModuloSchedGraphNode * >set)
Guochun Shif1c154f2003-03-27 17:57:44 +0000577{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000578 for (unsigned i = 0; i < set.size(); i++)
Guochun Shi33280522003-06-08 20:40:47 +0000579 DEBUG_PRINT(std::cerr << set[i]->getNodeId() << "\t");
580 DEBUG_PRINT(std::cerr << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +0000581}
582
Misha Brukman8baa01c2003-04-09 21:51:34 +0000583std::vector<ModuloSchedGraphNode*>
584ModuloSchedGraph::vectorUnion(std::vector<ModuloSchedGraphNode*> set1,
585 std::vector<ModuloSchedGraphNode*> set2)
Guochun Shif1c154f2003-03-27 17:57:44 +0000586{
587 std::vector<ModuloSchedGraphNode*> unionVec;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000588 for (unsigned i = 0; i < set1.size(); i++)
Guochun Shif1c154f2003-03-27 17:57:44 +0000589 unionVec.push_back(set1[i]);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000590 for (unsigned j = 0; j < set2.size(); j++) {
591 bool inset = false;
592 for (unsigned i = 0; i < unionVec.size(); i++)
593 if (set2[j] == unionVec[i])
594 inset = true;
595 if (!inset)
596 unionVec.push_back(set2[j]);
Guochun Shif1c154f2003-03-27 17:57:44 +0000597 }
598 return unionVec;
599}
Misha Brukman8baa01c2003-04-09 21:51:34 +0000600
601std::vector<ModuloSchedGraphNode*>
602ModuloSchedGraph::vectorConj(std::vector<ModuloSchedGraphNode*> set1,
603 std::vector<ModuloSchedGraphNode*> set2)
Guochun Shif1c154f2003-03-27 17:57:44 +0000604{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000605 std::vector<ModuloSchedGraphNode*> conjVec;
606 for (unsigned i = 0; i < set1.size(); i++)
607 for (unsigned j = 0; j < set2.size(); j++)
608 if (set1[i] == set2[j])
609 conjVec.push_back(set1[i]);
610 return conjVec;
Guochun Shif1c154f2003-03-27 17:57:44 +0000611}
612
Misha Brukman8baa01c2003-04-09 21:51:34 +0000613ModuloSchedGraph::NodeVec ModuloSchedGraph::vectorSub(NodeVec set1,
614 NodeVec set2)
Guochun Shif1c154f2003-03-27 17:57:44 +0000615{
616 NodeVec newVec;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000617 for (NodeVec::iterator I = set1.begin(); I != set1.end(); I++) {
618 bool inset = false;
619 for (NodeVec::iterator II = set2.begin(); II != set2.end(); II++)
620 if ((*I)->getNodeId() == (*II)->getNodeId()) {
621 inset = true;
622 break;
623 }
624 if (!inset)
625 newVec.push_back(*I);
Guochun Shif1c154f2003-03-27 17:57:44 +0000626 }
627 return newVec;
628}
Guochun Shif1c154f2003-03-27 17:57:44 +0000629
Misha Brukman8baa01c2003-04-09 21:51:34 +0000630void ModuloSchedGraph::orderNodes() {
631 oNodes.clear();
632
633 std::vector < ModuloSchedGraphNode * >set;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000634 unsigned numNodes = bb->size();
635
Misha Brukman2c821cc2003-04-10 19:19:23 +0000636 // first order all the sets
Misha Brukman8baa01c2003-04-09 21:51:34 +0000637 int j = -1;
638 int totalDelay = -1;
639 int preDelay = -1;
640 while (circuits[++j][0] != 0) {
641 int k = -1;
642 preDelay = totalDelay;
643
644 while (circuits[j][++k] != 0) {
645 ModuloSchedGraphNode *node = getNode(circuits[j][k]);
Guochun Shif1c154f2003-03-27 17:57:44 +0000646 unsigned nextNodeId;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000647 nextNodeId =
648 circuits[j][k + 1] != 0 ? circuits[j][k + 1] : circuits[j][0];
649 SchedGraphEdge *edge = getMaxDelayEdge(circuits[j][k], nextNodeId);
Guochun Shif1c154f2003-03-27 17:57:44 +0000650 totalDelay += edge->getMinDelay();
651 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000652 if (preDelay != -1 && totalDelay > preDelay) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000653 // swap circuits[j][] and cuicuits[j-1][]
Guochun Shif1c154f2003-03-27 17:57:44 +0000654 unsigned temp[MAXNODE];
Misha Brukman8baa01c2003-04-09 21:51:34 +0000655 for (int k = 0; k < MAXNODE; k++) {
656 temp[k] = circuits[j - 1][k];
657 circuits[j - 1][k] = circuits[j][k];
658 circuits[j][k] = temp[k];
Guochun Shif1c154f2003-03-27 17:57:44 +0000659 }
660 //restart
Misha Brukman8baa01c2003-04-09 21:51:34 +0000661 j = -1;
Guochun Shif1c154f2003-03-27 17:57:44 +0000662 }
663 }
664
Misha Brukman2c821cc2003-04-10 19:19:23 +0000665 // build the first set
Guochun Shif1c154f2003-03-27 17:57:44 +0000666 int backEdgeSrc;
667 int backEdgeSink;
Misha Brukman2c821cc2003-04-10 19:19:23 +0000668 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000669 DEBUG_PRINT(std::cerr << "building the first set" << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000670 int setSeq = -1;
671 int k = -1;
Guochun Shif1c154f2003-03-27 17:57:44 +0000672 setSeq++;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000673 while (circuits[setSeq][++k] != 0)
Guochun Shif1c154f2003-03-27 17:57:44 +0000674 set.push_back(getNode(circuits[setSeq][k]));
Misha Brukman8baa01c2003-04-09 21:51:34 +0000675 if (circuits[setSeq][0] != 0) {
676 backEdgeSrc = circuits[setSeq][k - 1];
677 backEdgeSink = circuits[setSeq][0];
Guochun Shif1c154f2003-03-27 17:57:44 +0000678 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000679 if (ModuloScheduling::printScheduleProcess()) {
Guochun Shi33280522003-06-08 20:40:47 +0000680 DEBUG_PRINT(std::cerr << "the first set is:");
Guochun Shif1c154f2003-03-27 17:57:44 +0000681 dumpSet(set);
682 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000683 // implement the ordering algorithm
Misha Brukman8baa01c2003-04-09 21:51:34 +0000684 enum OrderSeq { bottom_up, top_down };
Guochun Shif1c154f2003-03-27 17:57:44 +0000685 OrderSeq order;
686 std::vector<ModuloSchedGraphNode*> R;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000687 while (!set.empty()) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000688 std::vector<ModuloSchedGraphNode*> pset = predSet(oNodes);
689 std::vector<ModuloSchedGraphNode*> sset = succSet(oNodes);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000690
691 if (!pset.empty() && !vectorConj(pset, set).empty()) {
692 R = vectorConj(pset, set);
693 order = bottom_up;
694 } else if (!sset.empty() && !vectorConj(sset, set).empty()) {
695 R = vectorConj(sset, set);
696 order = top_down;
697 } else {
698 int maxASAP = -1;
699 int position = -1;
700 for (unsigned i = 0; i < set.size(); i++) {
701 int temp = set[i]->getASAP();
702 if (temp > maxASAP) {
703 maxASAP = temp;
704 position = i;
705 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000706 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000707 R.push_back(set[position]);
708 order = bottom_up;
709 }
710
711 while (!R.empty()) {
712 if (order == top_down) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000713 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000714 DEBUG_PRINT(std::cerr << "in top_down round\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000715 while (!R.empty()) {
716 int maxHeight = -1;
717 NodeVec::iterator chosenI;
718 for (NodeVec::iterator I = R.begin(); I != R.end(); I++) {
719 int temp = (*I)->height;
720 if ((temp > maxHeight)
721 || (temp == maxHeight && (*I)->mov <= (*chosenI)->mov)) {
722
723 if ((temp > maxHeight)
724 || (temp == maxHeight && (*I)->mov < (*chosenI)->mov)) {
725 maxHeight = temp;
726 chosenI = I;
727 continue;
728 }
729 //possible case: instruction A and B has the same height and mov,
730 //but A has dependence to B e.g B is the branch instruction in the
731 //end, or A is the phi instruction at the beginning
732 if ((*I)->mov == (*chosenI)->mov)
733 for (ModuloSchedGraphNode::const_iterator oe =
734 (*I)->beginOutEdges(), end = (*I)->endOutEdges();
735 oe != end; oe++) {
736 if ((*oe)->getSink() == (*chosenI)) {
737 maxHeight = temp;
738 chosenI = I;
739 continue;
740 }
741 }
742 }
743 }
744 ModuloSchedGraphNode *mu = *chosenI;
745 oNodes.push_back(mu);
746 R.erase(chosenI);
747 std::vector<ModuloSchedGraphNode*> succ_mu =
748 succSet(mu, backEdgeSrc, backEdgeSink);
749 std::vector<ModuloSchedGraphNode*> comm =
750 vectorConj(succ_mu, set);
751 comm = vectorSub(comm, oNodes);
752 R = vectorUnion(comm, R);
753 }
754 order = bottom_up;
755 R = vectorConj(predSet(oNodes), set);
756 } else {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000757 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000758 DEBUG_PRINT(std::cerr << "in bottom up round\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000759 while (!R.empty()) {
760 int maxDepth = -1;
761 NodeVec::iterator chosenI;
762 for (NodeVec::iterator I = R.begin(); I != R.end(); I++) {
763 int temp = (*I)->depth;
764 if ((temp > maxDepth)
765 || (temp == maxDepth && (*I)->mov < (*chosenI)->mov)) {
766 maxDepth = temp;
767 chosenI = I;
768 }
769 }
770 ModuloSchedGraphNode *mu = *chosenI;
771 oNodes.push_back(mu);
772 R.erase(chosenI);
773 std::vector<ModuloSchedGraphNode*> pred_mu =
774 predSet(mu, backEdgeSrc, backEdgeSink);
775 std::vector<ModuloSchedGraphNode*> comm =
776 vectorConj(pred_mu, set);
777 comm = vectorSub(comm, oNodes);
778 R = vectorUnion(comm, R);
779 }
780 order = top_down;
781 R = vectorConj(succSet(oNodes), set);
Guochun Shif1c154f2003-03-27 17:57:44 +0000782 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000783 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000784 if (ModuloScheduling::printScheduleProcess()) {
Guochun Shi33280522003-06-08 20:40:47 +0000785 DEBUG_PRINT(std::cerr << "order finished\n");
786 DEBUG_PRINT(std::cerr << "dumping the ordered nodes:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000787 dumpSet(oNodes);
788 dumpCircuits();
789 }
790 //create a new set
791 //FIXME: the nodes between onodes and this circuit should also be include in
792 //this set
Misha Brukman2c821cc2003-04-10 19:19:23 +0000793 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000794 DEBUG_PRINT(std::cerr << "building the next set\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000795 set.clear();
796 int k = -1;
797 setSeq++;
798 while (circuits[setSeq][++k] != 0)
799 set.push_back(getNode(circuits[setSeq][k]));
800 if (circuits[setSeq][0] != 0) {
801 backEdgeSrc = circuits[setSeq][k - 1];
802 backEdgeSink = circuits[setSeq][0];
803 }
804 if (set.empty()) {
805 //no circuits any more
806 //collect all other nodes
Misha Brukman2c821cc2003-04-10 19:19:23 +0000807 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000808 DEBUG_PRINT(std::cerr << "no circuits any more, collect the rest nodes\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000809 for (unsigned i = 2; i < numNodes + 2; i++) {
810 bool inset = false;
811 for (unsigned j = 0; j < oNodes.size(); j++)
812 if (oNodes[j]->getNodeId() == i) {
813 inset = true;
814 break;
815 }
816 if (!inset)
817 set.push_back(getNode(i));
Guochun Shif1c154f2003-03-27 17:57:44 +0000818 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000819 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000820 if (ModuloScheduling::printScheduleProcess()) {
Guochun Shi33280522003-06-08 20:40:47 +0000821 DEBUG_PRINT(std::cerr << "next set is:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000822 dumpSet(set);
823 }
824 } //while(!set.empty())
825
Guochun Shif1c154f2003-03-27 17:57:44 +0000826}
827
828
829
Misha Brukman8baa01c2003-04-09 21:51:34 +0000830void ModuloSchedGraph::buildGraph(const TargetMachine & target)
Guochun Shif1c154f2003-03-27 17:57:44 +0000831{
Guochun Shif1c154f2003-03-27 17:57:44 +0000832
Guochun Shi099b0642003-06-02 17:48:56 +0000833 assert(this->bb && "The basicBlock is NULL?");
Guochun Shif1c154f2003-03-27 17:57:44 +0000834
Guochun Shif1c154f2003-03-27 17:57:44 +0000835
Misha Brukman8baa01c2003-04-09 21:51:34 +0000836 // Make a dummy root node. We'll add edges to the real roots later.
837 graphRoot = new ModuloSchedGraphNode(0, NULL, NULL, -1, target);
838 graphLeaf = new ModuloSchedGraphNode(1, NULL, NULL, -1, target);
839
840 //----------------------------------------------------------------
841 // First add nodes for all the LLVM instructions in the basic block because
842 // this greatly simplifies identifying which edges to add. Do this one VM
843 // instruction at a time since the ModuloSchedGraphNode needs that.
Guochun Shif1c154f2003-03-27 17:57:44 +0000844 // Also, remember the load/store instructions to add memory deps later.
845 //----------------------------------------------------------------
846
847 //FIXME:if there is call instruction, then we shall quit somewhere
848 // currently we leave call instruction and continue construct graph
849
850 //dump only the blocks which are from loops
851
852
Misha Brukman2c821cc2003-04-10 19:19:23 +0000853 if (ModuloScheduling::printScheduleProcess())
Guochun Shif1c154f2003-03-27 17:57:44 +0000854 this->dump(bb);
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000855
Misha Brukman8baa01c2003-04-09 21:51:34 +0000856 if (isLoop(bb)) {
Misha Brukman8baa01c2003-04-09 21:51:34 +0000857
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000858 DEBUG_PRINT(cerr << "building nodes for this BasicBlock\n");
859 buildNodesforBB(target, bb);
860
861 DEBUG_PRINT(cerr << "adding def-use edge to this basic block\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000862 this->addDefUseEdges(bb);
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000863
864 DEBUG_PRINT(cerr << "adding CD edges to this basic block\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000865 this->addCDEdges(bb);
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000866
867 DEBUG_PRINT(cerr << "adding memory edges to this basicblock\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000868 this->addMemEdges(bb);
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000869
Misha Brukman8baa01c2003-04-09 21:51:34 +0000870 int ResII = this->computeResII(bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000871 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000872 DEBUG_PRINT(std::cerr << "ResII is " << ResII << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000873 int RecII = this->computeRecII(bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000874 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000875 DEBUG_PRINT(std::cerr << "RecII is " << RecII << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000876
877 this->MII = std::max(ResII, RecII);
878
879 this->computeNodeProperty(bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000880 if (ModuloScheduling::printScheduleProcess())
Misha Brukman8baa01c2003-04-09 21:51:34 +0000881 this->dumpNodeProperty();
882
883 this->orderNodes();
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000884
Misha Brukman2c821cc2003-04-10 19:19:23 +0000885 if (ModuloScheduling::printScheduleProcess())
Misha Brukman8baa01c2003-04-09 21:51:34 +0000886 this->dump();
Misha Brukman8baa01c2003-04-09 21:51:34 +0000887
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000888 //this->instrScheduling();
889
Misha Brukman8baa01c2003-04-09 21:51:34 +0000890 //this->dumpScheduling();
891 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000892}
893
Misha Brukman8baa01c2003-04-09 21:51:34 +0000894ModuloSchedGraphNode *ModuloSchedGraph::getNode(const unsigned nodeId) const
Guochun Shif1c154f2003-03-27 17:57:44 +0000895{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000896 for (const_iterator I = begin(), E = end(); I != E; I++)
897 if ((*I).second->getNodeId() == nodeId)
898 return (ModuloSchedGraphNode *) (*I).second;
Guochun Shif1c154f2003-03-27 17:57:44 +0000899 return NULL;
900}
901
Misha Brukman8baa01c2003-04-09 21:51:34 +0000902int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
Guochun Shif1c154f2003-03-27 17:57:44 +0000903{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000904 int RecII = 0;
Guochun Shif1c154f2003-03-27 17:57:44 +0000905
906 //os<<"begining computerRecII()"<<"\n";
907
Misha Brukman8baa01c2003-04-09 21:51:34 +0000908 //FIXME: only deal with circuits starting at the first node: the phi node
909 //nodeId=2;
Guochun Shif1c154f2003-03-27 17:57:44 +0000910
911 //search all elementary circuits in the dependance graph
912 //assume maximum number of nodes is MAXNODE
Misha Brukman8baa01c2003-04-09 21:51:34 +0000913
Guochun Shif1c154f2003-03-27 17:57:44 +0000914 unsigned path[MAXNODE];
915 unsigned stack[MAXNODE][MAXNODE];
916
Misha Brukman8baa01c2003-04-09 21:51:34 +0000917 for (int j = 0; j < MAXNODE; j++) {
918 path[j] = 0;
919 for (int k = 0; k < MAXNODE; k++)
920 stack[j][k] = 0;
921 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000922 //in our graph, the node number starts at 2
923
924 //number of nodes, because each instruction will result in one node
Misha Brukman8baa01c2003-04-09 21:51:34 +0000925 const unsigned numNodes = bb->size();
Guochun Shif1c154f2003-03-27 17:57:44 +0000926
Misha Brukman8baa01c2003-04-09 21:51:34 +0000927 int i = 0;
928 path[i] = 2;
Guochun Shif1c154f2003-03-27 17:57:44 +0000929
Misha Brukman8baa01c2003-04-09 21:51:34 +0000930 ModuloSchedGraphNode *initNode = getNode(path[0]);
931 unsigned initNodeId = initNode->getNodeId();
932 ModuloSchedGraphNode *currentNode = initNode;
Guochun Shif1c154f2003-03-27 17:57:44 +0000933
Misha Brukman8baa01c2003-04-09 21:51:34 +0000934 while (currentNode != NULL) {
935 unsigned currentNodeId = currentNode->getNodeId();
Guochun Shi33280522003-06-08 20:40:47 +0000936 // DEBUG_PRINT(std::cerr<<"current node is "<<currentNodeId<<"\n");
Guochun Shif1c154f2003-03-27 17:57:44 +0000937
Misha Brukman8baa01c2003-04-09 21:51:34 +0000938 ModuloSchedGraphNode *nextNode = NULL;
939 for (ModuloSchedGraphNode::const_iterator I =
940 currentNode->beginOutEdges(), E = currentNode->endOutEdges();
941 I != E; I++) {
Guochun Shi33280522003-06-08 20:40:47 +0000942 //DEBUG_PRINT(std::cerr <<" searching in outgoint edges of node
Misha Brukman8baa01c2003-04-09 21:51:34 +0000943 //"<<currentNodeId<<"\n";
944 unsigned nodeId = ((SchedGraphEdge *) * I)->getSink()->getNodeId();
945 bool inpath = false, instack = false;
946 int k;
Guochun Shif1c154f2003-03-27 17:57:44 +0000947
Guochun Shi33280522003-06-08 20:40:47 +0000948 //DEBUG_PRINT(std::cerr<<"nodeId is "<<nodeId<<"\n");
Guochun Shif1c154f2003-03-27 17:57:44 +0000949
Misha Brukman8baa01c2003-04-09 21:51:34 +0000950 k = -1;
951 while (path[++k] != 0)
952 if (nodeId == path[k]) {
953 inpath = true;
954 break;
955 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000956
Misha Brukman8baa01c2003-04-09 21:51:34 +0000957 k = -1;
958 while (stack[i][++k] != 0)
959 if (nodeId == stack[i][k]) {
960 instack = true;
961 break;
962 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000963
Misha Brukman8baa01c2003-04-09 21:51:34 +0000964 if (nodeId > currentNodeId && !inpath && !instack) {
965 nextNode =
966 (ModuloSchedGraphNode *) ((SchedGraphEdge *) * I)->getSink();
967 break;
968 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000969 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000970
971 if (nextNode != NULL) {
Guochun Shi33280522003-06-08 20:40:47 +0000972 //DEBUG_PRINT(std::cerr<<"find the next Node "<<nextNode->getNodeId()<<"\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000973
974 int j = 0;
975 while (stack[i][j] != 0)
976 j++;
977 stack[i][j] = nextNode->getNodeId();
978
979 i++;
980 path[i] = nextNode->getNodeId();
981 currentNode = nextNode;
982 } else {
Guochun Shi33280522003-06-08 20:40:47 +0000983 //DEBUG_PRINT(std::cerr<<"no expansion any more"<<"\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000984 //confirmCircuit();
985 for (ModuloSchedGraphNode::const_iterator I =
986 currentNode->beginOutEdges(), E = currentNode->endOutEdges();
987 I != E; I++) {
988 unsigned nodeId = ((SchedGraphEdge *) * I)->getSink()->getNodeId();
989 if (nodeId == initNodeId) {
990
991 int j = -1;
992 while (circuits[++j][0] != 0);
993 for (int k = 0; k < MAXNODE; k++)
994 circuits[j][k] = path[k];
995
996 }
997 }
998 //remove this node in the path and clear the corresponding entries in the
999 //stack
1000 path[i] = 0;
1001 int j = 0;
1002 for (j = 0; j < MAXNODE; j++)
1003 stack[i][j] = 0;
1004 i--;
1005 currentNode = getNode(path[i]);
1006 }
1007 if (i == 0) {
1008
Misha Brukman2c821cc2003-04-10 19:19:23 +00001009 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001010 DEBUG_PRINT(std::cerr << "circuits found are:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001011 int j = -1;
1012 while (circuits[++j][0] != 0) {
1013 int k = -1;
1014 while (circuits[j][++k] != 0)
Misha Brukman2c821cc2003-04-10 19:19:23 +00001015 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001016 DEBUG_PRINT(std::cerr << circuits[j][k] << "\t");
Misha Brukman2c821cc2003-04-10 19:19:23 +00001017 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001018 DEBUG_PRINT(std::cerr << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001019
1020 //for this circuit, compute the sum of all edge delay
1021 int sumDelay = 0;
1022 k = -1;
1023 while (circuits[j][++k] != 0) {
1024 //ModuloSchedGraphNode* node =getNode(circuits[j][k]);
1025 unsigned nextNodeId;
1026 nextNodeId =
1027 circuits[j][k + 1] !=
1028 0 ? circuits[j][k + 1] : circuits[j][0];
1029
1030 /*
1031 for(ModuloSchedGraphNode::const_iterator I=node->beginOutEdges(),
1032 E=node->endOutEdges();I !=E; I++)
1033 {
1034 SchedGraphEdge* edge= *I;
1035 if(edge->getSink()->getNodeId() == nextNodeId)
1036 {sumDelay += edge->getMinDelay();break;}
1037 }
1038 */
1039
1040 sumDelay +=
1041 getMaxDelayEdge(circuits[j][k], nextNodeId)->getMinDelay();
1042
1043 }
1044 // assume we have distance 1, in this case the sumDelay is RecII
1045 // this is correct for SSA form only
1046 //
Misha Brukman2c821cc2003-04-10 19:19:23 +00001047 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001048 DEBUG_PRINT(std::cerr << "The total Delay in the circuit is " << sumDelay
Misha Brukman2c821cc2003-04-10 19:19:23 +00001049 << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001050
1051 RecII = RecII > sumDelay ? RecII : sumDelay;
1052
1053 }
1054 return RecII;
1055 }
1056
1057 }
1058
Guochun Shif1c154f2003-03-27 17:57:44 +00001059 return -1;
1060}
1061
Misha Brukman8baa01c2003-04-09 21:51:34 +00001062void ModuloSchedGraph::addResourceUsage(std::vector<std::pair<int,int> > &ruVec,
1063 int rid)
1064{
Guochun Shi33280522003-06-08 20:40:47 +00001065 //DEBUG_PRINT(std::cerr<<"\nadding a resouce , current resouceUsage vector size is
Misha Brukman8baa01c2003-04-09 21:51:34 +00001066 //"<<ruVec.size()<<"\n";
1067 bool alreadyExists = false;
1068 for (unsigned i = 0; i < ruVec.size(); i++) {
1069 if (rid == ruVec[i].first) {
Guochun Shif1c154f2003-03-27 17:57:44 +00001070 ruVec[i].second++;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001071 alreadyExists = true;
Guochun Shif1c154f2003-03-27 17:57:44 +00001072 break;
1073 }
1074 }
Misha Brukman8baa01c2003-04-09 21:51:34 +00001075 if (!alreadyExists)
1076 ruVec.push_back(std::make_pair(rid, 1));
Guochun Shi33280522003-06-08 20:40:47 +00001077 //DEBUG_PRINT(std::cerr<<"current resouceUsage vector size is "<<ruVec.size()<<"\n";
Guochun Shif1c154f2003-03-27 17:57:44 +00001078
1079}
Misha Brukman8baa01c2003-04-09 21:51:34 +00001080void ModuloSchedGraph::dumpResourceUsage(std::vector<std::pair<int,int> > &ru)
Guochun Shif1c154f2003-03-27 17:57:44 +00001081{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001082 TargetSchedInfo & msi = (TargetSchedInfo &) target.getSchedInfo();
1083
Misha Brukman2c821cc2003-04-10 19:19:23 +00001084 std::vector<std::pair<int,int> > resourceNumVector = msi.resourceNumVector;
Guochun Shi33280522003-06-08 20:40:47 +00001085 DEBUG_PRINT(std::cerr << "resourceID\t" << "resourceNum\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001086 for (unsigned i = 0; i < resourceNumVector.size(); i++)
Guochun Shi33280522003-06-08 20:40:47 +00001087 DEBUG_PRINT(std::cerr << resourceNumVector[i].
Misha Brukman2c821cc2003-04-10 19:19:23 +00001088 first << "\t" << resourceNumVector[i].second << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001089
Guochun Shi33280522003-06-08 20:40:47 +00001090 DEBUG_PRINT(std::cerr << " maxNumIssueTotal(issue slot in one cycle) = " << msi.
Misha Brukman2c821cc2003-04-10 19:19:23 +00001091 maxNumIssueTotal << "\n");
Guochun Shi33280522003-06-08 20:40:47 +00001092 DEBUG_PRINT(std::cerr << "resourceID\t resourceUsage\t ResourceNum\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001093 for (unsigned i = 0; i < ru.size(); i++) {
Guochun Shi33280522003-06-08 20:40:47 +00001094 DEBUG_PRINT(std::cerr << ru[i].first << "\t" << ru[i].second);
Misha Brukman8baa01c2003-04-09 21:51:34 +00001095 const unsigned resNum = msi.getCPUResourceNum(ru[i].first);
Guochun Shi33280522003-06-08 20:40:47 +00001096 DEBUG_PRINT(std::cerr << "\t" << resNum << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001097 }
1098}
1099
Misha Brukman8baa01c2003-04-09 21:51:34 +00001100int ModuloSchedGraph::computeResII(const BasicBlock * bb)
Guochun Shif1c154f2003-03-27 17:57:44 +00001101{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001102
1103 const TargetInstrInfo & mii = target.getInstrInfo();
1104 const TargetSchedInfo & msi = target.getSchedInfo();
1105
Guochun Shif1c154f2003-03-27 17:57:44 +00001106 int ResII;
Misha Brukman2c821cc2003-04-10 19:19:23 +00001107 std::vector<std::pair<int,int> > resourceUsage;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001108 //pair<int resourceid, int resourceUsageTimes_in_the_whole_block>
1109
1110 //FIXME: number of functional units the target machine can provide should be
1111 //get from Target here I temporary hardcode it
1112
1113 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E;
1114 I++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001115 if (ModuloScheduling::printScheduleProcess()) {
Guochun Shi33280522003-06-08 20:40:47 +00001116 DEBUG_PRINT(std::cerr << "machine instruction for llvm instruction( node " <<
Misha Brukman2c821cc2003-04-10 19:19:23 +00001117 getGraphNodeForInst(I)->getNodeId() << ")\n");
Guochun Shi33280522003-06-08 20:40:47 +00001118 DEBUG_PRINT(std::cerr << "\t" << *I);
Guochun Shif1c154f2003-03-27 17:57:44 +00001119 }
Misha Brukman8baa01c2003-04-09 21:51:34 +00001120 MachineCodeForInstruction & tempMvec =
1121 MachineCodeForInstruction::get(I);
Misha Brukman2c821cc2003-04-10 19:19:23 +00001122 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001123 DEBUG_PRINT(std::cerr << "size =" << tempMvec.size() << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001124 for (unsigned i = 0; i < tempMvec.size(); i++) {
1125 MachineInstr *minstr = tempMvec[i];
1126
1127 unsigned minDelay = mii.minLatency(minstr->getOpCode());
1128 InstrRUsage rUsage = msi.getInstrRUsage(minstr->getOpCode());
1129 InstrClassRUsage classRUsage =
1130 msi.getClassRUsage(mii.getSchedClass(minstr->getOpCode()));
1131 unsigned totCycles = classRUsage.totCycles;
1132
Misha Brukman2c821cc2003-04-10 19:19:23 +00001133 std::vector<std::vector<resourceId_t> > resources=rUsage.resourcesByCycle;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001134 assert(totCycles == resources.size());
Misha Brukman2c821cc2003-04-10 19:19:23 +00001135 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001136 DEBUG_PRINT(std::cerr << "resources Usage for this Instr(totCycles="
Misha Brukman2c821cc2003-04-10 19:19:23 +00001137 << totCycles << ",mindLatency="
1138 << mii.minLatency(minstr->getOpCode()) << "): " << *minstr
1139 << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001140 for (unsigned j = 0; j < resources.size(); j++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001141 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001142 DEBUG_PRINT(std::cerr << "cycle " << j << ": ");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001143 for (unsigned k = 0; k < resources[j].size(); k++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001144 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001145 DEBUG_PRINT(std::cerr << "\t" << resources[j][k]);
Misha Brukman8baa01c2003-04-09 21:51:34 +00001146 addResourceUsage(resourceUsage, resources[j][k]);
1147 }
Misha Brukman2c821cc2003-04-10 19:19:23 +00001148 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001149 DEBUG_PRINT(std::cerr << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001150 }
1151 }
1152 }
Misha Brukman2c821cc2003-04-10 19:19:23 +00001153 if (ModuloScheduling::printScheduleProcess())
Guochun Shif1c154f2003-03-27 17:57:44 +00001154 this->dumpResourceUsage(resourceUsage);
1155
1156 //compute ResII
Misha Brukman8baa01c2003-04-09 21:51:34 +00001157 ResII = 0;
1158 int issueSlots = msi.maxNumIssueTotal;
1159 for (unsigned i = 0; i < resourceUsage.size(); i++) {
1160 int resourceNum = msi.getCPUResourceNum(resourceUsage[i].first);
1161 int useNum = resourceUsage[i].second;
Guochun Shif1c154f2003-03-27 17:57:44 +00001162 double tempII;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001163 if (resourceNum <= issueSlots)
1164 tempII = ceil(1.0 * useNum / resourceNum);
Guochun Shif1c154f2003-03-27 17:57:44 +00001165 else
Misha Brukman8baa01c2003-04-09 21:51:34 +00001166 tempII = ceil(1.0 * useNum / issueSlots);
1167 ResII = std::max((int) tempII, ResII);
Guochun Shif1c154f2003-03-27 17:57:44 +00001168 }
1169 return ResII;
1170}
1171
Guochun Shif1c154f2003-03-27 17:57:44 +00001172
1173
Guochun Shif1c154f2003-03-27 17:57:44 +00001174
Misha Brukman8baa01c2003-04-09 21:51:34 +00001175void ModuloSchedGraph::dump(const BasicBlock * bb)
Guochun Shif1c154f2003-03-27 17:57:44 +00001176{
Guochun Shi33280522003-06-08 20:40:47 +00001177 DEBUG_PRINT(std::cerr << "dumping basic block:");
1178 DEBUG_PRINT(std::cerr << (bb->hasName()? bb->getName() : "block")
Misha Brukman2c821cc2003-04-10 19:19:23 +00001179 << " (" << bb << ")" << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001180}
1181
Misha Brukman8baa01c2003-04-09 21:51:34 +00001182void ModuloSchedGraph::dump(const BasicBlock * bb, std::ostream & os)
Guochun Shif1c154f2003-03-27 17:57:44 +00001183{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001184 os << "dumping basic block:";
1185 os << (bb->hasName()? bb->getName() : "block")
1186 << " (" << bb << ")" << "\n";
Guochun Shif1c154f2003-03-27 17:57:44 +00001187}
1188
Misha Brukman8baa01c2003-04-09 21:51:34 +00001189void ModuloSchedGraph::dump() const
Guochun Shif1c154f2003-03-27 17:57:44 +00001190{
Guochun Shi33280522003-06-08 20:40:47 +00001191 DEBUG_PRINT(std::cerr << " ModuloSchedGraph for basic Blocks:");
Guochun Shi099b0642003-06-02 17:48:56 +00001192
Guochun Shi33280522003-06-08 20:40:47 +00001193 DEBUG_PRINT(std::cerr << (bb->hasName()? bb->getName() : "block")
Guochun Shi099b0642003-06-02 17:48:56 +00001194 << " (" << bb << ")" << "");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001195
Guochun Shi33280522003-06-08 20:40:47 +00001196 DEBUG_PRINT(std::cerr << "\n\n Actual Root nodes : ");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001197 for (unsigned i = 0, N = graphRoot->outEdges.size(); i < N; i++)
Guochun Shi33280522003-06-08 20:40:47 +00001198 DEBUG_PRINT(std::cerr << graphRoot->outEdges[i]->getSink()->getNodeId()
Misha Brukman2c821cc2003-04-10 19:19:23 +00001199 << ((i == N - 1) ? "" : ", "));
Guochun Shif1c154f2003-03-27 17:57:44 +00001200
Guochun Shi33280522003-06-08 20:40:47 +00001201 DEBUG_PRINT(std::cerr << "\n Graph Nodes:\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001202 //for (const_iterator I=begin(); I != end(); ++I)
Guochun Shi33280522003-06-08 20:40:47 +00001203 //DEBUG_PRINT(std::cerr << "\n" << *I->second;
Guochun Shi099b0642003-06-02 17:48:56 +00001204 unsigned numNodes = bb->size();
Misha Brukman8baa01c2003-04-09 21:51:34 +00001205 for (unsigned i = 2; i < numNodes + 2; i++) {
1206 ModuloSchedGraphNode *node = getNode(i);
Guochun Shi33280522003-06-08 20:40:47 +00001207 DEBUG_PRINT(std::cerr << "\n" << *node);
Misha Brukman8baa01c2003-04-09 21:51:34 +00001208 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001209
Guochun Shi33280522003-06-08 20:40:47 +00001210 DEBUG_PRINT(std::cerr << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001211}
Misha Brukman8baa01c2003-04-09 21:51:34 +00001212
1213void ModuloSchedGraph::dumpNodeProperty() const
Guochun Shif1c154f2003-03-27 17:57:44 +00001214{
Guochun Shi099b0642003-06-02 17:48:56 +00001215
Misha Brukman8baa01c2003-04-09 21:51:34 +00001216 unsigned numNodes = bb->size();
1217 for (unsigned i = 2; i < numNodes + 2; i++) {
1218 ModuloSchedGraphNode *node = getNode(i);
Guochun Shi33280522003-06-08 20:40:47 +00001219 DEBUG_PRINT(std::cerr << "NodeId " << node->getNodeId() << "\t");
1220 DEBUG_PRINT(std::cerr << "ASAP " << node->getASAP() << "\t");
1221 DEBUG_PRINT(std::cerr << "ALAP " << node->getALAP() << "\t");
1222 DEBUG_PRINT(std::cerr << "mov " << node->getMov() << "\t");
1223 DEBUG_PRINT(std::cerr << "depth " << node->getDepth() << "\t");
1224 DEBUG_PRINT(std::cerr << "height " << node->getHeight() << "\t\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001225 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001226}
1227
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001228
1229
1230
1231/************member functions for ModuloSchedGraphSet**************/
1232
1233ModuloSchedGraphSet::ModuloSchedGraphSet(const Function *function,
1234 const TargetMachine &target)
1235: method(function){
1236
1237 buildGraphsForMethod(method, target);
1238
1239}
1240
1241
1242ModuloSchedGraphSet::~ModuloSchedGraphSet(){
1243
1244 //delete all the graphs
1245 for (iterator I = begin(), E = end(); I != E; ++I)
1246 delete *I;
1247}
1248
1249
1250
1251void
1252ModuloSchedGraphSet::buildGraphsForMethod(const Function *F,
1253 const TargetMachine &target){
1254
Guochun Shi099b0642003-06-02 17:48:56 +00001255 for (Function::const_iterator BI = F->begin(); BI != F->end(); ++BI){
1256 const BasicBlock* local_bb;
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001257
Guochun Shi099b0642003-06-02 17:48:56 +00001258 local_bb=BI;
1259 addGraph(new ModuloSchedGraph((BasicBlock*)local_bb, target));
1260 }
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001261
Guochun Shif1c154f2003-03-27 17:57:44 +00001262}
1263
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001264void
1265ModuloSchedGraphSet::dump() const{
1266
1267 DEBUG_PRINT(std::cerr << " ====== ModuloSched graphs for function `" <<
1268 method->getName() << "' =========\n\n");
1269 for (const_iterator I = begin(); I != end(); ++I)
1270 (*I)->dump();
1271
1272 DEBUG_PRINT(std::cerr << "\n=========End graphs for function `" << method->getName()
1273 << "' ==========\n\n");
1274}
1275
1276
1277
1278
1279/********************misc functions***************************/
1280
1281
1282static void
1283dumpBasicBlock(const BasicBlock * bb){
1284
1285 DEBUG_PRINT(std::cerr << "dumping basic block:");
1286 DEBUG_PRINT(std::cerr << (bb->hasName()? bb->getName() : "block")
1287 << " (" << bb << ")" << "\n");
1288}
1289
1290
Misha Brukman63e04f32003-04-22 23:00:08 +00001291std::ostream& operator<<(std::ostream &os,
1292 const ModuloSchedGraphNode &node)
Guochun Shif1c154f2003-03-27 17:57:44 +00001293{
1294 os << std::string(8, ' ')
Misha Brukman8baa01c2003-04-09 21:51:34 +00001295 << "Node " << node.nodeId << " : "
1296 << "latency = " << node.latency << "\n" << std::string(12, ' ');
Guochun Shif1c154f2003-03-27 17:57:44 +00001297
1298 if (node.getInst() == NULL)
1299 os << "(Dummy node)\n";
Misha Brukman8baa01c2003-04-09 21:51:34 +00001300 else {
1301 os << *node.getInst() << "\n" << std::string(12, ' ');
1302 os << node.inEdges.size() << " Incoming Edges:\n";
1303 for (unsigned i = 0, N = node.inEdges.size(); i < N; i++)
1304 os << std::string(16, ' ') << *node.inEdges[i];
1305
1306 os << std::string(12, ' ') << node.outEdges.size()
1307 << " Outgoing Edges:\n";
1308 for (unsigned i = 0, N = node.outEdges.size(); i < N; i++)
1309 os << std::string(16, ' ') << *node.outEdges[i];
1310 }
1311
Guochun Shif1c154f2003-03-27 17:57:44 +00001312 return os;
1313}