blob: 8bc78adc877eefe174a679f9eceaaaaf53a979be [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 Brukman2c821cc2003-04-10 19:19:23 +000022// FIXME: Should be using #include <cmath>
Misha Brukman8baa01c2003-04-09 21:51:34 +000023#include <math.h>
24//#include <swig.h>
Guochun Shif1c154f2003-03-27 17:57:44 +000025
26#define UNIDELAY 1
Guochun Shif1c154f2003-03-27 17:57:44 +000027
Guochun Shif1c154f2003-03-27 17:57:44 +000028//*********************** Internal Data Structures *************************/
29
30// The following two types need to be classes, not typedefs, so we can use
31// opaque declarations in SchedGraph.h
32//
Misha Brukman2c821cc2003-04-10 19:19:23 +000033struct RefVec:public std::vector<std::pair<ModuloSchedGraphNode*,int> > {
Misha Brukman8baa01c2003-04-09 21:51:34 +000034 typedef std::vector<std::pair<ModuloSchedGraphNode*,
35 int> >::iterator iterator;
36 typedef std::vector<std::pair<ModuloSchedGraphNode*,
37 int> >::const_iterator const_iterator;
Guochun Shif1c154f2003-03-27 17:57:44 +000038};
39
Misha Brukman2c821cc2003-04-10 19:19:23 +000040struct RegToRefVecMap:public hash_map<int,RefVec> {
41 typedef hash_map<int,RefVec>::iterator iterator;
42 typedef hash_map<int,RefVec>::const_iterator const_iterator;
Guochun Shif1c154f2003-03-27 17:57:44 +000043};
44
Misha Brukman2c821cc2003-04-10 19:19:23 +000045struct ValueToDefVecMap:public hash_map<const Instruction*,RefVec> {
46 typedef hash_map<const Instruction*, RefVec>::iterator iterator;
47 typedef hash_map<const Instruction*,
Misha Brukman8baa01c2003-04-09 21:51:34 +000048 RefVec>::const_iterator const_iterator;
Guochun Shif1c154f2003-03-27 17:57:44 +000049};
50
Guochun Shif1c154f2003-03-27 17:57:44 +000051// class Modulo SchedGraphNode
52
Guochun Shif1c154f2003-03-27 17:57:44 +000053ModuloSchedGraphNode::ModuloSchedGraphNode(unsigned int _nodeId,
Misha Brukman8baa01c2003-04-09 21:51:34 +000054 const BasicBlock * _bb,
55 const Instruction * _inst,
56 int indexInBB,
57 const TargetMachine & target)
58:SchedGraphNodeCommon(_nodeId, _bb, indexInBB), inst(_inst)
Guochun Shif1c154f2003-03-27 17:57:44 +000059{
Misha Brukman8baa01c2003-04-09 21:51:34 +000060 if (inst) {
61 //FIXME: find the latency
62 //currently setthe latency to zero
63 latency = 0;
64 }
Guochun Shif1c154f2003-03-27 17:57:44 +000065}
Misha Brukman8baa01c2003-04-09 21:51:34 +000066
Guochun Shif1c154f2003-03-27 17:57:44 +000067//class ModuloScheGraph
68
Misha Brukman8baa01c2003-04-09 21:51:34 +000069void ModuloSchedGraph::addDummyEdges()
Guochun Shif1c154f2003-03-27 17:57:44 +000070{
71 assert(graphRoot->outEdges.size() == 0);
Misha Brukman8baa01c2003-04-09 21:51:34 +000072
73 for (const_iterator I = begin(); I != end(); ++I) {
74 ModuloSchedGraphNode *node = (ModuloSchedGraphNode *) ((*I).second);
75 assert(node != graphRoot && node != graphLeaf);
76 if (node->beginInEdges() == node->endInEdges())
77 (void) new SchedGraphEdge(graphRoot, node, SchedGraphEdge::CtrlDep,
78 SchedGraphEdge::NonDataDep, 0);
79 if (node->beginOutEdges() == node->endOutEdges())
80 (void) new SchedGraphEdge(node, graphLeaf, SchedGraphEdge::CtrlDep,
81 SchedGraphEdge::NonDataDep, 0);
82 }
Guochun Shif1c154f2003-03-27 17:57:44 +000083}
84
Misha Brukman8baa01c2003-04-09 21:51:34 +000085bool isDefinition(const Instruction *I)
Guochun Shif1c154f2003-03-27 17:57:44 +000086{
87 //if(TerminatorInst::classof(I)||FreeInst::classof(I) || StoreInst::classof(I) || CallInst::classof(I))
Misha Brukman8baa01c2003-04-09 21:51:34 +000088 if (!I->hasName())
Guochun Shif1c154f2003-03-27 17:57:44 +000089 return false;
90 else
91 return true;
92}
93
Misha Brukman8baa01c2003-04-09 21:51:34 +000094void ModuloSchedGraph::addDefUseEdges(const BasicBlock *bb)
Guochun Shif1c154f2003-03-27 17:57:44 +000095{
96 //collect def instructions, store them in vector
Guochun Shi6fbe5fb2003-04-06 23:56:19 +000097 // const TargetInstrInfo& mii = target.getInstrInfo();
Misha Brukman8baa01c2003-04-09 21:51:34 +000098 const TargetInstrInfo & mii = target.getInstrInfo();
99
100 typedef std::vector < ModuloSchedGraphNode * >DefVec;
Guochun Shif1c154f2003-03-27 17:57:44 +0000101 DefVec defVec;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000102
Guochun Shif1c154f2003-03-27 17:57:44 +0000103 //find those def instructions
Misha Brukman8baa01c2003-04-09 21:51:34 +0000104 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E; ++I) {
105 if (I->getType() != Type::VoidTy) {
106 defVec.push_back(this->getGraphNodeForInst(I));
107 }
108 }
109
110 for (unsigned int i = 0; i < defVec.size(); i++) {
111 for (Value::use_const_iterator I = defVec[i]->getInst()->use_begin();
112 I != defVec[i]->getInst()->use_end(); I++) {
Misha Brukman63e04f32003-04-22 23:00:08 +0000113 //for each use of a def, add a flow edge from the def instruction to the
114 //ref instruction
Misha Brukman8baa01c2003-04-09 21:51:34 +0000115
116 const Instruction *value = defVec[i]->getInst();
117 Instruction *inst = (Instruction *) (*I);
118 ModuloSchedGraphNode *node = NULL;
119
120 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end();
121 I != E; ++I)
122 if ((const Instruction *) I == inst) {
123 node = (*this)[inst];
124 break;
125 }
126
127 assert(inst != NULL && " Use not an Instruction ?");
128
129 if (node == NULL) //inst is not an instruction in this block
Guochun Shif1c154f2003-03-27 17:57:44 +0000130 {
Misha Brukman8baa01c2003-04-09 21:51:34 +0000131 } else {
132 // Add a flow edge from the def instruction to the ref instruction
133
134 // self loop will not happen in SSA form
135 assert(defVec[i] != node && "same node?");
136
137 // This is a true dependence, so the delay is equal to the delay of the
138 // pred node.
139 int delay = 0;
140 MachineCodeForInstruction & tempMvec =
141 MachineCodeForInstruction::get(value);
142 for (unsigned j = 0; j < tempMvec.size(); j++) {
143 MachineInstr *temp = tempMvec[j];
144 //delay +=mii.minLatency(temp->getOpCode());
145 delay = std::max(delay, mii.minLatency(temp->getOpCode()));
146 }
147
148 SchedGraphEdge *trueEdge =
149 new SchedGraphEdge(defVec[i], node, value,
150 SchedGraphEdge::TrueDep, delay);
151
152 // if the ref instruction is before the def instrution
153 // then the def instruction must be a phi instruction
154 // add an anti-dependence edge to from the ref instruction to the def
155 // instruction
156 if (node->getOrigIndexInBB() < defVec[i]->getOrigIndexInBB()) {
157 assert(PHINode::classof(inst)
158 && "the ref instruction befre def is not PHINode?");
159 trueEdge->setIteDiff(1);
160 }
161
Guochun Shif1c154f2003-03-27 17:57:44 +0000162 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000163
Misha Brukman8baa01c2003-04-09 21:51:34 +0000164 }
165 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000166}
167
Misha Brukman8baa01c2003-04-09 21:51:34 +0000168void ModuloSchedGraph::addCDEdges(const BasicBlock * bb) {
169 // find the last instruction in the basic block
170 // see if it is an branch instruction.
171 // If yes, then add an edge from each node expcept the last node to the last
172 // node
173 const Instruction *inst = &(bb->back());
174 ModuloSchedGraphNode *lastNode = (*this)[inst];
175 if (TerminatorInst::classof(inst))
176 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E;
177 I++) {
178 if (inst != I) {
179 ModuloSchedGraphNode *node = (*this)[I];
180 //use latency of 0
181 (void) new SchedGraphEdge(node, lastNode, SchedGraphEdge::CtrlDep,
182 SchedGraphEdge::NonDataDep, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000183 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000184
185 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000186}
187
Misha Brukman8baa01c2003-04-09 21:51:34 +0000188static const int SG_LOAD_REF = 0;
Guochun Shif1c154f2003-03-27 17:57:44 +0000189static const int SG_STORE_REF = 1;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000190static const int SG_CALL_REF = 2;
Guochun Shif1c154f2003-03-27 17:57:44 +0000191
192static const unsigned int SG_DepOrderArray[][3] = {
Misha Brukman8baa01c2003-04-09 21:51:34 +0000193 {SchedGraphEdge::NonDataDep,
194 SchedGraphEdge::AntiDep,
195 SchedGraphEdge::AntiDep},
196 {SchedGraphEdge::TrueDep,
197 SchedGraphEdge::OutputDep,
198 SchedGraphEdge::TrueDep | SchedGraphEdge::OutputDep},
199 {SchedGraphEdge::TrueDep,
200 SchedGraphEdge::AntiDep | SchedGraphEdge::OutputDep,
201 SchedGraphEdge::TrueDep | SchedGraphEdge::AntiDep
202 | SchedGraphEdge::OutputDep}
Guochun Shif1c154f2003-03-27 17:57:44 +0000203};
204
205
206// Add a dependence edge between every pair of machine load/store/call
207// instructions, where at least one is a store or a call.
208// Use latency 1 just to ensure that memory operations are ordered;
209// latency does not otherwise matter (true dependences enforce that).
210//
Misha Brukman8baa01c2003-04-09 21:51:34 +0000211void ModuloSchedGraph::addMemEdges(const BasicBlock * bb) {
212
213 std::vector<ModuloSchedGraphNode*> memNodeVec;
Guochun Shif1c154f2003-03-27 17:57:44 +0000214
215 //construct the memNodeVec
Misha Brukman8baa01c2003-04-09 21:51:34 +0000216 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E; ++I) {
217 if (LoadInst::classof(I) || StoreInst::classof(I)
218 || CallInst::classof(I)) {
219 ModuloSchedGraphNode *node = (*this)[(const Instruction *) I];
220 memNodeVec.push_back(node);
221 }
222 }
223
Guochun Shif1c154f2003-03-27 17:57:44 +0000224 // Instructions in memNodeVec are in execution order within the basic block,
225 // so simply look at all pairs <memNodeVec[i], memNodeVec[j: j > i]>.
226 //
Misha Brukman8baa01c2003-04-09 21:51:34 +0000227 for (unsigned im = 0, NM = memNodeVec.size(); im < NM; im++) {
228 const Instruction *fromInst = memNodeVec[im]->getInst();
229 int fromType = CallInst::classof(fromInst) ? SG_CALL_REF
230 : LoadInst::classof(fromInst) ? SG_LOAD_REF : SG_STORE_REF;
231 for (unsigned jm = im + 1; jm < NM; jm++) {
232 const Instruction *toInst = memNodeVec[jm]->getInst();
233 int toType = CallInst::classof(toInst) ? SG_CALL_REF
234 : LoadInst::classof(toInst) ? SG_LOAD_REF : SG_STORE_REF;
235 if (fromType != SG_LOAD_REF || toType != SG_LOAD_REF) {
236 (void) new SchedGraphEdge(memNodeVec[im], memNodeVec[jm],
237 SchedGraphEdge::MemoryDep,
238 SG_DepOrderArray[fromType][toType], 1);
239
240 SchedGraphEdge *edge =
241 new SchedGraphEdge(memNodeVec[jm], memNodeVec[im],
242 SchedGraphEdge::MemoryDep,
243 SG_DepOrderArray[toType][fromType], 1);
244 edge->setIteDiff(1);
245
246 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000247 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000248 }
249}
Guochun Shif1c154f2003-03-27 17:57:44 +0000250
251
252
Misha Brukman8baa01c2003-04-09 21:51:34 +0000253void ModuloSchedGraph::buildNodesforBB(const TargetMachine &target,
254 const BasicBlock *bb,
255 std::vector<ModuloSchedGraphNode*> &memNode,
256 RegToRefVecMap &regToRefVecMap,
257 ValueToDefVecMap &valueToDefVecMap)
Guochun Shif1c154f2003-03-27 17:57:44 +0000258{
Guochun Shi6fbe5fb2003-04-06 23:56:19 +0000259 //const TargetInstrInfo& mii=target.getInstrInfo();
Misha Brukman8baa01c2003-04-09 21:51:34 +0000260
Guochun Shif1c154f2003-03-27 17:57:44 +0000261 //Build graph nodes for each LLVM instruction and gather def/use info.
262 //Do both together in a single pass over all machine instructions.
Misha Brukman8baa01c2003-04-09 21:51:34 +0000263
264 int i = 0;
265 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E;
266 ++I) {
267 ModuloSchedGraphNode *node =
268 new ModuloSchedGraphNode(getNumNodes(), bb, I, i, target);
269 i++;
270 this->noteModuloSchedGraphNodeForInst(I, node);
271 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000272
273 //this function finds some info about instruction in basic block for later use
Misha Brukman8baa01c2003-04-09 21:51:34 +0000274 //findDefUseInfoAtInstr(target, node,
275 //memNode,regToRefVecMap,valueToDefVecMap);
Guochun Shif1c154f2003-03-27 17:57:44 +0000276}
277
278
Misha Brukman8baa01c2003-04-09 21:51:34 +0000279bool ModuloSchedGraph::isLoop(const BasicBlock *bb) {
Guochun Shif1c154f2003-03-27 17:57:44 +0000280 //only if the last instruction in the basicblock is branch instruction and
281 //there is at least an option to branch itself
282
Misha Brukman8baa01c2003-04-09 21:51:34 +0000283 const Instruction *inst = &(bb->back());
284 if (BranchInst::classof(inst)) {
285 for (unsigned i = 0; i < ((BranchInst *) inst)->getNumSuccessors();
286 i++) {
287 BasicBlock *sb = ((BranchInst *) inst)->getSuccessor(i);
288 if (sb == bb)
289 return true;
290 }
291 }
292
Guochun Shif1c154f2003-03-27 17:57:44 +0000293 return false;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000294
Guochun Shif1c154f2003-03-27 17:57:44 +0000295}
Misha Brukman8baa01c2003-04-09 21:51:34 +0000296
297bool ModuloSchedGraph::isLoop() {
Guochun Shif1c154f2003-03-27 17:57:44 +0000298 //only if the last instruction in the basicblock is branch instruction and
299 //there is at least an option to branch itself
Guochun Shif1c154f2003-03-27 17:57:44 +0000300
Misha Brukman8baa01c2003-04-09 21:51:34 +0000301 assert(bbVec.size() == 1 && "only 1 basicblock in a graph");
302 const BasicBlock *bb = bbVec[0];
303 const Instruction *inst = &(bb->back());
304 if (BranchInst::classof(inst))
305 for (unsigned i = 0; i < ((BranchInst *) inst)->getNumSuccessors();
306 i++) {
307 BasicBlock *sb = ((BranchInst *) inst)->getSuccessor(i);
308 if (sb == bb)
309 return true;
Guochun Shif1c154f2003-03-27 17:57:44 +0000310 }
311
Misha Brukman8baa01c2003-04-09 21:51:34 +0000312 return false;
313
314}
315
316void ModuloSchedGraph::computeNodeASAP(const BasicBlock *bb) {
317
318 //FIXME: now assume the only backward edges come from the edges from other
319 //nodes to the phi Node so i will ignore all edges to the phi node; after
320 //this, there shall be no recurrence.
321
322 unsigned numNodes = bb->size();
323 for (unsigned i = 2; i < numNodes + 2; i++) {
324 ModuloSchedGraphNode *node = getNode(i);
325 node->setPropertyComputed(false);
326 }
327
328 for (unsigned i = 2; i < numNodes + 2; i++) {
329 ModuloSchedGraphNode *node = getNode(i);
330 node->ASAP = 0;
331 if (i == 2 || node->getNumInEdges() == 0) {
Guochun Shif1c154f2003-03-27 17:57:44 +0000332 node->setPropertyComputed(true);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000333 continue;
Guochun Shif1c154f2003-03-27 17:57:44 +0000334 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000335 for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E =
336 node->endInEdges(); I != E; I++) {
337 SchedGraphEdge *edge = *I;
338 ModuloSchedGraphNode *pred =
339 (ModuloSchedGraphNode *) (edge->getSrc());
340 assert(pred->getPropertyComputed()
341 && "pred node property is not computed!");
342 int temp =
343 pred->ASAP + edge->getMinDelay() -
344 edge->getIteDiff() * this->MII;
345 node->ASAP = std::max(node->ASAP, temp);
346 }
347 node->setPropertyComputed(true);
348 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000349}
350
Misha Brukman8baa01c2003-04-09 21:51:34 +0000351void ModuloSchedGraph::computeNodeALAP(const BasicBlock *bb) {
352 unsigned numNodes = bb->size();
353 int maxASAP = 0;
354 for (unsigned i = numNodes + 1; i >= 2; i--) {
355 ModuloSchedGraphNode *node = getNode(i);
356 node->setPropertyComputed(false);
357 //cerr<< " maxASAP= " <<maxASAP<<" node->ASAP= "<< node->ASAP<<"\n";
358 maxASAP = std::max(maxASAP, node->ASAP);
359 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000360
361 //cerr<<"maxASAP is "<<maxASAP<<"\n";
Misha Brukman8baa01c2003-04-09 21:51:34 +0000362
363 for (unsigned i = numNodes + 1; i >= 2; i--) {
364 ModuloSchedGraphNode *node = getNode(i);
365 node->ALAP = maxASAP;
366 for (ModuloSchedGraphNode::const_iterator I =
367 node->beginOutEdges(), E = node->endOutEdges(); I != E; I++) {
368 SchedGraphEdge *edge = *I;
369 ModuloSchedGraphNode *succ =
370 (ModuloSchedGraphNode *) (edge->getSink());
371 if (PHINode::classof(succ->getInst()))
372 continue;
373 assert(succ->getPropertyComputed()
374 && "succ node property is not computed!");
375 int temp =
376 succ->ALAP - edge->getMinDelay() +
377 edge->getIteDiff() * this->MII;
378 node->ALAP = std::min(node->ALAP, temp);
379 }
380 node->setPropertyComputed(true);
381 }
382}
383
384void ModuloSchedGraph::computeNodeMov(const BasicBlock *bb)
385{
386 unsigned numNodes = bb->size();
387 for (unsigned i = 2; i < numNodes + 2; i++) {
388 ModuloSchedGraphNode *node = getNode(i);
389 node->mov = node->ALAP - node->ASAP;
390 assert(node->mov >= 0
391 && "move freedom for this node is less than zero? ");
392 }
393}
394
395
396void ModuloSchedGraph::computeNodeDepth(const BasicBlock * bb)
397{
398
399 unsigned numNodes = bb->size();
400 for (unsigned i = 2; i < numNodes + 2; i++) {
401 ModuloSchedGraphNode *node = getNode(i);
402 node->setPropertyComputed(false);
403 }
404
405 for (unsigned i = 2; i < numNodes + 2; i++) {
406 ModuloSchedGraphNode *node = getNode(i);
407 node->depth = 0;
408 if (i == 2 || node->getNumInEdges() == 0) {
Guochun Shif1c154f2003-03-27 17:57:44 +0000409 node->setPropertyComputed(true);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000410 continue;
Guochun Shif1c154f2003-03-27 17:57:44 +0000411 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000412 for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E =
413 node->endInEdges(); I != E; I++) {
414 SchedGraphEdge *edge = *I;
415 ModuloSchedGraphNode *pred =
416 (ModuloSchedGraphNode *) (edge->getSrc());
417 assert(pred->getPropertyComputed()
418 && "pred node property is not computed!");
419 int temp = pred->depth + edge->getMinDelay();
420 node->depth = std::max(node->depth, temp);
Guochun Shif1c154f2003-03-27 17:57:44 +0000421 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000422 node->setPropertyComputed(true);
423 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000424
425}
426
427
Misha Brukman8baa01c2003-04-09 21:51:34 +0000428void ModuloSchedGraph::computeNodeHeight(const BasicBlock *bb)
Guochun Shif1c154f2003-03-27 17:57:44 +0000429{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000430 unsigned numNodes = bb->size();
431 for (unsigned i = numNodes + 1; i >= 2; i--) {
432 ModuloSchedGraphNode *node = getNode(i);
433 node->setPropertyComputed(false);
434 }
435
436 for (unsigned i = numNodes + 1; i >= 2; i--) {
437 ModuloSchedGraphNode *node = getNode(i);
438 node->height = 0;
439 for (ModuloSchedGraphNode::const_iterator I =
440 node->beginOutEdges(), E = node->endOutEdges(); I != E; ++I) {
441 SchedGraphEdge *edge = *I;
442 ModuloSchedGraphNode *succ =
443 (ModuloSchedGraphNode *) (edge->getSink());
444 if (PHINode::classof(succ->getInst()))
445 continue;
446 assert(succ->getPropertyComputed()
447 && "succ node property is not computed!");
448 node->height = std::max(node->height, succ->height + edge->getMinDelay());
449
Guochun Shif1c154f2003-03-27 17:57:44 +0000450 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000451 node->setPropertyComputed(true);
452
453 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000454
455}
456
Misha Brukman8baa01c2003-04-09 21:51:34 +0000457void ModuloSchedGraph::computeNodeProperty(const BasicBlock * bb)
Guochun Shif1c154f2003-03-27 17:57:44 +0000458{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000459 //FIXME: now assume the only backward edges come from the edges from other
460 //nodes to the phi Node so i will ignore all edges to the phi node; after
461 //this, there shall be no recurrence.
462
Guochun Shif1c154f2003-03-27 17:57:44 +0000463 this->computeNodeASAP(bb);
464 this->computeNodeALAP(bb);
465 this->computeNodeMov(bb);
466 this->computeNodeDepth(bb);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000467 this->computeNodeHeight(bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000468}
469
470
471//do not consider the backedge in these two functions:
472// i.e. don't consider the edge with destination in phi node
Misha Brukman8baa01c2003-04-09 21:51:34 +0000473std::vector<ModuloSchedGraphNode*>
474ModuloSchedGraph::predSet(std::vector<ModuloSchedGraphNode*> set,
475 unsigned backEdgeSrc,
476 unsigned
477 backEdgeSink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000478{
479 std::vector<ModuloSchedGraphNode*> predS;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000480 for (unsigned i = 0; i < set.size(); i++) {
481 ModuloSchedGraphNode *node = set[i];
482 for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E =
483 node->endInEdges(); I != E; I++) {
484 SchedGraphEdge *edge = *I;
485 if (edge->getSrc()->getNodeId() == backEdgeSrc
486 && edge->getSink()->getNodeId() == backEdgeSink)
487 continue;
488 ModuloSchedGraphNode *pred =
489 (ModuloSchedGraphNode *) (edge->getSrc());
490 //if pred is not in the predSet, push it in vector
491 bool alreadyInset = false;
492 for (unsigned j = 0; j < predS.size(); ++j)
493 if (predS[j]->getNodeId() == pred->getNodeId()) {
494 alreadyInset = true;
495 break;
496 }
497
498 for (unsigned j = 0; j < set.size(); ++j)
499 if (set[j]->getNodeId() == pred->getNodeId()) {
500 alreadyInset = true;
501 break;
502 }
503
504 if (!alreadyInset)
505 predS.push_back(pred);
Guochun Shif1c154f2003-03-27 17:57:44 +0000506 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000507 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000508 return predS;
509}
510
511ModuloSchedGraph::NodeVec ModuloSchedGraph::predSet(NodeVec set)
512{
513 //node number increases from 2
Misha Brukman8baa01c2003-04-09 21:51:34 +0000514 return predSet(set, 0, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000515}
516
Misha Brukman8baa01c2003-04-09 21:51:34 +0000517std::vector <ModuloSchedGraphNode*>
518ModuloSchedGraph::predSet(ModuloSchedGraphNode *_node,
519 unsigned backEdgeSrc, unsigned backEdgeSink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000520{
Guochun Shif1c154f2003-03-27 17:57:44 +0000521 std::vector<ModuloSchedGraphNode*> set;
522 set.push_back(_node);
523 return predSet(set, backEdgeSrc, backEdgeSink);
Guochun Shif1c154f2003-03-27 17:57:44 +0000524}
525
Misha Brukman8baa01c2003-04-09 21:51:34 +0000526std::vector <ModuloSchedGraphNode*>
527ModuloSchedGraph::predSet(ModuloSchedGraphNode * _node)
Guochun Shif1c154f2003-03-27 17:57:44 +0000528{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000529 return predSet(_node, 0, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000530}
531
Misha Brukman8baa01c2003-04-09 21:51:34 +0000532std::vector<ModuloSchedGraphNode*>
533ModuloSchedGraph::succSet(std::vector<ModuloSchedGraphNode*> set,
534 unsigned src, unsigned sink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000535{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000536 std::vector<ModuloSchedGraphNode*> succS;
537 for (unsigned i = 0; i < set.size(); i++) {
538 ModuloSchedGraphNode *node = set[i];
539 for (ModuloSchedGraphNode::const_iterator I =
540 node->beginOutEdges(), E = node->endOutEdges(); I != E; I++) {
541 SchedGraphEdge *edge = *I;
542 if (edge->getSrc()->getNodeId() == src
543 && edge->getSink()->getNodeId() == sink)
544 continue;
545 ModuloSchedGraphNode *succ =
546 (ModuloSchedGraphNode *) (edge->getSink());
547 //if pred is not in the predSet, push it in vector
548 bool alreadyInset = false;
549 for (unsigned j = 0; j < succS.size(); j++)
550 if (succS[j]->getNodeId() == succ->getNodeId()) {
551 alreadyInset = true;
552 break;
553 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000554
Misha Brukman8baa01c2003-04-09 21:51:34 +0000555 for (unsigned j = 0; j < set.size(); j++)
556 if (set[j]->getNodeId() == succ->getNodeId()) {
557 alreadyInset = true;
558 break;
559 }
560 if (!alreadyInset)
561 succS.push_back(succ);
Guochun Shif1c154f2003-03-27 17:57:44 +0000562 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000563 }
564 return succS;
Guochun Shif1c154f2003-03-27 17:57:44 +0000565}
566
567ModuloSchedGraph::NodeVec ModuloSchedGraph::succSet(NodeVec set)
568{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000569 return succSet(set, 0, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000570}
571
572
Misha Brukman8baa01c2003-04-09 21:51:34 +0000573std::vector<ModuloSchedGraphNode*>
574ModuloSchedGraph::succSet(ModuloSchedGraphNode *_node,
575 unsigned src, unsigned sink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000576{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000577 std::vector<ModuloSchedGraphNode*>set;
Guochun Shif1c154f2003-03-27 17:57:44 +0000578 set.push_back(_node);
579 return succSet(set, src, sink);
Guochun Shif1c154f2003-03-27 17:57:44 +0000580}
581
Misha Brukman8baa01c2003-04-09 21:51:34 +0000582std::vector<ModuloSchedGraphNode*>
583ModuloSchedGraph::succSet(ModuloSchedGraphNode * _node)
Guochun Shif1c154f2003-03-27 17:57:44 +0000584{
585 return succSet(_node, 0, 0);
586}
587
Misha Brukman8baa01c2003-04-09 21:51:34 +0000588SchedGraphEdge *ModuloSchedGraph::getMaxDelayEdge(unsigned srcId,
589 unsigned sinkId)
Guochun Shif1c154f2003-03-27 17:57:44 +0000590{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000591 ModuloSchedGraphNode *node = getNode(srcId);
592 SchedGraphEdge *maxDelayEdge = NULL;
593 int maxDelay = -1;
594 for (ModuloSchedGraphNode::const_iterator I = node->beginOutEdges(), E =
595 node->endOutEdges(); I != E; I++) {
596 SchedGraphEdge *edge = *I;
597 if (edge->getSink()->getNodeId() == sinkId)
598 if (edge->getMinDelay() > maxDelay) {
599 maxDelayEdge = edge;
600 maxDelay = edge->getMinDelay();
601 }
602 }
603 assert(maxDelayEdge != NULL && "no edge between the srcId and sinkId?");
Guochun Shif1c154f2003-03-27 17:57:44 +0000604 return maxDelayEdge;
605}
606
607void ModuloSchedGraph::dumpCircuits()
608{
Misha Brukman2c821cc2003-04-10 19:19:23 +0000609 DEBUG(std::cerr << "dumping circuits for graph:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000610 int j = -1;
611 while (circuits[++j][0] != 0) {
612 int k = -1;
613 while (circuits[j][++k] != 0)
Misha Brukman2c821cc2003-04-10 19:19:23 +0000614 DEBUG(std::cerr << circuits[j][k] << "\t");
615 DEBUG(std::cerr << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +0000616 }
617}
618
Misha Brukman8baa01c2003-04-09 21:51:34 +0000619void ModuloSchedGraph::dumpSet(std::vector < ModuloSchedGraphNode * >set)
Guochun Shif1c154f2003-03-27 17:57:44 +0000620{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000621 for (unsigned i = 0; i < set.size(); i++)
Misha Brukman2c821cc2003-04-10 19:19:23 +0000622 DEBUG(std::cerr << set[i]->getNodeId() << "\t");
623 DEBUG(std::cerr << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +0000624}
625
Misha Brukman8baa01c2003-04-09 21:51:34 +0000626std::vector<ModuloSchedGraphNode*>
627ModuloSchedGraph::vectorUnion(std::vector<ModuloSchedGraphNode*> set1,
628 std::vector<ModuloSchedGraphNode*> set2)
Guochun Shif1c154f2003-03-27 17:57:44 +0000629{
630 std::vector<ModuloSchedGraphNode*> unionVec;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000631 for (unsigned i = 0; i < set1.size(); i++)
Guochun Shif1c154f2003-03-27 17:57:44 +0000632 unionVec.push_back(set1[i]);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000633 for (unsigned j = 0; j < set2.size(); j++) {
634 bool inset = false;
635 for (unsigned i = 0; i < unionVec.size(); i++)
636 if (set2[j] == unionVec[i])
637 inset = true;
638 if (!inset)
639 unionVec.push_back(set2[j]);
Guochun Shif1c154f2003-03-27 17:57:44 +0000640 }
641 return unionVec;
642}
Misha Brukman8baa01c2003-04-09 21:51:34 +0000643
644std::vector<ModuloSchedGraphNode*>
645ModuloSchedGraph::vectorConj(std::vector<ModuloSchedGraphNode*> set1,
646 std::vector<ModuloSchedGraphNode*> set2)
Guochun Shif1c154f2003-03-27 17:57:44 +0000647{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000648 std::vector<ModuloSchedGraphNode*> conjVec;
649 for (unsigned i = 0; i < set1.size(); i++)
650 for (unsigned j = 0; j < set2.size(); j++)
651 if (set1[i] == set2[j])
652 conjVec.push_back(set1[i]);
653 return conjVec;
Guochun Shif1c154f2003-03-27 17:57:44 +0000654}
655
Misha Brukman8baa01c2003-04-09 21:51:34 +0000656ModuloSchedGraph::NodeVec ModuloSchedGraph::vectorSub(NodeVec set1,
657 NodeVec set2)
Guochun Shif1c154f2003-03-27 17:57:44 +0000658{
659 NodeVec newVec;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000660 for (NodeVec::iterator I = set1.begin(); I != set1.end(); I++) {
661 bool inset = false;
662 for (NodeVec::iterator II = set2.begin(); II != set2.end(); II++)
663 if ((*I)->getNodeId() == (*II)->getNodeId()) {
664 inset = true;
665 break;
666 }
667 if (!inset)
668 newVec.push_back(*I);
Guochun Shif1c154f2003-03-27 17:57:44 +0000669 }
670 return newVec;
671}
Guochun Shif1c154f2003-03-27 17:57:44 +0000672
Misha Brukman8baa01c2003-04-09 21:51:34 +0000673void ModuloSchedGraph::orderNodes() {
674 oNodes.clear();
675
676 std::vector < ModuloSchedGraphNode * >set;
677 const BasicBlock *bb = bbVec[0];
678 unsigned numNodes = bb->size();
679
Misha Brukman2c821cc2003-04-10 19:19:23 +0000680 // first order all the sets
Misha Brukman8baa01c2003-04-09 21:51:34 +0000681 int j = -1;
682 int totalDelay = -1;
683 int preDelay = -1;
684 while (circuits[++j][0] != 0) {
685 int k = -1;
686 preDelay = totalDelay;
687
688 while (circuits[j][++k] != 0) {
689 ModuloSchedGraphNode *node = getNode(circuits[j][k]);
Guochun Shif1c154f2003-03-27 17:57:44 +0000690 unsigned nextNodeId;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000691 nextNodeId =
692 circuits[j][k + 1] != 0 ? circuits[j][k + 1] : circuits[j][0];
693 SchedGraphEdge *edge = getMaxDelayEdge(circuits[j][k], nextNodeId);
Guochun Shif1c154f2003-03-27 17:57:44 +0000694 totalDelay += edge->getMinDelay();
695 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000696 if (preDelay != -1 && totalDelay > preDelay) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000697 // swap circuits[j][] and cuicuits[j-1][]
Guochun Shif1c154f2003-03-27 17:57:44 +0000698 unsigned temp[MAXNODE];
Misha Brukman8baa01c2003-04-09 21:51:34 +0000699 for (int k = 0; k < MAXNODE; k++) {
700 temp[k] = circuits[j - 1][k];
701 circuits[j - 1][k] = circuits[j][k];
702 circuits[j][k] = temp[k];
Guochun Shif1c154f2003-03-27 17:57:44 +0000703 }
704 //restart
Misha Brukman8baa01c2003-04-09 21:51:34 +0000705 j = -1;
Guochun Shif1c154f2003-03-27 17:57:44 +0000706 }
707 }
708
Misha Brukman2c821cc2003-04-10 19:19:23 +0000709 // build the first set
Guochun Shif1c154f2003-03-27 17:57:44 +0000710 int backEdgeSrc;
711 int backEdgeSink;
Misha Brukman2c821cc2003-04-10 19:19:23 +0000712 if (ModuloScheduling::printScheduleProcess())
713 DEBUG(std::cerr << "building the first set" << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000714 int setSeq = -1;
715 int k = -1;
Guochun Shif1c154f2003-03-27 17:57:44 +0000716 setSeq++;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000717 while (circuits[setSeq][++k] != 0)
Guochun Shif1c154f2003-03-27 17:57:44 +0000718 set.push_back(getNode(circuits[setSeq][k]));
Misha Brukman8baa01c2003-04-09 21:51:34 +0000719 if (circuits[setSeq][0] != 0) {
720 backEdgeSrc = circuits[setSeq][k - 1];
721 backEdgeSink = circuits[setSeq][0];
Guochun Shif1c154f2003-03-27 17:57:44 +0000722 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000723 if (ModuloScheduling::printScheduleProcess()) {
724 DEBUG(std::cerr << "the first set is:");
Guochun Shif1c154f2003-03-27 17:57:44 +0000725 dumpSet(set);
726 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000727 // implement the ordering algorithm
Misha Brukman8baa01c2003-04-09 21:51:34 +0000728 enum OrderSeq { bottom_up, top_down };
Guochun Shif1c154f2003-03-27 17:57:44 +0000729 OrderSeq order;
730 std::vector<ModuloSchedGraphNode*> R;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000731 while (!set.empty()) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000732 std::vector<ModuloSchedGraphNode*> pset = predSet(oNodes);
733 std::vector<ModuloSchedGraphNode*> sset = succSet(oNodes);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000734
735 if (!pset.empty() && !vectorConj(pset, set).empty()) {
736 R = vectorConj(pset, set);
737 order = bottom_up;
738 } else if (!sset.empty() && !vectorConj(sset, set).empty()) {
739 R = vectorConj(sset, set);
740 order = top_down;
741 } else {
742 int maxASAP = -1;
743 int position = -1;
744 for (unsigned i = 0; i < set.size(); i++) {
745 int temp = set[i]->getASAP();
746 if (temp > maxASAP) {
747 maxASAP = temp;
748 position = i;
749 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000750 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000751 R.push_back(set[position]);
752 order = bottom_up;
753 }
754
755 while (!R.empty()) {
756 if (order == top_down) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000757 if (ModuloScheduling::printScheduleProcess())
758 DEBUG(std::cerr << "in top_down round\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000759 while (!R.empty()) {
760 int maxHeight = -1;
761 NodeVec::iterator chosenI;
762 for (NodeVec::iterator I = R.begin(); I != R.end(); I++) {
763 int temp = (*I)->height;
764 if ((temp > maxHeight)
765 || (temp == maxHeight && (*I)->mov <= (*chosenI)->mov)) {
766
767 if ((temp > maxHeight)
768 || (temp == maxHeight && (*I)->mov < (*chosenI)->mov)) {
769 maxHeight = temp;
770 chosenI = I;
771 continue;
772 }
773 //possible case: instruction A and B has the same height and mov,
774 //but A has dependence to B e.g B is the branch instruction in the
775 //end, or A is the phi instruction at the beginning
776 if ((*I)->mov == (*chosenI)->mov)
777 for (ModuloSchedGraphNode::const_iterator oe =
778 (*I)->beginOutEdges(), end = (*I)->endOutEdges();
779 oe != end; oe++) {
780 if ((*oe)->getSink() == (*chosenI)) {
781 maxHeight = temp;
782 chosenI = I;
783 continue;
784 }
785 }
786 }
787 }
788 ModuloSchedGraphNode *mu = *chosenI;
789 oNodes.push_back(mu);
790 R.erase(chosenI);
791 std::vector<ModuloSchedGraphNode*> succ_mu =
792 succSet(mu, backEdgeSrc, backEdgeSink);
793 std::vector<ModuloSchedGraphNode*> comm =
794 vectorConj(succ_mu, set);
795 comm = vectorSub(comm, oNodes);
796 R = vectorUnion(comm, R);
797 }
798 order = bottom_up;
799 R = vectorConj(predSet(oNodes), set);
800 } else {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000801 if (ModuloScheduling::printScheduleProcess())
802 DEBUG(std::cerr << "in bottom up round\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000803 while (!R.empty()) {
804 int maxDepth = -1;
805 NodeVec::iterator chosenI;
806 for (NodeVec::iterator I = R.begin(); I != R.end(); I++) {
807 int temp = (*I)->depth;
808 if ((temp > maxDepth)
809 || (temp == maxDepth && (*I)->mov < (*chosenI)->mov)) {
810 maxDepth = temp;
811 chosenI = I;
812 }
813 }
814 ModuloSchedGraphNode *mu = *chosenI;
815 oNodes.push_back(mu);
816 R.erase(chosenI);
817 std::vector<ModuloSchedGraphNode*> pred_mu =
818 predSet(mu, backEdgeSrc, backEdgeSink);
819 std::vector<ModuloSchedGraphNode*> comm =
820 vectorConj(pred_mu, set);
821 comm = vectorSub(comm, oNodes);
822 R = vectorUnion(comm, R);
823 }
824 order = top_down;
825 R = vectorConj(succSet(oNodes), set);
Guochun Shif1c154f2003-03-27 17:57:44 +0000826 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000827 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000828 if (ModuloScheduling::printScheduleProcess()) {
829 DEBUG(std::cerr << "order finished\n");
830 DEBUG(std::cerr << "dumping the ordered nodes:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000831 dumpSet(oNodes);
832 dumpCircuits();
833 }
834 //create a new set
835 //FIXME: the nodes between onodes and this circuit should also be include in
836 //this set
Misha Brukman2c821cc2003-04-10 19:19:23 +0000837 if (ModuloScheduling::printScheduleProcess())
838 DEBUG(std::cerr << "building the next set\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000839 set.clear();
840 int k = -1;
841 setSeq++;
842 while (circuits[setSeq][++k] != 0)
843 set.push_back(getNode(circuits[setSeq][k]));
844 if (circuits[setSeq][0] != 0) {
845 backEdgeSrc = circuits[setSeq][k - 1];
846 backEdgeSink = circuits[setSeq][0];
847 }
848 if (set.empty()) {
849 //no circuits any more
850 //collect all other nodes
Misha Brukman2c821cc2003-04-10 19:19:23 +0000851 if (ModuloScheduling::printScheduleProcess())
852 DEBUG(std::cerr << "no circuits any more, collect the rest nodes\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000853 for (unsigned i = 2; i < numNodes + 2; i++) {
854 bool inset = false;
855 for (unsigned j = 0; j < oNodes.size(); j++)
856 if (oNodes[j]->getNodeId() == i) {
857 inset = true;
858 break;
859 }
860 if (!inset)
861 set.push_back(getNode(i));
Guochun Shif1c154f2003-03-27 17:57:44 +0000862 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000863 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000864 if (ModuloScheduling::printScheduleProcess()) {
865 DEBUG(std::cerr << "next set is:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000866 dumpSet(set);
867 }
868 } //while(!set.empty())
869
Guochun Shif1c154f2003-03-27 17:57:44 +0000870}
871
872
873
Misha Brukman8baa01c2003-04-09 21:51:34 +0000874void ModuloSchedGraph::buildGraph(const TargetMachine & target)
Guochun Shif1c154f2003-03-27 17:57:44 +0000875{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000876 const BasicBlock *bb = bbVec[0];
Guochun Shif1c154f2003-03-27 17:57:44 +0000877
Misha Brukman8baa01c2003-04-09 21:51:34 +0000878 assert(bbVec.size() == 1 && "only handling a single basic block here");
Guochun Shif1c154f2003-03-27 17:57:44 +0000879
880 // Use this data structure to note all machine operands that compute
881 // ordinary LLVM values. These must be computed defs (i.e., instructions).
882 // Note that there may be multiple machine instructions that define
883 // each Value.
884 ValueToDefVecMap valueToDefVecMap;
885
886 // Use this data structure to note all memory instructions.
887 // We use this to add memory dependence edges without a second full walk.
888 //
889 // vector<const Instruction*> memVec;
Misha Brukman2c821cc2003-04-10 19:19:23 +0000890 std::vector<ModuloSchedGraphNode*> memNodeVec;
Guochun Shif1c154f2003-03-27 17:57:44 +0000891
Misha Brukman8baa01c2003-04-09 21:51:34 +0000892 // Use this data structure to note any uses or definitions of
Guochun Shif1c154f2003-03-27 17:57:44 +0000893 // machine registers so we can add edges for those later without
894 // extra passes over the nodes.
895 // The vector holds an ordered list of references to the machine reg,
896 // ordered according to control-flow order. This only works for a
897 // single basic block, hence the assertion. Each reference is identified
898 // by the pair: <node, operand-number>.
899 //
900 RegToRefVecMap regToRefVecMap;
Guochun Shif1c154f2003-03-27 17:57:44 +0000901
Misha Brukman8baa01c2003-04-09 21:51:34 +0000902 // Make a dummy root node. We'll add edges to the real roots later.
903 graphRoot = new ModuloSchedGraphNode(0, NULL, NULL, -1, target);
904 graphLeaf = new ModuloSchedGraphNode(1, NULL, NULL, -1, target);
905
906 //----------------------------------------------------------------
907 // First add nodes for all the LLVM instructions in the basic block because
908 // this greatly simplifies identifying which edges to add. Do this one VM
909 // instruction at a time since the ModuloSchedGraphNode needs that.
Guochun Shif1c154f2003-03-27 17:57:44 +0000910 // Also, remember the load/store instructions to add memory deps later.
911 //----------------------------------------------------------------
912
913 //FIXME:if there is call instruction, then we shall quit somewhere
914 // currently we leave call instruction and continue construct graph
915
916 //dump only the blocks which are from loops
917
918
Misha Brukman2c821cc2003-04-10 19:19:23 +0000919 if (ModuloScheduling::printScheduleProcess())
Guochun Shif1c154f2003-03-27 17:57:44 +0000920 this->dump(bb);
921
Misha Brukman8baa01c2003-04-09 21:51:34 +0000922 if (!isLoop(bb)) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000923 DEBUG(std::cerr << " dumping non-loop BB:\n");
Guochun Shif1c154f2003-03-27 17:57:44 +0000924 dump(bb);
925 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000926 if (isLoop(bb)) {
927 buildNodesforBB(target, bb, memNodeVec, regToRefVecMap,
928 valueToDefVecMap);
929
930 this->addDefUseEdges(bb);
931 this->addCDEdges(bb);
932 this->addMemEdges(bb);
933
934 //this->dump();
935
936 int ResII = this->computeResII(bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000937 if (ModuloScheduling::printScheduleProcess())
938 DEBUG(std::cerr << "ResII is " << ResII << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000939 int RecII = this->computeRecII(bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000940 if (ModuloScheduling::printScheduleProcess())
941 DEBUG(std::cerr << "RecII is " << RecII << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000942
943 this->MII = std::max(ResII, RecII);
944
945 this->computeNodeProperty(bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000946 if (ModuloScheduling::printScheduleProcess())
Misha Brukman8baa01c2003-04-09 21:51:34 +0000947 this->dumpNodeProperty();
948
949 this->orderNodes();
950
Misha Brukman2c821cc2003-04-10 19:19:23 +0000951 if (ModuloScheduling::printScheduleProcess())
Misha Brukman8baa01c2003-04-09 21:51:34 +0000952 this->dump();
953 //this->instrScheduling();
954
955 //this->dumpScheduling();
956 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000957}
958
Misha Brukman8baa01c2003-04-09 21:51:34 +0000959ModuloSchedGraphNode *ModuloSchedGraph::getNode(const unsigned nodeId) const
Guochun Shif1c154f2003-03-27 17:57:44 +0000960{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000961 for (const_iterator I = begin(), E = end(); I != E; I++)
962 if ((*I).second->getNodeId() == nodeId)
963 return (ModuloSchedGraphNode *) (*I).second;
Guochun Shif1c154f2003-03-27 17:57:44 +0000964 return NULL;
965}
966
Misha Brukman8baa01c2003-04-09 21:51:34 +0000967int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
Guochun Shif1c154f2003-03-27 17:57:44 +0000968{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000969 int RecII = 0;
Guochun Shif1c154f2003-03-27 17:57:44 +0000970
971 //os<<"begining computerRecII()"<<"\n";
972
Misha Brukman8baa01c2003-04-09 21:51:34 +0000973 //FIXME: only deal with circuits starting at the first node: the phi node
974 //nodeId=2;
Guochun Shif1c154f2003-03-27 17:57:44 +0000975
976 //search all elementary circuits in the dependance graph
977 //assume maximum number of nodes is MAXNODE
Misha Brukman8baa01c2003-04-09 21:51:34 +0000978
Guochun Shif1c154f2003-03-27 17:57:44 +0000979 unsigned path[MAXNODE];
980 unsigned stack[MAXNODE][MAXNODE];
981
Misha Brukman8baa01c2003-04-09 21:51:34 +0000982 for (int j = 0; j < MAXNODE; j++) {
983 path[j] = 0;
984 for (int k = 0; k < MAXNODE; k++)
985 stack[j][k] = 0;
986 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000987 //in our graph, the node number starts at 2
988
989 //number of nodes, because each instruction will result in one node
Misha Brukman8baa01c2003-04-09 21:51:34 +0000990 const unsigned numNodes = bb->size();
Guochun Shif1c154f2003-03-27 17:57:44 +0000991
Misha Brukman8baa01c2003-04-09 21:51:34 +0000992 int i = 0;
993 path[i] = 2;
Guochun Shif1c154f2003-03-27 17:57:44 +0000994
Misha Brukman8baa01c2003-04-09 21:51:34 +0000995 ModuloSchedGraphNode *initNode = getNode(path[0]);
996 unsigned initNodeId = initNode->getNodeId();
997 ModuloSchedGraphNode *currentNode = initNode;
Guochun Shif1c154f2003-03-27 17:57:44 +0000998
Misha Brukman8baa01c2003-04-09 21:51:34 +0000999 while (currentNode != NULL) {
1000 unsigned currentNodeId = currentNode->getNodeId();
Misha Brukman2c821cc2003-04-10 19:19:23 +00001001 // DEBUG(std::cerr<<"current node is "<<currentNodeId<<"\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001002
Misha Brukman8baa01c2003-04-09 21:51:34 +00001003 ModuloSchedGraphNode *nextNode = NULL;
1004 for (ModuloSchedGraphNode::const_iterator I =
1005 currentNode->beginOutEdges(), E = currentNode->endOutEdges();
1006 I != E; I++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001007 //DEBUG(std::cerr <<" searching in outgoint edges of node
Misha Brukman8baa01c2003-04-09 21:51:34 +00001008 //"<<currentNodeId<<"\n";
1009 unsigned nodeId = ((SchedGraphEdge *) * I)->getSink()->getNodeId();
1010 bool inpath = false, instack = false;
1011 int k;
Guochun Shif1c154f2003-03-27 17:57:44 +00001012
Misha Brukman2c821cc2003-04-10 19:19:23 +00001013 //DEBUG(std::cerr<<"nodeId is "<<nodeId<<"\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001014
Misha Brukman8baa01c2003-04-09 21:51:34 +00001015 k = -1;
1016 while (path[++k] != 0)
1017 if (nodeId == path[k]) {
1018 inpath = true;
1019 break;
1020 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001021
Misha Brukman8baa01c2003-04-09 21:51:34 +00001022 k = -1;
1023 while (stack[i][++k] != 0)
1024 if (nodeId == stack[i][k]) {
1025 instack = true;
1026 break;
1027 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001028
Misha Brukman8baa01c2003-04-09 21:51:34 +00001029 if (nodeId > currentNodeId && !inpath && !instack) {
1030 nextNode =
1031 (ModuloSchedGraphNode *) ((SchedGraphEdge *) * I)->getSink();
1032 break;
1033 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001034 }
Misha Brukman8baa01c2003-04-09 21:51:34 +00001035
1036 if (nextNode != NULL) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001037 //DEBUG(std::cerr<<"find the next Node "<<nextNode->getNodeId()<<"\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001038
1039 int j = 0;
1040 while (stack[i][j] != 0)
1041 j++;
1042 stack[i][j] = nextNode->getNodeId();
1043
1044 i++;
1045 path[i] = nextNode->getNodeId();
1046 currentNode = nextNode;
1047 } else {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001048 //DEBUG(std::cerr<<"no expansion any more"<<"\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001049 //confirmCircuit();
1050 for (ModuloSchedGraphNode::const_iterator I =
1051 currentNode->beginOutEdges(), E = currentNode->endOutEdges();
1052 I != E; I++) {
1053 unsigned nodeId = ((SchedGraphEdge *) * I)->getSink()->getNodeId();
1054 if (nodeId == initNodeId) {
1055
1056 int j = -1;
1057 while (circuits[++j][0] != 0);
1058 for (int k = 0; k < MAXNODE; k++)
1059 circuits[j][k] = path[k];
1060
1061 }
1062 }
1063 //remove this node in the path and clear the corresponding entries in the
1064 //stack
1065 path[i] = 0;
1066 int j = 0;
1067 for (j = 0; j < MAXNODE; j++)
1068 stack[i][j] = 0;
1069 i--;
1070 currentNode = getNode(path[i]);
1071 }
1072 if (i == 0) {
1073
Misha Brukman2c821cc2003-04-10 19:19:23 +00001074 if (ModuloScheduling::printScheduleProcess())
1075 DEBUG(std::cerr << "circuits found are:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001076 int j = -1;
1077 while (circuits[++j][0] != 0) {
1078 int k = -1;
1079 while (circuits[j][++k] != 0)
Misha Brukman2c821cc2003-04-10 19:19:23 +00001080 if (ModuloScheduling::printScheduleProcess())
1081 DEBUG(std::cerr << circuits[j][k] << "\t");
1082 if (ModuloScheduling::printScheduleProcess())
1083 DEBUG(std::cerr << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001084
1085 //for this circuit, compute the sum of all edge delay
1086 int sumDelay = 0;
1087 k = -1;
1088 while (circuits[j][++k] != 0) {
1089 //ModuloSchedGraphNode* node =getNode(circuits[j][k]);
1090 unsigned nextNodeId;
1091 nextNodeId =
1092 circuits[j][k + 1] !=
1093 0 ? circuits[j][k + 1] : circuits[j][0];
1094
1095 /*
1096 for(ModuloSchedGraphNode::const_iterator I=node->beginOutEdges(),
1097 E=node->endOutEdges();I !=E; I++)
1098 {
1099 SchedGraphEdge* edge= *I;
1100 if(edge->getSink()->getNodeId() == nextNodeId)
1101 {sumDelay += edge->getMinDelay();break;}
1102 }
1103 */
1104
1105 sumDelay +=
1106 getMaxDelayEdge(circuits[j][k], nextNodeId)->getMinDelay();
1107
1108 }
1109 // assume we have distance 1, in this case the sumDelay is RecII
1110 // this is correct for SSA form only
1111 //
Misha Brukman2c821cc2003-04-10 19:19:23 +00001112 if (ModuloScheduling::printScheduleProcess())
1113 DEBUG(std::cerr << "The total Delay in the circuit is " << sumDelay
1114 << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001115
1116 RecII = RecII > sumDelay ? RecII : sumDelay;
1117
1118 }
1119 return RecII;
1120 }
1121
1122 }
1123
Guochun Shif1c154f2003-03-27 17:57:44 +00001124 return -1;
1125}
1126
Misha Brukman8baa01c2003-04-09 21:51:34 +00001127void ModuloSchedGraph::addResourceUsage(std::vector<std::pair<int,int> > &ruVec,
1128 int rid)
1129{
Misha Brukman2c821cc2003-04-10 19:19:23 +00001130 //DEBUG(std::cerr<<"\nadding a resouce , current resouceUsage vector size is
Misha Brukman8baa01c2003-04-09 21:51:34 +00001131 //"<<ruVec.size()<<"\n";
1132 bool alreadyExists = false;
1133 for (unsigned i = 0; i < ruVec.size(); i++) {
1134 if (rid == ruVec[i].first) {
Guochun Shif1c154f2003-03-27 17:57:44 +00001135 ruVec[i].second++;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001136 alreadyExists = true;
Guochun Shif1c154f2003-03-27 17:57:44 +00001137 break;
1138 }
1139 }
Misha Brukman8baa01c2003-04-09 21:51:34 +00001140 if (!alreadyExists)
1141 ruVec.push_back(std::make_pair(rid, 1));
Misha Brukman2c821cc2003-04-10 19:19:23 +00001142 //DEBUG(std::cerr<<"current resouceUsage vector size is "<<ruVec.size()<<"\n";
Guochun Shif1c154f2003-03-27 17:57:44 +00001143
1144}
Misha Brukman8baa01c2003-04-09 21:51:34 +00001145void ModuloSchedGraph::dumpResourceUsage(std::vector<std::pair<int,int> > &ru)
Guochun Shif1c154f2003-03-27 17:57:44 +00001146{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001147 TargetSchedInfo & msi = (TargetSchedInfo &) target.getSchedInfo();
1148
Misha Brukman2c821cc2003-04-10 19:19:23 +00001149 std::vector<std::pair<int,int> > resourceNumVector = msi.resourceNumVector;
1150 DEBUG(std::cerr << "resourceID\t" << "resourceNum\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001151 for (unsigned i = 0; i < resourceNumVector.size(); i++)
Misha Brukman2c821cc2003-04-10 19:19:23 +00001152 DEBUG(std::cerr << resourceNumVector[i].
1153 first << "\t" << resourceNumVector[i].second << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001154
Misha Brukman2c821cc2003-04-10 19:19:23 +00001155 DEBUG(std::cerr << " maxNumIssueTotal(issue slot in one cycle) = " << msi.
1156 maxNumIssueTotal << "\n");
1157 DEBUG(std::cerr << "resourceID\t resourceUsage\t ResourceNum\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001158 for (unsigned i = 0; i < ru.size(); i++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001159 DEBUG(std::cerr << ru[i].first << "\t" << ru[i].second);
Misha Brukman8baa01c2003-04-09 21:51:34 +00001160 const unsigned resNum = msi.getCPUResourceNum(ru[i].first);
Misha Brukman2c821cc2003-04-10 19:19:23 +00001161 DEBUG(std::cerr << "\t" << resNum << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001162 }
1163}
1164
Misha Brukman8baa01c2003-04-09 21:51:34 +00001165int ModuloSchedGraph::computeResII(const BasicBlock * bb)
Guochun Shif1c154f2003-03-27 17:57:44 +00001166{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001167
1168 const TargetInstrInfo & mii = target.getInstrInfo();
1169 const TargetSchedInfo & msi = target.getSchedInfo();
1170
Guochun Shif1c154f2003-03-27 17:57:44 +00001171 int ResII;
Misha Brukman2c821cc2003-04-10 19:19:23 +00001172 std::vector<std::pair<int,int> > resourceUsage;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001173 //pair<int resourceid, int resourceUsageTimes_in_the_whole_block>
1174
1175 //FIXME: number of functional units the target machine can provide should be
1176 //get from Target here I temporary hardcode it
1177
1178 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E;
1179 I++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001180 if (ModuloScheduling::printScheduleProcess()) {
1181 DEBUG(std::cerr << "machine instruction for llvm instruction( node " <<
1182 getGraphNodeForInst(I)->getNodeId() << ")\n");
1183 DEBUG(std::cerr << "\t" << *I);
Guochun Shif1c154f2003-03-27 17:57:44 +00001184 }
Misha Brukman8baa01c2003-04-09 21:51:34 +00001185 MachineCodeForInstruction & tempMvec =
1186 MachineCodeForInstruction::get(I);
Misha Brukman2c821cc2003-04-10 19:19:23 +00001187 if (ModuloScheduling::printScheduleProcess())
1188 DEBUG(std::cerr << "size =" << tempMvec.size() << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001189 for (unsigned i = 0; i < tempMvec.size(); i++) {
1190 MachineInstr *minstr = tempMvec[i];
1191
1192 unsigned minDelay = mii.minLatency(minstr->getOpCode());
1193 InstrRUsage rUsage = msi.getInstrRUsage(minstr->getOpCode());
1194 InstrClassRUsage classRUsage =
1195 msi.getClassRUsage(mii.getSchedClass(minstr->getOpCode()));
1196 unsigned totCycles = classRUsage.totCycles;
1197
Misha Brukman2c821cc2003-04-10 19:19:23 +00001198 std::vector<std::vector<resourceId_t> > resources=rUsage.resourcesByCycle;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001199 assert(totCycles == resources.size());
Misha Brukman2c821cc2003-04-10 19:19:23 +00001200 if (ModuloScheduling::printScheduleProcess())
1201 DEBUG(std::cerr << "resources Usage for this Instr(totCycles="
1202 << totCycles << ",mindLatency="
1203 << mii.minLatency(minstr->getOpCode()) << "): " << *minstr
1204 << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001205 for (unsigned j = 0; j < resources.size(); j++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001206 if (ModuloScheduling::printScheduleProcess())
1207 DEBUG(std::cerr << "cycle " << j << ": ");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001208 for (unsigned k = 0; k < resources[j].size(); k++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001209 if (ModuloScheduling::printScheduleProcess())
1210 DEBUG(std::cerr << "\t" << resources[j][k]);
Misha Brukman8baa01c2003-04-09 21:51:34 +00001211 addResourceUsage(resourceUsage, resources[j][k]);
1212 }
Misha Brukman2c821cc2003-04-10 19:19:23 +00001213 if (ModuloScheduling::printScheduleProcess())
1214 DEBUG(std::cerr << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001215 }
1216 }
1217 }
Misha Brukman2c821cc2003-04-10 19:19:23 +00001218 if (ModuloScheduling::printScheduleProcess())
Guochun Shif1c154f2003-03-27 17:57:44 +00001219 this->dumpResourceUsage(resourceUsage);
1220
1221 //compute ResII
Misha Brukman8baa01c2003-04-09 21:51:34 +00001222 ResII = 0;
1223 int issueSlots = msi.maxNumIssueTotal;
1224 for (unsigned i = 0; i < resourceUsage.size(); i++) {
1225 int resourceNum = msi.getCPUResourceNum(resourceUsage[i].first);
1226 int useNum = resourceUsage[i].second;
Guochun Shif1c154f2003-03-27 17:57:44 +00001227 double tempII;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001228 if (resourceNum <= issueSlots)
1229 tempII = ceil(1.0 * useNum / resourceNum);
Guochun Shif1c154f2003-03-27 17:57:44 +00001230 else
Misha Brukman8baa01c2003-04-09 21:51:34 +00001231 tempII = ceil(1.0 * useNum / issueSlots);
1232 ResII = std::max((int) tempII, ResII);
Guochun Shif1c154f2003-03-27 17:57:44 +00001233 }
1234 return ResII;
1235}
1236
Misha Brukman2c821cc2003-04-10 19:19:23 +00001237ModuloSchedGraphSet::ModuloSchedGraphSet(const Function *function,
1238 const TargetMachine &target)
Misha Brukman8baa01c2003-04-09 21:51:34 +00001239: method(function)
Guochun Shif1c154f2003-03-27 17:57:44 +00001240{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001241 buildGraphsForMethod(method, target);
Guochun Shif1c154f2003-03-27 17:57:44 +00001242}
1243
1244
1245ModuloSchedGraphSet::~ModuloSchedGraphSet()
1246{
1247 //delete all the graphs
Misha Brukman8baa01c2003-04-09 21:51:34 +00001248 for (iterator I = begin(), E = end(); I != E; ++I)
Guochun Shif1c154f2003-03-27 17:57:44 +00001249 delete *I;
1250}
1251
Misha Brukman8baa01c2003-04-09 21:51:34 +00001252void ModuloSchedGraphSet::dump() const
Guochun Shif1c154f2003-03-27 17:57:44 +00001253{
Misha Brukman2c821cc2003-04-10 19:19:23 +00001254 DEBUG(std::cerr << " ====== ModuloSched graphs for function `" <<
1255 method->getName() << "' =========\n\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001256 for (const_iterator I = begin(); I != end(); ++I)
Guochun Shif1c154f2003-03-27 17:57:44 +00001257 (*I)->dump();
Misha Brukman8baa01c2003-04-09 21:51:34 +00001258
Misha Brukman2c821cc2003-04-10 19:19:23 +00001259 DEBUG(std::cerr << "\n=========End graphs for function `" << method->getName()
1260 << "' ==========\n\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001261}
1262
Misha Brukman8baa01c2003-04-09 21:51:34 +00001263void ModuloSchedGraph::dump(const BasicBlock * bb)
Guochun Shif1c154f2003-03-27 17:57:44 +00001264{
Misha Brukman2c821cc2003-04-10 19:19:23 +00001265 DEBUG(std::cerr << "dumping basic block:");
1266 DEBUG(std::cerr << (bb->hasName()? bb->getName() : "block")
1267 << " (" << bb << ")" << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001268}
1269
Misha Brukman8baa01c2003-04-09 21:51:34 +00001270void ModuloSchedGraph::dump(const BasicBlock * bb, std::ostream & os)
Guochun Shif1c154f2003-03-27 17:57:44 +00001271{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001272 os << "dumping basic block:";
1273 os << (bb->hasName()? bb->getName() : "block")
1274 << " (" << bb << ")" << "\n";
Guochun Shif1c154f2003-03-27 17:57:44 +00001275}
1276
Misha Brukman8baa01c2003-04-09 21:51:34 +00001277void ModuloSchedGraph::dump() const
Guochun Shif1c154f2003-03-27 17:57:44 +00001278{
Misha Brukman2c821cc2003-04-10 19:19:23 +00001279 DEBUG(std::cerr << " ModuloSchedGraph for basic Blocks:");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001280 for (unsigned i = 0, N = bbVec.size(); i < N; i++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001281 DEBUG(std::cerr << (bbVec[i]->hasName()? bbVec[i]->getName() : "block")
1282 << " (" << bbVec[i] << ")" << ((i == N - 1) ? "" : ", "));
Misha Brukman8baa01c2003-04-09 21:51:34 +00001283 }
1284
Misha Brukman2c821cc2003-04-10 19:19:23 +00001285 DEBUG(std::cerr << "\n\n Actual Root nodes : ");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001286 for (unsigned i = 0, N = graphRoot->outEdges.size(); i < N; i++)
Misha Brukman2c821cc2003-04-10 19:19:23 +00001287 DEBUG(std::cerr << graphRoot->outEdges[i]->getSink()->getNodeId()
1288 << ((i == N - 1) ? "" : ", "));
Guochun Shif1c154f2003-03-27 17:57:44 +00001289
Misha Brukman2c821cc2003-04-10 19:19:23 +00001290 DEBUG(std::cerr << "\n Graph Nodes:\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001291 //for (const_iterator I=begin(); I != end(); ++I)
Misha Brukman2c821cc2003-04-10 19:19:23 +00001292 //DEBUG(std::cerr << "\n" << *I->second;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001293 unsigned numNodes = bbVec[0]->size();
1294 for (unsigned i = 2; i < numNodes + 2; i++) {
1295 ModuloSchedGraphNode *node = getNode(i);
Misha Brukman2c821cc2003-04-10 19:19:23 +00001296 DEBUG(std::cerr << "\n" << *node);
Misha Brukman8baa01c2003-04-09 21:51:34 +00001297 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001298
Misha Brukman2c821cc2003-04-10 19:19:23 +00001299 DEBUG(std::cerr << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001300}
Misha Brukman8baa01c2003-04-09 21:51:34 +00001301
1302void ModuloSchedGraph::dumpNodeProperty() const
Guochun Shif1c154f2003-03-27 17:57:44 +00001303{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001304 const BasicBlock *bb = bbVec[0];
1305 unsigned numNodes = bb->size();
1306 for (unsigned i = 2; i < numNodes + 2; i++) {
1307 ModuloSchedGraphNode *node = getNode(i);
Misha Brukman2c821cc2003-04-10 19:19:23 +00001308 DEBUG(std::cerr << "NodeId " << node->getNodeId() << "\t");
1309 DEBUG(std::cerr << "ASAP " << node->getASAP() << "\t");
1310 DEBUG(std::cerr << "ALAP " << node->getALAP() << "\t");
1311 DEBUG(std::cerr << "mov " << node->getMov() << "\t");
1312 DEBUG(std::cerr << "depth " << node->getDepth() << "\t");
1313 DEBUG(std::cerr << "height " << node->getHeight() << "\t\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001314 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001315}
1316
Misha Brukman63e04f32003-04-22 23:00:08 +00001317void ModuloSchedGraphSet::buildGraphsForMethod(const Function *F,
1318 const TargetMachine &target)
Guochun Shif1c154f2003-03-27 17:57:44 +00001319{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001320 for (Function::const_iterator BI = F->begin(); BI != F->end(); ++BI)
1321 addGraph(new ModuloSchedGraph(BI, target));
Guochun Shif1c154f2003-03-27 17:57:44 +00001322}
1323
Misha Brukman63e04f32003-04-22 23:00:08 +00001324std::ostream& operator<<(std::ostream &os,
1325 const ModuloSchedGraphNode &node)
Guochun Shif1c154f2003-03-27 17:57:44 +00001326{
1327 os << std::string(8, ' ')
Misha Brukman8baa01c2003-04-09 21:51:34 +00001328 << "Node " << node.nodeId << " : "
1329 << "latency = " << node.latency << "\n" << std::string(12, ' ');
Guochun Shif1c154f2003-03-27 17:57:44 +00001330
1331 if (node.getInst() == NULL)
1332 os << "(Dummy node)\n";
Misha Brukman8baa01c2003-04-09 21:51:34 +00001333 else {
1334 os << *node.getInst() << "\n" << std::string(12, ' ');
1335 os << node.inEdges.size() << " Incoming Edges:\n";
1336 for (unsigned i = 0, N = node.inEdges.size(); i < N; i++)
1337 os << std::string(16, ' ') << *node.inEdges[i];
1338
1339 os << std::string(12, ' ') << node.outEdges.size()
1340 << " Outgoing Edges:\n";
1341 for (unsigned i = 0, N = node.outEdges.size(); i < N; i++)
1342 os << std::string(16, ' ') << *node.outEdges[i];
1343 }
1344
Guochun Shif1c154f2003-03-27 17:57:44 +00001345 return os;
1346}