Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. #ifndef LLVM_PROFILEDATA_RAWMEMPROFREADER_H_
  2. #define LLVM_PROFILEDATA_RAWMEMPROFREADER_H_
  3. //===- MemProfReader.h - Instrumented memory profiling reader ---*- C++ -*-===//
  4. //
  5. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  6. // See https://llvm.org/LICENSE.txt for license information.
  7. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  8. //
  9. //===----------------------------------------------------------------------===//
  10. //
  11. // This file contains support for reading MemProf profiling data.
  12. //
  13. //===----------------------------------------------------------------------===//
  14.  
  15. #include "llvm/ADT/DenseMap.h"
  16. #include "llvm/ADT/MapVector.h"
  17. #include "llvm/ADT/StringRef.h"
  18. #include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
  19. #include "llvm/DebugInfo/Symbolize/Symbolize.h"
  20. #include "llvm/IR/GlobalValue.h"
  21. #include "llvm/Object/Binary.h"
  22. #include "llvm/Object/ObjectFile.h"
  23. #include "llvm/ProfileData/InstrProfReader.h"
  24. #include "llvm/ProfileData/MemProf.h"
  25. #include "llvm/ProfileData/MemProfData.inc"
  26. #include "llvm/Support/Error.h"
  27. #include "llvm/Support/MemoryBuffer.h"
  28.  
  29. #include <cstddef>
  30.  
  31. namespace llvm {
  32. namespace memprof {
  33.  
  34. // Map from id (recorded from sanitizer stack depot) to virtual addresses for
  35. // each program counter address in the callstack.
  36. using CallStackMap = llvm::DenseMap<uint64_t, llvm::SmallVector<uint64_t>>;
  37.  
  38. class RawMemProfReader {
  39. public:
  40.   RawMemProfReader(const RawMemProfReader &) = delete;
  41.   RawMemProfReader &operator=(const RawMemProfReader &) = delete;
  42.  
  43.   // Prints the contents of the profile in YAML format.
  44.   void printYAML(raw_ostream &OS);
  45.  
  46.   // Return true if the \p DataBuffer starts with magic bytes indicating it is
  47.   // a raw binary memprof profile.
  48.   static bool hasFormat(const MemoryBuffer &DataBuffer);
  49.   // Return true if the file at \p Path starts with magic bytes indicating it is
  50.   // a raw binary memprof profile.
  51.   static bool hasFormat(const StringRef Path);
  52.  
  53.   // Create a RawMemProfReader after sanity checking the contents of the file at
  54.   // \p Path. The binary from which the profile has been collected is specified
  55.   // via a path in \p ProfiledBinary.
  56.   static Expected<std::unique_ptr<RawMemProfReader>>
  57.   create(const Twine &Path, const StringRef ProfiledBinary,
  58.          bool KeepName = false);
  59.  
  60.   using GuidMemProfRecordPair = std::pair<GlobalValue::GUID, MemProfRecord>;
  61.   using Iterator = InstrProfIterator<GuidMemProfRecordPair, RawMemProfReader>;
  62.   Iterator end() { return Iterator(); }
  63.   Iterator begin() {
  64.     Iter = FunctionProfileData.begin();
  65.     return Iterator(this);
  66.   }
  67.  
  68.   Error readNextRecord(GuidMemProfRecordPair &GuidRecord);
  69.  
  70.   // The RawMemProfReader only holds memory profile information.
  71.   InstrProfKind getProfileKind() const { return InstrProfKind::MemProf; }
  72.  
  73.   // Constructor for unittests only.
  74.   RawMemProfReader(std::unique_ptr<llvm::symbolize::SymbolizableModule> Sym,
  75.                    llvm::SmallVectorImpl<SegmentEntry> &Seg,
  76.                    llvm::MapVector<uint64_t, MemInfoBlock> &Prof,
  77.                    CallStackMap &SM, bool KeepName = false)
  78.       : Symbolizer(std::move(Sym)), SegmentInfo(Seg.begin(), Seg.end()),
  79.         CallstackProfileData(Prof), StackMap(SM), KeepSymbolName(KeepName) {
  80.     // We don't call initialize here since there is no raw profile to read. The
  81.     // test should pass in the raw profile as structured data.
  82.  
  83.     // If there is an error here then the mock symbolizer has not been
  84.     // initialized properly.
  85.     if (Error E = symbolizeAndFilterStackFrames())
  86.       report_fatal_error(std::move(E));
  87.     if (Error E = mapRawProfileToRecords())
  88.       report_fatal_error(std::move(E));
  89.   }
  90.  
  91.   // Return a const reference to the internal Id to Frame mappings.
  92.   const llvm::DenseMap<FrameId, Frame> &getFrameMapping() const {
  93.     return IdToFrame;
  94.   }
  95.  
  96.   // Return a const reference to the internal function profile data.
  97.   const llvm::MapVector<GlobalValue::GUID, IndexedMemProfRecord> &
  98.   getProfileData() const {
  99.     return FunctionProfileData;
  100.   }
  101.  
  102. private:
  103.   RawMemProfReader(object::OwningBinary<object::Binary> &&Bin, bool KeepName)
  104.       : Binary(std::move(Bin)), KeepSymbolName(KeepName) {}
  105.   // Initializes the RawMemProfReader with the contents in `DataBuffer`.
  106.   Error initialize(std::unique_ptr<MemoryBuffer> DataBuffer);
  107.   // Read and parse the contents of the `DataBuffer` as a binary format profile.
  108.   Error readRawProfile(std::unique_ptr<MemoryBuffer> DataBuffer);
  109.   // Symbolize and cache all the virtual addresses we encounter in the
  110.   // callstacks from the raw profile. Also prune callstack frames which we can't
  111.   // symbolize or those that belong to the runtime. For profile entries where
  112.   // the entire callstack is pruned, we drop the entry from the profile.
  113.   Error symbolizeAndFilterStackFrames();
  114.   // Construct memprof records for each function and store it in the
  115.   // `FunctionProfileData` map. A function may have allocation profile data or
  116.   // callsite data or both.
  117.   Error mapRawProfileToRecords();
  118.  
  119.   // A helper method to extract the frame from the IdToFrame map.
  120.   const Frame &idToFrame(const FrameId Id) const {
  121.     auto It = IdToFrame.find(Id);
  122.     assert(It != IdToFrame.end() && "Id not found in map.");
  123.     return It->getSecond();
  124.   }
  125.  
  126.   object::SectionedAddress getModuleOffset(uint64_t VirtualAddress);
  127.  
  128.   object::OwningBinary<object::Binary> Binary;
  129.   std::unique_ptr<llvm::symbolize::SymbolizableModule> Symbolizer;
  130.  
  131.   // The contents of the raw profile.
  132.   llvm::SmallVector<SegmentEntry, 16> SegmentInfo;
  133.   // A map from callstack id (same as key in CallStackMap below) to the heap
  134.   // information recorded for that allocation context.
  135.   llvm::MapVector<uint64_t, MemInfoBlock> CallstackProfileData;
  136.   CallStackMap StackMap;
  137.  
  138.   // Cached symbolization from PC to Frame.
  139.   llvm::DenseMap<uint64_t, llvm::SmallVector<FrameId>> SymbolizedFrame;
  140.   llvm::DenseMap<FrameId, Frame> IdToFrame;
  141.  
  142.   llvm::MapVector<GlobalValue::GUID, IndexedMemProfRecord> FunctionProfileData;
  143.   llvm::MapVector<GlobalValue::GUID, IndexedMemProfRecord>::iterator Iter;
  144.  
  145.   // Whether to keep the symbol name for each frame after hashing.
  146.   bool KeepSymbolName = false;
  147.   // A mapping of the hash to symbol name, only used if KeepSymbolName is true.
  148.   llvm::DenseMap<uint64_t, std::string> GuidToSymbolName;
  149. };
  150. } // namespace memprof
  151. } // namespace llvm
  152.  
  153. #endif // LLVM_PROFILEDATA_RAWMEMPROFREADER_H_
  154.