1//===- SampleProfWriter.h - Write LLVM sample profile data ------*- C++ -*-===//
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 contains definitions needed for writing sample profiles.
11//
12//===----------------------------------------------------------------------===//
13#ifndef LLVM_PROFILEDATA_SAMPLEPROFWRITER_H
14#define LLVM_PROFILEDATA_SAMPLEPROFWRITER_H
15
16#include "llvm/ADT/MapVector.h"
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/IR/ProfileSummary.h"
20#include "llvm/ProfileData/SampleProf.h"
21#include "llvm/Support/ErrorOr.h"
22#include "llvm/Support/raw_ostream.h"
23#include <algorithm>
24#include <cstdint>
25#include <memory>
26#include <system_error>
27
28namespace llvm {
29namespace sampleprof {
30
31enum SampleProfileFormat { SPF_None = 0, SPF_Text, SPF_Binary, SPF_GCC };
32
33/// \brief Sample-based profile writer. Base class.
34class SampleProfileWriter {
35public:
36  virtual ~SampleProfileWriter() = default;
37
38  /// Write sample profiles in \p S.
39  ///
40  /// \returns status code of the file update operation.
41  virtual std::error_code write(const FunctionSamples &S) = 0;
42
43  /// Write all the sample profiles in the given map of samples.
44  ///
45  /// \returns status code of the file update operation.
46  std::error_code write(const StringMap<FunctionSamples> &ProfileMap);
47
48  raw_ostream &getOutputStream() { return *OutputStream; }
49
50  /// Profile writer factory.
51  ///
52  /// Create a new file writer based on the value of \p Format.
53  static ErrorOr<std::unique_ptr<SampleProfileWriter>>
54  create(StringRef Filename, SampleProfileFormat Format);
55
56  /// Create a new stream writer based on the value of \p Format.
57  /// For testing.
58  static ErrorOr<std::unique_ptr<SampleProfileWriter>>
59  create(std::unique_ptr<raw_ostream> &OS, SampleProfileFormat Format);
60
61protected:
62  SampleProfileWriter(std::unique_ptr<raw_ostream> &OS)
63      : OutputStream(std::move(OS)) {}
64
65  /// \brief Write a file header for the profile file.
66  virtual std::error_code
67  writeHeader(const StringMap<FunctionSamples> &ProfileMap) = 0;
68
69  /// \brief Output stream where to emit the profile to.
70  std::unique_ptr<raw_ostream> OutputStream;
71
72  /// \brief Profile summary.
73  std::unique_ptr<ProfileSummary> Summary;
74
75  /// \brief Compute summary for this profile.
76  void computeSummary(const StringMap<FunctionSamples> &ProfileMap);
77};
78
79/// \brief Sample-based profile writer (text format).
80class SampleProfileWriterText : public SampleProfileWriter {
81public:
82  std::error_code write(const FunctionSamples &S) override;
83
84protected:
85  SampleProfileWriterText(std::unique_ptr<raw_ostream> &OS)
86      : SampleProfileWriter(OS), Indent(0) {}
87
88  std::error_code
89  writeHeader(const StringMap<FunctionSamples> &ProfileMap) override {
90    return sampleprof_error::success;
91  }
92
93private:
94  /// Indent level to use when writing.
95  ///
96  /// This is used when printing inlined callees.
97  unsigned Indent;
98
99  friend ErrorOr<std::unique_ptr<SampleProfileWriter>>
100  SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
101                              SampleProfileFormat Format);
102};
103
104/// \brief Sample-based profile writer (binary format).
105class SampleProfileWriterBinary : public SampleProfileWriter {
106public:
107  std::error_code write(const FunctionSamples &S) override;
108
109protected:
110  SampleProfileWriterBinary(std::unique_ptr<raw_ostream> &OS)
111      : SampleProfileWriter(OS) {}
112
113  std::error_code
114  writeHeader(const StringMap<FunctionSamples> &ProfileMap) override;
115  std::error_code writeSummary();
116  std::error_code writeNameIdx(StringRef FName);
117  std::error_code writeBody(const FunctionSamples &S);
118
119private:
120  void addName(StringRef FName);
121  void addNames(const FunctionSamples &S);
122
123  MapVector<StringRef, uint32_t> NameTable;
124
125  friend ErrorOr<std::unique_ptr<SampleProfileWriter>>
126  SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
127                              SampleProfileFormat Format);
128};
129
130} // end namespace sampleprof
131} // end namespace llvm
132
133#endif // LLVM_PROFILEDATA_SAMPLEPROFWRITER_H
134