aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ProfileData/SampleProfWriter.cpp
blob: ab2e76177620b9f431358dc042d102050b18066f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//===- SampleProfWriter.cpp - Write LLVM sample profile data --------------===//
//
//                      The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the class that writes LLVM sample profiles. It
// supports two file formats: text and binary. The textual representation
// is useful for debugging and testing purposes. The binary representation
// is more compact, resulting in smaller file sizes. However, they can
// both be used interchangeably.
//
// See lib/ProfileData/SampleProfReader.cpp for documentation on each of the
// supported formats.
//
//===----------------------------------------------------------------------===//

#include "llvm/ProfileData/SampleProfWriter.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/Regex.h"

using namespace llvm::sampleprof;
using namespace llvm;

/// \brief Write samples to a text file.
bool SampleProfileWriterText::write(const Function &F,
                                    const FunctionSamples &S) {
  if (S.empty())
    return true;

  OS << F.getName() << ":" << S.getTotalSamples() << ":" << S.getHeadSamples()
     << "\n";

  for (BodySampleMap::const_iterator I = S.getBodySamples().begin(),
                                     E = S.getBodySamples().end();
       I != E; ++I) {
    LineLocation Loc = I->first;
    SampleRecord Sample = I->second;
    if (Loc.Discriminator == 0)
      OS << Loc.LineOffset << ": ";
    else
      OS << Loc.LineOffset << "." << Loc.Discriminator << ": ";

    OS << Sample.getSamples();

    for (SampleRecord::CallTargetList::const_iterator
             I = Sample.getCallTargets().begin(),
             E = Sample.getCallTargets().end();
         I != E; ++I)
      OS << " " << (*I).first << ":" << (*I).second;
    OS << "\n";
  }

  return true;
}

SampleProfileWriterBinary::SampleProfileWriterBinary(StringRef F,
                                                     std::error_code &EC)
    : SampleProfileWriter(F, EC, sys::fs::F_None) {
  if (EC)
    return;

  // Write the file header.
  encodeULEB128(SPMagic(), OS);
  encodeULEB128(SPVersion(), OS);
}

/// \brief Write samples to a binary file.
///
/// \returns true if the samples were written successfully, false otherwise.
bool SampleProfileWriterBinary::write(const Function &F,
                                      const FunctionSamples &S) {
  if (S.empty())
    return true;

  OS << F.getName();
  encodeULEB128(0, OS);
  encodeULEB128(S.getTotalSamples(), OS);
  encodeULEB128(S.getHeadSamples(), OS);
  encodeULEB128(S.getBodySamples().size(), OS);
  for (BodySampleMap::const_iterator I = S.getBodySamples().begin(),
                                     E = S.getBodySamples().end();
       I != E; ++I) {
    LineLocation Loc = I->first;
    SampleRecord Sample = I->second;
    encodeULEB128(Loc.LineOffset, OS);
    encodeULEB128(Loc.Discriminator, OS);
    encodeULEB128(Sample.getSamples(), OS);
    encodeULEB128(Sample.getCallTargets().size(), OS);
    for (SampleRecord::CallTargetList::const_iterator
             I = Sample.getCallTargets().begin(),
             E = Sample.getCallTargets().end();
         I != E; ++I) {
      std::string Callee = (*I).first;
      unsigned CalleeSamples = (*I).second;
      OS << Callee;
      encodeULEB128(0, OS);
      encodeULEB128(CalleeSamples, OS);
    }
  }

  return true;
}