//===- PathNumbering.h ----------------------------------------*- C++ -*---===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // Ball-Larus path numbers uniquely identify paths through a directed acyclic // graph (DAG) [Ball96]. For a CFG backedges are removed and replaced by phony // edges to obtain a DAG, and thus the unique path numbers [Ball96]. // // The purpose of this analysis is to enumerate the edges in a CFG in order // to obtain paths from path numbers in a convenient manner. As described in // [Ball96] edges can be enumerated such that given a path number by following // the CFG and updating the path number, the path is obtained. // // [Ball96] // T. Ball and J. R. Larus. "Efficient Path Profiling." // International Symposium on Microarchitecture, pages 46-57, 1996. // http://portal.acm.org/citation.cfm?id=243857 // //===----------------------------------------------------------------------===// #ifndef LLVM_PATH_NUMBERING_H #define LLVM_PATH_NUMBERING_H #include "llvm/BasicBlock.h" #include "llvm/Instructions.h" #include "llvm/Pass.h" #include "llvm/Support/CFG.h" #include "llvm/Analysis/ProfileInfoTypes.h" #include <map> #include <stack> #include <vector> namespace llvm { class BallLarusNode; class BallLarusEdge; class BallLarusDag; // typedefs for storage/ interators of various DAG components typedef std::vector<BallLarusNode*> BLNodeVector; typedef std::vector<BallLarusNode*>::iterator BLNodeIterator; typedef std::vector<BallLarusEdge*> BLEdgeVector; typedef std::vector<BallLarusEdge*>::iterator BLEdgeIterator; typedef std::map<BasicBlock*, BallLarusNode*> BLBlockNodeMap; typedef std::stack<BallLarusNode*> BLNodeStack; // Represents a basic block with information necessary for the BallLarus // algorithms. class BallLarusNode { public: enum NodeColor { WHITE, GRAY, BLACK }; // Constructor: Initializes a new Node for the given BasicBlock BallLarusNode(BasicBlock* BB) : _basicBlock(BB), _numberPaths(0), _color(WHITE) { static unsigned nextUID = 0; _uid = nextUID++; } // Returns the basic block for the BallLarusNode BasicBlock* getBlock(); // Get/set the number of paths to the exit starting at the node. unsigned getNumberPaths(); void setNumberPaths(unsigned numberPaths); // Get/set the NodeColor used in graph algorithms. NodeColor getColor(); void setColor(NodeColor color); // Iterator information for predecessor edges. Includes phony and // backedges. BLEdgeIterator predBegin(); BLEdgeIterator predEnd(); unsigned getNumberPredEdges(); // Iterator information for successor edges. Includes phony and // backedges. BLEdgeIterator succBegin(); BLEdgeIterator succEnd(); unsigned getNumberSuccEdges(); // Add an edge to the predecessor list. void addPredEdge(BallLarusEdge* edge); // Remove an edge from the predecessor list. void removePredEdge(BallLarusEdge* edge); // Add an edge to the successor list. void addSuccEdge(BallLarusEdge* edge); // Remove an edge from the successor list. void removeSuccEdge(BallLarusEdge* edge); // Returns the name of the BasicBlock being represented. If BasicBlock // is null then returns "<null>". If BasicBlock has no name, then // "<unnamed>" is returned. Intended for use with debug output. std::string getName(); private: // The corresponding underlying BB. BasicBlock* _basicBlock; // Holds the predecessor edges of this node. BLEdgeVector _predEdges; // Holds the successor edges of this node. BLEdgeVector _succEdges; // The number of paths from the node to the exit. unsigned _numberPaths; // 'Color' used by graph algorithms to mark the node. NodeColor _color; // Unique ID to ensure naming difference with dotgraphs unsigned _uid; // Removes an edge from an edgeVector. Used by removePredEdge and // removeSuccEdge. void removeEdge(BLEdgeVector& v, BallLarusEdge* e); }; // Represents an edge in the Dag. For an edge, v -> w, v is the source, and // w is the target. class BallLarusEdge { public: enum EdgeType { NORMAL, BACKEDGE, SPLITEDGE, BACKEDGE_PHONY, SPLITEDGE_PHONY, CALLEDGE_PHONY }; // Constructor: Initializes an BallLarusEdge with a source and target. BallLarusEdge(BallLarusNode* source, BallLarusNode* target, unsigned duplicateNumber) : _source(source), _target(target), _weight(0), _edgeType(NORMAL), _realEdge(NULL), _duplicateNumber(duplicateNumber) {} // Returns the source/ target node of this edge. BallLarusNode* getSource() const; BallLarusNode* getTarget() const; // Sets the type of the edge. EdgeType getType() const; // Gets the type of the edge. void setType(EdgeType type); // Returns the weight of this edge. Used to decode path numbers to // sequences of basic blocks. unsigned getWeight(); // Sets the weight of the edge. Used during path numbering. void setWeight(unsigned weight); // Gets/sets the phony edge originating at the root. BallLarusEdge* getPhonyRoot(); void setPhonyRoot(BallLarusEdge* phonyRoot); // Gets/sets the phony edge terminating at the exit. BallLarusEdge* getPhonyExit(); void setPhonyExit(BallLarusEdge* phonyExit); // Gets/sets the associated real edge if this is a phony edge. BallLarusEdge* getRealEdge(); void setRealEdge(BallLarusEdge* realEdge); // Returns the duplicate number of the edge. unsigned getDuplicateNumber(); protected: // Source node for this edge. BallLarusNode* _source; // Target node for this edge. BallLarusNode* _target; private: // Edge weight cooresponding to path number increments before removing // increments along a spanning tree. The sum over the edge weights gives // the path number. unsigned _weight; // Type to represent for what this edge is intended EdgeType _edgeType; // For backedges and split-edges, the phony edge which is linked to the // root node of the DAG. This contains a path number initialization. BallLarusEdge* _phonyRoot; // For backedges and split-edges, the phony edge which is linked to the // exit node of the DAG. This contains a path counter increment, and // potentially a path number increment. BallLarusEdge* _phonyExit; // If this is a phony edge, _realEdge is a link to the back or split // edge. Otherwise, this is null. BallLarusEdge* _realEdge; // An ID to differentiate between those edges which have the same source // and destination blocks. unsigned _duplicateNumber; }; // Represents the Ball Larus DAG for a given Function. Can calculate // various properties required for instrumentation or analysis. E.g. the // edge weights that determine the path number. class BallLarusDag { public: // Initializes a BallLarusDag from the CFG of a given function. Must // call init() after creation, since some initialization requires // virtual functions. BallLarusDag(Function &F) : _root(NULL), _exit(NULL), _function(F) {} // Initialization that requires virtual functions which are not fully // functional in the constructor. void init(); // Frees all memory associated with the DAG. virtual ~BallLarusDag(); // Calculate the path numbers by assigning edge increments as prescribed // in Ball-Larus path profiling. void calculatePathNumbers(); // Returns the number of paths for the DAG. unsigned getNumberOfPaths(); // Returns the root (i.e. entry) node for the DAG. BallLarusNode* getRoot(); // Returns the exit node for the DAG. BallLarusNode* getExit(); // Returns the function for the DAG. Function& getFunction(); // Clears the node colors. void clearColors(BallLarusNode::NodeColor color); protected: // All nodes in the DAG. BLNodeVector _nodes; // All edges in the DAG. BLEdgeVector _edges; // All backedges in the DAG. BLEdgeVector _backEdges; // Allows subclasses to determine which type of Node is created. // Override this method to produce subclasses of BallLarusNode if // necessary. The destructor of BallLarusDag will call free on each pointer // created. virtual BallLarusNode* createNode(BasicBlock* BB); // Allows subclasses to determine which type of Edge is created. // Override this method to produce subclasses of BallLarusEdge if // necessary. Parameters source and target will have been created by // createNode and can be cast to the subclass of BallLarusNode* // returned by createNode. The destructor of BallLarusDag will call free // on each pointer created. virtual BallLarusEdge* createEdge(BallLarusNode* source, BallLarusNode* target, unsigned duplicateNumber); // Proxy to node's constructor. Updates the DAG state. BallLarusNode* addNode(BasicBlock* BB); // Proxy to edge's constructor. Updates the DAG state. BallLarusEdge* addEdge(BallLarusNode* source, BallLarusNode* target, unsigned duplicateNumber); private: // The root (i.e. entry) node for this DAG. BallLarusNode* _root; // The exit node for this DAG. BallLarusNode* _exit; // The function represented by this DAG. Function& _function; // Processes one node and its imediate edges for building the DAG. void buildNode(BLBlockNodeMap& inDag, std::stack<BallLarusNode*>& dfsStack); // Process an edge in the CFG for DAG building. void buildEdge(BLBlockNodeMap& inDag, std::stack<BallLarusNode*>& dfsStack, BallLarusNode* currentNode, BasicBlock* succBB, unsigned duplicateNumber); // The weight on each edge is the increment required along any path that // contains that edge. void calculatePathNumbersFrom(BallLarusNode* node); // Adds a backedge with its phony edges. Updates the DAG state. void addBackedge(BallLarusNode* source, BallLarusNode* target, unsigned duplicateCount); }; } // end namespace llvm #endif