Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //===-- BitstreamRemarkSerializer.h - Bitstream serializer ------*- C++ -*-===//
  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 provides an implementation of the serializer using the LLVM
  10. // Bitstream format.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_REMARKS_BITSTREAMREMARKSERIALIZER_H
  15. #define LLVM_REMARKS_BITSTREAMREMARKSERIALIZER_H
  16.  
  17. #include "llvm/Bitstream/BitstreamWriter.h"
  18. #include "llvm/Remarks/BitstreamRemarkContainer.h"
  19. #include "llvm/Remarks/RemarkSerializer.h"
  20. #include <optional>
  21.  
  22. namespace llvm {
  23. namespace remarks {
  24.  
  25. struct Remarks;
  26.  
  27. /// Serialize the remarks to LLVM bitstream.
  28. /// This class provides ways to emit remarks in the LLVM bitstream format and
  29. /// its associated metadata.
  30. ///
  31. /// * The separate model:
  32. ///   Separate meta:        | Container info
  33. ///                         | String table
  34. ///                         | External file
  35. ///
  36. ///   Separate remarks:     | Container info
  37. ///                         | Remark version
  38. ///                         | Remark0
  39. ///                         | Remark1
  40. ///                         | Remark2
  41. ///                         | ...
  42. ///
  43. /// * The standalone model: | Container info
  44. ///                         | String table
  45. ///                         | Remark version
  46. ///                         | Remark0
  47. ///                         | Remark1
  48. ///                         | Remark2
  49. ///                         | ...
  50. ///
  51. struct BitstreamRemarkSerializerHelper {
  52.   /// Buffer used for encoding the bitstream before writing it to the final
  53.   /// stream.
  54.   SmallVector<char, 1024> Encoded;
  55.   /// Buffer used to construct records and pass to the bitstream writer.
  56.   SmallVector<uint64_t, 64> R;
  57.   /// The Bitstream writer.
  58.   BitstreamWriter Bitstream;
  59.   /// The type of the container we are serializing.
  60.   BitstreamRemarkContainerType ContainerType;
  61.  
  62.   /// Abbrev IDs initialized in the block info block.
  63.   /// Note: depending on the container type, some IDs might be uninitialized.
  64.   /// Warning: When adding more abbrev IDs, make sure to update the
  65.   /// BlockCodeSize (in the call to EnterSubblock).
  66.   uint64_t RecordMetaContainerInfoAbbrevID = 0;
  67.   uint64_t RecordMetaRemarkVersionAbbrevID = 0;
  68.   uint64_t RecordMetaStrTabAbbrevID = 0;
  69.   uint64_t RecordMetaExternalFileAbbrevID = 0;
  70.   uint64_t RecordRemarkHeaderAbbrevID = 0;
  71.   uint64_t RecordRemarkDebugLocAbbrevID = 0;
  72.   uint64_t RecordRemarkHotnessAbbrevID = 0;
  73.   uint64_t RecordRemarkArgWithDebugLocAbbrevID = 0;
  74.   uint64_t RecordRemarkArgWithoutDebugLocAbbrevID = 0;
  75.  
  76.   BitstreamRemarkSerializerHelper(BitstreamRemarkContainerType ContainerType);
  77.  
  78.   // Disable copy and move: Bitstream points to Encoded, which needs special
  79.   // handling during copy/move, but moving the vectors is probably useless
  80.   // anyway.
  81.   BitstreamRemarkSerializerHelper(const BitstreamRemarkSerializerHelper &) =
  82.       delete;
  83.   BitstreamRemarkSerializerHelper &
  84.   operator=(const BitstreamRemarkSerializerHelper &) = delete;
  85.   BitstreamRemarkSerializerHelper(BitstreamRemarkSerializerHelper &&) = delete;
  86.   BitstreamRemarkSerializerHelper &
  87.   operator=(BitstreamRemarkSerializerHelper &&) = delete;
  88.  
  89.   /// Set up the necessary block info entries according to the container type.
  90.   void setupBlockInfo();
  91.  
  92.   /// Set up the block info for the metadata block.
  93.   void setupMetaBlockInfo();
  94.   /// The remark version in the metadata block.
  95.   void setupMetaRemarkVersion();
  96.   void emitMetaRemarkVersion(uint64_t RemarkVersion);
  97.   /// The strtab in the metadata block.
  98.   void setupMetaStrTab();
  99.   void emitMetaStrTab(const StringTable &StrTab);
  100.   /// The external file in the metadata block.
  101.   void setupMetaExternalFile();
  102.   void emitMetaExternalFile(StringRef Filename);
  103.  
  104.   /// The block info for the remarks block.
  105.   void setupRemarkBlockInfo();
  106.  
  107.   /// Emit the metadata for the remarks.
  108.   void emitMetaBlock(uint64_t ContainerVersion,
  109.                      std::optional<uint64_t> RemarkVersion,
  110.                      std::optional<const StringTable *> StrTab = std::nullopt,
  111.                      std::optional<StringRef> Filename = std::nullopt);
  112.  
  113.   /// Emit a remark block. The string table is required.
  114.   void emitRemarkBlock(const Remark &Remark, StringTable &StrTab);
  115.   /// Finalize the writing to \p OS.
  116.   void flushToStream(raw_ostream &OS);
  117.   /// Finalize the writing to a buffer.
  118.   /// The contents of the buffer remain valid for the lifetime of the object.
  119.   /// Any call to any other function in this class will invalidate the buffer.
  120.   StringRef getBuffer();
  121. };
  122.  
  123. /// Implementation of the remark serializer using LLVM bitstream.
  124. struct BitstreamRemarkSerializer : public RemarkSerializer {
  125.   /// The file should contain:
  126.   /// 1) The block info block that describes how to read the blocks.
  127.   /// 2) The metadata block that contains various information about the remarks
  128.   ///    in the file.
  129.   /// 3) A number of remark blocks.
  130.  
  131.   /// We need to set up 1) and 2) first, so that we can emit 3) after. This flag
  132.   /// is used to emit the first two blocks only once.
  133.   bool DidSetUp = false;
  134.   /// The helper to emit bitstream.
  135.   BitstreamRemarkSerializerHelper Helper;
  136.  
  137.   /// Construct a serializer that will create its own string table.
  138.   BitstreamRemarkSerializer(raw_ostream &OS, SerializerMode Mode);
  139.   /// Construct a serializer with a pre-filled string table.
  140.   BitstreamRemarkSerializer(raw_ostream &OS, SerializerMode Mode,
  141.                             StringTable StrTab);
  142.  
  143.   /// Emit a remark to the stream. This also emits the metadata associated to
  144.   /// the remarks based on the SerializerMode specified at construction.
  145.   /// This writes the serialized output to the provided stream.
  146.   void emit(const Remark &Remark) override;
  147.   /// The metadata serializer associated to this remark serializer. Based on the
  148.   /// container type of the current serializer, the container type of the
  149.   /// metadata serializer will change.
  150.   std::unique_ptr<MetaSerializer> metaSerializer(
  151.       raw_ostream &OS,
  152.       std::optional<StringRef> ExternalFilename = std::nullopt) override;
  153.  
  154.   static bool classof(const RemarkSerializer *S) {
  155.     return S->SerializerFormat == Format::Bitstream;
  156.   }
  157. };
  158.  
  159. /// Serializer of metadata for bitstream remarks.
  160. struct BitstreamMetaSerializer : public MetaSerializer {
  161.   /// This class can be used with [1] a pre-constructed
  162.   /// BitstreamRemarkSerializerHelper, or with [2] one that is owned by the meta
  163.   /// serializer. In case of [1], we need to be able to store a reference to the
  164.   /// object, while in case of [2] we need to store the whole object.
  165.   std::optional<BitstreamRemarkSerializerHelper> TmpHelper;
  166.   /// The actual helper, that can point to \p TmpHelper or to an external helper
  167.   /// object.
  168.   BitstreamRemarkSerializerHelper *Helper = nullptr;
  169.  
  170.   std::optional<const StringTable *> StrTab;
  171.   std::optional<StringRef> ExternalFilename;
  172.  
  173.   /// Create a new meta serializer based on \p ContainerType.
  174.   BitstreamMetaSerializer(
  175.       raw_ostream &OS, BitstreamRemarkContainerType ContainerType,
  176.       std::optional<const StringTable *> StrTab = std::nullopt,
  177.       std::optional<StringRef> ExternalFilename = std::nullopt)
  178.       : MetaSerializer(OS), TmpHelper(std::nullopt), Helper(nullptr),
  179.         StrTab(StrTab), ExternalFilename(ExternalFilename) {
  180.     TmpHelper.emplace(ContainerType);
  181.     Helper = &*TmpHelper;
  182.   }
  183.  
  184.   /// Create a new meta serializer based on a previously built \p Helper.
  185.   BitstreamMetaSerializer(
  186.       raw_ostream &OS, BitstreamRemarkSerializerHelper &Helper,
  187.       std::optional<const StringTable *> StrTab = std::nullopt,
  188.       std::optional<StringRef> ExternalFilename = std::nullopt)
  189.       : MetaSerializer(OS), TmpHelper(std::nullopt), Helper(&Helper),
  190.         StrTab(StrTab), ExternalFilename(ExternalFilename) {}
  191.  
  192.   void emit() override;
  193. };
  194.  
  195. } // end namespace remarks
  196. } // end namespace llvm
  197.  
  198. #endif // LLVM_REMARKS_BITSTREAMREMARKSERIALIZER_H
  199.