LLVM API Documentation
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 }