diff options
author | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
---|---|---|
committer | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
commit | 6ffe9e53658409f212834330e13564e4952558f6 (patch) | |
tree | 85b1e00183517648b228aafa7c8fb07f5276f419 /contrib/libs/llvm14/include/llvm/Remarks | |
parent | 726057070f9c5a91fc10fde0d5024913d10f1ab9 (diff) | |
download | ydb-6ffe9e53658409f212834330e13564e4952558f6.tar.gz |
YQ Connector: support managed ClickHouse
Со стороны dqrun можно обратиться к инстансу коннектора, который работает на streaming стенде, и извлечь данные из облачного CH.
Diffstat (limited to 'contrib/libs/llvm14/include/llvm/Remarks')
12 files changed, 1372 insertions, 0 deletions
diff --git a/contrib/libs/llvm14/include/llvm/Remarks/BitstreamRemarkContainer.h b/contrib/libs/llvm14/include/llvm/Remarks/BitstreamRemarkContainer.h new file mode 100644 index 0000000000..4872206ebe --- /dev/null +++ b/contrib/libs/llvm14/include/llvm/Remarks/BitstreamRemarkContainer.h @@ -0,0 +1,117 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-- BitstreamRemarkContainer.h - Container for remarks --------------*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides declarations for things used in the various types of +// remark containers. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_REMARKS_BITSTREAMREMARKCONTAINER_H +#define LLVM_REMARKS_BITSTREAMREMARKCONTAINER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Bitstream/BitCodes.h" +#include <cstdint> + +namespace llvm { +namespace remarks { + +/// The current version of the remark container. +/// Note: this is different from the version of the remark entry. +constexpr uint64_t CurrentContainerVersion = 0; +/// The magic number used for identifying remark blocks. +constexpr StringLiteral ContainerMagic("RMRK"); + +/// Type of the remark container. +/// The remark container has two modes: +/// * separate: the metadata is separate from the remarks and points to the +/// auxiliary file that contains the remarks. +/// * standalone: the metadata and the remarks are emitted together. +enum class BitstreamRemarkContainerType { + /// The metadata emitted separately. + /// This will contain the following: + /// * Container version and type + /// * String table + /// * External file + SeparateRemarksMeta, + /// The remarks emitted separately. + /// This will contain the following: + /// * Container version and type + /// * Remark version + SeparateRemarksFile, + /// Everything is emitted together. + /// This will contain the following: + /// * Container version and type + /// * Remark version + /// * String table + Standalone, + First = SeparateRemarksMeta, + Last = Standalone, +}; + +/// The possible blocks that will be encountered in a bitstream remark +/// container. +enum BlockIDs { + /// The metadata block is mandatory. It should always come after the + /// BLOCKINFO_BLOCK, and contains metadata that should be used when parsing + /// REMARK_BLOCKs. + /// There should always be only one META_BLOCK. + META_BLOCK_ID = bitc::FIRST_APPLICATION_BLOCKID, + /// One remark entry is represented using a REMARK_BLOCK. There can be + /// multiple REMARK_BLOCKs in the same file. + REMARK_BLOCK_ID +}; + +constexpr StringRef MetaBlockName = StringRef("Meta", 4); +constexpr StringRef RemarkBlockName = StringRef("Remark", 6); + +/// The possible records that can be encountered in the previously described +/// blocks. +enum RecordIDs { + // Meta block records. + RECORD_META_CONTAINER_INFO = 1, + RECORD_META_REMARK_VERSION, + RECORD_META_STRTAB, + RECORD_META_EXTERNAL_FILE, + // Remark block records. + RECORD_REMARK_HEADER, + RECORD_REMARK_DEBUG_LOC, + RECORD_REMARK_HOTNESS, + RECORD_REMARK_ARG_WITH_DEBUGLOC, + RECORD_REMARK_ARG_WITHOUT_DEBUGLOC, + // Helpers. + RECORD_FIRST = RECORD_META_CONTAINER_INFO, + RECORD_LAST = RECORD_REMARK_ARG_WITHOUT_DEBUGLOC +}; + +constexpr StringRef MetaContainerInfoName = StringRef("Container info", 14); +constexpr StringRef MetaRemarkVersionName = StringRef("Remark version", 14); +constexpr StringRef MetaStrTabName = StringRef("String table", 12); +constexpr StringRef MetaExternalFileName = StringRef("External File", 13); +constexpr StringRef RemarkHeaderName = StringRef("Remark header", 13); +constexpr StringRef RemarkDebugLocName = StringRef("Remark debug location", 21); +constexpr StringRef RemarkHotnessName = StringRef("Remark hotness", 14); +constexpr StringRef RemarkArgWithDebugLocName = + StringRef("Argument with debug location", 28); +constexpr StringRef RemarkArgWithoutDebugLocName = StringRef("Argument", 8); + +} // end namespace remarks +} // end namespace llvm + +#endif // LLVM_REMARKS_BITSTREAMREMARKCONTAINER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm14/include/llvm/Remarks/BitstreamRemarkParser.h b/contrib/libs/llvm14/include/llvm/Remarks/BitstreamRemarkParser.h new file mode 100644 index 0000000000..8a31c76064 --- /dev/null +++ b/contrib/libs/llvm14/include/llvm/Remarks/BitstreamRemarkParser.h @@ -0,0 +1,127 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-- BitstreamRemarkParser.h - Bitstream parser --------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides an implementation of the remark parser using the LLVM +// Bitstream format. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_REMARKS_BITSTREAMREMARKPARSER_H +#define LLVM_REMARKS_BITSTREAMREMARKPARSER_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Bitstream/BitstreamReader.h" +#include "llvm/Support/Error.h" +#include <array> +#include <cstdint> + +namespace llvm { +namespace remarks { + +/// Helper to parse a META_BLOCK for a bitstream remark container. +struct BitstreamMetaParserHelper { + /// The Bitstream reader. + BitstreamCursor &Stream; + /// Reference to the storage for the block info. + BitstreamBlockInfo &BlockInfo; + /// The parsed content: depending on the container type, some fields might be + /// empty. + Optional<uint64_t> ContainerVersion; + Optional<uint8_t> ContainerType; + Optional<StringRef> StrTabBuf; + Optional<StringRef> ExternalFilePath; + Optional<uint64_t> RemarkVersion; + + /// Continue parsing with \p Stream. \p Stream is expected to contain a + /// ENTER_SUBBLOCK to the META_BLOCK at the current position. + /// \p Stream is expected to have a BLOCKINFO_BLOCK set. + BitstreamMetaParserHelper(BitstreamCursor &Stream, + BitstreamBlockInfo &BlockInfo); + + /// Parse the META_BLOCK and fill the available entries. + /// This helper does not check for the validity of the fields. + Error parse(); +}; + +/// Helper to parse a REMARK_BLOCK for a bitstream remark container. +struct BitstreamRemarkParserHelper { + /// The Bitstream reader. + BitstreamCursor &Stream; + /// The parsed content: depending on the remark, some fields might be empty. + Optional<uint8_t> Type; + Optional<uint64_t> RemarkNameIdx; + Optional<uint64_t> PassNameIdx; + Optional<uint64_t> FunctionNameIdx; + Optional<uint64_t> SourceFileNameIdx; + Optional<uint32_t> SourceLine; + Optional<uint32_t> SourceColumn; + Optional<uint64_t> Hotness; + struct Argument { + Optional<uint64_t> KeyIdx; + Optional<uint64_t> ValueIdx; + Optional<uint64_t> SourceFileNameIdx; + Optional<uint32_t> SourceLine; + Optional<uint32_t> SourceColumn; + }; + Optional<ArrayRef<Argument>> Args; + /// Avoid re-allocating a vector every time. + SmallVector<Argument, 8> TmpArgs; + + /// Continue parsing with \p Stream. \p Stream is expected to contain a + /// ENTER_SUBBLOCK to the REMARK_BLOCK at the current position. + /// \p Stream is expected to have a BLOCKINFO_BLOCK set and to have already + /// parsed the META_BLOCK. + BitstreamRemarkParserHelper(BitstreamCursor &Stream); + + /// Parse the REMARK_BLOCK and fill the available entries. + /// This helper does not check for the validity of the fields. + Error parse(); +}; + +/// Helper to parse any bitstream remark container. +struct BitstreamParserHelper { + /// The Bitstream reader. + BitstreamCursor Stream; + /// The block info block. + BitstreamBlockInfo BlockInfo; + /// Start parsing at \p Buffer. + BitstreamParserHelper(StringRef Buffer); + /// Parse the magic number. + Expected<std::array<char, 4>> parseMagic(); + /// Parse the block info block containing all the abbrevs. + /// This needs to be called before calling any other parsing function. + Error parseBlockInfoBlock(); + /// Return true if the next block is a META_BLOCK. This function does not move + /// the cursor. + Expected<bool> isMetaBlock(); + /// Return true if the next block is a REMARK_BLOCK. This function does not + /// move the cursor. + Expected<bool> isRemarkBlock(); + /// Return true if the parser reached the end of the stream. + bool atEndOfStream() { return Stream.AtEndOfStream(); } + /// Jump to the end of the stream, skipping everything. + void skipToEnd() { return Stream.skipToEnd(); } +}; + +} // end namespace remarks +} // end namespace llvm + +#endif // LLVM_REMARKS_BITSTREAMREMARKPARSER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm14/include/llvm/Remarks/BitstreamRemarkSerializer.h b/contrib/libs/llvm14/include/llvm/Remarks/BitstreamRemarkSerializer.h new file mode 100644 index 0000000000..067b694eb0 --- /dev/null +++ b/contrib/libs/llvm14/include/llvm/Remarks/BitstreamRemarkSerializer.h @@ -0,0 +1,208 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-- BitstreamRemarkSerializer.h - Bitstream serializer ------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides an implementation of the serializer using the LLVM +// Bitstream format. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_REMARKS_BITSTREAMREMARKSERIALIZER_H +#define LLVM_REMARKS_BITSTREAMREMARKSERIALIZER_H + +#include "llvm/Bitstream/BitstreamWriter.h" +#include "llvm/Remarks/BitstreamRemarkContainer.h" +#include "llvm/Remarks/RemarkSerializer.h" + +namespace llvm { +namespace remarks { + +struct Remarks; + +/// Serialize the remarks to LLVM bitstream. +/// This class provides ways to emit remarks in the LLVM bitstream format and +/// its associated metadata. +/// +/// * The separate model: +/// Separate meta: | Container info +/// | String table +/// | External file +/// +/// Separate remarks: | Container info +/// | Remark version +/// | Remark0 +/// | Remark1 +/// | Remark2 +/// | ... +/// +/// * The standalone model: | Container info +/// | String table +/// | Remark version +/// | Remark0 +/// | Remark1 +/// | Remark2 +/// | ... +/// +struct BitstreamRemarkSerializerHelper { + /// Buffer used for encoding the bitstream before writing it to the final + /// stream. + SmallVector<char, 1024> Encoded; + /// Buffer used to construct records and pass to the bitstream writer. + SmallVector<uint64_t, 64> R; + /// The Bitstream writer. + BitstreamWriter Bitstream; + /// The type of the container we are serializing. + BitstreamRemarkContainerType ContainerType; + + /// Abbrev IDs initialized in the block info block. + /// Note: depending on the container type, some IDs might be uninitialized. + /// Warning: When adding more abbrev IDs, make sure to update the + /// BlockCodeSize (in the call to EnterSubblock). + uint64_t RecordMetaContainerInfoAbbrevID = 0; + uint64_t RecordMetaRemarkVersionAbbrevID = 0; + uint64_t RecordMetaStrTabAbbrevID = 0; + uint64_t RecordMetaExternalFileAbbrevID = 0; + uint64_t RecordRemarkHeaderAbbrevID = 0; + uint64_t RecordRemarkDebugLocAbbrevID = 0; + uint64_t RecordRemarkHotnessAbbrevID = 0; + uint64_t RecordRemarkArgWithDebugLocAbbrevID = 0; + uint64_t RecordRemarkArgWithoutDebugLocAbbrevID = 0; + + BitstreamRemarkSerializerHelper(BitstreamRemarkContainerType ContainerType); + + // Disable copy and move: Bitstream points to Encoded, which needs special + // handling during copy/move, but moving the vectors is probably useless + // anyway. + BitstreamRemarkSerializerHelper(const BitstreamRemarkSerializerHelper &) = + delete; + BitstreamRemarkSerializerHelper & + operator=(const BitstreamRemarkSerializerHelper &) = delete; + BitstreamRemarkSerializerHelper(BitstreamRemarkSerializerHelper &&) = delete; + BitstreamRemarkSerializerHelper & + operator=(BitstreamRemarkSerializerHelper &&) = delete; + + /// Set up the necessary block info entries according to the container type. + void setupBlockInfo(); + + /// Set up the block info for the metadata block. + void setupMetaBlockInfo(); + /// The remark version in the metadata block. + void setupMetaRemarkVersion(); + void emitMetaRemarkVersion(uint64_t RemarkVersion); + /// The strtab in the metadata block. + void setupMetaStrTab(); + void emitMetaStrTab(const StringTable &StrTab); + /// The external file in the metadata block. + void setupMetaExternalFile(); + void emitMetaExternalFile(StringRef Filename); + + /// The block info for the remarks block. + void setupRemarkBlockInfo(); + + /// Emit the metadata for the remarks. + void emitMetaBlock(uint64_t ContainerVersion, + Optional<uint64_t> RemarkVersion, + Optional<const StringTable *> StrTab = None, + Optional<StringRef> Filename = None); + + /// Emit a remark block. The string table is required. + void emitRemarkBlock(const Remark &Remark, StringTable &StrTab); + /// Finalize the writing to \p OS. + void flushToStream(raw_ostream &OS); + /// Finalize the writing to a buffer. + /// The contents of the buffer remain valid for the lifetime of the object. + /// Any call to any other function in this class will invalidate the buffer. + StringRef getBuffer(); +}; + +/// Implementation of the remark serializer using LLVM bitstream. +struct BitstreamRemarkSerializer : public RemarkSerializer { + /// The file should contain: + /// 1) The block info block that describes how to read the blocks. + /// 2) The metadata block that contains various information about the remarks + /// in the file. + /// 3) A number of remark blocks. + + /// We need to set up 1) and 2) first, so that we can emit 3) after. This flag + /// is used to emit the first two blocks only once. + bool DidSetUp = false; + /// The helper to emit bitstream. + BitstreamRemarkSerializerHelper Helper; + + /// Construct a serializer that will create its own string table. + BitstreamRemarkSerializer(raw_ostream &OS, SerializerMode Mode); + /// Construct a serializer with a pre-filled string table. + BitstreamRemarkSerializer(raw_ostream &OS, SerializerMode Mode, + StringTable StrTab); + + /// Emit a remark to the stream. This also emits the metadata associated to + /// the remarks based on the SerializerMode specified at construction. + /// This writes the serialized output to the provided stream. + void emit(const Remark &Remark) override; + /// The metadata serializer associated to this remark serializer. Based on the + /// container type of the current serializer, the container type of the + /// metadata serializer will change. + std::unique_ptr<MetaSerializer> + metaSerializer(raw_ostream &OS, + Optional<StringRef> ExternalFilename = None) override; + + static bool classof(const RemarkSerializer *S) { + return S->SerializerFormat == Format::Bitstream; + } +}; + +/// Serializer of metadata for bitstream remarks. +struct BitstreamMetaSerializer : public MetaSerializer { + /// This class can be used with [1] a pre-constructed + /// BitstreamRemarkSerializerHelper, or with [2] one that is owned by the meta + /// serializer. In case of [1], we need to be able to store a reference to the + /// object, while in case of [2] we need to store the whole object. + Optional<BitstreamRemarkSerializerHelper> TmpHelper; + /// The actual helper, that can point to \p TmpHelper or to an external helper + /// object. + BitstreamRemarkSerializerHelper *Helper = nullptr; + + Optional<const StringTable *> StrTab; + Optional<StringRef> ExternalFilename; + + /// Create a new meta serializer based on \p ContainerType. + BitstreamMetaSerializer(raw_ostream &OS, + BitstreamRemarkContainerType ContainerType, + Optional<const StringTable *> StrTab = None, + Optional<StringRef> ExternalFilename = None) + : MetaSerializer(OS), TmpHelper(None), Helper(nullptr), StrTab(StrTab), + ExternalFilename(ExternalFilename) { + TmpHelper.emplace(ContainerType); + Helper = &*TmpHelper; + } + + /// Create a new meta serializer based on a previously built \p Helper. + BitstreamMetaSerializer(raw_ostream &OS, + BitstreamRemarkSerializerHelper &Helper, + Optional<const StringTable *> StrTab = None, + Optional<StringRef> ExternalFilename = None) + : MetaSerializer(OS), TmpHelper(None), Helper(&Helper), StrTab(StrTab), + ExternalFilename(ExternalFilename) {} + + void emit() override; +}; + +} // end namespace remarks +} // end namespace llvm + +#endif // LLVM_REMARKS_BITSTREAMREMARKSERIALIZER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm14/include/llvm/Remarks/HotnessThresholdParser.h b/contrib/libs/llvm14/include/llvm/Remarks/HotnessThresholdParser.h new file mode 100644 index 0000000000..1d53f5eea5 --- /dev/null +++ b/contrib/libs/llvm14/include/llvm/Remarks/HotnessThresholdParser.h @@ -0,0 +1,74 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- HotnessThresholdParser.h - Parser for hotness threshold --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file implements a simple parser to decode commandline option for +/// remarks hotness threshold that supports both int and a special 'auto' value. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_REMARKS_HOTNESSTHRESHOLDPARSER_H +#define LLVM_REMARKS_HOTNESSTHRESHOLDPARSER_H + +#include "llvm/ADT/Optional.h" +#include "llvm/Support/CommandLine.h" + +namespace llvm { +namespace remarks { + +// Parse remarks hotness threshold argument value. +// Valid option values are +// 1. integer: manually specified threshold; or +// 2. string 'auto': automatically get threshold from profile summary. +// +// Return None Optional if 'auto' is specified, indicating the value will +// be filled later during PSI. +inline Expected<Optional<uint64_t>> parseHotnessThresholdOption(StringRef Arg) { + if (Arg == "auto") + return None; + + int64_t Val; + if (Arg.getAsInteger(10, Val)) + return createStringError(llvm::inconvertibleErrorCode(), + "Not an integer: %s", Arg.data()); + + // Negative integer effectively means no threshold + return Val < 0 ? 0 : Val; +} + +// A simple CL parser for '*-remarks-hotness-threshold=' +class HotnessThresholdParser : public cl::parser<Optional<uint64_t>> { +public: + HotnessThresholdParser(cl::Option &O) : cl::parser<Optional<uint64_t>>(O) {} + + bool parse(cl::Option &O, StringRef ArgName, StringRef Arg, + Optional<uint64_t> &V) { + auto ResultOrErr = parseHotnessThresholdOption(Arg); + if (!ResultOrErr) + return O.error("Invalid argument '" + Arg + + "', only integer or 'auto' is supported."); + + V = *ResultOrErr; + return false; + } +}; + +} // namespace remarks +} // namespace llvm +#endif // LLVM_REMARKS_HOTNESSTHRESHOLDPARSER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm14/include/llvm/Remarks/Remark.h b/contrib/libs/llvm14/include/llvm/Remarks/Remark.h new file mode 100644 index 0000000000..93872cb1a0 --- /dev/null +++ b/contrib/libs/llvm14/include/llvm/Remarks/Remark.h @@ -0,0 +1,188 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-- llvm/Remarks/Remark.h - The remark type -----------------*- C++/-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines an abstraction for handling remarks. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_REMARKS_REMARK_H +#define LLVM_REMARKS_REMARK_H + +#include "llvm-c/Remarks.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/CBindingWrapping.h" +#include <string> + +namespace llvm { +namespace remarks { + +/// The current version of the remark entry. +constexpr uint64_t CurrentRemarkVersion = 0; + +/// The debug location used to track a remark back to the source file. +struct RemarkLocation { + /// Absolute path of the source file corresponding to this remark. + StringRef SourceFilePath; + unsigned SourceLine = 0; + unsigned SourceColumn = 0; +}; + +// Create wrappers for C Binding types (see CBindingWrapping.h). +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(RemarkLocation, LLVMRemarkDebugLocRef) + +/// A key-value pair with a debug location that is used to display the remarks +/// at the right place in the source. +struct Argument { + StringRef Key; + // FIXME: We might want to be able to store other types than strings here. + StringRef Val; + // If set, the debug location corresponding to the value. + Optional<RemarkLocation> Loc; +}; + +// Create wrappers for C Binding types (see CBindingWrapping.h). +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Argument, LLVMRemarkArgRef) + +/// The type of the remark. +enum class Type { + Unknown, + Passed, + Missed, + Analysis, + AnalysisFPCommute, + AnalysisAliasing, + Failure, + First = Unknown, + Last = Failure +}; + +/// A remark type used for both emission and parsing. +struct Remark { + /// The type of the remark. + Type RemarkType = Type::Unknown; + + /// Name of the pass that triggers the emission of this remark. + StringRef PassName; + + /// Textual identifier for the remark (single-word, camel-case). Can be used + /// by external tools reading the output file for remarks to identify the + /// remark. + StringRef RemarkName; + + /// Mangled name of the function that triggers the emssion of this remark. + StringRef FunctionName; + + /// The location in the source file of the remark. + Optional<RemarkLocation> Loc; + + /// If profile information is available, this is the number of times the + /// corresponding code was executed in a profile instrumentation run. + Optional<uint64_t> Hotness; + + /// Arguments collected via the streaming interface. + SmallVector<Argument, 5> Args; + + Remark() = default; + Remark(Remark &&) = default; + Remark &operator=(Remark &&) = default; + + /// Return a message composed from the arguments as a string. + std::string getArgsAsMsg() const; + + /// Clone this remark to explicitly ask for a copy. + Remark clone() const { return *this; } + +private: + /// In order to avoid unwanted copies, "delete" the copy constructor. + /// If a copy is needed, it should be done through `Remark::clone()`. + Remark(const Remark &) = default; + Remark& operator=(const Remark &) = default; +}; + +// Create wrappers for C Binding types (see CBindingWrapping.h). +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Remark, LLVMRemarkEntryRef) + +/// Comparison operators for Remark objects and dependent objects. + +template <typename T> +bool operator<(const Optional<T> &LHS, const Optional<T> &RHS) { + // Sorting based on optionals should result in all `None` entries to appear + // before the valid entries. For example, remarks with no debug location will + // appear first. + if (!LHS && !RHS) + return false; + if (!LHS && RHS) + return true; + if (LHS && !RHS) + return false; + return *LHS < *RHS; +} + +inline bool operator==(const RemarkLocation &LHS, const RemarkLocation &RHS) { + return LHS.SourceFilePath == RHS.SourceFilePath && + LHS.SourceLine == RHS.SourceLine && + LHS.SourceColumn == RHS.SourceColumn; +} + +inline bool operator!=(const RemarkLocation &LHS, const RemarkLocation &RHS) { + return !(LHS == RHS); +} + +inline bool operator<(const RemarkLocation &LHS, const RemarkLocation &RHS) { + return std::make_tuple(LHS.SourceFilePath, LHS.SourceLine, LHS.SourceColumn) < + std::make_tuple(RHS.SourceFilePath, RHS.SourceLine, RHS.SourceColumn); +} + +inline bool operator==(const Argument &LHS, const Argument &RHS) { + return LHS.Key == RHS.Key && LHS.Val == RHS.Val && LHS.Loc == RHS.Loc; +} + +inline bool operator!=(const Argument &LHS, const Argument &RHS) { + return !(LHS == RHS); +} + +inline bool operator<(const Argument &LHS, const Argument &RHS) { + return std::make_tuple(LHS.Key, LHS.Val, LHS.Loc) < + std::make_tuple(RHS.Key, RHS.Val, RHS.Loc); +} + +inline bool operator==(const Remark &LHS, const Remark &RHS) { + return LHS.RemarkType == RHS.RemarkType && LHS.PassName == RHS.PassName && + LHS.RemarkName == RHS.RemarkName && + LHS.FunctionName == RHS.FunctionName && LHS.Loc == RHS.Loc && + LHS.Hotness == RHS.Hotness && LHS.Args == RHS.Args; +} + +inline bool operator!=(const Remark &LHS, const Remark &RHS) { + return !(LHS == RHS); +} + +inline bool operator<(const Remark &LHS, const Remark &RHS) { + return std::make_tuple(LHS.RemarkType, LHS.PassName, LHS.RemarkName, + LHS.FunctionName, LHS.Loc, LHS.Hotness, LHS.Args) < + std::make_tuple(RHS.RemarkType, RHS.PassName, RHS.RemarkName, + RHS.FunctionName, RHS.Loc, RHS.Hotness, RHS.Args); +} + +} // end namespace remarks +} // end namespace llvm + +#endif /* LLVM_REMARKS_REMARK_H */ + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm14/include/llvm/Remarks/RemarkFormat.h b/contrib/libs/llvm14/include/llvm/Remarks/RemarkFormat.h new file mode 100644 index 0000000000..1e87aece40 --- /dev/null +++ b/contrib/libs/llvm14/include/llvm/Remarks/RemarkFormat.h @@ -0,0 +1,47 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-- llvm/Remarks/RemarkFormat.h - The format of remarks -----*- C++/-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines utilities to deal with the format of remarks. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_REMARKS_REMARKFORMAT_H +#define LLVM_REMARKS_REMARKFORMAT_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" + +namespace llvm { +namespace remarks { + +constexpr StringLiteral Magic("REMARKS"); + +/// The format used for serializing/deserializing remarks. +enum class Format { Unknown, YAML, YAMLStrTab, Bitstream }; + +/// Parse and validate a string for the remark format. +Expected<Format> parseFormat(StringRef FormatStr); + +/// Parse and validate a magic number to a remark format. +Expected<Format> magicToFormat(StringRef Magic); + +} // end namespace remarks +} // end namespace llvm + +#endif // LLVM_REMARKS_REMARKFORMAT_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm14/include/llvm/Remarks/RemarkLinker.h b/contrib/libs/llvm14/include/llvm/Remarks/RemarkLinker.h new file mode 100644 index 0000000000..a9b08bc09b --- /dev/null +++ b/contrib/libs/llvm14/include/llvm/Remarks/RemarkLinker.h @@ -0,0 +1,114 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-- llvm/Remarks/RemarkLinker.h -----------------------------*- C++/-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides an interface to link together multiple remark files. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_REMARKS_REMARKLINKER_H +#define LLVM_REMARKS_REMARKLINKER_H + +#include "llvm/Remarks/Remark.h" +#include "llvm/Remarks/RemarkFormat.h" +#include "llvm/Remarks/RemarkStringTable.h" +#include "llvm/Support/Error.h" +#include <memory> +#include <set> + +namespace llvm { + +namespace object { +class ObjectFile; +} + +namespace remarks { + +struct RemarkLinker { +private: + /// Compare through the pointers. + struct RemarkPtrCompare { + bool operator()(const std::unique_ptr<Remark> &LHS, + const std::unique_ptr<Remark> &RHS) const { + assert(LHS && RHS && "Invalid pointers to compare."); + return *LHS < *RHS; + }; + }; + + /// The main string table for the remarks. + /// Note: all remarks should use the strings from this string table to avoid + /// dangling references. + StringTable StrTab; + + /// A set holding unique remarks. + /// FIXME: std::set is probably not the most appropriate data structure here. + /// Due to the limitation of having a move-only key, there isn't another + /// obvious choice for now. + std::set<std::unique_ptr<Remark>, RemarkPtrCompare> Remarks; + + /// A path to append before the external file path found in remark metadata. + Optional<std::string> PrependPath; + + /// Keep this remark. If it's already in the set, discard it. + Remark &keep(std::unique_ptr<Remark> Remark); + +public: + /// Set a path to prepend to the external file path. + void setExternalFilePrependPath(StringRef PrependPath); + + /// Link the remarks found in \p Buffer. + /// If \p RemarkFormat is not provided, try to deduce it from the metadata in + /// \p Buffer. + /// \p Buffer can be either a standalone remark container or just + /// metadata. This takes care of uniquing and merging the remarks. + Error link(StringRef Buffer, Optional<Format> RemarkFormat = None); + + /// Link the remarks found in \p Obj by looking for the right section and + /// calling the method above. + Error link(const object::ObjectFile &Obj, + Optional<Format> RemarkFormat = None); + + /// Serialize the linked remarks to the stream \p OS, using the format \p + /// RemarkFormat. + /// This clears internal state such as the string table. + /// Note: this implies that the serialization mode is standalone. + Error serialize(raw_ostream &OS, Format RemarksFormat) const; + + /// Check whether there are any remarks linked. + bool empty() const { return Remarks.empty(); } + + /// Return a collection of the linked unique remarks to iterate on. + /// Ex: + /// for (const Remark &R : RL.remarks() { [...] } + using iterator = pointee_iterator<decltype(Remarks)::const_iterator>; + + iterator_range<iterator> remarks() const { + return {Remarks.begin(), Remarks.end()}; + } +}; + +/// Returns a buffer with the contents of the remarks section depending on the +/// format of the file. If the section doesn't exist, this returns an empty +/// optional. +Expected<Optional<StringRef>> +getRemarksSectionContents(const object::ObjectFile &Obj); + +} // end namespace remarks +} // end namespace llvm + +#endif // LLVM_REMARKS_REMARKLINKER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm14/include/llvm/Remarks/RemarkParser.h b/contrib/libs/llvm14/include/llvm/Remarks/RemarkParser.h new file mode 100644 index 0000000000..710f454356 --- /dev/null +++ b/contrib/libs/llvm14/include/llvm/Remarks/RemarkParser.h @@ -0,0 +1,104 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-- llvm/Remarks/Remark.h - The remark type -----------------*- C++/-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides an interface for parsing remarks in LLVM. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_REMARKS_REMARKPARSER_H +#define LLVM_REMARKS_REMARKPARSER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Remarks/RemarkFormat.h" +#include "llvm/Support/Error.h" +#include <memory> + +namespace llvm { +namespace remarks { + +struct Remark; + +class EndOfFileError : public ErrorInfo<EndOfFileError> { +public: + static char ID; + + EndOfFileError() = default; + + void log(raw_ostream &OS) const override { OS << "End of file reached."; } + std::error_code convertToErrorCode() const override { + return inconvertibleErrorCode(); + } +}; + +/// Parser used to parse a raw buffer to remarks::Remark objects. +struct RemarkParser { + /// The format of the parser. + Format ParserFormat; + /// Path to prepend when opening an external remark file. + std::string ExternalFilePrependPath; + + RemarkParser(Format ParserFormat) : ParserFormat(ParserFormat) {} + + /// If no error occurs, this returns a valid Remark object. + /// If an error of type EndOfFileError occurs, it is safe to recover from it + /// by stopping the parsing. + /// If any other error occurs, it should be propagated to the user. + /// The pointer should never be null. + virtual Expected<std::unique_ptr<Remark>> next() = 0; + + virtual ~RemarkParser() = default; +}; + +/// In-memory representation of the string table parsed from a buffer (e.g. the +/// remarks section). +struct ParsedStringTable { + /// The buffer mapped from the section contents. + StringRef Buffer; + /// This object has high changes to be std::move'd around, so don't use a + /// SmallVector for once. + std::vector<size_t> Offsets; + + ParsedStringTable(StringRef Buffer); + /// Disable copy. + ParsedStringTable(const ParsedStringTable &) = delete; + ParsedStringTable &operator=(const ParsedStringTable &) = delete; + /// Should be movable. + ParsedStringTable(ParsedStringTable &&) = default; + ParsedStringTable &operator=(ParsedStringTable &&) = default; + + size_t size() const { return Offsets.size(); } + Expected<StringRef> operator[](size_t Index) const; +}; + +Expected<std::unique_ptr<RemarkParser>> createRemarkParser(Format ParserFormat, + StringRef Buf); + +Expected<std::unique_ptr<RemarkParser>> +createRemarkParser(Format ParserFormat, StringRef Buf, + ParsedStringTable StrTab); + +Expected<std::unique_ptr<RemarkParser>> +createRemarkParserFromMeta(Format ParserFormat, StringRef Buf, + Optional<ParsedStringTable> StrTab = None, + Optional<StringRef> ExternalFilePrependPath = None); + +} // end namespace remarks +} // end namespace llvm + +#endif // LLVM_REMARKS_REMARKPARSER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm14/include/llvm/Remarks/RemarkSerializer.h b/contrib/libs/llvm14/include/llvm/Remarks/RemarkSerializer.h new file mode 100644 index 0000000000..752e63049b --- /dev/null +++ b/contrib/libs/llvm14/include/llvm/Remarks/RemarkSerializer.h @@ -0,0 +1,103 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-- RemarkSerializer.h - Remark serialization interface -----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides an interface for serializing remarks to different formats. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_REMARKS_REMARKSERIALIZER_H +#define LLVM_REMARKS_REMARKSERIALIZER_H + +#include "llvm/Remarks/Remark.h" +#include "llvm/Remarks/RemarkFormat.h" +#include "llvm/Remarks/RemarkStringTable.h" + +namespace llvm { + +class raw_ostream; + +namespace remarks { + +struct Remark; + +enum class SerializerMode { + Separate, // A mode where the metadata is serialized separately from the + // remarks. Typically, this is used when the remarks need to be + // streamed to a side file and the metadata is embedded into the + // final result of the compilation. + Standalone // A mode where everything can be retrieved in the same + // file/buffer. Typically, this is used for storing remarks for + // later use. +}; + +struct MetaSerializer; + +/// This is the base class for a remark serializer. +/// It includes support for using a string table while emitting. +struct RemarkSerializer { + /// The format of the serializer. + Format SerializerFormat; + /// The open raw_ostream that the remark diagnostics are emitted to. + raw_ostream &OS; + /// The serialization mode. + SerializerMode Mode; + /// The string table containing all the unique strings used in the output. + /// The table can be serialized to be consumed after the compilation. + Optional<StringTable> StrTab; + + RemarkSerializer(Format SerializerFormat, raw_ostream &OS, + SerializerMode Mode) + : SerializerFormat(SerializerFormat), OS(OS), Mode(Mode) {} + + /// This is just an interface. + virtual ~RemarkSerializer() = default; + /// Emit a remark to the stream. + virtual void emit(const Remark &Remark) = 0; + /// Return the corresponding metadata serializer. + virtual std::unique_ptr<MetaSerializer> + metaSerializer(raw_ostream &OS, + Optional<StringRef> ExternalFilename = None) = 0; +}; + +/// This is the base class for a remark metadata serializer. +struct MetaSerializer { + /// The open raw_ostream that the metadata is emitted to. + raw_ostream &OS; + + MetaSerializer(raw_ostream &OS) : OS(OS) {} + + /// This is just an interface. + virtual ~MetaSerializer() = default; + virtual void emit() = 0; +}; + +/// Create a remark serializer. +Expected<std::unique_ptr<RemarkSerializer>> +createRemarkSerializer(Format RemarksFormat, SerializerMode Mode, + raw_ostream &OS); + +/// Create a remark serializer that uses a pre-filled string table. +Expected<std::unique_ptr<RemarkSerializer>> +createRemarkSerializer(Format RemarksFormat, SerializerMode Mode, + raw_ostream &OS, remarks::StringTable StrTab); + +} // end namespace remarks +} // end namespace llvm + +#endif // LLVM_REMARKS_REMARKSERIALIZER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm14/include/llvm/Remarks/RemarkStreamer.h b/contrib/libs/llvm14/include/llvm/Remarks/RemarkStreamer.h new file mode 100644 index 0000000000..a86a28c689 --- /dev/null +++ b/contrib/libs/llvm14/include/llvm/Remarks/RemarkStreamer.h @@ -0,0 +1,86 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- llvm/Remarks/RemarkStreamer.h ----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the main interface for streaming remarks. +// +// This is used to stream any llvm::remarks::Remark to an open file taking +// advantage of all the serialization capabilities developed for remarks (e.g. +// metadata in a section, bitstream format, etc.). +// +// Typically, a specialized remark emitter should hold a reference to the main +// remark streamer set up in the LLVMContext, and should convert specialized +// diagnostics to llvm::remarks::Remark objects as they get emitted. +// +// Specialized remark emitters can be components like: +// * Remarks from LLVM (M)IR passes +// * Remarks from the frontend +// * Remarks from an intermediate IR +// +// This allows for composition between specialized remark emitters throughout +// the compilation pipeline, that end up in the same file, using the same format +// and serialization techniques. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_REMARKS_REMARKSTREAMER_H +#define LLVM_REMARKS_REMARKSTREAMER_H + +#include "llvm/ADT/Optional.h" +#include "llvm/Remarks/RemarkSerializer.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/Regex.h" +#include <memory> + +namespace llvm { + +class raw_ostream; + +namespace remarks { +class RemarkStreamer final { + /// The regex used to filter remarks based on the passes that emit them. + Optional<Regex> PassFilter; + /// The object used to serialize the remarks to a specific format. + std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer; + /// The filename that the remark diagnostics are emitted to. + const Optional<std::string> Filename; + +public: + RemarkStreamer(std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer, + Optional<StringRef> Filename = None); + + /// Return the filename that the remark diagnostics are emitted to. + Optional<StringRef> getFilename() const { + return Filename ? Optional<StringRef>(*Filename) : None; + } + /// Return stream that the remark diagnostics are emitted to. + raw_ostream &getStream() { return RemarkSerializer->OS; } + /// Return the serializer used for this stream. + remarks::RemarkSerializer &getSerializer() { return *RemarkSerializer; } + /// Set a pass filter based on a regex \p Filter. + /// Returns an error if the regex is invalid. + Error setFilter(StringRef Filter); + /// Check wether the string matches the filter. + bool matchesFilter(StringRef Str); + /// Check if the remarks also need to have associated metadata in a section. + bool needsSection() const; +}; +} // end namespace remarks +} // end namespace llvm + +#endif // LLVM_REMARKS_REMARKSTREAMER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm14/include/llvm/Remarks/RemarkStringTable.h b/contrib/libs/llvm14/include/llvm/Remarks/RemarkStringTable.h new file mode 100644 index 0000000000..f79a480848 --- /dev/null +++ b/contrib/libs/llvm14/include/llvm/Remarks/RemarkStringTable.h @@ -0,0 +1,85 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-- RemarkStringTable.h - Serializing string table ----------*- C++/-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This class is used to deduplicate and serialize a string table used for +// generating remarks. +// +// For parsing a string table, use ParsedStringTable in RemarkParser.h +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_REMARKS_REMARKSTRINGTABLE_H +#define LLVM_REMARKS_REMARKSTRINGTABLE_H + +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/Allocator.h" +#include <vector> + +namespace llvm { + +class raw_ostream; +class StringRef; + +namespace remarks { + +struct ParsedStringTable; +struct Remark; + +/// The string table used for serializing remarks. +/// This table can be for example serialized in a section to be consumed after +/// the compilation. +struct StringTable { + /// The string table containing all the unique strings used in the output. + /// It maps a string to an unique ID. + StringMap<unsigned, BumpPtrAllocator> StrTab; + /// Total size of the string table when serialized. + size_t SerializedSize = 0; + + StringTable() = default; + + /// Disable copy. + StringTable(const StringTable &) = delete; + StringTable &operator=(const StringTable &) = delete; + /// Should be movable. + StringTable(StringTable &&) = default; + StringTable &operator=(StringTable &&) = default; + + /// Construct a string table from a ParsedStringTable. + StringTable(const ParsedStringTable &Other); + + /// Add a string to the table. It returns an unique ID of the string. + std::pair<unsigned, StringRef> add(StringRef Str); + /// Modify \p R to use strings from this string table. If the string table + /// does not contain the strings, it adds them. + void internalize(Remark &R); + /// Serialize the string table to a stream. It is serialized as a little + /// endian uint64 (the size of the table in bytes) followed by a sequence of + /// NULL-terminated strings, where the N-th string is the string with the ID N + /// in the StrTab map. + void serialize(raw_ostream &OS) const; + /// Serialize the string table to a vector. This allows users to do the actual + /// writing to file/memory/other. + /// The string with the ID == N should be the N-th element in the vector. + std::vector<StringRef> serialize() const; +}; + +} // end namespace remarks +} // end namespace llvm + +#endif // LLVM_REMARKS_REMARKSTRINGTABLE_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm14/include/llvm/Remarks/YAMLRemarkSerializer.h b/contrib/libs/llvm14/include/llvm/Remarks/YAMLRemarkSerializer.h new file mode 100644 index 0000000000..0c16287ee8 --- /dev/null +++ b/contrib/libs/llvm14/include/llvm/Remarks/YAMLRemarkSerializer.h @@ -0,0 +1,119 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-- YAMLRemarkSerializer.h - YAML Remark serialization ---*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides an interface for serializing remarks to YAML. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_REMARKS_YAMLREMARKSERIALIZER_H +#define LLVM_REMARKS_YAMLREMARKSERIALIZER_H + +#include "llvm/Remarks/RemarkSerializer.h" +#include "llvm/Support/YAMLTraits.h" + +namespace llvm { +namespace remarks { + +/// Serialize the remarks to YAML. One remark entry looks like this: +/// --- !<TYPE> +/// Pass: <PASSNAME> +/// Name: <REMARKNAME> +/// DebugLoc: { File: <SOURCEFILENAME>, Line: <SOURCELINE>, +/// Column: <SOURCECOLUMN> } +/// Function: <FUNCTIONNAME> +/// Args: +/// - <KEY>: <VALUE> +/// DebugLoc: { File: <FILE>, Line: <LINE>, Column: <COL> } +/// ... +struct YAMLRemarkSerializer : public RemarkSerializer { + /// The YAML streamer. + yaml::Output YAMLOutput; + + YAMLRemarkSerializer(raw_ostream &OS, SerializerMode Mode, + Optional<StringTable> StrTab = None); + + void emit(const Remark &Remark) override; + std::unique_ptr<MetaSerializer> + metaSerializer(raw_ostream &OS, + Optional<StringRef> ExternalFilename = None) override; + + static bool classof(const RemarkSerializer *S) { + return S->SerializerFormat == Format::YAML; + } + +protected: + YAMLRemarkSerializer(Format SerializerFormat, raw_ostream &OS, + SerializerMode Mode, + Optional<StringTable> StrTab = None); +}; + +struct YAMLMetaSerializer : public MetaSerializer { + Optional<StringRef> ExternalFilename; + + YAMLMetaSerializer(raw_ostream &OS, Optional<StringRef> ExternalFilename) + : MetaSerializer(OS), ExternalFilename(ExternalFilename) {} + + void emit() override; +}; + +/// Serialize the remarks to YAML using a string table. An remark entry looks +/// like the regular YAML remark but instead of string entries it's using +/// numbers that map to an index in the string table. +struct YAMLStrTabRemarkSerializer : public YAMLRemarkSerializer { + /// Wether we already emitted the metadata in standalone mode. + /// This should be set to true after the first invocation of `emit`. + bool DidEmitMeta = false; + + YAMLStrTabRemarkSerializer(raw_ostream &OS, SerializerMode Mode) + : YAMLRemarkSerializer(Format::YAMLStrTab, OS, Mode) { + // We always need a string table for this type of serializer. + StrTab.emplace(); + } + YAMLStrTabRemarkSerializer(raw_ostream &OS, SerializerMode Mode, + StringTable StrTab) + : YAMLRemarkSerializer(Format::YAMLStrTab, OS, Mode, std::move(StrTab)) {} + + /// Override to emit the metadata if necessary. + void emit(const Remark &Remark) override; + + std::unique_ptr<MetaSerializer> + metaSerializer(raw_ostream &OS, + Optional<StringRef> ExternalFilename = None) override; + + static bool classof(const RemarkSerializer *S) { + return S->SerializerFormat == Format::YAMLStrTab; + } +}; + +struct YAMLStrTabMetaSerializer : public YAMLMetaSerializer { + /// The string table is part of the metadata. + const StringTable &StrTab; + + YAMLStrTabMetaSerializer(raw_ostream &OS, + Optional<StringRef> ExternalFilename, + const StringTable &StrTab) + : YAMLMetaSerializer(OS, ExternalFilename), StrTab(StrTab) {} + + void emit() override; +}; + +} // end namespace remarks +} // end namespace llvm + +#endif // LLVM_REMARKS_YAMLREMARKSERIALIZER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif |