blob: efe0af55c0642eebfcfdd14a907bf1e8a1ff460a [file] [log] [blame]
Anand Shuklaea77a492002-09-18 03:55:26 +00001//===----Instrumentation/ProfilePaths/RetracePath.cppTrigger.cpp--*- C++ -*--=//
2//
3// Retraces a path of BasicBlock, given a path number and a graph!
4//
5//===----------------------------------------------------------------------===//
6
Anand Shuklaea77a492002-09-18 03:55:26 +00007#include "llvm/Module.h"
Anand Shuklaea77a492002-09-18 03:55:26 +00008#include "llvm/iTerminators.h"
Anand Shuklaea77a492002-09-18 03:55:26 +00009#include "llvm/iOther.h"
Chris Lattner2f04a0d2003-01-14 22:33:56 +000010#include "llvm/Support/CFG.h"
11#include "Graph.h"
Anand Shuklaea77a492002-09-18 03:55:26 +000012
13using std::vector;
14using std::map;
15using std::cerr;
16
17//Routines to get the path trace!
18
19void getPathFrmNode(Node *n, vector<BasicBlock*> &vBB, int pathNo, Graph g,
20 vector<Edge> &stDummy, vector<Edge> &exDummy,
21 vector<Edge> &be,
22 double strand){
23 Graph::nodeList nlist=g.getNodeList(n);
24
25 int maxCount=-9999999;
26 bool isStart=false;
27
28 if(*n==*g.getRoot())//its root: so first node of path
29 isStart=true;
30
31 double edgeRnd=0;
32 Node *nextRoot=n;
33 for(Graph::nodeList::iterator NLI=nlist.begin(), NLE=nlist.end(); NLI!=NLE;
34 ++NLI){
35 if(NLI->weight>maxCount && NLI->weight<=pathNo){
36 maxCount=NLI->weight;
37 nextRoot=NLI->element;
38 edgeRnd=NLI->randId;
39 if(isStart)
40 strand=NLI->randId;
41 }
42 }
43
44 if(!isStart)
45 assert(strand!=-1 && "strand not assigned!");
46
47 assert(!(*nextRoot==*n && pathNo>0) && "No more BBs to go");
48 assert(!(*nextRoot==*g.getExit() && pathNo-maxCount!=0) && "Reached exit");
49
50 vBB.push_back(n->getElement());
51
52 if(pathNo-maxCount==0 && *nextRoot==*g.getExit()){
53
54 //look for strnd and edgeRnd now:
55 bool has1=false, has2=false;
56 //check if exit has it
57 for(vector<Edge>::iterator VI=exDummy.begin(), VE=exDummy.end(); VI!=VE;
58 ++VI){
59 if(VI->getRandId()==edgeRnd){
60 has2=true;
61 break;
62 }
63 }
64
65 //check if start has it
66 for(vector<Edge>::iterator VI=stDummy.begin(), VE=stDummy.end(); VI!=VE;
67 ++VI){
68 if(VI->getRandId()==strand){
69 has1=true;
70 break;
71 }
72 }
73
74 if(has1){
75 //find backedge with endpoint vBB[1]
76 for(vector<Edge>::iterator VI=be.begin(), VE=be.end(); VI!=VE; ++VI){
77 assert(vBB.size()>0 && "vector too small");
78 if( VI->getSecond()->getElement() == vBB[1] ){
79 //vBB[0]=VI->getFirst()->getElement();
80 vBB.erase(vBB.begin());
81 break;
82 }
83 }
84 }
85
86 if(has2){
87 //find backedge with startpoint vBB[vBB.size()-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->getFirst()->getElement() == vBB[vBB.size()-1] &&
91 VI->getSecond()->getElement() == vBB[0]){
92 //vBB.push_back(VI->getSecond()->getElement());
93 break;
94 }
95 }
96 }
97 else
98 vBB.push_back(nextRoot->getElement());
99
100 return;
101 }
102
103 assert(pathNo-maxCount>=0);
104
105 return getPathFrmNode(nextRoot, vBB, pathNo-maxCount, g, stDummy,
106 exDummy, be, strand);
107}
108
109
110static Node *findBB(std::vector<Node *> &st, BasicBlock *BB){
111 for(std::vector<Node *>::iterator si=st.begin(); si!=st.end(); ++si){
112 if(((*si)->getElement())==BB){
113 return *si;
114 }
115 }
116 return NULL;
117}
118
119void getBBtrace(vector<BasicBlock *> &vBB, int pathNo, Function *M){
120 //step 1: create graph
121 //Transform the cfg s.t. we have just one exit node
122
123 std::vector<Node *> nodes;
124 std::vector<Edge> edges;
125 Node *tmp;
126 Node *exitNode=0, *startNode=0;
127 static std::map<Function *, Graph *> graphMap;
128 static std::map<Function *, vector<Edge> > stMap, exMap, beMap;
129
130 if(!graphMap[M]){
131 BasicBlock *ExitNode = 0;
132 for (Function::iterator I = M->begin(), E = M->end(); I != E; ++I){
133 if (isa<ReturnInst>(I->getTerminator())) {
134 ExitNode = &*I;
135 break;
136 }
137 }
138
139 assert(ExitNode!=0 && "exitnode not found");
140
141 //iterating over BBs and making graph
142 //The nodes must be uniquely identified:
143 //That is, no two nodes must hav same BB*
144
145 //First enter just nodes: later enter edges
146 for(Function::iterator BB = M->begin(), BE=M->end(); BB != BE; ++BB){
147 if(BB->size()==2){
148 const Instruction *inst = BB->getInstList().begin();
149 if(isa<CallInst>(inst)){
150 Instruction *ii1 = BB->getInstList().begin();
151 CallInst *callInst = dyn_cast<CallInst>(ii1);
152 if(callInst->getCalledFunction()->getName()=="trigger")
153 continue;
154 }
155 }
156 Node *nd=new Node(BB);
157 nodes.push_back(nd);
158 if(&*BB==ExitNode)
159 exitNode=nd;
160 if(&*BB==&M->front())
161 startNode=nd;
162 }
163
164 assert(exitNode!=0 && startNode!=0 && "Start or exit not found!");
165
166 for (Function::iterator BB = M->begin(), BE=M->end(); BB != BE; ++BB){
167 if(BB->size()==2){
168 const Instruction *inst = BB->getInstList().begin();
169 if(isa<CallInst>(inst)){
170 Instruction *ii1 = BB->getInstList().begin();
171 CallInst *callInst = dyn_cast<CallInst>(ii1);
172 if(callInst->getCalledFunction()->getName()=="trigger")
173 continue;
174 }
175 }
176
177 Node *nd=findBB(nodes, BB);
178 assert(nd && "No node for this edge!");
179
180 for(BasicBlock::succ_iterator s=succ_begin(&*BB), se=succ_end(&*BB);
181 s!=se; ++s){
182 if((*s)->size()==2){
183 const Instruction *inst = (*s)->getInstList().begin();
184 if(isa<CallInst>(inst)){
185 Instruction *ii1 = (*s)->getInstList().begin();
186 CallInst *callInst = dyn_cast<CallInst>(ii1);
187 if(callInst->getCalledFunction()->getName()=="trigger")
188 continue;
189 }
190 }
191
192 Node *nd2=findBB(nodes,*s);
193 assert(nd2 && "No node for this edge!");
194 Edge ed(nd,nd2,0);
195 edges.push_back(ed);
196 }
197 }
198
199 graphMap[M]= new Graph(nodes,edges, startNode, exitNode);
200
201 Graph *g = graphMap[M];
202
203 if (M->size() <= 1) return; //uninstrumented
204
205 //step 2: getBackEdges
206 //vector<Edge> be;
207 std::map<Node *, int> nodePriority;
208 g->getBackEdges(beMap[M], nodePriority);
209
210 //step 3: add dummy edges
211 //vector<Edge> stDummy;
212 //vector<Edge> exDummy;
213 addDummyEdges(stMap[M], exMap[M], *g, beMap[M]);
214
215 //step 4: value assgn to edges
216 int numPaths = valueAssignmentToEdges(*g, nodePriority, beMap[M]);
217 }
218
219 //step 5: now travel from root, select max(edge) < pathNo,
220 //and go on until reach the exit
221 return getPathFrmNode(graphMap[M]->getRoot(), vBB, pathNo, *graphMap[M],
222 stMap[M], exMap[M], beMap[M], -1);
223}