blob: 4f46a73fb47dd64ea9c08ba77a267f690b7f2c12 [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
24#define UNIDELAY 1
Guochun Shif1c154f2003-03-27 17:57:44 +000025
Guochun Shif1c154f2003-03-27 17:57:44 +000026//*********************** Internal Data Structures *************************/
27
28// The following two types need to be classes, not typedefs, so we can use
29// opaque declarations in SchedGraph.h
30//
Misha Brukman2c821cc2003-04-10 19:19:23 +000031struct RefVec:public std::vector<std::pair<ModuloSchedGraphNode*,int> > {
Misha Brukman8baa01c2003-04-09 21:51:34 +000032 typedef std::vector<std::pair<ModuloSchedGraphNode*,
33 int> >::iterator iterator;
34 typedef std::vector<std::pair<ModuloSchedGraphNode*,
35 int> >::const_iterator const_iterator;
Guochun Shif1c154f2003-03-27 17:57:44 +000036};
37
Misha Brukman2c821cc2003-04-10 19:19:23 +000038struct RegToRefVecMap:public hash_map<int,RefVec> {
39 typedef hash_map<int,RefVec>::iterator iterator;
40 typedef hash_map<int,RefVec>::const_iterator const_iterator;
Guochun Shif1c154f2003-03-27 17:57:44 +000041};
42
Misha Brukman2c821cc2003-04-10 19:19:23 +000043struct ValueToDefVecMap:public hash_map<const Instruction*,RefVec> {
44 typedef hash_map<const Instruction*, RefVec>::iterator iterator;
45 typedef hash_map<const Instruction*,
Misha Brukman8baa01c2003-04-09 21:51:34 +000046 RefVec>::const_iterator const_iterator;
Guochun Shif1c154f2003-03-27 17:57:44 +000047};
48
Guochun Shif1c154f2003-03-27 17:57:44 +000049// class Modulo SchedGraphNode
50
Guochun Shi099b0642003-06-02 17:48:56 +000051ModuloSchedGraphNode::ModuloSchedGraphNode(unsigned int in_nodeId,
52 const BasicBlock * in_bb,
53 const Instruction * in_inst,
Misha Brukman8baa01c2003-04-09 21:51:34 +000054 int indexInBB,
55 const TargetMachine & target)
Guochun Shi099b0642003-06-02 17:48:56 +000056:SchedGraphNodeCommon(in_nodeId, indexInBB), inst(in_inst)
Guochun Shif1c154f2003-03-27 17:57:44 +000057{
Misha Brukman8baa01c2003-04-09 21:51:34 +000058 if (inst) {
59 //FIXME: find the latency
60 //currently setthe latency to zero
61 latency = 0;
62 }
Guochun Shif1c154f2003-03-27 17:57:44 +000063}
Misha Brukman8baa01c2003-04-09 21:51:34 +000064
Guochun Shif1c154f2003-03-27 17:57:44 +000065//class ModuloScheGraph
66
Misha Brukman8baa01c2003-04-09 21:51:34 +000067void ModuloSchedGraph::addDummyEdges()
Guochun Shif1c154f2003-03-27 17:57:44 +000068{
69 assert(graphRoot->outEdges.size() == 0);
Misha Brukman8baa01c2003-04-09 21:51:34 +000070
71 for (const_iterator I = begin(); I != end(); ++I) {
72 ModuloSchedGraphNode *node = (ModuloSchedGraphNode *) ((*I).second);
73 assert(node != graphRoot && node != graphLeaf);
74 if (node->beginInEdges() == node->endInEdges())
75 (void) new SchedGraphEdge(graphRoot, node, SchedGraphEdge::CtrlDep,
76 SchedGraphEdge::NonDataDep, 0);
77 if (node->beginOutEdges() == node->endOutEdges())
78 (void) new SchedGraphEdge(node, graphLeaf, SchedGraphEdge::CtrlDep,
79 SchedGraphEdge::NonDataDep, 0);
80 }
Guochun Shif1c154f2003-03-27 17:57:44 +000081}
82
Misha Brukman8baa01c2003-04-09 21:51:34 +000083bool isDefinition(const Instruction *I)
Guochun Shif1c154f2003-03-27 17:57:44 +000084{
85 //if(TerminatorInst::classof(I)||FreeInst::classof(I) || StoreInst::classof(I) || CallInst::classof(I))
Misha Brukman8baa01c2003-04-09 21:51:34 +000086 if (!I->hasName())
Guochun Shif1c154f2003-03-27 17:57:44 +000087 return false;
88 else
89 return true;
90}
91
Misha Brukman8baa01c2003-04-09 21:51:34 +000092void ModuloSchedGraph::addDefUseEdges(const BasicBlock *bb)
Guochun Shif1c154f2003-03-27 17:57:44 +000093{
94 //collect def instructions, store them in vector
Guochun Shi6fbe5fb2003-04-06 23:56:19 +000095 // const TargetInstrInfo& mii = target.getInstrInfo();
Misha Brukman8baa01c2003-04-09 21:51:34 +000096 const TargetInstrInfo & mii = target.getInstrInfo();
97
98 typedef std::vector < ModuloSchedGraphNode * >DefVec;
Guochun Shif1c154f2003-03-27 17:57:44 +000099 DefVec defVec;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000100
Guochun Shif1c154f2003-03-27 17:57:44 +0000101 //find those def instructions
Misha Brukman8baa01c2003-04-09 21:51:34 +0000102 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E; ++I) {
103 if (I->getType() != Type::VoidTy) {
104 defVec.push_back(this->getGraphNodeForInst(I));
105 }
106 }
107
108 for (unsigned int i = 0; i < defVec.size(); i++) {
109 for (Value::use_const_iterator I = defVec[i]->getInst()->use_begin();
110 I != defVec[i]->getInst()->use_end(); I++) {
Misha Brukman63e04f32003-04-22 23:00:08 +0000111 //for each use of a def, add a flow edge from the def instruction to the
112 //ref instruction
Misha Brukman8baa01c2003-04-09 21:51:34 +0000113
114 const Instruction *value = defVec[i]->getInst();
115 Instruction *inst = (Instruction *) (*I);
116 ModuloSchedGraphNode *node = NULL;
117
118 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end();
119 I != E; ++I)
120 if ((const Instruction *) I == inst) {
121 node = (*this)[inst];
122 break;
123 }
124
125 assert(inst != NULL && " Use not an Instruction ?");
126
127 if (node == NULL) //inst is not an instruction in this block
Guochun Shif1c154f2003-03-27 17:57:44 +0000128 {
Misha Brukman8baa01c2003-04-09 21:51:34 +0000129 } else {
130 // Add a flow edge from the def instruction to the ref instruction
131
132 // self loop will not happen in SSA form
133 assert(defVec[i] != node && "same node?");
134
135 // This is a true dependence, so the delay is equal to the delay of the
136 // pred node.
137 int delay = 0;
138 MachineCodeForInstruction & tempMvec =
139 MachineCodeForInstruction::get(value);
140 for (unsigned j = 0; j < tempMvec.size(); j++) {
141 MachineInstr *temp = tempMvec[j];
142 //delay +=mii.minLatency(temp->getOpCode());
143 delay = std::max(delay, mii.minLatency(temp->getOpCode()));
144 }
145
146 SchedGraphEdge *trueEdge =
147 new SchedGraphEdge(defVec[i], node, value,
148 SchedGraphEdge::TrueDep, delay);
149
150 // if the ref instruction is before the def instrution
151 // then the def instruction must be a phi instruction
152 // add an anti-dependence edge to from the ref instruction to the def
153 // instruction
154 if (node->getOrigIndexInBB() < defVec[i]->getOrigIndexInBB()) {
155 assert(PHINode::classof(inst)
156 && "the ref instruction befre def is not PHINode?");
157 trueEdge->setIteDiff(1);
158 }
159
Guochun Shif1c154f2003-03-27 17:57:44 +0000160 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000161
Misha Brukman8baa01c2003-04-09 21:51:34 +0000162 }
163 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000164}
165
Misha Brukman8baa01c2003-04-09 21:51:34 +0000166void ModuloSchedGraph::addCDEdges(const BasicBlock * bb) {
167 // find the last instruction in the basic block
168 // see if it is an branch instruction.
169 // If yes, then add an edge from each node expcept the last node to the last
170 // node
171 const Instruction *inst = &(bb->back());
172 ModuloSchedGraphNode *lastNode = (*this)[inst];
173 if (TerminatorInst::classof(inst))
174 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E;
175 I++) {
176 if (inst != I) {
177 ModuloSchedGraphNode *node = (*this)[I];
178 //use latency of 0
179 (void) new SchedGraphEdge(node, lastNode, SchedGraphEdge::CtrlDep,
180 SchedGraphEdge::NonDataDep, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000181 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000182
183 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000184}
185
Misha Brukman8baa01c2003-04-09 21:51:34 +0000186static const int SG_LOAD_REF = 0;
Guochun Shif1c154f2003-03-27 17:57:44 +0000187static const int SG_STORE_REF = 1;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000188static const int SG_CALL_REF = 2;
Guochun Shif1c154f2003-03-27 17:57:44 +0000189
190static const unsigned int SG_DepOrderArray[][3] = {
Misha Brukman8baa01c2003-04-09 21:51:34 +0000191 {SchedGraphEdge::NonDataDep,
192 SchedGraphEdge::AntiDep,
193 SchedGraphEdge::AntiDep},
194 {SchedGraphEdge::TrueDep,
195 SchedGraphEdge::OutputDep,
196 SchedGraphEdge::TrueDep | SchedGraphEdge::OutputDep},
197 {SchedGraphEdge::TrueDep,
198 SchedGraphEdge::AntiDep | SchedGraphEdge::OutputDep,
199 SchedGraphEdge::TrueDep | SchedGraphEdge::AntiDep
200 | SchedGraphEdge::OutputDep}
Guochun Shif1c154f2003-03-27 17:57:44 +0000201};
202
203
204// Add a dependence edge between every pair of machine load/store/call
205// instructions, where at least one is a store or a call.
206// Use latency 1 just to ensure that memory operations are ordered;
207// latency does not otherwise matter (true dependences enforce that).
208//
Misha Brukman8baa01c2003-04-09 21:51:34 +0000209void ModuloSchedGraph::addMemEdges(const BasicBlock * bb) {
210
211 std::vector<ModuloSchedGraphNode*> memNodeVec;
Guochun Shif1c154f2003-03-27 17:57:44 +0000212
213 //construct the memNodeVec
Misha Brukman8baa01c2003-04-09 21:51:34 +0000214 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E; ++I) {
215 if (LoadInst::classof(I) || StoreInst::classof(I)
216 || CallInst::classof(I)) {
217 ModuloSchedGraphNode *node = (*this)[(const Instruction *) I];
218 memNodeVec.push_back(node);
219 }
220 }
221
Guochun Shif1c154f2003-03-27 17:57:44 +0000222 // Instructions in memNodeVec are in execution order within the basic block,
223 // so simply look at all pairs <memNodeVec[i], memNodeVec[j: j > i]>.
224 //
Misha Brukman8baa01c2003-04-09 21:51:34 +0000225 for (unsigned im = 0, NM = memNodeVec.size(); im < NM; im++) {
226 const Instruction *fromInst = memNodeVec[im]->getInst();
227 int fromType = CallInst::classof(fromInst) ? SG_CALL_REF
228 : LoadInst::classof(fromInst) ? SG_LOAD_REF : SG_STORE_REF;
229 for (unsigned jm = im + 1; jm < NM; jm++) {
230 const Instruction *toInst = memNodeVec[jm]->getInst();
231 int toType = CallInst::classof(toInst) ? SG_CALL_REF
232 : LoadInst::classof(toInst) ? SG_LOAD_REF : SG_STORE_REF;
233 if (fromType != SG_LOAD_REF || toType != SG_LOAD_REF) {
234 (void) new SchedGraphEdge(memNodeVec[im], memNodeVec[jm],
235 SchedGraphEdge::MemoryDep,
236 SG_DepOrderArray[fromType][toType], 1);
237
238 SchedGraphEdge *edge =
239 new SchedGraphEdge(memNodeVec[jm], memNodeVec[im],
240 SchedGraphEdge::MemoryDep,
241 SG_DepOrderArray[toType][fromType], 1);
242 edge->setIteDiff(1);
243
244 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000245 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000246 }
247}
Guochun Shif1c154f2003-03-27 17:57:44 +0000248
249
250
Misha Brukman8baa01c2003-04-09 21:51:34 +0000251void ModuloSchedGraph::buildNodesforBB(const TargetMachine &target,
252 const BasicBlock *bb,
253 std::vector<ModuloSchedGraphNode*> &memNode,
254 RegToRefVecMap &regToRefVecMap,
255 ValueToDefVecMap &valueToDefVecMap)
Guochun Shif1c154f2003-03-27 17:57:44 +0000256{
Guochun Shi6fbe5fb2003-04-06 23:56:19 +0000257 //const TargetInstrInfo& mii=target.getInstrInfo();
Misha Brukman8baa01c2003-04-09 21:51:34 +0000258
Guochun Shif1c154f2003-03-27 17:57:44 +0000259 //Build graph nodes for each LLVM instruction and gather def/use info.
260 //Do both together in a single pass over all machine instructions.
Misha Brukman8baa01c2003-04-09 21:51:34 +0000261
262 int i = 0;
263 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E;
264 ++I) {
265 ModuloSchedGraphNode *node =
266 new ModuloSchedGraphNode(getNumNodes(), bb, I, i, target);
267 i++;
268 this->noteModuloSchedGraphNodeForInst(I, node);
269 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000270
271 //this function finds some info about instruction in basic block for later use
Misha Brukman8baa01c2003-04-09 21:51:34 +0000272 //findDefUseInfoAtInstr(target, node,
273 //memNode,regToRefVecMap,valueToDefVecMap);
Guochun Shif1c154f2003-03-27 17:57:44 +0000274}
275
276
Misha Brukman8baa01c2003-04-09 21:51:34 +0000277bool ModuloSchedGraph::isLoop(const BasicBlock *bb) {
Guochun Shif1c154f2003-03-27 17:57:44 +0000278 //only if the last instruction in the basicblock is branch instruction and
279 //there is at least an option to branch itself
280
Misha Brukman8baa01c2003-04-09 21:51:34 +0000281 const Instruction *inst = &(bb->back());
282 if (BranchInst::classof(inst)) {
283 for (unsigned i = 0; i < ((BranchInst *) inst)->getNumSuccessors();
284 i++) {
285 BasicBlock *sb = ((BranchInst *) inst)->getSuccessor(i);
286 if (sb == bb)
287 return true;
288 }
289 }
290
Guochun Shif1c154f2003-03-27 17:57:44 +0000291 return false;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000292
Guochun Shif1c154f2003-03-27 17:57:44 +0000293}
Misha Brukman8baa01c2003-04-09 21:51:34 +0000294
295bool ModuloSchedGraph::isLoop() {
Guochun Shif1c154f2003-03-27 17:57:44 +0000296 //only if the last instruction in the basicblock is branch instruction and
297 //there is at least an option to branch itself
Guochun Shif1c154f2003-03-27 17:57:44 +0000298
Guochun Shi099b0642003-06-02 17:48:56 +0000299 assert(this->bb&& "the basicblock is not empty");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000300 const Instruction *inst = &(bb->back());
301 if (BranchInst::classof(inst))
302 for (unsigned i = 0; i < ((BranchInst *) inst)->getNumSuccessors();
303 i++) {
304 BasicBlock *sb = ((BranchInst *) inst)->getSuccessor(i);
305 if (sb == bb)
306 return true;
Guochun Shif1c154f2003-03-27 17:57:44 +0000307 }
Guochun Shi099b0642003-06-02 17:48:56 +0000308
Misha Brukman8baa01c2003-04-09 21:51:34 +0000309 return false;
310
311}
312
313void ModuloSchedGraph::computeNodeASAP(const BasicBlock *bb) {
314
315 //FIXME: now assume the only backward edges come from the edges from other
316 //nodes to the phi Node so i will ignore all edges to the phi node; after
317 //this, there shall be no recurrence.
318
319 unsigned numNodes = bb->size();
320 for (unsigned i = 2; i < numNodes + 2; i++) {
321 ModuloSchedGraphNode *node = getNode(i);
322 node->setPropertyComputed(false);
323 }
324
325 for (unsigned i = 2; i < numNodes + 2; i++) {
326 ModuloSchedGraphNode *node = getNode(i);
327 node->ASAP = 0;
328 if (i == 2 || node->getNumInEdges() == 0) {
Guochun Shif1c154f2003-03-27 17:57:44 +0000329 node->setPropertyComputed(true);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000330 continue;
Guochun Shif1c154f2003-03-27 17:57:44 +0000331 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000332 for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E =
333 node->endInEdges(); I != E; I++) {
334 SchedGraphEdge *edge = *I;
335 ModuloSchedGraphNode *pred =
336 (ModuloSchedGraphNode *) (edge->getSrc());
337 assert(pred->getPropertyComputed()
338 && "pred node property is not computed!");
339 int temp =
340 pred->ASAP + edge->getMinDelay() -
341 edge->getIteDiff() * this->MII;
342 node->ASAP = std::max(node->ASAP, temp);
343 }
344 node->setPropertyComputed(true);
345 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000346}
347
Misha Brukman8baa01c2003-04-09 21:51:34 +0000348void ModuloSchedGraph::computeNodeALAP(const BasicBlock *bb) {
349 unsigned numNodes = bb->size();
350 int maxASAP = 0;
351 for (unsigned i = numNodes + 1; i >= 2; i--) {
352 ModuloSchedGraphNode *node = getNode(i);
353 node->setPropertyComputed(false);
354 //cerr<< " maxASAP= " <<maxASAP<<" node->ASAP= "<< node->ASAP<<"\n";
355 maxASAP = std::max(maxASAP, node->ASAP);
356 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000357
358 //cerr<<"maxASAP is "<<maxASAP<<"\n";
Misha Brukman8baa01c2003-04-09 21:51:34 +0000359
360 for (unsigned i = numNodes + 1; i >= 2; i--) {
361 ModuloSchedGraphNode *node = getNode(i);
362 node->ALAP = maxASAP;
363 for (ModuloSchedGraphNode::const_iterator I =
364 node->beginOutEdges(), E = node->endOutEdges(); I != E; I++) {
365 SchedGraphEdge *edge = *I;
366 ModuloSchedGraphNode *succ =
367 (ModuloSchedGraphNode *) (edge->getSink());
368 if (PHINode::classof(succ->getInst()))
369 continue;
370 assert(succ->getPropertyComputed()
371 && "succ node property is not computed!");
372 int temp =
373 succ->ALAP - edge->getMinDelay() +
374 edge->getIteDiff() * this->MII;
375 node->ALAP = std::min(node->ALAP, temp);
376 }
377 node->setPropertyComputed(true);
378 }
379}
380
381void ModuloSchedGraph::computeNodeMov(const BasicBlock *bb)
382{
383 unsigned numNodes = bb->size();
384 for (unsigned i = 2; i < numNodes + 2; i++) {
385 ModuloSchedGraphNode *node = getNode(i);
386 node->mov = node->ALAP - node->ASAP;
387 assert(node->mov >= 0
388 && "move freedom for this node is less than zero? ");
389 }
390}
391
392
393void ModuloSchedGraph::computeNodeDepth(const BasicBlock * bb)
394{
395
396 unsigned numNodes = bb->size();
397 for (unsigned i = 2; i < numNodes + 2; i++) {
398 ModuloSchedGraphNode *node = getNode(i);
399 node->setPropertyComputed(false);
400 }
401
402 for (unsigned i = 2; i < numNodes + 2; i++) {
403 ModuloSchedGraphNode *node = getNode(i);
404 node->depth = 0;
405 if (i == 2 || node->getNumInEdges() == 0) {
Guochun Shif1c154f2003-03-27 17:57:44 +0000406 node->setPropertyComputed(true);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000407 continue;
Guochun Shif1c154f2003-03-27 17:57:44 +0000408 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000409 for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E =
410 node->endInEdges(); I != E; I++) {
411 SchedGraphEdge *edge = *I;
412 ModuloSchedGraphNode *pred =
413 (ModuloSchedGraphNode *) (edge->getSrc());
414 assert(pred->getPropertyComputed()
415 && "pred node property is not computed!");
416 int temp = pred->depth + edge->getMinDelay();
417 node->depth = std::max(node->depth, temp);
Guochun Shif1c154f2003-03-27 17:57:44 +0000418 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000419 node->setPropertyComputed(true);
420 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000421
422}
423
424
Misha Brukman8baa01c2003-04-09 21:51:34 +0000425void ModuloSchedGraph::computeNodeHeight(const BasicBlock *bb)
Guochun Shif1c154f2003-03-27 17:57:44 +0000426{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000427 unsigned numNodes = bb->size();
428 for (unsigned i = numNodes + 1; i >= 2; i--) {
429 ModuloSchedGraphNode *node = getNode(i);
430 node->setPropertyComputed(false);
431 }
432
433 for (unsigned i = numNodes + 1; i >= 2; i--) {
434 ModuloSchedGraphNode *node = getNode(i);
435 node->height = 0;
436 for (ModuloSchedGraphNode::const_iterator I =
437 node->beginOutEdges(), E = node->endOutEdges(); I != E; ++I) {
438 SchedGraphEdge *edge = *I;
439 ModuloSchedGraphNode *succ =
440 (ModuloSchedGraphNode *) (edge->getSink());
441 if (PHINode::classof(succ->getInst()))
442 continue;
443 assert(succ->getPropertyComputed()
444 && "succ node property is not computed!");
445 node->height = std::max(node->height, succ->height + edge->getMinDelay());
446
Guochun Shif1c154f2003-03-27 17:57:44 +0000447 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000448 node->setPropertyComputed(true);
449
450 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000451
452}
453
Misha Brukman8baa01c2003-04-09 21:51:34 +0000454void ModuloSchedGraph::computeNodeProperty(const BasicBlock * bb)
Guochun Shif1c154f2003-03-27 17:57:44 +0000455{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000456 //FIXME: now assume the only backward edges come from the edges from other
457 //nodes to the phi Node so i will ignore all edges to the phi node; after
458 //this, there shall be no recurrence.
459
Guochun Shif1c154f2003-03-27 17:57:44 +0000460 this->computeNodeASAP(bb);
461 this->computeNodeALAP(bb);
462 this->computeNodeMov(bb);
463 this->computeNodeDepth(bb);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000464 this->computeNodeHeight(bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000465}
466
467
468//do not consider the backedge in these two functions:
469// i.e. don't consider the edge with destination in phi node
Misha Brukman8baa01c2003-04-09 21:51:34 +0000470std::vector<ModuloSchedGraphNode*>
471ModuloSchedGraph::predSet(std::vector<ModuloSchedGraphNode*> set,
472 unsigned backEdgeSrc,
473 unsigned
474 backEdgeSink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000475{
476 std::vector<ModuloSchedGraphNode*> predS;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000477 for (unsigned i = 0; i < set.size(); i++) {
478 ModuloSchedGraphNode *node = set[i];
479 for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E =
480 node->endInEdges(); I != E; I++) {
481 SchedGraphEdge *edge = *I;
482 if (edge->getSrc()->getNodeId() == backEdgeSrc
483 && edge->getSink()->getNodeId() == backEdgeSink)
484 continue;
485 ModuloSchedGraphNode *pred =
486 (ModuloSchedGraphNode *) (edge->getSrc());
487 //if pred is not in the predSet, push it in vector
488 bool alreadyInset = false;
489 for (unsigned j = 0; j < predS.size(); ++j)
490 if (predS[j]->getNodeId() == pred->getNodeId()) {
491 alreadyInset = true;
492 break;
493 }
494
495 for (unsigned j = 0; j < set.size(); ++j)
496 if (set[j]->getNodeId() == pred->getNodeId()) {
497 alreadyInset = true;
498 break;
499 }
500
501 if (!alreadyInset)
502 predS.push_back(pred);
Guochun Shif1c154f2003-03-27 17:57:44 +0000503 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000504 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000505 return predS;
506}
507
508ModuloSchedGraph::NodeVec ModuloSchedGraph::predSet(NodeVec set)
509{
510 //node number increases from 2
Misha Brukman8baa01c2003-04-09 21:51:34 +0000511 return predSet(set, 0, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000512}
513
Misha Brukman8baa01c2003-04-09 21:51:34 +0000514std::vector <ModuloSchedGraphNode*>
515ModuloSchedGraph::predSet(ModuloSchedGraphNode *_node,
516 unsigned backEdgeSrc, unsigned backEdgeSink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000517{
Guochun Shif1c154f2003-03-27 17:57:44 +0000518 std::vector<ModuloSchedGraphNode*> set;
519 set.push_back(_node);
520 return predSet(set, backEdgeSrc, backEdgeSink);
Guochun Shif1c154f2003-03-27 17:57:44 +0000521}
522
Misha Brukman8baa01c2003-04-09 21:51:34 +0000523std::vector <ModuloSchedGraphNode*>
524ModuloSchedGraph::predSet(ModuloSchedGraphNode * _node)
Guochun Shif1c154f2003-03-27 17:57:44 +0000525{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000526 return predSet(_node, 0, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000527}
528
Misha Brukman8baa01c2003-04-09 21:51:34 +0000529std::vector<ModuloSchedGraphNode*>
530ModuloSchedGraph::succSet(std::vector<ModuloSchedGraphNode*> set,
531 unsigned src, unsigned sink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000532{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000533 std::vector<ModuloSchedGraphNode*> succS;
534 for (unsigned i = 0; i < set.size(); i++) {
535 ModuloSchedGraphNode *node = set[i];
536 for (ModuloSchedGraphNode::const_iterator I =
537 node->beginOutEdges(), E = node->endOutEdges(); I != E; I++) {
538 SchedGraphEdge *edge = *I;
539 if (edge->getSrc()->getNodeId() == src
540 && edge->getSink()->getNodeId() == sink)
541 continue;
542 ModuloSchedGraphNode *succ =
543 (ModuloSchedGraphNode *) (edge->getSink());
544 //if pred is not in the predSet, push it in vector
545 bool alreadyInset = false;
546 for (unsigned j = 0; j < succS.size(); j++)
547 if (succS[j]->getNodeId() == succ->getNodeId()) {
548 alreadyInset = true;
549 break;
550 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000551
Misha Brukman8baa01c2003-04-09 21:51:34 +0000552 for (unsigned j = 0; j < set.size(); j++)
553 if (set[j]->getNodeId() == succ->getNodeId()) {
554 alreadyInset = true;
555 break;
556 }
557 if (!alreadyInset)
558 succS.push_back(succ);
Guochun Shif1c154f2003-03-27 17:57:44 +0000559 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000560 }
561 return succS;
Guochun Shif1c154f2003-03-27 17:57:44 +0000562}
563
564ModuloSchedGraph::NodeVec ModuloSchedGraph::succSet(NodeVec set)
565{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000566 return succSet(set, 0, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000567}
568
569
Misha Brukman8baa01c2003-04-09 21:51:34 +0000570std::vector<ModuloSchedGraphNode*>
571ModuloSchedGraph::succSet(ModuloSchedGraphNode *_node,
572 unsigned src, unsigned sink)
Guochun Shif1c154f2003-03-27 17:57:44 +0000573{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000574 std::vector<ModuloSchedGraphNode*>set;
Guochun Shif1c154f2003-03-27 17:57:44 +0000575 set.push_back(_node);
576 return succSet(set, src, sink);
Guochun Shif1c154f2003-03-27 17:57:44 +0000577}
578
Misha Brukman8baa01c2003-04-09 21:51:34 +0000579std::vector<ModuloSchedGraphNode*>
580ModuloSchedGraph::succSet(ModuloSchedGraphNode * _node)
Guochun Shif1c154f2003-03-27 17:57:44 +0000581{
582 return succSet(_node, 0, 0);
583}
584
Misha Brukman8baa01c2003-04-09 21:51:34 +0000585SchedGraphEdge *ModuloSchedGraph::getMaxDelayEdge(unsigned srcId,
586 unsigned sinkId)
Guochun Shif1c154f2003-03-27 17:57:44 +0000587{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000588 ModuloSchedGraphNode *node = getNode(srcId);
589 SchedGraphEdge *maxDelayEdge = NULL;
590 int maxDelay = -1;
591 for (ModuloSchedGraphNode::const_iterator I = node->beginOutEdges(), E =
592 node->endOutEdges(); I != E; I++) {
593 SchedGraphEdge *edge = *I;
594 if (edge->getSink()->getNodeId() == sinkId)
595 if (edge->getMinDelay() > maxDelay) {
596 maxDelayEdge = edge;
597 maxDelay = edge->getMinDelay();
598 }
599 }
600 assert(maxDelayEdge != NULL && "no edge between the srcId and sinkId?");
Guochun Shif1c154f2003-03-27 17:57:44 +0000601 return maxDelayEdge;
602}
603
604void ModuloSchedGraph::dumpCircuits()
605{
Guochun Shi33280522003-06-08 20:40:47 +0000606 DEBUG_PRINT(std::cerr << "dumping circuits for graph:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000607 int j = -1;
608 while (circuits[++j][0] != 0) {
609 int k = -1;
610 while (circuits[j][++k] != 0)
Guochun Shi33280522003-06-08 20:40:47 +0000611 DEBUG_PRINT(std::cerr << circuits[j][k] << "\t");
612 DEBUG_PRINT(std::cerr << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +0000613 }
614}
615
Misha Brukman8baa01c2003-04-09 21:51:34 +0000616void ModuloSchedGraph::dumpSet(std::vector < ModuloSchedGraphNode * >set)
Guochun Shif1c154f2003-03-27 17:57:44 +0000617{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000618 for (unsigned i = 0; i < set.size(); i++)
Guochun Shi33280522003-06-08 20:40:47 +0000619 DEBUG_PRINT(std::cerr << set[i]->getNodeId() << "\t");
620 DEBUG_PRINT(std::cerr << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +0000621}
622
Misha Brukman8baa01c2003-04-09 21:51:34 +0000623std::vector<ModuloSchedGraphNode*>
624ModuloSchedGraph::vectorUnion(std::vector<ModuloSchedGraphNode*> set1,
625 std::vector<ModuloSchedGraphNode*> set2)
Guochun Shif1c154f2003-03-27 17:57:44 +0000626{
627 std::vector<ModuloSchedGraphNode*> unionVec;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000628 for (unsigned i = 0; i < set1.size(); i++)
Guochun Shif1c154f2003-03-27 17:57:44 +0000629 unionVec.push_back(set1[i]);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000630 for (unsigned j = 0; j < set2.size(); j++) {
631 bool inset = false;
632 for (unsigned i = 0; i < unionVec.size(); i++)
633 if (set2[j] == unionVec[i])
634 inset = true;
635 if (!inset)
636 unionVec.push_back(set2[j]);
Guochun Shif1c154f2003-03-27 17:57:44 +0000637 }
638 return unionVec;
639}
Misha Brukman8baa01c2003-04-09 21:51:34 +0000640
641std::vector<ModuloSchedGraphNode*>
642ModuloSchedGraph::vectorConj(std::vector<ModuloSchedGraphNode*> set1,
643 std::vector<ModuloSchedGraphNode*> set2)
Guochun Shif1c154f2003-03-27 17:57:44 +0000644{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000645 std::vector<ModuloSchedGraphNode*> conjVec;
646 for (unsigned i = 0; i < set1.size(); i++)
647 for (unsigned j = 0; j < set2.size(); j++)
648 if (set1[i] == set2[j])
649 conjVec.push_back(set1[i]);
650 return conjVec;
Guochun Shif1c154f2003-03-27 17:57:44 +0000651}
652
Misha Brukman8baa01c2003-04-09 21:51:34 +0000653ModuloSchedGraph::NodeVec ModuloSchedGraph::vectorSub(NodeVec set1,
654 NodeVec set2)
Guochun Shif1c154f2003-03-27 17:57:44 +0000655{
656 NodeVec newVec;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000657 for (NodeVec::iterator I = set1.begin(); I != set1.end(); I++) {
658 bool inset = false;
659 for (NodeVec::iterator II = set2.begin(); II != set2.end(); II++)
660 if ((*I)->getNodeId() == (*II)->getNodeId()) {
661 inset = true;
662 break;
663 }
664 if (!inset)
665 newVec.push_back(*I);
Guochun Shif1c154f2003-03-27 17:57:44 +0000666 }
667 return newVec;
668}
Guochun Shif1c154f2003-03-27 17:57:44 +0000669
Misha Brukman8baa01c2003-04-09 21:51:34 +0000670void ModuloSchedGraph::orderNodes() {
671 oNodes.clear();
672
673 std::vector < ModuloSchedGraphNode * >set;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000674 unsigned numNodes = bb->size();
675
Misha Brukman2c821cc2003-04-10 19:19:23 +0000676 // first order all the sets
Misha Brukman8baa01c2003-04-09 21:51:34 +0000677 int j = -1;
678 int totalDelay = -1;
679 int preDelay = -1;
680 while (circuits[++j][0] != 0) {
681 int k = -1;
682 preDelay = totalDelay;
683
684 while (circuits[j][++k] != 0) {
685 ModuloSchedGraphNode *node = getNode(circuits[j][k]);
Guochun Shif1c154f2003-03-27 17:57:44 +0000686 unsigned nextNodeId;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000687 nextNodeId =
688 circuits[j][k + 1] != 0 ? circuits[j][k + 1] : circuits[j][0];
689 SchedGraphEdge *edge = getMaxDelayEdge(circuits[j][k], nextNodeId);
Guochun Shif1c154f2003-03-27 17:57:44 +0000690 totalDelay += edge->getMinDelay();
691 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000692 if (preDelay != -1 && totalDelay > preDelay) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000693 // swap circuits[j][] and cuicuits[j-1][]
Guochun Shif1c154f2003-03-27 17:57:44 +0000694 unsigned temp[MAXNODE];
Misha Brukman8baa01c2003-04-09 21:51:34 +0000695 for (int k = 0; k < MAXNODE; k++) {
696 temp[k] = circuits[j - 1][k];
697 circuits[j - 1][k] = circuits[j][k];
698 circuits[j][k] = temp[k];
Guochun Shif1c154f2003-03-27 17:57:44 +0000699 }
700 //restart
Misha Brukman8baa01c2003-04-09 21:51:34 +0000701 j = -1;
Guochun Shif1c154f2003-03-27 17:57:44 +0000702 }
703 }
704
Misha Brukman2c821cc2003-04-10 19:19:23 +0000705 // build the first set
Guochun Shif1c154f2003-03-27 17:57:44 +0000706 int backEdgeSrc;
707 int backEdgeSink;
Misha Brukman2c821cc2003-04-10 19:19:23 +0000708 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000709 DEBUG_PRINT(std::cerr << "building the first set" << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000710 int setSeq = -1;
711 int k = -1;
Guochun Shif1c154f2003-03-27 17:57:44 +0000712 setSeq++;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000713 while (circuits[setSeq][++k] != 0)
Guochun Shif1c154f2003-03-27 17:57:44 +0000714 set.push_back(getNode(circuits[setSeq][k]));
Misha Brukman8baa01c2003-04-09 21:51:34 +0000715 if (circuits[setSeq][0] != 0) {
716 backEdgeSrc = circuits[setSeq][k - 1];
717 backEdgeSink = circuits[setSeq][0];
Guochun Shif1c154f2003-03-27 17:57:44 +0000718 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000719 if (ModuloScheduling::printScheduleProcess()) {
Guochun Shi33280522003-06-08 20:40:47 +0000720 DEBUG_PRINT(std::cerr << "the first set is:");
Guochun Shif1c154f2003-03-27 17:57:44 +0000721 dumpSet(set);
722 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000723 // implement the ordering algorithm
Misha Brukman8baa01c2003-04-09 21:51:34 +0000724 enum OrderSeq { bottom_up, top_down };
Guochun Shif1c154f2003-03-27 17:57:44 +0000725 OrderSeq order;
726 std::vector<ModuloSchedGraphNode*> R;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000727 while (!set.empty()) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000728 std::vector<ModuloSchedGraphNode*> pset = predSet(oNodes);
729 std::vector<ModuloSchedGraphNode*> sset = succSet(oNodes);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000730
731 if (!pset.empty() && !vectorConj(pset, set).empty()) {
732 R = vectorConj(pset, set);
733 order = bottom_up;
734 } else if (!sset.empty() && !vectorConj(sset, set).empty()) {
735 R = vectorConj(sset, set);
736 order = top_down;
737 } else {
738 int maxASAP = -1;
739 int position = -1;
740 for (unsigned i = 0; i < set.size(); i++) {
741 int temp = set[i]->getASAP();
742 if (temp > maxASAP) {
743 maxASAP = temp;
744 position = i;
745 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000746 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000747 R.push_back(set[position]);
748 order = bottom_up;
749 }
750
751 while (!R.empty()) {
752 if (order == top_down) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000753 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000754 DEBUG_PRINT(std::cerr << "in top_down round\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000755 while (!R.empty()) {
756 int maxHeight = -1;
757 NodeVec::iterator chosenI;
758 for (NodeVec::iterator I = R.begin(); I != R.end(); I++) {
759 int temp = (*I)->height;
760 if ((temp > maxHeight)
761 || (temp == maxHeight && (*I)->mov <= (*chosenI)->mov)) {
762
763 if ((temp > maxHeight)
764 || (temp == maxHeight && (*I)->mov < (*chosenI)->mov)) {
765 maxHeight = temp;
766 chosenI = I;
767 continue;
768 }
769 //possible case: instruction A and B has the same height and mov,
770 //but A has dependence to B e.g B is the branch instruction in the
771 //end, or A is the phi instruction at the beginning
772 if ((*I)->mov == (*chosenI)->mov)
773 for (ModuloSchedGraphNode::const_iterator oe =
774 (*I)->beginOutEdges(), end = (*I)->endOutEdges();
775 oe != end; oe++) {
776 if ((*oe)->getSink() == (*chosenI)) {
777 maxHeight = temp;
778 chosenI = I;
779 continue;
780 }
781 }
782 }
783 }
784 ModuloSchedGraphNode *mu = *chosenI;
785 oNodes.push_back(mu);
786 R.erase(chosenI);
787 std::vector<ModuloSchedGraphNode*> succ_mu =
788 succSet(mu, backEdgeSrc, backEdgeSink);
789 std::vector<ModuloSchedGraphNode*> comm =
790 vectorConj(succ_mu, set);
791 comm = vectorSub(comm, oNodes);
792 R = vectorUnion(comm, R);
793 }
794 order = bottom_up;
795 R = vectorConj(predSet(oNodes), set);
796 } else {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000797 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000798 DEBUG_PRINT(std::cerr << "in bottom up round\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000799 while (!R.empty()) {
800 int maxDepth = -1;
801 NodeVec::iterator chosenI;
802 for (NodeVec::iterator I = R.begin(); I != R.end(); I++) {
803 int temp = (*I)->depth;
804 if ((temp > maxDepth)
805 || (temp == maxDepth && (*I)->mov < (*chosenI)->mov)) {
806 maxDepth = temp;
807 chosenI = I;
808 }
809 }
810 ModuloSchedGraphNode *mu = *chosenI;
811 oNodes.push_back(mu);
812 R.erase(chosenI);
813 std::vector<ModuloSchedGraphNode*> pred_mu =
814 predSet(mu, backEdgeSrc, backEdgeSink);
815 std::vector<ModuloSchedGraphNode*> comm =
816 vectorConj(pred_mu, set);
817 comm = vectorSub(comm, oNodes);
818 R = vectorUnion(comm, R);
819 }
820 order = top_down;
821 R = vectorConj(succSet(oNodes), set);
Guochun Shif1c154f2003-03-27 17:57:44 +0000822 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000823 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000824 if (ModuloScheduling::printScheduleProcess()) {
Guochun Shi33280522003-06-08 20:40:47 +0000825 DEBUG_PRINT(std::cerr << "order finished\n");
826 DEBUG_PRINT(std::cerr << "dumping the ordered nodes:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000827 dumpSet(oNodes);
828 dumpCircuits();
829 }
830 //create a new set
831 //FIXME: the nodes between onodes and this circuit should also be include in
832 //this set
Misha Brukman2c821cc2003-04-10 19:19:23 +0000833 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000834 DEBUG_PRINT(std::cerr << "building the next set\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000835 set.clear();
836 int k = -1;
837 setSeq++;
838 while (circuits[setSeq][++k] != 0)
839 set.push_back(getNode(circuits[setSeq][k]));
840 if (circuits[setSeq][0] != 0) {
841 backEdgeSrc = circuits[setSeq][k - 1];
842 backEdgeSink = circuits[setSeq][0];
843 }
844 if (set.empty()) {
845 //no circuits any more
846 //collect all other nodes
Misha Brukman2c821cc2003-04-10 19:19:23 +0000847 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000848 DEBUG_PRINT(std::cerr << "no circuits any more, collect the rest nodes\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000849 for (unsigned i = 2; i < numNodes + 2; i++) {
850 bool inset = false;
851 for (unsigned j = 0; j < oNodes.size(); j++)
852 if (oNodes[j]->getNodeId() == i) {
853 inset = true;
854 break;
855 }
856 if (!inset)
857 set.push_back(getNode(i));
Guochun Shif1c154f2003-03-27 17:57:44 +0000858 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000859 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000860 if (ModuloScheduling::printScheduleProcess()) {
Guochun Shi33280522003-06-08 20:40:47 +0000861 DEBUG_PRINT(std::cerr << "next set is:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000862 dumpSet(set);
863 }
864 } //while(!set.empty())
865
Guochun Shif1c154f2003-03-27 17:57:44 +0000866}
867
868
869
Misha Brukman8baa01c2003-04-09 21:51:34 +0000870void ModuloSchedGraph::buildGraph(const TargetMachine & target)
Guochun Shif1c154f2003-03-27 17:57:44 +0000871{
Guochun Shif1c154f2003-03-27 17:57:44 +0000872
Guochun Shi099b0642003-06-02 17:48:56 +0000873 assert(this->bb && "The basicBlock is NULL?");
Guochun Shif1c154f2003-03-27 17:57:44 +0000874
875 // Use this data structure to note all machine operands that compute
876 // ordinary LLVM values. These must be computed defs (i.e., instructions).
877 // Note that there may be multiple machine instructions that define
878 // each Value.
879 ValueToDefVecMap valueToDefVecMap;
880
881 // Use this data structure to note all memory instructions.
882 // We use this to add memory dependence edges without a second full walk.
883 //
884 // vector<const Instruction*> memVec;
Misha Brukman2c821cc2003-04-10 19:19:23 +0000885 std::vector<ModuloSchedGraphNode*> memNodeVec;
Guochun Shif1c154f2003-03-27 17:57:44 +0000886
Misha Brukman8baa01c2003-04-09 21:51:34 +0000887 // Use this data structure to note any uses or definitions of
Guochun Shif1c154f2003-03-27 17:57:44 +0000888 // machine registers so we can add edges for those later without
889 // extra passes over the nodes.
890 // The vector holds an ordered list of references to the machine reg,
891 // ordered according to control-flow order. This only works for a
892 // single basic block, hence the assertion. Each reference is identified
893 // by the pair: <node, operand-number>.
894 //
895 RegToRefVecMap regToRefVecMap;
Guochun Shif1c154f2003-03-27 17:57:44 +0000896
Misha Brukman8baa01c2003-04-09 21:51:34 +0000897 // Make a dummy root node. We'll add edges to the real roots later.
898 graphRoot = new ModuloSchedGraphNode(0, NULL, NULL, -1, target);
899 graphLeaf = new ModuloSchedGraphNode(1, NULL, NULL, -1, target);
900
901 //----------------------------------------------------------------
902 // First add nodes for all the LLVM instructions in the basic block because
903 // this greatly simplifies identifying which edges to add. Do this one VM
904 // instruction at a time since the ModuloSchedGraphNode needs that.
Guochun Shif1c154f2003-03-27 17:57:44 +0000905 // Also, remember the load/store instructions to add memory deps later.
906 //----------------------------------------------------------------
907
908 //FIXME:if there is call instruction, then we shall quit somewhere
909 // currently we leave call instruction and continue construct graph
910
911 //dump only the blocks which are from loops
912
913
Misha Brukman2c821cc2003-04-10 19:19:23 +0000914 if (ModuloScheduling::printScheduleProcess())
Guochun Shif1c154f2003-03-27 17:57:44 +0000915 this->dump(bb);
916
Misha Brukman8baa01c2003-04-09 21:51:34 +0000917 if (!isLoop(bb)) {
Guochun Shi33280522003-06-08 20:40:47 +0000918 DEBUG_PRINT(std::cerr << " dumping non-loop BB:\n");
Guochun Shif1c154f2003-03-27 17:57:44 +0000919 dump(bb);
920 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000921 if (isLoop(bb)) {
922 buildNodesforBB(target, bb, memNodeVec, regToRefVecMap,
923 valueToDefVecMap);
924
925 this->addDefUseEdges(bb);
926 this->addCDEdges(bb);
927 this->addMemEdges(bb);
928
929 //this->dump();
930
931 int ResII = this->computeResII(bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000932 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000933 DEBUG_PRINT(std::cerr << "ResII is " << ResII << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000934 int RecII = this->computeRecII(bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000935 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000936 DEBUG_PRINT(std::cerr << "RecII is " << RecII << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000937
938 this->MII = std::max(ResII, RecII);
939
940 this->computeNodeProperty(bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000941 if (ModuloScheduling::printScheduleProcess())
Misha Brukman8baa01c2003-04-09 21:51:34 +0000942 this->dumpNodeProperty();
943
944 this->orderNodes();
945
Misha Brukman2c821cc2003-04-10 19:19:23 +0000946 if (ModuloScheduling::printScheduleProcess())
Misha Brukman8baa01c2003-04-09 21:51:34 +0000947 this->dump();
948 //this->instrScheduling();
949
950 //this->dumpScheduling();
951 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000952}
953
Misha Brukman8baa01c2003-04-09 21:51:34 +0000954ModuloSchedGraphNode *ModuloSchedGraph::getNode(const unsigned nodeId) const
Guochun Shif1c154f2003-03-27 17:57:44 +0000955{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000956 for (const_iterator I = begin(), E = end(); I != E; I++)
957 if ((*I).second->getNodeId() == nodeId)
958 return (ModuloSchedGraphNode *) (*I).second;
Guochun Shif1c154f2003-03-27 17:57:44 +0000959 return NULL;
960}
961
Misha Brukman8baa01c2003-04-09 21:51:34 +0000962int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
Guochun Shif1c154f2003-03-27 17:57:44 +0000963{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000964 int RecII = 0;
Guochun Shif1c154f2003-03-27 17:57:44 +0000965
966 //os<<"begining computerRecII()"<<"\n";
967
Misha Brukman8baa01c2003-04-09 21:51:34 +0000968 //FIXME: only deal with circuits starting at the first node: the phi node
969 //nodeId=2;
Guochun Shif1c154f2003-03-27 17:57:44 +0000970
971 //search all elementary circuits in the dependance graph
972 //assume maximum number of nodes is MAXNODE
Misha Brukman8baa01c2003-04-09 21:51:34 +0000973
Guochun Shif1c154f2003-03-27 17:57:44 +0000974 unsigned path[MAXNODE];
975 unsigned stack[MAXNODE][MAXNODE];
976
Misha Brukman8baa01c2003-04-09 21:51:34 +0000977 for (int j = 0; j < MAXNODE; j++) {
978 path[j] = 0;
979 for (int k = 0; k < MAXNODE; k++)
980 stack[j][k] = 0;
981 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000982 //in our graph, the node number starts at 2
983
984 //number of nodes, because each instruction will result in one node
Misha Brukman8baa01c2003-04-09 21:51:34 +0000985 const unsigned numNodes = bb->size();
Guochun Shif1c154f2003-03-27 17:57:44 +0000986
Misha Brukman8baa01c2003-04-09 21:51:34 +0000987 int i = 0;
988 path[i] = 2;
Guochun Shif1c154f2003-03-27 17:57:44 +0000989
Misha Brukman8baa01c2003-04-09 21:51:34 +0000990 ModuloSchedGraphNode *initNode = getNode(path[0]);
991 unsigned initNodeId = initNode->getNodeId();
992 ModuloSchedGraphNode *currentNode = initNode;
Guochun Shif1c154f2003-03-27 17:57:44 +0000993
Misha Brukman8baa01c2003-04-09 21:51:34 +0000994 while (currentNode != NULL) {
995 unsigned currentNodeId = currentNode->getNodeId();
Guochun Shi33280522003-06-08 20:40:47 +0000996 // DEBUG_PRINT(std::cerr<<"current node is "<<currentNodeId<<"\n");
Guochun Shif1c154f2003-03-27 17:57:44 +0000997
Misha Brukman8baa01c2003-04-09 21:51:34 +0000998 ModuloSchedGraphNode *nextNode = NULL;
999 for (ModuloSchedGraphNode::const_iterator I =
1000 currentNode->beginOutEdges(), E = currentNode->endOutEdges();
1001 I != E; I++) {
Guochun Shi33280522003-06-08 20:40:47 +00001002 //DEBUG_PRINT(std::cerr <<" searching in outgoint edges of node
Misha Brukman8baa01c2003-04-09 21:51:34 +00001003 //"<<currentNodeId<<"\n";
1004 unsigned nodeId = ((SchedGraphEdge *) * I)->getSink()->getNodeId();
1005 bool inpath = false, instack = false;
1006 int k;
Guochun Shif1c154f2003-03-27 17:57:44 +00001007
Guochun Shi33280522003-06-08 20:40:47 +00001008 //DEBUG_PRINT(std::cerr<<"nodeId is "<<nodeId<<"\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001009
Misha Brukman8baa01c2003-04-09 21:51:34 +00001010 k = -1;
1011 while (path[++k] != 0)
1012 if (nodeId == path[k]) {
1013 inpath = true;
1014 break;
1015 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001016
Misha Brukman8baa01c2003-04-09 21:51:34 +00001017 k = -1;
1018 while (stack[i][++k] != 0)
1019 if (nodeId == stack[i][k]) {
1020 instack = true;
1021 break;
1022 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001023
Misha Brukman8baa01c2003-04-09 21:51:34 +00001024 if (nodeId > currentNodeId && !inpath && !instack) {
1025 nextNode =
1026 (ModuloSchedGraphNode *) ((SchedGraphEdge *) * I)->getSink();
1027 break;
1028 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001029 }
Misha Brukman8baa01c2003-04-09 21:51:34 +00001030
1031 if (nextNode != NULL) {
Guochun Shi33280522003-06-08 20:40:47 +00001032 //DEBUG_PRINT(std::cerr<<"find the next Node "<<nextNode->getNodeId()<<"\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001033
1034 int j = 0;
1035 while (stack[i][j] != 0)
1036 j++;
1037 stack[i][j] = nextNode->getNodeId();
1038
1039 i++;
1040 path[i] = nextNode->getNodeId();
1041 currentNode = nextNode;
1042 } else {
Guochun Shi33280522003-06-08 20:40:47 +00001043 //DEBUG_PRINT(std::cerr<<"no expansion any more"<<"\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001044 //confirmCircuit();
1045 for (ModuloSchedGraphNode::const_iterator I =
1046 currentNode->beginOutEdges(), E = currentNode->endOutEdges();
1047 I != E; I++) {
1048 unsigned nodeId = ((SchedGraphEdge *) * I)->getSink()->getNodeId();
1049 if (nodeId == initNodeId) {
1050
1051 int j = -1;
1052 while (circuits[++j][0] != 0);
1053 for (int k = 0; k < MAXNODE; k++)
1054 circuits[j][k] = path[k];
1055
1056 }
1057 }
1058 //remove this node in the path and clear the corresponding entries in the
1059 //stack
1060 path[i] = 0;
1061 int j = 0;
1062 for (j = 0; j < MAXNODE; j++)
1063 stack[i][j] = 0;
1064 i--;
1065 currentNode = getNode(path[i]);
1066 }
1067 if (i == 0) {
1068
Misha Brukman2c821cc2003-04-10 19:19:23 +00001069 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001070 DEBUG_PRINT(std::cerr << "circuits found are:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001071 int j = -1;
1072 while (circuits[++j][0] != 0) {
1073 int k = -1;
1074 while (circuits[j][++k] != 0)
Misha Brukman2c821cc2003-04-10 19:19:23 +00001075 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001076 DEBUG_PRINT(std::cerr << circuits[j][k] << "\t");
Misha Brukman2c821cc2003-04-10 19:19:23 +00001077 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001078 DEBUG_PRINT(std::cerr << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001079
1080 //for this circuit, compute the sum of all edge delay
1081 int sumDelay = 0;
1082 k = -1;
1083 while (circuits[j][++k] != 0) {
1084 //ModuloSchedGraphNode* node =getNode(circuits[j][k]);
1085 unsigned nextNodeId;
1086 nextNodeId =
1087 circuits[j][k + 1] !=
1088 0 ? circuits[j][k + 1] : circuits[j][0];
1089
1090 /*
1091 for(ModuloSchedGraphNode::const_iterator I=node->beginOutEdges(),
1092 E=node->endOutEdges();I !=E; I++)
1093 {
1094 SchedGraphEdge* edge= *I;
1095 if(edge->getSink()->getNodeId() == nextNodeId)
1096 {sumDelay += edge->getMinDelay();break;}
1097 }
1098 */
1099
1100 sumDelay +=
1101 getMaxDelayEdge(circuits[j][k], nextNodeId)->getMinDelay();
1102
1103 }
1104 // assume we have distance 1, in this case the sumDelay is RecII
1105 // this is correct for SSA form only
1106 //
Misha Brukman2c821cc2003-04-10 19:19:23 +00001107 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001108 DEBUG_PRINT(std::cerr << "The total Delay in the circuit is " << sumDelay
Misha Brukman2c821cc2003-04-10 19:19:23 +00001109 << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001110
1111 RecII = RecII > sumDelay ? RecII : sumDelay;
1112
1113 }
1114 return RecII;
1115 }
1116
1117 }
1118
Guochun Shif1c154f2003-03-27 17:57:44 +00001119 return -1;
1120}
1121
Misha Brukman8baa01c2003-04-09 21:51:34 +00001122void ModuloSchedGraph::addResourceUsage(std::vector<std::pair<int,int> > &ruVec,
1123 int rid)
1124{
Guochun Shi33280522003-06-08 20:40:47 +00001125 //DEBUG_PRINT(std::cerr<<"\nadding a resouce , current resouceUsage vector size is
Misha Brukman8baa01c2003-04-09 21:51:34 +00001126 //"<<ruVec.size()<<"\n";
1127 bool alreadyExists = false;
1128 for (unsigned i = 0; i < ruVec.size(); i++) {
1129 if (rid == ruVec[i].first) {
Guochun Shif1c154f2003-03-27 17:57:44 +00001130 ruVec[i].second++;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001131 alreadyExists = true;
Guochun Shif1c154f2003-03-27 17:57:44 +00001132 break;
1133 }
1134 }
Misha Brukman8baa01c2003-04-09 21:51:34 +00001135 if (!alreadyExists)
1136 ruVec.push_back(std::make_pair(rid, 1));
Guochun Shi33280522003-06-08 20:40:47 +00001137 //DEBUG_PRINT(std::cerr<<"current resouceUsage vector size is "<<ruVec.size()<<"\n";
Guochun Shif1c154f2003-03-27 17:57:44 +00001138
1139}
Misha Brukman8baa01c2003-04-09 21:51:34 +00001140void ModuloSchedGraph::dumpResourceUsage(std::vector<std::pair<int,int> > &ru)
Guochun Shif1c154f2003-03-27 17:57:44 +00001141{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001142 TargetSchedInfo & msi = (TargetSchedInfo &) target.getSchedInfo();
1143
Misha Brukman2c821cc2003-04-10 19:19:23 +00001144 std::vector<std::pair<int,int> > resourceNumVector = msi.resourceNumVector;
Guochun Shi33280522003-06-08 20:40:47 +00001145 DEBUG_PRINT(std::cerr << "resourceID\t" << "resourceNum\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001146 for (unsigned i = 0; i < resourceNumVector.size(); i++)
Guochun Shi33280522003-06-08 20:40:47 +00001147 DEBUG_PRINT(std::cerr << resourceNumVector[i].
Misha Brukman2c821cc2003-04-10 19:19:23 +00001148 first << "\t" << resourceNumVector[i].second << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001149
Guochun Shi33280522003-06-08 20:40:47 +00001150 DEBUG_PRINT(std::cerr << " maxNumIssueTotal(issue slot in one cycle) = " << msi.
Misha Brukman2c821cc2003-04-10 19:19:23 +00001151 maxNumIssueTotal << "\n");
Guochun Shi33280522003-06-08 20:40:47 +00001152 DEBUG_PRINT(std::cerr << "resourceID\t resourceUsage\t ResourceNum\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001153 for (unsigned i = 0; i < ru.size(); i++) {
Guochun Shi33280522003-06-08 20:40:47 +00001154 DEBUG_PRINT(std::cerr << ru[i].first << "\t" << ru[i].second);
Misha Brukman8baa01c2003-04-09 21:51:34 +00001155 const unsigned resNum = msi.getCPUResourceNum(ru[i].first);
Guochun Shi33280522003-06-08 20:40:47 +00001156 DEBUG_PRINT(std::cerr << "\t" << resNum << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001157 }
1158}
1159
Misha Brukman8baa01c2003-04-09 21:51:34 +00001160int ModuloSchedGraph::computeResII(const BasicBlock * bb)
Guochun Shif1c154f2003-03-27 17:57:44 +00001161{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001162
1163 const TargetInstrInfo & mii = target.getInstrInfo();
1164 const TargetSchedInfo & msi = target.getSchedInfo();
1165
Guochun Shif1c154f2003-03-27 17:57:44 +00001166 int ResII;
Misha Brukman2c821cc2003-04-10 19:19:23 +00001167 std::vector<std::pair<int,int> > resourceUsage;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001168 //pair<int resourceid, int resourceUsageTimes_in_the_whole_block>
1169
1170 //FIXME: number of functional units the target machine can provide should be
1171 //get from Target here I temporary hardcode it
1172
1173 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E;
1174 I++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001175 if (ModuloScheduling::printScheduleProcess()) {
Guochun Shi33280522003-06-08 20:40:47 +00001176 DEBUG_PRINT(std::cerr << "machine instruction for llvm instruction( node " <<
Misha Brukman2c821cc2003-04-10 19:19:23 +00001177 getGraphNodeForInst(I)->getNodeId() << ")\n");
Guochun Shi33280522003-06-08 20:40:47 +00001178 DEBUG_PRINT(std::cerr << "\t" << *I);
Guochun Shif1c154f2003-03-27 17:57:44 +00001179 }
Misha Brukman8baa01c2003-04-09 21:51:34 +00001180 MachineCodeForInstruction & tempMvec =
1181 MachineCodeForInstruction::get(I);
Misha Brukman2c821cc2003-04-10 19:19:23 +00001182 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001183 DEBUG_PRINT(std::cerr << "size =" << tempMvec.size() << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001184 for (unsigned i = 0; i < tempMvec.size(); i++) {
1185 MachineInstr *minstr = tempMvec[i];
1186
1187 unsigned minDelay = mii.minLatency(minstr->getOpCode());
1188 InstrRUsage rUsage = msi.getInstrRUsage(minstr->getOpCode());
1189 InstrClassRUsage classRUsage =
1190 msi.getClassRUsage(mii.getSchedClass(minstr->getOpCode()));
1191 unsigned totCycles = classRUsage.totCycles;
1192
Misha Brukman2c821cc2003-04-10 19:19:23 +00001193 std::vector<std::vector<resourceId_t> > resources=rUsage.resourcesByCycle;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001194 assert(totCycles == resources.size());
Misha Brukman2c821cc2003-04-10 19:19:23 +00001195 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001196 DEBUG_PRINT(std::cerr << "resources Usage for this Instr(totCycles="
Misha Brukman2c821cc2003-04-10 19:19:23 +00001197 << totCycles << ",mindLatency="
1198 << mii.minLatency(minstr->getOpCode()) << "): " << *minstr
1199 << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001200 for (unsigned j = 0; j < resources.size(); j++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001201 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001202 DEBUG_PRINT(std::cerr << "cycle " << j << ": ");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001203 for (unsigned k = 0; k < resources[j].size(); k++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001204 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001205 DEBUG_PRINT(std::cerr << "\t" << resources[j][k]);
Misha Brukman8baa01c2003-04-09 21:51:34 +00001206 addResourceUsage(resourceUsage, resources[j][k]);
1207 }
Misha Brukman2c821cc2003-04-10 19:19:23 +00001208 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001209 DEBUG_PRINT(std::cerr << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001210 }
1211 }
1212 }
Misha Brukman2c821cc2003-04-10 19:19:23 +00001213 if (ModuloScheduling::printScheduleProcess())
Guochun Shif1c154f2003-03-27 17:57:44 +00001214 this->dumpResourceUsage(resourceUsage);
1215
1216 //compute ResII
Misha Brukman8baa01c2003-04-09 21:51:34 +00001217 ResII = 0;
1218 int issueSlots = msi.maxNumIssueTotal;
1219 for (unsigned i = 0; i < resourceUsage.size(); i++) {
1220 int resourceNum = msi.getCPUResourceNum(resourceUsage[i].first);
1221 int useNum = resourceUsage[i].second;
Guochun Shif1c154f2003-03-27 17:57:44 +00001222 double tempII;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001223 if (resourceNum <= issueSlots)
1224 tempII = ceil(1.0 * useNum / resourceNum);
Guochun Shif1c154f2003-03-27 17:57:44 +00001225 else
Misha Brukman8baa01c2003-04-09 21:51:34 +00001226 tempII = ceil(1.0 * useNum / issueSlots);
1227 ResII = std::max((int) tempII, ResII);
Guochun Shif1c154f2003-03-27 17:57:44 +00001228 }
1229 return ResII;
1230}
1231
Misha Brukman2c821cc2003-04-10 19:19:23 +00001232ModuloSchedGraphSet::ModuloSchedGraphSet(const Function *function,
1233 const TargetMachine &target)
Misha Brukman8baa01c2003-04-09 21:51:34 +00001234: method(function)
Guochun Shif1c154f2003-03-27 17:57:44 +00001235{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001236 buildGraphsForMethod(method, target);
Guochun Shif1c154f2003-03-27 17:57:44 +00001237}
1238
1239
1240ModuloSchedGraphSet::~ModuloSchedGraphSet()
1241{
1242 //delete all the graphs
Misha Brukman8baa01c2003-04-09 21:51:34 +00001243 for (iterator I = begin(), E = end(); I != E; ++I)
Guochun Shif1c154f2003-03-27 17:57:44 +00001244 delete *I;
1245}
1246
Misha Brukman8baa01c2003-04-09 21:51:34 +00001247void ModuloSchedGraphSet::dump() const
Guochun Shif1c154f2003-03-27 17:57:44 +00001248{
Guochun Shi33280522003-06-08 20:40:47 +00001249 DEBUG_PRINT(std::cerr << " ====== ModuloSched graphs for function `" <<
Misha Brukman2c821cc2003-04-10 19:19:23 +00001250 method->getName() << "' =========\n\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001251 for (const_iterator I = begin(); I != end(); ++I)
Guochun Shif1c154f2003-03-27 17:57:44 +00001252 (*I)->dump();
Misha Brukman8baa01c2003-04-09 21:51:34 +00001253
Guochun Shi33280522003-06-08 20:40:47 +00001254 DEBUG_PRINT(std::cerr << "\n=========End graphs for function `" << method->getName()
Misha Brukman2c821cc2003-04-10 19:19:23 +00001255 << "' ==========\n\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001256}
1257
Misha Brukman8baa01c2003-04-09 21:51:34 +00001258void ModuloSchedGraph::dump(const BasicBlock * bb)
Guochun Shif1c154f2003-03-27 17:57:44 +00001259{
Guochun Shi33280522003-06-08 20:40:47 +00001260 DEBUG_PRINT(std::cerr << "dumping basic block:");
1261 DEBUG_PRINT(std::cerr << (bb->hasName()? bb->getName() : "block")
Misha Brukman2c821cc2003-04-10 19:19:23 +00001262 << " (" << bb << ")" << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001263}
1264
Misha Brukman8baa01c2003-04-09 21:51:34 +00001265void ModuloSchedGraph::dump(const BasicBlock * bb, std::ostream & os)
Guochun Shif1c154f2003-03-27 17:57:44 +00001266{
Misha Brukman8baa01c2003-04-09 21:51:34 +00001267 os << "dumping basic block:";
1268 os << (bb->hasName()? bb->getName() : "block")
1269 << " (" << bb << ")" << "\n";
Guochun Shif1c154f2003-03-27 17:57:44 +00001270}
1271
Misha Brukman8baa01c2003-04-09 21:51:34 +00001272void ModuloSchedGraph::dump() const
Guochun Shif1c154f2003-03-27 17:57:44 +00001273{
Guochun Shi33280522003-06-08 20:40:47 +00001274 DEBUG_PRINT(std::cerr << " ModuloSchedGraph for basic Blocks:");
Guochun Shi099b0642003-06-02 17:48:56 +00001275
Guochun Shi33280522003-06-08 20:40:47 +00001276 DEBUG_PRINT(std::cerr << (bb->hasName()? bb->getName() : "block")
Guochun Shi099b0642003-06-02 17:48:56 +00001277 << " (" << bb << ")" << "");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001278
Guochun Shi33280522003-06-08 20:40:47 +00001279 DEBUG_PRINT(std::cerr << "\n\n Actual Root nodes : ");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001280 for (unsigned i = 0, N = graphRoot->outEdges.size(); i < N; i++)
Guochun Shi33280522003-06-08 20:40:47 +00001281 DEBUG_PRINT(std::cerr << graphRoot->outEdges[i]->getSink()->getNodeId()
Misha Brukman2c821cc2003-04-10 19:19:23 +00001282 << ((i == N - 1) ? "" : ", "));
Guochun Shif1c154f2003-03-27 17:57:44 +00001283
Guochun Shi33280522003-06-08 20:40:47 +00001284 DEBUG_PRINT(std::cerr << "\n Graph Nodes:\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001285 //for (const_iterator I=begin(); I != end(); ++I)
Guochun Shi33280522003-06-08 20:40:47 +00001286 //DEBUG_PRINT(std::cerr << "\n" << *I->second;
Guochun Shi099b0642003-06-02 17:48:56 +00001287 unsigned numNodes = bb->size();
Misha Brukman8baa01c2003-04-09 21:51:34 +00001288 for (unsigned i = 2; i < numNodes + 2; i++) {
1289 ModuloSchedGraphNode *node = getNode(i);
Guochun Shi33280522003-06-08 20:40:47 +00001290 DEBUG_PRINT(std::cerr << "\n" << *node);
Misha Brukman8baa01c2003-04-09 21:51:34 +00001291 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001292
Guochun Shi33280522003-06-08 20:40:47 +00001293 DEBUG_PRINT(std::cerr << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001294}
Misha Brukman8baa01c2003-04-09 21:51:34 +00001295
1296void ModuloSchedGraph::dumpNodeProperty() const
Guochun Shif1c154f2003-03-27 17:57:44 +00001297{
Guochun Shi099b0642003-06-02 17:48:56 +00001298
Misha Brukman8baa01c2003-04-09 21:51:34 +00001299 unsigned numNodes = bb->size();
1300 for (unsigned i = 2; i < numNodes + 2; i++) {
1301 ModuloSchedGraphNode *node = getNode(i);
Guochun Shi33280522003-06-08 20:40:47 +00001302 DEBUG_PRINT(std::cerr << "NodeId " << node->getNodeId() << "\t");
1303 DEBUG_PRINT(std::cerr << "ASAP " << node->getASAP() << "\t");
1304 DEBUG_PRINT(std::cerr << "ALAP " << node->getALAP() << "\t");
1305 DEBUG_PRINT(std::cerr << "mov " << node->getMov() << "\t");
1306 DEBUG_PRINT(std::cerr << "depth " << node->getDepth() << "\t");
1307 DEBUG_PRINT(std::cerr << "height " << node->getHeight() << "\t\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001308 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001309}
1310
Misha Brukman63e04f32003-04-22 23:00:08 +00001311void ModuloSchedGraphSet::buildGraphsForMethod(const Function *F,
1312 const TargetMachine &target)
Guochun Shif1c154f2003-03-27 17:57:44 +00001313{
Guochun Shi099b0642003-06-02 17:48:56 +00001314 for (Function::const_iterator BI = F->begin(); BI != F->end(); ++BI){
1315 const BasicBlock* local_bb;
1316 local_bb=BI;
1317 addGraph(new ModuloSchedGraph((BasicBlock*)local_bb, target));
1318 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001319}
1320
Misha Brukman63e04f32003-04-22 23:00:08 +00001321std::ostream& operator<<(std::ostream &os,
1322 const ModuloSchedGraphNode &node)
Guochun Shif1c154f2003-03-27 17:57:44 +00001323{
1324 os << std::string(8, ' ')
Misha Brukman8baa01c2003-04-09 21:51:34 +00001325 << "Node " << node.nodeId << " : "
1326 << "latency = " << node.latency << "\n" << std::string(12, ' ');
Guochun Shif1c154f2003-03-27 17:57:44 +00001327
1328 if (node.getInst() == NULL)
1329 os << "(Dummy node)\n";
Misha Brukman8baa01c2003-04-09 21:51:34 +00001330 else {
1331 os << *node.getInst() << "\n" << std::string(12, ' ');
1332 os << node.inEdges.size() << " Incoming Edges:\n";
1333 for (unsigned i = 0, N = node.inEdges.size(); i < N; i++)
1334 os << std::string(16, ' ') << *node.inEdges[i];
1335
1336 os << std::string(12, ' ') << node.outEdges.size()
1337 << " Outgoing Edges:\n";
1338 for (unsigned i = 0, N = node.outEdges.size(); i < N; i++)
1339 os << std::string(16, ' ') << *node.outEdges[i];
1340 }
1341
Guochun Shif1c154f2003-03-27 17:57:44 +00001342 return os;
1343}