Fixed bug in searchPath function for finding nodes between two recurrences.
[oota-llvm.git] / lib / Target / SparcV9 / ModuloScheduling / MSchedGraph.cpp
1 //===-- MSchedGraph.cpp - Scheduling Graph ----------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // A graph class for dependencies. This graph only contains true, anti, and
11 // output data dependencies for a given MachineBasicBlock. Dependencies
12 // across iterations are also computed. Unless data dependence analysis
13 // is provided, a conservative approach of adding dependencies between all
14 // loads and stores is taken.
15 //===----------------------------------------------------------------------===//
16 #define DEBUG_TYPE "ModuloSched"
17
18 #include "MSchedGraph.h"
19 #include "../SparcV9RegisterInfo.h"
20 #include "../MachineCodeForInstruction.h"
21 #include "llvm/BasicBlock.h"
22 #include "llvm/Constants.h"
23 #include "llvm/Instructions.h"
24 #include "llvm/Type.h"
25 #include "llvm/CodeGen/MachineBasicBlock.h"
26 #include "llvm/Target/TargetInstrInfo.h"
27 #include "llvm/Support/Debug.h"
28 #include <cstdlib>
29 #include <algorithm>
30 #include <set>
31
32 using namespace llvm;
33
34 //MSchedGraphNode constructor
35 MSchedGraphNode::MSchedGraphNode(const MachineInstr* inst,
36                                  MSchedGraph *graph, unsigned idx,
37                                  unsigned late, bool isBranch) 
38   : Inst(inst), Parent(graph), index(idx), latency(late), 
39     isBranchInstr(isBranch) {
40
41   //Add to the graph
42   graph->addNode(inst, this);
43 }
44
45 //MSchedGraphNode copy constructor
46 MSchedGraphNode::MSchedGraphNode(const MSchedGraphNode &N)
47   : Predecessors(N.Predecessors), Successors(N.Successors) {
48
49   Inst = N.Inst;
50   Parent = N.Parent;
51   index = N.index;
52   latency = N.latency;
53   isBranchInstr = N.isBranchInstr;
54
55 }
56
57 //Print the node (instruction and latency)
58 void MSchedGraphNode::print(std::ostream &os) const {
59   os << "MSchedGraphNode: Inst=" << *Inst << ", latency= " << latency << "\n";
60 }
61
62
63 //Get the edge from a predecessor to this node
64 MSchedGraphEdge MSchedGraphNode::getInEdge(MSchedGraphNode *pred) {
65   //Loop over all the successors of our predecessor
66   //return the edge the corresponds to this in edge
67   for (MSchedGraphNode::succ_iterator I = pred->succ_begin(),
68          E = pred->succ_end(); I != E; ++I) {
69     if (*I == this)
70       return I.getEdge();
71   }
72   assert(0 && "Should have found edge between this node and its predecessor!");
73   abort();
74 }
75
76 //Get the iteration difference for the edge from this node to its successor
77 unsigned MSchedGraphNode::getIteDiff(MSchedGraphNode *succ) {
78   for(std::vector<MSchedGraphEdge>::iterator I = Successors.begin(), 
79         E = Successors.end();
80       I != E; ++I) {
81     if(I->getDest() == succ)
82       return I->getIteDiff();
83   }
84   return 0;
85 }
86
87 //Get the index into the vector of edges for the edge from pred to this node
88 unsigned MSchedGraphNode::getInEdgeNum(MSchedGraphNode *pred) {
89   //Loop over all the successors of our predecessor
90   //return the edge the corresponds to this in edge
91   int count = 0;
92   for(MSchedGraphNode::succ_iterator I = pred->succ_begin(), 
93         E = pred->succ_end();
94       I != E; ++I) {
95     if(*I == this)
96       return count;
97     count++;
98   }
99   assert(0 && "Should have found edge between this node and its predecessor!");
100   abort();
101 }
102
103 //Determine if succ is a successor of this node
104 bool MSchedGraphNode::isSuccessor(MSchedGraphNode *succ) {
105   for(succ_iterator I = succ_begin(), E = succ_end(); I != E; ++I)
106     if(*I == succ)
107       return true;
108   return false;
109 }
110
111 //Dtermine if pred is a predecessor of this node
112 bool MSchedGraphNode::isPredecessor(MSchedGraphNode *pred) {
113   if(std::find( Predecessors.begin(),  Predecessors.end(), 
114                 pred) !=   Predecessors.end())
115     return true;
116   else
117     return false;
118 }
119
120 //Add a node to the graph
121 void MSchedGraph::addNode(const MachineInstr *MI,
122                           MSchedGraphNode *node) {
123
124   //Make sure node does not already exist
125   assert(GraphMap.find(MI) == GraphMap.end()
126          && "New MSchedGraphNode already exists for this instruction");
127
128   GraphMap[MI] = node;
129 }
130
131 //Delete a node to the graph
132 void MSchedGraph::deleteNode(MSchedGraphNode *node) {
133
134   //Delete the edge to this node from all predecessors
135   while(node->pred_size() > 0) {
136     //DEBUG(std::cerr << "Delete edge from: " << **P << " to " << *node << "\n");
137     MSchedGraphNode *pred = *(node->pred_begin());
138     pred->deleteSuccessor(node);
139   }
140
141   //Remove this node from the graph
142   GraphMap.erase(node->getInst());
143
144 }
145
146
147 //Create a graph for a machine block. The ignoreInstrs map is so that
148 //we ignore instructions associated to the index variable since this
149 //is a special case in Modulo Scheduling.  We only want to deal with
150 //the body of the loop.
151 MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, 
152                          const TargetMachine &targ, 
153                          std::map<const MachineInstr*, unsigned> &ignoreInstrs, 
154                          DependenceAnalyzer &DA, 
155                          std::map<MachineInstr*, Instruction*> &machineTollvm)
156   : Target(targ) {
157
158   //Make sure BB is not null,
159   assert(bb != NULL && "Basic Block is null");
160
161   BBs.push_back(bb);
162   
163   //Create nodes and edges for this BB
164   buildNodesAndEdges(ignoreInstrs, DA, machineTollvm);
165
166   //Experimental!
167   //addBranchEdges();
168 }
169
170 //Copies the graph and keeps a map from old to new nodes
171 MSchedGraph::MSchedGraph(const MSchedGraph &G, 
172                          std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes) 
173   : Target(G.Target) {
174
175   BBs = G.BBs;
176
177   std::map<MSchedGraphNode*, MSchedGraphNode*> oldToNew;
178   //Copy all nodes
179   for(MSchedGraph::const_iterator N = G.GraphMap.begin(), 
180         NE = G.GraphMap.end(); N != NE; ++N) {
181
182     MSchedGraphNode *newNode = new MSchedGraphNode(*(N->second));
183     oldToNew[&*(N->second)] = newNode;
184     newNodes[newNode] = &*(N->second);
185     GraphMap[&*(N->first)] = newNode;
186   }
187
188   //Loop over nodes and update edges to point to new nodes
189   for(MSchedGraph::iterator N = GraphMap.begin(), NE = GraphMap.end(); 
190       N != NE; ++N) {
191
192     //Get the node we are dealing with
193     MSchedGraphNode *node = &*(N->second);
194
195     node->setParent(this);
196
197     //Loop over nodes successors and predecessors and update to the new nodes
198     for(unsigned i = 0; i < node->pred_size(); ++i) {
199       node->setPredecessor(i, oldToNew[node->getPredecessor(i)]);
200     }
201
202     for(unsigned i = 0; i < node->succ_size(); ++i) {
203       MSchedGraphEdge *edge = node->getSuccessor(i);
204       MSchedGraphNode *oldDest = edge->getDest();
205       edge->setDest(oldToNew[oldDest]);
206     }
207   }
208 }
209
210 //Deconstructor, deletes all nodes in the graph
211 MSchedGraph::~MSchedGraph () {
212   for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end(); 
213       I != E; ++I)
214     delete I->second;
215 }
216
217 //Print out graph
218 void MSchedGraph::print(std::ostream &os) const {
219   for(MSchedGraph::const_iterator N = GraphMap.begin(), NE = GraphMap.end(); 
220       N != NE; ++N) {
221     
222     //Get the node we are dealing with
223     MSchedGraphNode *node = &*(N->second);
224
225     os << "Node Start\n";
226     node->print(os);
227     os << "Successors:\n";
228     //print successors
229     for(unsigned i = 0; i < node->succ_size(); ++i) {
230       MSchedGraphEdge *edge = node->getSuccessor(i);
231       MSchedGraphNode *oldDest = edge->getDest();
232       oldDest->print(os);
233     }
234     os << "Node End\n";
235   }
236 }
237
238 //Calculate total delay
239 int MSchedGraph::totalDelay() {
240   int sum = 0;
241
242   for(MSchedGraph::const_iterator N = GraphMap.begin(), NE = GraphMap.end(); 
243       N != NE; ++N) {
244     
245     //Get the node we are dealing with
246     MSchedGraphNode *node = &*(N->second);
247     sum += node->getLatency();
248   }
249   return sum;
250 }
251 //Experimental code to add edges from the branch to all nodes dependent upon it.
252 void hasPath(MSchedGraphNode *node, std::set<MSchedGraphNode*> &visited, 
253            std::set<MSchedGraphNode*> &branches, MSchedGraphNode *startNode,
254            std::set<std::pair<MSchedGraphNode*,MSchedGraphNode*> > &newEdges ) {
255
256   visited.insert(node);
257   DEBUG(std::cerr << "Visiting: " << *node << "\n");
258   //Loop over successors
259   for(unsigned i = 0; i < node->succ_size(); ++i) {
260     MSchedGraphEdge *edge = node->getSuccessor(i);
261     MSchedGraphNode *dest = edge->getDest();
262     if(branches.count(dest))
263       newEdges.insert(std::make_pair(dest, startNode));
264
265     //only visit if we have not already
266     else if(!visited.count(dest)) {
267       if(edge->getIteDiff() == 0)
268         hasPath(dest, visited, branches, startNode, newEdges);}
269
270   }
271
272 }
273
274 //Experimental code to add edges from the branch to all nodes dependent upon it.
275 void MSchedGraph::addBranchEdges() {
276   std::set<MSchedGraphNode*> branches;
277   std::set<MSchedGraphNode*> nodes;
278
279   for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end(); 
280       I != E; ++I) {
281     if(I->second->isBranch())
282       if(I->second->hasPredecessors())
283         branches.insert(I->second);
284   }
285
286   //See if there is a path first instruction to the branches, if so, add an
287   //iteration dependence between that node and the branch
288   std::set<std::pair<MSchedGraphNode*, MSchedGraphNode*> > newEdges;
289   for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end(); 
290       I != E; ++I) {
291     std::set<MSchedGraphNode*> visited;
292     hasPath((I->second), visited, branches, (I->second), newEdges);
293   }
294
295   //Spit out all edges we are going to add
296   unsigned min = GraphMap.size();
297   if(newEdges.size() == 1) {
298     ((newEdges.begin())->first)->addOutEdge(((newEdges.begin())->second),
299                            MSchedGraphEdge::BranchDep,
300                            MSchedGraphEdge::NonDataDep, 1);
301   }
302   else {
303
304     unsigned count = 0;
305     MSchedGraphNode *start;
306     MSchedGraphNode *end;
307     for(std::set<std::pair<MSchedGraphNode*, MSchedGraphNode*> >::iterator I = newEdges.begin(), E = newEdges.end(); I != E; ++I) {
308
309       DEBUG(std::cerr << "Branch Edge from: " << *(I->first) << " to " << *(I->second) << "\n");
310
311       //      if(I->second->getIndex() <= min) {
312         start = I->first;
313         end = I->second;
314         //min = I->second->getIndex();
315         //}
316         start->addOutEdge(end,
317                           MSchedGraphEdge::BranchDep,
318                           MSchedGraphEdge::NonDataDep, 1);
319     }
320   }
321 }
322
323
324 //Add edges between the nodes
325 void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ignoreInstrs,
326                                      DependenceAnalyzer &DA,
327                        std::map<MachineInstr*, Instruction*> &machineTollvm) {
328   
329
330   //Get Machine target information for calculating latency
331   const TargetInstrInfo *MTI = Target.getInstrInfo();
332
333   std::vector<MSchedGraphNode*> memInstructions;
334   std::map<int, std::vector<OpIndexNodePair> > regNumtoNodeMap;
335   std::map<const Value*, std::vector<OpIndexNodePair> > valuetoNodeMap;
336
337   //Save PHI instructions to deal with later
338   std::vector<const MachineInstr*> phiInstrs;
339   unsigned index = 0;
340
341   for(std::vector<const MachineBasicBlock*>::iterator B = BBs.begin(), 
342         BE = BBs.end(); B != BE; ++B) {
343     
344     const MachineBasicBlock *BB = *B;
345
346     //Loop over instructions in MBB and add nodes and edges
347     for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end(); 
348          MI != e; ++MI) {
349       
350       //Ignore indvar instructions
351       if(ignoreInstrs.count(MI)) {
352         ++index;
353         continue;
354       }
355       
356       //Get each instruction of machine basic block, get the delay
357       //using the op code, create a new node for it, and add to the
358       //graph.
359       
360       MachineOpCode opCode = MI->getOpcode();
361       int delay;
362       
363 #if 0  // FIXME: LOOK INTO THIS
364       //Check if subsequent instructions can be issued before
365       //the result is ready, if so use min delay.
366       if(MTI->hasResultInterlock(MIopCode))
367         delay = MTI->minLatency(MIopCode);
368       else
369 #endif
370         //Get delay
371         delay = MTI->maxLatency(opCode);
372       
373       //Create new node for this machine instruction and add to the graph.
374       //Create only if not a nop
375       if(MTI->isNop(opCode))
376         continue;
377       
378       //Sparc BE does not use PHI opcode, so assert on this case
379       assert(opCode != TargetInstrInfo::PHI && "Did not expect PHI opcode");
380       
381       bool isBranch = false;
382       
383       //We want to flag the branch node to treat it special
384       if(MTI->isBranch(opCode))
385         isBranch = true;
386       
387       //Node is created and added to the graph automatically
388       MSchedGraphNode *node =  new MSchedGraphNode(MI, this, index, delay, 
389                                                    isBranch);
390       
391       DEBUG(std::cerr << "Created Node: " << *node << "\n");
392       
393       //Check OpCode to keep track of memory operations to add memory
394       //dependencies later.
395       if(MTI->isLoad(opCode) || MTI->isStore(opCode))
396         memInstructions.push_back(node);
397       
398       //Loop over all operands, and put them into the register number to
399       //graph node map for determining dependencies
400       //If an operands is a use/def, we have an anti dependence to itself
401       for(unsigned i=0; i < MI->getNumOperands(); ++i) {
402         //Get Operand
403         const MachineOperand &mOp = MI->getOperand(i);
404         
405         //Check if it has an allocated register
406         if(mOp.hasAllocatedReg()) {
407           int regNum = mOp.getReg();
408           
409           if(regNum != SparcV9::g0) {
410             //Put into our map
411             regNumtoNodeMap[regNum].push_back(std::make_pair(i, node));
412           }
413           continue;
414         }
415         
416         
417         //Add virtual registers dependencies
418         //Check if any exist in the value map already and create dependencies
419         //between them.
420         if(mOp.getType() == MachineOperand::MO_VirtualRegister 
421            ||  mOp.getType() == MachineOperand::MO_CCRegister) {
422           
423           //Make sure virtual register value is not null
424           assert((mOp.getVRegValue() != NULL) && "Null value is defined");
425           
426           //Check if this is a read operation in a phi node, if so DO NOT PROCESS
427           if(mOp.isUse() && (opCode == TargetInstrInfo::PHI)) {
428             DEBUG(std::cerr << "Read Operation in a PHI node\n");
429             continue;
430           }
431           
432           if (const Value* srcI = mOp.getVRegValue()) {
433             
434             //Find value in the map
435             std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
436               = valuetoNodeMap.find(srcI);
437             
438             //If there is something in the map already, add edges from
439             //those instructions
440             //to this one we are processing
441             if(V != valuetoNodeMap.end()) {
442               addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), phiInstrs);
443               
444               //Add to value map
445               V->second.push_back(std::make_pair(i,node));
446             }
447             //Otherwise put it in the map
448             else
449               //Put into value map
450               valuetoNodeMap[mOp.getVRegValue()].push_back(std::make_pair(i, node));
451           }
452         }
453       }
454       ++index;
455     }
456     
457     //Loop over LLVM BB, examine phi instructions, and add them to our
458     //phiInstr list to process
459     const BasicBlock *llvm_bb = BB->getBasicBlock();
460     for(BasicBlock::const_iterator I = llvm_bb->begin(), E = llvm_bb->end(); 
461         I != E; ++I) {
462       if(const PHINode *PN = dyn_cast<PHINode>(I)) {
463         MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(PN);
464         for (unsigned j = 0; j < tempMvec.size(); j++) {
465           if(!ignoreInstrs.count(tempMvec[j])) {
466             DEBUG(std::cerr << "Inserting phi instr into map: " << *tempMvec[j] << "\n");
467             phiInstrs.push_back((MachineInstr*) tempMvec[j]);
468           }
469         }
470       }
471       
472     }
473     
474     addMemEdges(memInstructions, DA, machineTollvm);
475     addMachRegEdges(regNumtoNodeMap);
476     
477     //Finally deal with PHI Nodes and Value*
478     for(std::vector<const MachineInstr*>::iterator I = phiInstrs.begin(), 
479           E = phiInstrs.end(); I != E;  ++I) {
480       
481       //Get Node for this instruction
482       std::map<const MachineInstr*, MSchedGraphNode*>::iterator X;
483       X = find(*I);
484       
485       if(X == GraphMap.end())
486         continue;
487       
488       MSchedGraphNode *node = X->second;
489       
490       DEBUG(std::cerr << "Adding ite diff edges for node: " << *node << "\n");
491       
492       //Loop over operands for this instruction and add value edges
493       for(unsigned i=0; i < (*I)->getNumOperands(); ++i) {
494         //Get Operand
495         const MachineOperand &mOp = (*I)->getOperand(i);
496         if((mOp.getType() == MachineOperand::MO_VirtualRegister 
497             ||  mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) {
498           
499           //find the value in the map
500           if (const Value* srcI = mOp.getVRegValue()) {
501             
502             //Find value in the map
503             std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
504               = valuetoNodeMap.find(srcI);
505             
506             //If there is something in the map already, add edges from
507             //those instructions
508             //to this one we are processing
509             if(V != valuetoNodeMap.end()) {
510               addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), 
511                             phiInstrs, 1);
512             }
513           }
514         }
515       }
516     }
517   }
518 }
519 //Add dependencies for Value*s
520 void MSchedGraph::addValueEdges(std::vector<OpIndexNodePair> &NodesInMap,
521                                 MSchedGraphNode *destNode, bool nodeIsUse,
522                                 bool nodeIsDef, std::vector<const MachineInstr*> &phiInstrs, int diff) {
523
524   for(std::vector<OpIndexNodePair>::iterator I = NodesInMap.begin(),
525         E = NodesInMap.end(); I != E; ++I) {
526
527     //Get node in vectors machine operand that is the same value as node
528     MSchedGraphNode *srcNode = I->second;
529     MachineOperand mOp = srcNode->getInst()->getOperand(I->first);
530
531     if(diff > 0)
532       if(std::find(phiInstrs.begin(), phiInstrs.end(), srcNode->getInst()) == phiInstrs.end())
533         continue;
534
535     //Node is a Def, so add output dep.
536     if(nodeIsDef) {
537       if(mOp.isUse()) {
538         DEBUG(std::cerr << "Edge from " << *srcNode << " to " << *destNode << " (itediff=" << diff << ", type=anti)\n");
539         srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
540                             MSchedGraphEdge::AntiDep, diff);
541       }
542       if(mOp.isDef()) {
543         DEBUG(std::cerr << "Edge from " << *srcNode << " to " << *destNode << " (itediff=" << diff << ", type=output)\n");
544         srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
545                             MSchedGraphEdge::OutputDep, diff);
546       }
547     }
548     if(nodeIsUse) {
549       if(mOp.isDef()) {
550         DEBUG(std::cerr << "Edge from " << *srcNode << " to " << *destNode << " (itediff=" << diff << ", type=true)\n");
551         srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
552                             MSchedGraphEdge::TrueDep, diff);
553       }
554     }
555   }
556 }
557
558 //Add dependencies for machine registers across iterations
559 void MSchedGraph::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >& regNumtoNodeMap) {
560   //Loop over all machine registers in the map, and add dependencies
561   //between the instructions that use it
562   typedef std::map<int, std::vector<OpIndexNodePair> > regNodeMap;
563   for(regNodeMap::iterator I = regNumtoNodeMap.begin(); 
564       I != regNumtoNodeMap.end(); ++I) {
565     //Get the register number
566     int regNum = (*I).first;
567
568     //Get Vector of nodes that use this register
569     std::vector<OpIndexNodePair> Nodes = (*I).second;
570
571     //Loop over nodes and determine the dependence between the other
572     //nodes in the vector
573     for(unsigned i =0; i < Nodes.size(); ++i) {
574
575       //Get src node operator index that uses this machine register
576       int srcOpIndex = Nodes[i].first;
577
578       //Get the actual src Node
579       MSchedGraphNode *srcNode = Nodes[i].second;
580
581       //Get Operand
582       const MachineOperand &srcMOp = srcNode->getInst()->getOperand(srcOpIndex);
583
584       bool srcIsUseandDef = srcMOp.isDef() && srcMOp.isUse();
585       bool srcIsUse = srcMOp.isUse() && !srcMOp.isDef();
586
587
588       //Look at all instructions after this in execution order
589       for(unsigned j=i+1; j < Nodes.size(); ++j) {
590         
591         //Sink node is a write
592         if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
593                       //Src only uses the register (read)
594             if(srcIsUse)
595               srcNode->addOutEdge(Nodes[j].second, 
596                                   MSchedGraphEdge::MachineRegister,
597                                   MSchedGraphEdge::AntiDep);
598         
599             else if(srcIsUseandDef) {
600               srcNode->addOutEdge(Nodes[j].second, 
601                                   MSchedGraphEdge::MachineRegister,
602                                   MSchedGraphEdge::AntiDep);
603               
604               srcNode->addOutEdge(Nodes[j].second, 
605                                   MSchedGraphEdge::MachineRegister,
606                                   MSchedGraphEdge::OutputDep);
607             }
608             else
609               srcNode->addOutEdge(Nodes[j].second, 
610                                   MSchedGraphEdge::MachineRegister,
611                                   MSchedGraphEdge::OutputDep);
612         }
613         //Dest node is a read
614         else {
615           if(!srcIsUse || srcIsUseandDef)
616             srcNode->addOutEdge(Nodes[j].second, 
617                                 MSchedGraphEdge::MachineRegister,
618                                 MSchedGraphEdge::TrueDep);
619         }
620
621       }
622
623       //Look at all the instructions before this one since machine registers
624       //could live across iterations.
625       for(unsigned j = 0; j < i; ++j) {
626                 //Sink node is a write
627         if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
628                       //Src only uses the register (read)
629             if(srcIsUse)
630               srcNode->addOutEdge(Nodes[j].second, 
631                                   MSchedGraphEdge::MachineRegister,
632                                   MSchedGraphEdge::AntiDep, 1);
633             else if(srcIsUseandDef) {
634               srcNode->addOutEdge(Nodes[j].second, 
635                                   MSchedGraphEdge::MachineRegister,
636                                   MSchedGraphEdge::AntiDep, 1);
637               
638               srcNode->addOutEdge(Nodes[j].second, 
639                                   MSchedGraphEdge::MachineRegister,
640                                   MSchedGraphEdge::OutputDep, 1);
641             }
642             else
643               srcNode->addOutEdge(Nodes[j].second, 
644                                   MSchedGraphEdge::MachineRegister,
645                                   MSchedGraphEdge::OutputDep, 1);
646         }
647         //Dest node is a read
648         else {
649           if(!srcIsUse || srcIsUseandDef)
650             srcNode->addOutEdge(Nodes[j].second, 
651                                 MSchedGraphEdge::MachineRegister,
652                                 MSchedGraphEdge::TrueDep,1 );
653         }
654         
655
656       }
657
658     }
659
660   }
661
662 }
663
664 //Add edges between all loads and stores
665 //Can be less strict with alias analysis and data dependence analysis.
666 void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst, 
667                       DependenceAnalyzer &DA, 
668                       std::map<MachineInstr*, Instruction*> &machineTollvm) {
669
670   //Get Target machine instruction info
671   const TargetInstrInfo *TMI = Target.getInstrInfo();
672
673   //Loop over all memory instructions in the vector
674   //Knowing that they are in execution, add true, anti, and output dependencies
675   for (unsigned srcIndex = 0; srcIndex < memInst.size(); ++srcIndex) {
676
677     MachineInstr *srcInst = (MachineInstr*) memInst[srcIndex]->getInst();
678
679     //Get the machine opCode to determine type of memory instruction
680     MachineOpCode srcNodeOpCode = srcInst->getOpcode();
681     
682     //All instructions after this one in execution order have an
683     //iteration delay of 0
684     for(unsigned destIndex = 0; destIndex < memInst.size(); ++destIndex) {
685
686       //No self loops
687       if(destIndex == srcIndex)
688         continue;
689
690       MachineInstr *destInst = (MachineInstr*) memInst[destIndex]->getInst();
691
692       DEBUG(std::cerr << "MInst1: " << *srcInst << "\n");
693       DEBUG(std::cerr << "MInst2: " << *destInst << "\n");
694       
695       //Assuming instructions without corresponding llvm instructions
696       //are from constant pools.
697       if (!machineTollvm.count(srcInst) || !machineTollvm.count(destInst))
698         continue;
699       
700       bool useDepAnalyzer = true;
701
702       //Some machine loads and stores are generated by casts, so be
703       //conservative and always add deps
704       Instruction *srcLLVM = machineTollvm[srcInst];
705       Instruction *destLLVM = machineTollvm[destInst];
706       if(!isa<LoadInst>(srcLLVM) 
707          && !isa<StoreInst>(srcLLVM)) {
708         if(isa<BinaryOperator>(srcLLVM)) {
709           if(isa<ConstantFP>(srcLLVM->getOperand(0)) || isa<ConstantFP>(srcLLVM->getOperand(1)))
710             continue;
711         }
712         useDepAnalyzer = false;
713       }
714       if(!isa<LoadInst>(destLLVM) 
715          && !isa<StoreInst>(destLLVM)) {
716         if(isa<BinaryOperator>(destLLVM)) {
717           if(isa<ConstantFP>(destLLVM->getOperand(0)) || isa<ConstantFP>(destLLVM->getOperand(1)))
718             continue;
719         }
720         useDepAnalyzer = false;
721       }
722
723       //Use dep analysis when we have corresponding llvm loads/stores
724       if(useDepAnalyzer) {
725         bool srcBeforeDest = true;
726         if(destIndex < srcIndex)
727           srcBeforeDest = false;
728
729         DependenceResult dr = DA.getDependenceInfo(machineTollvm[srcInst], 
730                                                    machineTollvm[destInst], 
731                                                    srcBeforeDest);
732         
733         for(std::vector<Dependence>::iterator d = dr.dependences.begin(), 
734               de = dr.dependences.end(); d != de; ++d) {
735           //Add edge from load to store
736           memInst[srcIndex]->addOutEdge(memInst[destIndex], 
737                                         MSchedGraphEdge::MemoryDep, 
738                                         d->getDepType(), d->getIteDiff());
739           
740         }
741       }
742       //Otherwise, we can not do any further analysis and must make a dependence
743       else {
744                 
745         //Get the machine opCode to determine type of memory instruction
746         MachineOpCode destNodeOpCode = destInst->getOpcode();
747
748         //Get the Value* that we are reading from the load, always the first op
749         const MachineOperand &mOp = srcInst->getOperand(0);
750         const MachineOperand &mOp2 = destInst->getOperand(0);
751         
752         if(mOp.hasAllocatedReg())
753           if(mOp.getReg() == SparcV9::g0)
754             continue;
755         if(mOp2.hasAllocatedReg())
756           if(mOp2.getReg() == SparcV9::g0)
757             continue;
758
759         DEBUG(std::cerr << "Adding dependence for machine instructions\n");
760         //Load-Store deps
761         if(TMI->isLoad(srcNodeOpCode)) {
762
763           if(TMI->isStore(destNodeOpCode))
764             memInst[srcIndex]->addOutEdge(memInst[destIndex], 
765                                           MSchedGraphEdge::MemoryDep, 
766                                           MSchedGraphEdge::AntiDep, 0);
767         }
768         else if(TMI->isStore(srcNodeOpCode)) {
769           if(TMI->isStore(destNodeOpCode))
770             memInst[srcIndex]->addOutEdge(memInst[destIndex], 
771                                           MSchedGraphEdge::MemoryDep, 
772                                           MSchedGraphEdge::OutputDep, 0);
773
774           else
775             memInst[srcIndex]->addOutEdge(memInst[destIndex], 
776                                           MSchedGraphEdge::MemoryDep, 
777                                           MSchedGraphEdge::TrueDep, 0);
778         }
779       }
780     }
781   }
782 }