LLVM API Documentation
00001 //===- PathProfileInfo.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 // This file defines the interface used by optimizers to load path profiles, 00011 // and provides a loader pass which reads a path profile file. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 #define DEBUG_TYPE "path-profile-info" 00015 00016 #include "llvm/Analysis/PathProfileInfo.h" 00017 #include "llvm/Analysis/Passes.h" 00018 #include "llvm/Analysis/ProfileInfoTypes.h" 00019 #include "llvm/IR/Module.h" 00020 #include "llvm/Pass.h" 00021 #include "llvm/Support/CommandLine.h" 00022 #include "llvm/Support/Debug.h" 00023 #include "llvm/Support/raw_ostream.h" 00024 #include <cstdio> 00025 00026 using namespace llvm; 00027 00028 // command line option for loading path profiles 00029 static cl::opt<std::string> 00030 PathProfileInfoFilename("path-profile-loader-file", cl::init("llvmprof.out"), 00031 cl::value_desc("filename"), 00032 cl::desc("Path profile file loaded by -path-profile-loader"), cl::Hidden); 00033 00034 namespace { 00035 class PathProfileLoaderPass : public ModulePass, public PathProfileInfo { 00036 public: 00037 PathProfileLoaderPass() : ModulePass(ID) { } 00038 ~PathProfileLoaderPass(); 00039 00040 // this pass doesn't change anything (only loads information) 00041 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 00042 AU.setPreservesAll(); 00043 } 00044 00045 // the full name of the loader pass 00046 virtual const char* getPassName() const { 00047 return "Path Profiling Information Loader"; 00048 } 00049 00050 // required since this pass implements multiple inheritance 00051 virtual void *getAdjustedAnalysisPointer(AnalysisID PI) { 00052 if (PI == &PathProfileInfo::ID) 00053 return (PathProfileInfo*)this; 00054 return this; 00055 } 00056 00057 // entry point to run the pass 00058 bool runOnModule(Module &M); 00059 00060 // pass identification 00061 static char ID; 00062 00063 private: 00064 // make a reference table to refer to function by number 00065 void buildFunctionRefs(Module &M); 00066 00067 // process argument info of a program from the input file 00068 void handleArgumentInfo(); 00069 00070 // process path number information from the input file 00071 void handlePathInfo(); 00072 00073 // array of references to the functions in the module 00074 std::vector<Function*> _functions; 00075 00076 // path profile file handle 00077 FILE* _file; 00078 00079 // path profile file name 00080 std::string _filename; 00081 }; 00082 } 00083 00084 // register PathLoader 00085 char PathProfileLoaderPass::ID = 0; 00086 00087 INITIALIZE_ANALYSIS_GROUP(PathProfileInfo, "Path Profile Information", 00088 NoPathProfileInfo) 00089 INITIALIZE_AG_PASS(PathProfileLoaderPass, PathProfileInfo, 00090 "path-profile-loader", 00091 "Load path profile information from file", 00092 false, true, false) 00093 00094 char &llvm::PathProfileLoaderPassID = PathProfileLoaderPass::ID; 00095 00096 // link PathLoader as a pass, and make it available as an optimisation 00097 ModulePass *llvm::createPathProfileLoaderPass() { 00098 return new PathProfileLoaderPass; 00099 } 00100 00101 // ---------------------------------------------------------------------------- 00102 // PathEdge implementation 00103 // 00104 ProfilePathEdge::ProfilePathEdge (BasicBlock* source, BasicBlock* target, 00105 unsigned duplicateNumber) 00106 : _source(source), _target(target), _duplicateNumber(duplicateNumber) {} 00107 00108 // ---------------------------------------------------------------------------- 00109 // Path implementation 00110 // 00111 00112 ProfilePath::ProfilePath (unsigned int number, unsigned int count, 00113 double countStdDev, PathProfileInfo* ppi) 00114 : _number(number) , _count(count), _countStdDev(countStdDev), _ppi(ppi) {} 00115 00116 double ProfilePath::getFrequency() const { 00117 return 100 * double(_count) / 00118 double(_ppi->_functionPathCounts[_ppi->_currentFunction]); 00119 } 00120 00121 static BallLarusEdge* getNextEdge (BallLarusNode* node, 00122 unsigned int pathNumber) { 00123 BallLarusEdge* best = 0; 00124 00125 for( BLEdgeIterator next = node->succBegin(), 00126 end = node->succEnd(); next != end; next++ ) { 00127 if( (*next)->getType() != BallLarusEdge::BACKEDGE && // no backedges 00128 (*next)->getType() != BallLarusEdge::SPLITEDGE && // no split edges 00129 (*next)->getWeight() <= pathNumber && // weight must be <= pathNumber 00130 (!best || (best->getWeight() < (*next)->getWeight())) ) // best one? 00131 best = *next; 00132 } 00133 00134 return best; 00135 } 00136 00137 ProfilePathEdgeVector* ProfilePath::getPathEdges() const { 00138 BallLarusNode* currentNode = _ppi->_currentDag->getRoot (); 00139 unsigned int increment = _number; 00140 ProfilePathEdgeVector* pev = new ProfilePathEdgeVector; 00141 00142 while (currentNode != _ppi->_currentDag->getExit()) { 00143 BallLarusEdge* next = getNextEdge(currentNode, increment); 00144 00145 increment -= next->getWeight(); 00146 00147 if( next->getType() != BallLarusEdge::BACKEDGE_PHONY && 00148 next->getType() != BallLarusEdge::SPLITEDGE_PHONY && 00149 next->getTarget() != _ppi->_currentDag->getExit() ) 00150 pev->push_back(ProfilePathEdge( 00151 next->getSource()->getBlock(), 00152 next->getTarget()->getBlock(), 00153 next->getDuplicateNumber())); 00154 00155 if( next->getType() == BallLarusEdge::BACKEDGE_PHONY && 00156 next->getTarget() == _ppi->_currentDag->getExit() ) 00157 pev->push_back(ProfilePathEdge( 00158 next->getRealEdge()->getSource()->getBlock(), 00159 next->getRealEdge()->getTarget()->getBlock(), 00160 next->getDuplicateNumber())); 00161 00162 if( next->getType() == BallLarusEdge::SPLITEDGE_PHONY && 00163 next->getSource() == _ppi->_currentDag->getRoot() ) 00164 pev->push_back(ProfilePathEdge( 00165 next->getRealEdge()->getSource()->getBlock(), 00166 next->getRealEdge()->getTarget()->getBlock(), 00167 next->getDuplicateNumber())); 00168 00169 // set the new node 00170 currentNode = next->getTarget(); 00171 } 00172 00173 return pev; 00174 } 00175 00176 ProfilePathBlockVector* ProfilePath::getPathBlocks() const { 00177 BallLarusNode* currentNode = _ppi->_currentDag->getRoot (); 00178 unsigned int increment = _number; 00179 ProfilePathBlockVector* pbv = new ProfilePathBlockVector; 00180 00181 while (currentNode != _ppi->_currentDag->getExit()) { 00182 BallLarusEdge* next = getNextEdge(currentNode, increment); 00183 increment -= next->getWeight(); 00184 00185 // add block to the block list if it is a real edge 00186 if( next->getType() == BallLarusEdge::NORMAL) 00187 pbv->push_back (currentNode->getBlock()); 00188 // make the back edge the last edge since we are at the end 00189 else if( next->getTarget() == _ppi->_currentDag->getExit() ) { 00190 pbv->push_back (currentNode->getBlock()); 00191 pbv->push_back (next->getRealEdge()->getTarget()->getBlock()); 00192 } 00193 00194 // set the new node 00195 currentNode = next->getTarget(); 00196 } 00197 00198 return pbv; 00199 } 00200 00201 BasicBlock* ProfilePath::getFirstBlockInPath() const { 00202 BallLarusNode* root = _ppi->_currentDag->getRoot(); 00203 BallLarusEdge* edge = getNextEdge(root, _number); 00204 00205 if( edge && (edge->getType() == BallLarusEdge::BACKEDGE_PHONY || 00206 edge->getType() == BallLarusEdge::SPLITEDGE_PHONY) ) 00207 return edge->getTarget()->getBlock(); 00208 00209 return root->getBlock(); 00210 } 00211 00212 // ---------------------------------------------------------------------------- 00213 // PathProfileInfo implementation 00214 // 00215 00216 // Pass identification 00217 char llvm::PathProfileInfo::ID = 0; 00218 00219 PathProfileInfo::PathProfileInfo () : _currentDag(0) , _currentFunction(0) { 00220 } 00221 00222 PathProfileInfo::~PathProfileInfo() { 00223 if (_currentDag) 00224 delete _currentDag; 00225 } 00226 00227 // set the function for which paths are currently begin processed 00228 void PathProfileInfo::setCurrentFunction(Function* F) { 00229 // Make sure it exists 00230 if (!F) return; 00231 00232 if (_currentDag) 00233 delete _currentDag; 00234 00235 _currentFunction = F; 00236 _currentDag = new BallLarusDag(*F); 00237 _currentDag->init(); 00238 _currentDag->calculatePathNumbers(); 00239 } 00240 00241 // get the function for which paths are currently being processed 00242 Function* PathProfileInfo::getCurrentFunction() const { 00243 return _currentFunction; 00244 } 00245 00246 // get the entry block of the function 00247 BasicBlock* PathProfileInfo::getCurrentFunctionEntry() { 00248 return _currentDag->getRoot()->getBlock(); 00249 } 00250 00251 // return the path based on its number 00252 ProfilePath* PathProfileInfo::getPath(unsigned int number) { 00253 return _functionPaths[_currentFunction][number]; 00254 } 00255 00256 // return the number of paths which a function may potentially execute 00257 unsigned int PathProfileInfo::getPotentialPathCount() { 00258 return _currentDag ? _currentDag->getNumberOfPaths() : 0; 00259 } 00260 00261 // return an iterator for the beginning of a functions executed paths 00262 ProfilePathIterator PathProfileInfo::pathBegin() { 00263 return _functionPaths[_currentFunction].begin(); 00264 } 00265 00266 // return an iterator for the end of a functions executed paths 00267 ProfilePathIterator PathProfileInfo::pathEnd() { 00268 return _functionPaths[_currentFunction].end(); 00269 } 00270 00271 // returns the total number of paths run in the function 00272 unsigned int PathProfileInfo::pathsRun() { 00273 return _currentFunction ? _functionPaths[_currentFunction].size() : 0; 00274 } 00275 00276 // ---------------------------------------------------------------------------- 00277 // PathLoader implementation 00278 // 00279 00280 // remove all generated paths 00281 PathProfileLoaderPass::~PathProfileLoaderPass() { 00282 for( FunctionPathIterator funcNext = _functionPaths.begin(), 00283 funcEnd = _functionPaths.end(); funcNext != funcEnd; funcNext++) 00284 for( ProfilePathIterator pathNext = funcNext->second.begin(), 00285 pathEnd = funcNext->second.end(); pathNext != pathEnd; pathNext++) 00286 delete pathNext->second; 00287 } 00288 00289 // entry point of the pass; this loads and parses a file 00290 bool PathProfileLoaderPass::runOnModule(Module &M) { 00291 // get the filename and setup the module's function references 00292 _filename = PathProfileInfoFilename; 00293 buildFunctionRefs (M); 00294 00295 if (!(_file = fopen(_filename.c_str(), "rb"))) { 00296 errs () << "error: input '" << _filename << "' file does not exist.\n"; 00297 return false; 00298 } 00299 00300 ProfilingType profType; 00301 00302 while( fread(&profType, sizeof(ProfilingType), 1, _file) ) { 00303 switch (profType) { 00304 case ArgumentInfo: 00305 handleArgumentInfo (); 00306 break; 00307 case PathInfo: 00308 handlePathInfo (); 00309 break; 00310 default: 00311 errs () << "error: bad path profiling file syntax, " << profType << "\n"; 00312 fclose (_file); 00313 return false; 00314 } 00315 } 00316 00317 fclose (_file); 00318 00319 return true; 00320 } 00321 00322 // create a reference table for functions defined in the path profile file 00323 void PathProfileLoaderPass::buildFunctionRefs (Module &M) { 00324 _functions.push_back(0); // make the 0 index a null pointer 00325 00326 for (Module::iterator F = M.begin(), E = M.end(); F != E; F++) { 00327 if (F->isDeclaration()) 00328 continue; 00329 _functions.push_back(F); 00330 } 00331 } 00332 00333 // handle command like argument infor in the output file 00334 void PathProfileLoaderPass::handleArgumentInfo() { 00335 // get the argument list's length 00336 unsigned savedArgsLength; 00337 if( fread(&savedArgsLength, sizeof(unsigned), 1, _file) != 1 ) { 00338 errs() << "warning: argument info header/data mismatch\n"; 00339 return; 00340 } 00341 00342 // allocate a buffer, and get the arguments 00343 char* args = new char[savedArgsLength+1]; 00344 if( fread(args, 1, savedArgsLength, _file) != savedArgsLength ) 00345 errs() << "warning: argument info header/data mismatch\n"; 00346 00347 args[savedArgsLength] = '\0'; 00348 argList = std::string(args); 00349 delete [] args; // cleanup dynamic string 00350 00351 // byte alignment 00352 if (savedArgsLength & 3) 00353 fseek(_file, 4-(savedArgsLength&3), SEEK_CUR); 00354 } 00355 00356 // Handle path profile information in the output file 00357 void PathProfileLoaderPass::handlePathInfo () { 00358 // get the number of functions in this profile 00359 unsigned functionCount; 00360 if( fread(&functionCount, sizeof(functionCount), 1, _file) != 1 ) { 00361 errs() << "warning: path info header/data mismatch\n"; 00362 return; 00363 } 00364 00365 // gather path information for each function 00366 for (unsigned i = 0; i < functionCount; i++) { 00367 PathProfileHeader pathHeader; 00368 if( fread(&pathHeader, sizeof(pathHeader), 1, _file) != 1 ) { 00369 errs() << "warning: bad header for path function info\n"; 00370 break; 00371 } 00372 00373 Function* f = _functions[pathHeader.fnNumber]; 00374 00375 // dynamically allocate a table to store path numbers 00376 PathProfileTableEntry* pathTable = 00377 new PathProfileTableEntry[pathHeader.numEntries]; 00378 00379 if( fread(pathTable, sizeof(PathProfileTableEntry), 00380 pathHeader.numEntries, _file) != pathHeader.numEntries) { 00381 delete [] pathTable; 00382 errs() << "warning: path function info header/data mismatch\n"; 00383 return; 00384 } 00385 00386 // Build a new path for the current function 00387 unsigned int totalPaths = 0; 00388 for (unsigned int j = 0; j < pathHeader.numEntries; j++) { 00389 totalPaths += pathTable[j].pathCounter; 00390 _functionPaths[f][pathTable[j].pathNumber] 00391 = new ProfilePath(pathTable[j].pathNumber, pathTable[j].pathCounter, 00392 0, this); 00393 } 00394 00395 _functionPathCounts[f] = totalPaths; 00396 00397 delete [] pathTable; 00398 } 00399 } 00400 00401 //===----------------------------------------------------------------------===// 00402 // NoProfile PathProfileInfo implementation 00403 // 00404 00405 namespace { 00406 struct NoPathProfileInfo : public ImmutablePass, public PathProfileInfo { 00407 static char ID; // Class identification, replacement for typeinfo 00408 NoPathProfileInfo() : ImmutablePass(ID) { 00409 initializeNoPathProfileInfoPass(*PassRegistry::getPassRegistry()); 00410 } 00411 00412 /// getAdjustedAnalysisPointer - This method is used when a pass implements 00413 /// an analysis interface through multiple inheritance. If needed, it 00414 /// should override this to adjust the this pointer as needed for the 00415 /// specified pass info. 00416 virtual void *getAdjustedAnalysisPointer(AnalysisID PI) { 00417 if (PI == &PathProfileInfo::ID) 00418 return (PathProfileInfo*)this; 00419 return this; 00420 } 00421 00422 virtual const char *getPassName() const { 00423 return "NoPathProfileInfo"; 00424 } 00425 }; 00426 } // End of anonymous namespace 00427 00428 char NoPathProfileInfo::ID = 0; 00429 // Register this pass... 00430 INITIALIZE_AG_PASS(NoPathProfileInfo, PathProfileInfo, "no-path-profile", 00431 "No Path Profile Information", false, true, true) 00432 00433 ImmutablePass *llvm::createNoPathProfileInfoPass() { return new NoPathProfileInfo(); }