diff options
author | Anand Shukla <ashukla@cs.uiuc.edu> | 2002-06-25 14:28:55 +0000 |
---|---|---|
committer | Anand Shukla <ashukla@cs.uiuc.edu> | 2002-06-25 14:28:55 +0000 |
commit | c43fa80e1fd1fa319f050a2906ca1726d8d51cf1 (patch) | |
tree | ce5521b70c0d755afe1fa9942338c59fbf62ac24 /lib/Transforms | |
parent | 15c5977869a0460096756fcc89553bf3bf8d6a87 (diff) |
Relocating Graph.h
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2770 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Instrumentation/ProfilePaths/Graph.h | 465 |
1 files changed, 465 insertions, 0 deletions
diff --git a/lib/Transforms/Instrumentation/ProfilePaths/Graph.h b/lib/Transforms/Instrumentation/ProfilePaths/Graph.h new file mode 100644 index 0000000000..22280d2db7 --- /dev/null +++ b/lib/Transforms/Instrumentation/ProfilePaths/Graph.h @@ -0,0 +1,465 @@ +//===-- ------------------------llvm/graph.h ---------------------*- C++ -*--=// +// +//Header file for Graph: This Graph is used by +//PathProfiles class, and is used +//for detecting proper points in cfg for code insertion +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_GRAPH_H +#define LLVM_GRAPH_H + +#include "Support/StatisticReporter.h" + +#include <map> +//#include <list> +//#include <set> +#include <vector> +#include <cstdlib> + +#include "llvm/BasicBlock.h" + +class BasicBlock; +//class Method; +class Module; +//======= +class Function; +//>>>>>>> 1.4 +class Instruction; + +//Class Node +//It forms the vertex for the graph +class Node{ +public: + BasicBlock* element; + int weight; +public: + inline Node(BasicBlock* x) { element=x; weight=0; } + inline BasicBlock* &getElement() { return element; } + inline BasicBlock* const &getElement() const { return element; } + inline int getWeight() { return weight; } + inline void setElement(BasicBlock* e) { element=e; } + inline void setWeight(int w) { weight=w;} + inline bool operator<(Node& nd) const { return element<nd.element; } + inline bool operator==(Node& nd) const { return element==nd.element; } +}; +//////////////////////// + +//Class Edge +//Denotes an edge in the graph +class Edge{ +private: + Node *first; + Node *second; + bool isnull; + int weight; + double randId; +public: + inline Edge(Node *f,Node *s, int wt=0){ + first=f; + second=s; + weight=wt; + randId=rand(); + isnull=false; + } + + inline Edge(Node *f,Node *s, int wt, double rd){ + first=f; + second=s; + weight=wt; + randId=rd; + isnull=false; + } + + inline Edge() { isnull = true; } + inline double getRandId(){ return randId; } + inline Node* getFirst() { assert(!isNull()); return first; } + inline Node* const getFirst() const { assert(!isNull()); return first; } + inline Node* getSecond() { assert(!isNull()); return second; } + inline Node* const getSecond() const { assert(!isNull()); return second; } + + inline int getWeight() { assert(!isNull()); return weight; } + inline void setWeight(int n) { assert(!isNull()); weight=n; } + + inline void setFirst(Node *&f) { assert(!isNull()); first=f; } + inline void setSecond(Node *&s) { assert(!isNull()); second=s; } + + + inline bool isNull() const { return isnull;} + + inline bool operator<(const Edge& ed) const{ + // Can't be the same if one is null and the other isn't + if (isNull() != ed.isNull()) + return true; + + return (*first<*(ed.getFirst()))|| + (*first==*(ed.getFirst()) && *second<*(ed.getSecond())); + } + + inline bool operator==(const Edge& ed) const{ + return !(*this<ed) && !(ed<*this); + } + + inline bool operator!=(const Edge& ed) const{return !(*this==ed);} +}; +//////////////////////// + +//graphListElement +//This forms the "adjacency list element" of a +//vertex adjacency list in graph +struct graphListElement{ + Node *element; + int weight; + double randId; + inline graphListElement(Node *n, int w, double rand){ + element=n; + weight=w; + randId=rand; + } +}; +///////////////////////// + +namespace std { + struct less<Node *> : public binary_function<Node *, Node *,bool> { + bool operator()(Node *n1, Node *n2) const { + return n1->getElement() < n2->getElement(); + } + }; + + struct less<Edge> : public binary_function<Edge,Edge,bool> { + bool operator()(Edge e1, Edge e2) const { + assert(!e1.isNull() && !e2.isNull()); + + Node *x1=e1.getFirst(); + Node *x2=e1.getSecond(); + Node *y1=e2.getFirst(); + Node *y2=e2.getSecond(); + return (*x1<*y1 ||(*x1==*y1 && *x2<*y2)); + } + }; +} + +struct BBSort{ + bool operator()(BasicBlock *BB1, BasicBlock *BB2) const{ + std::string name1=BB1->getName(); + std::string name2=BB2->getName(); + return name1<name2; + } +}; + +struct NodeListSort{ + bool operator()(graphListElement BB1, graphListElement BB2) const{ + std::string name1=BB1.element->getElement()->getName(); + std::string name2=BB2.element->getElement()->getName(); + return name1<name2; + } +}; +struct EdgeCompare{ + bool operator()(Edge e1, Edge e2) const { + assert(!e1.isNull() && !e2.isNull()); + Node *x1=e1.getFirst(); + Node *x2=e1.getSecond(); + Node *y1=e2.getFirst(); + Node *y2=e2.getSecond(); + int w1=e1.getWeight(); + int w2=e2.getWeight(); + return (*x1<*y1 || (*x1==*y1 && *x2<*y2) || (*x1==*y1 && *x2==*y2 && w1<w2)); + } +}; + +//////////////////// + +//this is used to color vertices +//during DFS +enum Color{ + WHITE, + GREY, + BLACK +}; + + +//For path profiling, +//We assume that the graph is connected (which is true for +//any method CFG) +//We also assume that the graph has single entry and single exit +//(For this, we make a pass over the graph that ensures this) +//The graph is a construction over any existing graph of BBs +//Its a construction "over" existing cfg: with +//additional features like edges and weights to edges + +//graph uses adjacency list representation +class Graph{ +public: + //typedef std::map<Node*, std::list<graphListElement> > nodeMapTy; + typedef std::map<Node*, std::vector<graphListElement> > nodeMapTy;//chng +private: + //the adjacency list of a vertex or node + nodeMapTy nodes; + + //the start or root node + Node *strt; + + //the exit node + Node *ext; + + //a private method for doing DFS traversal of graph + //this is used in determining the reverse topological sort + //of the graph + void DFS_Visit(Node *nd, std::vector<Node *> &toReturn) const; + + //Its a variation of DFS to get the backedges in the graph + //We get back edges by associating a time + //and a color with each vertex. + //The time of a vertex is the time when it was first visited + //The color of a vertex is initially WHITE, + //Changes to GREY when it is first visited, + //and changes to BLACK when ALL its neighbors + //have been visited + //So we have a back edge when we meet a successor of + //a node with smaller time, and GREY color + void getBackEdgesVisit(Node *u, + std::vector<Edge > &be, + std::map<Node *, Color> &clr, + std::map<Node *, int> &d, + int &time) const; + +public: + typedef nodeMapTy::iterator elementIterator; + typedef nodeMapTy::const_iterator constElementIterator; + typedef std::vector<graphListElement > nodeList;//chng + //typedef std::vector<graphListElement > nodeList; + + //graph constructors + + //empty constructor: then add edges and nodes later on + Graph() {} + + //constructor with root and exit node specified + Graph(std::vector<Node*> n, + std::vector<Edge> e, Node *rt, Node *lt); + + //add a node + void addNode(Node *nd); + + //add an edge + //this adds an edge ONLY when + //the edge to be added doesn not already exist + //we "equate" two edges here only with their + //end points + void addEdge(Edge ed, int w); + + //add an edge EVEN IF such an edge already exists + //this may make a multi-graph + //which does happen when we add dummy edges + //to the graph, for compensating for back-edges + void addEdgeForce(Edge ed); + + //set the weight of an edge + void setWeight(Edge ed); + + //remove an edge + //Note that it removes just one edge, + //the first edge that is encountered + void removeEdge(Edge ed); + + //remove edge with given wt + void removeEdgeWithWt(Edge ed); + + //check whether graph has an edge + //having an edge simply means that there is an edge in the graph + //which has same endpoints as the given edge + //it may possibly have different weight though + bool hasEdge(Edge ed) const; + + //check whether graph has an edge, with a given wt + bool hasEdgeAndWt(Edge ed) const; + + //get the list of successor nodes + std::vector<Node *> getSuccNodes(Node *nd) const; + + //get the number of outgoing edges + int getNumberOfOutgoingEdges(Node *nd) const; + + //get the list of predecessor nodes + std::vector<Node *> getPredNodes(Node *nd) const; + + + //to get the no of incoming edges + int getNumberOfIncomingEdges(Node *nd) const; + + //get the list of all the vertices in graph + std::vector<Node *> getAllNodes() const; + std::vector<Node *> getAllNodes(); + + //get a list of nodes in the graph + //in r-topological sorted order + //note that we assumed graph to be connected + std::vector<Node *> reverseTopologicalSort() const; + + //reverse the sign of weights on edges + //this way, max-spanning tree could be obtained + //usin min-spanning tree, and vice versa + void reverseWts(); + + //Ordinarily, the graph is directional + //this converts the graph into an + //undirectional graph + //This is done by adding an edge + //v->u for all existing edges u->v + void makeUnDirectional(); + + //print graph: for debugging + void printGraph(); + + //get a vector of back edges in the graph + void getBackEdges(std::vector<Edge> &be) const; + + //Get the Maximal spanning tree (also a graph) + //of the graph + Graph* getMaxSpanningTree(); + + //get the nodeList adjacent to a node + //a nodeList element contains a node, and the weight + //corresponding to the edge for that element + inline const nodeList &getNodeList(Node *nd) const { + constElementIterator nli = nodes.find(nd); + assert(nli != nodes.end() && "Node must be in nodes map"); + return nli->second; + } + + inline nodeList &getNodeList(Node *nd) { + elementIterator nli = nodes.find(nd); + assert(nli != nodes.end() && "Node must be in nodes map"); + return nli->second; + } + + //get the root of the graph + inline Node *getRoot() {return strt; } + inline Node * const getRoot() const {return strt; } + + //get exit: we assumed there IS a unique exit :) + inline Node *getExit() {return ext; } + inline Node * const getExit() const {return ext; } + //Check if a given node is the root + inline bool isRoot(Node *n) const {return (*n==*strt); } + + //check if a given node is leaf node + //here we hv only 1 leaf: which is the exit node + inline bool isLeaf(Node *n) const {return (*n==*ext); } +}; + +//This class is used to generate +//"appropriate" code to be inserted +//along an edge +//The code to be inserted can be of six different types +//as given below +//1: r=k (where k is some constant) +//2: r=0 +//3: r+=k +//4: count[k]++ +//5: Count[r+k]++ +//6: Count[r]++ +class getEdgeCode{ + private: + //cond implies which + //"kind" of code is to be inserted + //(from 1-6 above) + int cond; + //inc is the increment: eg k, or 0 + int inc; + + //A backedge must carry the code + //of both incoming "dummy" edge + //and outgoing "dummy" edge + //If a->b is a backedge + //then incoming dummy edge is root->b + //and outgoing dummy edge is a->exit + + //incoming dummy edge, if any + getEdgeCode *cdIn; + + //outgoing dummy edge, if any + getEdgeCode *cdOut; + +public: + getEdgeCode(){ + cdIn=NULL; + cdOut=NULL; + inc=0; + cond=0; + } + + //set condition: 1-6 + inline void setCond(int n) {cond=n;} + + //get the condition + inline int getCond() { return cond;} + + //set increment + inline void setInc(int n) {inc=n;} + + //get increment + inline int getInc() {return inc;} + + //set CdIn (only used for backedges) + inline void setCdIn(getEdgeCode *gd){ cdIn=gd;} + + //set CdOut (only used for backedges) + inline void setCdOut(getEdgeCode *gd){ cdOut=gd;} + + //get the code to be inserted on the edge + //This is determined from cond (1-6) + //<<<<<<< Graph.h + void getCode(Instruction *a, Instruction *b, Function *M, BasicBlock *BB, + int numPaths, int MethNo); + //======= + //void getCode(Instruction *a, Instruction *b, Function *F, BasicBlock *BB); + //>>>>>>> 1.4 +}; + + +//auxillary functions on graph + +//print a given edge in the form BB1Label->BB2Label +void printEdge(Edge 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, std::vector<Edge> &be, std::vector<Edge> &stDummy, std::vector<Edge> &exDummy, int n); + +//print the graph (for debugging) +void printGraph(Graph &g); + + +//void printGraph(const Graph g); +//insert a basic block with appropriate code +//along a given edge +void insertBB(Edge ed, getEdgeCode *edgeCode, Instruction *rInst, Instruction *countInst, int n, int Methno); + +//Insert the initialization code in the top BB +//this includes initializing r, and count +//r is like an accumulator, that +//keeps on adding increments as we traverse along a path +//and at the end of the path, r contains the path +//number of that path +//Count is an array, where Count[k] represents +//the number of executions of path k +void insertInTopBB(BasicBlock *front, int k, Instruction *rVar, Instruction *countVar); + +//Add dummy edges corresponding to the back edges +//If a->b is a backedge +//then incoming dummy edge is root->b +//and outgoing dummy edge is a->exit +void addDummyEdges(std::vector<Edge> &stDummy, std::vector<Edge> &exDummy, Graph &g, std::vector<Edge> &be); + +//Assign a value to all the edges in the graph +//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); + +void getBBtrace(std::vector<BasicBlock *> &vBB, int pathNo, Function *M); +#endif + + |