Incorporated changes in alloca and getElementPointer instruction
[oota-llvm.git] / lib / Transforms / Instrumentation / ProfilePaths / GraphAuxiliary.cpp
index c045762dcfe546c794ca3e0ed3510be962045aea..45ceadaa930763b650fdfb6aed96dc86f0580c2f 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#include "Graph.h"
+#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
+#include "llvm/Transforms/Instrumentation/Graph.h"
+#include "llvm/Function.h"
+#include "llvm/Pass.h"
+#include "llvm/Module.h"
+#include "llvm/Function.h"
 #include "llvm/BasicBlock.h"
+#include "llvm/InstrTypes.h"
+#include "llvm/iTerminators.h"
 #include <algorithm>
 #include <iostream>
+#include <sstream>
+#include <vector>
+#include <string>
 
-using std::list;
+//using std::list;
 using std::map;
 using std::vector;
 using std::cerr;
 
-//check if 2 edges are equal (same endpoints and same weight)
-static bool edgesEqual(Edge  ed1, Edge ed2);
-
-//Get the vector of edges that are to be instrumented in the graph
-static void getChords(vector<Edge > &chords, Graph g, Graph st);
-
-//Given a tree t, and a "directed graph" g
-//replace the edges in the tree t with edges that exist in graph
-//The tree is formed from "undirectional" copy of graph
-//So whatever edges the tree has, the undirectional graph 
-//would have too. This function corrects some of the directions in 
-//the tree so that now, all edge directions in the tree match
-//the edge directions of corresponding edges in the directed graph
-static void removeTreeEdges(Graph g, Graph& t);
-
-//Now we select a subset of all edges
-//and assign them some values such that 
-//if we consider just this subset, it still represents
-//the path sum along any path in the graph
-static map<Edge, int> getEdgeIncrements(Graph& g, Graph& t);
-
-//Based on edgeIncrements (above), now obtain
-//the kind of code to be inserted along an edge
-//The idea here is to minimize the computation
-//by inserting only the needed code
-static void getCodeInsertions(Graph &g, map<Edge, getEdgeCode *> &Insertions,
-                              vector<Edge > &chords, 
-                              map<Edge,int> &edIncrements);
-
-//Move the incoming dummy edge code and outgoing dummy
-//edge code over to the corresponding back edge
-static void moveDummyCode(const vector<Edge> &stDummy, 
-                          const vector<Edge> &exDummy, 
-                          const vector<Edge> &be,  
-                          map<Edge, getEdgeCode *> &insertions);
-
-
-
-//Do graph processing: to determine minimal edge increments, 
-//appropriate code insertions etc and insert the code at
-//appropriate locations
-void processGraph(Graph &g, 
-                 Instruction *rInst, 
-                 Instruction *countInst, 
-                 vector<Edge >& be, 
-                 vector<Edge >& stDummy, 
-                 vector<Edge >& exDummy){
-  //Given a graph: with exit->root edge, do the following in seq:
-  //1. get back edges
-  //2. insert dummy edges and remove back edges
-  //3. get edge assignments
-  //4. Get Max spanning tree of graph:
-  //   -Make graph g2=g undirectional
-  //   -Get Max spanning tree t
-  //   -Make t undirectional
-  //   -remove edges from t not in graph g
-  //5. Get edge increments
-  //6. Get code insertions
-  //7. move code on dummy edges over to the back edges
-  
-
-  //This is used as maximum "weight" for 
-  //priority queue
-  //This would hold all 
-  //right as long as number of paths in the graph
-  //is less than this
-  const int INFINITY=99999999;
-
-
-  //step 1-3 are already done on the graph when this function is called
-#ifdef DEBUG_PATH_PROFILES 
-  printGraph(g);
-#endif
-  //step 4: Get Max spanning tree of graph
-
-  //now insert exit to root edge
-  //if its there earlier, remove it!
-  //assign it weight INFINITY
-  //so that this edge IS ALWAYS IN spanning tree
-  //Note than edges in spanning tree do not get 
-  //instrumented: and we do not want the
-  //edge exit->root to get instrumented
-  //as it MAY BE a dummy edge
-  Edge ed(g.getExit(),g.getRoot(),INFINITY);
-  g.addEdge(ed,INFINITY);
-  Graph g2=g;
-
-  //make g2 undirectional: this gives a better
-  //maximal spanning tree
-  g2.makeUnDirectional();
-#ifdef DEBUG_PATH_PROFILES
-  printGraph(g2);
-#endif
-  Graph *t=g2.getMaxSpanningTree();
-#ifdef DEBUG_PATH_PROFILES
-  printGraph(*t);
-#endif
-  //now edges of tree t have weights reversed
-  //(negative) because the algorithm used
-  //to find max spanning tree is 
-  //actually for finding min spanning tree
-  //so get back the original weights
-  t->reverseWts();
-
-  //Ordinarily, the graph is directional
-  //lets converts the graph into an 
-  //undirectional graph
-  //This is done by adding an edge
-  //v->u for all existing edges u->v
-  t->makeUnDirectional();
-
-  //Given a tree t, and a "directed graph" g
-  //replace the edges in the tree t with edges that exist in graph
-  //The tree is formed from "undirectional" copy of graph
-  //So whatever edges the tree has, the undirectional graph 
-  //would have too. This function corrects some of the directions in 
-  //the tree so that now, all edge directions in the tree match
-  //the edge directions of corresponding edges in the directed graph
-  removeTreeEdges(g, *t);
-#ifdef DEBUG_PATH_PROFILES
-  cerr<<"Spanning tree---------\n";
-  printGraph(*t);
-  cerr<<"-------end spanning tree\n";
-#endif
-  //now remove the exit->root node
-  //and re-add it with weight 0
-  //since infinite weight is kinda confusing
-  g.removeEdge(ed);
-  Edge edNew(g.getExit(), g.getRoot(),0);
-  g.addEdge(edNew,0);
-  if(t->hasEdge(ed)){
-    t->removeEdge(ed);
-    t->addEdge(edNew,0);
-  }
-
-#ifdef DEBUG_PATH_PROFILES
-  printGraph(g);
-  printGraph(*t);
-#endif
-  //step 5: Get edge increments
-
-  //Now we select a subset of all edges
-  //and assign them some values such that 
-  //if we consider just this subset, it still represents
-  //the path sum along any path in the graph
-  map<Edge, int> increment=getEdgeIncrements(g,*t);
-#ifdef DEBUG_PATH_PROFILES
-  //print edge increments for debugging
-  for(map<Edge, int>::iterator M_I=increment.begin(), M_E=increment.end(); 
-      M_I!=M_E; ++M_I){
-    printEdge(M_I->first);
-    cerr<<"Increment for above:"<<M_I->second<<"\n";
-  }
-#endif
-  //step 6: Get code insertions
-  
-  //Based on edgeIncrements (above), now obtain
-  //the kind of code to be inserted along an edge
-  //The idea here is to minimize the computation
-  //by inserting only the needed code
-  vector<Edge> chords;
-  getChords(chords, g, *t);
-
-  map<Edge, getEdgeCode *> codeInsertions;
-  getCodeInsertions(g, codeInsertions, chords,increment);
-  
-#ifdef DEBUG_PATH_PROFILES
-  //print edges with code for debugging
-  cerr<<"Code inserted in following---------------\n";
-  for(map<Edge, getEdgeCode *>::iterator cd_i=codeInsertions->begin(), 
-       cd_e=codeInsertions->end(); cd_i!=cd_e; ++cd_i){
-    printEdge(cd_i->first);
-    cerr<<cd_i->second->getCond()<<":"<<cd_i->second->getInc()<<"\n";
-  }
-  cerr<<"-----end insertions\n";
-#endif
-  //step 7: move code on dummy edges over to the back edges
-
-  //Move the incoming dummy edge code and outgoing dummy
-  //edge code over to the corresponding back edge
-  moveDummyCode(stDummy, exDummy, be, codeInsertions);
-  
-#ifdef DEBUG_PATH_PROFILES
-  //debugging info
-  cerr<<"After moving dummy code\n";
-  for(map<Edge, getEdgeCode *>::iterator cd_i=codeInsertions.begin(), 
-       cd_e=codeInsertions.end(); cd_i != cd_e; ++cd_i){
-    printEdge(cd_i->first);
-    cerr<<cd_i->second->getCond()<<":"
-       <<cd_i->second->getInc()<<"\n";
-  }
-  cerr<<"Dummy end------------\n";
-#endif
-
-  //see what it looks like...
-  //now insert code along edges which have codes on them
-  for(map<Edge, getEdgeCode *>::iterator MI=codeInsertions.begin(), 
-       ME=codeInsertions.end(); MI!=ME; ++MI){
-    Edge ed=MI->first;
-    insertBB(ed, MI->second, rInst, countInst);
-  } 
-}
-
-
-
 //check if 2 edges are equal (same endpoints and same weight)
 static bool edgesEqual(Edge  ed1, Edge ed2){
   return ((ed1==ed2) && ed1.getWeight()==ed2.getWeight());
 }
 
 //Get the vector of edges that are to be instrumented in the graph
