blob: 58b3840587bdf34d6398f4aa42211ef51af72d45 [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"
Anand Shuklaea77a492002-09-18 03:55:26 +000019
20using std::vector;
21using std::map;
22using std::cerr;
23
24//Routines to get the path trace!
25
Anand Shuklaf8c09ee2003-02-14 20:41:53 +000026void getPathFrmNode(Node *n, vector<BasicBlock*> &vBB, int pathNo, Graph &g,
Anand Shuklaea77a492002-09-18 03:55:26 +000027 vector<Edge> &stDummy, vector<Edge> &exDummy,
28 vector<Edge> &be,
29 double strand){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +000030 Graph::nodeList &nlist = g.getNodeList(n);
Anand Shuklaea77a492002-09-18 03:55:26 +000031
Anand Shuklaf8c09ee2003-02-14 20:41:53 +000032 //printGraph(g);
33 //std::cerr<<"Path No: "<<pathNo<<"\n";
Anand Shuklaea77a492002-09-18 03:55:26 +000034 int maxCount=-9999999;
35 bool isStart=false;
36
37 if(*n==*g.getRoot())//its root: so first node of path
38 isStart=true;
39
40 double edgeRnd=0;
41 Node *nextRoot=n;
Anand Shuklaf8c09ee2003-02-14 20:41:53 +000042 for(Graph::nodeList::iterator NLI = nlist.begin(), NLE=nlist.end(); NLI!=NLE;
Anand Shuklaea77a492002-09-18 03:55:26 +000043 ++NLI){
44 if(NLI->weight>maxCount && NLI->weight<=pathNo){
45 maxCount=NLI->weight;
46 nextRoot=NLI->element;
47 edgeRnd=NLI->randId;
48 if(isStart)
49 strand=NLI->randId;
50 }
51 }
52
53 if(!isStart)
54 assert(strand!=-1 && "strand not assigned!");
55
56 assert(!(*nextRoot==*n && pathNo>0) && "No more BBs to go");
57 assert(!(*nextRoot==*g.getExit() && pathNo-maxCount!=0) && "Reached exit");
58
59 vBB.push_back(n->getElement());
60
61 if(pathNo-maxCount==0 && *nextRoot==*g.getExit()){
62
63 //look for strnd and edgeRnd now:
64 bool has1=false, has2=false;
65 //check if exit has it
66 for(vector<Edge>::iterator VI=exDummy.begin(), VE=exDummy.end(); VI!=VE;
67 ++VI){
68 if(VI->getRandId()==edgeRnd){
69 has2=true;
70 break;
71 }
72 }
73
74 //check if start has it
75 for(vector<Edge>::iterator VI=stDummy.begin(), VE=stDummy.end(); VI!=VE;
76 ++VI){
77 if(VI->getRandId()==strand){
78 has1=true;
79 break;
80 }
81 }
82
83 if(has1){
84 //find backedge with endpoint vBB[1]
85 for(vector<Edge>::iterator VI=be.begin(), VE=be.end(); VI!=VE; ++VI){
86 assert(vBB.size()>0 && "vector too small");
87 if( VI->getSecond()->getElement() == vBB[1] ){
88 //vBB[0]=VI->getFirst()->getElement();
89 vBB.erase(vBB.begin());
90 break;
91 }
92 }
93 }
94
95 if(has2){
96 //find backedge with startpoint vBB[vBB.size()-1]
97 for(vector<Edge>::iterator VI=be.begin(), VE=be.end(); VI!=VE; ++VI){
98 assert(vBB.size()>0 && "vector too small");
99 if( VI->getFirst()->getElement() == vBB[vBB.size()-1] &&
100 VI->getSecond()->getElement() == vBB[0]){
101 //vBB.push_back(VI->getSecond()->getElement());
102 break;
103 }
104 }
105 }
106 else
107 vBB.push_back(nextRoot->getElement());
108
109 return;
110 }
111
112 assert(pathNo-maxCount>=0);
113
114 return getPathFrmNode(nextRoot, vBB, pathNo-maxCount, g, stDummy,
115 exDummy, be, strand);
116}
117
118
119static Node *findBB(std::vector<Node *> &st, BasicBlock *BB){
120 for(std::vector<Node *>::iterator si=st.begin(); si!=st.end(); ++si){
121 if(((*si)->getElement())==BB){
122 return *si;
123 }
124 }
125 return NULL;
126}
127
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000128void getBBtrace(vector<BasicBlock *> &vBB, int pathNo, Function *M){//,
129 // vector<Instruction *> &instToErase){
Anand Shuklaea77a492002-09-18 03:55:26 +0000130 //step 1: create graph
131 //Transform the cfg s.t. we have just one exit node
132
133 std::vector<Node *> nodes;
134 std::vector<Edge> edges;
135 Node *tmp;
136 Node *exitNode=0, *startNode=0;
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000137
138 //Creat cfg just once for each function!
139 static std::map<Function *, Graph *> graphMap;
140
141 //get backedges, exit and start edges for the graphs and store them
Anand Shuklaea77a492002-09-18 03:55:26 +0000142 static std::map<Function *, vector<Edge> > stMap, exMap, beMap;
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000143 static std::map<Function *, Value *> pathReg; //path register
144
Anand Shuklaea77a492002-09-18 03:55:26 +0000145
146 if(!graphMap[M]){
147 BasicBlock *ExitNode = 0;
148 for (Function::iterator I = M->begin(), E = M->end(); I != E; ++I){
149 if (isa<ReturnInst>(I->getTerminator())) {
Chris Lattner889f6202003-04-23 16:37:45 +0000150 ExitNode = I;
Anand Shuklaea77a492002-09-18 03:55:26 +0000151 break;
152 }
153 }
154
155 assert(ExitNode!=0 && "exitnode not found");
156
157 //iterating over BBs and making graph
158 //The nodes must be uniquely identified:
159 //That is, no two nodes must hav same BB*
160
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000161 //keep a map for trigger basicblocks!
162 std::map<BasicBlock *, unsigned char> triggerBBs;
Anand Shuklaea77a492002-09-18 03:55:26 +0000163 //First enter just nodes: later enter edges
164 for(Function::iterator BB = M->begin(), BE=M->end(); BB != BE; ++BB){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000165 bool cont = false;
166
167 if(BB->size()==3 || BB->size() ==2){
168 for(BasicBlock::iterator II = BB->begin(), IE = BB->end();
169 II != IE; ++II){
Chris Lattner889f6202003-04-23 16:37:45 +0000170 if(CallInst *callInst = dyn_cast<CallInst>(II)){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000171 //std::cerr<<*callInst;
172 Function *calledFunction = callInst->getCalledFunction();
173 if(calledFunction && calledFunction->getName() == "trigger"){
174 triggerBBs[BB] = 9;
175 cont = true;
176 //std::cerr<<"Found trigger!\n";
177 break;
178 }
179 }
Anand Shuklaea77a492002-09-18 03:55:26 +0000180 }
181 }
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000182
183 if(cont)
184 continue;
185
186 // const Instruction *inst = BB->getInstList().begin();
187 // if(isa<CallInst>(inst)){
188 // Instruction *ii1 = BB->getInstList().begin();
189 // CallInst *callInst = dyn_cast<CallInst>(ii1);
190 // if(callInst->getCalledFunction()->getName()=="trigger")
191 // continue;
192 // }
193
Anand Shuklaea77a492002-09-18 03:55:26 +0000194 Node *nd=new Node(BB);
195 nodes.push_back(nd);
196 if(&*BB==ExitNode)
197 exitNode=nd;
198 if(&*BB==&M->front())
199 startNode=nd;
200 }
201
202 assert(exitNode!=0 && startNode!=0 && "Start or exit not found!");
203
204 for (Function::iterator BB = M->begin(), BE=M->end(); BB != BE; ++BB){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000205 if(triggerBBs[BB] == 9)
206 continue;
207
208 //if(BB->size()==3)
Chris Lattner889f6202003-04-23 16:37:45 +0000209 //if(CallInst *callInst = dyn_cast<CallInst>(BB->getInstList().begin()))
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000210 //if(callInst->getCalledFunction()->getName() == "trigger")
211 //continue;
212
213 // if(BB->size()==2){
214 // const Instruction *inst = BB->getInstList().begin();
215 // if(isa<CallInst>(inst)){
216 // Instruction *ii1 = BB->getInstList().begin();
217 // CallInst *callInst = dyn_cast<CallInst>(ii1);
218 // if(callInst->getCalledFunction()->getName()=="trigger")
219 // continue;
220 // }
221 // }
222
Anand Shuklaea77a492002-09-18 03:55:26 +0000223 Node *nd=findBB(nodes, BB);
224 assert(nd && "No node for this edge!");
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000225
Chris Lattnera9400952003-09-24 22:06:25 +0000226 for(succ_iterator s=succ_begin(BB), se=succ_end(BB); s!=se; ++s){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000227
228 if(triggerBBs[*s] == 9){
229 //if(!pathReg[M]){ //Get the path register for this!
230 //if(BB->size()>8)
Chris Lattner889f6202003-04-23 16:37:45 +0000231 // if(LoadInst *ldInst = dyn_cast<LoadInst>(BB->getInstList().begin()))
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000232 // pathReg[M] = ldInst->getPointerOperand();
233 //}
234 continue;
Anand Shuklaea77a492002-09-18 03:55:26 +0000235 }
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000236 //if((*s)->size()==3)
237 //if(CallInst *callInst =
Chris Lattner889f6202003-04-23 16:37:45 +0000238 // dyn_cast<CallInst>((*s)->getInstList().begin()))
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000239 // if(callInst->getCalledFunction()->getName() == "trigger")
240 // continue;
241
242 // if((*s)->size()==2){
243 // const Instruction *inst = (*s)->getInstList().begin();
244 // if(isa<CallInst>(inst)){
245 // Instruction *ii1 = (*s)->getInstList().begin();
246 // CallInst *callInst = dyn_cast<CallInst>(ii1);
247 // if(callInst->getCalledFunction()->getName()=="trigger")
248 // continue;
249 // }
250 // }
251
252 Node *nd2 = findBB(nodes,*s);
Anand Shuklaea77a492002-09-18 03:55:26 +0000253 assert(nd2 && "No node for this edge!");
254 Edge ed(nd,nd2,0);
255 edges.push_back(ed);
256 }
257 }
258
259 graphMap[M]= new Graph(nodes,edges, startNode, exitNode);
260
261 Graph *g = graphMap[M];
262
263 if (M->size() <= 1) return; //uninstrumented
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000264
Anand Shuklaea77a492002-09-18 03:55:26 +0000265 //step 2: getBackEdges
266 //vector<Edge> be;
267 std::map<Node *, int> nodePriority;
268 g->getBackEdges(beMap[M], nodePriority);
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000269
Anand Shuklaea77a492002-09-18 03:55:26 +0000270 //step 3: add dummy edges
271 //vector<Edge> stDummy;
272 //vector<Edge> exDummy;
273 addDummyEdges(stMap[M], exMap[M], *g, beMap[M]);
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000274
Anand Shuklaea77a492002-09-18 03:55:26 +0000275 //step 4: value assgn to edges
276 int numPaths = valueAssignmentToEdges(*g, nodePriority, beMap[M]);
277 }
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000278
279
Anand Shuklaea77a492002-09-18 03:55:26 +0000280 //step 5: now travel from root, select max(edge) < pathNo,
281 //and go on until reach the exit
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000282 getPathFrmNode(graphMap[M]->getRoot(), vBB, pathNo, *graphMap[M],
283 stMap[M], exMap[M], beMap[M], -1);
284
285
286 //post process vBB to locate instructions to be erased
287 /*
288 if(pathReg[M]){
289 for(vector<BasicBlock *>::iterator VBI = vBB.begin(), VBE = vBB.end();
290 VBI != VBE; ++VBI){
291 for(BasicBlock::iterator BBI = (*VBI)->begin(), BBE = (*VBI)->end();
292 BBI != BBE; ++BBI){
Chris Lattner889f6202003-04-23 16:37:45 +0000293 if(LoadInst *ldInst = dyn_cast<LoadInst>(BBI)){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000294 if(pathReg[M] == ldInst->getPointerOperand())
295 instToErase.push_back(ldInst);
296 }
Chris Lattner889f6202003-04-23 16:37:45 +0000297 else if(StoreInst *stInst = dyn_cast<StoreInst>(BBI)){
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000298 if(pathReg[M] == stInst->getPointerOperand())
299 instToErase.push_back(stInst);
300 }
301 }
302 }
303 }
304 */
Anand Shuklaea77a492002-09-18 03:55:26 +0000305}