LLVM 22.0.0git
MemProfReader.h
Go to the documentation of this file.
1//===- MemProfReader.h - Instrumented memory profiling reader ---*- 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 support for reading MemProf profiling data.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_PROFILEDATA_MEMPROFREADER_H_
14#define LLVM_PROFILEDATA_MEMPROFREADER_H_
15
16#include "llvm/ADT/DenseMap.h"
17#include "llvm/ADT/MapVector.h"
18#include "llvm/ADT/StringRef.h"
21#include "llvm/IR/GlobalValue.h"
22#include "llvm/Object/Binary.h"
29#include "llvm/Support/Error.h"
31
32#include <functional>
33
34namespace llvm {
35namespace memprof {
36// A class for memprof profile data populated directly from external
37// sources.
39public:
40 // The MemProfReader only holds memory profile information.
42
43 using GuidMemProfRecordPair = std::pair<GlobalValue::GUID, MemProfRecord>;
45 Iterator end() { return Iterator(); }
47 Iter = MemProfData.Records.begin();
48 return Iterator(this);
49 }
50
51 // Take the complete profile data. Once this function is invoked,
52 // MemProfReader no longer owns the MemProf profile.
54
55 virtual Error
57 std::function<const Frame(const FrameId)> Callback = nullptr) {
58 if (MemProfData.Records.empty())
59 return make_error<InstrProfError>(instrprof_error::empty_raw_profile);
60
61 if (Iter == MemProfData.Records.end())
62 return make_error<InstrProfError>(instrprof_error::eof);
63
64 if (Callback == nullptr)
65 Callback = [&](FrameId Id) { return idToFrame(Id); };
66
68 MemProfData.CallStacks, Callback);
69
70 const IndexedMemProfRecord &IndexedRecord = Iter->second;
71 GuidRecord = {
72 Iter->first,
73 IndexedRecord.toMemProfRecord(CSIdConv),
74 };
75 if (CSIdConv.LastUnmappedId)
76 return make_error<InstrProfError>(instrprof_error::hash_mismatch);
77 Iter++;
78 return Error::success();
79 }
80
81 // Allow default construction for derived classes which can populate the
82 // contents after construction.
83 MemProfReader() = default;
84 virtual ~MemProfReader() = default;
85
86 // Initialize the MemProfReader with the given MemProf profile.
89
90protected:
91 // A helper method to extract the frame from the IdToFrame map.
92 const Frame &idToFrame(const FrameId Id) const {
93 auto It = MemProfData.Frames.find(Id);
94 assert(It != MemProfData.Frames.end() && "Id not found in map.");
95 return It->second;
96 }
97 // A complete pacakge of the MemProf profile.
99 // An iterator to the internal function profile data structure.
101};
102
103// Map from id (recorded from sanitizer stack depot) to virtual addresses for
104// each program counter address in the callstack.
106
107// Specializes the MemProfReader class to populate the contents from raw binary
108// memprof profiles from instrumentation based profiling.
110public:
113 virtual ~RawMemProfReader() override;
114
115 // Prints the contents of the profile in YAML format.
116 void printYAML(raw_ostream &OS);
117
118 // Return true if the \p DataBuffer starts with magic bytes indicating it is
119 // a raw binary memprof profile.
120 static bool hasFormat(const MemoryBuffer &DataBuffer);
121 // Return true if the file at \p Path starts with magic bytes indicating it is
122 // a raw binary memprof profile.
123 static bool hasFormat(const StringRef Path);
124
125 // Create a RawMemProfReader after sanity checking the contents of the file at
126 // \p Path or the \p Buffer. The binary from which the profile has been
127 // collected is specified via a path in \p ProfiledBinary.
129 create(const Twine &Path, StringRef ProfiledBinary, bool KeepName = false);
131 create(std::unique_ptr<MemoryBuffer> Buffer, StringRef ProfiledBinary,
132 bool KeepName = false);
133
134 // Returns a list of build ids recorded in the segment information.
135 static std::vector<std::string> peekBuildIds(MemoryBuffer *DataBuffer);
136
137 Error
138 readNextRecord(GuidMemProfRecordPair &GuidRecord,
139 std::function<const Frame(const FrameId)> Callback) override;
140
141 // Constructor for unittests only.
142 RawMemProfReader(std::unique_ptr<llvm::symbolize::SymbolizableModule> Sym,
145 CallStackMap &SM, bool KeepName = false)
146 : SegmentInfo(Seg.begin(), Seg.end()), CallstackProfileData(Prof),
147 StackMap(SM), KeepSymbolName(KeepName) {
148 // We don't call initialize here since there is no raw profile to read. The
149 // test should pass in the raw profile as structured data.
150
151 // If there is an error here then the mock symbolizer has not been
152 // initialized properly.
153 if (Error E = symbolizeAndFilterStackFrames(std::move(Sym)))
154 report_fatal_error(std::move(E));
155 if (Error E = mapRawProfileToRecords())
156 report_fatal_error(std::move(E));
157 }
158
159private:
161 : Binary(std::move(Bin)), KeepSymbolName(KeepName) {}
162 // Initializes the RawMemProfReader with the contents in `DataBuffer`.
163 Error initialize(std::unique_ptr<MemoryBuffer> DataBuffer);
164 // Read and parse the contents of the `DataBuffer` as a binary format profile.
165 Error readRawProfile(std::unique_ptr<MemoryBuffer> DataBuffer);
166 // Initialize the segment mapping information for symbolization.
167 Error setupForSymbolization();
168 // Symbolize and cache all the virtual addresses we encounter in the
169 // callstacks from the raw profile. Also prune callstack frames which we can't
170 // symbolize or those that belong to the runtime. For profile entries where
171 // the entire callstack is pruned, we drop the entry from the profile.
172 Error symbolizeAndFilterStackFrames(
173 std::unique_ptr<llvm::symbolize::SymbolizableModule> Symbolizer);
174 // Construct memprof records for each function and store it in the
175 // `FunctionProfileData` map. A function may have allocation profile data or
176 // callsite data or both.
177 Error mapRawProfileToRecords();
178
179 object::SectionedAddress getModuleOffset(uint64_t VirtualAddress);
180
182 readMemInfoBlocks(const char *Ptr);
183
184 // The profiled binary.
186 // Version of raw memprof binary currently being read. Defaults to most up
187 // to date version.
188 uint64_t MemprofRawVersion = MEMPROF_RAW_VERSION;
189 // The preferred load address of the executable segment.
190 uint64_t PreferredTextSegmentAddress = 0;
191 // The base address of the text segment in the process during profiling.
192 uint64_t ProfiledTextSegmentStart = 0;
193 // The limit address of the text segment in the process during profiling.
194 uint64_t ProfiledTextSegmentEnd = 0;
195
196 // The memory mapped segment information for all executable segments in the
197 // profiled binary (filtered from the raw profile using the build id).
199
200 // A map from callstack id (same as key in CallStackMap below) to the heap
201 // information recorded for that allocation context.
202 llvm::MapVector<uint64_t, MemInfoBlock> CallstackProfileData;
203 CallStackMap StackMap;
204
205 // Cached symbolization from PC to Frame.
207
208 // Whether to keep the symbol name for each frame after hashing.
209 bool KeepSymbolName = false;
210 // A mapping of the hash to symbol name, only used if KeepSymbolName is true.
212};
213
214class YAMLMemProfReader final : public MemProfReader {
215public:
216 YAMLMemProfReader() = default;
217
218 // Return true if the \p DataBuffer starts with "---" indicating it is a YAML
219 // file.
220 LLVM_ABI static bool hasFormat(const MemoryBuffer &DataBuffer);
221 // Wrapper around hasFormat above, reading the file instead of the memory
222 // buffer.
223 LLVM_ABI static bool hasFormat(const StringRef Path);
224
225 // Create a YAMLMemProfReader after sanity checking the contents of the file
226 // at \p Path or the \p Buffer.
228 create(const Twine &Path);
230 create(std::unique_ptr<MemoryBuffer> Buffer);
231
232 LLVM_ABI void parse(StringRef YAMLData);
233
234 std::unique_ptr<memprof::DataAccessProfData> takeDataAccessProfData() {
235 return std::move(DataAccessProfileData);
236 }
237
238private:
239 // Called by `parse` to set data access profiles after parsing them from Yaml
240 // files.
241 void
242 setDataAccessProfileData(std::unique_ptr<memprof::DataAccessProfData> Data) {
243 DataAccessProfileData = std::move(Data);
244 }
245
246 std::unique_ptr<memprof::DataAccessProfData> DataAccessProfileData;
247};
248} // namespace memprof
249} // namespace llvm
250
251#endif // LLVM_PROFILEDATA_MEMPROFREADER_H_
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ABI
Definition: Compiler.h:213
This file defines the DenseMap class.
Symbol * Sym
Definition: ELF_riscv.cpp:479
This file implements a map that provides insertion order iteration.
raw_pwrite_stream & OS
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
static ErrorSuccess success()
Create a success value.
Definition: Error.h:336
Tagged union holding either a T or a Error.
Definition: Error.h:485
A file format agnostic iterator over profiling data.
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:36
typename VectorType::iterator iterator
Definition: MapVector.h:42
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:52
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
const Frame & idToFrame(const FrameId Id) const
Definition: MemProfReader.h:92
virtual ~MemProfReader()=default
IndexedMemProfData takeMemProfData()
Definition: MemProfReader.h:53
InstrProfIterator< GuidMemProfRecordPair, MemProfReader > Iterator
Definition: MemProfReader.h:44
IndexedMemProfData MemProfData
Definition: MemProfReader.h:98
InstrProfKind getProfileKind() const
Definition: MemProfReader.h:41
virtual Error readNextRecord(GuidMemProfRecordPair &GuidRecord, std::function< const Frame(const FrameId)> Callback=nullptr)
Definition: MemProfReader.h:56
MemProfReader(IndexedMemProfData &&MemProfData)
Definition: MemProfReader.h:87
llvm::MapVector< GlobalValue::GUID, IndexedMemProfRecord >::iterator Iter
std::pair< GlobalValue::GUID, MemProfRecord > GuidMemProfRecordPair
Definition: MemProfReader.h:43
RawMemProfReader & operator=(const RawMemProfReader &)=delete
RawMemProfReader(const RawMemProfReader &)=delete
RawMemProfReader(std::unique_ptr< llvm::symbolize::SymbolizableModule > Sym, llvm::SmallVectorImpl< SegmentEntry > &Seg, llvm::MapVector< uint64_t, MemInfoBlock > &Prof, CallStackMap &SM, bool KeepName=false)
static LLVM_ABI bool hasFormat(const MemoryBuffer &DataBuffer)
std::unique_ptr< memprof::DataAccessProfData > takeDataAccessProfData()
static LLVM_ABI Expected< std::unique_ptr< YAMLMemProfReader > > create(const Twine &Path)
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition: Error.cpp:167
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1886
InstrProfKind
An enum describing the attributes of an instrumented profile.
Definition: InstrProf.h:374
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
llvm::MapVector< CallStackId, llvm::SmallVector< FrameId > > CallStacks
llvm::MapVector< GlobalValue::GUID, IndexedMemProfRecord > Records
llvm::MapVector< FrameId, Frame > Frames
LLVM_ABI MemProfRecord toMemProfRecord(llvm::function_ref< std::vector< Frame >(const CallStackId)> Callback) const
Definition: MemProf.cpp:323
Definition: regcomp.c:186