Add profile writing capabilities for sampling profiles.
[oota-llvm.git] / lib / ProfileData / SampleProfWriter.cpp
1 //===- SampleProfWriter.cpp - Write LLVM sample profile data --------------===//
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 implements the class that writes LLVM sample profiles. It
11 // supports two file formats: text and binary. The textual representation
12 // is useful for debugging and testing purposes. The binary representation
13 // is more compact, resulting in smaller file sizes. However, they can
14 // both be used interchangeably.
15 //
16 // See lib/ProfileData/SampleProfReader.cpp for documentation on each of the
17 // supported formats.
18 //
19 //===----------------------------------------------------------------------===//
20
21 #include "llvm/ProfileData/SampleProfWriter.h"
22 #include "llvm/Support/Debug.h"
23 #include "llvm/Support/ErrorOr.h"
24 #include "llvm/Support/MemoryBuffer.h"
25 #include "llvm/Support/LEB128.h"
26 #include "llvm/Support/LineIterator.h"
27 #include "llvm/Support/Regex.h"
28
29 using namespace llvm::sampleprof;
30 using namespace llvm;
31
32 /// \brief Write samples to a text file.
33 bool SampleProfileWriterText::write(const Function &F,
34                                     const FunctionSamples &S) {
35   if (S.empty())
36     return true;
37
38   OS << F.getName() << ":" << S.getTotalSamples() << ":" << S.getHeadSamples()
39      << "\n";
40
41   for (BodySampleMap::const_iterator I = S.getBodySamples().begin(),
42                                      E = S.getBodySamples().end();
43        I != E; ++I) {
44     LineLocation Loc = I->first;
45     SampleRecord Sample = I->second;
46     if (Loc.Discriminator == 0)
47       OS << Loc.LineOffset << ": ";
48     else
49       OS << Loc.LineOffset << "." << Loc.Discriminator << ": ";
50
51     OS << Sample.getSamples();
52
53     for (SampleRecord::CallTargetList::const_iterator
54              I = Sample.getCallTargets().begin(),
55              E = Sample.getCallTargets().end();
56          I != E; ++I)
57       OS << " " << (*I).first << ":" << (*I).second;
58     OS << "\n";
59   }
60
61   return true;
62 }
63
64 SampleProfileWriterBinary::SampleProfileWriterBinary(StringRef F,
65                                                      std::error_code &EC)
66     : SampleProfileWriter(F, EC, sys::fs::F_None) {
67   if (EC)
68     return;
69
70   // Write the file header.
71   encodeULEB128(SPMagic(), OS);
72   encodeULEB128(SPVersion(), OS);
73 }
74
75 /// \brief Write samples to a binary file.
76 ///
77 /// \returns true if the samples were written successfully, false otherwise.
78 bool SampleProfileWriterBinary::write(const Function &F,
79                                       const FunctionSamples &S) {
80   if (S.empty())
81     return true;
82
83   OS << F.getName();
84   encodeULEB128(0, OS);
85   encodeULEB128(S.getTotalSamples(), OS);
86   encodeULEB128(S.getHeadSamples(), OS);
87   encodeULEB128(S.getBodySamples().size(), OS);
88   for (BodySampleMap::const_iterator I = S.getBodySamples().begin(),
89                                      E = S.getBodySamples().end();
90        I != E; ++I) {
91     LineLocation Loc = I->first;
92     SampleRecord Sample = I->second;
93     encodeULEB128(Loc.LineOffset, OS);
94     encodeULEB128(Loc.Discriminator, OS);
95     encodeULEB128(Sample.getSamples(), OS);
96     encodeULEB128(Sample.getCallTargets().size(), OS);
97     for (SampleRecord::CallTargetList::const_iterator
98              I = Sample.getCallTargets().begin(),
99              E = Sample.getCallTargets().end();
100          I != E; ++I) {
101       std::string Callee = (*I).first;
102       unsigned CalleeSamples = (*I).second;
103       OS << Callee;
104       encodeULEB128(0, OS);
105       encodeULEB128(CalleeSamples, OS);
106     }
107   }
108
109   return true;
110 }