LLVM  14.0.0git
RawMemProfReader.cpp
Go to the documentation of this file.
1 //===- RawMemProfReader.cpp - Instrumented memory profiling reader --------===//
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 #include <cstdint>
14 #include <type_traits>
15 
19 
20 namespace llvm {
21 namespace memprof {
22 namespace {
23 
24 struct Summary {
30 };
31 
32 template <class T = uint64_t> inline T alignedRead(const char *Ptr) {
33  static_assert(std::is_pod<T>::value, "Not a pod type.");
34  assert(reinterpret_cast<size_t>(Ptr) % sizeof(T) == 0 && "Unaligned Read");
35  return *reinterpret_cast<const T *>(Ptr);
36 }
37 
38 Summary computeSummary(const char *Start) {
39  auto *H = reinterpret_cast<const Header *>(Start);
40 
41  // Check alignment while reading the number of items in each section.
42  return Summary{
43  H->Version,
44  H->TotalSize,
45  alignedRead(Start + H->SegmentOffset),
46  alignedRead(Start + H->MIBOffset),
47  alignedRead(Start + H->StackOffset),
48  };
49 }
50 
51 } // namespace
52 
53 Expected<std::unique_ptr<RawMemProfReader>>
55  auto BufferOr = MemoryBuffer::getFileOrSTDIN(Path, /*IsText=*/true);
56  if (std::error_code EC = BufferOr.getError())
57  return errorCodeToError(EC);
58 
59  std::unique_ptr<MemoryBuffer> Buffer(BufferOr.get().release());
60 
61  if (Buffer->getBufferSize() == 0)
62  return make_error<InstrProfError>(instrprof_error::empty_raw_profile);
63 
64  if (!RawMemProfReader::hasFormat(*Buffer))
65  return make_error<InstrProfError>(instrprof_error::bad_magic);
66 
67  if (Buffer->getBufferSize() < sizeof(Header)) {
68  return make_error<InstrProfError>(instrprof_error::truncated);
69  }
70 
71  // The size of the buffer can be > header total size since we allow repeated
72  // serialization of memprof profiles to the same file.
73  uint64_t TotalSize = 0;
74  const char *Next = Buffer->getBufferStart();
75  while (Next < Buffer->getBufferEnd()) {
76  auto *H = reinterpret_cast<const Header *>(Next);
77  if (H->Version != MEMPROF_RAW_VERSION) {
78  return make_error<InstrProfError>(instrprof_error::unsupported_version);
79  }
80 
81  TotalSize += H->TotalSize;
82  Next += H->TotalSize;
83  }
84 
85  if (Buffer->getBufferSize() != TotalSize) {
86  return make_error<InstrProfError>(instrprof_error::malformed);
87  }
88 
89  return std::make_unique<RawMemProfReader>(std::move(Buffer));
90 }
91 
93  if (Buffer.getBufferSize() < sizeof(uint64_t))
94  return false;
95  // Aligned read to sanity check that the buffer was allocated with at least 8b
96  // alignment.
97  const uint64_t Magic = alignedRead(Buffer.getBufferStart());
98  return Magic == MEMPROF_RAW_MAGIC_64;
99 }
100 
102  int Count = 0;
103  const char *Next = DataBuffer->getBufferStart();
104  while (Next < DataBuffer->getBufferEnd()) {
105  auto Summary = computeSummary(Next);
106  OS << "MemProf Profile " << ++Count << "\n";
107  OS << " Version: " << Summary.Version << "\n";
108  OS << " TotalSizeBytes: " << Summary.TotalSizeBytes << "\n";
109  OS << " NumSegments: " << Summary.NumSegments << "\n";
110  OS << " NumMIBInfo: " << Summary.NumMIBInfo << "\n";
111  OS << " NumStackOffsets: " << Summary.NumStackOffsets << "\n";
112  // TODO: Print the build ids once we can record them using the
113  // sanitizer_procmaps library for linux.
114 
115  auto *H = reinterpret_cast<const Header *>(Next);
116  Next += H->TotalSize;
117  }
118 }
119 
120 } // namespace memprof
121 } // namespace llvm
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
NumStackOffsets
uint64_t NumStackOffsets
Definition: RawMemProfReader.cpp:29
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::MemoryBuffer
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:50
NumSegments
uint64_t NumSegments
Definition: RawMemProfReader.cpp:27
TotalSizeBytes
uint64_t TotalSizeBytes
Definition: RawMemProfReader.cpp:26
llvm::MemoryBuffer::getBufferSize
size_t getBufferSize() const
Definition: MemoryBuffer.h:67
llvm::errorCodeToError
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:90
InstrProf.h
llvm::instrprof_error::truncated
@ truncated
llvm::memprof::RawMemProfReader::create
static Expected< std::unique_ptr< RawMemProfReader > > create(const Twine &Path)
Definition: RawMemProfReader.cpp:54
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::instrprof_error::bad_magic
@ bad_magic
llvm::instrprof_error::unsupported_version
@ unsupported_version
llvm::memprof::RawMemProfReader::printSummaries
void printSummaries(raw_ostream &OS) const
Definition: RawMemProfReader.cpp:101
NumMIBInfo
uint64_t NumMIBInfo
Definition: RawMemProfReader.cpp:28
uint64_t
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::MemoryBuffer::getFileOrSTDIN
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
Definition: MemoryBuffer.cpp:143
llvm::instrprof_error::empty_raw_profile
@ empty_raw_profile
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::msf::Magic
static const char Magic[]
Definition: MSFCommon.h:23
MemProfData.inc
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::MemoryBuffer::getBufferStart
const char * getBufferStart() const
Definition: MemoryBuffer.h:65
H
#define H(x, y, z)
Definition: MD5.cpp:57
llvm::memprof::RawMemProfReader::hasFormat
static bool hasFormat(const MemoryBuffer &DataBuffer)
Definition: RawMemProfReader.cpp:92
memprof
memprof
Definition: MemProfiler.cpp:282
Version
uint64_t Version
Definition: RawMemProfReader.cpp:25
llvm::instrprof_error::malformed
@ malformed
RawMemProfReader.h