1 //===-- ------------------------llvm/graph.h ---------------------*- C++ -*--=//
3 //Header file for Graph: This Graph is used by
4 //PathProfiles class, and is used
5 //for detecting proper points in cfg for code insertion
7 //===----------------------------------------------------------------------===//
12 #include "llvm/BasicBlock.h"
20 //It forms the vertex for the graph
26 inline Node(BasicBlock* x) { element=x; weight=0; }
27 inline BasicBlock* &getElement() { return element; }
28 inline BasicBlock* const &getElement() const { return element; }
29 inline int getWeight() { return weight; }
30 inline void setElement(BasicBlock* e) { element=e; }
31 inline void setWeight(int w) { weight=w;}
32 inline bool operator<(Node& nd) const { return element<nd.element; }
33 inline bool operator==(Node& nd) const { return element==nd.element; }
37 //Denotes an edge in the graph
46 inline Edge(Node *f,Node *s, int wt=0){
54 inline Edge(Node *f,Node *s, int wt, double rd){
62 inline Edge() { isnull = true; }
63 inline double getRandId(){ return randId; }
64 inline Node* getFirst() { assert(!isNull()); return first; }
65 inline Node* const getFirst() const { assert(!isNull()); return first; }
66 inline Node* getSecond() { assert(!isNull()); return second; }
67 inline Node* const getSecond() const { assert(!isNull()); return second; }
69 inline int getWeight() { assert(!isNull()); return weight; }
70 inline void setWeight(int n) { assert(!isNull()); weight=n; }
72 inline void setFirst(Node *&f) { assert(!isNull()); first=f; }
73 inline void setSecond(Node *&s) { assert(!isNull()); second=s; }
76 inline bool isNull() const { return isnull;}
78 inline bool operator<(const Edge& ed) const{
79 // Can't be the same if one is null and the other isn't
80 if (isNull() != ed.isNull())
83 return (*first<*(ed.getFirst()))||
84 (*first==*(ed.getFirst()) && *second<*(ed.getSecond()));
87 inline bool operator==(const Edge& ed) const{
88 return !(*this<ed) && !(ed<*this);
91 inline bool operator!=(const Edge& ed) const{return !(*this==ed);}
96 //This forms the "adjacency list element" of a
97 //vertex adjacency list in graph
98 struct graphListElement{
102 inline graphListElement(Node *n, int w, double rand){
111 struct less<Node *> : public binary_function<Node *, Node *,bool> {
112 bool operator()(Node *n1, Node *n2) const {
113 return n1->getElement() < n2->getElement();
117 struct less<Edge> : public binary_function<Edge,Edge,bool> {
118 bool operator()(Edge e1, Edge e2) const {
119 assert(!e1.isNull() && !e2.isNull());
121 Node *x1=e1.getFirst();
122 Node *x2=e1.getSecond();
123 Node *y1=e2.getFirst();
124 Node *y2=e2.getSecond();
125 return (*x1<*y1 ||(*x1==*y1 && *x2<*y2));
131 bool operator()(BasicBlock *BB1, BasicBlock *BB2) const{
132 std::string name1=BB1->getName();
133 std::string name2=BB2->getName();
139 bool operator()(graphListElement BB1, graphListElement BB2) const{
140 std::string name1=BB1.element->getElement()->getName();
141 std::string name2=BB2.element->getElement()->getName();
147 bool operator()(Edge e1, Edge e2) const {
148 assert(!e1.isNull() && !e2.isNull());
149 Node *x1=e1.getFirst();
150 Node *x2=e1.getSecond();
151 Node *y1=e2.getFirst();
152 Node *y2=e2.getSecond();
153 int w1=e1.getWeight();
154 int w2=e2.getWeight();
155 double r1 = e1.getRandId();
156 double r2 = e2.getRandId();
157 //return (*x1<*y1 || (*x1==*y1 && *x2<*y2) || (*x1==*y1 && *x2==*y2 && w1<w2));
158 return (*x1<*y1 || (*x1==*y1 && *x2<*y2) || (*x1==*y1 && *x2==*y2 && w1<w2) || (*x1==*y1 && *x2==*y2 && w1==w2 && r1<r2));
162 //struct EdgeCompare2{
163 //bool operator()(Edge e1, Edge e2) const {
164 // assert(!e1.isNull() && !e2.isNull());
165 // return (e1.getRandId()<e2.getRandId());
170 //this is used to color vertices
179 //For path profiling,
180 //We assume that the graph is connected (which is true for
182 //We also assume that the graph has single entry and single exit
183 //(For this, we make a pass over the graph that ensures this)
184 //The graph is a construction over any existing graph of BBs
185 //Its a construction "over" existing cfg: with
186 //additional features like edges and weights to edges
188 //graph uses adjacency list representation
191 //typedef std::map<Node*, std::list<graphListElement> > nodeMapTy;
192 typedef std::map<Node*, std::vector<graphListElement> > nodeMapTy;//chng
194 //the adjacency list of a vertex or node
197 //the start or root node
203 //a private method for doing DFS traversal of graph
204 //this is used in determining the reverse topological sort
206 void DFS_Visit(Node *nd, std::vector<Node *> &toReturn);
208 //Its a variation of DFS to get the backedges in the graph
209 //We get back edges by associating a time
210 //and a color with each vertex.
211 //The time of a vertex is the time when it was first visited
212 //The color of a vertex is initially WHITE,
213 //Changes to GREY when it is first visited,
214 //and changes to BLACK when ALL its neighbors
216 //So we have a back edge when we meet a successor of
217 //a node with smaller time, and GREY color
218 void getBackEdgesVisit(Node *u,
219 std::vector<Edge > &be,
220 std::map<Node *, Color> &clr,
221 std::map<Node *, int> &d,
225 typedef nodeMapTy::iterator elementIterator;
226 typedef nodeMapTy::const_iterator constElementIterator;
227 typedef std::vector<graphListElement > nodeList;//chng
228 //typedef std::vector<graphListElement > nodeList;
232 //empty constructor: then add edges and nodes later on
235 //constructor with root and exit node specified
236 Graph(std::vector<Node*> n,
237 std::vector<Edge> e, Node *rt, Node *lt);
240 void addNode(Node *nd);
243 //this adds an edge ONLY when
244 //the edge to be added doesn not already exist
245 //we "equate" two edges here only with their
247 void addEdge(Edge ed, int w);
249 //add an edge EVEN IF such an edge already exists
250 //this may make a multi-graph
251 //which does happen when we add dummy edges
252 //to the graph, for compensating for back-edges
253 void addEdgeForce(Edge ed);
255 //set the weight of an edge
256 void setWeight(Edge ed);
259 //Note that it removes just one edge,
260 //the first edge that is encountered
261 void removeEdge(Edge ed);
263 //remove edge with given wt
264 void removeEdgeWithWt(Edge ed);
266 //check whether graph has an edge
267 //having an edge simply means that there is an edge in the graph
268 //which has same endpoints as the given edge
269 //it may possibly have different weight though
270 bool hasEdge(Edge ed);
272 //check whether graph has an edge, with a given wt
273 bool hasEdgeAndWt(Edge ed);
275 //get the list of successor nodes
276 std::vector<Node *> getSuccNodes(Node *nd);
278 //get the number of outgoing edges
279 int getNumberOfOutgoingEdges(Node *nd) const;
281 //get the list of predecessor nodes
282 std::vector<Node *> getPredNodes(Node *nd);
285 //to get the no of incoming edges
286 int getNumberOfIncomingEdges(Node *nd);
288 //get the list of all the vertices in graph
289 std::vector<Node *> getAllNodes() const;
290 std::vector<Node *> getAllNodes();
292 //get a list of nodes in the graph
293 //in r-topological sorted order
294 //note that we assumed graph to be connected
295 std::vector<Node *> reverseTopologicalSort();
297 //reverse the sign of weights on edges
298 //this way, max-spanning tree could be obtained
299 //usin min-spanning tree, and vice versa
302 //Ordinarily, the graph is directional
303 //this converts the graph into an
304 //undirectional graph
305 //This is done by adding an edge
306 //v->u for all existing edges u->v
307 void makeUnDirectional();
309 //print graph: for debugging
312 //get a vector of back edges in the graph
313 void getBackEdges(std::vector<Edge> &be, std::map<Node *, int> &d);
315 nodeList &sortNodeList(Node *par, nodeList &nl, std::vector<Edge> &be);
317 //Get the Maximal spanning tree (also a graph)
319 Graph* getMaxSpanningTree();
321 //get the nodeList adjacent to a node
322 //a nodeList element contains a node, and the weight
323 //corresponding to the edge for that element
324 inline nodeList &getNodeList(Node *nd) {
325 elementIterator nli = nodes.find(nd);
326 assert(nli != nodes.end() && "Node must be in nodes map");
327 return nodes[nd];//sortNodeList(nd, nli->second);
330 nodeList &getSortedNodeList(Node *nd, std::vector<Edge> &be) {
331 elementIterator nli = nodes.find(nd);
332 assert(nli != nodes.end() && "Node must be in nodes map");
333 return sortNodeList(nd, nodes[nd], be);
336 //get the root of the graph
337 inline Node *getRoot() {return strt; }
338 inline Node * const getRoot() const {return strt; }
340 //get exit: we assumed there IS a unique exit :)
341 inline Node *getExit() {return ext; }
342 inline Node * const getExit() const {return ext; }
343 //Check if a given node is the root
344 inline bool isRoot(Node *n) const {return (*n==*strt); }
346 //check if a given node is leaf node
347 //here we hv only 1 leaf: which is the exit node
348 inline bool isLeaf(Node *n) const {return (*n==*ext); }
351 //This class is used to generate
352 //"appropriate" code to be inserted
354 //The code to be inserted can be of six different types
356 //1: r=k (where k is some constant)
365 //"kind" of code is to be inserted
368 //inc is the increment: eg k, or 0
371 //A backedge must carry the code
372 //of both incoming "dummy" edge
373 //and outgoing "dummy" edge
374 //If a->b is a backedge
375 //then incoming dummy edge is root->b
376 //and outgoing dummy edge is a->exit
378 //incoming dummy edge, if any
381 //outgoing dummy edge, if any
393 inline void setCond(int n) {cond=n;}
396 inline int getCond() { return cond;}
399 inline void setInc(int n) {inc=n;}
402 inline int getInc() {return inc;}
404 //set CdIn (only used for backedges)
405 inline void setCdIn(getEdgeCode *gd){ cdIn=gd;}
407 //set CdOut (only used for backedges)
408 inline void setCdOut(getEdgeCode *gd){ cdOut=gd;}
410 //get the code to be inserted on the edge
411 //This is determined from cond (1-6)
412 void getCode(Instruction *a, Value *b, Function *M, BasicBlock *BB,
413 std::vector<Value *> &retVec);
417 //auxillary functions on graph
419 //print a given edge in the form BB1Label->BB2Label
420 void printEdge(Edge ed);
422 //Do graph processing: to determine minimal edge increments,
423 //appropriate code insertions etc and insert the code at
424 //appropriate locations
425 void processGraph(Graph &g, Instruction *rInst, Value *countInst, std::vector<Edge> &be, std::vector<Edge> &stDummy, std::vector<Edge> &exDummy, int n, int MethNo, Value *threshold);
427 //print the graph (for debugging)
428 void printGraph(Graph &g);
431 //void printGraph(const Graph g);
432 //insert a basic block with appropriate code
434 void insertBB(Edge ed, getEdgeCode *edgeCode, Instruction *rInst, Value *countInst, int n, int Methno, Value *threshold);
436 //Insert the initialization code in the top BB
437 //this includes initializing r, and count
438 //r is like an accumulator, that
439 //keeps on adding increments as we traverse along a path
440 //and at the end of the path, r contains the path
441 //number of that path
442 //Count is an array, where Count[k] represents
443 //the number of executions of path k
444 void insertInTopBB(BasicBlock *front, int k, Instruction *rVar, Value *threshold);
446 //Add dummy edges corresponding to the back edges
447 //If a->b is a backedge
448 //then incoming dummy edge is root->b
449 //and outgoing dummy edge is a->exit
450 void addDummyEdges(std::vector<Edge> &stDummy, std::vector<Edge> &exDummy, Graph &g, std::vector<Edge> &be);
452 //Assign a value to all the edges in the graph
453 //such that if we traverse along any path from root to exit, and
454 //add up the edge values, we get a path number that uniquely
455 //refers to the path we travelled
456 int valueAssignmentToEdges(Graph& g, std::map<Node *, int> nodePriority,
457 std::vector<Edge> &be);
459 void getBBtrace(std::vector<BasicBlock *> &vBB, int pathNo, Function *M);