LLVM API Documentation

PathNumbering.cpp
Go to the documentation of this file.
00001 //===- PathNumbering.cpp --------------------------------------*- C++ -*---===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // Ball-Larus path numbers uniquely identify paths through a directed acyclic
00011 // graph (DAG) [Ball96].  For a CFG backedges are removed and replaced by phony
00012 // edges to obtain a DAG, and thus the unique path numbers [Ball96].
00013 //
00014 // The purpose of this analysis is to enumerate the edges in a CFG in order
00015 // to obtain paths from path numbers in a convenient manner.  As described in
00016 // [Ball96] edges can be enumerated such that given a path number by following
00017 // the CFG and updating the path number, the path is obtained.
00018 //
00019 // [Ball96]
00020 //  T. Ball and J. R. Larus. "Efficient Path Profiling."
00021 //  International Symposium on Microarchitecture, pages 46-57, 1996.
00022 //  http://portal.acm.org/citation.cfm?id=243857
00023 //
00024 //===----------------------------------------------------------------------===//
00025 #define DEBUG_TYPE "ball-larus-numbering"
00026 
00027 #include "llvm/Analysis/PathNumbering.h"
00028 #include "llvm/IR/Constants.h"
00029 #include "llvm/IR/DerivedTypes.h"
00030 #include "llvm/IR/InstrTypes.h"
00031 #include "llvm/IR/Instructions.h"
00032 #include "llvm/IR/Module.h"
00033 #include "llvm/IR/TypeBuilder.h"
00034 #include "llvm/Pass.h"
00035 #include "llvm/Support/CFG.h"
00036 #include "llvm/Support/CommandLine.h"
00037 #include "llvm/Support/Compiler.h"
00038 #include "llvm/Support/Debug.h"
00039 #include "llvm/Support/raw_ostream.h"
00040 #include <queue>
00041 #include <sstream>
00042 #include <stack>
00043 #include <string>
00044 #include <utility>
00045 
00046 using namespace llvm;
00047 
00048 // Are we enabling early termination
00049 static cl::opt<bool> ProcessEarlyTermination(
00050   "path-profile-early-termination", cl::Hidden,
00051   cl::desc("In path profiling, insert extra instrumentation to account for "
00052            "unexpected function termination."));
00053 
00054 // Returns the basic block for the BallLarusNode
00055 BasicBlock* BallLarusNode::getBlock() {
00056   return(_basicBlock);
00057 }
00058 
00059 // Returns the number of paths to the exit starting at the node.
00060 unsigned BallLarusNode::getNumberPaths() {
00061   return(_numberPaths);
00062 }
00063 
00064 // Sets the number of paths to the exit starting at the node.
00065 void BallLarusNode::setNumberPaths(unsigned numberPaths) {
00066   _numberPaths = numberPaths;
00067 }
00068 
00069 // Gets the NodeColor used in graph algorithms.
00070 BallLarusNode::NodeColor BallLarusNode::getColor() {
00071   return(_color);
00072 }
00073 
00074 // Sets the NodeColor used in graph algorithms.
00075 void BallLarusNode::setColor(BallLarusNode::NodeColor color) {
00076   _color = color;
00077 }
00078 
00079 // Returns an iterator over predecessor edges. Includes phony and
00080 // backedges.
00081 BLEdgeIterator BallLarusNode::predBegin() {
00082   return(_predEdges.begin());
00083 }
00084 
00085 // Returns the end sentinel for the predecessor iterator.
00086 BLEdgeIterator BallLarusNode::predEnd() {
00087   return(_predEdges.end());
00088 }
00089 
00090 // Returns the number of predecessor edges.  Includes phony and
00091 // backedges.
00092 unsigned BallLarusNode::getNumberPredEdges() {
00093   return(_predEdges.size());
00094 }
00095 
00096 // Returns an iterator over successor edges. Includes phony and
00097 // backedges.
00098 BLEdgeIterator BallLarusNode::succBegin() {
00099   return(_succEdges.begin());
00100 }
00101 
00102 // Returns the end sentinel for the successor iterator.
00103 BLEdgeIterator BallLarusNode::succEnd() {
00104   return(_succEdges.end());
00105 }
00106 
00107 // Returns the number of successor edges.  Includes phony and
00108 // backedges.
00109 unsigned BallLarusNode::getNumberSuccEdges() {
00110   return(_succEdges.size());
00111 }
00112 
00113 // Add an edge to the predecessor list.
00114 void BallLarusNode::addPredEdge(BallLarusEdge* edge) {
00115   _predEdges.push_back(edge);
00116 }
00117 
00118 // Remove an edge from the predecessor list.
00119 void BallLarusNode::removePredEdge(BallLarusEdge* edge) {
00120   removeEdge(_predEdges, edge);
00121 }
00122 
00123 // Add an edge to the successor list.
00124 void BallLarusNode::addSuccEdge(BallLarusEdge* edge) {
00125   _succEdges.push_back(edge);
00126 }
00127 
00128 // Remove an edge from the successor list.
00129 void BallLarusNode::removeSuccEdge(BallLarusEdge* edge) {
00130   removeEdge(_succEdges, edge);
00131 }
00132 
00133 // Returns the name of the BasicBlock being represented.  If BasicBlock
00134 // is null then returns "<null>".  If BasicBlock has no name, then
00135 // "<unnamed>" is returned.  Intended for use with debug output.
00136 std::string BallLarusNode::getName() {
00137   std::stringstream name;
00138 
00139   if(getBlock() != NULL) {
00140     if(getBlock()->hasName()) {
00141       std::string tempName(getBlock()->getName());
00142       name << tempName.c_str() << " (" << _uid << ")";
00143     } else
00144       name << "<unnamed> (" << _uid << ")";
00145   } else
00146     name << "<null> (" << _uid << ")";
00147 
00148   return name.str();
00149 }
00150 
00151 // Removes an edge from an edgeVector.  Used by removePredEdge and
00152 // removeSuccEdge.
00153 void BallLarusNode::removeEdge(BLEdgeVector& v, BallLarusEdge* e) {
00154   // TODO: Avoid linear scan by using a set instead
00155   for(BLEdgeIterator i = v.begin(),
00156         end = v.end();
00157       i != end;
00158       ++i) {
00159     if((*i) == e) {
00160       v.erase(i);
00161       break;
00162     }
00163   }
00164 }
00165 
00166 // Returns the source node of this edge.
00167 BallLarusNode* BallLarusEdge::getSource() const {
00168   return(_source);
00169 }
00170 
00171 // Returns the target node of this edge.
00172 BallLarusNode* BallLarusEdge::getTarget() const {
00173   return(_target);
00174 }
00175 
00176 // Sets the type of the edge.
00177 BallLarusEdge::EdgeType BallLarusEdge::getType() const {
00178   return _edgeType;
00179 }
00180 
00181 // Gets the type of the edge.
00182 void BallLarusEdge::setType(EdgeType type) {
00183   _edgeType = type;
00184 }
00185 
00186 // Returns the weight of this edge.  Used to decode path numbers to sequences
00187 // of basic blocks.
00188 unsigned BallLarusEdge::getWeight() {
00189   return(_weight);
00190 }
00191 
00192 // Sets the weight of the edge.  Used during path numbering.
00193 void BallLarusEdge::setWeight(unsigned weight) {
00194   _weight = weight;
00195 }
00196 
00197 // Gets the phony edge originating at the root.
00198 BallLarusEdge* BallLarusEdge::getPhonyRoot() {
00199   return _phonyRoot;
00200 }
00201 
00202 // Sets the phony edge originating at the root.
00203 void BallLarusEdge::setPhonyRoot(BallLarusEdge* phonyRoot) {
00204   _phonyRoot = phonyRoot;
00205 }
00206 
00207 // Gets the phony edge terminating at the exit.
00208 BallLarusEdge* BallLarusEdge::getPhonyExit() {
00209   return _phonyExit;
00210 }
00211 
00212 // Sets the phony edge terminating at the exit.
00213 void BallLarusEdge::setPhonyExit(BallLarusEdge* phonyExit) {
00214   _phonyExit = phonyExit;
00215 }
00216 
00217 // Gets the associated real edge if this is a phony edge.
00218 BallLarusEdge* BallLarusEdge::getRealEdge() {
00219   return _realEdge;
00220 }
00221 
00222 // Sets the associated real edge if this is a phony edge.
00223 void BallLarusEdge::setRealEdge(BallLarusEdge* realEdge) {
00224   _realEdge = realEdge;
00225 }
00226 
00227 // Returns the duplicate number of the edge.
00228 unsigned BallLarusEdge::getDuplicateNumber() {
00229   return(_duplicateNumber);
00230 }
00231 
00232 // Initialization that requires virtual functions which are not fully
00233 // functional in the constructor.
00234 void BallLarusDag::init() {
00235   BLBlockNodeMap inDag;
00236   std::stack<BallLarusNode*> dfsStack;
00237 
00238   _root = addNode(&(_function.getEntryBlock()));
00239   _exit = addNode(NULL);
00240 
00241   // start search from root
00242   dfsStack.push(getRoot());
00243 
00244   // dfs to add each bb into the dag
00245   while(dfsStack.size())
00246     buildNode(inDag, dfsStack);
00247 
00248   // put in the final edge
00249   addEdge(getExit(),getRoot(),0);
00250 }
00251 
00252 // Frees all memory associated with the DAG.
00253 BallLarusDag::~BallLarusDag() {
00254   for(BLEdgeIterator edge = _edges.begin(), end = _edges.end(); edge != end;
00255       ++edge)
00256     delete (*edge);
00257 
00258   for(BLNodeIterator node = _nodes.begin(), end = _nodes.end(); node != end;
00259       ++node)
00260     delete (*node);
00261 }
00262 
00263 // Calculate the path numbers by assigning edge increments as prescribed
00264 // in Ball-Larus path profiling.
00265 void BallLarusDag::calculatePathNumbers() {
00266   BallLarusNode* node;
00267   std::queue<BallLarusNode*> bfsQueue;
00268   bfsQueue.push(getExit());
00269 
00270   while(bfsQueue.size() > 0) {
00271     node = bfsQueue.front();
00272 
00273     DEBUG(dbgs() << "calculatePathNumbers on " << node->getName() << "\n");
00274 
00275     bfsQueue.pop();
00276     unsigned prevPathNumber = node->getNumberPaths();
00277     calculatePathNumbersFrom(node);
00278 
00279     // Check for DAG splitting
00280     if( node->getNumberPaths() > 100000000 && node != getRoot() ) {
00281       // Add new phony edge from the split-node to the DAG's exit
00282       BallLarusEdge* exitEdge = addEdge(node, getExit(), 0);
00283       exitEdge->setType(BallLarusEdge::SPLITEDGE_PHONY);
00284 
00285       // Counters to handle the possibility of a multi-graph
00286       BasicBlock* oldTarget = 0;
00287       unsigned duplicateNumber = 0;
00288 
00289       // Iterate through each successor edge, adding phony edges
00290       for( BLEdgeIterator succ = node->succBegin(), end = node->succEnd();
00291            succ != end; oldTarget = (*succ)->getTarget()->getBlock(), succ++ ) {
00292 
00293         if( (*succ)->getType() == BallLarusEdge::NORMAL ) {
00294           // is this edge a duplicate?
00295           if( oldTarget != (*succ)->getTarget()->getBlock() )
00296             duplicateNumber = 0;
00297 
00298           // create the new phony edge: root -> succ
00299           BallLarusEdge* rootEdge =
00300             addEdge(getRoot(), (*succ)->getTarget(), duplicateNumber++);
00301           rootEdge->setType(BallLarusEdge::SPLITEDGE_PHONY);
00302           rootEdge->setRealEdge(*succ);
00303 
00304           // split on this edge and reference it's exit/root phony edges
00305           (*succ)->setType(BallLarusEdge::SPLITEDGE);
00306           (*succ)->setPhonyRoot(rootEdge);
00307           (*succ)->setPhonyExit(exitEdge);
00308           (*succ)->setWeight(0);
00309         }
00310       }
00311 
00312       calculatePathNumbersFrom(node);
00313     }
00314 
00315     DEBUG(dbgs() << "prev, new number paths " << prevPathNumber << ", "
00316           << node->getNumberPaths() << ".\n");
00317 
00318     if(prevPathNumber == 0 && node->getNumberPaths() != 0) {
00319       DEBUG(dbgs() << "node ready : " << node->getName() << "\n");
00320       for(BLEdgeIterator pred = node->predBegin(), end = node->predEnd();
00321           pred != end; pred++) {
00322         if( (*pred)->getType() == BallLarusEdge::BACKEDGE ||
00323             (*pred)->getType() == BallLarusEdge::SPLITEDGE )
00324           continue;
00325 
00326         BallLarusNode* nextNode = (*pred)->getSource();
00327         // not yet visited?
00328         if(nextNode->getNumberPaths() == 0)
00329           bfsQueue.push(nextNode);
00330       }
00331     }
00332   }
00333 
00334   DEBUG(dbgs() << "\tNumber of paths: " << getRoot()->getNumberPaths() << "\n");
00335 }
00336 
00337 // Returns the number of paths for the Dag.
00338 unsigned BallLarusDag::getNumberOfPaths() {
00339   return(getRoot()->getNumberPaths());
00340 }
00341 
00342 // Returns the root (i.e. entry) node for the DAG.
00343 BallLarusNode* BallLarusDag::getRoot() {
00344   return _root;
00345 }
00346 
00347 // Returns the exit node for the DAG.
00348 BallLarusNode* BallLarusDag::getExit() {
00349   return _exit;
00350 }
00351 
00352 // Returns the function for the DAG.
00353 Function& BallLarusDag::getFunction() {
00354   return(_function);
00355 }
00356 
00357 // Clears the node colors.
00358 void BallLarusDag::clearColors(BallLarusNode::NodeColor color) {
00359   for (BLNodeIterator nodeIt = _nodes.begin(); nodeIt != _nodes.end(); nodeIt++)
00360     (*nodeIt)->setColor(color);
00361 }
00362 
00363 // Processes one node and its imediate edges for building the DAG.
00364 void BallLarusDag::buildNode(BLBlockNodeMap& inDag, BLNodeStack& dfsStack) {
00365   BallLarusNode* currentNode = dfsStack.top();
00366   BasicBlock* currentBlock = currentNode->getBlock();
00367 
00368   if(currentNode->getColor() != BallLarusNode::WHITE) {
00369     // we have already visited this node
00370     dfsStack.pop();
00371     currentNode->setColor(BallLarusNode::BLACK);
00372   } else {
00373     // are there any external procedure calls?
00374     if( ProcessEarlyTermination ) {
00375       for( BasicBlock::iterator bbCurrent = currentNode->getBlock()->begin(),
00376              bbEnd = currentNode->getBlock()->end(); bbCurrent != bbEnd;
00377            bbCurrent++ ) {
00378         Instruction& instr = *bbCurrent;
00379         if( instr.getOpcode() == Instruction::Call ) {
00380           BallLarusEdge* callEdge = addEdge(currentNode, getExit(), 0);
00381           callEdge->setType(BallLarusEdge::CALLEDGE_PHONY);
00382           break;
00383         }
00384       }
00385     }
00386 
00387     TerminatorInst* terminator = currentNode->getBlock()->getTerminator();
00388     if(isa<ReturnInst>(terminator) || isa<UnreachableInst>(terminator) ||
00389        isa<ResumeInst>(terminator))
00390       addEdge(currentNode, getExit(),0);
00391 
00392     currentNode->setColor(BallLarusNode::GRAY);
00393     inDag[currentBlock] = currentNode;
00394 
00395     BasicBlock* oldSuccessor = 0;
00396     unsigned duplicateNumber = 0;
00397 
00398     // iterate through this node's successors
00399     for(succ_iterator successor = succ_begin(currentBlock),
00400           succEnd = succ_end(currentBlock); successor != succEnd;
00401         oldSuccessor = *successor, ++successor ) {
00402       BasicBlock* succBB = *successor;
00403 
00404       // is this edge a duplicate?
00405       if (oldSuccessor == succBB)
00406         duplicateNumber++;
00407       else
00408         duplicateNumber = 0;
00409 
00410       buildEdge(inDag, dfsStack, currentNode, succBB, duplicateNumber);
00411     }
00412   }
00413 }
00414 
00415 // Process an edge in the CFG for DAG building.
00416 void BallLarusDag::buildEdge(BLBlockNodeMap& inDag, std::stack<BallLarusNode*>&
00417                              dfsStack, BallLarusNode* currentNode,
00418                              BasicBlock* succBB, unsigned duplicateCount) {
00419   BallLarusNode* succNode = inDag[succBB];
00420 
00421   if(succNode && succNode->getColor() == BallLarusNode::BLACK) {
00422     // visited node and forward edge
00423     addEdge(currentNode, succNode, duplicateCount);
00424   } else if(succNode && succNode->getColor() == BallLarusNode::GRAY) {
00425     // visited node and back edge
00426     DEBUG(dbgs() << "Backedge detected.\n");
00427     addBackedge(currentNode, succNode, duplicateCount);
00428   } else {
00429     BallLarusNode* childNode;
00430     // not visited node and forward edge
00431     if(succNode) // an unvisited node that is child of a gray node
00432       childNode = succNode;
00433     else { // an unvisited node that is a child of a an unvisted node
00434       childNode = addNode(succBB);
00435       inDag[succBB] = childNode;
00436     }
00437     addEdge(currentNode, childNode, duplicateCount);
00438     dfsStack.push(childNode);
00439   }
00440 }
00441 
00442 // The weight on each edge is the increment required along any path that
00443 // contains that edge.
00444 void BallLarusDag::calculatePathNumbersFrom(BallLarusNode* node) {
00445   if(node == getExit())
00446     // The Exit node must be base case
00447     node->setNumberPaths(1);
00448   else {
00449     unsigned sumPaths = 0;
00450     BallLarusNode* succNode;
00451 
00452     for(BLEdgeIterator succ = node->succBegin(), end = node->succEnd();
00453         succ != end; succ++) {
00454       if( (*succ)->getType() == BallLarusEdge::BACKEDGE ||
00455           (*succ)->getType() == BallLarusEdge::SPLITEDGE )
00456         continue;
00457 
00458       (*succ)->setWeight(sumPaths);
00459       succNode = (*succ)->getTarget();
00460 
00461       if( !succNode->getNumberPaths() )
00462         return;
00463       sumPaths += succNode->getNumberPaths();
00464     }
00465 
00466     node->setNumberPaths(sumPaths);
00467   }
00468 }
00469 
00470 // Allows subclasses to determine which type of Node is created.
00471 // Override this method to produce subclasses of BallLarusNode if
00472 // necessary. The destructor of BallLarusDag will call free on each
00473 // pointer created.
00474 BallLarusNode* BallLarusDag::createNode(BasicBlock* BB) {
00475   return( new BallLarusNode(BB) );
00476 }
00477 
00478 // Allows subclasses to determine which type of Edge is created.
00479 // Override this method to produce subclasses of BallLarusEdge if
00480 // necessary. The destructor of BallLarusDag will call free on each
00481 // pointer created.
00482 BallLarusEdge* BallLarusDag::createEdge(BallLarusNode* source,
00483                                         BallLarusNode* target,
00484                                         unsigned duplicateCount) {
00485   return( new BallLarusEdge(source, target, duplicateCount) );
00486 }
00487 
00488 // Proxy to node's constructor.  Updates the DAG state.
00489 BallLarusNode* BallLarusDag::addNode(BasicBlock* BB) {
00490   BallLarusNode* newNode = createNode(BB);
00491   _nodes.push_back(newNode);
00492   return( newNode );
00493 }
00494 
00495 // Proxy to edge's constructor. Updates the DAG state.
00496 BallLarusEdge* BallLarusDag::addEdge(BallLarusNode* source,
00497                                      BallLarusNode* target,
00498                                      unsigned duplicateCount) {
00499   BallLarusEdge* newEdge = createEdge(source, target, duplicateCount);
00500   _edges.push_back(newEdge);
00501   source->addSuccEdge(newEdge);
00502   target->addPredEdge(newEdge);
00503   return(newEdge);
00504 }
00505 
00506 // Adds a backedge with its phony edges. Updates the DAG state.
00507 void BallLarusDag::addBackedge(BallLarusNode* source, BallLarusNode* target,
00508                                unsigned duplicateCount) {
00509   BallLarusEdge* childEdge = addEdge(source, target, duplicateCount);
00510   childEdge->setType(BallLarusEdge::BACKEDGE);
00511 
00512   childEdge->setPhonyRoot(addEdge(getRoot(), target,0));
00513   childEdge->setPhonyExit(addEdge(source, getExit(),0));
00514 
00515   childEdge->getPhonyRoot()->setRealEdge(childEdge);
00516   childEdge->getPhonyRoot()->setType(BallLarusEdge::BACKEDGE_PHONY);
00517 
00518   childEdge->getPhonyExit()->setRealEdge(childEdge);
00519   childEdge->getPhonyExit()->setType(BallLarusEdge::BACKEDGE_PHONY);
00520   _backEdges.push_back(childEdge);
00521 }