LLVM API Documentation

PathProfileInfo.cpp
Go to the documentation of this file.
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(); }