15#define MIBEntryDef(NameTag, Name, Type) List.push_back(Meta::Name);
22 return {Meta::AllocCount, Meta::TotalSize, Meta::TotalLifetime,
23 Meta::TotalLifetimeAccessDensity};
77 Result +=
N.serializedSize(Schema,
Version0);
81 for (
const auto &Frames :
Record.CallSites) {
84 Result += Frames.size() *
sizeof(
FrameId);
94 Result +=
N.serializedSize(Schema,
Version2);
108 Result +=
N.serializedSize(Schema,
Version3);
133 using namespace support;
140 for (
const FrameId &Id :
N.CallStack)
142 N.Info.serialize(Schema,
OS);
147 for (
const auto &Frames :
Record.CallSites) {
149 for (
const FrameId &Id : Frames)
156 using namespace support;
163 N.Info.serialize(Schema,
OS);
168 for (
const auto &CSId :
Record.CallSiteIds)
176 using namespace support;
184 N.Info.serialize(Schema,
OS);
189 for (
const auto &CSId :
Record.CallSiteIds) {
215 const unsigned char *
Ptr) {
216 using namespace support;
222 endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
226 endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
227 for (
uint64_t J = 0; J < NumFrames; J++) {
229 endian::readNext<FrameId, llvm::endianness::little>(
Ptr);
230 Node.CallStack.push_back(Id);
233 Node.Info.deserialize(Schema,
Ptr);
240 endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
241 for (
uint64_t J = 0; J < NumCtxs; J++) {
243 endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
246 for (
uint64_t K = 0; K < NumFrames; K++) {
248 endian::readNext<FrameId, llvm::endianness::little>(
Ptr);
251 Record.CallSites.push_back(Frames);
259 const unsigned char *
Ptr) {
260 using namespace support;
266 endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
267 Record.AllocSites.reserve(NumNodes);
270 Node.CSId = endian::readNext<CallStackId, llvm::endianness::little>(
Ptr);
271 Node.Info.deserialize(Schema,
Ptr);
278 endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
279 Record.CallSiteIds.reserve(NumCtxs);
280 for (
uint64_t J = 0; J < NumCtxs; J++) {
282 endian::readNext<CallStackId, llvm::endianness::little>(
Ptr);
283 Record.CallSiteIds.push_back(CSId);
290 const unsigned char *
Ptr) {
291 using namespace support;
297 endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
298 Record.AllocSites.reserve(NumNodes);
302 endian::readNext<LinearCallStackId, llvm::endianness::little>(
Ptr);
303 Node.Info.deserialize(Schema,
Ptr);
310 endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
311 Record.CallSiteIds.reserve(NumCtxs);
312 for (
uint64_t J = 0; J < NumCtxs; J++) {
318 endian::readNext<LinearCallStackId, llvm::endianness::little>(
Ptr);
319 Record.CallSiteIds.push_back(CSId);
327 const unsigned char *
Ptr,
348 AI.
Info = IndexedAI.Info;
350 Record.AllocSites.push_back(std::move(AI));
355 Record.CallSites.push_back(Callback(CSId));
377 using namespace support;
379 const unsigned char *
Ptr = Buffer;
381 endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
384 "memprof schema invalid");
388 for (
size_t I = 0;
I < NumSchemaIds;
I++) {
390 endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
393 "memprof schema invalid");
395 Result.push_back(
static_cast<Meta>(
Tag));
409 std::memcpy(&CSId, Hash.data(),
sizeof(Hash));
452 CommonLen = std::distance(CallStack->
rbegin(), Pos.second);
456 assert(CommonLen <= Indexes.size());
457 Indexes.resize(CommonLen);
461 uint32_t CurrentIndex = RadixArray.size();
462 uint32_t ParentIndex = Indexes.back();
465 assert(ParentIndex < CurrentIndex);
466 RadixArray.push_back(ParentIndex - CurrentIndex);
473 Indexes.push_back(RadixArray.size());
474 RadixArray.push_back(MemProfFrameIndexes.
find(
F)->second);
479 RadixArray.push_back(CallStack->
size());
483 return RadixArray.size() - 1;
488 &&MemProfCallStackData,
496 if (CallStacks.
empty()) {
498 CallStackPos.clear();
537 llvm::sort(CallStacks, [&](
const CSIdPair &L,
const CSIdPair &R) {
540 return std::lexicographical_compare(
541 L.second.rbegin(), L.second.rend(), R.second.rbegin(), R.second.rend(),
543 uint64_t H1 = FrameHistogram[F1].Count;
544 uint64_t H2 = FrameHistogram[F2].Count;
556 RadixArray.reserve(CallStacks.
size() * 8);
560 Indexes.reserve(512);
563 CallStackPos.clear();
564 CallStackPos.reserve(CallStacks.
size());
595 encodeCallStack(&
CallStack, Prev, MemProfFrameIndexes);
596 CallStackPos.insert({CSId, Pos});
601 assert(!RadixArray.empty());
607 for (
size_t I = 0, J = RadixArray.size() - 1;
I < J; ++
I, --J)
611 for (
auto &[K, V] : CallStackPos)
612 V = RadixArray.size() - 1 - V;
617 &MemProfCallStackData) {
620 for (
const auto &KV : MemProfCallStackData) {
621 const auto &CS = KV.second;
622 for (
unsigned I = 0,
E = CS.size();
I !=
E; ++
I) {
623 auto &S = Histogram[CS[
I]];
632 for (
const auto &AS :
Record.AllocSites) {
640 &FunctionProfileData) {
641 for (
const auto &[GUID,
Record] : FunctionProfileData) {
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
iterator find(const_arg_type_t< KeyT > Val)
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Tagged union holding either a T or a Error.
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
HashResultTy< HasherT_ > final()
Forward to HasherT::final() if available.
Interface to help hash various types through a hasher type.
std::enable_if_t< hashbuilder_detail::IsHashableData< T >::value, HashBuilder & > add(T Value)
Implement hashing for hashable data types, e.g. integral or enum values.
This class implements a map that also provides access to all stored values in a deterministic order.
void reserve(size_type N)
void push_back(const T &Elt)
reverse_iterator rbegin()
StringRef - Represent a constant reference to a string, i.e.
An efficient, type-erasing, non-owning reference to a callable.
void build(llvm::MapVector< CallStackId, llvm::SmallVector< FrameId > > &&MemProfCallStackData, const llvm::DenseMap< FrameId, LinearFrameId > &MemProfFrameIndexes, llvm::DenseMap< FrameId, FrameStat > &FrameHistogram)
Helper class to iterate through stack ids in both metadata (memprof MIB and callsite) and the corresp...
This class implements an extremely fast bulk output stream that can only output to a stream.
static StringRef getCanonicalFnName(const Function &F)
Return the canonical name for a function, taking into account suffix elision policy attributes.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void verifyIndexedMemProfRecord(const IndexedMemProfRecord &Record)
static IndexedMemProfRecord deserializeV3(const MemProfSchema &Schema, const unsigned char *Ptr)
static void serializeV3(const IndexedMemProfRecord &Record, const MemProfSchema &Schema, raw_ostream &OS, llvm::DenseMap< CallStackId, LinearCallStackId > &MemProfCallStackIndexes)
MemProfSchema getHotColdSchema()
uint32_t LinearCallStackId
llvm::DenseMap< FrameId, FrameStat > computeFrameHistogram(llvm::MapVector< CallStackId, llvm::SmallVector< FrameId > > &MemProfCallStackData)
CallStackId hashCallStack(ArrayRef< FrameId > CS)
static size_t serializedSizeV2(const IndexedAllocationInfo &IAI, const MemProfSchema &Schema)
static size_t serializedSizeV0(const IndexedAllocationInfo &IAI, const MemProfSchema &Schema)
static void serializeV0(const IndexedMemProfRecord &Record, const MemProfSchema &Schema, raw_ostream &OS)
static size_t serializedSizeV3(const IndexedAllocationInfo &IAI, const MemProfSchema &Schema)
static IndexedMemProfRecord deserializeV0(const MemProfSchema &Schema, const unsigned char *Ptr)
MemProfSchema getFullSchema()
Expected< MemProfSchema > readMemProfSchema(const unsigned char *&Buffer)
void verifyFunctionProfileData(const llvm::MapVector< GlobalValue::GUID, IndexedMemProfRecord > &FunctionProfileData)
static void serializeV2(const IndexedMemProfRecord &Record, const MemProfSchema &Schema, raw_ostream &OS)
static IndexedMemProfRecord deserializeV2(const MemProfSchema &Schema, const unsigned char *Ptr)
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
std::array< uint8_t, NumBytes > BLAKE3Result
The constant LLVM_BLAKE3_OUT_LEN provides the default output length, 32 bytes, which is recommended f...
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
std::vector< Frame > CallStack
PortableMemInfoBlock Info
size_t serializedSize(const MemProfSchema &Schema, IndexedVersion Version) const
llvm::SmallVector< FrameId > CallStack
llvm::SmallVector< CallStackId > CallSiteIds
llvm::SmallVector< IndexedAllocationInfo > AllocSites
size_t serializedSize(const MemProfSchema &Schema, IndexedVersion Version) const
void serialize(const MemProfSchema &Schema, raw_ostream &OS, IndexedVersion Version, llvm::DenseMap< CallStackId, LinearCallStackId > *MemProfCallStackIndexes=nullptr) const
static IndexedMemProfRecord deserialize(const MemProfSchema &Schema, const unsigned char *Buffer, IndexedVersion Version)
static GlobalValue::GUID getGUID(const StringRef FunctionName)
MemProfRecord toMemProfRecord(llvm::function_ref< std::vector< Frame >(const CallStackId)> Callback) const
static size_t serializedSize(const MemProfSchema &Schema)
Adapter to write values to a stream in a particular byte order.