blob: d5ac6e53e4f723c40b45429c9d67049df813f64c [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- 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>
Andrew Scullcdfcccc2018-10-05 20:58:37 +010026#include <set>
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010027#include <system_error>
28
29namespace llvm {
30namespace sampleprof {
31
Andrew Scullcdfcccc2018-10-05 20:58:37 +010032/// Sample-based profile writer. Base class.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010033class SampleProfileWriter {
34public:
35 virtual ~SampleProfileWriter() = default;
36
37 /// Write sample profiles in \p S.
38 ///
39 /// \returns status code of the file update operation.
40 virtual std::error_code write(const FunctionSamples &S) = 0;
41
42 /// Write all the sample profiles in the given map of samples.
43 ///
44 /// \returns status code of the file update operation.
Andrew Scull0372a572018-11-16 15:47:06 +000045 virtual std::error_code write(const StringMap<FunctionSamples> &ProfileMap);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010046
47 raw_ostream &getOutputStream() { return *OutputStream; }
48
49 /// Profile writer factory.
50 ///
51 /// Create a new file writer based on the value of \p Format.
52 static ErrorOr<std::unique_ptr<SampleProfileWriter>>
53 create(StringRef Filename, SampleProfileFormat Format);
54
55 /// Create a new stream writer based on the value of \p Format.
56 /// For testing.
57 static ErrorOr<std::unique_ptr<SampleProfileWriter>>
58 create(std::unique_ptr<raw_ostream> &OS, SampleProfileFormat Format);
59
60protected:
61 SampleProfileWriter(std::unique_ptr<raw_ostream> &OS)
62 : OutputStream(std::move(OS)) {}
63
Andrew Scullcdfcccc2018-10-05 20:58:37 +010064 /// Write a file header for the profile file.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010065 virtual std::error_code
66 writeHeader(const StringMap<FunctionSamples> &ProfileMap) = 0;
67
Andrew Scullcdfcccc2018-10-05 20:58:37 +010068 /// Output stream where to emit the profile to.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010069 std::unique_ptr<raw_ostream> OutputStream;
70
Andrew Scullcdfcccc2018-10-05 20:58:37 +010071 /// Profile summary.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010072 std::unique_ptr<ProfileSummary> Summary;
73
Andrew Scullcdfcccc2018-10-05 20:58:37 +010074 /// Compute summary for this profile.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010075 void computeSummary(const StringMap<FunctionSamples> &ProfileMap);
76};
77
Andrew Scullcdfcccc2018-10-05 20:58:37 +010078/// Sample-based profile writer (text format).
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010079class SampleProfileWriterText : public SampleProfileWriter {
80public:
81 std::error_code write(const FunctionSamples &S) override;
82
83protected:
84 SampleProfileWriterText(std::unique_ptr<raw_ostream> &OS)
85 : SampleProfileWriter(OS), Indent(0) {}
86
87 std::error_code
88 writeHeader(const StringMap<FunctionSamples> &ProfileMap) override {
89 return sampleprof_error::success;
90 }
91
92private:
93 /// Indent level to use when writing.
94 ///
95 /// This is used when printing inlined callees.
96 unsigned Indent;
97
98 friend ErrorOr<std::unique_ptr<SampleProfileWriter>>
99 SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
100 SampleProfileFormat Format);
101};
102
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100103/// Sample-based profile writer (binary format).
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100104class SampleProfileWriterBinary : public SampleProfileWriter {
105public:
Andrew Scull0372a572018-11-16 15:47:06 +0000106 virtual std::error_code write(const FunctionSamples &S) override;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100107 SampleProfileWriterBinary(std::unique_ptr<raw_ostream> &OS)
108 : SampleProfileWriter(OS) {}
109
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100110protected:
111 virtual std::error_code writeNameTable() = 0;
112 virtual std::error_code writeMagicIdent() = 0;
Andrew Scull0372a572018-11-16 15:47:06 +0000113 virtual std::error_code
114 writeHeader(const StringMap<FunctionSamples> &ProfileMap) override;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100115 std::error_code writeSummary();
116 std::error_code writeNameIdx(StringRef FName);
117 std::error_code writeBody(const FunctionSamples &S);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100118 inline void stablizeNameTable(std::set<StringRef> &V);
119
120 MapVector<StringRef, uint32_t> NameTable;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100121
122private:
123 void addName(StringRef FName);
124 void addNames(const FunctionSamples &S);
125
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100126 friend ErrorOr<std::unique_ptr<SampleProfileWriter>>
127 SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
128 SampleProfileFormat Format);
129};
130
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100131class SampleProfileWriterRawBinary : public SampleProfileWriterBinary {
132 using SampleProfileWriterBinary::SampleProfileWriterBinary;
133
134protected:
135 virtual std::error_code writeNameTable() override;
136 virtual std::error_code writeMagicIdent() override;
137};
138
Andrew Scull0372a572018-11-16 15:47:06 +0000139// CompactBinary is a compact format of binary profile which both reduces
140// the profile size and the load time needed when compiling. It has two
141// major difference with Binary format.
142// 1. It represents all the strings in name table using md5 hash.
143// 2. It saves a function offset table which maps function name index to
144// the offset of its function profile to the start of the binary profile,
145// so by using the function offset table, for those function profiles which
146// will not be needed when compiling a module, the profile reader does't
147// have to read them and it saves compile time if the profile size is huge.
148// The layout of the compact format is shown as follows:
149//
150// Part1: Profile header, the same as binary format, containing magic
151// number, version, summary, name table...
152// Part2: Function Offset Table Offset, which saves the position of
153// Part4.
154// Part3: Function profile collection
155// function1 profile start
156// ....
157// function2 profile start
158// ....
159// function3 profile start
160// ....
161// ......
162// Part4: Function Offset Table
163// function1 name index --> function1 profile start
164// function2 name index --> function2 profile start
165// function3 name index --> function3 profile start
166//
167// We need Part2 because profile reader can use it to find out and read
168// function offset table without reading Part3 first.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100169class SampleProfileWriterCompactBinary : public SampleProfileWriterBinary {
170 using SampleProfileWriterBinary::SampleProfileWriterBinary;
171
Andrew Scull0372a572018-11-16 15:47:06 +0000172public:
173 virtual std::error_code write(const FunctionSamples &S) override;
174 virtual std::error_code
175 write(const StringMap<FunctionSamples> &ProfileMap) override;
176
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100177protected:
Andrew Scull0372a572018-11-16 15:47:06 +0000178 /// The table mapping from function name to the offset of its FunctionSample
179 /// towards profile start.
180 MapVector<StringRef, uint64_t> FuncOffsetTable;
181 /// The offset of the slot to be filled with the offset of FuncOffsetTable
182 /// towards profile start.
183 uint64_t TableOffset;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100184 virtual std::error_code writeNameTable() override;
185 virtual std::error_code writeMagicIdent() override;
Andrew Scull0372a572018-11-16 15:47:06 +0000186 virtual std::error_code
187 writeHeader(const StringMap<FunctionSamples> &ProfileMap) override;
188 std::error_code writeFuncOffsetTable();
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100189};
190
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100191} // end namespace sampleprof
192} // end namespace llvm
193
194#endif // LLVM_PROFILEDATA_SAMPLEPROFWRITER_H