blob: 376cbfdf09d2b5aecd667c4ec01a988ca388e20e [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
115 for(MSchedGraphNode::pred_iterator P = node->pred_begin(), PE = node->pred_end();
116 P != PE; ++P) {
117 (*P)->deleteSuccessor(node);
118 }
119
120 //Remove this node from the graph
121 GraphMap.erase(node->getInst());
122
123}
124
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000125MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ)
126 : BB(bb), Target(targ) {
127
128 //Make sure BB is not null,
129 assert(BB != NULL && "Basic Block is null");
130
Tanya Lattner420025b2004-10-10 22:44:35 +0000131 //DEBUG(std::cerr << "Constructing graph for " << bb << "\n");
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000132
133 //Create nodes and edges for this BB
134 buildNodesAndEdges();
135}
136
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000137MSchedGraph::MSchedGraph(const MSchedGraph &G, std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes)
138 : BB(G.BB), Target(G.Target) {
139
140 std::map<MSchedGraphNode*, MSchedGraphNode*> oldToNew;
141 //Copy all nodes
142 for(MSchedGraph::const_iterator N = G.GraphMap.begin(), NE = G.GraphMap.end();
143 N != NE; ++N) {
144 MSchedGraphNode *newNode = new MSchedGraphNode(*(N->second));
145 oldToNew[&*(N->second)] = newNode;
146 newNodes[newNode] = &*(N->second);
147 GraphMap[&*(N->first)] = newNode;
148 }
149
150 //Loop over nodes and update edges to point to new nodes
151 for(MSchedGraph::iterator N = GraphMap.begin(), NE = GraphMap.end(); N != NE; ++N) {
152
153 //Get the node we are dealing with
154 MSchedGraphNode *node = &*(N->second);
155
156 node->setParent(this);
157
158 //Loop over nodes successors and predecessors and update to the new nodes
159 for(unsigned i = 0; i < node->pred_size(); ++i) {
160 node->setPredecessor(i, oldToNew[node->getPredecessor(i)]);
161 }
162
163 for(unsigned i = 0; i < node->succ_size(); ++i) {
164 MSchedGraphEdge *edge = node->getSuccessor(i);
165 MSchedGraphNode *oldDest = edge->getDest();
166 edge->setDest(oldToNew[oldDest]);
167 }
168 }
169}
170
171
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000172MSchedGraph::~MSchedGraph () {
173 for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end(); I != E; ++I)
174 delete I->second;
175}
176
177void MSchedGraph::buildNodesAndEdges() {
178
179 //Get Machine target information for calculating latency
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000180 const TargetInstrInfo *MTI = Target.getInstrInfo();
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000181
182 std::vector<MSchedGraphNode*> memInstructions;
183 std::map<int, std::vector<OpIndexNodePair> > regNumtoNodeMap;
184 std::map<const Value*, std::vector<OpIndexNodePair> > valuetoNodeMap;
185
186 //Save PHI instructions to deal with later
187 std::vector<const MachineInstr*> phiInstrs;
Tanya Lattner28e5eab2004-11-28 23:36:15 +0000188 unsigned index = 0;
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000189
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000190 //Loop over instructions in MBB and add nodes and edges
191 for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end(); MI != e; ++MI) {
192 //Get each instruction of machine basic block, get the delay
193 //using the op code, create a new node for it, and add to the
194 //graph.
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000195
Tanya Lattner4cffb582004-05-26 06:27:18 +0000196 MachineOpCode opCode = MI->getOpcode();
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000197 int delay;
198
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000199#if 0 // FIXME: LOOK INTO THIS
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000200 //Check if subsequent instructions can be issued before
201 //the result is ready, if so use min delay.
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000202 if(MTI->hasResultInterlock(MIopCode))
203 delay = MTI->minLatency(MIopCode);
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000204 else
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000205#endif
Tanya Lattner4cffb582004-05-26 06:27:18 +0000206 //Get delay
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000207 delay = MTI->maxLatency(opCode);
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000208
209 //Create new node for this machine instruction and add to the graph.
210 //Create only if not a nop
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000211 if(MTI->isNop(opCode))
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000212 continue;
213
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000214 //Sparc BE does not use PHI opcode, so assert on this case
215 assert(opCode != TargetInstrInfo::PHI && "Did not expect PHI opcode");
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000216
Tanya Lattner4cffb582004-05-26 06:27:18 +0000217 bool isBranch = false;
218
219 //We want to flag the branch node to treat it special
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000220 if(MTI->isBranch(opCode))
Tanya Lattner4cffb582004-05-26 06:27:18 +0000221 isBranch = true;
222
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000223 //Node is created and added to the graph automatically
Tanya Lattner28e5eab2004-11-28 23:36:15 +0000224 MSchedGraphNode *node = new MSchedGraphNode(MI, this, index, delay, isBranch);
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000225
226 DEBUG(std::cerr << "Created Node: " << *node << "\n");
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000227
Tanya Lattner4cffb582004-05-26 06:27:18 +0000228 //Check OpCode to keep track of memory operations to add memory dependencies later.
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000229 if(MTI->isLoad(opCode) || MTI->isStore(opCode))
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000230 memInstructions.push_back(node);
231
232 //Loop over all operands, and put them into the register number to
233 //graph node map for determining dependencies
234 //If an operands is a use/def, we have an anti dependence to itself
235 for(unsigned i=0; i < MI->getNumOperands(); ++i) {
236 //Get Operand
237 const MachineOperand &mOp = MI->getOperand(i);
238
Tanya Lattner4cffb582004-05-26 06:27:18 +0000239 //Check if it has an allocated register
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000240 if(mOp.hasAllocatedReg()) {
241 int regNum = mOp.getReg();
Tanya Lattner4cffb582004-05-26 06:27:18 +0000242
243 if(regNum != SparcV9::g0) {
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000244 //Put into our map
245 regNumtoNodeMap[regNum].push_back(std::make_pair(i, node));
Tanya Lattner4cffb582004-05-26 06:27:18 +0000246 }
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000247 continue;
248 }
249
250
251 //Add virtual registers dependencies
252 //Check if any exist in the value map already and create dependencies
253 //between them.
254 if(mOp.getType() == MachineOperand::MO_VirtualRegister || mOp.getType() == MachineOperand::MO_CCRegister) {
255
256 //Make sure virtual register value is not null
257 assert((mOp.getVRegValue() != NULL) && "Null value is defined");
258
259 //Check if this is a read operation in a phi node, if so DO NOT PROCESS
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000260 if(mOp.isUse() && (opCode == TargetInstrInfo::PHI)) {
261 DEBUG(std::cerr << "Read Operation in a PHI node\n");
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000262 continue;
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000263 }
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000264
265
266 if (const Value* srcI = mOp.getVRegValue()) {
267
268 //Find value in the map
269 std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
270 = valuetoNodeMap.find(srcI);
271
272 //If there is something in the map already, add edges from
273 //those instructions
274 //to this one we are processing
275 if(V != valuetoNodeMap.end()) {
276 addValueEdges(V->second, node, mOp.isUse(), mOp.isDef());
277
278 //Add to value map
279 V->second.push_back(std::make_pair(i,node));
280 }
281 //Otherwise put it in the map
282 else
283 //Put into value map
284 valuetoNodeMap[mOp.getVRegValue()].push_back(std::make_pair(i, node));
285 }
286 }
287 }
Tanya Lattner28e5eab2004-11-28 23:36:15 +0000288 ++index;
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000289 }
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000290
291 //Loop over LLVM BB, examine phi instructions, and add them to our phiInstr list to process
292 const BasicBlock *llvm_bb = BB->getBasicBlock();
293 for(BasicBlock::const_iterator I = llvm_bb->begin(), E = llvm_bb->end(); I != E; ++I) {
294 if(const PHINode *PN = dyn_cast<PHINode>(I)) {
295 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(PN);
296 for (unsigned j = 0; j < tempMvec.size(); j++) {
297 DEBUG(std::cerr << "Inserting phi instr into map: " << *tempMvec[j] << "\n");
298 phiInstrs.push_back((MachineInstr*) tempMvec[j]);
299 }
300 }
301
302 }
303
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000304 addMemEdges(memInstructions);
305 addMachRegEdges(regNumtoNodeMap);
306
307 //Finally deal with PHI Nodes and Value*
308 for(std::vector<const MachineInstr*>::iterator I = phiInstrs.begin(), E = phiInstrs.end(); I != E; ++I) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000309
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000310 //Get Node for this instruction
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000311 std::map<const MachineInstr*, MSchedGraphNode*>::iterator X;
312 X = find(*I);
313
314 if(X == GraphMap.end())
315 continue;
316
317 MSchedGraphNode *node = X->second;
318
319 DEBUG(std::cerr << "Adding ite diff edges for node: " << *node << "\n");
320
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000321 //Loop over operands for this instruction and add value edges
322 for(unsigned i=0; i < (*I)->getNumOperands(); ++i) {
323 //Get Operand
324 const MachineOperand &mOp = (*I)->getOperand(i);
325 if((mOp.getType() == MachineOperand::MO_VirtualRegister || mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) {
326 //find the value in the map
327 if (const Value* srcI = mOp.getVRegValue()) {
328
329 //Find value in the map
330 std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
331 = valuetoNodeMap.find(srcI);
332
333 //If there is something in the map already, add edges from
334 //those instructions
335 //to this one we are processing
336 if(V != valuetoNodeMap.end()) {
337 addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), 1);
338 }
339 }
340 }
341 }
342 }
343}
344
345void MSchedGraph::addValueEdges(std::vector<OpIndexNodePair> &NodesInMap,
346 MSchedGraphNode *destNode, bool nodeIsUse,
347 bool nodeIsDef, int diff) {
348
349 for(std::vector<OpIndexNodePair>::iterator I = NodesInMap.begin(),
350 E = NodesInMap.end(); I != E; ++I) {
351
352 //Get node in vectors machine operand that is the same value as node
353 MSchedGraphNode *srcNode = I->second;
354 MachineOperand mOp = srcNode->getInst()->getOperand(I->first);
355
356 //Node is a Def, so add output dep.
357 if(nodeIsDef) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000358 if(mOp.isUse()) {
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000359 srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
360 MSchedGraphEdge::AntiDep, diff);
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000361 }
362 if(mOp.isDef()) {
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000363 srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
364 MSchedGraphEdge::OutputDep, diff);
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000365 }
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000366 }
367 if(nodeIsUse) {
368 if(mOp.isDef())
369 srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
370 MSchedGraphEdge::TrueDep, diff);
371 }
372 }
373}
374
375
376void MSchedGraph::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >& regNumtoNodeMap) {
377 //Loop over all machine registers in the map, and add dependencies
378 //between the instructions that use it
379 typedef std::map<int, std::vector<OpIndexNodePair> > regNodeMap;
380 for(regNodeMap::iterator I = regNumtoNodeMap.begin(); I != regNumtoNodeMap.end(); ++I) {
381 //Get the register number
382 int regNum = (*I).first;
383
384 //Get Vector of nodes that use this register
385 std::vector<OpIndexNodePair> Nodes = (*I).second;
386
387 //Loop over nodes and determine the dependence between the other
388 //nodes in the vector
389 for(unsigned i =0; i < Nodes.size(); ++i) {
390
391 //Get src node operator index that uses this machine register
392 int srcOpIndex = Nodes[i].first;
393
394 //Get the actual src Node
395 MSchedGraphNode *srcNode = Nodes[i].second;
396
397 //Get Operand
398 const MachineOperand &srcMOp = srcNode->getInst()->getOperand(srcOpIndex);
399
400 bool srcIsUseandDef = srcMOp.isDef() && srcMOp.isUse();
401 bool srcIsUse = srcMOp.isUse() && !srcMOp.isDef();
402
403
404 //Look at all instructions after this in execution order
405 for(unsigned j=i+1; j < Nodes.size(); ++j) {
406
407 //Sink node is a write
408 if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
409 //Src only uses the register (read)
410 if(srcIsUse)
411 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
412 MSchedGraphEdge::AntiDep);
413
414 else if(srcIsUseandDef) {
415 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
416 MSchedGraphEdge::AntiDep);
417
418 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
419 MSchedGraphEdge::OutputDep);
420 }
421 else
422 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
423 MSchedGraphEdge::OutputDep);
424 }
425 //Dest node is a read
426 else {
427 if(!srcIsUse || srcIsUseandDef)
428 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
429 MSchedGraphEdge::TrueDep);
430 }
431
432 }
433
434 //Look at all the instructions before this one since machine registers
435 //could live across iterations.
436 for(unsigned j = 0; j < i; ++j) {
437 //Sink node is a write
438 if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
439 //Src only uses the register (read)
440 if(srcIsUse)
441 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
Tanya Lattner4cffb582004-05-26 06:27:18 +0000442 MSchedGraphEdge::AntiDep, 1);
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000443
444 else if(srcIsUseandDef) {
445 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
Tanya Lattner4cffb582004-05-26 06:27:18 +0000446 MSchedGraphEdge::AntiDep, 1);
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000447
448 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
Tanya Lattner4cffb582004-05-26 06:27:18 +0000449 MSchedGraphEdge::OutputDep, 1);
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000450 }
451 else
452 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
Tanya Lattner4cffb582004-05-26 06:27:18 +0000453 MSchedGraphEdge::OutputDep, 1);
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000454 }
455 //Dest node is a read
456 else {
457 if(!srcIsUse || srcIsUseandDef)
458 srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
Tanya Lattner4cffb582004-05-26 06:27:18 +0000459 MSchedGraphEdge::TrueDep,1 );
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000460 }
461
462
463 }
464
465 }
466
467 }
468
469}
470
471void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst) {
472
473 //Get Target machine instruction info
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000474 const TargetInstrInfo *TMI = Target.getInstrInfo();
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000475
476 //Loop over all memory instructions in the vector
477 //Knowing that they are in execution, add true, anti, and output dependencies
478 for (unsigned srcIndex = 0; srcIndex < memInst.size(); ++srcIndex) {
479
480 //Get the machine opCode to determine type of memory instruction
481 MachineOpCode srcNodeOpCode = memInst[srcIndex]->getInst()->getOpcode();
482
483 //All instructions after this one in execution order have an iteration delay of 0
484 for(unsigned destIndex = srcIndex + 1; destIndex < memInst.size(); ++destIndex) {
485
486 //source is a Load, so add anti-dependencies (store after load)
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000487 if(TMI->isLoad(srcNodeOpCode))
488 if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode()))
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000489 memInst[srcIndex]->addOutEdge(memInst[destIndex],
490 MSchedGraphEdge::MemoryDep,
491 MSchedGraphEdge::AntiDep);
492
493 //If source is a store, add output and true dependencies
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000494 if(TMI->isStore(srcNodeOpCode)) {
495 if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode()))
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000496 memInst[srcIndex]->addOutEdge(memInst[destIndex],
497 MSchedGraphEdge::MemoryDep,
498 MSchedGraphEdge::OutputDep);
499 else
500 memInst[srcIndex]->addOutEdge(memInst[destIndex],
501 MSchedGraphEdge::MemoryDep,
502 MSchedGraphEdge::TrueDep);
503 }
504 }
505
506 //All instructions before the src in execution order have an iteration delay of 1
507 for(unsigned destIndex = 0; destIndex < srcIndex; ++destIndex) {
508 //source is a Load, so add anti-dependencies (store after load)
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000509 if(TMI->isLoad(srcNodeOpCode))
510 if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode()))
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000511 memInst[srcIndex]->addOutEdge(memInst[destIndex],
512 MSchedGraphEdge::MemoryDep,
513 MSchedGraphEdge::AntiDep, 1);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000514 if(TMI->isStore(srcNodeOpCode)) {
515 if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode()))
Tanya Lattner9b3cbdb2004-03-01 02:50:57 +0000516 memInst[srcIndex]->addOutEdge(memInst[destIndex],
517 MSchedGraphEdge::MemoryDep,
518 MSchedGraphEdge::OutputDep, 1);
519 else
520 memInst[srcIndex]->addOutEdge(memInst[destIndex],
521 MSchedGraphEdge::MemoryDep,
522 MSchedGraphEdge::TrueDep, 1);
523 }
524
525 }
526
527 }
528}