xref: /freebsd/contrib/llvm-project/llvm/lib/ProfileData/MemProfSummary.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1*700637cbSDimitry Andric //=-- MemProfSummary.cpp - MemProf summary support ---------------=//
2*700637cbSDimitry Andric //
3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*700637cbSDimitry Andric //
7*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
8*700637cbSDimitry Andric //
9*700637cbSDimitry Andric // This file contains MemProf summary support.
10*700637cbSDimitry Andric //
11*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
12*700637cbSDimitry Andric 
13*700637cbSDimitry Andric #include "llvm/ProfileData/MemProfSummary.h"
14*700637cbSDimitry Andric 
15*700637cbSDimitry Andric using namespace llvm;
16*700637cbSDimitry Andric using namespace llvm::memprof;
17*700637cbSDimitry Andric 
printSummaryYaml(raw_ostream & OS) const18*700637cbSDimitry Andric void MemProfSummary::printSummaryYaml(raw_ostream &OS) const {
19*700637cbSDimitry Andric   // For now emit as YAML comments, since they aren't read on input.
20*700637cbSDimitry Andric   OS << "---\n";
21*700637cbSDimitry Andric   OS << "# MemProfSummary:\n";
22*700637cbSDimitry Andric   OS << "#   Total contexts: " << NumContexts << "\n";
23*700637cbSDimitry Andric   OS << "#   Total cold contexts: " << NumColdContexts << "\n";
24*700637cbSDimitry Andric   OS << "#   Total hot contexts: " << NumHotContexts << "\n";
25*700637cbSDimitry Andric   OS << "#   Maximum cold context total size: " << MaxColdTotalSize << "\n";
26*700637cbSDimitry Andric   OS << "#   Maximum warm context total size: " << MaxWarmTotalSize << "\n";
27*700637cbSDimitry Andric   OS << "#   Maximum hot context total size: " << MaxHotTotalSize << "\n";
28*700637cbSDimitry Andric }
29*700637cbSDimitry Andric 
write(ProfOStream & OS) const30*700637cbSDimitry Andric void MemProfSummary::write(ProfOStream &OS) const {
31*700637cbSDimitry Andric   // Write the current number of fields first, which helps enable backwards and
32*700637cbSDimitry Andric   // forwards compatibility (see comment in header).
33*700637cbSDimitry Andric   OS.write32(memprof::MemProfSummary::getNumSummaryFields());
34*700637cbSDimitry Andric   auto StartPos = OS.tell();
35*700637cbSDimitry Andric   (void)StartPos;
36*700637cbSDimitry Andric   OS.write(NumContexts);
37*700637cbSDimitry Andric   OS.write(NumColdContexts);
38*700637cbSDimitry Andric   OS.write(NumHotContexts);
39*700637cbSDimitry Andric   OS.write(MaxColdTotalSize);
40*700637cbSDimitry Andric   OS.write(MaxWarmTotalSize);
41*700637cbSDimitry Andric   OS.write(MaxHotTotalSize);
42*700637cbSDimitry Andric   // Sanity check that the number of fields was kept in sync with actual fields.
43*700637cbSDimitry Andric   assert((OS.tell() - StartPos) / 8 == MemProfSummary::getNumSummaryFields());
44*700637cbSDimitry Andric }
45*700637cbSDimitry Andric 
46*700637cbSDimitry Andric std::unique_ptr<MemProfSummary>
deserialize(const unsigned char * & Ptr)47*700637cbSDimitry Andric MemProfSummary::deserialize(const unsigned char *&Ptr) {
48*700637cbSDimitry Andric   auto NumSummaryFields =
49*700637cbSDimitry Andric       support::endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
50*700637cbSDimitry Andric   // The initial version of the summary contains 6 fields. To support backwards
51*700637cbSDimitry Andric   // compatibility with older profiles, if new summary fields are added (until a
52*700637cbSDimitry Andric   // version bump) this code will need to check NumSummaryFields against the
53*700637cbSDimitry Andric   // current value of MemProfSummary::getNumSummaryFields(). If NumSummaryFields
54*700637cbSDimitry Andric   // is lower then default values will need to be filled in for the newer fields
55*700637cbSDimitry Andric   // instead of trying to read them from the profile.
56*700637cbSDimitry Andric   //
57*700637cbSDimitry Andric   // For now, assert that the profile contains at least as many fields as
58*700637cbSDimitry Andric   // expected by the code.
59*700637cbSDimitry Andric   assert(NumSummaryFields >= MemProfSummary::getNumSummaryFields());
60*700637cbSDimitry Andric 
61*700637cbSDimitry Andric   auto MemProfSum = std::make_unique<MemProfSummary>(
62*700637cbSDimitry Andric       support::endian::read<uint64_t, llvm::endianness::little>(Ptr),
63*700637cbSDimitry Andric       support::endian::read<uint64_t, llvm::endianness::little>(Ptr + 8),
64*700637cbSDimitry Andric       support::endian::read<uint64_t, llvm::endianness::little>(Ptr + 16),
65*700637cbSDimitry Andric       support::endian::read<uint64_t, llvm::endianness::little>(Ptr + 24),
66*700637cbSDimitry Andric       support::endian::read<uint64_t, llvm::endianness::little>(Ptr + 32),
67*700637cbSDimitry Andric       support::endian::read<uint64_t, llvm::endianness::little>(Ptr + 40));
68*700637cbSDimitry Andric 
69*700637cbSDimitry Andric   // Enable forwards compatibility by skipping past any additional fields in the
70*700637cbSDimitry Andric   // profile's summary.
71*700637cbSDimitry Andric   Ptr += NumSummaryFields * sizeof(uint64_t);
72*700637cbSDimitry Andric 
73*700637cbSDimitry Andric   return MemProfSum;
74*700637cbSDimitry Andric }
75