blob: f0db940ced1c149c1420967e3e05fea7e1bbb614 [file] [log] [blame]
Chris Lattner44d2c352003-10-13 03:32:08 +00001//===- GraphAuxiliary.cpp - Auxiliary functions on graph ------------------===//
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 Shukla854c3022002-02-26 19:02:16 +00009//
Chris Lattner44d2c352003-10-13 03:32:08 +000010// auxiliary function associated with graph: they all operate on graph, and help
11// in inserting instrumentation for trace generation
Anand Shukla854c3022002-02-26 19:02:16 +000012//
13//===----------------------------------------------------------------------===//
14
Anand Shukla21906892002-06-25 21:14:58 +000015#include "llvm/Pass.h"
Anand Shuklaf94ad682002-09-16 05:26:51 +000016#include "llvm/Module.h"
Anand Shuklafd61c602002-07-18 20:56:47 +000017#include "llvm/iTerminators.h"
Chris Lattner8abcd562003-08-01 22:15:03 +000018#include "Support/Debug.h"
Anand Shukla854c3022002-02-26 19:02:16 +000019#include <algorithm>
Reid Spencereb04d9b2004-07-04 12:19:56 +000020#include <iostream>
Chris Lattner2f04a0d2003-01-14 22:33:56 +000021#include "Graph.h"
Chris Lattner5328c6f2002-02-26 19:40:28 +000022
Anand Shukla21906892002-06-25 21:14:58 +000023//using std::list;
Chris Lattner5328c6f2002-02-26 19:40:28 +000024using std::map;
25using std::vector;
26using std::cerr;
Anand Shukla854c3022002-02-26 19:02:16 +000027
Brian Gaeke960707c2003-11-11 22:41:34 +000028namespace llvm {
29
Anand Shukla854c3022002-02-26 19:02:16 +000030//check if 2 edges are equal (same endpoints and same weight)
Anand Shukla854c3022002-02-26 19:02:16 +000031static bool edgesEqual(Edge ed1, Edge ed2){
32 return ((ed1==ed2) && ed1.getWeight()==ed2.getWeight());
33}
34
35//Get the vector of edges that are to be instrumented in the graph
Chris Lattner570b8e12002-02-26 19:49:45 +000036static void getChords(vector<Edge > &chords, Graph &g, Graph st){
Anand Shukla854c3022002-02-26 19:02:16 +000037 //make sure the spanning tree is directional
38 //iterate over ALL the edges of the graph
Anand Shukla21906892002-06-25 21:14:58 +000039 vector<Node *> allNodes=g.getAllNodes();
40 for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
Anand Shukla854c3022002-02-26 19:02:16 +000041 ++NI){
42 Graph::nodeList node_list=g.getNodeList(*NI);
43 for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end();
44 NLI!=NLE; ++NLI){
Anand Shukla21906892002-06-25 21:14:58 +000045 Edge f(*NI, NLI->element,NLI->weight, NLI->randId);
Anand Shukla854c3022002-02-26 19:02:16 +000046 if(!(st.hasEdgeAndWt(f)))//addnl
47 chords.push_back(f);
48 }
49 }
50}
51
52//Given a tree t, and a "directed graph" g
53//replace the edges in the tree t with edges that exist in graph
54//The tree is formed from "undirectional" copy of graph
55//So whatever edges the tree has, the undirectional graph
56//would have too. This function corrects some of the directions in
57//the tree so that now, all edge directions in the tree match
58//the edge directions of corresponding edges in the directed graph
Chris Lattner570b8e12002-02-26 19:49:45 +000059static void removeTreeEdges(Graph &g, Graph& t){
Anand Shukla21906892002-06-25 21:14:58 +000060 vector<Node* > allNodes=t.getAllNodes();
61 for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
Anand Shukla854c3022002-02-26 19:02:16 +000062 ++NI){
63 Graph::nodeList nl=t.getNodeList(*NI);
64 for(Graph::nodeList::iterator NLI=nl.begin(), NLE=nl.end(); NLI!=NLE;++NLI){
65 Edge ed(NLI->element, *NI, NLI->weight);
Anand Shukla854c3022002-02-26 19:02:16 +000066 if(!g.hasEdgeAndWt(ed)) t.removeEdge(ed);//tree has only one edge
67 //between any pair of vertices, so no need to delete by edge wt
68 }
69 }
70}
71
72//Assign a value to all the edges in the graph
73//such that if we traverse along any path from root to exit, and
74//add up the edge values, we get a path number that uniquely
75//refers to the path we travelled
Anand Shuklaf94ad682002-09-16 05:26:51 +000076int valueAssignmentToEdges(Graph& g, map<Node *, int> nodePriority,
77 vector<Edge> &be){
Anand Shukla21906892002-06-25 21:14:58 +000078 vector<Node *> revtop=g.reverseTopologicalSort();
Anand Shukla854c3022002-02-26 19:02:16 +000079 map<Node *,int > NumPaths;
Anand Shukla2d3d20b2002-07-08 19:37:06 +000080 for(vector<Node *>::iterator RI=revtop.begin(), RE=revtop.end();
81 RI!=RE; ++RI){
Anand Shukla854c3022002-02-26 19:02:16 +000082 if(g.isLeaf(*RI))
83 NumPaths[*RI]=1;
84 else{
85 NumPaths[*RI]=0;
Anand Shukla2d3d20b2002-07-08 19:37:06 +000086
Anand Shuklaf94ad682002-09-16 05:26:51 +000087 // Modified Graph::nodeList &nlist=g.getNodeList(*RI);
88 Graph::nodeList &nlist=g.getSortedNodeList(*RI, be);
89
Anand Shukla21906892002-06-25 21:14:58 +000090 //sort nodelist by increasing order of numpaths
91
92 int sz=nlist.size();
Anand Shukla2d3d20b2002-07-08 19:37:06 +000093
Anand Shukla21906892002-06-25 21:14:58 +000094 for(int i=0;i<sz-1; i++){
95 int min=i;
Anand Shukla2d3d20b2002-07-08 19:37:06 +000096 for(int j=i+1; j<sz; j++){
97 BasicBlock *bb1 = nlist[j].element->getElement();
98 BasicBlock *bb2 = nlist[min].element->getElement();
Anand Shuklafd61c602002-07-18 20:56:47 +000099
100 if(bb1 == bb2) continue;
101
102 if(*RI == g.getRoot()){
103 assert(nodePriority[nlist[min].element]!=
104 nodePriority[nlist[j].element]
105 && "priorities can't be same!");
106
107 if(nodePriority[nlist[j].element] <
108 nodePriority[nlist[min].element])
109 min = j;
110 }
Anand Shukla2d3d20b2002-07-08 19:37:06 +0000111
Anand Shuklafd61c602002-07-18 20:56:47 +0000112 else{
113 TerminatorInst *tti = (*RI)->getElement()->getTerminator();
Anand Shuklaf94ad682002-09-16 05:26:51 +0000114
Anand Shuklafd61c602002-07-18 20:56:47 +0000115 BranchInst *ti = cast<BranchInst>(tti);
116 assert(ti && "not a branch");
117 assert(ti->getNumSuccessors()==2 && "less successors!");
118
119 BasicBlock *tB = ti->getSuccessor(0);
120 BasicBlock *fB = ti->getSuccessor(1);
121
122 if(tB == bb1 || fB == bb2)
Anand Shukla2d3d20b2002-07-08 19:37:06 +0000123 min = j;
Anand Shukla2d3d20b2002-07-08 19:37:06 +0000124 }
125
126 }
Anand Shukla21906892002-06-25 21:14:58 +0000127 graphListElement tempEl=nlist[min];
128 nlist[min]=nlist[i];
129 nlist[i]=tempEl;
130 }
Anand Shukla2d3d20b2002-07-08 19:37:06 +0000131
Anand Shukla21906892002-06-25 21:14:58 +0000132 //sorted now!
Anand Shukla21906892002-06-25 21:14:58 +0000133 for(Graph::nodeList::iterator GLI=nlist.begin(), GLE=nlist.end();
134 GLI!=GLE; ++GLI){
Anand Shuklaf94ad682002-09-16 05:26:51 +0000135 GLI->weight=NumPaths[*RI];
Anand Shukla21906892002-06-25 21:14:58 +0000136 NumPaths[*RI]+=NumPaths[GLI->element];
Anand Shukla854c3022002-02-26 19:02:16 +0000137 }
138 }
139 }
140 return NumPaths[g.getRoot()];
141}
142
143//This is a helper function to get the edge increments
Misha Brukman8b2bd4e2003-10-10 17:57:28 +0000144//This is used in conjunction with inc_DFS
Anand Shukla854c3022002-02-26 19:02:16 +0000145//to get the edge increments
146//Edge increment implies assigning a value to all the edges in the graph
147//such that if we traverse along any path from root to exit, and
148//add up the edge values, we get a path number that uniquely
149//refers to the path we travelled
150//inc_Dir tells whether 2 edges are in same, or in different directions
151//if same direction, return 1, else -1
Chris Lattner570b8e12002-02-26 19:49:45 +0000152static int inc_Dir(Edge e, Edge f){
Anand Shukla854c3022002-02-26 19:02:16 +0000153 if(e.isNull())
154 return 1;
155
Misha Brukman8b2bd4e2003-10-10 17:57:28 +0000156 //check that the edges must have at least one common endpoint
Anand Shukla854c3022002-02-26 19:02:16 +0000157 assert(*(e.getFirst())==*(f.getFirst()) ||
158 *(e.getFirst())==*(f.getSecond()) ||
159 *(e.getSecond())==*(f.getFirst()) ||
160 *(e.getSecond())==*(f.getSecond()));
161
162 if(*(e.getFirst())==*(f.getSecond()) ||
163 *(e.getSecond())==*(f.getFirst()))
164 return 1;
165
166 return -1;
167}
168
Anand Shukla21906892002-06-25 21:14:58 +0000169
Anand Shukla854c3022002-02-26 19:02:16 +0000170//used for getting edge increments (read comments above in inc_Dir)
171//inc_DFS is a modification of DFS
Anand Shuklaf94ad682002-09-16 05:26:51 +0000172static void inc_DFS(Graph& g,Graph& t,map<Edge, int, EdgeCompare2>& Increment,
Anand Shukla854c3022002-02-26 19:02:16 +0000173 int events, Node *v, Edge e){
174
Anand Shukla21906892002-06-25 21:14:58 +0000175 vector<Node *> allNodes=t.getAllNodes();
176
Anand Shukla21906892002-06-25 21:14:58 +0000177 for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
Anand Shukla854c3022002-02-26 19:02:16 +0000178 ++NI){
179 Graph::nodeList node_list=t.getNodeList(*NI);
180 for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end();
181 NLI!= NLE; ++NLI){
Anand Shukla21906892002-06-25 21:14:58 +0000182 Edge f(*NI, NLI->element,NLI->weight, NLI->randId);
Anand Shukla854c3022002-02-26 19:02:16 +0000183 if(!edgesEqual(f,e) && *v==*(f.getSecond())){
184 int dir_count=inc_Dir(e,f);
185 int wt=1*f.getWeight();
186 inc_DFS(g,t, Increment, dir_count*events+wt, f.getFirst(), f);
187 }
188 }
189 }
190
Anand Shukla21906892002-06-25 21:14:58 +0000191 for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
Anand Shukla854c3022002-02-26 19:02:16 +0000192 ++NI){
193 Graph::nodeList node_list=t.getNodeList(*NI);
194 for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end();
195 NLI!=NLE; ++NLI){
Anand Shukla21906892002-06-25 21:14:58 +0000196 Edge f(*NI, NLI->element,NLI->weight, NLI->randId);
Anand Shukla854c3022002-02-26 19:02:16 +0000197 if(!edgesEqual(f,e) && *v==*(f.getFirst())){
198 int dir_count=inc_Dir(e,f);
Anand Shukla21906892002-06-25 21:14:58 +0000199 int wt=f.getWeight();
Anand Shukla854c3022002-02-26 19:02:16 +0000200 inc_DFS(g,t, Increment, dir_count*events+wt,
201 f.getSecond(), f);
202 }
203 }
204 }
205
206 allNodes=g.getAllNodes();
Anand Shukla21906892002-06-25 21:14:58 +0000207 for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
Anand Shukla854c3022002-02-26 19:02:16 +0000208 ++NI){
209 Graph::nodeList node_list=g.getNodeList(*NI);
210 for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end();
211 NLI!=NLE; ++NLI){
Anand Shukla21906892002-06-25 21:14:58 +0000212 Edge f(*NI, NLI->element,NLI->weight, NLI->randId);
Anand Shukla854c3022002-02-26 19:02:16 +0000213 if(!(t.hasEdgeAndWt(f)) && (*v==*(f.getSecond()) ||
214 *v==*(f.getFirst()))){
215 int dir_count=inc_Dir(e,f);
216 Increment[f]+=dir_count*events;
217 }
218 }
219 }
220}
221
222//Now we select a subset of all edges
223//and assign them some values such that
224//if we consider just this subset, it still represents
225//the path sum along any path in the graph
Anand Shuklaf94ad682002-09-16 05:26:51 +0000226static map<Edge, int, EdgeCompare2> getEdgeIncrements(Graph& g, Graph& t,
227 vector<Edge> &be){
Anand Shukla854c3022002-02-26 19:02:16 +0000228 //get all edges in g-t
Anand Shuklaf94ad682002-09-16 05:26:51 +0000229 map<Edge, int, EdgeCompare2> Increment;
Anand Shukla854c3022002-02-26 19:02:16 +0000230
Anand Shukla21906892002-06-25 21:14:58 +0000231 vector<Node *> allNodes=g.getAllNodes();
Anand Shukla854c3022002-02-26 19:02:16 +0000232
Anand Shukla21906892002-06-25 21:14:58 +0000233 for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
Anand Shukla854c3022002-02-26 19:02:16 +0000234 ++NI){
Anand Shuklaf94ad682002-09-16 05:26:51 +0000235 Graph::nodeList node_list=g.getSortedNodeList(*NI, be);
236 //modified g.getNodeList(*NI);
Anand Shukla854c3022002-02-26 19:02:16 +0000237 for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end();
238 NLI!=NLE; ++NLI){
Anand Shukla21906892002-06-25 21:14:58 +0000239 Edge ed(*NI, NLI->element,NLI->weight,NLI->randId);
240 if(!(t.hasEdgeAndWt(ed))){
Anand Shukla854c3022002-02-26 19:02:16 +0000241 Increment[ed]=0;;
242 }
243 }
244 }
245
246 Edge *ed=new Edge();
247 inc_DFS(g,t,Increment, 0, g.getRoot(), *ed);
248
Anand Shukla21906892002-06-25 21:14:58 +0000249 for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
Anand Shukla854c3022002-02-26 19:02:16 +0000250 ++NI){
Anand Shuklaf94ad682002-09-16 05:26:51 +0000251 Graph::nodeList node_list=g.getSortedNodeList(*NI, be);
252 //modified g.getNodeList(*NI);
Anand Shukla854c3022002-02-26 19:02:16 +0000253 for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end();
254 NLI!=NLE; ++NLI){
Anand Shukla21906892002-06-25 21:14:58 +0000255 Edge ed(*NI, NLI->element,NLI->weight, NLI->randId);
256 if(!(t.hasEdgeAndWt(ed))){
Anand Shukla854c3022002-02-26 19:02:16 +0000257 int wt=ed.getWeight();
258 Increment[ed]+=wt;
259 }
260 }
261 }
262
263 return Increment;
264}
265
Anand Shukla21906892002-06-25 21:14:58 +0000266//push it up: TODO
267const graphListElement *findNodeInList(const Graph::nodeList &NL,
268 Node *N);
269
270graphListElement *findNodeInList(Graph::nodeList &NL, Node *N);
271//end TODO
272
Anand Shukla854c3022002-02-26 19:02:16 +0000273//Based on edgeIncrements (above), now obtain
274//the kind of code to be inserted along an edge
275//The idea here is to minimize the computation
276//by inserting only the needed code
Anand Shuklaf94ad682002-09-16 05:26:51 +0000277static void getCodeInsertions(Graph &g, map<Edge, getEdgeCode *, EdgeCompare2> &instr,
Chris Lattner5328c6f2002-02-26 19:40:28 +0000278 vector<Edge > &chords,
Anand Shuklaf94ad682002-09-16 05:26:51 +0000279 map<Edge,int, EdgeCompare2> &edIncrements){
Anand Shukla854c3022002-02-26 19:02:16 +0000280
281 //Register initialization code
282 vector<Node *> ws;
283 ws.push_back(g.getRoot());
284 while(ws.size()>0){
Chris Lattner5328c6f2002-02-26 19:40:28 +0000285 Node *v=ws.back();
286 ws.pop_back();
Anand Shukla854c3022002-02-26 19:02:16 +0000287 //for each edge v->w
288 Graph::nodeList succs=g.getNodeList(v);
289
290 for(Graph::nodeList::iterator nl=succs.begin(), ne=succs.end();
291 nl!=ne; ++nl){
292 int edgeWt=nl->weight;
293 Node *w=nl->element;
294 //if chords has v->w
Anand Shukla21906892002-06-25 21:14:58 +0000295 Edge ed(v,w, edgeWt, nl->randId);
Anand Shukla854c3022002-02-26 19:02:16 +0000296 bool hasEdge=false;
297 for(vector<Edge>::iterator CI=chords.begin(), CE=chords.end();
298 CI!=CE && !hasEdge;++CI){
Anand Shukla21906892002-06-25 21:14:58 +0000299 if(*CI==ed && CI->getWeight()==edgeWt){//modf
Anand Shukla854c3022002-02-26 19:02:16 +0000300 hasEdge=true;
301 }
302 }
Anand Shukla21906892002-06-25 21:14:58 +0000303
304 if(hasEdge){//so its a chord edge
Anand Shukla854c3022002-02-26 19:02:16 +0000305 getEdgeCode *edCd=new getEdgeCode();
306 edCd->setCond(1);
307 edCd->setInc(edIncrements[ed]);
Chris Lattner5328c6f2002-02-26 19:40:28 +0000308 instr[ed]=edCd;
Anand Shukla854c3022002-02-26 19:02:16 +0000309 }
Anand Shukla21906892002-06-25 21:14:58 +0000310 else if(g.getNumberOfIncomingEdges(w)==1){
Anand Shukla854c3022002-02-26 19:02:16 +0000311 ws.push_back(w);
312 }
313 else{
314 getEdgeCode *edCd=new getEdgeCode();
315 edCd->setCond(2);
316 edCd->setInc(0);
Chris Lattner5328c6f2002-02-26 19:40:28 +0000317 instr[ed]=edCd;
Anand Shukla854c3022002-02-26 19:02:16 +0000318 }
319 }
320 }
321
322 /////Memory increment code
323 ws.push_back(g.getExit());
324
Chris Lattner5328c6f2002-02-26 19:40:28 +0000325 while(!ws.empty()) {
326 Node *w=ws.back();
327 ws.pop_back();
Anand Shukla21906892002-06-25 21:14:58 +0000328
329
330 ///////
331 //vector<Node *> lt;
332 vector<Node *> lllt=g.getAllNodes();
333 for(vector<Node *>::iterator EII=lllt.begin(); EII!=lllt.end() ;++EII){
334 Node *lnode=*EII;
335 Graph::nodeList &nl = g.getNodeList(lnode);
Anand Shuklaf94ad682002-09-16 05:26:51 +0000336 //graphListElement *N = findNodeInList(nl, w);
337 for(Graph::nodeList::const_iterator N = nl.begin(),
338 NNEN = nl.end(); N!= NNEN; ++N){
339 if (*N->element == *w){
340 Node *v=lnode;
341
342 //if chords has v->w
343 Edge ed(v,w, N->weight, N->randId);
344 getEdgeCode *edCd=new getEdgeCode();
345 bool hasEdge=false;
346 for(vector<Edge>::iterator CI=chords.begin(), CE=chords.end(); CI!=CE;
347 ++CI){
348 if(*CI==ed && CI->getWeight()==N->weight){
349 hasEdge=true;
350 break;
351 }
352 }
353 if(hasEdge){
354 //char str[100];
355 if(instr[ed]!=NULL && instr[ed]->getCond()==1){
356 instr[ed]->setCond(4);
357 }
358 else{
359 edCd->setCond(5);
360 edCd->setInc(edIncrements[ed]);
361 instr[ed]=edCd;
362 }
363
364 }
365 else if(g.getNumberOfOutgoingEdges(v)==1)
366 ws.push_back(v);
367 else{
368 edCd->setCond(6);
369 instr[ed]=edCd;
370 }
371 }
Anand Shukla854c3022002-02-26 19:02:16 +0000372 }
373 }
374 }
Anand Shukla854c3022002-02-26 19:02:16 +0000375 ///// Register increment code
376 for(vector<Edge>::iterator CI=chords.begin(), CE=chords.end(); CI!=CE; ++CI){
377 getEdgeCode *edCd=new getEdgeCode();
Chris Lattner5328c6f2002-02-26 19:40:28 +0000378 if(instr[*CI]==NULL){
379 edCd->setCond(3);
380 edCd->setInc(edIncrements[*CI]);
381 instr[*CI]=edCd;
382 }
Anand Shukla854c3022002-02-26 19:02:16 +0000383 }
Anand Shukla854c3022002-02-26 19:02:16 +0000384}
385
386//Add dummy edges corresponding to the back edges
387//If a->b is a backedge
388//then incoming dummy edge is root->b
389//and outgoing dummy edge is a->exit
Anand Shukla21906892002-06-25 21:14:58 +0000390//changed
Anand Shukla854c3022002-02-26 19:02:16 +0000391void addDummyEdges(vector<Edge > &stDummy,
392 vector<Edge > &exDummy,
Chris Lattner5328c6f2002-02-26 19:40:28 +0000393 Graph &g, vector<Edge> &be){
Anand Shukla854c3022002-02-26 19:02:16 +0000394 for(vector<Edge >::iterator VI=be.begin(), VE=be.end(); VI!=VE; ++VI){
395 Edge ed=*VI;
396 Node *first=ed.getFirst();
397 Node *second=ed.getSecond();
398 g.removeEdge(ed);
399
400 if(!(*second==*(g.getRoot()))){
Anand Shukla21906892002-06-25 21:14:58 +0000401 Edge *st=new Edge(g.getRoot(), second, ed.getWeight(), ed.getRandId());
402 stDummy.push_back(*st);
Chris Lattner5328c6f2002-02-26 19:40:28 +0000403 g.addEdgeForce(*st);
Anand Shukla854c3022002-02-26 19:02:16 +0000404 }
405
406 if(!(*first==*(g.getExit()))){
Anand Shukla21906892002-06-25 21:14:58 +0000407 Edge *ex=new Edge(first, g.getExit(), ed.getWeight(), ed.getRandId());
408 exDummy.push_back(*ex);
409 g.addEdgeForce(*ex);
Anand Shukla854c3022002-02-26 19:02:16 +0000410 }
411 }
412}
413
414//print a given edge in the form BB1Label->BB2Label
415void printEdge(Edge ed){
416 cerr<<((ed.getFirst())->getElement())
417 ->getName()<<"->"<<((ed.getSecond())
418 ->getElement())->getName()<<
Anand Shukla21906892002-06-25 21:14:58 +0000419 ":"<<ed.getWeight()<<" rndId::"<<ed.getRandId()<<"\n";
Anand Shukla854c3022002-02-26 19:02:16 +0000420}
421
422//Move the incoming dummy edge code and outgoing dummy
423//edge code over to the corresponding back edge
Anand Shukla21906892002-06-25 21:14:58 +0000424static void moveDummyCode(vector<Edge> &stDummy,
425 vector<Edge> &exDummy,
426 vector<Edge> &be,
Anand Shuklaf94ad682002-09-16 05:26:51 +0000427 map<Edge, getEdgeCode *, EdgeCompare2> &insertions,
Anand Shukla21906892002-06-25 21:14:58 +0000428 Graph &g){
429 typedef vector<Edge >::iterator vec_iter;
Anand Shukla854c3022002-02-26 19:02:16 +0000430
Anand Shuklaf94ad682002-09-16 05:26:51 +0000431 map<Edge,getEdgeCode *, EdgeCompare2> temp;
Anand Shukla21906892002-06-25 21:14:58 +0000432 //iterate over edges with code
Chris Lattner5328c6f2002-02-26 19:40:28 +0000433 std::vector<Edge> toErase;
Anand Shuklaf94ad682002-09-16 05:26:51 +0000434 for(map<Edge,getEdgeCode *, EdgeCompare2>::iterator MI=insertions.begin(),
Anand Shukla854c3022002-02-26 19:02:16 +0000435 ME=insertions.end(); MI!=ME; ++MI){
436 Edge ed=MI->first;
437 getEdgeCode *edCd=MI->second;
Anand Shukla21906892002-06-25 21:14:58 +0000438
439 ///---new code
440 //iterate over be, and check if its starts and end vertices hv code
441 for(vector<Edge>::iterator BEI=be.begin(), BEE=be.end(); BEI!=BEE; ++BEI){
442 if(ed.getRandId()==BEI->getRandId()){
443
Anand Shukla21906892002-06-25 21:14:58 +0000444 if(temp[*BEI]==0)
445 temp[*BEI]=new getEdgeCode();
446
447 //so ed is either in st, or ex!
448 if(ed.getFirst()==g.getRoot()){
Anand Shukla2d3d20b2002-07-08 19:37:06 +0000449
Anand Shukla21906892002-06-25 21:14:58 +0000450 //so its in stDummy
451 temp[*BEI]->setCdIn(edCd);
452 toErase.push_back(ed);
453 }
454 else if(ed.getSecond()==g.getExit()){
Anand Shukla2d3d20b2002-07-08 19:37:06 +0000455
Anand Shukla21906892002-06-25 21:14:58 +0000456 //so its in exDummy
457 toErase.push_back(ed);
458 temp[*BEI]->setCdOut(edCd);
459 }
460 else{
461 assert(false && "Not found in either start or end! Rand failed?");
462 }
463 }
464 }
465 }
466
467 for(vector<Edge >::iterator vmi=toErase.begin(), vme=toErase.end(); vmi!=vme;
468 ++vmi){
469 insertions.erase(*vmi);
Anand Shukla21906892002-06-25 21:14:58 +0000470 g.removeEdgeWithWt(*vmi);
471 }
472
Anand Shuklaf94ad682002-09-16 05:26:51 +0000473 for(map<Edge,getEdgeCode *, EdgeCompare2>::iterator MI=temp.begin(),
Anand Shukla21906892002-06-25 21:14:58 +0000474 ME=temp.end(); MI!=ME; ++MI){
475 insertions[MI->first]=MI->second;
Anand Shukla21906892002-06-25 21:14:58 +0000476 }
Anand Shukla2d3d20b2002-07-08 19:37:06 +0000477
Anand Shukla21906892002-06-25 21:14:58 +0000478#ifdef DEBUG_PATH_PROFILES
479 cerr<<"size of deletions: "<<toErase.size()<<"\n";
Anand Shukla21906892002-06-25 21:14:58 +0000480 cerr<<"SIZE OF INSERTIONS AFTER DEL "<<insertions.size()<<"\n";
481#endif
Anand Shukla854c3022002-02-26 19:02:16 +0000482
Anand Shukla854c3022002-02-26 19:02:16 +0000483}
484
Chris Lattner18ff9452002-02-26 19:43:49 +0000485//Do graph processing: to determine minimal edge increments,
486//appropriate code insertions etc and insert the code at
487//appropriate locations
488void processGraph(Graph &g,
489 Instruction *rInst,
Anand Shuklaf8c09ee2003-02-14 20:41:53 +0000490 Value *countInst,
Chris Lattner18ff9452002-02-26 19:43:49 +0000491 vector<Edge >& be,
492 vector<Edge >& stDummy,
Anand Shukla21906892002-06-25 21:14:58 +0000493 vector<Edge >& exDummy,
Anand Shukla77dca142002-09-20 16:44:35 +0000494 int numPaths, int MethNo,
495 Value *threshold){
Anand Shukla21906892002-06-25 21:14:58 +0000496
Chris Lattner18ff9452002-02-26 19:43:49 +0000497 //Given a graph: with exit->root edge, do the following in seq:
498 //1. get back edges
499 //2. insert dummy edges and remove back edges
500 //3. get edge assignments
501 //4. Get Max spanning tree of graph:
502 // -Make graph g2=g undirectional
503 // -Get Max spanning tree t
504 // -Make t undirectional
505 // -remove edges from t not in graph g
506 //5. Get edge increments
507 //6. Get code insertions
508 //7. move code on dummy edges over to the back edges
509
510
511 //This is used as maximum "weight" for
512 //priority queue
513 //This would hold all
514 //right as long as number of paths in the graph
515 //is less than this
Chris Lattner22cbac62002-09-17 23:46:33 +0000516 const int Infinity=99999999;
Chris Lattner18ff9452002-02-26 19:43:49 +0000517
518
519 //step 1-3 are already done on the graph when this function is called
Chris Lattnere1fc2d92002-05-22 21:56:32 +0000520 DEBUG(printGraph(g));
521
Chris Lattner18ff9452002-02-26 19:43:49 +0000522 //step 4: Get Max spanning tree of graph
523
524 //now insert exit to root edge
525 //if its there earlier, remove it!
Chris Lattner22cbac62002-09-17 23:46:33 +0000526 //assign it weight Infinity
Chris Lattner18ff9452002-02-26 19:43:49 +0000527 //so that this edge IS ALWAYS IN spanning tree
528 //Note than edges in spanning tree do not get
529 //instrumented: and we do not want the
530 //edge exit->root to get instrumented
531 //as it MAY BE a dummy edge
Chris Lattner22cbac62002-09-17 23:46:33 +0000532 Edge ed(g.getExit(),g.getRoot(),Infinity);
533 g.addEdge(ed,Infinity);
Chris Lattner18ff9452002-02-26 19:43:49 +0000534 Graph g2=g;
535
536 //make g2 undirectional: this gives a better
537 //maximal spanning tree
538 g2.makeUnDirectional();
Chris Lattnere1fc2d92002-05-22 21:56:32 +0000539 DEBUG(printGraph(g2));
540
Chris Lattner18ff9452002-02-26 19:43:49 +0000541 Graph *t=g2.getMaxSpanningTree();
Anand Shukla2d3d20b2002-07-08 19:37:06 +0000542#ifdef DEBUG_PATH_PROFILES
543 std::cerr<<"Original maxspanning tree\n";
544 printGraph(*t);
545#endif
Chris Lattner18ff9452002-02-26 19:43:49 +0000546 //now edges of tree t have weights reversed
547 //(negative) because the algorithm used
548 //to find max spanning tree is
549 //actually for finding min spanning tree
550 //so get back the original weights
551 t->reverseWts();
552
553 //Ordinarily, the graph is directional
554 //lets converts the graph into an
555 //undirectional graph
556 //This is done by adding an edge
557 //v->u for all existing edges u->v
558 t->makeUnDirectional();
559
560 //Given a tree t, and a "directed graph" g
561 //replace the edges in the tree t with edges that exist in graph
562 //The tree is formed from "undirectional" copy of graph
563 //So whatever edges the tree has, the undirectional graph
564 //would have too. This function corrects some of the directions in
565 //the tree so that now, all edge directions in the tree match
566 //the edge directions of corresponding edges in the directed graph
567 removeTreeEdges(g, *t);
Chris Lattnere1fc2d92002-05-22 21:56:32 +0000568
Anand Shukla21906892002-06-25 21:14:58 +0000569#ifdef DEBUG_PATH_PROFILES
570 cerr<<"Final Spanning tree---------\n";
571 printGraph(*t);
572 cerr<<"-------end spanning tree\n";
573#endif
Chris Lattnere1fc2d92002-05-22 21:56:32 +0000574
Chris Lattner18ff9452002-02-26 19:43:49 +0000575 //now remove the exit->root node
576 //and re-add it with weight 0
577 //since infinite weight is kinda confusing
578 g.removeEdge(ed);
579 Edge edNew(g.getExit(), g.getRoot(),0);
580 g.addEdge(edNew,0);
581 if(t->hasEdge(ed)){
582 t->removeEdge(ed);
583 t->addEdge(edNew,0);
584 }
585
Chris Lattnere1fc2d92002-05-22 21:56:32 +0000586 DEBUG(printGraph(g);
587 printGraph(*t));
588
Chris Lattner18ff9452002-02-26 19:43:49 +0000589 //step 5: Get edge increments
590
591 //Now we select a subset of all edges
592 //and assign them some values such that
593 //if we consider just this subset, it still represents
594 //the path sum along any path in the graph
Chris Lattnere1fc2d92002-05-22 21:56:32 +0000595
Anand Shuklaf94ad682002-09-16 05:26:51 +0000596 map<Edge, int, EdgeCompare2> increment=getEdgeIncrements(g,*t, be);
Anand Shukla21906892002-06-25 21:14:58 +0000597#ifdef DEBUG_PATH_PROFILES
598 //print edge increments for debugging
Anand Shuklaf94ad682002-09-16 05:26:51 +0000599 std::cerr<<"Edge Increments------\n";
600 for(map<Edge, int, EdgeCompare2>::iterator MMI=increment.begin(), MME=increment.end(); MMI != MME; ++MMI){
601 printEdge(MMI->first);
602 std::cerr<<"Increment for above:"<<MMI->second<<"\n";
Anand Shukla21906892002-06-25 21:14:58 +0000603 }
Anand Shuklaf94ad682002-09-16 05:26:51 +0000604 std::cerr<<"-------end of edge increments\n";
Anand Shukla21906892002-06-25 21:14:58 +0000605#endif
606
Chris Lattner18ff9452002-02-26 19:43:49 +0000607
608 //step 6: Get code insertions
609
610 //Based on edgeIncrements (above), now obtain
611 //the kind of code to be inserted along an edge
612 //The idea here is to minimize the computation
613 //by inserting only the needed code
614 vector<Edge> chords;
615 getChords(chords, g, *t);
616
Anand Shukla21906892002-06-25 21:14:58 +0000617
Anand Shuklaf94ad682002-09-16 05:26:51 +0000618 map<Edge, getEdgeCode *, EdgeCompare2> codeInsertions;
Chris Lattner18ff9452002-02-26 19:43:49 +0000619 getCodeInsertions(g, codeInsertions, chords,increment);
620
Anand Shukla21906892002-06-25 21:14:58 +0000621#ifdef DEBUG_PATH_PROFILES
622 //print edges with code for debugging
623 cerr<<"Code inserted in following---------------\n";
Anand Shuklaf94ad682002-09-16 05:26:51 +0000624 for(map<Edge, getEdgeCode *, EdgeCompare2>::iterator cd_i=codeInsertions.begin(),
Anand Shukla21906892002-06-25 21:14:58 +0000625 cd_e=codeInsertions.end(); cd_i!=cd_e; ++cd_i){
626 printEdge(cd_i->first);
627 cerr<<cd_i->second->getCond()<<":"<<cd_i->second->getInc()<<"\n";
628 }
629 cerr<<"-----end insertions\n";
630#endif
Chris Lattnere1fc2d92002-05-22 21:56:32 +0000631
Chris Lattner18ff9452002-02-26 19:43:49 +0000632 //step 7: move code on dummy edges over to the back edges
633
634 //Move the incoming dummy edge code and outgoing dummy
635 //edge code over to the corresponding back edge
Anand Shukla21906892002-06-25 21:14:58 +0000636
637 moveDummyCode(stDummy, exDummy, be, codeInsertions, g);
Anand Shukla2d3d20b2002-07-08 19:37:06 +0000638
Anand Shukla21906892002-06-25 21:14:58 +0000639#ifdef DEBUG_PATH_PROFILES
640 //debugging info
641 cerr<<"After moving dummy code\n";
642 for(map<Edge, getEdgeCode *>::iterator cd_i=codeInsertions.begin(),
643 cd_e=codeInsertions.end(); cd_i != cd_e; ++cd_i){
644 printEdge(cd_i->first);
645 cerr<<cd_i->second->getCond()<<":"
646 <<cd_i->second->getInc()<<"\n";
647 }
648 cerr<<"Dummy end------------\n";
649#endif
650
Chris Lattner18ff9452002-02-26 19:43:49 +0000651
652 //see what it looks like...
653 //now insert code along edges which have codes on them
654 for(map<Edge, getEdgeCode *>::iterator MI=codeInsertions.begin(),
655 ME=codeInsertions.end(); MI!=ME; ++MI){
656 Edge ed=MI->first;
Anand Shukla77dca142002-09-20 16:44:35 +0000657 insertBB(ed, MI->second, rInst, countInst, numPaths, MethNo, threshold);
Chris Lattner18ff9452002-02-26 19:43:49 +0000658 }
659}
660
Anand Shukla854c3022002-02-26 19:02:16 +0000661//print the graph (for debugging)
Chris Lattner570b8e12002-02-26 19:49:45 +0000662void printGraph(Graph &g){
Anand Shukla21906892002-06-25 21:14:58 +0000663 vector<Node *> lt=g.getAllNodes();
Anand Shukla854c3022002-02-26 19:02:16 +0000664 cerr<<"Graph---------------------\n";
Anand Shukla21906892002-06-25 21:14:58 +0000665 for(vector<Node *>::iterator LI=lt.begin();
Anand Shukla854c3022002-02-26 19:02:16 +0000666 LI!=lt.end(); ++LI){
667 cerr<<((*LI)->getElement())->getName()<<"->";
668 Graph::nodeList nl=g.getNodeList(*LI);
669 for(Graph::nodeList::iterator NI=nl.begin();
670 NI!=nl.end(); ++NI){
671 cerr<<":"<<"("<<(NI->element->getElement())
Anand Shukla21906892002-06-25 21:14:58 +0000672 ->getName()<<":"<<NI->element->getWeight()<<","<<NI->weight<<","
673 <<NI->randId<<")";
Anand Shukla854c3022002-02-26 19:02:16 +0000674 }
675 cerr<<"\n";
676 }
677 cerr<<"--------------------Graph\n";
678}
Brian Gaeke960707c2003-11-11 22:41:34 +0000679
680} // End llvm namespace