llvm-prof.cpp revision 065344dfd5a7b3502098810b981eb0077e5d81f3
1//===- llvm-prof.cpp - Read in and process llvmprof.out data files --------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source 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/InstrTypes.h" 17#include "llvm/Module.h" 18#include "llvm/Assembly/AsmAnnotationWriter.h" 19#include "llvm/Analysis/ProfileInfoLoader.h" 20#include "llvm/Bitcode/ReaderWriter.h" 21#include "llvm/Support/CommandLine.h" 22#include "llvm/Support/ManagedStatic.h" 23#include "llvm/Support/MemoryBuffer.h" 24#include "llvm/System/Signals.h" 25#include <algorithm> 26#include <iostream> 27#include <iomanip> 28#include <map> 29#include <set> 30 31using namespace llvm; 32 33namespace { 34 cl::opt<std::string> 35 BytecodeFile(cl::Positional, cl::desc("<program bytecode file>"), 36 cl::Required); 37 38 cl::opt<std::string> 39 ProfileDataFile(cl::Positional, cl::desc("<llvmprof.out file>"), 40 cl::Optional, cl::init("llvmprof.out")); 41 42 cl::opt<bool> 43 PrintAnnotatedLLVM("annotated-llvm", 44 cl::desc("Print LLVM code with frequency annotations")); 45 cl::alias PrintAnnotated2("A", cl::desc("Alias for --annotated-llvm"), 46 cl::aliasopt(PrintAnnotatedLLVM)); 47 cl::opt<bool> 48 PrintAllCode("print-all-code", 49 cl::desc("Print annotated code for the entire program")); 50} 51 52// PairSecondSort - A sorting predicate to sort by the second element of a pair. 53template<class T> 54struct PairSecondSortReverse 55 : public std::binary_function<std::pair<T, unsigned>, 56 std::pair<T, unsigned>, bool> { 57 bool operator()(const std::pair<T, unsigned> &LHS, 58 const std::pair<T, unsigned> &RHS) const { 59 return LHS.second > RHS.second; 60 } 61}; 62 63namespace { 64 class ProfileAnnotator : public AssemblyAnnotationWriter { 65 std::map<const Function *, unsigned> &FuncFreqs; 66 std::map<const BasicBlock*, unsigned> &BlockFreqs; 67 std::map<ProfileInfoLoader::Edge, unsigned> &EdgeFreqs; 68 public: 69 ProfileAnnotator(std::map<const Function *, unsigned> &FF, 70 std::map<const BasicBlock*, unsigned> &BF, 71 std::map<ProfileInfoLoader::Edge, unsigned> &EF) 72 : FuncFreqs(FF), BlockFreqs(BF), EdgeFreqs(EF) {} 73 74 virtual void emitFunctionAnnot(const Function *F, std::ostream &OS) { 75 OS << ";;; %" << F->getName() << " called " << FuncFreqs[F] 76 << " times.\n;;;\n"; 77 } 78 virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, 79 std::ostream &OS) { 80 if (BlockFreqs.empty()) return; 81 if (unsigned Count = BlockFreqs[BB]) 82 OS << "\t;;; Basic block executed " << Count << " times.\n"; 83 else 84 OS << "\t;;; Never executed!\n"; 85 } 86 87 virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, std::ostream &OS){ 88 if (EdgeFreqs.empty()) return; 89 90 // Figure out how many times each successor executed. 91 std::vector<std::pair<const BasicBlock*, unsigned> > SuccCounts; 92 const TerminatorInst *TI = BB->getTerminator(); 93 94 std::map<ProfileInfoLoader::Edge, unsigned>::iterator I = 95 EdgeFreqs.lower_bound(std::make_pair(const_cast<BasicBlock*>(BB), 0U)); 96 for (; I != EdgeFreqs.end() && I->first.first == BB; ++I) 97 if (I->second) 98 SuccCounts.push_back(std::make_pair(TI->getSuccessor(I->first.second), 99 I->second)); 100 if (!SuccCounts.empty()) { 101 OS << "\t;;; Out-edge counts:"; 102 for (unsigned i = 0, e = SuccCounts.size(); i != e; ++i) 103 OS << " [" << SuccCounts[i].second << " -> " 104 << SuccCounts[i].first->getName() << "]"; 105 OS << "\n"; 106 } 107 } 108 }; 109} 110 111 112int main(int argc, char **argv) { 113 llvm_shutdown_obj X; // Call llvm_shutdown() on exit. 114 try { 115 cl::ParseCommandLineOptions(argc, argv, " llvm profile dump decoder\n"); 116 sys::PrintStackTraceOnErrorSignal(); 117 118 // Read in the bytecode file... 119 std::string ErrorMessage; 120 Module *M; 121 if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(BytecodeFile, 122 &ErrorMessage)) { 123 M = ParseBitcodeFile(Buffer, &ErrorMessage); 124 delete Buffer; 125 } 126 if (M == 0) { 127 std::cerr << argv[0] << ": " << BytecodeFile << ": " 128 << ErrorMessage << "\n"; 129 return 1; 130 } 131 132 // Read the profiling information 133 ProfileInfoLoader PI(argv[0], ProfileDataFile, *M); 134 135 std::map<const Function *, unsigned> FuncFreqs; 136 std::map<const BasicBlock*, unsigned> BlockFreqs; 137 std::map<ProfileInfoLoader::Edge, unsigned> EdgeFreqs; 138 139 // Output a report. Eventually, there will be multiple reports selectable on 140 // the command line, for now, just keep things simple. 141 142 // Emit the most frequent function table... 143 std::vector<std::pair<Function*, unsigned> > FunctionCounts; 144 PI.getFunctionCounts(FunctionCounts); 145 FuncFreqs.insert(FunctionCounts.begin(), FunctionCounts.end()); 146 147 // Sort by the frequency, backwards. 148 sort(FunctionCounts.begin(), FunctionCounts.end(), 149 PairSecondSortReverse<Function*>()); 150 151 uint64_t TotalExecutions = 0; 152 for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i) 153 TotalExecutions += FunctionCounts[i].second; 154 155 std::cout << "===" << std::string(73, '-') << "===\n" 156 << "LLVM profiling output for execution"; 157 if (PI.getNumExecutions() != 1) std::cout << "s"; 158 std::cout << ":\n"; 159 160 for (unsigned i = 0, e = PI.getNumExecutions(); i != e; ++i) { 161 std::cout << " "; 162 if (e != 1) std::cout << i+1 << ". "; 163 std::cout << PI.getExecution(i) << "\n"; 164 } 165 166 std::cout << "\n===" << std::string(73, '-') << "===\n"; 167 std::cout << "Function execution frequencies:\n\n"; 168 169 // Print out the function frequencies... 170 std::cout << " ## Frequency\n"; 171 for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i) { 172 if (FunctionCounts[i].second == 0) { 173 std::cout << "\n NOTE: " << e-i << " function" << 174 (e-i-1 ? "s were" : " was") << " never executed!\n"; 175 break; 176 } 177 178 std::cout << std::setw(3) << i+1 << ". " 179 << std::setw(5) << FunctionCounts[i].second << "/" 180 << TotalExecutions << " " 181 << FunctionCounts[i].first->getName().c_str() << "\n"; 182 } 183 184 std::set<Function*> FunctionsToPrint; 185 186 // If we have block count information, print out the LLVM module with 187 // frequency annotations. 188 if (PI.hasAccurateBlockCounts()) { 189 std::vector<std::pair<BasicBlock*, unsigned> > Counts; 190 PI.getBlockCounts(Counts); 191 192 TotalExecutions = 0; 193 for (unsigned i = 0, e = Counts.size(); i != e; ++i) 194 TotalExecutions += Counts[i].second; 195 196 // Sort by the frequency, backwards. 197 sort(Counts.begin(), Counts.end(), 198 PairSecondSortReverse<BasicBlock*>()); 199 200 std::cout << "\n===" << std::string(73, '-') << "===\n"; 201 std::cout << "Top 20 most frequently executed basic blocks:\n\n"; 202 203 // Print out the function frequencies... 204 std::cout <<" ## %% \tFrequency\n"; 205 unsigned BlocksToPrint = Counts.size(); 206 if (BlocksToPrint > 20) BlocksToPrint = 20; 207 for (unsigned i = 0; i != BlocksToPrint; ++i) { 208 if (Counts[i].second == 0) break; 209 Function *F = Counts[i].first->getParent(); 210 std::cout << std::setw(3) << i+1 << ". " 211 << std::setw(5) << std::setprecision(2) 212 << Counts[i].second/(double)TotalExecutions*100 << "% " 213 << std::setw(5) << Counts[i].second << "/" 214 << TotalExecutions << "\t" 215 << F->getName().c_str() << "() - " 216 << Counts[i].first->getName().c_str() << "\n"; 217 FunctionsToPrint.insert(F); 218 } 219 220 BlockFreqs.insert(Counts.begin(), Counts.end()); 221 } 222 223 if (PI.hasAccurateEdgeCounts()) { 224 std::vector<std::pair<ProfileInfoLoader::Edge, unsigned> > Counts; 225 PI.getEdgeCounts(Counts); 226 EdgeFreqs.insert(Counts.begin(), Counts.end()); 227 } 228 229 if (PrintAnnotatedLLVM || PrintAllCode) { 230 std::cout << "\n===" << std::string(73, '-') << "===\n"; 231 std::cout << "Annotated LLVM code for the module:\n\n"; 232 233 ProfileAnnotator PA(FuncFreqs, BlockFreqs, EdgeFreqs); 234 235 if (FunctionsToPrint.empty() || PrintAllCode) 236 M->print(std::cout, &PA); 237 else 238 // Print just a subset of the functions... 239 for (std::set<Function*>::iterator I = FunctionsToPrint.begin(), 240 E = FunctionsToPrint.end(); I != E; ++I) 241 (*I)->print(std::cout, &PA); 242 } 243 244 return 0; 245 } catch (const std::string& msg) { 246 std::cerr << argv[0] << ": " << msg << "\n"; 247 } catch (...) { 248 std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; 249 } 250 return 1; 251} 252