]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/ProfileData/SampleProfWriter.h
Fix a memory leak in if_delgroups() introduced in r334118.
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / ProfileData / SampleProfWriter.h
1 //===- SampleProfWriter.h - Write LLVM sample profile data ------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains definitions needed for writing sample profiles.
10 //
11 //===----------------------------------------------------------------------===//
12 #ifndef LLVM_PROFILEDATA_SAMPLEPROFWRITER_H
13 #define LLVM_PROFILEDATA_SAMPLEPROFWRITER_H
14
15 #include "llvm/ADT/MapVector.h"
16 #include "llvm/ADT/StringMap.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/IR/ProfileSummary.h"
19 #include "llvm/ProfileData/SampleProf.h"
20 #include "llvm/Support/ErrorOr.h"
21 #include "llvm/Support/raw_ostream.h"
22 #include <algorithm>
23 #include <cstdint>
24 #include <memory>
25 #include <set>
26 #include <system_error>
27
28 namespace llvm {
29 namespace sampleprof {
30
31 /// Sample-based profile writer. Base class.
32 class SampleProfileWriter {
33 public:
34   virtual ~SampleProfileWriter() = default;
35
36   /// Write sample profiles in \p S.
37   ///
38   /// \returns status code of the file update operation.
39   virtual std::error_code write(const FunctionSamples &S) = 0;
40
41   /// Write all the sample profiles in the given map of samples.
42   ///
43   /// \returns status code of the file update operation.
44   virtual std::error_code write(const StringMap<FunctionSamples> &ProfileMap);
45
46   raw_ostream &getOutputStream() { return *OutputStream; }
47
48   /// Profile writer factory.
49   ///
50   /// Create a new file writer based on the value of \p Format.
51   static ErrorOr<std::unique_ptr<SampleProfileWriter>>
52   create(StringRef Filename, SampleProfileFormat Format);
53
54   /// Create a new stream writer based on the value of \p Format.
55   /// For testing.
56   static ErrorOr<std::unique_ptr<SampleProfileWriter>>
57   create(std::unique_ptr<raw_ostream> &OS, SampleProfileFormat Format);
58
59 protected:
60   SampleProfileWriter(std::unique_ptr<raw_ostream> &OS)
61       : OutputStream(std::move(OS)) {}
62
63   /// Write a file header for the profile file.
64   virtual std::error_code
65   writeHeader(const StringMap<FunctionSamples> &ProfileMap) = 0;
66
67   /// Output stream where to emit the profile to.
68   std::unique_ptr<raw_ostream> OutputStream;
69
70   /// Profile summary.
71   std::unique_ptr<ProfileSummary> Summary;
72
73   /// Compute summary for this profile.
74   void computeSummary(const StringMap<FunctionSamples> &ProfileMap);
75 };
76
77 /// Sample-based profile writer (text format).
78 class SampleProfileWriterText : public SampleProfileWriter {
79 public:
80   std::error_code write(const FunctionSamples &S) override;
81
82 protected:
83   SampleProfileWriterText(std::unique_ptr<raw_ostream> &OS)
84       : SampleProfileWriter(OS), Indent(0) {}
85
86   std::error_code
87   writeHeader(const StringMap<FunctionSamples> &ProfileMap) override {
88     return sampleprof_error::success;
89   }
90
91 private:
92   /// Indent level to use when writing.
93   ///
94   /// This is used when printing inlined callees.
95   unsigned Indent;
96
97   friend ErrorOr<std::unique_ptr<SampleProfileWriter>>
98   SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
99                               SampleProfileFormat Format);
100 };
101
102 /// Sample-based profile writer (binary format).
103 class SampleProfileWriterBinary : public SampleProfileWriter {
104 public:
105   virtual std::error_code write(const FunctionSamples &S) override;
106   SampleProfileWriterBinary(std::unique_ptr<raw_ostream> &OS)
107       : SampleProfileWriter(OS) {}
108
109 protected:
110   virtual std::error_code writeNameTable() = 0;
111   virtual std::error_code writeMagicIdent() = 0;
112   virtual std::error_code
113   writeHeader(const StringMap<FunctionSamples> &ProfileMap) override;
114   std::error_code writeSummary();
115   std::error_code writeNameIdx(StringRef FName);
116   std::error_code writeBody(const FunctionSamples &S);
117   inline void stablizeNameTable(std::set<StringRef> &V);
118
119   MapVector<StringRef, uint32_t> NameTable;
120
121 private:
122   void addName(StringRef FName);
123   void addNames(const FunctionSamples &S);
124
125   friend ErrorOr<std::unique_ptr<SampleProfileWriter>>
126   SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
127                               SampleProfileFormat Format);
128 };
129
130 class SampleProfileWriterRawBinary : public SampleProfileWriterBinary {
131   using SampleProfileWriterBinary::SampleProfileWriterBinary;
132
133 protected:
134   virtual std::error_code writeNameTable() override;
135   virtual std::error_code writeMagicIdent() override;
136 };
137
138 // CompactBinary is a compact format of binary profile which both reduces
139 // the profile size and the load time needed when compiling. It has two
140 // major difference with Binary format.
141 // 1. It represents all the strings in name table using md5 hash.
142 // 2. It saves a function offset table which maps function name index to
143 // the offset of its function profile to the start of the binary profile,
144 // so by using the function offset table, for those function profiles which
145 // will not be needed when compiling a module, the profile reader does't
146 // have to read them and it saves compile time if the profile size is huge.
147 // The layout of the compact format is shown as follows:
148 //
149 //    Part1: Profile header, the same as binary format, containing magic
150 //           number, version, summary, name table...
151 //    Part2: Function Offset Table Offset, which saves the position of
152 //           Part4.
153 //    Part3: Function profile collection
154 //             function1 profile start
155 //                 ....
156 //             function2 profile start
157 //                 ....
158 //             function3 profile start
159 //                 ....
160 //                ......
161 //    Part4: Function Offset Table
162 //             function1 name index --> function1 profile start
163 //             function2 name index --> function2 profile start
164 //             function3 name index --> function3 profile start
165 //
166 // We need Part2 because profile reader can use it to find out and read
167 // function offset table without reading Part3 first.
168 class SampleProfileWriterCompactBinary : public SampleProfileWriterBinary {
169   using SampleProfileWriterBinary::SampleProfileWriterBinary;
170
171 public:
172   virtual std::error_code write(const FunctionSamples &S) override;
173   virtual std::error_code
174   write(const StringMap<FunctionSamples> &ProfileMap) override;
175
176 protected:
177   /// The table mapping from function name to the offset of its FunctionSample
178   /// towards profile start.
179   MapVector<StringRef, uint64_t> FuncOffsetTable;
180   /// The offset of the slot to be filled with the offset of FuncOffsetTable
181   /// towards profile start.
182   uint64_t TableOffset;
183   virtual std::error_code writeNameTable() override;
184   virtual std::error_code writeMagicIdent() override;
185   virtual std::error_code
186   writeHeader(const StringMap<FunctionSamples> &ProfileMap) override;
187   std::error_code writeFuncOffsetTable();
188 };
189
190 } // end namespace sampleprof
191 } // end namespace llvm
192
193 #endif // LLVM_PROFILEDATA_SAMPLEPROFWRITER_H