blob: e40037f6bab352f3bb5282fb8f0d4fff73ac62b4 [file] [log] [blame]
Anand Shukla854c3022002-02-26 19:02:16 +00001//===-- GrapAuxillary.cpp- Auxillary functions on graph ----------*- C++ -*--=//
2//
3//auxillary function associated with graph: they
4//all operate on graph, and help in inserting
5//instrumentation for trace generation
6//
7//===----------------------------------------------------------------------===//
8
9#include "Graph.h"
10#include "llvm/BasicBlock.h"
11#include <algorithm>
12
13//check if 2 edges are equal (same endpoints and same weight)
14static bool edgesEqual(Edge ed1, Edge ed2);
15
16//Get the vector of edges that are to be instrumented in the graph
17static void getChords(vector<Edge > &chords, Graph g, Graph st);
18
19//Given a tree t, and a "directed graph" g
20//replace the edges in the tree t with edges that exist in graph
21//The tree is formed from "undirectional" copy of graph
22//So whatever edges the tree has, the undirectional graph
23//would have too. This function corrects some of the directions in
24//the tree so that now, all edge directions in the tree match
25//the edge directions of corresponding edges in the directed graph
26static void removeTreeEdges(Graph g, Graph& t);
27
28//Now we select a subset of all edges
29//and assign them some values such that
30//if we consider just this subset, it still represents
31//the path sum along any path in the graph
32static map<Edge, int> getEdgeIncrements(Graph& g, Graph& t);
33
34//Based on edgeIncrements (above), now obtain
35//the kind of code to be inserted along an edge
36//The idea here is to minimize the computation
37//by inserting only the needed code
38static map<Edge, getEdgeCode *>*
39getCodeInsertions(Graph &g,
40 vector<Edge > &chords,
41 map<Edge,int> &edIncrements);
42
43//Move the incoming dummy edge code and outgoing dummy
44//edge code over to the corresponding back edge
45static void moveDummyCode(vector<Edge > stDummy,
46 vector<Edge > exDummy,
47 vector<Edge > be,
48 map<Edge, getEdgeCode *> &insertions);
49
50
51
52//Do graph processing: to determine minimal edge increments,
53//appropriate code insertions etc and insert the code at
54//appropriate locations
55void processGraph(Graph &g,
56 Instruction *rInst,
57 Instruction *countInst,
58 vector<Edge >& be,
59 vector<Edge >& stDummy,
60 vector<Edge >& exDummy){
61 //Given a graph: with exit->root edge, do the following in seq:
62 //1. get back edges
63 //2. insert dummy edges and remove back edges
64 //3. get edge assignments
65 //4. Get Max spanning tree of graph:
66 // -Make graph g2=g undirectional
67 // -Get Max spanning tree t
68 // -Make t undirectional
69 // -remove edges from t not in graph g
70 //5. Get edge increments
71 //6. Get code insertions
72 //7. move code on dummy edges over to the back edges
73
74
75 //This is used as maximum "weight" for
76 //priority queue
77 //This would hold all
78 //right as long as number of paths in the graph
79 //is less than this
80 const int INFINITY=99999999;
81
82
83 //step 1-3 are already done on the graph when this function is called
84#ifdef DEBUG_PATH_PROFILES
85 printGraph(g);
86#endif
87 //step 4: Get Max spanning tree of graph
88
89 //now insert exit to root edge
90 //if its there earlier, remove it!
91 //assign it weight INFINITY
92 //so that this edge IS ALWAYS IN spanning tree
93 //Note than edges in spanning tree do not get
94 //instrumented: and we do not want the
95 //edge exit->root to get instrumented
96 //as it MAY BE a dummy edge
97 Edge ed(g.getExit(),g.getRoot(),INFINITY);
98 g.addEdge(ed,INFINITY);
99 Graph g2=g;
100
101 //make g2 undirectional: this gives a better
102 //maximal spanning tree
103 g2.makeUnDirectional();
104#ifdef DEBUG_PATH_PROFILES
105 printGraph(g2);
106#endif
107 Graph *t=g2.getMaxSpanningTree();
108#ifdef DEBUG_PATH_PROFILES
109 printGraph(*t);
110#endif
111 //now edges of tree t have weights reversed
112 //(negative) because the algorithm used
113 //to find max spanning tree is
114 //actually for finding min spanning tree
115 //so get back the original weights
116 t->reverseWts();
117
118 //Ordinarily, the graph is directional
119 //lets converts the graph into an
120 //undirectional graph
121 //This is done by adding an edge
122 //v->u for all existing edges u->v
123 t->makeUnDirectional();
124
125 //Given a tree t, and a "directed graph" g
126 //replace the edges in the tree t with edges that exist in graph
127 //The tree is formed from "undirectional" copy of graph
128 //So whatever edges the tree has, the undirectional graph
129 //would have too. This function corrects some of the directions in
130 //the tree so that now, all edge directions in the tree match
131 //the edge directions of corresponding edges in the directed graph
132 removeTreeEdges(g, *t);
133#ifdef DEBUG_PATH_PROFILES
134 cerr<<"Spanning tree---------\n";
135 printGraph(*t);
136 cerr<<"-------end spanning tree\n";
137#endif
138 //now remove the exit->root node
139 //and re-add it with weight 0
140 //since infinite weight is kinda confusing
141 g.removeEdge(ed);
142 Edge edNew(g.getExit(), g.getRoot(),0);
143 g.addEdge(edNew,0);
144 if(t->hasEdge(ed)){
145 t->removeEdge(ed);
146 t->addEdge(edNew,0);
147 }
148
149#ifdef DEBUG_PATH_PROFILES
150 printGraph(g);
151 printGraph(*t);
152#endif
153 //step 5: Get edge increments
154
155 //Now we select a subset of all edges
156 //and assign them some values such that
157 //if we consider just this subset, it still represents
158 //the path sum along any path in the graph
159 map<Edge, int> increment=getEdgeIncrements(g,*t);
160#ifdef DEBUG_PATH_PROFILES
161 //print edge increments for debugging
162 for(map<Edge, int>::iterator M_I=increment.begin(), M_E=increment.end();
163 M_I!=M_E; ++M_I){
164 printEdge(M_I->first);
165 cerr<<"Increment for above:"<<M_I->second<<endl;
166 }
167#endif
168
169 //step 6: Get code insertions
170
171 //Based on edgeIncrements (above), now obtain
172 //the kind of code to be inserted along an edge
173 //The idea here is to minimize the computation
174 //by inserting only the needed code
175 map<Edge, getEdgeCode *>* codeInsertions;
176 vector<Edge > chords;
177 getChords(chords, g, *t);
178 codeInsertions=getCodeInsertions(g,chords,increment);
179
180#ifdef DEBUG_PATH_PROFILES
181 //print edges with code for debugging
182 cerr<<"Code inserted in following---------------\n";
183 for(map<Edge, getEdgeCode *>::iterator cd_i=codeInsertions->begin(),
184 cd_e=codeInsertions->end(); cd_i!=cd_e; ++cd_i){
185 printEdge(cd_i->first);
186 cerr<<cd_i->second->getCond()<<":"<<cd_i->second->getInc()<<endl;
187 }
188 cerr<<"-----end insertions\n";
189#endif
190 //step 7: move code on dummy edges over to the back edges
191
192 //Move the incoming dummy edge code and outgoing dummy
193 //edge code over to the corresponding back edge
194 moveDummyCode(stDummy, exDummy, be, *codeInsertions);
195
196#ifdef DEBUG_PATH_PROFILES
197 //debugging info
198 cerr<<"After moving dummy code\n";
199 for(map<Edge, getEdgeCode *>::iterator cd_i=codeInsertions->begin(),
200 cd_e=codeInsertions->end(); cd_i!=cd_e; ++cd_i){
201 printEdge(cd_i->first);
202 cerr<<cd_i->second->getCond()<<":"
203 <<cd_i->second->getInc()<<endl;
204 }
205 cerr<<"Dummy end------------\n";
206#endif
207
208 //see what it looks like...
209 //now insert code along edges which have codes on them
210 for(map<Edge, getEdgeCode *>::iterator MI=codeInsertions->begin(),
211 ME=codeInsertions->end(); MI!=ME; ++MI){
212 Edge ed=MI->first;
213 insertBB(ed, MI->second, rInst, countInst);
214 }
215}
216
217
218
219//check if 2 edges are equal (same endpoints and same weight)
220static bool edgesEqual(Edge ed1, Edge ed2){
221 return ((ed1==ed2) && ed1.getWeight()==ed2.getWeight());
222}
223
224//Get the vector of edges that are to be instrumented in the graph
225static void getChords(vector<Edge > &chords, Graph g, Graph st){
226 //make sure the spanning tree is directional
227 //iterate over ALL the edges of the graph
228 list<Node *> allNodes=g.getAllNodes();
229 for(list<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
230 ++NI){
231 Graph::nodeList node_list=g.getNodeList(*NI);
232 for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end();
233 NLI!=NLE; ++NLI){
234 Edge f(*NI, NLI->element,NLI->weight);
235 if(!(st.hasEdgeAndWt(f)))//addnl
236 chords.push_back(f);
237 }
238 }
239}
240
241//Given a tree t, and a "directed graph" g
242//replace the edges in the tree t with edges that exist in graph
243//The tree is formed from "undirectional" copy of graph
244//So whatever edges the tree has, the undirectional graph
245//would have too. This function corrects some of the directions in
246//the tree so that now, all edge directions in the tree match
247//the edge directions of corresponding edges in the directed graph
248static void removeTreeEdges(Graph g, Graph& t){
249 list<Node* > allNodes=t.getAllNodes();
250 for(list<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
251 ++NI){
252 Graph::nodeList nl=t.getNodeList(*NI);
253 for(Graph::nodeList::iterator NLI=nl.begin(), NLE=nl.end(); NLI!=NLE;++NLI){
254 Edge ed(NLI->element, *NI, NLI->weight);
255 //if(!g.hasEdge(ed)) t.removeEdge(ed);
256 if(!g.hasEdgeAndWt(ed)) t.removeEdge(ed);//tree has only one edge
257 //between any pair of vertices, so no need to delete by edge wt
258 }
259 }
260}
261
262//Assign a value to all the edges in the graph
263//such that if we traverse along any path from root to exit, and
264//add up the edge values, we get a path number that uniquely
265//refers to the path we travelled
266int valueAssignmentToEdges(Graph& g){
267 list<Node *> revtop=g.reverseTopologicalSort();
268 map<Node *,int > NumPaths;
269 for(list<Node *>::iterator RI=revtop.begin(), RE=revtop.end(); RI!=RE; ++RI){
270 if(g.isLeaf(*RI))
271 NumPaths[*RI]=1;
272 else{
273 NumPaths[*RI]=0;
274 list<Node *> succ=g.getSuccNodes(*RI);
275 for(list<Node *>::iterator SI=succ.begin(), SE=succ.end(); SI!=SE; ++SI){
276 Edge ed(*RI,*SI,NumPaths[*RI]);
277 g.setWeight(ed);
278 NumPaths[*RI]+=NumPaths[*SI];
279 }
280 }
281 }
282 return NumPaths[g.getRoot()];
283}
284
285//This is a helper function to get the edge increments
286//This is used in conjuntion with inc_DFS
287//to get the edge increments
288//Edge increment implies assigning a value to all the edges in the graph
289//such that if we traverse along any path from root to exit, and
290//add up the edge values, we get a path number that uniquely
291//refers to the path we travelled
292//inc_Dir tells whether 2 edges are in same, or in different directions
293//if same direction, return 1, else -1
294static int inc_Dir(Edge e,Edge f){
295 if(e.isNull())
296 return 1;
297
298 //check that the edges must have atleast one common endpoint
299 assert(*(e.getFirst())==*(f.getFirst()) ||
300 *(e.getFirst())==*(f.getSecond()) ||
301 *(e.getSecond())==*(f.getFirst()) ||
302 *(e.getSecond())==*(f.getSecond()));
303
304 if(*(e.getFirst())==*(f.getSecond()) ||
305 *(e.getSecond())==*(f.getFirst()))
306 return 1;
307
308 return -1;
309}
310
311//used for getting edge increments (read comments above in inc_Dir)
312//inc_DFS is a modification of DFS
313static void inc_DFS(Graph& g,Graph& t,map<Edge, int>& Increment,
314 int events, Node *v, Edge e){
315
316 list<Node *> allNodes=t.getAllNodes();
317
318 for(list<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
319 ++NI){
320 Graph::nodeList node_list=t.getNodeList(*NI);
321 for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end();
322 NLI!= NLE; ++NLI){
323 Edge f(*NI, NLI->element,NLI->weight);
324 if(!edgesEqual(f,e) && *v==*(f.getSecond())){
325 int dir_count=inc_Dir(e,f);
326 int wt=1*f.getWeight();
327 inc_DFS(g,t, Increment, dir_count*events+wt, f.getFirst(), f);
328 }
329 }
330 }
331
332 for(list<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
333 ++NI){
334 Graph::nodeList node_list=t.getNodeList(*NI);
335 for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end();
336 NLI!=NLE; ++NLI){
337 Edge f(*NI, NLI->element,NLI->weight);
338 if(!edgesEqual(f,e) && *v==*(f.getFirst())){
339 int dir_count=inc_Dir(e,f);
340 int wt=1*f.getWeight();
341 inc_DFS(g,t, Increment, dir_count*events+wt,
342 f.getSecond(), f);
343 }
344 }
345 }
346
347 allNodes=g.getAllNodes();
348 for(list<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
349 ++NI){
350 Graph::nodeList node_list=g.getNodeList(*NI);
351 for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end();
352 NLI!=NLE; ++NLI){
353 Edge f(*NI, NLI->element,NLI->weight);
354 if(!(t.hasEdgeAndWt(f)) && (*v==*(f.getSecond()) ||
355 *v==*(f.getFirst()))){
356 int dir_count=inc_Dir(e,f);
357 Increment[f]+=dir_count*events;
358 }
359 }
360 }
361}
362
363//Now we select a subset of all edges
364//and assign them some values such that
365//if we consider just this subset, it still represents
366//the path sum along any path in the graph
367static map<Edge, int> getEdgeIncrements(Graph& g, Graph& t){
368 //get all edges in g-t
369 map<Edge, int> Increment;
370
371 list<Node *> allNodes=g.getAllNodes();
372
373 for(list<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
374 ++NI){
375 Graph::nodeList node_list=g.getNodeList(*NI);
376 for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end();
377 NLI!=NLE; ++NLI){
378 Edge ed(*NI, NLI->element,NLI->weight);
379 if(!(t.hasEdge(ed))){
380 Increment[ed]=0;;
381 }
382 }
383 }
384
385 Edge *ed=new Edge();
386 inc_DFS(g,t,Increment, 0, g.getRoot(), *ed);
387
388
389 for(list<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
390 ++NI){
391 Graph::nodeList node_list=g.getNodeList(*NI);
392 for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end();
393 NLI!=NLE; ++NLI){
394 Edge ed(*NI, NLI->element,NLI->weight);
395 if(!(t.hasEdge(ed))){
396 int wt=ed.getWeight();
397 Increment[ed]+=wt;
398 }
399 }
400 }
401
402 return Increment;
403}
404
405//Based on edgeIncrements (above), now obtain
406//the kind of code to be inserted along an edge
407//The idea here is to minimize the computation
408//by inserting only the needed code
409static map<Edge, getEdgeCode *>*
410getCodeInsertions(Graph &g,
411 vector<Edge > &chords,
412 map<Edge,int> &edIncrements){
413 //map of instrumented edges that's returned in the end
414 map<Edge, getEdgeCode *> *instr=
415 new map<Edge, getEdgeCode *>;
416
417 //Register initialization code
418 vector<Node *> ws;
419 ws.push_back(g.getRoot());
420 while(ws.size()>0){
421 Node *v=ws[0];
422 ws.erase(ws.begin());
423 //for each edge v->w
424 Graph::nodeList succs=g.getNodeList(v);
425
426 for(Graph::nodeList::iterator nl=succs.begin(), ne=succs.end();
427 nl!=ne; ++nl){
428 int edgeWt=nl->weight;
429 Node *w=nl->element;
430 //if chords has v->w
431 Edge ed(v,w);
432
433 bool hasEdge=false;
434 for(vector<Edge>::iterator CI=chords.begin(), CE=chords.end();
435 CI!=CE && !hasEdge;++CI){
436 if(*CI==ed){
437 hasEdge=true;
438 }
439 }
440 if(hasEdge){
441 getEdgeCode *edCd=new getEdgeCode();
442 edCd->setCond(1);
443 edCd->setInc(edIncrements[ed]);
444 (*instr)[ed]=edCd;
445 }
446 else if((g.getPredNodes(w)).size()==1){
447 ws.push_back(w);
448 }
449 else{
450 getEdgeCode *edCd=new getEdgeCode();
451 edCd->setCond(2);
452 edCd->setInc(0);
453 (*instr)[ed]=edCd;
454 }
455 }
456 }
457
458 /////Memory increment code
459 ws.push_back(g.getExit());
460
461 while(ws.size()>0){
462 Node *w=ws[0];
463 ws.erase(&ws[0]);
464
465 //for each edge v->w
466 list<Node *> preds=g.getPredNodes(w);
467 for(list<Node *>::iterator pd=preds.begin(), pe=preds.end(); pd!=pe; ++pd){
468 Node *v=*pd;
469 //if chords has v->w
470
471 Edge ed(v,w);
472 getEdgeCode *edCd=new getEdgeCode();
473 bool hasEdge=false;
474 for(vector<Edge>::iterator CI=chords.begin(), CE=chords.end(); CI!=CE;
475 ++CI){
476 if(*CI==ed){
477 hasEdge=true;
478 break;
479 }
480 }
481 if(hasEdge){
482 char str[100];
483 if((*instr)[ed]!=NULL && (*instr)[ed]->getCond()==1){
484 (*instr)[ed]->setCond(4);
485 }
486 else{
487 edCd->setCond(5);
488 edCd->setInc(edIncrements[ed]);
489 (*instr)[ed]=edCd;
490 }
491
492 }
493 else if(g.getSuccNodes(v).size()==1)
494 ws.push_back(v);
495 else{
496 edCd->setCond(6);
497 (*instr)[ed]=edCd;
498 }
499 }
500 }
501
502 ///// Register increment code
503 for(vector<Edge>::iterator CI=chords.begin(), CE=chords.end(); CI!=CE; ++CI){
504 getEdgeCode *edCd=new getEdgeCode();
505 if((*instr)[*CI]==NULL){
506 edCd->setCond(3);
507 edCd->setInc(edIncrements[*CI]);
508 (*instr)[*CI]=edCd;
509 }
510 }
511
512 return instr;
513}
514
515//Add dummy edges corresponding to the back edges
516//If a->b is a backedge
517//then incoming dummy edge is root->b
518//and outgoing dummy edge is a->exit
519void addDummyEdges(vector<Edge > &stDummy,
520 vector<Edge > &exDummy,
521 Graph &g, vector<Edge > be){
522 for(vector<Edge >::iterator VI=be.begin(), VE=be.end(); VI!=VE; ++VI){
523 Edge ed=*VI;
524 Node *first=ed.getFirst();
525 Node *second=ed.getSecond();
526 g.removeEdge(ed);
527
528 if(!(*second==*(g.getRoot()))){
529 Edge *st=new Edge(g.getRoot(), second);
530
531 //check if stDummy doesn't have it already
532 bool hasIt=false;
533
534 if(find(stDummy.begin(), stDummy.end(), *st)!=stDummy.end())
535 hasIt=true;
536
537 /*
538 for(vector<Edge>::iterator DM=stDummy.begin(), DE=stDummy.end(); DM!=DE;
539 ++DM){
540 if(*DM==*st){
541 hasIt=true;
542 break;
543 }
544 }
545 */
546
547 if(!hasIt){
548 stDummy.push_back(*st);
549 g.addEdgeForce(*st);
550 }
551 }
552
553 if(!(*first==*(g.getExit()))){
554 Edge *ex=new Edge(first, g.getExit());
555
556 bool hasIt=false;
557 if(find(exDummy.begin(), exDummy.end(), *ex)!=exDummy.end())
558 hasIt=true;
559
560 /*
561 for(vector<Edge>::iterator DM=exDummy.begin(), DE=exDummy.end(); DM!=DE;
562 ++DM){
563 if(*DM==*ex){
564 hasIt=true;
565 break;
566 }
567 }
568 */
569
570 if(!hasIt){
571 exDummy.push_back(*ex);
572 g.addEdgeForce(*ex);
573 }
574 }
575 }
576}
577
578//print a given edge in the form BB1Label->BB2Label
579void printEdge(Edge ed){
580 cerr<<((ed.getFirst())->getElement())
581 ->getName()<<"->"<<((ed.getSecond())
582 ->getElement())->getName()<<
583 ":"<<ed.getWeight()<<endl;
584}
585
586//Move the incoming dummy edge code and outgoing dummy
587//edge code over to the corresponding back edge
588static void moveDummyCode(vector<Edge > stDummy,
589 vector<Edge > exDummy,
590 vector<Edge > be,
591 map<Edge, getEdgeCode *> &insertions){
592 typedef vector<Edge >::iterator vec_iter;
593
594#ifdef DEBUG_PATH_PROFILES
595 //print all back, st and ex dummy
596 cerr<<"BackEdges---------------\n";
597 for(vec_iter VI=be.begin(); VI!=be.end(); ++VI)
598 printEdge(*VI);
599 cerr<<"StEdges---------------\n";
600 for(vec_iter VI=stDummy.begin(); VI!=stDummy.end(); ++VI)
601 printEdge(*VI);
602 cerr<<"ExitEdges---------------\n";
603 for(vec_iter VI=exDummy.begin(); VI!=exDummy.end(); ++VI)
604 printEdge(*VI);
605 cerr<<"------end all edges\n";
606#endif
607
608 std::vector<Edge > toErase;
609 for(map<Edge,getEdgeCode *>::iterator MI=insertions.begin(),
610 ME=insertions.end(); MI!=ME; ++MI){
611 Edge ed=MI->first;
612 getEdgeCode *edCd=MI->second;
613 bool dummyHasIt=false;
614#ifdef DEBUG_PATH_PROFILES
615 cerr<<"Current edge considered---\n";
616 printEdge(ed);
617#endif
618 //now check if stDummy has ed
619 for(vec_iter VI=stDummy.begin(), VE=stDummy.end(); VI!=VE && !dummyHasIt;
620 ++VI){
621 if(*VI==ed){
622#ifdef DEBUG_PATH_PROFILES
623 cerr<<"Edge matched with stDummy\n";
624#endif
625 dummyHasIt=true;
626 bool dummyInBe=false;
627 //dummy edge with code
628 for(vec_iter BE=be.begin(), BEE=be.end(); BE!=BEE && !dummyInBe; ++BE){
629 Edge backEdge=*BE;
630 Node *st=backEdge.getSecond();
631 Node *dm=ed.getSecond();
632 if(*dm==*st){
633 //so this is the back edge to use
634#ifdef DEBUG_PATH_PROFILES
635 cerr<<"Moving to backedge\n";
636 printEdge(backEdge);
637#endif
638 getEdgeCode *ged=new getEdgeCode();
639 ged->setCdIn(edCd);
640 toErase.push_back(ed);
641 insertions[backEdge]=ged;
642 dummyInBe=true;
643 }
644 }
645 assert(dummyInBe);
646 }
647 }
648 if(!dummyHasIt){
649 //so exDummy may hv it
650 bool inExDummy=false;
651 for(vec_iter VI=exDummy.begin(), VE=exDummy.end(); VI!=VE && !inExDummy;
652 ++VI){
653 if(*VI==ed){
654 inExDummy=true;
655#ifdef DEBUG_PATH_PROFILES
656 cerr<<"Edge matched with exDummy\n";
657#endif
658 bool dummyInBe2=false;
659 //dummy edge with code
660 for(vec_iter BE=be.begin(), BEE=be.end(); BE!=BEE && !dummyInBe2;
661 ++BE){
662 Edge backEdge=*BE;
663 Node *st=backEdge.getFirst();
664 Node *dm=ed.getFirst();
665 if(*dm==*st){
666 //so this is the back edge to use
667 getEdgeCode *ged;
668 if(insertions[backEdge]==NULL)
669 ged=new getEdgeCode();
670 else
671 ged=insertions[backEdge];
672 toErase.push_back(ed);
673 ged->setCdOut(edCd);
674 insertions[backEdge]=ged;
675 dummyInBe2=true;
676 }
677 }
678 assert(dummyInBe2);
679 }
680 }
681 }
682 }
683
684#ifdef DEBUG_PATH_PROFILES
685 cerr<<"size of deletions: "<<toErase.size()<<endl;
686#endif
687
688 for(vector<Edge >::iterator vmi=toErase.begin(), vme=toErase.end(); vmi!=vme;
689 ++vmi)
690 insertions.erase(*vmi);
691
692#ifdef DEBUG_PATH_PROFILES
693 cerr<<"SIZE OF INSERTIONS AFTER DEL "<<insertions.size()<<endl;
694#endif
695}
696
697
698//print the graph (for debugging)
699void printGraph(Graph g){
700 list<Node *> lt=g.getAllNodes();
701 cerr<<"Graph---------------------\n";
702 for(list<Node *>::iterator LI=lt.begin();
703 LI!=lt.end(); ++LI){
704 cerr<<((*LI)->getElement())->getName()<<"->";
705 Graph::nodeList nl=g.getNodeList(*LI);
706 for(Graph::nodeList::iterator NI=nl.begin();
707 NI!=nl.end(); ++NI){
708 cerr<<":"<<"("<<(NI->element->getElement())
709 ->getName()<<":"<<NI->element->getWeight()<<","<<NI->weight<<")";
710 }
711 cerr<<"\n";
712 }
713 cerr<<"--------------------Graph\n";
714}