• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  //===- llvm-prof.cpp - Read in and process llvmprof.out data files --------===//
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 tools is meant for use with the various LLVM profiling instrumentation
11  // passes.  It reads in the data file produced by executing an instrumented
12  // program, and outputs a nice report.
13  //
14  //===----------------------------------------------------------------------===//
15  
16  #include "llvm/IR/LLVMContext.h"
17  #include "llvm/Analysis/Passes.h"
18  #include "llvm/Analysis/ProfileInfo.h"
19  #include "llvm/Analysis/ProfileInfoLoader.h"
20  #include "llvm/Assembly/AssemblyAnnotationWriter.h"
21  #include "llvm/Bitcode/ReaderWriter.h"
22  #include "llvm/IR/InstrTypes.h"
23  #include "llvm/IR/Module.h"
24  #include "llvm/PassManager.h"
25  #include "llvm/Support/CommandLine.h"
26  #include "llvm/Support/Format.h"
27  #include "llvm/Support/FormattedStream.h"
28  #include "llvm/Support/ManagedStatic.h"
29  #include "llvm/Support/MemoryBuffer.h"
30  #include "llvm/Support/PrettyStackTrace.h"
31  #include "llvm/Support/Signals.h"
32  #include "llvm/Support/raw_ostream.h"
33  #include "llvm/Support/system_error.h"
34  #include <algorithm>
35  #include <iomanip>
36  #include <map>
37  #include <set>
38  
39  using namespace llvm;
40  
41  namespace {
42    cl::opt<std::string>
43    BitcodeFile(cl::Positional, cl::desc("<program bitcode file>"),
44                cl::Required);
45  
46    cl::opt<std::string>
47    ProfileDataFile(cl::Positional, cl::desc("<llvmprof.out file>"),
48                    cl::Optional, cl::init("llvmprof.out"));
49  
50    cl::opt<bool>
51    PrintAnnotatedLLVM("annotated-llvm",
52                       cl::desc("Print LLVM code with frequency annotations"));
53    cl::alias PrintAnnotated2("A", cl::desc("Alias for --annotated-llvm"),
54                              cl::aliasopt(PrintAnnotatedLLVM));
55    cl::opt<bool>
56    PrintAllCode("print-all-code",
57                 cl::desc("Print annotated code for the entire program"));
58  }
59  
60  // PairSecondSort - A sorting predicate to sort by the second element of a pair.
61  template<class T>
62  struct PairSecondSortReverse
63    : public std::binary_function<std::pair<T, double>,
64                                  std::pair<T, double>, bool> {
operator ()PairSecondSortReverse65    bool operator()(const std::pair<T, double> &LHS,
66                    const std::pair<T, double> &RHS) const {
67      return LHS.second > RHS.second;
68    }
69  };
70  
ignoreMissing(double w)71  static double ignoreMissing(double w) {
72    if (w == ProfileInfo::MissingValue) return 0;
73    return w;
74  }
75  
76  namespace {
77    class ProfileAnnotator : public AssemblyAnnotationWriter {
78      ProfileInfo &PI;
79    public:
ProfileAnnotator(ProfileInfo & pi)80      ProfileAnnotator(ProfileInfo &pi) : PI(pi) {}
81  
emitFunctionAnnot(const Function * F,formatted_raw_ostream & OS)82      virtual void emitFunctionAnnot(const Function *F,
83                                     formatted_raw_ostream &OS) {
84        double w = PI.getExecutionCount(F);
85        if (w != ProfileInfo::MissingValue) {
86          OS << ";;; %" << F->getName() << " called "<<(unsigned)w
87             <<" times.\n;;;\n";
88        }
89      }
emitBasicBlockStartAnnot(const BasicBlock * BB,formatted_raw_ostream & OS)90      virtual void emitBasicBlockStartAnnot(const BasicBlock *BB,
91                                            formatted_raw_ostream &OS) {
92        double w = PI.getExecutionCount(BB);
93        if (w != ProfileInfo::MissingValue) {
94          if (w != 0) {
95            OS << "\t;;; Basic block executed " << (unsigned)w << " times.\n";
96          } else {
97            OS << "\t;;; Never executed!\n";
98          }
99        }
100      }
101  
emitBasicBlockEndAnnot(const BasicBlock * BB,formatted_raw_ostream & OS)102      virtual void emitBasicBlockEndAnnot(const BasicBlock *BB,
103                                          formatted_raw_ostream &OS) {
104        // Figure out how many times each successor executed.
105        std::vector<std::pair<ProfileInfo::Edge, double> > SuccCounts;
106  
107        const TerminatorInst *TI = BB->getTerminator();
108        for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
109          BasicBlock* Succ = TI->getSuccessor(s);
110          double w = ignoreMissing(PI.getEdgeWeight(std::make_pair(BB, Succ)));
111          if (w != 0)
112            SuccCounts.push_back(std::make_pair(std::make_pair(BB, Succ), w));
113        }
114        if (!SuccCounts.empty()) {
115          OS << "\t;;; Out-edge counts:";
116          for (unsigned i = 0, e = SuccCounts.size(); i != e; ++i)
117            OS << " [" << (SuccCounts[i]).second << " -> "
118               << (SuccCounts[i]).first.second->getName() << "]";
119          OS << "\n";
120        }
121      }
122    };
123  }
124  
125  namespace {
126    /// ProfileInfoPrinterPass - Helper pass to dump the profile information for
127    /// a module.
128    //
129    // FIXME: This should move elsewhere.
130    class ProfileInfoPrinterPass : public ModulePass {
131      ProfileInfoLoader &PIL;
132    public:
133      static char ID; // Class identification, replacement for typeinfo.
ProfileInfoPrinterPass(ProfileInfoLoader & _PIL)134      explicit ProfileInfoPrinterPass(ProfileInfoLoader &_PIL)
135        : ModulePass(ID), PIL(_PIL) {}
136  
getAnalysisUsage(AnalysisUsage & AU) const137      virtual void getAnalysisUsage(AnalysisUsage &AU) const {
138        AU.setPreservesAll();
139        AU.addRequired<ProfileInfo>();
140      }
141  
142      bool runOnModule(Module &M);
143    };
144  }
145  
146  char ProfileInfoPrinterPass::ID = 0;
147  
runOnModule(Module & M)148  bool ProfileInfoPrinterPass::runOnModule(Module &M) {
149    ProfileInfo &PI = getAnalysis<ProfileInfo>();
150    std::map<const Function  *, unsigned> FuncFreqs;
151    std::map<const BasicBlock*, unsigned> BlockFreqs;
152    std::map<ProfileInfo::Edge, unsigned> EdgeFreqs;
153  
154    // Output a report. Eventually, there will be multiple reports selectable on
155    // the command line, for now, just keep things simple.
156  
157    // Emit the most frequent function table...
158    std::vector<std::pair<Function*, double> > FunctionCounts;
159    std::vector<std::pair<BasicBlock*, double> > Counts;
160    for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) {
161      if (FI->isDeclaration()) continue;
162      double w = ignoreMissing(PI.getExecutionCount(FI));
163      FunctionCounts.push_back(std::make_pair(FI, w));
164      for (Function::iterator BB = FI->begin(), BBE = FI->end();
165           BB != BBE; ++BB) {
166        double w = ignoreMissing(PI.getExecutionCount(BB));
167        Counts.push_back(std::make_pair(BB, w));
168      }
169    }
170  
171    // Sort by the frequency, backwards.
172    sort(FunctionCounts.begin(), FunctionCounts.end(),
173              PairSecondSortReverse<Function*>());
174  
175    double TotalExecutions = 0;
176    for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i)
177      TotalExecutions += FunctionCounts[i].second;
178  
179    outs() << "===" << std::string(73, '-') << "===\n"
180           << "LLVM profiling output for execution";
181    if (PIL.getNumExecutions() != 1) outs() << "s";
182    outs() << ":\n";
183  
184    for (unsigned i = 0, e = PIL.getNumExecutions(); i != e; ++i) {
185      outs() << "  ";
186      if (e != 1) outs() << i+1 << ". ";
187      outs() << PIL.getExecution(i) << "\n";
188    }
189  
190    outs() << "\n===" << std::string(73, '-') << "===\n";
191    outs() << "Function execution frequencies:\n\n";
192  
193    // Print out the function frequencies...
194    outs() << " ##   Frequency\n";
195    for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i) {
196      if (FunctionCounts[i].second == 0) {
197        outs() << "\n  NOTE: " << e-i << " function"
198          << (e-i-1 ? "s were" : " was") << " never executed!\n";
199        break;
200      }
201  
202      outs() << format("%3d", i+1) << ". "
203             << format("%5.2g", FunctionCounts[i].second) << "/"
204             << format("%g", TotalExecutions) << " "
205             << FunctionCounts[i].first->getName() << "\n";
206    }
207  
208    std::set<Function*> FunctionsToPrint;
209  
210    TotalExecutions = 0;
211    for (unsigned i = 0, e = Counts.size(); i != e; ++i)
212      TotalExecutions += Counts[i].second;
213  
214    // Sort by the frequency, backwards.
215    sort(Counts.begin(), Counts.end(),
216         PairSecondSortReverse<BasicBlock*>());
217  
218    outs() << "\n===" << std::string(73, '-') << "===\n";
219    outs() << "Top 20 most frequently executed basic blocks:\n\n";
220  
221    // Print out the function frequencies...
222    outs() <<" ##      %% \tFrequency\n";
223    unsigned BlocksToPrint = Counts.size();
224    if (BlocksToPrint > 20) BlocksToPrint = 20;
225    for (unsigned i = 0; i != BlocksToPrint; ++i) {
226      if (Counts[i].second == 0) break;
227      Function *F = Counts[i].first->getParent();
228      outs() << format("%3d", i+1) << ". "
229             << format("%5g", Counts[i].second/(double)TotalExecutions*100)<<"% "
230             << format("%5.0f", Counts[i].second) << "/"
231             << format("%g", TotalExecutions) << "\t"
232             << F->getName() << "() - "
233             << Counts[i].first->getName() << "\n";
234      FunctionsToPrint.insert(F);
235    }
236  
237    if (PrintAnnotatedLLVM || PrintAllCode) {
238      outs() << "\n===" << std::string(73, '-') << "===\n";
239      outs() << "Annotated LLVM code for the module:\n\n";
240  
241      ProfileAnnotator PA(PI);
242  
243      if (FunctionsToPrint.empty() || PrintAllCode)
244        M.print(outs(), &PA);
245      else
246        // Print just a subset of the functions.
247        for (std::set<Function*>::iterator I = FunctionsToPrint.begin(),
248               E = FunctionsToPrint.end(); I != E; ++I)
249          (*I)->print(outs(), &PA);
250    }
251  
252    return false;
253  }
254  
main(int argc,char ** argv)255  int main(int argc, char **argv) {
256    // Print a stack trace if we signal out.
257    sys::PrintStackTraceOnErrorSignal();
258    PrettyStackTraceProgram X(argc, argv);
259  
260    LLVMContext &Context = getGlobalContext();
261    llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
262  
263    cl::ParseCommandLineOptions(argc, argv, "llvm profile dump decoder\n");
264  
265    // Read in the bitcode file...
266    std::string ErrorMessage;
267    OwningPtr<MemoryBuffer> Buffer;
268    error_code ec;
269    Module *M = 0;
270    if (!(ec = MemoryBuffer::getFileOrSTDIN(BitcodeFile, Buffer))) {
271      M = ParseBitcodeFile(Buffer.get(), Context, &ErrorMessage);
272    } else
273      ErrorMessage = ec.message();
274    if (M == 0) {
275      errs() << argv[0] << ": " << BitcodeFile << ": "
276        << ErrorMessage << "\n";
277      return 1;
278    }
279  
280    // Read the profiling information. This is redundant since we load it again
281    // using the standard profile info provider pass, but for now this gives us
282    // access to additional information not exposed via the ProfileInfo
283    // interface.
284    ProfileInfoLoader PIL(argv[0], ProfileDataFile);
285  
286    // Run the printer pass.
287    PassManager PassMgr;
288    PassMgr.add(createProfileLoaderPass(ProfileDataFile));
289    PassMgr.add(new ProfileInfoPrinterPass(PIL));
290    PassMgr.run(*M);
291  
292    return 0;
293  }
294