blob: 8c343df8f690081d6e06bd3bdf6d64d4a1146772 [file] [log] [blame]
Chris Lattner44d2c352003-10-13 03:32:08 +00001//===- RetracePath.cpp ----------------------------------------------------===//
Misha Brukmanb1c93172005-04-21 23:48:37 +00002//
John Criswell482202a2003-10-20 19:43:21 +00003// 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.
Misha Brukmanb1c93172005-04-21 23:48:37 +00007//
John Criswell482202a2003-10-20 19:43:21 +00008//===----------------------------------------------------------------------===//
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"
Misha Brukman63b38bd2004-07-29 17:30:56 +000015#include "llvm/Instructions.h"
Chris Lattner2f04a0d2003-01-14 22:33:56 +000016#include "llvm/Support/CFG.h"
17#include "Graph.h"
Reid Spencereb04d9b2004-07-04 12:19:56 +000018#include <iostream>
Anand Shuklaea77a492002-09-18 03:55:26 +000019
20using std::vector;
21using std::map;
22using std::cerr;
23
Brian Gaeke960707c2003-11-11 22:41:34 +000024namespace llvm {
25
Anand Shuklaea77a492002-09-18 03:55:26 +000026//Routines to get the path trace!
27
Misha Brukmanb1c93172005-04-21 23:48:37 +000028void getPathFrmNode(Node *n, vector<BasicBlock*> &vBB, int pathNo, Graph &g,
Jeff Cohen82639852005-04-23 21:38:35 +000029 vector<Edge> &stDummy, vector<Edge> &exDummy,
30 vector<Edge> &be,
31 double strand){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +000032 Graph::nodeList &nlist = g.getNodeList(n);
Misha Brukmanb1c93172005-04-21 23:48:37 +000033
Anand Shuklaf8c09ee2003-02-14 20:41:53 +000034 //printGraph(g);
35 //std::cerr<<"Path No: "<<pathNo<<"\n";
Anand Shuklaea77a492002-09-18 03:55:26 +000036 int maxCount=-9999999;
37 bool isStart=false;
38
39 if(*n==*g.getRoot())//its root: so first node of path
40 isStart=true;
41
42 double edgeRnd=0;
43 Node *nextRoot=n;
Anand Shuklaf8c09ee2003-02-14 20:41:53 +000044 for(Graph::nodeList::iterator NLI = nlist.begin(), NLE=nlist.end(); NLI!=NLE;
Anand Shuklaea77a492002-09-18 03:55:26 +000045 ++NLI){
46 if(NLI->weight>maxCount && NLI->weight<=pathNo){
47 maxCount=NLI->weight;
48 nextRoot=NLI->element;
49 edgeRnd=NLI->randId;
50 if(isStart)
Jeff Cohen82639852005-04-23 21:38:35 +000051 strand=NLI->randId;
Anand Shuklaea77a492002-09-18 03:55:26 +000052 }
53 }
54
55 if(!isStart)
Misha Brukmanb1c93172005-04-21 23:48:37 +000056 assert(strand!=-1 && "strand not assigned!");
Anand Shuklaea77a492002-09-18 03:55:26 +000057
58 assert(!(*nextRoot==*n && pathNo>0) && "No more BBs to go");
59 assert(!(*nextRoot==*g.getExit() && pathNo-maxCount!=0) && "Reached exit");
60
61 vBB.push_back(n->getElement());
62
63 if(pathNo-maxCount==0 && *nextRoot==*g.getExit()){
64
65 //look for strnd and edgeRnd now:
66 bool has1=false, has2=false;
67 //check if exit has it
Misha Brukmanb1c93172005-04-21 23:48:37 +000068 for(vector<Edge>::iterator VI=exDummy.begin(), VE=exDummy.end(); VI!=VE;
Jeff Cohen82639852005-04-23 21:38:35 +000069 ++VI){
Anand Shuklaea77a492002-09-18 03:55:26 +000070 if(VI->getRandId()==edgeRnd){
Jeff Cohen82639852005-04-23 21:38:35 +000071 has2=true;
72 break;
Anand Shuklaea77a492002-09-18 03:55:26 +000073 }
74 }
75
76 //check if start has it
Misha Brukmanb1c93172005-04-21 23:48:37 +000077 for(vector<Edge>::iterator VI=stDummy.begin(), VE=stDummy.end(); VI!=VE;
Jeff Cohen82639852005-04-23 21:38:35 +000078 ++VI){
Anand Shuklaea77a492002-09-18 03:55:26 +000079 if(VI->getRandId()==strand){
Jeff Cohen82639852005-04-23 21:38:35 +000080 has1=true;
81 break;
Anand Shuklaea77a492002-09-18 03:55:26 +000082 }
83 }
84
85 if(has1){
86 //find backedge with endpoint vBB[1]
87 for(vector<Edge>::iterator VI=be.begin(), VE=be.end(); VI!=VE; ++VI){
Jeff Cohen82639852005-04-23 21:38:35 +000088 assert(vBB.size()>0 && "vector too small");
89 if( VI->getSecond()->getElement() == vBB[1] ){
90 //vBB[0]=VI->getFirst()->getElement();
Anand Shuklaea77a492002-09-18 03:55:26 +000091 vBB.erase(vBB.begin());
Jeff Cohen82639852005-04-23 21:38:35 +000092 break;
93 }
Anand Shuklaea77a492002-09-18 03:55:26 +000094 }
95 }
96
97 if(has2){
98 //find backedge with startpoint vBB[vBB.size()-1]
99 for(vector<Edge>::iterator VI=be.begin(), VE=be.end(); VI!=VE; ++VI){
Jeff Cohen82639852005-04-23 21:38:35 +0000100 assert(vBB.size()>0 && "vector too small");
101 if( VI->getFirst()->getElement() == vBB[vBB.size()-1] &&
Anand Shuklaea77a492002-09-18 03:55:26 +0000102 VI->getSecond()->getElement() == vBB[0]){
Jeff Cohen82639852005-04-23 21:38:35 +0000103 //vBB.push_back(VI->getSecond()->getElement());
104 break;
105 }
Anand Shuklaea77a492002-09-18 03:55:26 +0000106 }
107 }
Misha Brukmanb1c93172005-04-21 23:48:37 +0000108 else
Anand Shuklaea77a492002-09-18 03:55:26 +0000109 vBB.push_back(nextRoot->getElement());
Misha Brukmanb1c93172005-04-21 23:48:37 +0000110
Anand Shuklaea77a492002-09-18 03:55:26 +0000111 return;
112 }
113
114 assert(pathNo-maxCount>=0);
115
Misha Brukmanb1c93172005-04-21 23:48:37 +0000116 return getPathFrmNode(nextRoot, vBB, pathNo-maxCount, g, stDummy,
Jeff Cohen82639852005-04-23 21:38:35 +0000117 exDummy, be, strand);
Anand Shuklaea77a492002-09-18 03:55:26 +0000118}
119
120
121static Node *findBB(std::vector<Node *> &st, BasicBlock *BB){
122 for(std::vector<Node *>::iterator si=st.begin(); si!=st.end(); ++si){
123 if(((*si)->getElement())==BB){
124 return *si;
125 }
126 }
127 return NULL;
128}
129
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000130void getBBtrace(vector<BasicBlock *> &vBB, int pathNo, Function *M){//,
131 // vector<Instruction *> &instToErase){
Anand Shuklaea77a492002-09-18 03:55:26 +0000132 //step 1: create graph
133 //Transform the cfg s.t. we have just one exit node
Misha Brukmanb1c93172005-04-21 23:48:37 +0000134
Anand Shuklaea77a492002-09-18 03:55:26 +0000135 std::vector<Node *> nodes;
136 std::vector<Edge> edges;
Anand Shuklaea77a492002-09-18 03:55:26 +0000137 Node *exitNode=0, *startNode=0;
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000138
139 //Creat cfg just once for each function!
Misha Brukmanb1c93172005-04-21 23:48:37 +0000140 static std::map<Function *, Graph *> graphMap;
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000141
142 //get backedges, exit and start edges for the graphs and store them
Misha Brukmanb1c93172005-04-21 23:48:37 +0000143 static std::map<Function *, vector<Edge> > stMap, exMap, beMap;
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000144 static std::map<Function *, Value *> pathReg; //path register
145
Anand Shuklaea77a492002-09-18 03:55:26 +0000146
147 if(!graphMap[M]){
148 BasicBlock *ExitNode = 0;
149 for (Function::iterator I = M->begin(), E = M->end(); I != E; ++I){
150 if (isa<ReturnInst>(I->getTerminator())) {
Chris Lattner889f6202003-04-23 16:37:45 +0000151 ExitNode = I;
Anand Shuklaea77a492002-09-18 03:55:26 +0000152 break;
153 }
154 }
Misha Brukmanb1c93172005-04-21 23:48:37 +0000155
Anand Shuklaea77a492002-09-18 03:55:26 +0000156 assert(ExitNode!=0 && "exitnode not found");
157
Misha Brukmanb1c93172005-04-21 23:48:37 +0000158 //iterating over BBs and making graph
Anand Shuklaea77a492002-09-18 03:55:26 +0000159 //The nodes must be uniquely identified:
160 //That is, no two nodes must hav same BB*
Misha Brukmanb1c93172005-04-21 23:48:37 +0000161
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000162 //keep a map for trigger basicblocks!
163 std::map<BasicBlock *, unsigned char> triggerBBs;
Anand Shuklaea77a492002-09-18 03:55:26 +0000164 //First enter just nodes: later enter edges
165 for(Function::iterator BB = M->begin(), BE=M->end(); BB != BE; ++BB){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000166 bool cont = false;
Misha Brukmanb1c93172005-04-21 23:48:37 +0000167
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000168 if(BB->size()==3 || BB->size() ==2){
169 for(BasicBlock::iterator II = BB->begin(), IE = BB->end();
170 II != IE; ++II){
Chris Lattner889f6202003-04-23 16:37:45 +0000171 if(CallInst *callInst = dyn_cast<CallInst>(II)){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000172 //std::cerr<<*callInst;
173 Function *calledFunction = callInst->getCalledFunction();
174 if(calledFunction && calledFunction->getName() == "trigger"){
175 triggerBBs[BB] = 9;
176 cont = true;
177 //std::cerr<<"Found trigger!\n";
178 break;
179 }
180 }
Anand Shuklaea77a492002-09-18 03:55:26 +0000181 }
182 }
Misha Brukmanb1c93172005-04-21 23:48:37 +0000183
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000184 if(cont)
185 continue;
Misha Brukmanb1c93172005-04-21 23:48:37 +0000186
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000187 // const Instruction *inst = BB->getInstList().begin();
188 // if(isa<CallInst>(inst)){
189 // Instruction *ii1 = BB->getInstList().begin();
190 // CallInst *callInst = dyn_cast<CallInst>(ii1);
191 // if(callInst->getCalledFunction()->getName()=="trigger")
192 // continue;
193 // }
Misha Brukmanb1c93172005-04-21 23:48:37 +0000194
Anand Shuklaea77a492002-09-18 03:55:26 +0000195 Node *nd=new Node(BB);
Misha Brukmanb1c93172005-04-21 23:48:37 +0000196 nodes.push_back(nd);
Anand Shuklaea77a492002-09-18 03:55:26 +0000197 if(&*BB==ExitNode)
198 exitNode=nd;
199 if(&*BB==&M->front())
200 startNode=nd;
201 }
202
203 assert(exitNode!=0 && startNode!=0 && "Start or exit not found!");
Misha Brukmanb1c93172005-04-21 23:48:37 +0000204
Anand Shuklaea77a492002-09-18 03:55:26 +0000205 for (Function::iterator BB = M->begin(), BE=M->end(); BB != BE; ++BB){
Misha Brukmanb1c93172005-04-21 23:48:37 +0000206 if(triggerBBs[BB] == 9)
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000207 continue;
Misha Brukmanb1c93172005-04-21 23:48:37 +0000208
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000209 //if(BB->size()==3)
Chris Lattner889f6202003-04-23 16:37:45 +0000210 //if(CallInst *callInst = dyn_cast<CallInst>(BB->getInstList().begin()))
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000211 //if(callInst->getCalledFunction()->getName() == "trigger")
212 //continue;
Misha Brukmanb1c93172005-04-21 23:48:37 +0000213
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000214 // if(BB->size()==2){
215 // const Instruction *inst = BB->getInstList().begin();
216 // if(isa<CallInst>(inst)){
217 // Instruction *ii1 = BB->getInstList().begin();
218 // CallInst *callInst = dyn_cast<CallInst>(ii1);
219 // if(callInst->getCalledFunction()->getName()=="trigger")
220 // continue;
221 // }
222 // }
Misha Brukmanb1c93172005-04-21 23:48:37 +0000223
Anand Shuklaea77a492002-09-18 03:55:26 +0000224 Node *nd=findBB(nodes, BB);
225 assert(nd && "No node for this edge!");
Misha Brukmanb1c93172005-04-21 23:48:37 +0000226
Chris Lattnera9400952003-09-24 22:06:25 +0000227 for(succ_iterator s=succ_begin(BB), se=succ_end(BB); s!=se; ++s){
Misha Brukmanb1c93172005-04-21 23:48:37 +0000228
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000229 if(triggerBBs[*s] == 9){
230 //if(!pathReg[M]){ //Get the path register for this!
231 //if(BB->size()>8)
Chris Lattner889f6202003-04-23 16:37:45 +0000232 // if(LoadInst *ldInst = dyn_cast<LoadInst>(BB->getInstList().begin()))
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000233 // pathReg[M] = ldInst->getPointerOperand();
234 //}
235 continue;
Anand Shuklaea77a492002-09-18 03:55:26 +0000236 }
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000237 //if((*s)->size()==3)
Misha Brukmanb1c93172005-04-21 23:48:37 +0000238 //if(CallInst *callInst =
Chris Lattner889f6202003-04-23 16:37:45 +0000239 // dyn_cast<CallInst>((*s)->getInstList().begin()))
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000240 // if(callInst->getCalledFunction()->getName() == "trigger")
241 // continue;
Misha Brukmanb1c93172005-04-21 23:48:37 +0000242
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000243 // if((*s)->size()==2){
244 // const Instruction *inst = (*s)->getInstList().begin();
245 // if(isa<CallInst>(inst)){
246 // Instruction *ii1 = (*s)->getInstList().begin();
247 // CallInst *callInst = dyn_cast<CallInst>(ii1);
248 // if(callInst->getCalledFunction()->getName()=="trigger")
249 // continue;
250 // }
251 // }
Misha Brukmanb1c93172005-04-21 23:48:37 +0000252
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000253 Node *nd2 = findBB(nodes,*s);
Anand Shuklaea77a492002-09-18 03:55:26 +0000254 assert(nd2 && "No node for this edge!");
255 Edge ed(nd,nd2,0);
256 edges.push_back(ed);
257 }
258 }
Misha Brukmanb1c93172005-04-21 23:48:37 +0000259
Anand Shuklaea77a492002-09-18 03:55:26 +0000260 graphMap[M]= new Graph(nodes,edges, startNode, exitNode);
Misha Brukmanb1c93172005-04-21 23:48:37 +0000261
Anand Shuklaea77a492002-09-18 03:55:26 +0000262 Graph *g = graphMap[M];
263
Misha Brukmanb1c93172005-04-21 23:48:37 +0000264 if (M->size() <= 1) return; //uninstrumented
265
Anand Shuklaea77a492002-09-18 03:55:26 +0000266 //step 2: getBackEdges
267 //vector<Edge> be;
268 std::map<Node *, int> nodePriority;
269 g->getBackEdges(beMap[M], nodePriority);
Misha Brukmanb1c93172005-04-21 23:48:37 +0000270
Anand Shuklaea77a492002-09-18 03:55:26 +0000271 //step 3: add dummy edges
272 //vector<Edge> stDummy;
273 //vector<Edge> exDummy;
274 addDummyEdges(stMap[M], exMap[M], *g, beMap[M]);
Misha Brukmanb1c93172005-04-21 23:48:37 +0000275
Anand Shuklaea77a492002-09-18 03:55:26 +0000276 //step 4: value assgn to edges
277 int numPaths = valueAssignmentToEdges(*g, nodePriority, beMap[M]);
278 }
Misha Brukmanb1c93172005-04-21 23:48:37 +0000279
280
281 //step 5: now travel from root, select max(edge) < pathNo,
Anand Shuklaea77a492002-09-18 03:55:26 +0000282 //and go on until reach the exit
Misha Brukmanb1c93172005-04-21 23:48:37 +0000283 getPathFrmNode(graphMap[M]->getRoot(), vBB, pathNo, *graphMap[M],
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000284 stMap[M], exMap[M], beMap[M], -1);
Misha Brukmanb1c93172005-04-21 23:48:37 +0000285
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000286
287 //post process vBB to locate instructions to be erased
288 /*
289 if(pathReg[M]){
290 for(vector<BasicBlock *>::iterator VBI = vBB.begin(), VBE = vBB.end();
291 VBI != VBE; ++VBI){
292 for(BasicBlock::iterator BBI = (*VBI)->begin(), BBE = (*VBI)->end();
293 BBI != BBE; ++BBI){
Chris Lattner889f6202003-04-23 16:37:45 +0000294 if(LoadInst *ldInst = dyn_cast<LoadInst>(BBI)){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000295 if(pathReg[M] == ldInst->getPointerOperand())
296 instToErase.push_back(ldInst);
297 }
Chris Lattner889f6202003-04-23 16:37:45 +0000298 else if(StoreInst *stInst = dyn_cast<StoreInst>(BBI)){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000299 if(pathReg[M] == stInst->getPointerOperand())
300 instToErase.push_back(stInst);
301 }
302 }
303 }
304 }
305 */
Anand Shuklaea77a492002-09-18 03:55:26 +0000306}
Brian Gaeke960707c2003-11-11 22:41:34 +0000307
308} // End llvm namespace