b361d3f4fa94b1e5a0eb09f2dd73b24412c861a3
[oota-llvm.git] / lib / Analysis / PathProfileInfo.cpp
1 //===- PathProfileInfo.cpp ------------------------------------*- C++ -*---===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the interface used by optimizers to load path profiles,
11 // and provides a loader pass which reads a path profile file.
12 //
13 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "path-profile-info"
15
16 #include "llvm/Module.h"
17 #include "llvm/Pass.h"
18 #include "llvm/Analysis/Passes.h"
19 #include "llvm/Analysis/ProfileInfoTypes.h"
20 #include "llvm/Analysis/PathProfileInfo.h"
21 #include "llvm/Support/CommandLine.h"
22 #include "llvm/Support/Debug.h"
23 #include "llvm/Support/raw_ostream.h"
24
25 #include <cstdio>
26
27 using namespace llvm;
28
29 // command line option for loading path profiles
30 static cl::opt<std::string>
31 PathProfileInfoFilename("path-profile-loader-file", cl::init("llvmprof.out"),
32   cl::value_desc("filename"),
33   cl::desc("Path profile file loaded by -path-profile-loader"), cl::Hidden);
34
35 namespace {
36   class PathProfileLoaderPass : public ModulePass, public PathProfileInfo {
37   public:
38     PathProfileLoaderPass() : ModulePass(ID) { }
39     ~PathProfileLoaderPass();
40
41     // this pass doesn't change anything (only loads information)
42     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
43       AU.setPreservesAll();
44     }
45
46     // the full name of the loader pass
47     virtual const char* getPassName() const {
48       return "Path Profiling Information Loader";
49     }
50
51     // required since this pass implements multiple inheritance
52                 virtual void *getAdjustedAnalysisPointer(AnalysisID PI) {
53       if (PI == &PathProfileInfo::ID)
54         return (PathProfileInfo*)this;
55       return this;
56     }
57
58     // entry point to run the pass
59     bool runOnModule(Module &M);
60
61     // pass identification
62     static char ID;
63
64   private:
65     // make a reference table to refer to function by number
66     void buildFunctionRefs(Module &M);
67
68     // process argument info of a program from the input file
69     void handleArgumentInfo();
70
71     // process path number information from the input file
72     void handlePathInfo();
73
74     // array of references to the functions in the module
75     std::vector<Function*> _functions;
76
77     // path profile file handle
78     FILE* _file;
79
80     // path profile file name
81     std::string _filename;
82   };
83 }
84
85 // register PathLoader
86 char PathProfileLoaderPass::ID = 0;
87
88 INITIALIZE_ANALYSIS_GROUP(PathProfileInfo, "Path Profile Information",
89                           NoPathProfileInfo)
90 INITIALIZE_AG_PASS(PathProfileLoaderPass, PathProfileInfo,
91                    "path-profile-loader",
92                    "Load path profile information from file",
93                    false, true, false)
94
95 char &llvm::PathProfileLoaderPassID = PathProfileLoaderPass::ID;
96
97 // link PathLoader as a pass, and make it available as an optimisation
98 ModulePass *llvm::createPathProfileLoaderPass() {
99   return new PathProfileLoaderPass;
100 }
101
102 // ----------------------------------------------------------------------------
103 // PathEdge implementation
104 //
105 ProfilePathEdge::ProfilePathEdge (BasicBlock* source, BasicBlock* target,
106                                   unsigned duplicateNumber)
107   : _source(source), _target(target), _duplicateNumber(duplicateNumber) {}
108
109 // ----------------------------------------------------------------------------
110 // Path implementation
111 //
112
113 ProfilePath::ProfilePath (unsigned int number, unsigned int count,
114                           double countStdDev,   PathProfileInfo* ppi)
115   : _number(number) , _count(count), _countStdDev(countStdDev), _ppi(ppi) {}
116
117 double ProfilePath::getFrequency() const {
118   return 100 * double(_count) /
119     double(_ppi->_functionPathCounts[_ppi->_currentFunction]);
120 }
121
122 static BallLarusEdge* getNextEdge (BallLarusNode* node,
123                                    unsigned int pathNumber) {
124   BallLarusEdge* best = 0;
125
126   for( BLEdgeIterator next = node->succBegin(),
127          end = node->succEnd(); next != end; next++ ) {
128     if( (*next)->getType() != BallLarusEdge::BACKEDGE && // no backedges
129         (*next)->getType() != BallLarusEdge::SPLITEDGE && // no split edges
130         (*next)->getWeight() <= pathNumber && // weight must be <= pathNumber
131         (!best || (best->getWeight() < (*next)->getWeight())) ) // best one?
132       best = *next;
133   }
134
135   return best;
136 }
137
138 ProfilePathEdgeVector* ProfilePath::getPathEdges() const {
139   BallLarusNode* currentNode = _ppi->_currentDag->getRoot ();
140   unsigned int increment = _number;
141   ProfilePathEdgeVector* pev = new ProfilePathEdgeVector;
142
143   while (currentNode != _ppi->_currentDag->getExit()) {
144     BallLarusEdge* next = getNextEdge(currentNode, increment);
145
146     increment -= next->getWeight();
147
148     if( next->getType() != BallLarusEdge::BACKEDGE_PHONY &&
149         next->getType() != BallLarusEdge::SPLITEDGE_PHONY &&
150         next->getTarget() != _ppi->_currentDag->getExit() )
151       pev->push_back(ProfilePathEdge(
152                        next->getSource()->getBlock(),
153                        next->getTarget()->getBlock(),
154                        next->getDuplicateNumber()));
155
156     if( next->getType() == BallLarusEdge::BACKEDGE_PHONY &&
157         next->getTarget() == _ppi->_currentDag->getExit() )
158       pev->push_back(ProfilePathEdge(
159                        next->getRealEdge()->getSource()->getBlock(),
160                        next->getRealEdge()->getTarget()->getBlock(),
161                        next->getDuplicateNumber()));
162
163     if( next->getType() == BallLarusEdge::SPLITEDGE_PHONY &&
164         next->getSource() == _ppi->_currentDag->getRoot() )
165       pev->push_back(ProfilePathEdge(
166                        next->getRealEdge()->getSource()->getBlock(),
167                        next->getRealEdge()->getTarget()->getBlock(),
168                        next->getDuplicateNumber()));
169
170     // set the new node
171     currentNode = next->getTarget();
172   }
173
174   return pev;
175 }
176
177 ProfilePathBlockVector* ProfilePath::getPathBlocks() const {
178   BallLarusNode* currentNode = _ppi->_currentDag->getRoot ();
179   unsigned int increment = _number;
180   ProfilePathBlockVector* pbv = new ProfilePathBlockVector;
181
182   while (currentNode != _ppi->_currentDag->getExit()) {
183     BallLarusEdge* next = getNextEdge(currentNode, increment);
184     increment -= next->getWeight();
185
186     // add block to the block list if it is a real edge
187     if( next->getType() == BallLarusEdge::NORMAL)
188       pbv->push_back (currentNode->getBlock());
189     // make the back edge the last edge since we are at the end
190     else if( next->getTarget() == _ppi->_currentDag->getExit() ) {
191       pbv->push_back (currentNode->getBlock());
192       pbv->push_back (next->getRealEdge()->getTarget()->getBlock());
193     }
194
195     // set the new node
196     currentNode = next->getTarget();
197   }
198
199   return pbv;
200 }
201
202 BasicBlock* ProfilePath::getFirstBlockInPath() const {
203   BallLarusNode* root = _ppi->_currentDag->getRoot();
204   BallLarusEdge* edge = getNextEdge(root, _number);
205
206   if( edge && (edge->getType() == BallLarusEdge::BACKEDGE_PHONY ||
207                edge->getType() == BallLarusEdge::SPLITEDGE_PHONY) )
208     return edge->getTarget()->getBlock();
209
210   return root->getBlock();
211 }
212
213 // ----------------------------------------------------------------------------
214 // PathProfileInfo implementation
215 //
216
217 // Pass identification
218 char llvm::PathProfileInfo::ID = 0;
219
220 PathProfileInfo::PathProfileInfo () : _currentDag(0) , _currentFunction(0) {
221 }
222
223 PathProfileInfo::~PathProfileInfo() {
224   if (_currentDag)
225     delete _currentDag;
226 }
227
228 // set the function for which paths are currently begin processed
229 void PathProfileInfo::setCurrentFunction(Function* F) {
230   // Make sure it exists
231   if (!F) return;
232
233   if (_currentDag)
234     delete _currentDag;
235
236   _currentFunction = F;
237   _currentDag = new BallLarusDag(*F);
238   _currentDag->init();
239   _currentDag->calculatePathNumbers();
240 }
241
242 // get the function for which paths are currently being processed
243 Function* PathProfileInfo::getCurrentFunction() const {
244   return _currentFunction;
245 }
246
247 // get the entry block of the function
248 BasicBlock* PathProfileInfo::getCurrentFunctionEntry() {
249   return _currentDag->getRoot()->getBlock();
250 }
251
252 // return the path based on its number
253 ProfilePath* PathProfileInfo::getPath(unsigned int number) {
254   return _functionPaths[_currentFunction][number];
255 }
256
257 // return the number of paths which a function may potentially execute
258 unsigned int PathProfileInfo::getPotentialPathCount() {
259   return _currentDag ? _currentDag->getNumberOfPaths() : 0;
260 }
261
262 // return an iterator for the beginning of a functions executed paths
263 ProfilePathIterator PathProfileInfo::pathBegin() {
264   return _functionPaths[_currentFunction].begin();
265 }
266
267 // return an iterator for the end of a functions executed paths
268 ProfilePathIterator PathProfileInfo::pathEnd() {
269   return _functionPaths[_currentFunction].end();
270 }
271
272 // returns the total number of paths run in the function
273 unsigned int PathProfileInfo::pathsRun() {
274   return _currentFunction ? _functionPaths[_currentFunction].size() : 0;
275 }
276
277 // ----------------------------------------------------------------------------
278 // PathLoader implementation
279 //
280
281 // remove all generated paths
282 PathProfileLoaderPass::~PathProfileLoaderPass() {
283   for( FunctionPathIterator funcNext = _functionPaths.begin(),
284          funcEnd = _functionPaths.end(); funcNext != funcEnd; funcNext++)
285     for( ProfilePathIterator pathNext = funcNext->second.begin(),
286            pathEnd = funcNext->second.end(); pathNext != pathEnd; pathNext++)
287       delete pathNext->second;
288 }
289
290 // entry point of the pass; this loads and parses a file
291 bool PathProfileLoaderPass::runOnModule(Module &M) {
292   // get the filename and setup the module's function references
293   _filename = PathProfileInfoFilename;
294   buildFunctionRefs (M);
295
296   if (!(_file = fopen(_filename.c_str(), "rb"))) {
297     errs () << "error: input '" << _filename << "' file does not exist.\n";
298     return false;
299   }
300
301   ProfilingType profType;
302
303   while( fread(&profType, sizeof(ProfilingType), 1, _file) ) {
304     switch (profType) {
305     case ArgumentInfo:
306       handleArgumentInfo ();
307       break;
308     case PathInfo:
309       handlePathInfo ();
310       break;
311     default:
312       errs () << "error: bad path profiling file syntax, " << profType << "\n";
313       fclose (_file);
314       return false;
315     }
316   }
317
318   fclose (_file);
319
320   return true;
321 }
322
323 // create a reference table for functions defined in the path profile file
324 void PathProfileLoaderPass::buildFunctionRefs (Module &M) {
325   _functions.push_back(0); // make the 0 index a null pointer
326
327   for (Module::iterator F = M.begin(), E = M.end(); F != E; F++) {
328     if (F->isDeclaration())
329       continue;
330     _functions.push_back(F);
331   }
332 }
333
334 // handle command like argument infor in the output file
335 void PathProfileLoaderPass::handleArgumentInfo() {
336   // get the argument list's length
337   unsigned savedArgsLength;
338   if( fread(&savedArgsLength, sizeof(unsigned), 1, _file) != 1 ) {
339     errs() << "warning: argument info header/data mismatch\n";
340     return;
341   }
342
343   // allocate a buffer, and get the arguments
344   char* args = new char[savedArgsLength+1];
345   if( fread(args, 1, savedArgsLength, _file) != savedArgsLength )
346     errs() << "warning: argument info header/data mismatch\n";
347
348   args[savedArgsLength] = '\0';
349   argList = std::string(args);
350   delete [] args; // cleanup dynamic string
351
352   // byte alignment
353   if (savedArgsLength & 3)
354     fseek(_file, 4-(savedArgsLength&3), SEEK_CUR);
355 }
356
357 // Handle path profile information in the output file
358 void PathProfileLoaderPass::handlePathInfo () {
359   // get the number of functions in this profile
360   unsigned functionCount;
361   if( fread(&functionCount, sizeof(functionCount), 1, _file) != 1 ) {
362     errs() << "warning: path info header/data mismatch\n";
363     return;
364   }
365
366   // gather path information for each function
367   for (unsigned i = 0; i < functionCount; i++) {
368     PathProfileHeader pathHeader;
369     if( fread(&pathHeader, sizeof(pathHeader), 1, _file) != 1 ) {
370       errs() << "warning: bad header for path function info\n";
371       break;
372     }
373
374     Function* f = _functions[pathHeader.fnNumber];
375
376     // dynamically allocate a table to store path numbers
377     PathProfileTableEntry* pathTable =
378       new PathProfileTableEntry[pathHeader.numEntries];
379
380     if( fread(pathTable, sizeof(PathProfileTableEntry),
381               pathHeader.numEntries, _file) != pathHeader.numEntries) {
382       delete [] pathTable;
383       errs() << "warning: path function info header/data mismatch\n";
384       return;
385     }
386
387     // Build a new path for the current function
388     unsigned int totalPaths = 0;
389     for (unsigned int j = 0; j < pathHeader.numEntries; j++) {
390       totalPaths += pathTable[j].pathCounter;
391       _functionPaths[f][pathTable[j].pathNumber]
392         = new ProfilePath(pathTable[j].pathNumber, pathTable[j].pathCounter,
393                           0, this);
394     }
395
396     _functionPathCounts[f] = totalPaths;
397
398     delete [] pathTable;
399   }
400 }
401
402 //===----------------------------------------------------------------------===//
403 //  NoProfile PathProfileInfo implementation
404 //
405
406 namespace {
407   struct NoPathProfileInfo : public ImmutablePass, public PathProfileInfo {
408     static char ID; // Class identification, replacement for typeinfo
409     NoPathProfileInfo() : ImmutablePass(ID) {
410       initializeNoPathProfileInfoPass(*PassRegistry::getPassRegistry());
411     }
412
413     /// getAdjustedAnalysisPointer - This method is used when a pass implements
414     /// an analysis interface through multiple inheritance.  If needed, it
415     /// should override this to adjust the this pointer as needed for the
416     /// specified pass info.
417     virtual void *getAdjustedAnalysisPointer(AnalysisID PI) {
418       if (PI == &PathProfileInfo::ID)
419         return (PathProfileInfo*)this;
420       return this;
421     }
422
423     virtual const char *getPassName() const {
424       return "NoPathProfileInfo";
425     }
426   };
427 }  // End of anonymous namespace
428
429 char NoPathProfileInfo::ID = 0;
430 // Register this pass...
431 INITIALIZE_AG_PASS(NoPathProfileInfo, PathProfileInfo, "no-path-profile",
432                    "No Path Profile Information", false, true, true)
433
434 ImmutablePass *llvm::createNoPathProfileInfoPass() { return new NoPathProfileInfo(); }