| //=-- MemProfSummary.cpp - MemProf summary support ---------------=// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file contains MemProf summary support. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/ProfileData/MemProfSummary.h" |
| |
| using namespace llvm; |
| using namespace llvm::memprof; |
| |
| void MemProfSummary::printSummaryYaml(raw_ostream &OS) const { |
| // For now emit as YAML comments, since they aren't read on input. |
| OS << "---\n"; |
| OS << "# MemProfSummary:\n"; |
| OS << "# Total contexts: " << NumContexts << "\n"; |
| OS << "# Total cold contexts: " << NumColdContexts << "\n"; |
| OS << "# Total hot contexts: " << NumHotContexts << "\n"; |
| OS << "# Maximum cold context total size: " << MaxColdTotalSize << "\n"; |
| OS << "# Maximum warm context total size: " << MaxWarmTotalSize << "\n"; |
| OS << "# Maximum hot context total size: " << MaxHotTotalSize << "\n"; |
| } |
| |
| void MemProfSummary::write(ProfOStream &OS) const { |
| // Write the current number of fields first, which helps enable backwards and |
| // forwards compatibility (see comment in header). |
| OS.write32(memprof::MemProfSummary::getNumSummaryFields()); |
| auto StartPos = OS.tell(); |
| (void)StartPos; |
| OS.write(NumContexts); |
| OS.write(NumColdContexts); |
| OS.write(NumHotContexts); |
| OS.write(MaxColdTotalSize); |
| OS.write(MaxWarmTotalSize); |
| OS.write(MaxHotTotalSize); |
| // Sanity check that the number of fields was kept in sync with actual fields. |
| assert((OS.tell() - StartPos) / 8 == MemProfSummary::getNumSummaryFields()); |
| } |
| |
| std::unique_ptr<MemProfSummary> |
| MemProfSummary::deserialize(const unsigned char *&Ptr) { |
| auto NumSummaryFields = |
| support::endian::readNext<uint32_t, llvm::endianness::little>(Ptr); |
| // The initial version of the summary contains 6 fields. To support backwards |
| // compatibility with older profiles, if new summary fields are added (until a |
| // version bump) this code will need to check NumSummaryFields against the |
| // current value of MemProfSummary::getNumSummaryFields(). If NumSummaryFields |
| // is lower then default values will need to be filled in for the newer fields |
| // instead of trying to read them from the profile. |
| // |
| // For now, assert that the profile contains at least as many fields as |
| // expected by the code. |
| assert(NumSummaryFields >= MemProfSummary::getNumSummaryFields()); |
| |
| auto MemProfSum = std::make_unique<MemProfSummary>( |
| support::endian::read<uint64_t, llvm::endianness::little>(Ptr), |
| support::endian::read<uint64_t, llvm::endianness::little>(Ptr + 8), |
| support::endian::read<uint64_t, llvm::endianness::little>(Ptr + 16), |
| support::endian::read<uint64_t, llvm::endianness::little>(Ptr + 24), |
| support::endian::read<uint64_t, llvm::endianness::little>(Ptr + 32), |
| support::endian::read<uint64_t, llvm::endianness::little>(Ptr + 40)); |
| |
| // Enable forwards compatibility by skipping past any additional fields in the |
| // profile's summary. |
| Ptr += NumSummaryFields * sizeof(uint64_t); |
| |
| return MemProfSum; |
| } |