1 //===- llvm-prof.cpp - Read in and process llvmprof.out data files --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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.
14 //===----------------------------------------------------------------------===//
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/Support/PrettyStackTrace.h"
25 #include "llvm/Support/raw_ostream.h"
26 #include "llvm/System/Signals.h"
37 BitcodeFile(cl::Positional
, cl::desc("<program bitcode file>"),
41 ProfileDataFile(cl::Positional
, cl::desc("<llvmprof.out file>"),
42 cl::Optional
, cl::init("llvmprof.out"));
45 PrintAnnotatedLLVM("annotated-llvm",
46 cl::desc("Print LLVM code with frequency annotations"));
47 cl::alias
PrintAnnotated2("A", cl::desc("Alias for --annotated-llvm"),
48 cl::aliasopt(PrintAnnotatedLLVM
));
50 PrintAllCode("print-all-code",
51 cl::desc("Print annotated code for the entire program"));
54 // PairSecondSort - A sorting predicate to sort by the second element of a pair.
56 struct PairSecondSortReverse
57 : public std::binary_function
<std::pair
<T
, unsigned>,
58 std::pair
<T
, unsigned>, bool> {
59 bool operator()(const std::pair
<T
, unsigned> &LHS
,
60 const std::pair
<T
, unsigned> &RHS
) const {
61 return LHS
.second
> RHS
.second
;
66 class ProfileAnnotator
: public AssemblyAnnotationWriter
{
67 std::map
<const Function
*, unsigned> &FuncFreqs
;
68 std::map
<const BasicBlock
*, unsigned> &BlockFreqs
;
69 std::map
<ProfileInfoLoader::Edge
, unsigned> &EdgeFreqs
;
71 ProfileAnnotator(std::map
<const Function
*, unsigned> &FF
,
72 std::map
<const BasicBlock
*, unsigned> &BF
,
73 std::map
<ProfileInfoLoader::Edge
, unsigned> &EF
)
74 : FuncFreqs(FF
), BlockFreqs(BF
), EdgeFreqs(EF
) {}
76 virtual void emitFunctionAnnot(const Function
*F
, raw_ostream
&OS
) {
77 OS
<< ";;; %" << F
->getName() << " called " << FuncFreqs
[F
]
80 virtual void emitBasicBlockStartAnnot(const BasicBlock
*BB
,
82 if (BlockFreqs
.empty()) return;
83 if (unsigned Count
= BlockFreqs
[BB
])
84 OS
<< "\t;;; Basic block executed " << Count
<< " times.\n";
86 OS
<< "\t;;; Never executed!\n";
89 virtual void emitBasicBlockEndAnnot(const BasicBlock
*BB
, raw_ostream
&OS
) {
90 if (EdgeFreqs
.empty()) return;
92 // Figure out how many times each successor executed.
93 std::vector
<std::pair
<const BasicBlock
*, unsigned> > SuccCounts
;
94 const TerminatorInst
*TI
= BB
->getTerminator();
96 std::map
<ProfileInfoLoader::Edge
, unsigned>::iterator I
=
97 EdgeFreqs
.lower_bound(std::make_pair(const_cast<BasicBlock
*>(BB
), 0U));
98 for (; I
!= EdgeFreqs
.end() && I
->first
.first
== BB
; ++I
)
100 SuccCounts
.push_back(std::make_pair(TI
->getSuccessor(I
->first
.second
),
102 if (!SuccCounts
.empty()) {
103 OS
<< "\t;;; Out-edge counts:";
104 for (unsigned i
= 0, e
= SuccCounts
.size(); i
!= e
; ++i
)
105 OS
<< " [" << SuccCounts
[i
].second
<< " -> "
106 << SuccCounts
[i
].first
->getName() << "]";
114 int main(int argc
, char **argv
) {
115 // Print a stack trace if we signal out.
116 sys::PrintStackTraceOnErrorSignal();
117 PrettyStackTraceProgram
X(argc
, argv
);
119 llvm_shutdown_obj Y
; // Call llvm_shutdown() on exit.
121 cl::ParseCommandLineOptions(argc
, argv
, "llvm profile dump decoder\n");
123 // Read in the bitcode file...
124 std::string ErrorMessage
;
126 if (MemoryBuffer
*Buffer
= MemoryBuffer::getFileOrSTDIN(BitcodeFile
,
128 M
= ParseBitcodeFile(Buffer
, &ErrorMessage
);
132 std::cerr
<< argv
[0] << ": " << BitcodeFile
<< ": "
133 << ErrorMessage
<< "\n";
137 // Read the profiling information
138 ProfileInfoLoader
PI(argv
[0], ProfileDataFile
, *M
);
140 std::map
<const Function
*, unsigned> FuncFreqs
;
141 std::map
<const BasicBlock
*, unsigned> BlockFreqs
;
142 std::map
<ProfileInfoLoader::Edge
, unsigned> EdgeFreqs
;
144 // Output a report. Eventually, there will be multiple reports selectable on
145 // the command line, for now, just keep things simple.
147 // Emit the most frequent function table...
148 std::vector
<std::pair
<Function
*, unsigned> > FunctionCounts
;
149 PI
.getFunctionCounts(FunctionCounts
);
150 FuncFreqs
.insert(FunctionCounts
.begin(), FunctionCounts
.end());
152 // Sort by the frequency, backwards.
153 sort(FunctionCounts
.begin(), FunctionCounts
.end(),
154 PairSecondSortReverse
<Function
*>());
156 uint64_t TotalExecutions
= 0;
157 for (unsigned i
= 0, e
= FunctionCounts
.size(); i
!= e
; ++i
)
158 TotalExecutions
+= FunctionCounts
[i
].second
;
160 std::cout
<< "===" << std::string(73, '-') << "===\n"
161 << "LLVM profiling output for execution";
162 if (PI
.getNumExecutions() != 1) std::cout
<< "s";
165 for (unsigned i
= 0, e
= PI
.getNumExecutions(); i
!= e
; ++i
) {
167 if (e
!= 1) std::cout
<< i
+1 << ". ";
168 std::cout
<< PI
.getExecution(i
) << "\n";
171 std::cout
<< "\n===" << std::string(73, '-') << "===\n";
172 std::cout
<< "Function execution frequencies:\n\n";
174 // Print out the function frequencies...
175 std::cout
<< " ## Frequency\n";
176 for (unsigned i
= 0, e
= FunctionCounts
.size(); i
!= e
; ++i
) {
177 if (FunctionCounts
[i
].second
== 0) {
178 std::cout
<< "\n NOTE: " << e
-i
<< " function" <<
179 (e
-i
-1 ? "s were" : " was") << " never executed!\n";
183 std::cout
<< std::setw(3) << i
+1 << ". "
184 << std::setw(5) << FunctionCounts
[i
].second
<< "/"
185 << TotalExecutions
<< " "
186 << FunctionCounts
[i
].first
->getName().c_str() << "\n";
189 std::set
<Function
*> FunctionsToPrint
;
191 // If we have block count information, print out the LLVM module with
192 // frequency annotations.
193 if (PI
.hasAccurateBlockCounts()) {
194 std::vector
<std::pair
<BasicBlock
*, unsigned> > Counts
;
195 PI
.getBlockCounts(Counts
);
198 for (unsigned i
= 0, e
= Counts
.size(); i
!= e
; ++i
)
199 TotalExecutions
+= Counts
[i
].second
;
201 // Sort by the frequency, backwards.
202 sort(Counts
.begin(), Counts
.end(),
203 PairSecondSortReverse
<BasicBlock
*>());
205 std::cout
<< "\n===" << std::string(73, '-') << "===\n";
206 std::cout
<< "Top 20 most frequently executed basic blocks:\n\n";
208 // Print out the function frequencies...
209 std::cout
<<" ## %% \tFrequency\n";
210 unsigned BlocksToPrint
= Counts
.size();
211 if (BlocksToPrint
> 20) BlocksToPrint
= 20;
212 for (unsigned i
= 0; i
!= BlocksToPrint
; ++i
) {
213 if (Counts
[i
].second
== 0) break;
214 Function
*F
= Counts
[i
].first
->getParent();
215 std::cout
<< std::setw(3) << i
+1 << ". "
216 << std::setw(5) << std::setprecision(2)
217 << Counts
[i
].second
/(double)TotalExecutions
*100 << "% "
218 << std::setw(5) << Counts
[i
].second
<< "/"
219 << TotalExecutions
<< "\t"
220 << F
->getName().c_str() << "() - "
221 << Counts
[i
].first
->getName().c_str() << "\n";
222 FunctionsToPrint
.insert(F
);
225 BlockFreqs
.insert(Counts
.begin(), Counts
.end());
228 if (PI
.hasAccurateEdgeCounts()) {
229 std::vector
<std::pair
<ProfileInfoLoader::Edge
, unsigned> > Counts
;
230 PI
.getEdgeCounts(Counts
);
231 EdgeFreqs
.insert(Counts
.begin(), Counts
.end());
234 if (PrintAnnotatedLLVM
|| PrintAllCode
) {
235 std::cout
<< "\n===" << std::string(73, '-') << "===\n";
236 std::cout
<< "Annotated LLVM code for the module:\n\n";
238 ProfileAnnotator
PA(FuncFreqs
, BlockFreqs
, EdgeFreqs
);
240 if (FunctionsToPrint
.empty() || PrintAllCode
)
241 M
->print(std::cout
, &PA
);
243 // Print just a subset of the functions.
244 for (std::set
<Function
*>::iterator I
= FunctionsToPrint
.begin(),
245 E
= FunctionsToPrint
.end(); I
!= E
; ++I
)
246 (*I
)->print(std::cout
, &PA
);
250 } catch (const std::string
& msg
) {
251 std::cerr
<< argv
[0] << ": " << msg
<< "\n";
253 std::cerr
<< argv
[0] << ": Unexpected unknown exception occurred.\n";