-static void getChords(vector<Edge > &chords, Graph g, Graph st){
+static void getChords(vector<Edge > &chords, Graph &g, Graph st){
   //make sure the spanning tree is directional
   //iterate over ALL the edges of the graph
-  list<Node *> allNodes=g.getAllNodes();
-  for(list<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; 
+  vector<Node *> allNodes=g.getAllNodes();
+  for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; 
       ++NI){
     Graph::nodeList node_list=g.getNodeList(*NI);
     for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end(); 
        NLI!=NLE; ++NLI){
-      Edge f(*NI, NLI->element,NLI->weight);
+      Edge f(*NI, NLI->element,NLI->weight, NLI->randId);
       if(!(st.hasEdgeAndWt(f)))//addnl
        chords.push_back(f);
     }
@@ -251,14 +55,13 @@ static void getChords(vector<Edge > &chords, Graph g, Graph st){
 //would have too. This function corrects some of the directions in 
 //the tree so that now, all edge directions in the tree match
 //the edge directions of corresponding edges in the directed graph
-static void removeTreeEdges(Graph g, Graph& t){
-  list<Node* > allNodes=t.getAllNodes();
-  for(list<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; 
+static void removeTreeEdges(Graph &g, Graph& t){
+  vector<Node* > allNodes=t.getAllNodes();
+  for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; 
       ++NI){
     Graph::nodeList nl=t.getNodeList(*NI);
     for(Graph::nodeList::iterator NLI=nl.begin(), NLE=nl.end();        NLI!=NLE;++NLI){
       Edge ed(NLI->element, *NI, NLI->weight);
-      //if(!g.hasEdge(ed)) t.removeEdge(ed);
       if(!g.hasEdgeAndWt(ed)) t.removeEdge(ed);//tree has only one edge
       //between any pair of vertices, so no need to delete by edge wt
     }
@@ -269,19 +72,67 @@ static void removeTreeEdges(Graph g, Graph& t){
 //such that if we traverse along any path from root to exit, and
 //add up the edge values, we get a path number that uniquely
 //refers to the path we travelled
-int valueAssignmentToEdges(Graph& g){
-  list<Node *> revtop=g.reverseTopologicalSort();
+int valueAssignmentToEdges(Graph& g,  map<Node *, int> nodePriority, 
+                           vector<Edge> &be){
+  vector<Node *> revtop=g.reverseTopologicalSort();
   map<Node *,int > NumPaths;
-  for(list<Node *>::iterator RI=revtop.begin(), RE=revtop.end(); RI!=RE; ++RI){
+  for(vector<Node *>::iterator RI=revtop.begin(), RE=revtop.end(); 
+      RI!=RE; ++RI){
     if(g.isLeaf(*RI))
       NumPaths[*RI]=1;
     else{
       NumPaths[*RI]=0;
-      list<Node *> succ=g.getSuccNodes(*RI);
-      for(list<Node *>::iterator SI=succ.begin(), SE=succ.end(); SI!=SE; ++SI){
-       Edge ed(*RI,*SI,NumPaths[*RI]);
-       g.setWeight(ed);
-       NumPaths[*RI]+=NumPaths[*SI];
+
+      // Modified Graph::nodeList &nlist=g.getNodeList(*RI);
+      Graph::nodeList &nlist=g.getSortedNodeList(*RI, be);
+
+      //sort nodelist by increasing order of numpaths
+      
+      int sz=nlist.size();
+      
+      for(int i=0;i<sz-1; i++){
+       int min=i;
+       for(int j=i+1; j<sz; j++){
+          BasicBlock *bb1 = nlist[j].element->getElement();
+          BasicBlock *bb2 = nlist[min].element->getElement();
+          
+          if(bb1 == bb2) continue;
+          
+          if(*RI == g.getRoot()){
+            assert(nodePriority[nlist[min].element]!= 
+                   nodePriority[nlist[j].element] 
+                   && "priorities can't be same!");
+            
+            if(nodePriority[nlist[j].element] < 
+               nodePriority[nlist[min].element])
+              min = j; 
+          }
+
+          else{
+            TerminatorInst *tti = (*RI)->getElement()->getTerminator();
+            
+            BranchInst *ti =  cast<BranchInst>(tti);
+            assert(ti && "not a branch");
+            assert(ti->getNumSuccessors()==2 && "less successors!");
+            
+            BasicBlock *tB = ti->getSuccessor(0);
+            BasicBlock *fB = ti->getSuccessor(1);
+            
+            if(tB == bb1 || fB == bb2)
+              min = j;
+          }
+          
+        }
+       graphListElement tempEl=nlist[min];
+       nlist[min]=nlist[i];
+       nlist[i]=tempEl;
+      }
+      
+      //sorted now!
+      for(Graph::nodeList::iterator GLI=nlist.begin(), GLE=nlist.end();
+         GLI!=GLE; ++GLI){
+               GLI->weight=NumPaths[*RI];
+       NumPaths[*RI]+=NumPaths[GLI->element];
       }
     }
   }
@@ -297,7 +148,7 @@ int valueAssignmentToEdges(Graph& g){
 //refers to the path we travelled
 //inc_Dir tells whether 2 edges are in same, or in different directions
 //if same direction, return 1, else -1
-static int inc_Dir(Edge e,Edge f){ 
+static int inc_Dir(Edge e, Edge f){ 
  if(e.isNull()) 
     return 1;
  
@@ -314,19 +165,20 @@ static int inc_Dir(Edge e,Edge f){
   return -1;
 }
 
+
 //used for getting edge increments (read comments above in inc_Dir)
 //inc_DFS is a modification of DFS 
-static void inc_DFS(Graph& g,Graph& t,map<Edge, int>& Increment, 
+static void inc_DFS(Graph& g,Graph& t,map<Edge, int, EdgeCompare2>& Increment, 
             int events, Node *v, Edge e){
   
-  list<Node *> allNodes=t.getAllNodes();
-  
-  for(list<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; 
+  vector<Node *> allNodes=t.getAllNodes();
+
+  for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; 
       ++NI){
     Graph::nodeList node_list=t.getNodeList(*NI);
     for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end(); 
        NLI!= NLE; ++NLI){
-      Edge f(*NI, NLI->element,NLI->weight);
+      Edge f(*NI, NLI->element,NLI->weight, NLI->randId);
       if(!edgesEqual(f,e) && *v==*(f.getSecond())){
        int dir_count=inc_Dir(e,f);
        int wt=1*f.getWeight();
@@ -335,15 +187,15 @@ static void inc_DFS(Graph& g,Graph& t,map<Edge, int>& Increment,
     }
   }
 
-  for(list<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; 
+  for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; 
       ++NI){
     Graph::nodeList node_list=t.getNodeList(*NI);
     for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end(); 
        NLI!=NLE; ++NLI){
-      Edge f(*NI, NLI->element,NLI->weight);
+      Edge f(*NI, NLI->element,NLI->weight, NLI->randId);
       if(!edgesEqual(f,e) && *v==*(f.getFirst())){
        int dir_count=inc_Dir(e,f);
-       int wt=1*f.getWeight();
+       int wt=f.getWeight();
        inc_DFS(g,t, Increment, dir_count*events+wt, 
                f.getSecond(), f);
       }
@@ -351,12 +203,12 @@ static void inc_DFS(Graph& g,Graph& t,map<Edge, int>& Increment,
   }
 
   allNodes=g.getAllNodes();
-  for(list<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; 
+  for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; 
       ++NI){
     Graph::nodeList node_list=g.getNodeList(*NI);
     for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end(); 
        NLI!=NLE; ++NLI){
-      Edge f(*NI, NLI->element,NLI->weight);
+      Edge f(*NI, NLI->element,NLI->weight, NLI->randId);
       if(!(t.hasEdgeAndWt(f)) && (*v==*(f.getSecond()) || 
                                  *v==*(f.getFirst()))){
        int dir_count=inc_Dir(e,f);
@@ -370,19 +222,21 @@ static void inc_DFS(Graph& g,Graph& t,map<Edge, int>& Increment,
 //and assign them some values such that 
 //if we consider just this subset, it still represents
 //the path sum along any path in the graph
-static map<Edge, int> getEdgeIncrements(Graph& g, Graph& t){
+static map<Edge, int, EdgeCompare2> getEdgeIncrements(Graph& g, Graph& t, 
+                                                      vector<Edge> &be){
   //get all edges in g-t
-  map<Edge, int> Increment;
+  map<Edge, int, EdgeCompare2> Increment;
 
-  list<Node *> allNodes=g.getAllNodes();
+  vector<Node *> allNodes=g.getAllNodes();
  
-  for(list<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; 
+  for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; 
       ++NI){
-    Graph::nodeList node_list=g.getNodeList(*NI);
+    Graph::nodeList node_list=g.getSortedNodeList(*NI, be);
+    //modified g.getNodeList(*NI);
     for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end(); 
        NLI!=NLE; ++NLI){
-      Edge ed(*NI, NLI->element,NLI->weight);
-      if(!(t.hasEdge(ed))){
+      Edge ed(*NI, NLI->element,NLI->weight,NLI->randId);
+      if(!(t.hasEdgeAndWt(ed))){
        Increment[ed]=0;;
       }
     }
@@ -391,14 +245,14 @@ static map<Edge, int> getEdgeIncrements(Graph& g, Graph& t){
   Edge *ed=new Edge();
   inc_DFS(g,t,Increment, 0, g.getRoot(), *ed);
 
-
-  for(list<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; 
+  for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; 
       ++NI){
-    Graph::nodeList node_list=g.getNodeList(*NI);
+    Graph::nodeList node_list=g.getSortedNodeList(*NI, be);
+    //modified g.getNodeList(*NI);
     for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end(); 
        NLI!=NLE; ++NLI){
-      Edge ed(*NI, NLI->element,NLI->weight);
-      if(!(t.hasEdge(ed))){
+      Edge ed(*NI, NLI->element,NLI->weight, NLI->randId);
+      if(!(t.hasEdgeAndWt(ed))){
        int wt=ed.getWeight();
        Increment[ed]+=wt;
       }
@@ -408,13 +262,20 @@ static map<Edge, int> getEdgeIncrements(Graph& g, Graph& t){
   return Increment;
 }
 
+//push it up: TODO
+const graphListElement *findNodeInList(const Graph::nodeList &NL,
+                                             Node *N);
+
+graphListElement *findNodeInList(Graph::nodeList &NL, Node *N);
+//end TODO
+
 //Based on edgeIncrements (above), now obtain
 //the kind of code to be inserted along an edge
 //The idea here is to minimize the computation
 //by inserting only the needed code
-static void getCodeInsertions(Graph &g, map<Edge, getEdgeCode *> &instr,
+static void getCodeInsertions(Graph &g, map<Edge, getEdgeCode *, EdgeCompare2> &instr,
                               vector<Edge > &chords, 
-                              map<Edge,int> &edIncrements){
+                              map<Edge,int, EdgeCompare2> &edIncrements){
 
   //Register initialization code
   vector<Node *> ws;
@@ -430,22 +291,22 @@ static void getCodeInsertions(Graph &g, map<Edge, getEdgeCode *> &instr,
       int edgeWt=nl->weight;
       Node *w=nl->element;
       //if chords has v->w
-      Edge ed(v,w);
-      
+      Edge ed(v,w, edgeWt, nl->randId);
       bool hasEdge=false;
       for(vector<Edge>::iterator CI=chords.begin(), CE=chords.end();
          CI!=CE && !hasEdge;++CI){
-       if(*CI==ed){
+       if(*CI==ed && CI->getWeight()==edgeWt){//modf
          hasEdge=true;
        }
       }
-      if(hasEdge){
+
+      if(hasEdge){//so its a chord edge
        getEdgeCode *edCd=new getEdgeCode();
        edCd->setCond(1);
        edCd->setInc(edIncrements[ed]);
        instr[ed]=edCd;
       }
-      else if((g.getPredNodes(w)).size()==1){
+      else if(g.getNumberOfIncomingEdges(w)==1){
        ws.push_back(w);
       }
       else{
@@ -463,44 +324,53 @@ static void getCodeInsertions(Graph &g, map<Edge, getEdgeCode *> &instr,
   while(!ws.empty()) {
     Node *w=ws.back();
     ws.pop_back();
-    
-    //for each edge v->w
-    list<Node *> preds=g.getPredNodes(w);
-    for(list<Node *>::iterator pd=preds.begin(), pe=preds.end(); pd!=pe; ++pd){
-      Node *v=*pd;
-      //if chords has v->w
-    
-      Edge ed(v,w);
-      getEdgeCode *edCd=new getEdgeCode();
-      bool hasEdge=false;
-      for(vector<Edge>::iterator CI=chords.begin(), CE=chords.end(); CI!=CE;
-         ++CI){
-       if(*CI==ed){
-         hasEdge=true;
-         break;
-       }
-      }
-      if(hasEdge){
-       char str[100];
-       if(instr[ed]!=NULL && instr[ed]->getCond()==1){
-         instr[ed]->setCond(4);
-       }
-       else{
-         edCd->setCond(5);
-         edCd->setInc(edIncrements[ed]);
-         instr[ed]=edCd;
-       }
-       
-      }
-      else if(g.getSuccNodes(v).size()==1)
-       ws.push_back(v);
-      else{
-       edCd->setCond(6);
-       instr[ed]=edCd;
+
+
+    ///////
+    //vector<Node *> lt;
+    vector<Node *> lllt=g.getAllNodes();
+    for(vector<Node *>::iterator EII=lllt.begin(); EII!=lllt.end() ;++EII){
+      Node *lnode=*EII;
+      Graph::nodeList &nl = g.getNodeList(lnode);
+      //graphListElement *N = findNodeInList(nl, w);
+      for(Graph::nodeList::const_iterator N = nl.begin(), 
+            NNEN = nl.end(); N!= NNEN; ++N){
+        if (*N->element == *w){        
+          Node *v=lnode;
+          
+          //if chords has v->w
+          Edge ed(v,w, N->weight, N->randId);
+          getEdgeCode *edCd=new getEdgeCode();
+          bool hasEdge=false;
+          for(vector<Edge>::iterator CI=chords.begin(), CE=chords.end(); CI!=CE;
+              ++CI){
+            if(*CI==ed && CI->getWeight()==N->weight){
+              hasEdge=true;
+              break;
+            }
+          }
+          if(hasEdge){
+            //char str[100];
+            if(instr[ed]!=NULL && instr[ed]->getCond()==1){
+              instr[ed]->setCond(4);
+            }
+            else{
+              edCd->setCond(5);
+              edCd->setInc(edIncrements[ed]);
+              instr[ed]=edCd;
+            }
+            
+          }
+          else if(g.getNumberOfOutgoingEdges(v)==1)
+            ws.push_back(v);
+          else{
+            edCd->setCond(6);
+            instr[ed]=edCd;
+          }
+        }
       }
     }
   }
-
   ///// Register increment code
   for(vector<Edge>::iterator CI=chords.begin(), CE=chords.end(); CI!=CE; ++CI){
     getEdgeCode *edCd=new getEdgeCode();
@@ -516,6 +386,7 @@ static void getCodeInsertions(Graph &g, map<Edge, getEdgeCode *> &instr,
 //If a->b is a backedge
 //then incoming dummy edge is root->b
 //and outgoing dummy edge is a->exit
+//changed
 void addDummyEdges(vector<Edge > &stDummy, 
                   vector<Edge > &exDummy, 
                   Graph &g, vector<Edge> &be){
@@ -526,21 +397,15 @@ void addDummyEdges(vector<Edge > &stDummy,
     g.removeEdge(ed);
 
     if(!(*second==*(g.getRoot()))){
-      Edge *st=new Edge(g.getRoot(), second); 
-      
-      //check if stDummy doesn't have it already
-      if(find(stDummy.begin(), stDummy.end(), *st) == stDummy.end())
-       stDummy.push_back(*st);
+      Edge *st=new Edge(g.getRoot(), second, ed.getWeight(), ed.getRandId());
+      stDummy.push_back(*st);
       g.addEdgeForce(*st);
     }
 
     if(!(*first==*(g.getExit()))){
-      Edge *ex=new Edge(first, g.getExit());
-      
-      if (find(exDummy.begin(), exDummy.end(), *ex) == exDummy.end()) {
-       exDummy.push_back(*ex);
-       g.addEdgeForce(*ex);
-      }
+      Edge *ex=new Edge(first, g.getExit(), ed.getWeight(), ed.getRandId());
+      exDummy.push_back(*ex);
+      g.addEdgeForce(*ex);
     }
   }
 }
@@ -550,133 +415,260 @@ void printEdge(Edge ed){
   cerr<<((ed.getFirst())->getElement())
     ->getName()<<"->"<<((ed.getSecond())
                          ->getElement())->getName()<<
-    ":"<<ed.getWeight()<<"\n";
+    ":"<<ed.getWeight()<<" rndId::"<<ed.getRandId()<<"\n";
 }
 
 //Move the incoming dummy edge code and outgoing dummy
 //edge code over to the corresponding back edge
-static void moveDummyCode(const vector<Edge> &stDummy, 
-                          const vector<Edge> &exDummy, 
-                          const vector<Edge> &be,  
-                          map<Edge, getEdgeCode *> &insertions){
-  typedef vector<Edge >::const_iterator vec_iter;
+static void moveDummyCode(vector<Edge> &stDummy, 
+                          vector<Edge> &exDummy, 
+                          vector<Edge> &be,  
+                          map<Edge, getEdgeCode *, EdgeCompare2> &insertions, 
+                         Graph &g){
+  typedef vector<Edge >::iterator vec_iter;
   
-#ifdef DEBUG_PATH_PROFILES
-  //print all back, st and ex dummy
-  cerr<<"BackEdges---------------\n";
-  for(vec_iter VI=be.begin(); VI!=be.end(); ++VI)
-    printEdge(*VI);
-  cerr<<"StEdges---------------\n";
-  for(vec_iter VI=stDummy.begin(); VI!=stDummy.end(); ++VI)
-    printEdge(*VI);
-  cerr<<"ExitEdges---------------\n";
-  for(vec_iter VI=exDummy.begin(); VI!=exDummy.end(); ++VI)
-    printEdge(*VI);
-  cerr<<"------end all edges\n";
-#endif
-
+  map<Edge,getEdgeCode *, EdgeCompare2> temp;
+  //iterate over edges with code
   std::vector<Edge> toErase;
-  for(map<Edge,getEdgeCode *>::iterator MI=insertions.begin(), 
+  for(map<Edge,getEdgeCode *, EdgeCompare2>::iterator MI=insertions.begin(), 
        ME=insertions.end(); MI!=ME; ++MI){
     Edge ed=MI->first;
     getEdgeCode *edCd=MI->second;
-    bool dummyHasIt=false;
+
+    ///---new code
+    //iterate over be, and check if its starts and end vertices hv code
+    for(vector<Edge>::iterator BEI=be.begin(), BEE=be.end(); BEI!=BEE; ++BEI){
+      if(ed.getRandId()==BEI->getRandId()){
+       
+       if(temp[*BEI]==0)
+         temp[*BEI]=new getEdgeCode();
+       
+       //so ed is either in st, or ex!
+       if(ed.getFirst()==g.getRoot()){
+
+         //so its in stDummy
+         temp[*BEI]->setCdIn(edCd);
+         toErase.push_back(ed);
+       }
+       else if(ed.getSecond()==g.getExit()){
+
+         //so its in exDummy
+         toErase.push_back(ed);
+         temp[*BEI]->setCdOut(edCd);
+       }
+       else{
+         assert(false && "Not found in either start or end! Rand failed?");
+       }
+      }
+    }
+  }
+  
+  for(vector<Edge >::iterator vmi=toErase.begin(), vme=toErase.end(); vmi!=vme; 
+      ++vmi){
+    insertions.erase(*vmi);
+    g.removeEdgeWithWt(*vmi);
+  }
+  
+  for(map<Edge,getEdgeCode *, EdgeCompare2>::iterator MI=temp.begin(), 
+      ME=temp.end(); MI!=ME; ++MI){
+    insertions[MI->first]=MI->second;
+  }
+    
 #ifdef DEBUG_PATH_PROFILES
-    cerr<<"Current edge considered---\n";
-    printEdge(ed);
+  cerr<<"size of deletions: "<<toErase.size()<<"\n";
+  cerr<<"SIZE OF INSERTIONS AFTER DEL "<<insertions.size()<<"\n";
 #endif
-    //now check if stDummy has ed
-    for(vec_iter VI=stDummy.begin(), VE=stDummy.end(); VI!=VE && !dummyHasIt; 
-       ++VI){
-      if(*VI==ed){
+
+}
+
+//Do graph processing: to determine minimal edge increments, 
+//appropriate code insertions etc and insert the code at
+//appropriate locations
+void processGraph(Graph &g, 
+                 Instruction *rInst, 
+                 Instruction *countInst, 
+                 vector<Edge >& be, 
+                 vector<Edge >& stDummy, 
+                 vector<Edge >& exDummy, 
+                 int numPaths, int MethNo){
+
+  //Given a graph: with exit->root edge, do the following in seq:
+  //1. get back edges
+  //2. insert dummy edges and remove back edges
+  //3. get edge assignments
+  //4. Get Max spanning tree of graph:
+  //   -Make graph g2=g undirectional
+  //   -Get Max spanning tree t
+  //   -Make t undirectional
+  //   -remove edges from t not in graph g
+  //5. Get edge increments
+  //6. Get code insertions
+  //7. move code on dummy edges over to the back edges
+  
+
+  //This is used as maximum "weight" for 
+  //priority queue
+  //This would hold all 
+  //right as long as number of paths in the graph
+  //is less than this
+  const int INFINITY=99999999;
+
+
+  //step 1-3 are already done on the graph when this function is called
+  DEBUG(printGraph(g));
+
+  //step 4: Get Max spanning tree of graph
+
+  //now insert exit to root edge
+  //if its there earlier, remove it!
+  //assign it weight INFINITY
+  //so that this edge IS ALWAYS IN spanning tree
+  //Note than edges in spanning tree do not get 
+  //instrumented: and we do not want the
+  //edge exit->root to get instrumented
+  //as it MAY BE a dummy edge
+  Edge ed(g.getExit(),g.getRoot(),INFINITY);
+  g.addEdge(ed,INFINITY);
+  Graph g2=g;
+
+  //make g2 undirectional: this gives a better
+  //maximal spanning tree
+  g2.makeUnDirectional();
+  DEBUG(printGraph(g2));
+
+  Graph *t=g2.getMaxSpanningTree();
 #ifdef DEBUG_PATH_PROFILES
-       cerr<<"Edge matched with stDummy\n";
+  std::cerr<<"Original maxspanning tree\n";
+  printGraph(*t);
 #endif
-       dummyHasIt=true;
-       bool dummyInBe=false;
-       //dummy edge with code
-       for(vec_iter BE=be.begin(), BEE=be.end(); BE!=BEE && !dummyInBe; ++BE){
-         Edge backEdge=*BE;
-         Node *st=backEdge.getSecond();
-         Node *dm=ed.getSecond();
-         if(*dm==*st){
-           //so this is the back edge to use
+  //now edges of tree t have weights reversed
+  //(negative) because the algorithm used
+  //to find max spanning tree is 
+  //actually for finding min spanning tree
+  //so get back the original weights
+  t->reverseWts();
+
+  //Ordinarily, the graph is directional
+  //lets converts the graph into an 
+  //undirectional graph
+  //This is done by adding an edge
+  //v->u for all existing edges u->v
+  t->makeUnDirectional();
+
+  //Given a tree t, and a "directed graph" g
+  //replace the edges in the tree t with edges that exist in graph
+  //The tree is formed from "undirectional" copy of graph
+  //So whatever edges the tree has, the undirectional graph 
+  //would have too. This function corrects some of the directions in 
+  //the tree so that now, all edge directions in the tree match
+  //the edge directions of corresponding edges in the directed graph
+  removeTreeEdges(g, *t);
+
 #ifdef DEBUG_PATH_PROFILES
-           cerr<<"Moving to backedge\n";
-           printEdge(backEdge);
+  cerr<<"Final Spanning tree---------\n";
+  printGraph(*t);
+  cerr<<"-------end spanning tree\n";
 #endif
-           getEdgeCode *ged=new getEdgeCode();
-           ged->setCdIn(edCd);
-           toErase.push_back(ed);
-           insertions[backEdge]=ged;
-           dummyInBe=true;
-         }
-       }
-       assert(dummyInBe);
-      }
-    }
-    if(!dummyHasIt){
-      //so exDummy may hv it
-      bool inExDummy=false;
-      for(vec_iter VI=exDummy.begin(), VE=exDummy.end(); VI!=VE && !inExDummy; 
-         ++VI){
-       if(*VI==ed){
-         inExDummy=true;
+
+  //now remove the exit->root node
+  //and re-add it with weight 0
+  //since infinite weight is kinda confusing
+  g.removeEdge(ed);
+  Edge edNew(g.getExit(), g.getRoot(),0);
+  g.addEdge(edNew,0);
+  if(t->hasEdge(ed)){
+    t->removeEdge(ed);
+    t->addEdge(edNew,0);
+  }
+
+  DEBUG(printGraph(g);
+        printGraph(*t));
+
+  //step 5: Get edge increments
+
+  //Now we select a subset of all edges
+  //and assign them some values such that 
+  //if we consider just this subset, it still represents
+  //the path sum along any path in the graph
+
+  map<Edge, int, EdgeCompare2> increment=getEdgeIncrements(g,*t, be);
 #ifdef DEBUG_PATH_PROFILES
-         cerr<<"Edge matched with exDummy\n";
-#endif
-         bool dummyInBe2=false;
-         //dummy edge with code
-         for(vec_iter BE=be.begin(), BEE=be.end(); BE!=BEE && !dummyInBe2; 
-             ++BE){
-           Edge backEdge=*BE;
-           Node *st=backEdge.getFirst();
-           Node *dm=ed.getFirst();
-           if(*dm==*st){
-             //so this is the back edge to use
-             getEdgeCode *ged;
-             if(insertions[backEdge]==NULL)
-               ged=new getEdgeCode();
-             else
-               ged=insertions[backEdge];
-             toErase.push_back(ed);
-             ged->setCdOut(edCd);
-             insertions[backEdge]=ged;
-             dummyInBe2=true;
-           }
-         }
-         assert(dummyInBe2);
-       }
-      }
-    }
+  //print edge increments for debugging
+  std::cerr<<"Edge Increments------\n";
+  for(map<Edge, int, EdgeCompare2>::iterator MMI=increment.begin(), MME=increment.end(); MMI != MME; ++MMI){
+    printEdge(MMI->first);
+    std::cerr<<"Increment for above:"<<MMI->second<<"\n";
   }
+  std::cerr<<"-------end of edge increments\n";
+#endif
+
+  //step 6: Get code insertions
+  
+  //Based on edgeIncrements (above), now obtain
+  //the kind of code to be inserted along an edge
+  //The idea here is to minimize the computation
+  //by inserting only the needed code
+  vector<Edge> chords;
+  getChords(chords, g, *t);
 
+
+  map<Edge, getEdgeCode *, EdgeCompare2> codeInsertions;
+  getCodeInsertions(g, codeInsertions, chords,increment);
+  
 #ifdef DEBUG_PATH_PROFILES
-  cerr<<"size of deletions: "<<toErase.size()<<"\n";
+  //print edges with code for debugging
+  cerr<<"Code inserted in following---------------\n";
+  for(map<Edge, getEdgeCode *, EdgeCompare2>::iterator cd_i=codeInsertions.begin(), 
+       cd_e=codeInsertions.end(); cd_i!=cd_e; ++cd_i){
+    printEdge(cd_i->first);
+    cerr<<cd_i->second->getCond()<<":"<<cd_i->second->getInc()<<"\n";
+  }
+  cerr<<"-----end insertions\n";
 #endif
 
-  for(vector<Edge >::iterator vmi=toErase.begin(), vme=toErase.end(); vmi!=vme; 
-      ++vmi)
-    insertions.erase(*vmi);
+  //step 7: move code on dummy edges over to the back edges
+
+  //Move the incoming dummy edge code and outgoing dummy
+  //edge code over to the corresponding back edge
 
+  moveDummyCode(stDummy, exDummy, be, codeInsertions, g);
+  
 #ifdef DEBUG_PATH_PROFILES
-  cerr<<"SIZE OF INSERTIONS AFTER DEL "<<insertions.size()<<"\n";
+  //debugging info
+  cerr<<"After moving dummy code\n";
+  for(map<Edge, getEdgeCode *>::iterator cd_i=codeInsertions.begin(), 
+       cd_e=codeInsertions.end(); cd_i != cd_e; ++cd_i){
+    printEdge(cd_i->first);
+    cerr<<cd_i->second->getCond()<<":"
+       <<cd_i->second->getInc()<<"\n";
+  }
+  cerr<<"Dummy end------------\n";
 #endif
-}
 
 
+  //see what it looks like...
+  //now insert code along edges which have codes on them
+  for(map<Edge, getEdgeCode *>::iterator MI=codeInsertions.begin(), 
+       ME=codeInsertions.end(); MI!=ME; ++MI){
+    Edge ed=MI->first;
+    insertBB(ed, MI->second, rInst, countInst, numPaths, MethNo);
+  } 
+}
+
 //print the graph (for debugging)
-void printGraph(Graph g){
-  list<Node *> lt=g.getAllNodes();
+void printGraph(Graph &g){
+  vector<Node *> lt=g.getAllNodes();
   cerr<<"Graph---------------------\n";
-  for(list<Node *>::iterator LI=lt.begin(); 
+  for(vector<Node *>::iterator LI=lt.begin(); 
       LI!=lt.end(); ++LI){
     cerr<<((*LI)->getElement())->getName()<<"->";
     Graph::nodeList nl=g.getNodeList(*LI);
     for(Graph::nodeList::iterator NI=nl.begin(); 
        NI!=nl.end(); ++NI){
       cerr<<":"<<"("<<(NI->element->getElement())
-       ->getName()<<":"<<NI->element->getWeight()<<","<<NI->weight<<")";
+       ->getName()<<":"<<NI->element->getWeight()<<","<<NI->weight<<","
+         <<NI->randId<<")";
     }
     cerr<<"\n";
   }