LLVM 20.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"
27#include "llvm/Support/Error.h"
29
30#include <functional>
31
32namespace llvm {
33namespace memprof {
34// A class for memprof profile data populated directly from external
35// sources.
37public:
38 // The MemProfReader only holds memory profile information.
40
41 using GuidMemProfRecordPair = std::pair<GlobalValue::GUID, MemProfRecord>;
43 Iterator end() { return Iterator(); }
45 Iter = MemProfData.Records.begin();
46 return Iterator(this);
47 }
48
49 // Take the complete profile data. Once this function is invoked,
50 // MemProfReader no longer owns the MemProf profile.
52
53 virtual Error
55 std::function<const Frame(const FrameId)> Callback = nullptr) {
56 if (MemProfData.Records.empty())
57 return make_error<InstrProfError>(instrprof_error::empty_raw_profile);
58
59 if (Iter == MemProfData.Records.end())
60 return make_error<InstrProfError>(instrprof_error::eof);
61
62 if (Callback == nullptr)
63 Callback =
64 std::bind(&MemProfReader::idToFrame, this, std::placeholders::_1);
65
67 MemProfData.CallStacks, Callback);
68
69 const IndexedMemProfRecord &IndexedRecord = Iter->second;
70 GuidRecord = {
71 Iter->first,
72 IndexedRecord.toMemProfRecord(CSIdConv),
73 };
74 if (CSIdConv.LastUnmappedId)
75 return make_error<InstrProfError>(instrprof_error::hash_mismatch);
76 Iter++;
77 return Error::success();
78 }
79
80 // Allow default construction for derived classes which can populate the
81 // contents after construction.
82 MemProfReader() = default;
83 virtual ~MemProfReader() = default;
84
85 // Initialize the MemProfReader with the given MemProf profile.
88
89protected:
90 // A helper method to extract the frame from the IdToFrame map.
91 const Frame &idToFrame(const FrameId Id) const {
92 auto It = MemProfData.Frames.find(Id);
93 assert(It != MemProfData.Frames.end() && "Id not found in map.");
94 return It->second;
95 }
96 // A complete pacakge of the MemProf profile.
98 // An iterator to the internal function profile data structure.
100};
101
102// Map from id (recorded from sanitizer stack depot) to virtual addresses for
103// each program counter address in the callstack.
105
106// Specializes the MemProfReader class to populate the contents from raw binary
107// memprof profiles from instrumentation based profiling.
108class RawMemProfReader final : public MemProfReader {
109public:
112 virtual ~RawMemProfReader() override;
113
114 // Prints the contents of the profile in YAML format.
115 void printYAML(raw_ostream &OS);
116
117 // Return true if the \p DataBuffer starts with magic bytes indicating it is
118 // a raw binary memprof profile.
119 static bool hasFormat(const MemoryBuffer &DataBuffer);
120 // Return true if the file at \p Path starts with magic bytes indicating it is
121 // a raw binary memprof profile.
122 static bool hasFormat(const StringRef Path);
123
124 // Create a RawMemProfReader after sanity checking the contents of the file at
125 // \p Path or the \p Buffer. The binary from which the profile has been
126 // collected is specified via a path in \p ProfiledBinary.
128 create(const Twine &Path, StringRef ProfiledBinary, bool KeepName = false);
130 create(std::unique_ptr<MemoryBuffer> Buffer, StringRef ProfiledBinary,
131 bool KeepName = false);
132
133 // Returns a list of build ids recorded in the segment information.
134 static std::vector<std::string> peekBuildIds(MemoryBuffer *DataBuffer);
135
136 Error
138 std::function<const Frame(const FrameId)> Callback) override;
139
140 // Constructor for unittests only.
141 RawMemProfReader(std::unique_ptr<llvm::symbolize::SymbolizableModule> Sym,
144 CallStackMap &SM, bool KeepName = false)
145 : SegmentInfo(Seg.begin(), Seg.end()), CallstackProfileData(Prof),
146 StackMap(SM), KeepSymbolName(KeepName) {
147 // We don't call initialize here since there is no raw profile to read. The
148 // test should pass in the raw profile as structured data.
149
150 // If there is an error here then the mock symbolizer has not been
151 // initialized properly.
152 if (Error E = symbolizeAndFilterStackFrames(std::move(Sym)))
153 report_fatal_error(std::move(E));
154 if (Error E = mapRawProfileToRecords())
155 report_fatal_error(std::move(E));
156 }
157
158private:
160 : Binary(std::move(Bin)), KeepSymbolName(KeepName) {}
161 // Initializes the RawMemProfReader with the contents in `DataBuffer`.
162 Error initialize(std::unique_ptr<MemoryBuffer> DataBuffer);
163 // Read and parse the contents of the `DataBuffer` as a binary format profile.
164 Error readRawProfile(std::unique_ptr<MemoryBuffer> DataBuffer);
165 // Initialize the segment mapping information for symbolization.
166 Error setupForSymbolization();
167 // Symbolize and cache all the virtual addresses we encounter in the
168 // callstacks from the raw profile. Also prune callstack frames which we can't
169 // symbolize or those that belong to the runtime. For profile entries where
170 // the entire callstack is pruned, we drop the entry from the profile.
171 Error symbolizeAndFilterStackFrames(
172 std::unique_ptr<llvm::symbolize::SymbolizableModule> Symbolizer);
173 // Construct memprof records for each function and store it in the
174 // `FunctionProfileData` map. A function may have allocation profile data or
175 // callsite data or both.
176 Error mapRawProfileToRecords();
177
178 object::SectionedAddress getModuleOffset(uint64_t VirtualAddress);
179
181 readMemInfoBlocks(const char *Ptr);
182
183 // The profiled binary.
185 // Version of raw memprof binary currently being read. Defaults to most up
186 // to date version.
187 uint64_t MemprofRawVersion = MEMPROF_RAW_VERSION;
188 // The preferred load address of the executable segment.
189 uint64_t PreferredTextSegmentAddress = 0;
190 // The base address of the text segment in the process during profiling.
191 uint64_t ProfiledTextSegmentStart = 0;
192 // The limit address of the text segment in the process during profiling.
193 uint64_t ProfiledTextSegmentEnd = 0;
194
195 // The memory mapped segment information for all executable segments in the
196 // profiled binary (filtered from the raw profile using the build id).
198
199 // A map from callstack id (same as key in CallStackMap below) to the heap
200 // information recorded for that allocation context.
201 llvm::MapVector<uint64_t, MemInfoBlock> CallstackProfileData;
202 CallStackMap StackMap;
203
204 // Cached symbolization from PC to Frame.
206
207 // Whether to keep the symbol name for each frame after hashing.
208 bool KeepSymbolName = false;
209 // A mapping of the hash to symbol name, only used if KeepSymbolName is true.
211};
212
213class YAMLMemProfReader final : public MemProfReader {
214public:
215 YAMLMemProfReader() = default;
216
217 // Return true if the \p DataBuffer starts with "---" indicating it is a YAML
218 // file.
219 static bool hasFormat(const MemoryBuffer &DataBuffer);
220 // Wrapper around hasFormat above, reading the file instead of the memory
221 // buffer.
222 static bool hasFormat(const StringRef Path);
223
224 // Create a YAMLMemProfReader after sanity checking the contents of the file
225 // at \p Path or the \p Buffer.
228 create(std::unique_ptr<MemoryBuffer> Buffer);
229
230 void parse(StringRef YAMLData);
231};
232} // namespace memprof
233} // namespace llvm
234
235#endif // LLVM_PROFILEDATA_MEMPROFREADER_H_
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
Symbol * Sym
Definition: ELF_riscv.cpp:479
This file implements a map that provides insertion order iteration.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Tagged union holding either a T or a Error.
Definition: Error.h:481
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:49
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:51
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
const Frame & idToFrame(const FrameId Id) const
Definition: MemProfReader.h:91
virtual ~MemProfReader()=default
IndexedMemProfData takeMemProfData()
Definition: MemProfReader.h:51
InstrProfIterator< GuidMemProfRecordPair, MemProfReader > Iterator
Definition: MemProfReader.h:42
IndexedMemProfData MemProfData
Definition: MemProfReader.h:97
InstrProfKind getProfileKind() const
Definition: MemProfReader.h:39
virtual Error readNextRecord(GuidMemProfRecordPair &GuidRecord, std::function< const Frame(const FrameId)> Callback=nullptr)
Definition: MemProfReader.h:54
MemProfReader(IndexedMemProfData &&MemProfData)
Definition: MemProfReader.h:86
llvm::MapVector< GlobalValue::GUID, IndexedMemProfRecord >::iterator Iter
Definition: MemProfReader.h:99
std::pair< GlobalValue::GUID, MemProfRecord > GuidMemProfRecordPair
Definition: MemProfReader.h:41
void printYAML(raw_ostream &OS)
RawMemProfReader & operator=(const RawMemProfReader &)=delete
RawMemProfReader(const RawMemProfReader &)=delete
static Expected< std::unique_ptr< RawMemProfReader > > create(const Twine &Path, StringRef ProfiledBinary, bool KeepName=false)
static std::vector< std::string > peekBuildIds(MemoryBuffer *DataBuffer)
Error readNextRecord(GuidMemProfRecordPair &GuidRecord, std::function< const Frame(const FrameId)> Callback) override
RawMemProfReader(std::unique_ptr< llvm::symbolize::SymbolizableModule > Sym, llvm::SmallVectorImpl< SegmentEntry > &Seg, llvm::MapVector< uint64_t, MemInfoBlock > &Prof, CallStackMap &SM, bool KeepName=false)
static bool hasFormat(const MemoryBuffer &DataBuffer)
virtual ~RawMemProfReader() override
static bool hasFormat(const MemoryBuffer &DataBuffer)
static 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:52
llvm::DenseMap< uint64_t, llvm::SmallVector< uint64_t > > CallStackMap
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
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:1873
InstrProfKind
An enum describing the attributes of an instrumented profile.
Definition: InstrProf.h:329
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
llvm::MapVector< CallStackId, llvm::SmallVector< FrameId > > CallStacks
Definition: MemProf.h:993
llvm::MapVector< GlobalValue::GUID, IndexedMemProfRecord > Records
Definition: MemProf.h:985
llvm::MapVector< FrameId, Frame > Frames
Definition: MemProf.h:990
MemProfRecord toMemProfRecord(llvm::function_ref< std::vector< Frame >(const CallStackId)> Callback) const
Definition: MemProf.cpp:232
Definition: regcomp.c:192