Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:25

0001 //===-- BitstreamRemarkSerializer.h - Bitstream serializer ------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file provides an implementation of the serializer using the LLVM
0010 // Bitstream format.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_REMARKS_BITSTREAMREMARKSERIALIZER_H
0015 #define LLVM_REMARKS_BITSTREAMREMARKSERIALIZER_H
0016 
0017 #include "llvm/Bitstream/BitstreamWriter.h"
0018 #include "llvm/Remarks/BitstreamRemarkContainer.h"
0019 #include "llvm/Remarks/RemarkSerializer.h"
0020 #include <optional>
0021 
0022 namespace llvm {
0023 namespace remarks {
0024 
0025 struct Remarks;
0026 
0027 /// Serialize the remarks to LLVM bitstream.
0028 /// This class provides ways to emit remarks in the LLVM bitstream format and
0029 /// its associated metadata.
0030 ///
0031 /// * The separate model:
0032 ///   Separate meta:        | Container info
0033 ///                         | String table
0034 ///                         | External file
0035 ///
0036 ///   Separate remarks:     | Container info
0037 ///                         | Remark version
0038 ///                         | Remark0
0039 ///                         | Remark1
0040 ///                         | Remark2
0041 ///                         | ...
0042 ///
0043 /// * The standalone model: | Container info
0044 ///                         | String table
0045 ///                         | Remark version
0046 ///                         | Remark0
0047 ///                         | Remark1
0048 ///                         | Remark2
0049 ///                         | ...
0050 ///
0051 struct BitstreamRemarkSerializerHelper {
0052   /// Buffer used for encoding the bitstream before writing it to the final
0053   /// stream.
0054   SmallVector<char, 1024> Encoded;
0055   /// Buffer used to construct records and pass to the bitstream writer.
0056   SmallVector<uint64_t, 64> R;
0057   /// The Bitstream writer.
0058   BitstreamWriter Bitstream;
0059   /// The type of the container we are serializing.
0060   BitstreamRemarkContainerType ContainerType;
0061 
0062   /// Abbrev IDs initialized in the block info block.
0063   /// Note: depending on the container type, some IDs might be uninitialized.
0064   /// Warning: When adding more abbrev IDs, make sure to update the
0065   /// BlockCodeSize (in the call to EnterSubblock).
0066   uint64_t RecordMetaContainerInfoAbbrevID = 0;
0067   uint64_t RecordMetaRemarkVersionAbbrevID = 0;
0068   uint64_t RecordMetaStrTabAbbrevID = 0;
0069   uint64_t RecordMetaExternalFileAbbrevID = 0;
0070   uint64_t RecordRemarkHeaderAbbrevID = 0;
0071   uint64_t RecordRemarkDebugLocAbbrevID = 0;
0072   uint64_t RecordRemarkHotnessAbbrevID = 0;
0073   uint64_t RecordRemarkArgWithDebugLocAbbrevID = 0;
0074   uint64_t RecordRemarkArgWithoutDebugLocAbbrevID = 0;
0075 
0076   BitstreamRemarkSerializerHelper(BitstreamRemarkContainerType ContainerType);
0077 
0078   // Disable copy and move: Bitstream points to Encoded, which needs special
0079   // handling during copy/move, but moving the vectors is probably useless
0080   // anyway.
0081   BitstreamRemarkSerializerHelper(const BitstreamRemarkSerializerHelper &) =
0082       delete;
0083   BitstreamRemarkSerializerHelper &
0084   operator=(const BitstreamRemarkSerializerHelper &) = delete;
0085   BitstreamRemarkSerializerHelper(BitstreamRemarkSerializerHelper &&) = delete;
0086   BitstreamRemarkSerializerHelper &
0087   operator=(BitstreamRemarkSerializerHelper &&) = delete;
0088 
0089   /// Set up the necessary block info entries according to the container type.
0090   void setupBlockInfo();
0091 
0092   /// Set up the block info for the metadata block.
0093   void setupMetaBlockInfo();
0094   /// The remark version in the metadata block.
0095   void setupMetaRemarkVersion();
0096   void emitMetaRemarkVersion(uint64_t RemarkVersion);
0097   /// The strtab in the metadata block.
0098   void setupMetaStrTab();
0099   void emitMetaStrTab(const StringTable &StrTab);
0100   /// The external file in the metadata block.
0101   void setupMetaExternalFile();
0102   void emitMetaExternalFile(StringRef Filename);
0103 
0104   /// The block info for the remarks block.
0105   void setupRemarkBlockInfo();
0106 
0107   /// Emit the metadata for the remarks.
0108   void emitMetaBlock(uint64_t ContainerVersion,
0109                      std::optional<uint64_t> RemarkVersion,
0110                      std::optional<const StringTable *> StrTab = std::nullopt,
0111                      std::optional<StringRef> Filename = std::nullopt);
0112 
0113   /// Emit a remark block. The string table is required.
0114   void emitRemarkBlock(const Remark &Remark, StringTable &StrTab);
0115   /// Finalize the writing to \p OS.
0116   void flushToStream(raw_ostream &OS);
0117   /// Finalize the writing to a buffer.
0118   /// The contents of the buffer remain valid for the lifetime of the object.
0119   /// Any call to any other function in this class will invalidate the buffer.
0120   StringRef getBuffer();
0121 };
0122 
0123 /// Implementation of the remark serializer using LLVM bitstream.
0124 struct BitstreamRemarkSerializer : public RemarkSerializer {
0125   /// The file should contain:
0126   /// 1) The block info block that describes how to read the blocks.
0127   /// 2) The metadata block that contains various information about the remarks
0128   ///    in the file.
0129   /// 3) A number of remark blocks.
0130 
0131   /// We need to set up 1) and 2) first, so that we can emit 3) after. This flag
0132   /// is used to emit the first two blocks only once.
0133   bool DidSetUp = false;
0134   /// The helper to emit bitstream.
0135   BitstreamRemarkSerializerHelper Helper;
0136 
0137   /// Construct a serializer that will create its own string table.
0138   BitstreamRemarkSerializer(raw_ostream &OS, SerializerMode Mode);
0139   /// Construct a serializer with a pre-filled string table.
0140   BitstreamRemarkSerializer(raw_ostream &OS, SerializerMode Mode,
0141                             StringTable StrTab);
0142 
0143   /// Emit a remark to the stream. This also emits the metadata associated to
0144   /// the remarks based on the SerializerMode specified at construction.
0145   /// This writes the serialized output to the provided stream.
0146   void emit(const Remark &Remark) override;
0147   /// The metadata serializer associated to this remark serializer. Based on the
0148   /// container type of the current serializer, the container type of the
0149   /// metadata serializer will change.
0150   std::unique_ptr<MetaSerializer> metaSerializer(
0151       raw_ostream &OS,
0152       std::optional<StringRef> ExternalFilename = std::nullopt) override;
0153 
0154   static bool classof(const RemarkSerializer *S) {
0155     return S->SerializerFormat == Format::Bitstream;
0156   }
0157 };
0158 
0159 /// Serializer of metadata for bitstream remarks.
0160 struct BitstreamMetaSerializer : public MetaSerializer {
0161   /// This class can be used with [1] a pre-constructed
0162   /// BitstreamRemarkSerializerHelper, or with [2] one that is owned by the meta
0163   /// serializer. In case of [1], we need to be able to store a reference to the
0164   /// object, while in case of [2] we need to store the whole object.
0165   std::optional<BitstreamRemarkSerializerHelper> TmpHelper;
0166   /// The actual helper, that can point to \p TmpHelper or to an external helper
0167   /// object.
0168   BitstreamRemarkSerializerHelper *Helper = nullptr;
0169 
0170   std::optional<const StringTable *> StrTab;
0171   std::optional<StringRef> ExternalFilename;
0172 
0173   /// Create a new meta serializer based on \p ContainerType.
0174   BitstreamMetaSerializer(
0175       raw_ostream &OS, BitstreamRemarkContainerType ContainerType,
0176       std::optional<const StringTable *> StrTab = std::nullopt,
0177       std::optional<StringRef> ExternalFilename = std::nullopt)
0178       : MetaSerializer(OS), TmpHelper(std::nullopt), Helper(nullptr),
0179         StrTab(StrTab), ExternalFilename(ExternalFilename) {
0180     TmpHelper.emplace(ContainerType);
0181     Helper = &*TmpHelper;
0182   }
0183 
0184   /// Create a new meta serializer based on a previously built \p Helper.
0185   BitstreamMetaSerializer(
0186       raw_ostream &OS, BitstreamRemarkSerializerHelper &Helper,
0187       std::optional<const StringTable *> StrTab = std::nullopt,
0188       std::optional<StringRef> ExternalFilename = std::nullopt)
0189       : MetaSerializer(OS), TmpHelper(std::nullopt), Helper(&Helper),
0190         StrTab(StrTab), ExternalFilename(ExternalFilename) {}
0191 
0192   void emit() override;
0193 };
0194 
0195 } // end namespace remarks
0196 } // end namespace llvm
0197 
0198 #endif // LLVM_REMARKS_BITSTREAMREMARKSERIALIZER_H