Use BranchProbability instead of floating points in IfConverter.
[llvm/stm8.git] / lib / Analysis / PathProfileInfo.cpp
blobb361d3f4fa94b1e5a0eb09f2dd73b24412c861a3
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.
13 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "path-profile-info"
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"
25 #include <cstdio>
27 using namespace llvm;
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);
35 namespace {
36 class PathProfileLoaderPass : public ModulePass, public PathProfileInfo {
37 public:
38 PathProfileLoaderPass() : ModulePass(ID) { }
39 ~PathProfileLoaderPass();
41 // this pass doesn't change anything (only loads information)
42 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
43 AU.setPreservesAll();
46 // the full name of the loader pass
47 virtual const char* getPassName() const {
48 return "Path Profiling Information Loader";
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;
58 // entry point to run the pass
59 bool runOnModule(Module &M);
61 // pass identification
62 static char ID;
64 private:
65 // make a reference table to refer to function by number
66 void buildFunctionRefs(Module &M);
68 // process argument info of a program from the input file
69 void handleArgumentInfo();
71 // process path number information from the input file
72 void handlePathInfo();
74 // array of references to the functions in the module
75 std::vector<Function*> _functions;
77 // path profile file handle
78 FILE* _file;
80 // path profile file name
81 std::string _filename;
85 // register PathLoader
86 char PathProfileLoaderPass::ID = 0;
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)
95 char &llvm::PathProfileLoaderPassID = PathProfileLoaderPass::ID;
97 // link PathLoader as a pass, and make it available as an optimisation
98 ModulePass *llvm::createPathProfileLoaderPass() {
99 return new PathProfileLoaderPass;
102 // ----------------------------------------------------------------------------
103 // PathEdge implementation
105 ProfilePathEdge::ProfilePathEdge (BasicBlock* source, BasicBlock* target,
106 unsigned duplicateNumber)
107 : _source(source), _target(target), _duplicateNumber(duplicateNumber) {}
109 // ----------------------------------------------------------------------------
110 // Path implementation
113 ProfilePath::ProfilePath (unsigned int number, unsigned int count,
114 double countStdDev, PathProfileInfo* ppi)
115 : _number(number) , _count(count), _countStdDev(countStdDev), _ppi(ppi) {}
117 double ProfilePath::getFrequency() const {
118 return 100 * double(_count) /
119 double(_ppi->_functionPathCounts[_ppi->_currentFunction]);
122 static BallLarusEdge* getNextEdge (BallLarusNode* node,
123 unsigned int pathNumber) {
124 BallLarusEdge* best = 0;
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;
135 return best;
138 ProfilePathEdgeVector* ProfilePath::getPathEdges() const {
139 BallLarusNode* currentNode = _ppi->_currentDag->getRoot ();
140 unsigned int increment = _number;
141 ProfilePathEdgeVector* pev = new ProfilePathEdgeVector;
143 while (currentNode != _ppi->_currentDag->getExit()) {
144 BallLarusEdge* next = getNextEdge(currentNode, increment);
146 increment -= next->getWeight();
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()));
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()));
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()));
170 // set the new node
171 currentNode = next->getTarget();
174 return pev;
177 ProfilePathBlockVector* ProfilePath::getPathBlocks() const {
178 BallLarusNode* currentNode = _ppi->_currentDag->getRoot ();
179 unsigned int increment = _number;
180 ProfilePathBlockVector* pbv = new ProfilePathBlockVector;
182 while (currentNode != _ppi->_currentDag->getExit()) {
183 BallLarusEdge* next = getNextEdge(currentNode, increment);
184 increment -= next->getWeight();
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());
195 // set the new node
196 currentNode = next->getTarget();
199 return pbv;
202 BasicBlock* ProfilePath::getFirstBlockInPath() const {
203 BallLarusNode* root = _ppi->_currentDag->getRoot();
204 BallLarusEdge* edge = getNextEdge(root, _number);
206 if( edge && (edge->getType() == BallLarusEdge::BACKEDGE_PHONY ||
207 edge->getType() == BallLarusEdge::SPLITEDGE_PHONY) )
208 return edge->getTarget()->getBlock();
210 return root->getBlock();
213 // ----------------------------------------------------------------------------
214 // PathProfileInfo implementation
217 // Pass identification
218 char llvm::PathProfileInfo::ID = 0;
220 PathProfileInfo::PathProfileInfo () : _currentDag(0) , _currentFunction(0) {
223 PathProfileInfo::~PathProfileInfo() {
224 if (_currentDag)
225 delete _currentDag;
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;
233 if (_currentDag)
234 delete _currentDag;
236 _currentFunction = F;
237 _currentDag = new BallLarusDag(*F);
238 _currentDag->init();
239 _currentDag->calculatePathNumbers();
242 // get the function for which paths are currently being processed
243 Function* PathProfileInfo::getCurrentFunction() const {
244 return _currentFunction;
247 // get the entry block of the function
248 BasicBlock* PathProfileInfo::getCurrentFunctionEntry() {
249 return _currentDag->getRoot()->getBlock();
252 // return the path based on its number
253 ProfilePath* PathProfileInfo::getPath(unsigned int number) {
254 return _functionPaths[_currentFunction][number];
257 // return the number of paths which a function may potentially execute
258 unsigned int PathProfileInfo::getPotentialPathCount() {
259 return _currentDag ? _currentDag->getNumberOfPaths() : 0;
262 // return an iterator for the beginning of a functions executed paths
263 ProfilePathIterator PathProfileInfo::pathBegin() {
264 return _functionPaths[_currentFunction].begin();
267 // return an iterator for the end of a functions executed paths
268 ProfilePathIterator PathProfileInfo::pathEnd() {
269 return _functionPaths[_currentFunction].end();
272 // returns the total number of paths run in the function
273 unsigned int PathProfileInfo::pathsRun() {
274 return _currentFunction ? _functionPaths[_currentFunction].size() : 0;
277 // ----------------------------------------------------------------------------
278 // PathLoader implementation
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;
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);
296 if (!(_file = fopen(_filename.c_str(), "rb"))) {
297 errs () << "error: input '" << _filename << "' file does not exist.\n";
298 return false;
301 ProfilingType profType;
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;
318 fclose (_file);
320 return true;
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
327 for (Module::iterator F = M.begin(), E = M.end(); F != E; F++) {
328 if (F->isDeclaration())
329 continue;
330 _functions.push_back(F);
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;
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";
348 args[savedArgsLength] = '\0';
349 argList = std::string(args);
350 delete [] args; // cleanup dynamic string
352 // byte alignment
353 if (savedArgsLength & 3)
354 fseek(_file, 4-(savedArgsLength&3), SEEK_CUR);
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;
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;
374 Function* f = _functions[pathHeader.fnNumber];
376 // dynamically allocate a table to store path numbers
377 PathProfileTableEntry* pathTable =
378 new PathProfileTableEntry[pathHeader.numEntries];
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;
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);
396 _functionPathCounts[f] = totalPaths;
398 delete [] pathTable;
402 //===----------------------------------------------------------------------===//
403 // NoProfile PathProfileInfo implementation
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());
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;
423 virtual const char *getPassName() const {
424 return "NoPathProfileInfo";
427 } // End of anonymous namespace
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)
434 ImmutablePass *llvm::createNoPathProfileInfoPass() { return new NoPathProfileInfo(); }