1 //===- SampleProfile.cpp - Incorporate sample profiles into the IR --------===//
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 file implements the SampleProfileLoader transformation. This pass
11 // reads a profile file generated by a sampling profiler (e.g. Linux Perf -
12 // http://perf.wiki.kernel.org/) and generates IR metadata to reflect the
13 // profile information in the given profile.
15 // This pass generates branch weight annotations on the IR:
17 // - prof: Represents branch weights. This annotation is added to branches
18 // to indicate the weights of each edge coming out of the branch.
19 // The weight of each edge is the weight of the target block for
20 // that edge. The weight of a block B is computed as the maximum
21 // number of samples found in B.
23 //===----------------------------------------------------------------------===//
25 #define DEBUG_TYPE "sample-profile"
27 #include "llvm/ADT/DenseMap.h"
28 #include "llvm/ADT/OwningPtr.h"
29 #include "llvm/ADT/StringMap.h"
30 #include "llvm/ADT/StringRef.h"
31 #include "llvm/DebugInfo/DIContext.h"
32 #include "llvm/IR/Constants.h"
33 #include "llvm/IR/Function.h"
34 #include "llvm/IR/Instructions.h"
35 #include "llvm/IR/LLVMContext.h"
36 #include "llvm/IR/Metadata.h"
37 #include "llvm/IR/MDBuilder.h"
38 #include "llvm/IR/Module.h"
39 #include "llvm/Pass.h"
40 #include "llvm/Support/CommandLine.h"
41 #include "llvm/Support/Debug.h"
42 #include "llvm/Support/InstIterator.h"
43 #include "llvm/Support/MemoryBuffer.h"
44 #include "llvm/Support/Regex.h"
45 #include "llvm/Support/raw_ostream.h"
46 #include "llvm/Transforms/Scalar.h"
50 // Command line option to specify the file to read samples from. This is
51 // mainly used for debugging.
52 static cl::opt<std::string> SampleProfileFile(
53 "sample-profile-file", cl::init(""), cl::value_desc("filename"),
54 cl::desc("Profile file loaded by -sample-profile"), cl::Hidden);
57 /// \brief Sample-based profile reader.
59 /// Each profile contains sample counts for all the functions
60 /// executed. Inside each function, statements are annotated with the
61 /// collected samples on all the instructions associated with that
64 /// For this to produce meaningful data, the program needs to be
65 /// compiled with some debug information (at minimum, line numbers:
66 /// -gline-tables-only). Otherwise, it will be impossible to match IR
67 /// instructions to the line numbers collected by the profiler.
69 /// From the profile file, we are interested in collecting the
70 /// following information:
72 /// * A list of functions included in the profile (mangled names).
74 /// * For each function F:
75 /// 1. The total number of samples collected in F.
77 /// 2. The samples collected at each line in F. To provide some
78 /// protection against source code shuffling, line numbers should
79 /// be relative to the start of the function.
82 SampleProfile(StringRef F) : Profiles(0), Filename(F) {}
85 virtual void loadText();
86 virtual void loadNative() { llvm_unreachable("not implemented"); }
87 virtual bool emitAnnotations(Function &F);
88 void printFunctionProfile(raw_ostream &OS, StringRef FName);
89 void dumpFunctionProfile(StringRef FName);
92 typedef DenseMap<uint32_t, uint32_t> BodySampleMap;
93 typedef DenseMap<BasicBlock *, uint32_t> BlockWeightMap;
95 /// \brief Representation of the runtime profile for a function.
97 /// This data structure contains the runtime profile for a given
98 /// function. It contains the total number of samples collected
99 /// in the function and a map of samples collected in every statement.
100 struct FunctionProfile {
101 /// \brief Total number of samples collected inside this function.
103 /// Samples are cumulative, they include all the samples collected
104 /// inside this function and all its inlined callees.
105 unsigned TotalSamples;
107 // \brief Total number of samples collected at the head of the function.
108 unsigned TotalHeadSamples;
110 /// \brief Map line offsets to collected samples.
112 /// Each entry in this map contains the number of samples
113 /// collected at the corresponding line offset. All line locations
114 /// are an offset from the start of the function.
115 BodySampleMap BodySamples;
117 /// \brief Map basic blocks to their computed weights.
119 /// The weight of a basic block is defined to be the maximum
120 /// of all the instruction weights in that block.
121 BlockWeightMap BlockWeights;
124 uint32_t getInstWeight(Instruction &I, unsigned FirstLineno,
125 BodySampleMap &BodySamples);
126 uint32_t computeBlockWeight(BasicBlock *B, unsigned FirstLineno,
127 BodySampleMap &BodySamples);
129 /// \brief Map every function to its associated profile.
131 /// The profile of every function executed at runtime is collected
132 /// in the structure FunctionProfile. This maps function objects
133 /// to their corresponding profiles.
134 StringMap<FunctionProfile> Profiles;
136 /// \brief Path name to the file holding the profile data.
138 /// The format of this file is defined by each profiler
139 /// independently. If possible, the profiler should have a text
140 /// version of the profile format to be used in constructing test
141 /// cases and debugging.
145 /// \brief Loader class for text-based profiles.
147 /// This class defines a simple interface to read text files containing
148 /// profiles. It keeps track of line number information and location of
149 /// the file pointer. Users of this class are responsible for actually
150 /// parsing the lines returned by the readLine function.
152 /// TODO - This does not really belong here. It is a generic text file
153 /// reader. It should be moved to the Support library and made more general.
154 class ExternalProfileTextLoader {
156 ExternalProfileTextLoader(StringRef F) : Filename(F) {
158 EC = MemoryBuffer::getFile(Filename, Buffer);
160 report_fatal_error("Could not open profile file " + Filename + ": " +
162 FP = Buffer->getBufferStart();
166 /// \brief Read a line from the mapped file.
167 StringRef readLine() {
169 const char *start = FP;
170 while (FP != Buffer->getBufferEnd() && *FP != '\n') {
174 if (FP != Buffer->getBufferEnd())
177 return StringRef(start, Length);
180 /// \brief Return true, if we've reached EOF.
181 bool atEOF() const { return FP == Buffer->getBufferEnd(); }
183 /// \brief Report a parse error message and stop compilation.
184 void reportParseError(Twine Msg) const {
185 report_fatal_error(Filename + ":" + Twine(Lineno) + ": " + Msg + "\n");
189 /// \brief Memory buffer holding the text file.
190 OwningPtr<MemoryBuffer> Buffer;
192 /// \brief Current position into the memory buffer.
195 /// \brief Current line number.
198 /// \brief Path name where to the profile file.
202 /// \brief Sample profile pass.
204 /// This pass reads profile data from the file specified by
205 /// -sample-profile-file and annotates every affected function with the
206 /// profile information found in that file.
207 class SampleProfileLoader : public FunctionPass {
209 // Class identification, replacement for typeinfo
212 SampleProfileLoader(StringRef Name = SampleProfileFile)
213 : FunctionPass(ID), Profiler(0), Filename(Name) {
214 initializeSampleProfileLoaderPass(*PassRegistry::getPassRegistry());
217 virtual bool doInitialization(Module &M);
219 void dump() { Profiler->dump(); }
221 virtual const char *getPassName() const { return "Sample profile pass"; }
223 virtual bool runOnFunction(Function &F);
225 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
226 AU.setPreservesCFG();
230 /// \brief Profile reader object.
231 OwningPtr<SampleProfile> Profiler;
233 /// \brief Name of the profile file to load.
238 /// \brief Print the function profile for \p FName on stream \p OS.
240 /// \param OS Stream to emit the output to.
241 /// \param FName Name of the function to print.
242 void SampleProfile::printFunctionProfile(raw_ostream &OS, StringRef FName) {
243 FunctionProfile FProfile = Profiles[FName];
244 OS << "Function: " << FName << ", " << FProfile.TotalSamples << ", "
245 << FProfile.TotalHeadSamples << ", " << FProfile.BodySamples.size()
246 << " sampled lines\n";
247 for (BodySampleMap::const_iterator SI = FProfile.BodySamples.begin(),
248 SE = FProfile.BodySamples.end();
250 OS << "\tline offset: " << SI->first
251 << ", number of samples: " << SI->second << "\n";
255 /// \brief Dump the function profile for \p FName.
257 /// \param FName Name of the function to print.
258 void SampleProfile::dumpFunctionProfile(StringRef FName) {
259 printFunctionProfile(dbgs(), FName);
262 /// \brief Dump all the function profiles found.
263 void SampleProfile::dump() {
264 for (StringMap<FunctionProfile>::const_iterator I = Profiles.begin(),
267 dumpFunctionProfile(I->getKey());
270 /// \brief Load samples from a text file.
272 /// The file is divided in two segments:
274 /// Symbol table (represented with the string "symbol table")
275 /// Number of symbols in the table
281 /// Function body profiles
282 /// function1:total_samples:total_head_samples:number_of_locations
283 /// location_offset_1: number_of_samples
284 /// location_offset_2: number_of_samples
286 /// location_offset_N: number_of_samples
288 /// Function names must be mangled in order for the profile loader to
289 /// match them in the current translation unit.
291 /// Since this is a flat profile, a function that shows up more than
292 /// once gets all its samples aggregated across all its instances.
293 /// TODO - flat profiles are too imprecise to provide good optimization
294 /// opportunities. Convert them to context-sensitive profile.
296 /// This textual representation is useful to generate unit tests and
297 /// for debugging purposes, but it should not be used to generate
298 /// profiles for large programs, as the representation is extremely
300 void SampleProfile::loadText() {
301 ExternalProfileTextLoader Loader(Filename);
303 // Read the symbol table.
304 StringRef Line = Loader.readLine();
305 if (Line != "symbol table")
306 Loader.reportParseError("Expected 'symbol table', found " + Line);
308 Line = Loader.readLine();
309 if (Line.getAsInteger(10, NumSymbols))
310 Loader.reportParseError("Expected a number, found " + Line);
311 for (int I = 0; I < NumSymbols; I++) {
312 StringRef FName = Loader.readLine();
313 FunctionProfile &FProfile = Profiles[FName];
314 FProfile.BodySamples.clear();
315 FProfile.TotalSamples = 0;
316 FProfile.TotalHeadSamples = 0;
319 // Read the profile of each function. Since each function may be
320 // mentioned more than once, and we are collecting flat profiles,
321 // accumulate samples as we parse them.
322 Regex HeadRE("^([^:]+):([0-9]+):([0-9]+):([0-9]+)$");
323 Regex LineSample("^([0-9]+): ([0-9]+)$");
324 while (!Loader.atEOF()) {
325 SmallVector<StringRef, 4> Matches;
326 Line = Loader.readLine();
327 if (!HeadRE.match(Line, &Matches))
328 Loader.reportParseError("Expected 'mangled_name:NUM:NUM:NUM', found " +
330 assert(Matches.size() == 5);
331 StringRef FName = Matches[1];
332 unsigned NumSamples, NumHeadSamples, NumSampledLines;
333 Matches[2].getAsInteger(10, NumSamples);
334 Matches[3].getAsInteger(10, NumHeadSamples);
335 Matches[4].getAsInteger(10, NumSampledLines);
336 FunctionProfile &FProfile = Profiles[FName];
337 FProfile.TotalSamples += NumSamples;
338 FProfile.TotalHeadSamples += NumHeadSamples;
339 BodySampleMap &SampleMap = FProfile.BodySamples;
341 for (I = 0; I < NumSampledLines && !Loader.atEOF(); I++) {
342 Line = Loader.readLine();
343 if (!LineSample.match(Line, &Matches))
344 Loader.reportParseError("Expected 'NUM: NUM', found " + Line);
345 assert(Matches.size() == 3);
346 unsigned LineOffset, NumSamples;
347 Matches[1].getAsInteger(10, LineOffset);
348 Matches[2].getAsInteger(10, NumSamples);
349 SampleMap[LineOffset] += NumSamples;
352 if (I < NumSampledLines)
353 Loader.reportParseError("Unexpected end of file");
357 /// \brief Get the weight for an instruction.
359 /// The "weight" of an instruction \p Inst is the number of samples
360 /// collected on that instruction at runtime. To retrieve it, we
361 /// need to compute the line number of \p Inst relative to the start of its
362 /// function. We use \p FirstLineno to compute the offset. We then
363 /// look up the samples collected for \p Inst using \p BodySamples.
365 /// \param Inst Instruction to query.
366 /// \param FirstLineno Line number of the first instruction in the function.
367 /// \param BodySamples Map of relative source line locations to samples.
369 /// \returns The profiled weight of I.
370 uint32_t SampleProfile::getInstWeight(Instruction &Inst, unsigned FirstLineno,
371 BodySampleMap &BodySamples) {
372 unsigned LOffset = Inst.getDebugLoc().getLine() - FirstLineno + 1;
373 return BodySamples.lookup(LOffset);
376 /// \brief Compute the weight of a basic block.
378 /// The weight of basic block \p B is the maximum weight of all the
379 /// instructions in B.
381 /// \param B The basic block to query.
382 /// \param FirstLineno The line number for the first line in the
383 /// function holding B.
384 /// \param BodySamples The map containing all the samples collected in that
387 /// \returns The computed weight of B.
388 uint32_t SampleProfile::computeBlockWeight(BasicBlock *B, unsigned FirstLineno,
389 BodySampleMap &BodySamples) {
390 // If we've computed B's weight before, return it.
391 Function *F = B->getParent();
392 FunctionProfile &FProfile = Profiles[F->getName()];
393 std::pair<BlockWeightMap::iterator, bool> Entry =
394 FProfile.BlockWeights.insert(std::make_pair(B, 0));
396 return Entry.first->second;
398 // Otherwise, compute and cache B's weight.
400 for (BasicBlock::iterator I = B->begin(), E = B->end(); I != E; ++I) {
401 uint32_t InstWeight = getInstWeight(*I, FirstLineno, BodySamples);
402 if (InstWeight > Weight)
405 Entry.first->second = Weight;
409 /// \brief Generate branch weight metadata for all branches in \p F.
411 /// For every branch instruction B in \p F, we compute the weight of the
412 /// target block for each of the edges out of B. This is the weight
413 /// that we associate with that branch.
415 /// TODO - This weight assignment will most likely be wrong if the
416 /// target branch has more than two predecessors. This needs to be done
417 /// using some form of flow propagation.
419 /// Once all the branch weights are computed, we emit the MD_prof
420 /// metadata on B using the computed values.
422 /// \param F The function to query.
423 bool SampleProfile::emitAnnotations(Function &F) {
424 bool Changed = false;
425 FunctionProfile &FProfile = Profiles[F.getName()];
426 unsigned FirstLineno = inst_begin(F)->getDebugLoc().getLine();
427 MDBuilder MDB(F.getContext());
429 // Clear the block weights cache.
430 FProfile.BlockWeights.clear();
432 // When we find a branch instruction: For each edge E out of the branch,
433 // the weight of E is the weight of the target block.
434 for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
436 TerminatorInst *TI = B->getTerminator();
437 if (TI->getNumSuccessors() == 1)
439 if (!isa<BranchInst>(TI) && !isa<SwitchInst>(TI))
442 SmallVector<uint32_t, 4> Weights;
443 unsigned NSuccs = TI->getNumSuccessors();
444 for (unsigned I = 0; I < NSuccs; ++I) {
445 BasicBlock *Succ = TI->getSuccessor(I);
447 computeBlockWeight(Succ, FirstLineno, FProfile.BodySamples);
448 Weights.push_back(Weight);
451 TI->setMetadata(llvm::LLVMContext::MD_prof,
452 MDB.createBranchWeights(Weights));
459 char SampleProfileLoader::ID = 0;
460 INITIALIZE_PASS(SampleProfileLoader, "sample-profile", "Sample Profile loader",
463 bool SampleProfileLoader::runOnFunction(Function &F) {
464 return Profiler->emitAnnotations(F);
467 bool SampleProfileLoader::doInitialization(Module &M) {
468 Profiler.reset(new SampleProfile(Filename));
469 Profiler->loadText();
473 FunctionPass *llvm::createSampleProfileLoaderPass() {
474 return new SampleProfileLoader(SampleProfileFile);
477 FunctionPass *llvm::createSampleProfileLoaderPass(StringRef Name) {
478 return new SampleProfileLoader(Name);