blob: 21d11bec2e06ed6db65dacccef7cbd7d53169773 [file] [log] [blame]
Chris Lattner44d2c352003-10-13 03:32:08 +00001//===- RetracePath.cpp ----------------------------------------------------===//
John Criswell482202a2003-10-20 19:43:21 +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//===----------------------------------------------------------------------===//
Anand Shuklaea77a492002-09-18 03:55:26 +00009//
10// Retraces a path of BasicBlock, given a path number and a graph!
11//
12//===----------------------------------------------------------------------===//
13
Anand Shuklaea77a492002-09-18 03:55:26 +000014#include "llvm/Module.h"
Anand Shuklaea77a492002-09-18 03:55:26 +000015#include "llvm/iTerminators.h"
Anand Shuklaea77a492002-09-18 03:55:26 +000016#include "llvm/iOther.h"
Chris Lattner2f04a0d2003-01-14 22:33:56 +000017#include "llvm/Support/CFG.h"
18#include "Graph.h"
Reid Spencereb04d9b2004-07-04 12:19:56 +000019#include <iostream>
Anand Shuklaea77a492002-09-18 03:55:26 +000020
21using std::vector;
22using std::map;
23using std::cerr;
24
Brian Gaeke960707c2003-11-11 22:41:34 +000025namespace llvm {
26
Anand Shuklaea77a492002-09-18 03:55:26 +000027//Routines to get the path trace!
28
Anand Shuklaf8c09ee2003-02-14 20:41:53 +000029void getPathFrmNode(Node *n, vector<BasicBlock*> &vBB, int pathNo, Graph &g,
Anand Shuklaea77a492002-09-18 03:55:26 +000030 vector<Edge> &stDummy, vector<Edge> &exDummy,
31 vector<Edge> &be,
32 double strand){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +000033 Graph::nodeList &nlist = g.getNodeList(n);
Anand Shuklaea77a492002-09-18 03:55:26 +000034
Anand Shuklaf8c09ee2003-02-14 20:41:53 +000035 //printGraph(g);
36 //std::cerr<<"Path No: "<<pathNo<<"\n";
Anand Shuklaea77a492002-09-18 03:55:26 +000037 int maxCount=-9999999;
38 bool isStart=false;
39
40 if(*n==*g.getRoot())//its root: so first node of path
41 isStart=true;
42
43 double edgeRnd=0;
44 Node *nextRoot=n;
Anand Shuklaf8c09ee2003-02-14 20:41:53 +000045 for(Graph::nodeList::iterator NLI = nlist.begin(), NLE=nlist.end(); NLI!=NLE;
Anand Shuklaea77a492002-09-18 03:55:26 +000046 ++NLI){
47 if(NLI->weight>maxCount && NLI->weight<=pathNo){
48 maxCount=NLI->weight;
49 nextRoot=NLI->element;
50 edgeRnd=NLI->randId;
51 if(isStart)
52 strand=NLI->randId;
53 }
54 }
55
56 if(!isStart)
57 assert(strand!=-1 && "strand not assigned!");
58
59 assert(!(*nextRoot==*n && pathNo>0) && "No more BBs to go");
60 assert(!(*nextRoot==*g.getExit() && pathNo-maxCount!=0) && "Reached exit");
61
62 vBB.push_back(n->getElement());
63
64 if(pathNo-maxCount==0 && *nextRoot==*g.getExit()){
65
66 //look for strnd and edgeRnd now:
67 bool has1=false, has2=false;
68 //check if exit has it
69 for(vector<Edge>::iterator VI=exDummy.begin(), VE=exDummy.end(); VI!=VE;
70 ++VI){
71 if(VI->getRandId()==edgeRnd){
72 has2=true;
73 break;
74 }
75 }
76
77 //check if start has it
78 for(vector<Edge>::iterator VI=stDummy.begin(), VE=stDummy.end(); VI!=VE;
79 ++VI){
80 if(VI->getRandId()==strand){
81 has1=true;
82 break;
83 }
84 }
85
86 if(has1){
87 //find backedge with endpoint vBB[1]
88 for(vector<Edge>::iterator VI=be.begin(), VE=be.end(); VI!=VE; ++VI){
89 assert(vBB.size()>0 && "vector too small");
90 if( VI->getSecond()->getElement() == vBB[1] ){
91 //vBB[0]=VI->getFirst()->getElement();
92 vBB.erase(vBB.begin());
93 break;
94 }
95 }
96 }
97
98 if(has2){
99 //find backedge with startpoint vBB[vBB.size()-1]
100 for(vector<Edge>::iterator VI=be.begin(), VE=be.end(); VI!=VE; ++VI){
101 assert(vBB.size()>0 && "vector too small");
102 if( VI->getFirst()->getElement() == vBB[vBB.size()-1] &&
103 VI->getSecond()->getElement() == vBB[0]){
104 //vBB.push_back(VI->getSecond()->getElement());
105 break;
106 }
107 }
108 }
109 else
110 vBB.push_back(nextRoot->getElement());
111
112 return;
113 }
114
115 assert(pathNo-maxCount>=0);
116
117 return getPathFrmNode(nextRoot, vBB, pathNo-maxCount, g, stDummy,
118 exDummy, be, strand);
119}
120
121
122static Node *findBB(std::vector<Node *> &st, BasicBlock *BB){
123 for(std::vector<Node *>::iterator si=st.begin(); si!=st.end(); ++si){
124 if(((*si)->getElement())==BB){
125 return *si;
126 }
127 }
128 return NULL;
129}
130
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000131void getBBtrace(vector<BasicBlock *> &vBB, int pathNo, Function *M){//,
132 // vector<Instruction *> &instToErase){
Anand Shuklaea77a492002-09-18 03:55:26 +0000133 //step 1: create graph
134 //Transform the cfg s.t. we have just one exit node
135
136 std::vector<Node *> nodes;
137 std::vector<Edge> edges;
138 Node *tmp;
139 Node *exitNode=0, *startNode=0;
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000140
141 //Creat cfg just once for each function!
142 static std::map<Function *, Graph *> graphMap;
143
144 //get backedges, exit and start edges for the graphs and store them
Anand Shuklaea77a492002-09-18 03:55:26 +0000145 static std::map<Function *, vector<Edge> > stMap, exMap, beMap;
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000146 static std::map<Function *, Value *> pathReg; //path register
147
Anand Shuklaea77a492002-09-18 03:55:26 +0000148
149 if(!graphMap[M]){
150 BasicBlock *ExitNode = 0;
151 for (Function::iterator I = M->begin(), E = M->end(); I != E; ++I){
152 if (isa<ReturnInst>(I->getTerminator())) {
Chris Lattner889f6202003-04-23 16:37:45 +0000153 ExitNode = I;
Anand Shuklaea77a492002-09-18 03:55:26 +0000154 break;
155 }
156 }
157
158 assert(ExitNode!=0 && "exitnode not found");
159
160 //iterating over BBs and making graph
161 //The nodes must be uniquely identified:
162 //That is, no two nodes must hav same BB*
163
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000164 //keep a map for trigger basicblocks!
165 std::map<BasicBlock *, unsigned char> triggerBBs;
Anand Shuklaea77a492002-09-18 03:55:26 +0000166 //First enter just nodes: later enter edges
167 for(Function::iterator BB = M->begin(), BE=M->end(); BB != BE; ++BB){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000168 bool cont = false;
169
170 if(BB->size()==3 || BB->size() ==2){
171 for(BasicBlock::iterator II = BB->begin(), IE = BB->end();
172 II != IE; ++II){
Chris Lattner889f6202003-04-23 16:37:45 +0000173 if(CallInst *callInst = dyn_cast<CallInst>(II)){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000174 //std::cerr<<*callInst;
175 Function *calledFunction = callInst->getCalledFunction();
176 if(calledFunction && calledFunction->getName() == "trigger"){
177 triggerBBs[BB] = 9;
178 cont = true;
179 //std::cerr<<"Found trigger!\n";
180 break;
181 }
182 }
Anand Shuklaea77a492002-09-18 03:55:26 +0000183 }
184 }
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000185
186 if(cont)
187 continue;
188
189 // const Instruction *inst = BB->getInstList().begin();
190 // if(isa<CallInst>(inst)){
191 // Instruction *ii1 = BB->getInstList().begin();
192 // CallInst *callInst = dyn_cast<CallInst>(ii1);
193 // if(callInst->getCalledFunction()->getName()=="trigger")
194 // continue;
195 // }
196
Anand Shuklaea77a492002-09-18 03:55:26 +0000197 Node *nd=new Node(BB);
198 nodes.push_back(nd);
199 if(&*BB==ExitNode)
200 exitNode=nd;
201 if(&*BB==&M->front())
202 startNode=nd;
203 }
204
205 assert(exitNode!=0 && startNode!=0 && "Start or exit not found!");
206
207 for (Function::iterator BB = M->begin(), BE=M->end(); BB != BE; ++BB){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000208 if(triggerBBs[BB] == 9)
209 continue;
210
211 //if(BB->size()==3)
Chris Lattner889f6202003-04-23 16:37:45 +0000212 //if(CallInst *callInst = dyn_cast<CallInst>(BB->getInstList().begin()))
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000213 //if(callInst->getCalledFunction()->getName() == "trigger")
214 //continue;
215
216 // if(BB->size()==2){
217 // const Instruction *inst = BB->getInstList().begin();
218 // if(isa<CallInst>(inst)){
219 // Instruction *ii1 = BB->getInstList().begin();
220 // CallInst *callInst = dyn_cast<CallInst>(ii1);
221 // if(callInst->getCalledFunction()->getName()=="trigger")
222 // continue;
223 // }
224 // }
225
Anand Shuklaea77a492002-09-18 03:55:26 +0000226 Node *nd=findBB(nodes, BB);
227 assert(nd && "No node for this edge!");
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000228
Chris Lattnera9400952003-09-24 22:06:25 +0000229 for(succ_iterator s=succ_begin(BB), se=succ_end(BB); s!=se; ++s){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000230
231 if(triggerBBs[*s] == 9){
232 //if(!pathReg[M]){ //Get the path register for this!
233 //if(BB->size()>8)
Chris Lattner889f6202003-04-23 16:37:45 +0000234 // if(LoadInst *ldInst = dyn_cast<LoadInst>(BB->getInstList().begin()))
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000235 // pathReg[M] = ldInst->getPointerOperand();
236 //}
237 continue;
Anand Shuklaea77a492002-09-18 03:55:26 +0000238 }
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000239 //if((*s)->size()==3)
240 //if(CallInst *callInst =
Chris Lattner889f6202003-04-23 16:37:45 +0000241 // dyn_cast<CallInst>((*s)->getInstList().begin()))
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000242 // if(callInst->getCalledFunction()->getName() == "trigger")
243 // continue;
244
245 // if((*s)->size()==2){
246 // const Instruction *inst = (*s)->getInstList().begin();
247 // if(isa<CallInst>(inst)){
248 // Instruction *ii1 = (*s)->getInstList().begin();
249 // CallInst *callInst = dyn_cast<CallInst>(ii1);
250 // if(callInst->getCalledFunction()->getName()=="trigger")
251 // continue;
252 // }
253 // }
254
255 Node *nd2 = findBB(nodes,*s);
Anand Shuklaea77a492002-09-18 03:55:26 +0000256 assert(nd2 && "No node for this edge!");
257 Edge ed(nd,nd2,0);
258 edges.push_back(ed);
259 }
260 }
261
262 graphMap[M]= new Graph(nodes,edges, startNode, exitNode);
263
264 Graph *g = graphMap[M];
265
266 if (M->size() <= 1) return; //uninstrumented
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000267
Anand Shuklaea77a492002-09-18 03:55:26 +0000268 //step 2: getBackEdges
269 //vector<Edge> be;
270 std::map<Node *, int> nodePriority;
271 g->getBackEdges(beMap[M], nodePriority);
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000272
Anand Shuklaea77a492002-09-18 03:55:26 +0000273 //step 3: add dummy edges
274 //vector<Edge> stDummy;
275 //vector<Edge> exDummy;
276 addDummyEdges(stMap[M], exMap[M], *g, beMap[M]);
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000277
Anand Shuklaea77a492002-09-18 03:55:26 +0000278 //step 4: value assgn to edges
279 int numPaths = valueAssignmentToEdges(*g, nodePriority, beMap[M]);
280 }
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000281
282
Anand Shuklaea77a492002-09-18 03:55:26 +0000283 //step 5: now travel from root, select max(edge) < pathNo,
284 //and go on until reach the exit
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000285 getPathFrmNode(graphMap[M]->getRoot(), vBB, pathNo, *graphMap[M],
286 stMap[M], exMap[M], beMap[M], -1);
287
288
289 //post process vBB to locate instructions to be erased
290 /*
291 if(pathReg[M]){
292 for(vector<BasicBlock *>::iterator VBI = vBB.begin(), VBE = vBB.end();
293 VBI != VBE; ++VBI){
294 for(BasicBlock::iterator BBI = (*VBI)->begin(), BBE = (*VBI)->end();
295 BBI != BBE; ++BBI){
Chris Lattner889f6202003-04-23 16:37:45 +0000296 if(LoadInst *ldInst = dyn_cast<LoadInst>(BBI)){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000297 if(pathReg[M] == ldInst->getPointerOperand())
298 instToErase.push_back(ldInst);
299 }
Chris Lattner889f6202003-04-23 16:37:45 +0000300 else if(StoreInst *stInst = dyn_cast<StoreInst>(BBI)){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000301 if(pathReg[M] == stInst->getPointerOperand())
302 instToErase.push_back(stInst);
303 }
304 }
305 }
306 }
307 */
Anand Shuklaea77a492002-09-18 03:55:26 +0000308}
Brian Gaeke960707c2003-11-11 22:41:34 +0000309
310} // End llvm namespace