blob: b135ff2ddf5565c6d78b365688ca65872ec04aeb [file] [log] [blame]
Misha Brukman8baa01c2003-04-09 21:51:34 +00001//===- ModuloSchedGraph.cpp - Graph datastructure for Modulo Scheduling ---===//
2//
3//
4//===----------------------------------------------------------------------===//
5
Guochun Shif1c154f2003-03-27 17:57:44 +00006#include "llvm/CodeGen/InstrSelection.h"
Guochun Shif1c154f2003-03-27 17:57:44 +00007#include "llvm/Function.h"
Misha Brukman8baa01c2003-04-09 21:51:34 +00008#include "llvm/Instructions.h"
Guochun Shif1c154f2003-03-27 17:57:44 +00009#include "llvm/Type.h"
10#include "llvm/CodeGen/MachineCodeForInstruction.h"
11#include "llvm/CodeGen/MachineInstr.h"
Guochun Shi6fbe5fb2003-04-06 23:56:19 +000012#include "llvm/Target/TargetSchedInfo.h"
Misha Brukman8baa01c2003-04-09 21:51:34 +000013#include "Support/StringExtras.h"
14#include "Support/STLExtras.h"
Misha Brukman2c821cc2003-04-10 19:19:23 +000015#include "Support/hash_map"
16#include "Support/Statistic.h"
17#include "ModuloScheduling.h"
Misha Brukman8baa01c2003-04-09 21:51:34 +000018#include "ModuloSchedGraph.h"
19#include <algorithm>
Misha Brukman2c821cc2003-04-10 19:19:23 +000020#include <ostream>
21#include <vector>
Misha Brukman8baa01c2003-04-09 21:51:34 +000022#include <math.h>
Guochun Shif1c154f2003-03-27 17:57:44 +000023
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000024
Guochun Shif1c154f2003-03-27 17:57:44 +000025#define UNIDELAY 1
Guochun Shif1c154f2003-03-27 17:57:44 +000026
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000027using std::cerr;
28using std::endl;
29using std::vector;
Guochun Shif1c154f2003-03-27 17:57:44 +000030
Guochun Shif1c154f2003-03-27 17:57:44 +000031
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000032/***********member functions for ModuloSchedGraphNode*********/
Guochun Shif1c154f2003-03-27 17:57:44 +000033
Guochun Shif1c154f2003-03-27 17:57:44 +000034
Guochun Shi099b0642003-06-02 17:48:56 +000035ModuloSchedGraphNode::ModuloSchedGraphNode(unsigned int in_nodeId,
36 const BasicBlock * in_bb,
37 const Instruction * in_inst,
Misha Brukman8baa01c2003-04-09 21:51:34 +000038 int indexInBB,
39 const TargetMachine & target)
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000040 :SchedGraphNodeCommon(in_nodeId, indexInBB), inst(in_inst){
41
Misha Brukman8baa01c2003-04-09 21:51:34 +000042 if (inst) {
43 //FIXME: find the latency
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000044 //currently set the latency to zero
Misha Brukman8baa01c2003-04-09 21:51:34 +000045 latency = 0;
46 }
Guochun Shif1c154f2003-03-27 17:57:44 +000047}
Misha Brukman8baa01c2003-04-09 21:51:34 +000048
Guochun Shif1c154f2003-03-27 17:57:44 +000049
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000050/***********member functions for ModuloSchedGraph*********/
Misha Brukman8baa01c2003-04-09 21:51:34 +000051
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000052void
53ModuloSchedGraph::addDefUseEdges(const BasicBlock *bb){
54
Guochun Shif1c154f2003-03-27 17:57:44 +000055 //collect def instructions, store them in vector
Misha Brukman8baa01c2003-04-09 21:51:34 +000056 const TargetInstrInfo & mii = target.getInstrInfo();
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000057 vector < ModuloSchedGraphNode * > defVec;
58
59
Guochun Shif1c154f2003-03-27 17:57:44 +000060 //find those def instructions
Misha Brukman8baa01c2003-04-09 21:51:34 +000061 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E; ++I) {
62 if (I->getType() != Type::VoidTy) {
63 defVec.push_back(this->getGraphNodeForInst(I));
64 }
65 }
66
67 for (unsigned int i = 0; i < defVec.size(); i++) {
68 for (Value::use_const_iterator I = defVec[i]->getInst()->use_begin();
69 I != defVec[i]->getInst()->use_end(); I++) {
Misha Brukman63e04f32003-04-22 23:00:08 +000070 //for each use of a def, add a flow edge from the def instruction to the
71 //ref instruction
Misha Brukman8baa01c2003-04-09 21:51:34 +000072
73 const Instruction *value = defVec[i]->getInst();
74 Instruction *inst = (Instruction *) (*I);
75 ModuloSchedGraphNode *node = NULL;
76
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000077 for (BasicBlock::const_iterator ins = bb->begin(), E = bb->end();
78 ins != E; ++ins)
79 if ((const Instruction *) ins == inst) {
Misha Brukman8baa01c2003-04-09 21:51:34 +000080 node = (*this)[inst];
81 break;
82 }
83
Misha Brukman8baa01c2003-04-09 21:51:34 +000084
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000085 if (node == NULL){
86
87 //inst is not an instruction in this block
88 //do nothing
89
Misha Brukman8baa01c2003-04-09 21:51:34 +000090 } else {
91 // Add a flow edge from the def instruction to the ref instruction
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000092 // This is a true dependence, so the delay is equal to the
93 //delay of the preceding node.
94
95 int delay = 0;
96
Misha Brukman8baa01c2003-04-09 21:51:34 +000097 // self loop will not happen in SSA form
98 assert(defVec[i] != node && "same node?");
99
Misha Brukman8baa01c2003-04-09 21:51:34 +0000100 MachineCodeForInstruction & tempMvec =
101 MachineCodeForInstruction::get(value);
102 for (unsigned j = 0; j < tempMvec.size(); j++) {
103 MachineInstr *temp = tempMvec[j];
Misha Brukman8baa01c2003-04-09 21:51:34 +0000104 delay = std::max(delay, mii.minLatency(temp->getOpCode()));
105 }
106
107 SchedGraphEdge *trueEdge =
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000108 new SchedGraphEdge(defVec[i], node, value,
Misha Brukman8baa01c2003-04-09 21:51:34 +0000109 SchedGraphEdge::TrueDep, delay);
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000110
Misha Brukman8baa01c2003-04-09 21:51:34 +0000111 // if the ref instruction is before the def instrution
112 // then the def instruction must be a phi instruction
113 // add an anti-dependence edge to from the ref instruction to the def
114 // instruction
115 if (node->getOrigIndexInBB() < defVec[i]->getOrigIndexInBB()) {
116 assert(PHINode::classof(inst)
117 && "the ref instruction befre def is not PHINode?");
118 trueEdge->setIteDiff(1);
119 }
120
Guochun Shif1c154f2003-03-27 17:57:44 +0000121 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000122
Misha Brukman8baa01c2003-04-09 21:51:34 +0000123 }
124 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000125}
126
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000127void
128ModuloSchedGraph::addCDEdges(const BasicBlock * bb) {
129
Misha Brukman8baa01c2003-04-09 21:51:34 +0000130 // find the last instruction in the basic block
131 // see if it is an branch instruction.
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000132 // If yes, then add an edge from each node expcept the last node
Guochun Shif3252612003-06-10 19:09:00 +0000133 // to the last node
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000134
Misha Brukman8baa01c2003-04-09 21:51:34 +0000135 const Instruction *inst = &(bb->back());
136 ModuloSchedGraphNode *lastNode = (*this)[inst];
137 if (TerminatorInst::classof(inst))
138 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E;
139 I++) {
140 if (inst != I) {
141 ModuloSchedGraphNode *node = (*this)[I];
142 //use latency of 0
143 (void) new SchedGraphEdge(node, lastNode, SchedGraphEdge::CtrlDep,
144 SchedGraphEdge::NonDataDep, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000145 }
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000146
Misha Brukman8baa01c2003-04-09 21:51:34 +0000147 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000148}
149
Misha Brukman8baa01c2003-04-09 21:51:34 +0000150static const int SG_LOAD_REF = 0;
Guochun Shif1c154f2003-03-27 17:57:44 +0000151static const int SG_STORE_REF = 1;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000152static const int SG_CALL_REF = 2;
Guochun Shif1c154f2003-03-27 17:57:44 +0000153
154static const unsigned int SG_DepOrderArray[][3] = {
Misha Brukman8baa01c2003-04-09 21:51:34 +0000155 {SchedGraphEdge::NonDataDep,
156 SchedGraphEdge::AntiDep,
157 SchedGraphEdge::AntiDep},
158 {SchedGraphEdge::TrueDep,
159 SchedGraphEdge::OutputDep,
160 SchedGraphEdge::TrueDep | SchedGraphEdge::OutputDep},
161 {SchedGraphEdge::TrueDep,
162 SchedGraphEdge::AntiDep | SchedGraphEdge::OutputDep,
163 SchedGraphEdge::TrueDep | SchedGraphEdge::AntiDep
164 | SchedGraphEdge::OutputDep}
Guochun Shif1c154f2003-03-27 17:57:44 +0000165};
166
167
168// Add a dependence edge between every pair of machine load/store/call
169// instructions, where at least one is a store or a call.
170// Use latency 1 just to ensure that memory operations are ordered;
171// latency does not otherwise matter (true dependences enforce that).
172//
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000173void
174ModuloSchedGraph::addMemEdges(const BasicBlock * bb) {
Misha Brukman8baa01c2003-04-09 21:51:34 +0000175
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000176 vector<ModuloSchedGraphNode*> memNodeVec;
177
Guochun Shif1c154f2003-03-27 17:57:44 +0000178 //construct the memNodeVec
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000179 for (BasicBlock::const_iterator I = bb->begin(),
180 E = bb->end(); I != E; ++I) {
181
Misha Brukman8baa01c2003-04-09 21:51:34 +0000182 if (LoadInst::classof(I) || StoreInst::classof(I)
183 || CallInst::classof(I)) {
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000184
Misha Brukman8baa01c2003-04-09 21:51:34 +0000185 ModuloSchedGraphNode *node = (*this)[(const Instruction *) I];
186 memNodeVec.push_back(node);
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000187
Misha Brukman8baa01c2003-04-09 21:51:34 +0000188 }
189 }
190
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000191 // Instructions in memNodeVec are in execution order within the
192 // basic block, so simply look at all pairs
193 // <memNodeVec[i], memNodeVec[j: j > i]>.
194
Misha Brukman8baa01c2003-04-09 21:51:34 +0000195 for (unsigned im = 0, NM = memNodeVec.size(); im < NM; im++) {
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000196
197 const Instruction *fromInst,*toInst;
198 int toType, fromType;
199
200 //get the first mem instruction and instruction type
201 fromInst = memNodeVec[im]->getInst();
202 fromType = CallInst::classof(fromInst) ? SG_CALL_REF
203 : LoadInst::classof(fromInst) ? SG_LOAD_REF : SG_STORE_REF;
204
Misha Brukman8baa01c2003-04-09 21:51:34 +0000205 for (unsigned jm = im + 1; jm < NM; jm++) {
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000206
207 //get the second mem instruction and instruction type
208 toInst = memNodeVec[jm]->getInst();
209 toType = CallInst::classof(toInst) ? SG_CALL_REF
Misha Brukman8baa01c2003-04-09 21:51:34 +0000210 : LoadInst::classof(toInst) ? SG_LOAD_REF : SG_STORE_REF;
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000211
212 //add two edges if not both of them are LOAD instructions
Misha Brukman8baa01c2003-04-09 21:51:34 +0000213 if (fromType != SG_LOAD_REF || toType != SG_LOAD_REF) {
214 (void) new SchedGraphEdge(memNodeVec[im], memNodeVec[jm],
215 SchedGraphEdge::MemoryDep,
216 SG_DepOrderArray[fromType][toType], 1);
217
218 SchedGraphEdge *edge =
219 new SchedGraphEdge(memNodeVec[jm], memNodeVec[im],
220 SchedGraphEdge::MemoryDep,
221 SG_DepOrderArray[toType][fromType], 1);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000222
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000223 //set the iteration difference for this edge to 1.
224 edge->setIteDiff(1);
225
Misha Brukman8baa01c2003-04-09 21:51:34 +0000226 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000227 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000228 }
229}
Guochun Shif1c154f2003-03-27 17:57:44 +0000230
Guochun Shif3252612003-06-10 19:09:00 +0000231/*
232 this function build graph nodes for each instruction
233 in the basicblock
234*/
Guochun Shif1c154f2003-03-27 17:57:44 +0000235
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000236void
237ModuloSchedGraph::buildNodesforBB(const TargetMachine &target,
238 const BasicBlock *bb){
239
Misha Brukman8baa01c2003-04-09 21:51:34 +0000240 int i = 0;
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000241 ModuloSchedGraphNode *node;
242
243 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end();
244 I != E; ++I) {
245
246 node=new ModuloSchedGraphNode(getNumNodes(), bb, I, i, target);
247
Misha Brukman8baa01c2003-04-09 21:51:34 +0000248 i++;
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000249
250 this->addHash(I, node);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000251 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000252
Guochun Shif1c154f2003-03-27 17:57:44 +0000253}
254
255
Guochun Shif3252612003-06-10 19:09:00 +0000256/*
257 determine if this basicblock includes a loop or not
258*/
259
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000260bool
261ModuloSchedGraph::isLoop(const BasicBlock *bb) {
262
Guochun Shif1c154f2003-03-27 17:57:44 +0000263 //only if the last instruction in the basicblock is branch instruction and
264 //there is at least an option to branch itself
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000265
Misha Brukman8baa01c2003-04-09 21:51:34 +0000266 const Instruction *inst = &(bb->back());
Guochun Shif3252612003-06-10 19:09:00 +0000267
Misha Brukman8baa01c2003-04-09 21:51:34 +0000268 if (BranchInst::classof(inst)) {
269 for (unsigned i = 0; i < ((BranchInst *) inst)->getNumSuccessors();
270 i++) {
271 BasicBlock *sb = ((BranchInst *) inst)->getSuccessor(i);
272 if (sb == bb)
273 return true;
274 }
275 }
276
Guochun Shif1c154f2003-03-27 17:57:44 +0000277 return false;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000278
Guochun Shif1c154f2003-03-27 17:57:44 +0000279}
Misha Brukman8baa01c2003-04-09 21:51:34 +0000280
Guochun Shif3252612003-06-10 19:09:00 +0000281/*
282 compute every node's ASAP
Misha Brukman8baa01c2003-04-09 21:51:34 +0000283
Guochun Shif3252612003-06-10 19:09:00 +0000284*/
285
286//FIXME: now assume the only backward edges come from the edges from other
287//nodes to the phi Node so i will ignore all edges to the phi node; after
288//this, there shall be no recurrence.
289
290void
291ModuloSchedGraph::computeNodeASAP(const BasicBlock *bb) {
292
Misha Brukman8baa01c2003-04-09 21:51:34 +0000293
294 unsigned numNodes = bb->size();
295 for (unsigned i = 2; i < numNodes + 2; i++) {
296 ModuloSchedGraphNode *node = getNode(i);
297 node->setPropertyComputed(false);
298 }
299
300 for (unsigned i = 2; i < numNodes + 2; i++) {
301 ModuloSchedGraphNode *node = getNode(i);
302 node->ASAP = 0;
303 if (i == 2 || node->getNumInEdges() == 0) {
Guochun Shif1c154f2003-03-27 17:57:44 +0000304 node->setPropertyComputed(true);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000305 continue;
Guochun Shif1c154f2003-03-27 17:57:44 +0000306 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000307 for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E =
308 node->endInEdges(); I != E; I++) {
309 SchedGraphEdge *edge = *I;
310 ModuloSchedGraphNode *pred =
311 (ModuloSchedGraphNode *) (edge->getSrc());
312 assert(pred->getPropertyComputed()
313 && "pred node property is not computed!");
314 int temp =
315 pred->ASAP + edge->getMinDelay() -
316 edge->getIteDiff() * this->MII;
317 node->ASAP = std::max(node->ASAP, temp);
318 }
319 node->setPropertyComputed(true);
320 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000321}
322
Guochun Shif3252612003-06-10 19:09:00 +0000323
324/*
325 compute every node's ALAP in the basic block
326*/
327
328void
329ModuloSchedGraph::computeNodeALAP(const BasicBlock *bb) {
330
Misha Brukman8baa01c2003-04-09 21:51:34 +0000331 unsigned numNodes = bb->size();
332 int maxASAP = 0;
333 for (unsigned i = numNodes + 1; i >= 2; i--) {
Guochun Shif3252612003-06-10 19:09:00 +0000334
Misha Brukman8baa01c2003-04-09 21:51:34 +0000335 ModuloSchedGraphNode *node = getNode(i);
336 node->setPropertyComputed(false);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000337 maxASAP = std::max(maxASAP, node->ASAP);
Guochun Shif1c154f2003-03-27 17:57:44 +0000338
Guochun Shif3252612003-06-10 19:09:00 +0000339 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000340
341 for (unsigned i = numNodes + 1; i >= 2; i--) {
342 ModuloSchedGraphNode *node = getNode(i);
Guochun Shif3252612003-06-10 19:09:00 +0000343
Misha Brukman8baa01c2003-04-09 21:51:34 +0000344 node->ALAP = maxASAP;
Guochun Shif3252612003-06-10 19:09:00 +0000345
Misha Brukman8baa01c2003-04-09 21:51:34 +0000346 for (ModuloSchedGraphNode::const_iterator I =
347 node->beginOutEdges(), E = node->endOutEdges(); I != E; I++) {
Guochun Shif3252612003-06-10 19:09:00 +0000348
Misha Brukman8baa01c2003-04-09 21:51:34 +0000349 SchedGraphEdge *edge = *I;
350 ModuloSchedGraphNode *succ =
Guochun Shif3252612003-06-10 19:09:00 +0000351 (ModuloSchedGraphNode *) (edge->getSink());
Misha Brukman8baa01c2003-04-09 21:51:34 +0000352 if (PHINode::classof(succ->getInst()))
353 continue;
Guochun Shif3252612003-06-10 19:09:00 +0000354
Misha Brukman8baa01c2003-04-09 21:51:34 +0000355 assert(succ->getPropertyComputed()
356 && "succ node property is not computed!");
Guochun Shif3252612003-06-10 19:09:00 +0000357
Misha Brukman8baa01c2003-04-09 21:51:34 +0000358 int temp =
359 succ->ALAP - edge->getMinDelay() +
360 edge->getIteDiff() * this->MII;
Guochun Shif3252612003-06-10 19:09:00 +0000361
Misha Brukman8baa01c2003-04-09 21:51:34 +0000362 node->ALAP = std::min(node->ALAP, temp);
Guochun Shif3252612003-06-10 19:09:00 +0000363
Misha Brukman8baa01c2003-04-09 21:51:34 +0000364 }
365 node->setPropertyComputed(true);
366 }
367}
368
Guochun Shif3252612003-06-10 19:09:00 +0000369/*
370 compute every node's mov in this basicblock
371*/
372
373void
374ModuloSchedGraph::computeNodeMov(const BasicBlock *bb){
375
Misha Brukman8baa01c2003-04-09 21:51:34 +0000376 unsigned numNodes = bb->size();
377 for (unsigned i = 2; i < numNodes + 2; i++) {
Guochun Shif3252612003-06-10 19:09:00 +0000378
Misha Brukman8baa01c2003-04-09 21:51:34 +0000379 ModuloSchedGraphNode *node = getNode(i);
380 node->mov = node->ALAP - node->ASAP;
381 assert(node->mov >= 0
382 && "move freedom for this node is less than zero? ");
Guochun Shif3252612003-06-10 19:09:00 +0000383
Misha Brukman8baa01c2003-04-09 21:51:34 +0000384 }
Guochun Shif3252612003-06-10 19:09:00 +0000385
Misha Brukman8baa01c2003-04-09 21:51:34 +0000386}
387
388
Guochun Shif3252612003-06-10 19:09:00 +0000389/*
390 compute every node's depth in this basicblock
391*/
392void
393ModuloSchedGraph::computeNodeDepth(const BasicBlock * bb){
394
Misha Brukman8baa01c2003-04-09 21:51:34 +0000395 unsigned numNodes = bb->size();
Guochun Shif3252612003-06-10 19:09:00 +0000396
Misha Brukman8baa01c2003-04-09 21:51:34 +0000397 for (unsigned i = 2; i < numNodes + 2; i++) {
Guochun Shif3252612003-06-10 19:09:00 +0000398
Misha Brukman8baa01c2003-04-09 21:51:34 +0000399 ModuloSchedGraphNode *node = getNode(i);
400 node->setPropertyComputed(false);
Guochun Shif3252612003-06-10 19:09:00 +0000401
Misha Brukman8baa01c2003-04-09 21:51:34 +0000402 }
403
404 for (unsigned i = 2; i < numNodes + 2; i++) {
Guochun Shif3252612003-06-10 19:09:00 +0000405
Misha Brukman8baa01c2003-04-09 21:51:34 +0000406 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 }
Guochun Shif3252612003-06-10 19:09:00 +0000412
Misha Brukman8baa01c2003-04-09 21:51:34 +0000413 for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E =
414 node->endInEdges(); I != E; I++) {
415 SchedGraphEdge *edge = *I;
416 ModuloSchedGraphNode *pred =
417 (ModuloSchedGraphNode *) (edge->getSrc());
418 assert(pred->getPropertyComputed()
419 && "pred node property is not computed!");
420 int temp = pred->depth + edge->getMinDelay();
421 node->depth = std::max(node->depth, temp);
Guochun Shif1c154f2003-03-27 17:57:44 +0000422 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000423 node->setPropertyComputed(true);
Guochun Shif1c154f2003-03-27 17:57:44 +0000424
Guochun Shif3252612003-06-10 19:09:00 +0000425 }
426
Guochun Shif1c154f2003-03-27 17:57:44 +0000427}
428
429
Guochun Shif3252612003-06-10 19:09:00 +0000430/*
431 compute every node's height in this basic block
432*/
433
434void
435ModuloSchedGraph::computeNodeHeight(const BasicBlock *bb){
436
Misha Brukman8baa01c2003-04-09 21:51:34 +0000437 unsigned numNodes = bb->size();
438 for (unsigned i = numNodes + 1; i >= 2; i--) {
439 ModuloSchedGraphNode *node = getNode(i);
440 node->setPropertyComputed(false);
441 }
Guochun Shif3252612003-06-10 19:09:00 +0000442
Misha Brukman8baa01c2003-04-09 21:51:34 +0000443 for (unsigned i = numNodes + 1; i >= 2; i--) {
444 ModuloSchedGraphNode *node = getNode(i);
445 node->height = 0;
446 for (ModuloSchedGraphNode::const_iterator I =
Guochun Shif3252612003-06-10 19:09:00 +0000447 node->beginOutEdges(), E = node->endOutEdges(); I != E; ++I) {
Misha Brukman8baa01c2003-04-09 21:51:34 +0000448 SchedGraphEdge *edge = *I;
449 ModuloSchedGraphNode *succ =
Guochun Shif3252612003-06-10 19:09:00 +0000450 (ModuloSchedGraphNode *) (edge->getSink());
Misha Brukman8baa01c2003-04-09 21:51:34 +0000451 if (PHINode::classof(succ->getInst()))
452 continue;
453 assert(succ->getPropertyComputed()
454 && "succ node property is not computed!");
455 node->height = std::max(node->height, succ->height + edge->getMinDelay());
Guochun Shif3252612003-06-10 19:09:00 +0000456
Guochun Shif1c154f2003-03-27 17:57:44 +0000457 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000458 node->setPropertyComputed(true);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000459 }
Guochun Shif3252612003-06-10 19:09:00 +0000460
Guochun Shif1c154f2003-03-27 17:57:44 +0000461}
462
Guochun Shif3252612003-06-10 19:09:00 +0000463/*
464 compute every node's property in a basicblock
465*/
466
Misha Brukman8baa01c2003-04-09 21:51:34 +0000467void ModuloSchedGraph::computeNodeProperty(const BasicBlock * bb)
Guochun Shif1c154f2003-03-27 17:57:44 +0000468{
Misha Brukman8baa01c2003-04-09 21:51:34 +0000469 //FIXME: now assume the only backward edges come from the edges from other
470 //nodes to the phi Node so i will ignore all edges to the phi node; after
471 //this, there shall be no recurrence.
472
Guochun Shif1c154f2003-03-27 17:57:44 +0000473 this->computeNodeASAP(bb);
474 this->computeNodeALAP(bb);
475 this->computeNodeMov(bb);
476 this->computeNodeDepth(bb);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000477 this->computeNodeHeight(bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000478}
479
480
Guochun Shif3252612003-06-10 19:09:00 +0000481/*
482 compute the preset of this set without considering the edges
483 between backEdgeSrc and backEdgeSink
484*/
Misha Brukman8baa01c2003-04-09 21:51:34 +0000485std::vector<ModuloSchedGraphNode*>
486ModuloSchedGraph::predSet(std::vector<ModuloSchedGraphNode*> set,
487 unsigned backEdgeSrc,
488 unsigned
Guochun Shif3252612003-06-10 19:09:00 +0000489 backEdgeSink){
490
Guochun Shif1c154f2003-03-27 17:57:44 +0000491 std::vector<ModuloSchedGraphNode*> predS;
Guochun Shif3252612003-06-10 19:09:00 +0000492
Misha Brukman8baa01c2003-04-09 21:51:34 +0000493 for (unsigned i = 0; i < set.size(); i++) {
Guochun Shif3252612003-06-10 19:09:00 +0000494
Misha Brukman8baa01c2003-04-09 21:51:34 +0000495 ModuloSchedGraphNode *node = set[i];
496 for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E =
497 node->endInEdges(); I != E; I++) {
498 SchedGraphEdge *edge = *I;
Guochun Shif3252612003-06-10 19:09:00 +0000499
500 //if edges between backEdgeSrc and backEdgeSink, omitted
Misha Brukman8baa01c2003-04-09 21:51:34 +0000501 if (edge->getSrc()->getNodeId() == backEdgeSrc
502 && edge->getSink()->getNodeId() == backEdgeSink)
503 continue;
504 ModuloSchedGraphNode *pred =
505 (ModuloSchedGraphNode *) (edge->getSrc());
Guochun Shif3252612003-06-10 19:09:00 +0000506
507 //if pred is not in the predSet ....
Misha Brukman8baa01c2003-04-09 21:51:34 +0000508 bool alreadyInset = false;
509 for (unsigned j = 0; j < predS.size(); ++j)
510 if (predS[j]->getNodeId() == pred->getNodeId()) {
511 alreadyInset = true;
512 break;
513 }
514
Guochun Shif3252612003-06-10 19:09:00 +0000515 // and pred is not in the set ....
Misha Brukman8baa01c2003-04-09 21:51:34 +0000516 for (unsigned j = 0; j < set.size(); ++j)
517 if (set[j]->getNodeId() == pred->getNodeId()) {
518 alreadyInset = true;
519 break;
520 }
521
Guochun Shif3252612003-06-10 19:09:00 +0000522 //push it into the predS
Misha Brukman8baa01c2003-04-09 21:51:34 +0000523 if (!alreadyInset)
524 predS.push_back(pred);
Guochun Shif1c154f2003-03-27 17:57:44 +0000525 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000526 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000527 return predS;
528}
529
Guochun Shif3252612003-06-10 19:09:00 +0000530
531/*
532 return pred set to this set
533*/
534
535ModuloSchedGraph::NodeVec
536ModuloSchedGraph::predSet(NodeVec set){
537
538 //node number increases from 2,
Misha Brukman8baa01c2003-04-09 21:51:34 +0000539 return predSet(set, 0, 0);
Guochun Shif1c154f2003-03-27 17:57:44 +0000540}
541
Guochun Shif3252612003-06-10 19:09:00 +0000542/*
543 return pred set to _node, ignoring
544 any edge between backEdgeSrc and backEdgeSink
545*/
Misha Brukman8baa01c2003-04-09 21:51:34 +0000546std::vector <ModuloSchedGraphNode*>
547ModuloSchedGraph::predSet(ModuloSchedGraphNode *_node,
Guochun Shif3252612003-06-10 19:09:00 +0000548 unsigned backEdgeSrc, unsigned backEdgeSink){
549
Guochun Shif1c154f2003-03-27 17:57:44 +0000550 std::vector<ModuloSchedGraphNode*> set;
551 set.push_back(_node);
552 return predSet(set, backEdgeSrc, backEdgeSink);
Guochun Shif1c154f2003-03-27 17:57:44 +0000553}
554
Guochun Shif3252612003-06-10 19:09:00 +0000555
556/*
557 return pred set to _node, ignoring
558*/
559
Misha Brukman8baa01c2003-04-09 21:51:34 +0000560std::vector <ModuloSchedGraphNode*>
Guochun Shif3252612003-06-10 19:09:00 +0000561ModuloSchedGraph::predSet(ModuloSchedGraphNode * _node){
562
Misha Brukman8baa01c2003-04-09 21:51:34 +0000563 return predSet(_node, 0, 0);
Guochun Shif3252612003-06-10 19:09:00 +0000564
Guochun Shif1c154f2003-03-27 17:57:44 +0000565}
566
Guochun Shif3252612003-06-10 19:09:00 +0000567/*
568 return successor set to the input set
569 ignoring any edge between src and sink
570*/
571
Misha Brukman8baa01c2003-04-09 21:51:34 +0000572std::vector<ModuloSchedGraphNode*>
573ModuloSchedGraph::succSet(std::vector<ModuloSchedGraphNode*> set,
Guochun Shif3252612003-06-10 19:09:00 +0000574 unsigned src, unsigned sink){
575
Misha Brukman8baa01c2003-04-09 21:51:34 +0000576 std::vector<ModuloSchedGraphNode*> succS;
Guochun Shif3252612003-06-10 19:09:00 +0000577
Misha Brukman8baa01c2003-04-09 21:51:34 +0000578 for (unsigned i = 0; i < set.size(); i++) {
579 ModuloSchedGraphNode *node = set[i];
580 for (ModuloSchedGraphNode::const_iterator I =
581 node->beginOutEdges(), E = node->endOutEdges(); I != E; I++) {
582 SchedGraphEdge *edge = *I;
Guochun Shif3252612003-06-10 19:09:00 +0000583
584 //if the edge is between src and sink, skip
Misha Brukman8baa01c2003-04-09 21:51:34 +0000585 if (edge->getSrc()->getNodeId() == src
586 && edge->getSink()->getNodeId() == sink)
587 continue;
588 ModuloSchedGraphNode *succ =
589 (ModuloSchedGraphNode *) (edge->getSink());
Guochun Shif3252612003-06-10 19:09:00 +0000590
591 //if pred is not in the successor set ....
Misha Brukman8baa01c2003-04-09 21:51:34 +0000592 bool alreadyInset = false;
593 for (unsigned j = 0; j < succS.size(); j++)
594 if (succS[j]->getNodeId() == succ->getNodeId()) {
595 alreadyInset = true;
596 break;
597 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000598
Guochun Shif3252612003-06-10 19:09:00 +0000599 //and not in this set ....
Misha Brukman8baa01c2003-04-09 21:51:34 +0000600 for (unsigned j = 0; j < set.size(); j++)
601 if (set[j]->getNodeId() == succ->getNodeId()) {
602 alreadyInset = true;
603 break;
604 }
Guochun Shif3252612003-06-10 19:09:00 +0000605
606 //push it into the successor set
Misha Brukman8baa01c2003-04-09 21:51:34 +0000607 if (!alreadyInset)
608 succS.push_back(succ);
Guochun Shif1c154f2003-03-27 17:57:44 +0000609 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000610 }
611 return succS;
Guochun Shif1c154f2003-03-27 17:57:44 +0000612}
613
Guochun Shif3252612003-06-10 19:09:00 +0000614/*
615 return successor set to the input set
616*/
617
618ModuloSchedGraph::NodeVec ModuloSchedGraph::succSet(NodeVec set){
619
Misha Brukman8baa01c2003-04-09 21:51:34 +0000620 return succSet(set, 0, 0);
Guochun Shif3252612003-06-10 19:09:00 +0000621
Guochun Shif1c154f2003-03-27 17:57:44 +0000622}
623
Guochun Shif3252612003-06-10 19:09:00 +0000624/*
625 return successor set to the input node
626 ignoring any edge between src and sink
627*/
Guochun Shif1c154f2003-03-27 17:57:44 +0000628
Misha Brukman8baa01c2003-04-09 21:51:34 +0000629std::vector<ModuloSchedGraphNode*>
630ModuloSchedGraph::succSet(ModuloSchedGraphNode *_node,
Guochun Shif3252612003-06-10 19:09:00 +0000631 unsigned src, unsigned sink){
632
Misha Brukman8baa01c2003-04-09 21:51:34 +0000633 std::vector<ModuloSchedGraphNode*>set;
Guochun Shif3252612003-06-10 19:09:00 +0000634
Guochun Shif1c154f2003-03-27 17:57:44 +0000635 set.push_back(_node);
Guochun Shif3252612003-06-10 19:09:00 +0000636
Guochun Shif1c154f2003-03-27 17:57:44 +0000637 return succSet(set, src, sink);
Guochun Shif3252612003-06-10 19:09:00 +0000638
Guochun Shif1c154f2003-03-27 17:57:44 +0000639}
640
Guochun Shif3252612003-06-10 19:09:00 +0000641/*
642 return successor set to the input node
643*/
644
Misha Brukman8baa01c2003-04-09 21:51:34 +0000645std::vector<ModuloSchedGraphNode*>
Guochun Shif3252612003-06-10 19:09:00 +0000646ModuloSchedGraph::succSet(ModuloSchedGraphNode * _node){
647
Guochun Shif1c154f2003-03-27 17:57:44 +0000648 return succSet(_node, 0, 0);
Guochun Shif3252612003-06-10 19:09:00 +0000649
Guochun Shif1c154f2003-03-27 17:57:44 +0000650}
651
Guochun Shif3252612003-06-10 19:09:00 +0000652
653/*
654 find maximum delay between srcId and sinkId
655*/
656
657SchedGraphEdge*
658ModuloSchedGraph::getMaxDelayEdge(unsigned srcId,
659 unsigned sinkId){
660
Misha Brukman8baa01c2003-04-09 21:51:34 +0000661 ModuloSchedGraphNode *node = getNode(srcId);
662 SchedGraphEdge *maxDelayEdge = NULL;
663 int maxDelay = -1;
664 for (ModuloSchedGraphNode::const_iterator I = node->beginOutEdges(), E =
665 node->endOutEdges(); I != E; I++) {
666 SchedGraphEdge *edge = *I;
667 if (edge->getSink()->getNodeId() == sinkId)
668 if (edge->getMinDelay() > maxDelay) {
669 maxDelayEdge = edge;
670 maxDelay = edge->getMinDelay();
671 }
672 }
673 assert(maxDelayEdge != NULL && "no edge between the srcId and sinkId?");
Guochun Shif1c154f2003-03-27 17:57:44 +0000674 return maxDelayEdge;
Guochun Shif3252612003-06-10 19:09:00 +0000675
Guochun Shif1c154f2003-03-27 17:57:44 +0000676}
677
Guochun Shif3252612003-06-10 19:09:00 +0000678/*
679 dump all circuits found
680*/
681
682void
683ModuloSchedGraph::dumpCircuits(){
684
Guochun Shi33280522003-06-08 20:40:47 +0000685 DEBUG_PRINT(std::cerr << "dumping circuits for graph:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000686 int j = -1;
687 while (circuits[++j][0] != 0) {
688 int k = -1;
689 while (circuits[j][++k] != 0)
Guochun Shi33280522003-06-08 20:40:47 +0000690 DEBUG_PRINT(std::cerr << circuits[j][k] << "\t");
691 DEBUG_PRINT(std::cerr << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +0000692 }
693}
694
Guochun Shif3252612003-06-10 19:09:00 +0000695/*
696 dump all sets found
697*/
698
699void
700ModuloSchedGraph::dumpSet(std::vector < ModuloSchedGraphNode * >set){
701
Misha Brukman8baa01c2003-04-09 21:51:34 +0000702 for (unsigned i = 0; i < set.size(); i++)
Guochun Shi33280522003-06-08 20:40:47 +0000703 DEBUG_PRINT(std::cerr << set[i]->getNodeId() << "\t");
704 DEBUG_PRINT(std::cerr << "\n");
Guochun Shif3252612003-06-10 19:09:00 +0000705
Guochun Shif1c154f2003-03-27 17:57:44 +0000706}
707
Guochun Shif3252612003-06-10 19:09:00 +0000708/*
709 return union of set1 and set2
710*/
711
Misha Brukman8baa01c2003-04-09 21:51:34 +0000712std::vector<ModuloSchedGraphNode*>
713ModuloSchedGraph::vectorUnion(std::vector<ModuloSchedGraphNode*> set1,
Guochun Shif3252612003-06-10 19:09:00 +0000714 std::vector<ModuloSchedGraphNode*> set2){
715
Guochun Shif1c154f2003-03-27 17:57:44 +0000716 std::vector<ModuloSchedGraphNode*> unionVec;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000717 for (unsigned i = 0; i < set1.size(); i++)
Guochun Shif1c154f2003-03-27 17:57:44 +0000718 unionVec.push_back(set1[i]);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000719 for (unsigned j = 0; j < set2.size(); j++) {
720 bool inset = false;
721 for (unsigned i = 0; i < unionVec.size(); i++)
722 if (set2[j] == unionVec[i])
723 inset = true;
724 if (!inset)
725 unionVec.push_back(set2[j]);
Guochun Shif1c154f2003-03-27 17:57:44 +0000726 }
727 return unionVec;
728}
Misha Brukman8baa01c2003-04-09 21:51:34 +0000729
Guochun Shif3252612003-06-10 19:09:00 +0000730/*
731 return conjuction of set1 and set2
732*/
Misha Brukman8baa01c2003-04-09 21:51:34 +0000733std::vector<ModuloSchedGraphNode*>
734ModuloSchedGraph::vectorConj(std::vector<ModuloSchedGraphNode*> set1,
Guochun Shif3252612003-06-10 19:09:00 +0000735 std::vector<ModuloSchedGraphNode*> set2){
736
Misha Brukman8baa01c2003-04-09 21:51:34 +0000737 std::vector<ModuloSchedGraphNode*> conjVec;
738 for (unsigned i = 0; i < set1.size(); i++)
739 for (unsigned j = 0; j < set2.size(); j++)
740 if (set1[i] == set2[j])
741 conjVec.push_back(set1[i]);
742 return conjVec;
Guochun Shif3252612003-06-10 19:09:00 +0000743
Guochun Shif1c154f2003-03-27 17:57:44 +0000744}
745
Guochun Shif3252612003-06-10 19:09:00 +0000746/*
747 return the result of subtracting set2 from set1
748 (set1 -set2)
749*/
750ModuloSchedGraph::NodeVec
751ModuloSchedGraph::vectorSub(NodeVec set1,
752 NodeVec set2){
753
Guochun Shif1c154f2003-03-27 17:57:44 +0000754 NodeVec newVec;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000755 for (NodeVec::iterator I = set1.begin(); I != set1.end(); I++) {
Guochun Shif3252612003-06-10 19:09:00 +0000756
Misha Brukman8baa01c2003-04-09 21:51:34 +0000757 bool inset = false;
758 for (NodeVec::iterator II = set2.begin(); II != set2.end(); II++)
759 if ((*I)->getNodeId() == (*II)->getNodeId()) {
760 inset = true;
761 break;
762 }
Guochun Shif3252612003-06-10 19:09:00 +0000763
Misha Brukman8baa01c2003-04-09 21:51:34 +0000764 if (!inset)
765 newVec.push_back(*I);
Guochun Shif3252612003-06-10 19:09:00 +0000766
Guochun Shif1c154f2003-03-27 17:57:44 +0000767 }
Guochun Shif3252612003-06-10 19:09:00 +0000768
Guochun Shif1c154f2003-03-27 17:57:44 +0000769 return newVec;
Guochun Shif3252612003-06-10 19:09:00 +0000770
Guochun Shif1c154f2003-03-27 17:57:44 +0000771}
Guochun Shif1c154f2003-03-27 17:57:44 +0000772
Guochun Shif3252612003-06-10 19:09:00 +0000773/*
774 order all nodes in the basicblock
775 based on the sets information and node property
776
777 output: ordered nodes are stored in oNodes
778*/
779
Misha Brukman8baa01c2003-04-09 21:51:34 +0000780void ModuloSchedGraph::orderNodes() {
781 oNodes.clear();
782
783 std::vector < ModuloSchedGraphNode * >set;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000784 unsigned numNodes = bb->size();
785
Misha Brukman2c821cc2003-04-10 19:19:23 +0000786 // first order all the sets
Misha Brukman8baa01c2003-04-09 21:51:34 +0000787 int j = -1;
788 int totalDelay = -1;
789 int preDelay = -1;
790 while (circuits[++j][0] != 0) {
791 int k = -1;
792 preDelay = totalDelay;
793
794 while (circuits[j][++k] != 0) {
795 ModuloSchedGraphNode *node = getNode(circuits[j][k]);
Guochun Shif1c154f2003-03-27 17:57:44 +0000796 unsigned nextNodeId;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000797 nextNodeId =
798 circuits[j][k + 1] != 0 ? circuits[j][k + 1] : circuits[j][0];
799 SchedGraphEdge *edge = getMaxDelayEdge(circuits[j][k], nextNodeId);
Guochun Shif1c154f2003-03-27 17:57:44 +0000800 totalDelay += edge->getMinDelay();
801 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000802 if (preDelay != -1 && totalDelay > preDelay) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000803 // swap circuits[j][] and cuicuits[j-1][]
Guochun Shif1c154f2003-03-27 17:57:44 +0000804 unsigned temp[MAXNODE];
Misha Brukman8baa01c2003-04-09 21:51:34 +0000805 for (int k = 0; k < MAXNODE; k++) {
806 temp[k] = circuits[j - 1][k];
807 circuits[j - 1][k] = circuits[j][k];
808 circuits[j][k] = temp[k];
Guochun Shif1c154f2003-03-27 17:57:44 +0000809 }
810 //restart
Misha Brukman8baa01c2003-04-09 21:51:34 +0000811 j = -1;
Guochun Shif1c154f2003-03-27 17:57:44 +0000812 }
813 }
814
Guochun Shif3252612003-06-10 19:09:00 +0000815
Misha Brukman2c821cc2003-04-10 19:19:23 +0000816 // build the first set
Guochun Shif1c154f2003-03-27 17:57:44 +0000817 int backEdgeSrc;
818 int backEdgeSink;
Misha Brukman2c821cc2003-04-10 19:19:23 +0000819 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000820 DEBUG_PRINT(std::cerr << "building the first set" << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000821 int setSeq = -1;
822 int k = -1;
Guochun Shif1c154f2003-03-27 17:57:44 +0000823 setSeq++;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000824 while (circuits[setSeq][++k] != 0)
Guochun Shif1c154f2003-03-27 17:57:44 +0000825 set.push_back(getNode(circuits[setSeq][k]));
Misha Brukman8baa01c2003-04-09 21:51:34 +0000826 if (circuits[setSeq][0] != 0) {
827 backEdgeSrc = circuits[setSeq][k - 1];
828 backEdgeSink = circuits[setSeq][0];
Guochun Shif1c154f2003-03-27 17:57:44 +0000829 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000830 if (ModuloScheduling::printScheduleProcess()) {
Guochun Shi33280522003-06-08 20:40:47 +0000831 DEBUG_PRINT(std::cerr << "the first set is:");
Guochun Shif1c154f2003-03-27 17:57:44 +0000832 dumpSet(set);
833 }
Guochun Shif3252612003-06-10 19:09:00 +0000834
Misha Brukman2c821cc2003-04-10 19:19:23 +0000835 // implement the ordering algorithm
Misha Brukman8baa01c2003-04-09 21:51:34 +0000836 enum OrderSeq { bottom_up, top_down };
Guochun Shif1c154f2003-03-27 17:57:44 +0000837 OrderSeq order;
838 std::vector<ModuloSchedGraphNode*> R;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000839 while (!set.empty()) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000840 std::vector<ModuloSchedGraphNode*> pset = predSet(oNodes);
841 std::vector<ModuloSchedGraphNode*> sset = succSet(oNodes);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000842
843 if (!pset.empty() && !vectorConj(pset, set).empty()) {
844 R = vectorConj(pset, set);
845 order = bottom_up;
846 } else if (!sset.empty() && !vectorConj(sset, set).empty()) {
847 R = vectorConj(sset, set);
848 order = top_down;
849 } else {
850 int maxASAP = -1;
851 int position = -1;
852 for (unsigned i = 0; i < set.size(); i++) {
853 int temp = set[i]->getASAP();
854 if (temp > maxASAP) {
855 maxASAP = temp;
856 position = i;
857 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000858 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000859 R.push_back(set[position]);
860 order = bottom_up;
861 }
862
863 while (!R.empty()) {
864 if (order == top_down) {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000865 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000866 DEBUG_PRINT(std::cerr << "in top_down round\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000867 while (!R.empty()) {
868 int maxHeight = -1;
869 NodeVec::iterator chosenI;
870 for (NodeVec::iterator I = R.begin(); I != R.end(); I++) {
871 int temp = (*I)->height;
872 if ((temp > maxHeight)
873 || (temp == maxHeight && (*I)->mov <= (*chosenI)->mov)) {
874
875 if ((temp > maxHeight)
876 || (temp == maxHeight && (*I)->mov < (*chosenI)->mov)) {
877 maxHeight = temp;
878 chosenI = I;
879 continue;
880 }
Guochun Shif3252612003-06-10 19:09:00 +0000881
Misha Brukman8baa01c2003-04-09 21:51:34 +0000882 //possible case: instruction A and B has the same height and mov,
883 //but A has dependence to B e.g B is the branch instruction in the
884 //end, or A is the phi instruction at the beginning
885 if ((*I)->mov == (*chosenI)->mov)
886 for (ModuloSchedGraphNode::const_iterator oe =
887 (*I)->beginOutEdges(), end = (*I)->endOutEdges();
888 oe != end; oe++) {
889 if ((*oe)->getSink() == (*chosenI)) {
890 maxHeight = temp;
891 chosenI = I;
892 continue;
893 }
894 }
895 }
896 }
Guochun Shif3252612003-06-10 19:09:00 +0000897
Misha Brukman8baa01c2003-04-09 21:51:34 +0000898 ModuloSchedGraphNode *mu = *chosenI;
899 oNodes.push_back(mu);
900 R.erase(chosenI);
901 std::vector<ModuloSchedGraphNode*> succ_mu =
902 succSet(mu, backEdgeSrc, backEdgeSink);
903 std::vector<ModuloSchedGraphNode*> comm =
904 vectorConj(succ_mu, set);
905 comm = vectorSub(comm, oNodes);
906 R = vectorUnion(comm, R);
907 }
908 order = bottom_up;
909 R = vectorConj(predSet(oNodes), set);
910 } else {
Misha Brukman2c821cc2003-04-10 19:19:23 +0000911 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000912 DEBUG_PRINT(std::cerr << "in bottom up round\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000913 while (!R.empty()) {
914 int maxDepth = -1;
915 NodeVec::iterator chosenI;
916 for (NodeVec::iterator I = R.begin(); I != R.end(); I++) {
917 int temp = (*I)->depth;
918 if ((temp > maxDepth)
919 || (temp == maxDepth && (*I)->mov < (*chosenI)->mov)) {
920 maxDepth = temp;
921 chosenI = I;
922 }
923 }
924 ModuloSchedGraphNode *mu = *chosenI;
925 oNodes.push_back(mu);
926 R.erase(chosenI);
927 std::vector<ModuloSchedGraphNode*> pred_mu =
928 predSet(mu, backEdgeSrc, backEdgeSink);
929 std::vector<ModuloSchedGraphNode*> comm =
930 vectorConj(pred_mu, set);
931 comm = vectorSub(comm, oNodes);
932 R = vectorUnion(comm, R);
933 }
934 order = top_down;
935 R = vectorConj(succSet(oNodes), set);
Guochun Shif1c154f2003-03-27 17:57:44 +0000936 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000937 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000938 if (ModuloScheduling::printScheduleProcess()) {
Guochun Shi33280522003-06-08 20:40:47 +0000939 DEBUG_PRINT(std::cerr << "order finished\n");
940 DEBUG_PRINT(std::cerr << "dumping the ordered nodes:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000941 dumpSet(oNodes);
942 dumpCircuits();
943 }
Guochun Shif3252612003-06-10 19:09:00 +0000944
Misha Brukman8baa01c2003-04-09 21:51:34 +0000945 //create a new set
946 //FIXME: the nodes between onodes and this circuit should also be include in
947 //this set
Misha Brukman2c821cc2003-04-10 19:19:23 +0000948 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000949 DEBUG_PRINT(std::cerr << "building the next set\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000950 set.clear();
951 int k = -1;
952 setSeq++;
953 while (circuits[setSeq][++k] != 0)
954 set.push_back(getNode(circuits[setSeq][k]));
955 if (circuits[setSeq][0] != 0) {
956 backEdgeSrc = circuits[setSeq][k - 1];
957 backEdgeSink = circuits[setSeq][0];
958 }
Guochun Shif3252612003-06-10 19:09:00 +0000959
Misha Brukman8baa01c2003-04-09 21:51:34 +0000960 if (set.empty()) {
961 //no circuits any more
962 //collect all other nodes
Misha Brukman2c821cc2003-04-10 19:19:23 +0000963 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +0000964 DEBUG_PRINT(std::cerr << "no circuits any more, collect the rest nodes\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000965 for (unsigned i = 2; i < numNodes + 2; i++) {
966 bool inset = false;
967 for (unsigned j = 0; j < oNodes.size(); j++)
968 if (oNodes[j]->getNodeId() == i) {
969 inset = true;
970 break;
971 }
972 if (!inset)
973 set.push_back(getNode(i));
Guochun Shif1c154f2003-03-27 17:57:44 +0000974 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000975 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000976 if (ModuloScheduling::printScheduleProcess()) {
Guochun Shi33280522003-06-08 20:40:47 +0000977 DEBUG_PRINT(std::cerr << "next set is:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +0000978 dumpSet(set);
979 }
Guochun Shif3252612003-06-10 19:09:00 +0000980 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000981
Guochun Shif1c154f2003-03-27 17:57:44 +0000982}
983
984
985
Guochun Shif3252612003-06-10 19:09:00 +0000986/*
987
988 build graph for instructions in this basic block
989
990*/
Misha Brukman8baa01c2003-04-09 21:51:34 +0000991void ModuloSchedGraph::buildGraph(const TargetMachine & target)
Guochun Shif1c154f2003-03-27 17:57:44 +0000992{
Guochun Shif3252612003-06-10 19:09:00 +0000993
Guochun Shi099b0642003-06-02 17:48:56 +0000994 assert(this->bb && "The basicBlock is NULL?");
Guochun Shif3252612003-06-10 19:09:00 +0000995
Misha Brukman8baa01c2003-04-09 21:51:34 +0000996 // Make a dummy root node. We'll add edges to the real roots later.
997 graphRoot = new ModuloSchedGraphNode(0, NULL, NULL, -1, target);
998 graphLeaf = new ModuloSchedGraphNode(1, NULL, NULL, -1, target);
999
Misha Brukman2c821cc2003-04-10 19:19:23 +00001000 if (ModuloScheduling::printScheduleProcess())
Guochun Shif1c154f2003-03-27 17:57:44 +00001001 this->dump(bb);
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001002
Misha Brukman8baa01c2003-04-09 21:51:34 +00001003 if (isLoop(bb)) {
Guochun Shif3252612003-06-10 19:09:00 +00001004
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001005 DEBUG_PRINT(cerr << "building nodes for this BasicBlock\n");
1006 buildNodesforBB(target, bb);
1007
1008 DEBUG_PRINT(cerr << "adding def-use edge to this basic block\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001009 this->addDefUseEdges(bb);
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001010
1011 DEBUG_PRINT(cerr << "adding CD edges to this basic block\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001012 this->addCDEdges(bb);
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001013
1014 DEBUG_PRINT(cerr << "adding memory edges to this basicblock\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001015 this->addMemEdges(bb);
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001016
Misha Brukman8baa01c2003-04-09 21:51:34 +00001017 int ResII = this->computeResII(bb);
Guochun Shif3252612003-06-10 19:09:00 +00001018
Misha Brukman2c821cc2003-04-10 19:19:23 +00001019 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001020 DEBUG_PRINT(std::cerr << "ResII is " << ResII << "\n");
Guochun Shif3252612003-06-10 19:09:00 +00001021
Misha Brukman8baa01c2003-04-09 21:51:34 +00001022 int RecII = this->computeRecII(bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +00001023 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001024 DEBUG_PRINT(std::cerr << "RecII is " << RecII << "\n");
Guochun Shif3252612003-06-10 19:09:00 +00001025
Misha Brukman8baa01c2003-04-09 21:51:34 +00001026 this->MII = std::max(ResII, RecII);
1027
1028 this->computeNodeProperty(bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +00001029 if (ModuloScheduling::printScheduleProcess())
Misha Brukman8baa01c2003-04-09 21:51:34 +00001030 this->dumpNodeProperty();
1031
1032 this->orderNodes();
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001033
Misha Brukman2c821cc2003-04-10 19:19:23 +00001034 if (ModuloScheduling::printScheduleProcess())
Misha Brukman8baa01c2003-04-09 21:51:34 +00001035 this->dump();
Misha Brukman8baa01c2003-04-09 21:51:34 +00001036
Misha Brukman8baa01c2003-04-09 21:51:34 +00001037 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001038}
1039
Guochun Shif3252612003-06-10 19:09:00 +00001040/*
1041 get node with nodeId
1042*/
1043
1044ModuloSchedGraphNode *
1045ModuloSchedGraph::getNode(const unsigned nodeId) const{
1046
Misha Brukman8baa01c2003-04-09 21:51:34 +00001047 for (const_iterator I = begin(), E = end(); I != E; I++)
1048 if ((*I).second->getNodeId() == nodeId)
1049 return (ModuloSchedGraphNode *) (*I).second;
Guochun Shif1c154f2003-03-27 17:57:44 +00001050 return NULL;
Guochun Shif3252612003-06-10 19:09:00 +00001051
Guochun Shif1c154f2003-03-27 17:57:44 +00001052}
1053
Guochun Shif3252612003-06-10 19:09:00 +00001054/*
1055 compute RecurrenceII
1056*/
1057
1058int
1059ModuloSchedGraph::computeRecII(const BasicBlock *bb){
1060
Misha Brukman8baa01c2003-04-09 21:51:34 +00001061 int RecII = 0;
Guochun Shif1c154f2003-03-27 17:57:44 +00001062
Guochun Shif1c154f2003-03-27 17:57:44 +00001063
Misha Brukman8baa01c2003-04-09 21:51:34 +00001064 //FIXME: only deal with circuits starting at the first node: the phi node
1065 //nodeId=2;
Guochun Shif1c154f2003-03-27 17:57:44 +00001066
1067 //search all elementary circuits in the dependance graph
1068 //assume maximum number of nodes is MAXNODE
Misha Brukman8baa01c2003-04-09 21:51:34 +00001069
Guochun Shif1c154f2003-03-27 17:57:44 +00001070 unsigned path[MAXNODE];
1071 unsigned stack[MAXNODE][MAXNODE];
Guochun Shif3252612003-06-10 19:09:00 +00001072
Misha Brukman8baa01c2003-04-09 21:51:34 +00001073 for (int j = 0; j < MAXNODE; j++) {
1074 path[j] = 0;
1075 for (int k = 0; k < MAXNODE; k++)
1076 stack[j][k] = 0;
1077 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001078
Guochun Shif3252612003-06-10 19:09:00 +00001079 //in our graph, the node number starts at 2
Misha Brukman8baa01c2003-04-09 21:51:34 +00001080 const unsigned numNodes = bb->size();
Guochun Shif1c154f2003-03-27 17:57:44 +00001081
Misha Brukman8baa01c2003-04-09 21:51:34 +00001082 int i = 0;
1083 path[i] = 2;
Guochun Shif1c154f2003-03-27 17:57:44 +00001084
Misha Brukman8baa01c2003-04-09 21:51:34 +00001085 ModuloSchedGraphNode *initNode = getNode(path[0]);
1086 unsigned initNodeId = initNode->getNodeId();
1087 ModuloSchedGraphNode *currentNode = initNode;
Guochun Shif1c154f2003-03-27 17:57:44 +00001088
Misha Brukman8baa01c2003-04-09 21:51:34 +00001089 while (currentNode != NULL) {
1090 unsigned currentNodeId = currentNode->getNodeId();
Guochun Shi33280522003-06-08 20:40:47 +00001091 // DEBUG_PRINT(std::cerr<<"current node is "<<currentNodeId<<"\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001092
Misha Brukman8baa01c2003-04-09 21:51:34 +00001093 ModuloSchedGraphNode *nextNode = NULL;
1094 for (ModuloSchedGraphNode::const_iterator I =
1095 currentNode->beginOutEdges(), E = currentNode->endOutEdges();
1096 I != E; I++) {
Guochun Shi33280522003-06-08 20:40:47 +00001097 //DEBUG_PRINT(std::cerr <<" searching in outgoint edges of node
Misha Brukman8baa01c2003-04-09 21:51:34 +00001098 //"<<currentNodeId<<"\n";
1099 unsigned nodeId = ((SchedGraphEdge *) * I)->getSink()->getNodeId();
1100 bool inpath = false, instack = false;
1101 int k;
Guochun Shif1c154f2003-03-27 17:57:44 +00001102
Guochun Shi33280522003-06-08 20:40:47 +00001103 //DEBUG_PRINT(std::cerr<<"nodeId is "<<nodeId<<"\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001104
Misha Brukman8baa01c2003-04-09 21:51:34 +00001105 k = -1;
1106 while (path[++k] != 0)
1107 if (nodeId == path[k]) {
1108 inpath = true;
1109 break;
1110 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001111
Misha Brukman8baa01c2003-04-09 21:51:34 +00001112 k = -1;
1113 while (stack[i][++k] != 0)
1114 if (nodeId == stack[i][k]) {
1115 instack = true;
1116 break;
1117 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001118
Misha Brukman8baa01c2003-04-09 21:51:34 +00001119 if (nodeId > currentNodeId && !inpath && !instack) {
1120 nextNode =
1121 (ModuloSchedGraphNode *) ((SchedGraphEdge *) * I)->getSink();
1122 break;
1123 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001124 }
Misha Brukman8baa01c2003-04-09 21:51:34 +00001125
1126 if (nextNode != NULL) {
Guochun Shi33280522003-06-08 20:40:47 +00001127 //DEBUG_PRINT(std::cerr<<"find the next Node "<<nextNode->getNodeId()<<"\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001128
1129 int j = 0;
1130 while (stack[i][j] != 0)
1131 j++;
1132 stack[i][j] = nextNode->getNodeId();
1133
1134 i++;
1135 path[i] = nextNode->getNodeId();
1136 currentNode = nextNode;
1137 } else {
Guochun Shi33280522003-06-08 20:40:47 +00001138 //DEBUG_PRINT(std::cerr<<"no expansion any more"<<"\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001139 //confirmCircuit();
1140 for (ModuloSchedGraphNode::const_iterator I =
1141 currentNode->beginOutEdges(), E = currentNode->endOutEdges();
1142 I != E; I++) {
1143 unsigned nodeId = ((SchedGraphEdge *) * I)->getSink()->getNodeId();
1144 if (nodeId == initNodeId) {
1145
1146 int j = -1;
1147 while (circuits[++j][0] != 0);
1148 for (int k = 0; k < MAXNODE; k++)
1149 circuits[j][k] = path[k];
1150
1151 }
1152 }
1153 //remove this node in the path and clear the corresponding entries in the
1154 //stack
1155 path[i] = 0;
1156 int j = 0;
1157 for (j = 0; j < MAXNODE; j++)
1158 stack[i][j] = 0;
1159 i--;
1160 currentNode = getNode(path[i]);
1161 }
1162 if (i == 0) {
1163
Misha Brukman2c821cc2003-04-10 19:19:23 +00001164 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001165 DEBUG_PRINT(std::cerr << "circuits found are:\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001166 int j = -1;
1167 while (circuits[++j][0] != 0) {
1168 int k = -1;
1169 while (circuits[j][++k] != 0)
Misha Brukman2c821cc2003-04-10 19:19:23 +00001170 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001171 DEBUG_PRINT(std::cerr << circuits[j][k] << "\t");
Misha Brukman2c821cc2003-04-10 19:19:23 +00001172 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001173 DEBUG_PRINT(std::cerr << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001174
1175 //for this circuit, compute the sum of all edge delay
1176 int sumDelay = 0;
1177 k = -1;
1178 while (circuits[j][++k] != 0) {
1179 //ModuloSchedGraphNode* node =getNode(circuits[j][k]);
1180 unsigned nextNodeId;
1181 nextNodeId =
1182 circuits[j][k + 1] !=
1183 0 ? circuits[j][k + 1] : circuits[j][0];
1184
Misha Brukman8baa01c2003-04-09 21:51:34 +00001185 sumDelay +=
Guochun Shif3252612003-06-10 19:09:00 +00001186 getMaxDelayEdge(circuits[j][k], nextNodeId)->getMinDelay();
Misha Brukman8baa01c2003-04-09 21:51:34 +00001187
1188 }
1189 // assume we have distance 1, in this case the sumDelay is RecII
1190 // this is correct for SSA form only
1191 //
Misha Brukman2c821cc2003-04-10 19:19:23 +00001192 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001193 DEBUG_PRINT(std::cerr << "The total Delay in the circuit is " << sumDelay
Misha Brukman2c821cc2003-04-10 19:19:23 +00001194 << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001195
1196 RecII = RecII > sumDelay ? RecII : sumDelay;
1197
1198 }
1199 return RecII;
1200 }
1201
1202 }
1203
Guochun Shif1c154f2003-03-27 17:57:44 +00001204 return -1;
1205}
1206
Guochun Shif3252612003-06-10 19:09:00 +00001207/*
1208 update resource usage vector (ruVec)
1209*/
1210void
1211ModuloSchedGraph::addResourceUsage(std::vector<std::pair<int,int> > &ruVec,
1212 int rid){
1213
Misha Brukman8baa01c2003-04-09 21:51:34 +00001214 bool alreadyExists = false;
1215 for (unsigned i = 0; i < ruVec.size(); i++) {
1216 if (rid == ruVec[i].first) {
Guochun Shif1c154f2003-03-27 17:57:44 +00001217 ruVec[i].second++;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001218 alreadyExists = true;
Guochun Shif1c154f2003-03-27 17:57:44 +00001219 break;
1220 }
1221 }
Misha Brukman8baa01c2003-04-09 21:51:34 +00001222 if (!alreadyExists)
1223 ruVec.push_back(std::make_pair(rid, 1));
Guochun Shif1c154f2003-03-27 17:57:44 +00001224
1225}
Misha Brukman8baa01c2003-04-09 21:51:34 +00001226
Guochun Shif3252612003-06-10 19:09:00 +00001227/*
1228 dump the resource usage vector
1229*/
1230
1231void
1232ModuloSchedGraph::dumpResourceUsage(std::vector<std::pair<int,int> > &ru){
1233
1234 TargetSchedInfo & msi = (TargetSchedInfo &) target.getSchedInfo();
1235
Misha Brukman2c821cc2003-04-10 19:19:23 +00001236 std::vector<std::pair<int,int> > resourceNumVector = msi.resourceNumVector;
Guochun Shi33280522003-06-08 20:40:47 +00001237 DEBUG_PRINT(std::cerr << "resourceID\t" << "resourceNum\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001238 for (unsigned i = 0; i < resourceNumVector.size(); i++)
Guochun Shi33280522003-06-08 20:40:47 +00001239 DEBUG_PRINT(std::cerr << resourceNumVector[i].
Misha Brukman2c821cc2003-04-10 19:19:23 +00001240 first << "\t" << resourceNumVector[i].second << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001241
Guochun Shi33280522003-06-08 20:40:47 +00001242 DEBUG_PRINT(std::cerr << " maxNumIssueTotal(issue slot in one cycle) = " << msi.
Misha Brukman2c821cc2003-04-10 19:19:23 +00001243 maxNumIssueTotal << "\n");
Guochun Shi33280522003-06-08 20:40:47 +00001244 DEBUG_PRINT(std::cerr << "resourceID\t resourceUsage\t ResourceNum\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001245 for (unsigned i = 0; i < ru.size(); i++) {
Guochun Shi33280522003-06-08 20:40:47 +00001246 DEBUG_PRINT(std::cerr << ru[i].first << "\t" << ru[i].second);
Misha Brukman8baa01c2003-04-09 21:51:34 +00001247 const unsigned resNum = msi.getCPUResourceNum(ru[i].first);
Guochun Shi33280522003-06-08 20:40:47 +00001248 DEBUG_PRINT(std::cerr << "\t" << resNum << "\n");
Guochun Shif3252612003-06-10 19:09:00 +00001249
1250 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001251}
1252
Guochun Shif3252612003-06-10 19:09:00 +00001253/*
1254 compute thre resource restriction II
1255*/
Misha Brukman8baa01c2003-04-09 21:51:34 +00001256
Guochun Shif3252612003-06-10 19:09:00 +00001257int
1258ModuloSchedGraph::computeResII(const BasicBlock * bb){
1259
Misha Brukman8baa01c2003-04-09 21:51:34 +00001260 const TargetInstrInfo & mii = target.getInstrInfo();
1261 const TargetSchedInfo & msi = target.getSchedInfo();
Guochun Shif3252612003-06-10 19:09:00 +00001262
Guochun Shif1c154f2003-03-27 17:57:44 +00001263 int ResII;
Misha Brukman2c821cc2003-04-10 19:19:23 +00001264 std::vector<std::pair<int,int> > resourceUsage;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001265
1266 for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E;
1267 I++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001268 if (ModuloScheduling::printScheduleProcess()) {
Guochun Shi33280522003-06-08 20:40:47 +00001269 DEBUG_PRINT(std::cerr << "machine instruction for llvm instruction( node " <<
Misha Brukman2c821cc2003-04-10 19:19:23 +00001270 getGraphNodeForInst(I)->getNodeId() << ")\n");
Guochun Shi33280522003-06-08 20:40:47 +00001271 DEBUG_PRINT(std::cerr << "\t" << *I);
Guochun Shif1c154f2003-03-27 17:57:44 +00001272 }
Misha Brukman8baa01c2003-04-09 21:51:34 +00001273 MachineCodeForInstruction & tempMvec =
1274 MachineCodeForInstruction::get(I);
Misha Brukman2c821cc2003-04-10 19:19:23 +00001275 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001276 DEBUG_PRINT(std::cerr << "size =" << tempMvec.size() << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001277 for (unsigned i = 0; i < tempMvec.size(); i++) {
1278 MachineInstr *minstr = tempMvec[i];
1279
1280 unsigned minDelay = mii.minLatency(minstr->getOpCode());
1281 InstrRUsage rUsage = msi.getInstrRUsage(minstr->getOpCode());
1282 InstrClassRUsage classRUsage =
1283 msi.getClassRUsage(mii.getSchedClass(minstr->getOpCode()));
1284 unsigned totCycles = classRUsage.totCycles;
1285
Misha Brukman2c821cc2003-04-10 19:19:23 +00001286 std::vector<std::vector<resourceId_t> > resources=rUsage.resourcesByCycle;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001287 assert(totCycles == resources.size());
Misha Brukman2c821cc2003-04-10 19:19:23 +00001288 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001289 DEBUG_PRINT(std::cerr << "resources Usage for this Instr(totCycles="
Misha Brukman2c821cc2003-04-10 19:19:23 +00001290 << totCycles << ",mindLatency="
1291 << mii.minLatency(minstr->getOpCode()) << "): " << *minstr
1292 << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001293 for (unsigned j = 0; j < resources.size(); j++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001294 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001295 DEBUG_PRINT(std::cerr << "cycle " << j << ": ");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001296 for (unsigned k = 0; k < resources[j].size(); k++) {
Misha Brukman2c821cc2003-04-10 19:19:23 +00001297 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001298 DEBUG_PRINT(std::cerr << "\t" << resources[j][k]);
Misha Brukman8baa01c2003-04-09 21:51:34 +00001299 addResourceUsage(resourceUsage, resources[j][k]);
1300 }
Misha Brukman2c821cc2003-04-10 19:19:23 +00001301 if (ModuloScheduling::printScheduleProcess())
Guochun Shi33280522003-06-08 20:40:47 +00001302 DEBUG_PRINT(std::cerr << "\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001303 }
1304 }
1305 }
Misha Brukman2c821cc2003-04-10 19:19:23 +00001306 if (ModuloScheduling::printScheduleProcess())
Guochun Shif1c154f2003-03-27 17:57:44 +00001307 this->dumpResourceUsage(resourceUsage);
1308
1309 //compute ResII
Misha Brukman8baa01c2003-04-09 21:51:34 +00001310 ResII = 0;
1311 int issueSlots = msi.maxNumIssueTotal;
1312 for (unsigned i = 0; i < resourceUsage.size(); i++) {
1313 int resourceNum = msi.getCPUResourceNum(resourceUsage[i].first);
1314 int useNum = resourceUsage[i].second;
Guochun Shif1c154f2003-03-27 17:57:44 +00001315 double tempII;
Misha Brukman8baa01c2003-04-09 21:51:34 +00001316 if (resourceNum <= issueSlots)
1317 tempII = ceil(1.0 * useNum / resourceNum);
Guochun Shif1c154f2003-03-27 17:57:44 +00001318 else
Misha Brukman8baa01c2003-04-09 21:51:34 +00001319 tempII = ceil(1.0 * useNum / issueSlots);
1320 ResII = std::max((int) tempII, ResII);
Guochun Shif1c154f2003-03-27 17:57:44 +00001321 }
1322 return ResII;
1323}
1324
Guochun Shif1c154f2003-03-27 17:57:44 +00001325
1326
Guochun Shif3252612003-06-10 19:09:00 +00001327/*
1328 dump the basicblock
1329*/
Guochun Shif1c154f2003-03-27 17:57:44 +00001330
Guochun Shif3252612003-06-10 19:09:00 +00001331void
1332ModuloSchedGraph::dump(const BasicBlock * bb){
1333
Guochun Shi33280522003-06-08 20:40:47 +00001334 DEBUG_PRINT(std::cerr << "dumping basic block:");
1335 DEBUG_PRINT(std::cerr << (bb->hasName()? bb->getName() : "block")
Guochun Shif3252612003-06-10 19:09:00 +00001336 << " (" << bb << ")" << "\n");
1337
Guochun Shif1c154f2003-03-27 17:57:44 +00001338}
1339
Guochun Shif3252612003-06-10 19:09:00 +00001340/*
1341 dump the basicblock to ostream os
1342*/
1343
1344void
1345ModuloSchedGraph::dump(const BasicBlock * bb, std::ostream & os){
1346
Misha Brukman8baa01c2003-04-09 21:51:34 +00001347 os << "dumping basic block:";
1348 os << (bb->hasName()? bb->getName() : "block")
1349 << " (" << bb << ")" << "\n";
Guochun Shif1c154f2003-03-27 17:57:44 +00001350}
1351
Guochun Shif3252612003-06-10 19:09:00 +00001352/*
1353 dump the graph
1354*/
1355
Misha Brukman8baa01c2003-04-09 21:51:34 +00001356void ModuloSchedGraph::dump() const
Guochun Shif1c154f2003-03-27 17:57:44 +00001357{
Guochun Shi33280522003-06-08 20:40:47 +00001358 DEBUG_PRINT(std::cerr << " ModuloSchedGraph for basic Blocks:");
Guochun Shi099b0642003-06-02 17:48:56 +00001359
Guochun Shi33280522003-06-08 20:40:47 +00001360 DEBUG_PRINT(std::cerr << (bb->hasName()? bb->getName() : "block")
Guochun Shi099b0642003-06-02 17:48:56 +00001361 << " (" << bb << ")" << "");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001362
Guochun Shi33280522003-06-08 20:40:47 +00001363 DEBUG_PRINT(std::cerr << "\n\n Actual Root nodes : ");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001364 for (unsigned i = 0, N = graphRoot->outEdges.size(); i < N; i++)
Guochun Shi33280522003-06-08 20:40:47 +00001365 DEBUG_PRINT(std::cerr << graphRoot->outEdges[i]->getSink()->getNodeId()
Misha Brukman2c821cc2003-04-10 19:19:23 +00001366 << ((i == N - 1) ? "" : ", "));
Guochun Shif1c154f2003-03-27 17:57:44 +00001367
Guochun Shi33280522003-06-08 20:40:47 +00001368 DEBUG_PRINT(std::cerr << "\n Graph Nodes:\n");
Guochun Shif3252612003-06-10 19:09:00 +00001369
Guochun Shi099b0642003-06-02 17:48:56 +00001370 unsigned numNodes = bb->size();
Misha Brukman8baa01c2003-04-09 21:51:34 +00001371 for (unsigned i = 2; i < numNodes + 2; i++) {
1372 ModuloSchedGraphNode *node = getNode(i);
Guochun Shi33280522003-06-08 20:40:47 +00001373 DEBUG_PRINT(std::cerr << "\n" << *node);
Misha Brukman8baa01c2003-04-09 21:51:34 +00001374 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001375
Guochun Shi33280522003-06-08 20:40:47 +00001376 DEBUG_PRINT(std::cerr << "\n");
Guochun Shif1c154f2003-03-27 17:57:44 +00001377}
Misha Brukman8baa01c2003-04-09 21:51:34 +00001378
Guochun Shif3252612003-06-10 19:09:00 +00001379
1380/*
1381 dump all node property
1382*/
1383
Misha Brukman8baa01c2003-04-09 21:51:34 +00001384void ModuloSchedGraph::dumpNodeProperty() const
Guochun Shif1c154f2003-03-27 17:57:44 +00001385{
Guochun Shi099b0642003-06-02 17:48:56 +00001386
Misha Brukman8baa01c2003-04-09 21:51:34 +00001387 unsigned numNodes = bb->size();
1388 for (unsigned i = 2; i < numNodes + 2; i++) {
1389 ModuloSchedGraphNode *node = getNode(i);
Guochun Shi33280522003-06-08 20:40:47 +00001390 DEBUG_PRINT(std::cerr << "NodeId " << node->getNodeId() << "\t");
1391 DEBUG_PRINT(std::cerr << "ASAP " << node->getASAP() << "\t");
1392 DEBUG_PRINT(std::cerr << "ALAP " << node->getALAP() << "\t");
1393 DEBUG_PRINT(std::cerr << "mov " << node->getMov() << "\t");
1394 DEBUG_PRINT(std::cerr << "depth " << node->getDepth() << "\t");
1395 DEBUG_PRINT(std::cerr << "height " << node->getHeight() << "\t\n");
Misha Brukman8baa01c2003-04-09 21:51:34 +00001396 }
Guochun Shif1c154f2003-03-27 17:57:44 +00001397}
1398
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001399
1400
1401
1402/************member functions for ModuloSchedGraphSet**************/
1403
Guochun Shif3252612003-06-10 19:09:00 +00001404/*
1405 constructor
1406*/
1407
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001408ModuloSchedGraphSet::ModuloSchedGraphSet(const Function *function,
1409 const TargetMachine &target)
1410: method(function){
1411
1412 buildGraphsForMethod(method, target);
1413
1414}
1415
Guochun Shif3252612003-06-10 19:09:00 +00001416/*
1417 destructor
1418*/
1419
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001420
1421ModuloSchedGraphSet::~ModuloSchedGraphSet(){
1422
1423 //delete all the graphs
1424 for (iterator I = begin(), E = end(); I != E; ++I)
1425 delete *I;
1426}
1427
1428
1429
Guochun Shif3252612003-06-10 19:09:00 +00001430/*
1431 build graph for each basicblock in this method
1432*/
1433
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001434void
1435ModuloSchedGraphSet::buildGraphsForMethod(const Function *F,
1436 const TargetMachine &target){
1437
Guochun Shi099b0642003-06-02 17:48:56 +00001438 for (Function::const_iterator BI = F->begin(); BI != F->end(); ++BI){
1439 const BasicBlock* local_bb;
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001440
Guochun Shi099b0642003-06-02 17:48:56 +00001441 local_bb=BI;
1442 addGraph(new ModuloSchedGraph((BasicBlock*)local_bb, target));
1443 }
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001444
Guochun Shif1c154f2003-03-27 17:57:44 +00001445}
1446
Guochun Shif3252612003-06-10 19:09:00 +00001447/*
1448 dump the graph set
1449*/
1450
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001451void
1452ModuloSchedGraphSet::dump() const{
1453
1454 DEBUG_PRINT(std::cerr << " ====== ModuloSched graphs for function `" <<
1455 method->getName() << "' =========\n\n");
1456 for (const_iterator I = begin(); I != end(); ++I)
1457 (*I)->dump();
1458
1459 DEBUG_PRINT(std::cerr << "\n=========End graphs for function `" << method->getName()
1460 << "' ==========\n\n");
1461}
1462
1463
1464
1465
1466/********************misc functions***************************/
1467
1468
Guochun Shif3252612003-06-10 19:09:00 +00001469/*
1470 dump the input basic block
1471*/
1472
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001473static void
1474dumpBasicBlock(const BasicBlock * bb){
1475
1476 DEBUG_PRINT(std::cerr << "dumping basic block:");
1477 DEBUG_PRINT(std::cerr << (bb->hasName()? bb->getName() : "block")
1478 << " (" << bb << ")" << "\n");
1479}
1480
Guochun Shif3252612003-06-10 19:09:00 +00001481/*
1482 dump the input node
1483*/
Guochun Shi8f1d4ab2003-06-08 23:16:07 +00001484
Misha Brukman63e04f32003-04-22 23:00:08 +00001485std::ostream& operator<<(std::ostream &os,
1486 const ModuloSchedGraphNode &node)
Guochun Shif1c154f2003-03-27 17:57:44 +00001487{
1488 os << std::string(8, ' ')
Misha Brukman8baa01c2003-04-09 21:51:34 +00001489 << "Node " << node.nodeId << " : "
1490 << "latency = " << node.latency << "\n" << std::string(12, ' ');
Guochun Shif1c154f2003-03-27 17:57:44 +00001491
1492 if (node.getInst() == NULL)
1493 os << "(Dummy node)\n";
Misha Brukman8baa01c2003-04-09 21:51:34 +00001494 else {
1495 os << *node.getInst() << "\n" << std::string(12, ' ');
1496 os << node.inEdges.size() << " Incoming Edges:\n";
1497 for (unsigned i = 0, N = node.inEdges.size(); i < N; i++)
1498 os << std::string(16, ' ') << *node.inEdges[i];
1499
1500 os << std::string(12, ' ') << node.outEdges.size()
1501 << " Outgoing Edges:\n";
1502 for (unsigned i = 0, N = node.outEdges.size(); i < N; i++)
1503 os << std::string(16, ' ') << *node.outEdges[i];
1504 }
1505
Guochun Shif1c154f2003-03-27 17:57:44 +00001506 return os;
1507}