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:
PathProfileLoaderPass()38 PathProfileLoaderPass() : ModulePass(ID) { }
39 ~PathProfileLoaderPass();
40
41 // this pass doesn't change anything (only loads information)
getAnalysisUsage(AnalysisUsage & AU) const42 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
43 AU.setPreservesAll();
44 }
45
46 // the full name of the loader pass
getPassName() const47 virtual const char* getPassName() const {
48 return "Path Profiling Information Loader";
49 }
50
51 // required since this pass implements multiple inheritance
getAdjustedAnalysisPointer(AnalysisID PI)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
createPathProfileLoaderPass()98 ModulePass *llvm::createPathProfileLoaderPass() {
99 return new PathProfileLoaderPass;
100 }
101
102 // ----------------------------------------------------------------------------
103 // PathEdge implementation
104 //
ProfilePathEdge(BasicBlock * source,BasicBlock * target,unsigned duplicateNumber)105 ProfilePathEdge::ProfilePathEdge (BasicBlock* source, BasicBlock* target,
106 unsigned duplicateNumber)
107 : _source(source), _target(target), _duplicateNumber(duplicateNumber) {}
108
109 // ----------------------------------------------------------------------------
110 // Path implementation
111 //
112
ProfilePath(unsigned int number,unsigned int count,double countStdDev,PathProfileInfo * ppi)113 ProfilePath::ProfilePath (unsigned int number, unsigned int count,
114 double countStdDev, PathProfileInfo* ppi)
115 : _number(number) , _count(count), _countStdDev(countStdDev), _ppi(ppi) {}
116
getFrequency() const117 double ProfilePath::getFrequency() const {
118 return 100 * double(_count) /
119 double(_ppi->_functionPathCounts[_ppi->_currentFunction]);
120 }
121
getNextEdge(BallLarusNode * node,unsigned int pathNumber)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
getPathEdges() const138 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
getPathBlocks() const177 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
getFirstBlockInPath() const202 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
PathProfileInfo()220 PathProfileInfo::PathProfileInfo () : _currentDag(0) , _currentFunction(0) {
221 }
222
~PathProfileInfo()223 PathProfileInfo::~PathProfileInfo() {
224 if (_currentDag)
225 delete _currentDag;
226 }
227
228 // set the function for which paths are currently begin processed
setCurrentFunction(Function * F)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
getCurrentFunction() const243 Function* PathProfileInfo::getCurrentFunction() const {
244 return _currentFunction;
245 }
246
247 // get the entry block of the function
getCurrentFunctionEntry()248 BasicBlock* PathProfileInfo::getCurrentFunctionEntry() {
249 return _currentDag->getRoot()->getBlock();
250 }
251
252 // return the path based on its number
getPath(unsigned int 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
getPotentialPathCount()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
pathBegin()263 ProfilePathIterator PathProfileInfo::pathBegin() {
264 return _functionPaths[_currentFunction].begin();
265 }
266
267 // return an iterator for the end of a functions executed paths
pathEnd()268 ProfilePathIterator PathProfileInfo::pathEnd() {
269 return _functionPaths[_currentFunction].end();
270 }
271
272 // returns the total number of paths run in the function
pathsRun()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
~PathProfileLoaderPass()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
runOnModule(Module & M)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
buildFunctionRefs(Module & M)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
handleArgumentInfo()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
handlePathInfo()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
NoPathProfileInfo__anon7644c0920211::NoPathProfileInfo409 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.
getAdjustedAnalysisPointer__anon7644c0920211::NoPathProfileInfo417 virtual void *getAdjustedAnalysisPointer(AnalysisID PI) {
418 if (PI == &PathProfileInfo::ID)
419 return (PathProfileInfo*)this;
420 return this;
421 }
422
getPassName__anon7644c0920211::NoPathProfileInfo423 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
createNoPathProfileInfoPass()434 ImmutablePass *llvm::createNoPathProfileInfoPass() { return new NoPathProfileInfo(); }
435