BitstreamRemarkSerializer.h 8.1 KB

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