blob: 9ac38b4dd3c6b4fb67714fa17c438e30be284471 [file] [log] [blame]
Misha Brukman6a90f822004-08-02 14:02:21 +00001//===-- MSchedGraph.cpp - Scheduling Graph ----------------------*- C++ -*-===//
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +00002//
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
11//
12//===----------------------------------------------------------------------===//
13#define DEBUG_TYPE "ModuloSched"
14
15#include "MSchedGraph.h"
Misha Brukman7da1e6e2004-10-10 23:34:50 +000016#include "../SparcV9RegisterInfo.h"
Tanya Lattnerdb40cf12005-02-10 17:02:58 +000017#include "../MachineCodeForInstruction.h"
18#include "llvm/BasicBlock.h"
19#include "llvm/Instructions.h"
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +000020#include "llvm/CodeGen/MachineBasicBlock.h"
21#include "llvm/Target/TargetInstrInfo.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000022#include "llvm/Support/Debug.h"
Misha Brukman6a90f822004-08-02 14:02:21 +000023#include <cstdlib>
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +000024#include <algorithm>
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +000025using namespace llvm;
26
27MSchedGraphNode::MSchedGraphNode(const MachineInstr* inst,
Tanya Lattner28e5eab2004-11-28 23:36:15 +000028 MSchedGraph *graph, unsigned idx,
Tanya Lattner4cffb582004-05-26 06:27:18 +000029 unsigned late, bool isBranch)
Tanya Lattner28e5eab2004-11-28 23:36:15 +000030 : Inst(inst), Parent(graph), index(idx), latency(late), isBranchInstr(isBranch) {
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +000031
32 //Add to the graph
33 graph->addNode(inst, this);
34}
35
Tanya Lattnerdb40cf12005-02-10 17:02:58 +000036MSchedGraphNode::MSchedGraphNode(const MSchedGraphNode &N)
37 : Predecessors(N.Predecessors), Successors(N.Successors) {
38
39 Inst = N.Inst;
40 Parent = N.Parent;
41 index = N.index;
42 latency = N.latency;
43 isBranchInstr = N.isBranchInstr;
44
45}
46
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +000047void MSchedGraphNode::print(std::ostream &os) const {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +000048 os << "MSchedGraphNode: Inst=" << *Inst << ", latency= " << latency << "\n";
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +000049}
50
51MSchedGraphEdge MSchedGraphNode::getInEdge(MSchedGraphNode *pred) {
52 //Loop over all the successors of our predecessor
53 //return the edge the corresponds to this in edge
Misha Brukman6a90f822004-08-02 14:02:21 +000054 for (MSchedGraphNode::succ_iterator I = pred->succ_begin(),
55 E = pred->succ_end(); I != E; ++I) {
56 if (*I == this)
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +000057 return I.getEdge();
58 }
59 assert(0 && "Should have found edge between this node and its predecessor!");
Misha Brukman6a90f822004-08-02 14:02:21 +000060 abort();
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +000061}
62
Tanya Lattnerdb40cf12005-02-10 17:02:58 +000063unsigned MSchedGraphNode::getIteDiff(MSchedGraphNode *succ) {
64 for(std::vector<MSchedGraphEdge>::iterator I = Successors.begin(), E = Successors.end();
65 I != E; ++I) {
66 if(I->getDest() == succ)
67 return I->getIteDiff();
68 }
69 return 0;
70}
71
72
Tanya Lattner73e3e2e2004-05-08 16:12:10 +000073unsigned MSchedGraphNode::getInEdgeNum(MSchedGraphNode *pred) {
74 //Loop over all the successors of our predecessor
75 //return the edge the corresponds to this in edge
76 int count = 0;
77 for(MSchedGraphNode::succ_iterator I = pred->succ_begin(), E = pred->succ_end();
78 I != E; ++I) {
79 if(*I == this)
80 return count;
81 count++;
82 }
83 assert(0 && "Should have found edge between this node and its predecessor!");
84 abort();
85}
86bool MSchedGraphNode::isSuccessor(MSchedGraphNode *succ) {
87 for(succ_iterator I = succ_begin(), E = succ_end(); I != E; ++I)
88 if(*I == succ)
89 return true;
90 return false;
91}
92
93
94bool MSchedGraphNode::isPredecessor(MSchedGraphNode *pred) {
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +000095 if(std::find( Predecessors.begin(), Predecessors.end(), pred) != Predecessors.end())
Tanya Lattner73e3e2e2004-05-08 16:12:10 +000096 return true;
97 else
98 return false;
99}
100
101
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000102void MSchedGraph::addNode(const MachineInstr *MI,
103 MSchedGraphNode *node) {
104
105 //Make sure node does not already exist
106 assert(GraphMap.find(MI) == GraphMap.end()
107 && "New MSchedGraphNode already exists for this instruction");
108
109 GraphMap[MI] = node;
110}
111
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000112void MSchedGraph::deleteNode(MSchedGraphNode *node) {
113
114 //Delete the edge to this node from all predecessors
Tanya Lattnerdb1680b2005-02-16 04:00:59 +0000115 while(node->pred_size() > 0) {
116 //DEBUG(std::cerr << "Delete edge from: " << **P << " to " << *node << "\n");
117 MSchedGraphNode *pred = *(node->pred_begin());
118 pred->deleteSuccessor(node);
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000119 }
Tanya Lattnerdb1680b2005-02-16 04:00:59 +0000120
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000121 //Remove this node from the graph
122 GraphMap.erase(node->getInst());
123
124}
125
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000126MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ)
127 : BB(bb), Target(targ) {
128
129 //Make sure BB is not null,
130 assert(BB != NULL && "Basic Block is null");
131
Tanya Lattner420025b2004-10-10 22:44:35 +0000132 //DEBUG(std::cerr << "Constructing graph for " << bb << "\n");
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000133
134 //Create nodes and edges for this BB
135 buildNodesAndEdges();
136}
137
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000138MSchedGraph::MSchedGraph(const MSchedGraph &G, std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes)
139 : BB(G.BB), Target(G.Target) {
140
141 std::map<MSchedGraphNode*, MSchedGraphNode*> oldToNew;
142 //Copy all nodes
143 for(MSchedGraph::const_iterator N = G.GraphMap.begin(), NE = G.GraphMap.end();
144 N != NE; ++N) {
145 MSchedGraphNode *newNode = new MSchedGraphNode(*(N->second));
146 oldToNew[&*(N->second)] = newNode;
147 newNodes[newNode] = &*(N->second);
148 GraphMap[&*(N->first)] = newNode;
149 }
150
151 //Loop over nodes and update edges to point to new nodes
152 for(MSchedGraph::iterator N = GraphMap.begin(), NE = GraphMap.end(); N != NE; ++N) {
153
154 //Get the node we are dealing with
155 MSchedGraphNode *node = &*(N->second);
156
157 node->setParent(this);
158
159 //Loop over nodes successors and predecessors and update to the new nodes
160 for(unsigned i = 0; i < node->pred_size(); ++i) {
161 node->setPredecessor(i, oldToNew[node->getPredecessor(i)]);
162 }
163
164 for(unsigned i = 0; i < node->succ_size(); ++i) {
165 MSchedGraphEdge *edge = node->getSuccessor(i);
166 MSchedGraphNode *oldDest = edge->getDest();
167 edge->setDest(oldToNew[oldDest]);
168 }
169 }
170}
171
172
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000173MSchedGraph::~MSchedGraph () {
174 for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end(); I != E; ++I)
175 delete I->second;
176}
177
178void MSchedGraph::buildNodesAndEdges() {
179
180 //Get Machine target information for calculating latency
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000181 const TargetInstrInfo *MTI = Target.getInstrInfo();
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000182
183 std::vector<MSchedGraphNode*> memInstructions;
184 std::map<int, std::vector<OpIndexNodePair> > regNumtoNodeMap;
185 std::map<const Value*, std::vector<OpIndexNodePair> > valuetoNodeMap;
186
187 //Save PHI instructions to deal with later
188 std::vector<const MachineInstr*> phiInstrs;
Tanya Lattner28e5eab2004-11-28 23:36:15 +0000189 unsigned index = 0;
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000190
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000191 //Loop over instructions in MBB and add nodes and edges
192 for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end(); MI != e; ++MI) {
193 //Get each instruction of machine basic block, get the delay
194 //using the op code, create a new node for it, and add to the
195 //graph.
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000196
Tanya Lattner4cffb582004-05-26 06:27:18 +0000197 MachineOpCode opCode = MI->getOpcode();
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000198 int delay;
199
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000200#if 0 // FIXME: LOOK INTO THIS
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000201 //Check if subsequent instructions can be issued before
202 //the result is ready, if so use min delay.
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000203 if(MTI->hasResultInterlock(MIopCode))
204 delay = MTI->minLatency(MIopCode);
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000205 else
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000206#endif
Tanya Lattner4cffb582004-05-26 06:27:18 +0000207 //Get delay
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000208 delay = MTI->maxLatency(opCode);
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000209
210 //Create new node for this machine instruction and add to the graph.
211 //Create only if not a nop
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000212 if(MTI->isNop(opCode))
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000213 continue;
214
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000215 //Sparc BE does not use PHI opcode, so assert on this case
216 assert(opCode != TargetInstrInfo::PHI && "Did not expect PHI opcode");
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000217
Tanya Lattner4cffb582004-05-26 06:27:18 +0000218 bool isBranch = false;
219
220 //We want to flag the branch node to treat it special
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000221 if(MTI->isBranch(opCode))
Tanya Lattner4cffb582004-05-26 06:27:18 +0000222 isBranch = true;
223
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000224 //Node is created and added to the graph automatically
Tanya Lattner28e5eab2004-11-28 23:36:15 +0000225 MSchedGraphNode *node = new MSchedGraphNode(MI, this, index, delay, isBranch);
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000226
227 DEBUG(std::cerr << "Created Node: " << *node << "\n");
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000228
Tanya Lattner4cffb582004-05-26 06:27:18 +0000229 //Check OpCode to keep track of memory operations to add memory dependencies later.
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000230 if(MTI->isLoad(opCode) || MTI->isStore(opCode))
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000231 memInstructions.push_back(node);
232
233 //Loop over all operands, and put them into the register number to
234 //graph node map for determining dependencies
235 //If an operands is a use/def, we have an anti dependence to itself
236 for(unsigned i=0; i < MI->getNumOperands(); ++i) {
237 //Get Operand
238 const MachineOperand &mOp = MI->getOperand(i);
239
Tanya Lattner4cffb582004-05-26 06:27:18 +0000240 //Check if it has an allocated register
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000241 if(mOp.hasAllocatedReg()) {
242 int regNum = mOp.getReg();
Tanya Lattner4cffb582004-05-26 06:27:18 +0000243
244 if(regNum != SparcV9::g0) {
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000245 //Put into our map
246 regNumtoNodeMap[regNum].push_back(std::make_pair(i, node));
Tanya Lattner4cffb582004-05-26 06:27:18 +0000247 }
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000248 continue;
249 }
250
251
252 //Add virtual registers dependencies
253 //Check if any exist in the value map already and create dependencies
254 //between them.
255 if(mOp.getType() == MachineOperand::MO_VirtualRegister || mOp.getType() == MachineOperand::MO_CCRegister) {
256
257 //Make sure virtual register value is not null
258 assert((mOp.getVRegValue() != NULL) && "Null value is defined");
259
260 //Check if this is a read operation in a phi node, if so DO NOT PROCESS
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000261 if(mOp.isUse() && (opCode == TargetInstrInfo::PHI)) {
262 DEBUG(std::cerr << "Read Operation in a PHI node\n");
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000263 continue;
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000264 }
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000265
266
267 if (const Value* srcI = mOp.getVRegValue()) {
268
269 //Find value in the map
270 std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
271 = valuetoNodeMap.find(srcI);
272
273 //If there is something in the map already, add edges from
274 //those instructions
275 //to this one we are processing
276 if(V != valuetoNodeMap.end()) {
277 addValueEdges(V->second, node, mOp.isUse(), mOp.isDef());
278
279 //Add to value map
280 V->second.push_back(std::make_pair(i,node));
281 }
282 //Otherwise put it in the map
283 else
284 //Put into value map
285 valuetoNodeMap[mOp.getVRegValue()].push_back(std::make_pair(i, node));
286 }
287 }
288 }
Tanya Lattner28e5eab2004-11-28 23:36:15 +0000289 ++index;
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000290 }
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000291
292 //Loop over LLVM BB, examine phi instructions, and add them to our phiInstr list to process
293 const BasicBlock *llvm_bb = BB->getBasicBlock();
294 for(BasicBlock::const_iterator I = llvm_bb->begin(), E = llvm_bb->end(); I != E; ++I) {
295 if(const PHINode *PN = dyn_cast<PHINode>(I)) {
296 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(PN);
297 for (unsigned j = 0; j < tempMvec.size(); j++) {
298 DEBUG(std::cerr << "Inserting phi instr into map: " << *tempMvec[j] << "\n");
299 phiInstrs.push_back((MachineInstr*) tempMvec[j]);
300 }
301 }
302
303 }
304
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000305 addMemEdges(memInstructions);
306 addMachRegEdges(regNumtoNodeMap);
307
308 //Finally deal with PHI Nodes and Value*
309 for(std::vector<const MachineInstr*>::iterator I = phiInstrs.begin(), E = phiInstrs.end(); I != E; ++I) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000310
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000311 //Get Node for this instruction
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000312 std::map<const MachineInstr*, MSchedGraphNode*>::iterator X;
313 X = find(*I);
314
315 if(X == GraphMap.end())
316 continue;
317
318 MSchedGraphNode *node = X->second;
319
320 DEBUG(std::cerr << "Adding ite diff edges for node: " << *node << "\n");
321
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000322 //Loop over operands for this instruction and add value edges
323 for(unsigned i=0; i < (*I)->getNumOperands(); ++i) {
324 //Get Operand
325 const MachineOperand &mOp = (*I)->getOperand(i);
326 if((mOp.getType() == MachineOperand::MO_VirtualRegister || mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) {
327 //find the value in the map
328 if (const Value* srcI = mOp.getVRegValue()) {
329
330 //Find value in the map
331 std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
332 = valuetoNodeMap.find(srcI);
333
334 //If there is something in the map already, add edges from
335 //those instructions
336 //to this one we are processing
337 if(V != valuetoNodeMap.end()) {
338 addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), 1);
339 }
340 }
341 }
342 }
343 }
344}
345
346void MSchedGraph::addValueEdges(std::vector<OpIndexNodePair> &NodesInMap,
347 MSchedGraphNode *destNode, bool nodeIsUse,
348 bool nodeIsDef, int diff) {
349
350 for(std::vector<OpIndexNodePair>::iterator I = NodesInMap.begin(),
351 E = NodesInMap.end(); I != E; ++I) {
352
353 //Get node in vectors machine operand that is the same value as node
354 MSchedGraphNode *srcNode = I->second;
355 MachineOperand mOp = srcNode->getInst()->getOperand(I->first);
356
357 //Node is a Def, so add output dep.
358 if(nodeIsDef) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000359 if(mOp.isUse()) {
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000360 srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
361 MSchedGraphEdge::AntiDep, diff);
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000362 }
363 if(mOp.isDef()) {
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000364 srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
365 MSchedGraphEdge::OutputDep, diff);
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000366 }
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000367 }
368 if(nodeIsUse) {
369 if(mOp.isDef())
370 srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
371 MSchedGraphEdge::TrueDep, diff);
372 }
373 }
374}
375
376
377void MSchedGraph::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >& regNumtoNodeMap) {
378 //Loop over all machine registers in the map, and add dependencies
379 //between the instructions that use it
380 typedef std::map<int, std::vector<OpIndexNodePair> > regNodeMap;
381 for(regNodeMap::iterator I = regNumtoNodeMap.begin(); I != regNumtoNodeMap.end(); ++I) {
382 //Get the register number
383 int regNum = (*I).first;
384
385 //Get Vector of nodes that use this register
386 std::vector<OpIndexNodePair> Nodes = (*I).second;
387
388 //Loop over nodes and determine the dependence between the other
389 //nodes in the vector
390 for(unsigned i =0; i < Nodes.size(); ++i) {
391
392 //Get src node operator index that uses this machine register
393 int srcOpIndex = Nodes[i].first;
394
395 //Get the actual src Node
396 MSchedGraphNode *srcNode = Nodes[i].second;
397
398 //Get Operand
399 const MachineOperand &srcMOp = srcNode->getInst()->getOperand(srcOpIndex);
400
401 bool srcIsUseandDef = srcMOp.isDef() && srcMOp.isUse();
402 bool srcIsUse = srcMOp.isUse() && !srcMOp.isDef();
403
404
405 //Look at all instructions after this in execution order
406 for(unsigned j=i+1; j < Nodes.size(); ++j) {
407
408 //Sink node is a write
409 if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
410 //Src only uses the register (read)
411 if(srcIsUse)
412 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
413 MSchedGraphEdge::AntiDep);
414
415 else if(srcIsUseandDef) {
416 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
417 MSchedGraphEdge::AntiDep);
418
419 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
420 MSchedGraphEdge::OutputDep);
421 }
422 else
423 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
424 MSchedGraphEdge::OutputDep);
425 }
426 //Dest node is a read
427 else {
428 if(!srcIsUse || srcIsUseandDef)
429 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
430 MSchedGraphEdge::TrueDep);
431 }
432
433 }
434
435 //Look at all the instructions before this one since machine registers
436 //could live across iterations.
437 for(unsigned j = 0; j < i; ++j) {
438 //Sink node is a write
439 if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
440 //Src only uses the register (read)
441 if(srcIsUse)
442 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
Tanya Lattner4cffb582004-05-26 06:27:18 +0000443 MSchedGraphEdge::AntiDep, 1);
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000444
445 else if(srcIsUseandDef) {
446 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
Tanya Lattner4cffb582004-05-26 06:27:18 +0000447 MSchedGraphEdge::AntiDep, 1);
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000448
449 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
Tanya Lattner4cffb582004-05-26 06:27:18 +0000450 MSchedGraphEdge::OutputDep, 1);
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000451 }
452 else
453 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
Tanya Lattner4cffb582004-05-26 06:27:18 +0000454 MSchedGraphEdge::OutputDep, 1);
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000455 }
456 //Dest node is a read
457 else {
458 if(!srcIsUse || srcIsUseandDef)
459 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
Tanya Lattner4cffb582004-05-26 06:27:18 +0000460 MSchedGraphEdge::TrueDep,1 );
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000461 }
462
463
464 }
465
466 }
467
468 }
469
470}
471
472void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst) {
473
474 //Get Target machine instruction info
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000475 const TargetInstrInfo *TMI = Target.getInstrInfo();
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000476
477 //Loop over all memory instructions in the vector
478 //Knowing that they are in execution, add true, anti, and output dependencies
479 for (unsigned srcIndex = 0; srcIndex < memInst.size(); ++srcIndex) {
480
481 //Get the machine opCode to determine type of memory instruction
482 MachineOpCode srcNodeOpCode = memInst[srcIndex]->getInst()->getOpcode();
483
484 //All instructions after this one in execution order have an iteration delay of 0
485 for(unsigned destIndex = srcIndex + 1; destIndex < memInst.size(); ++destIndex) {
486
487 //source is a Load, so add anti-dependencies (store after load)
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000488 if(TMI->isLoad(srcNodeOpCode))
489 if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode()))
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000490 memInst[srcIndex]->addOutEdge(memInst[destIndex],
491 MSchedGraphEdge::MemoryDep,
492 MSchedGraphEdge::AntiDep);
493
494 //If source is a store, add output and true dependencies
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000495 if(TMI->isStore(srcNodeOpCode)) {
496 if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode()))
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000497 memInst[srcIndex]->addOutEdge(memInst[destIndex],
498 MSchedGraphEdge::MemoryDep,
499 MSchedGraphEdge::OutputDep);
500 else
501 memInst[srcIndex]->addOutEdge(memInst[destIndex],
502 MSchedGraphEdge::MemoryDep,
503 MSchedGraphEdge::TrueDep);
504 }
505 }
506
507 //All instructions before the src in execution order have an iteration delay of 1
508 for(unsigned destIndex = 0; destIndex < srcIndex; ++destIndex) {
509 //source is a Load, so add anti-dependencies (store after load)
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000510 if(TMI->isLoad(srcNodeOpCode))
511 if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode()))
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000512 memInst[srcIndex]->addOutEdge(memInst[destIndex],
513 MSchedGraphEdge::MemoryDep,
514 MSchedGraphEdge::AntiDep, 1);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000515 if(TMI->isStore(srcNodeOpCode)) {
516 if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode()))
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000517 memInst[srcIndex]->addOutEdge(memInst[destIndex],
518 MSchedGraphEdge::MemoryDep,
519 MSchedGraphEdge::OutputDep, 1);
520 else
521 memInst[srcIndex]->addOutEdge(memInst[destIndex],
522 MSchedGraphEdge::MemoryDep,
523 MSchedGraphEdge::TrueDep, 1);
524 }
525
526 }
527
528 }
529}