1 //===-- BitstreamRemarkParser.h - Bitstream parser --------------*- 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 remark parser using the LLVM 10 // Bitstream format. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_REMARKS_BITSTREAMREMARKPARSER_H 15 #define LLVM_REMARKS_BITSTREAMREMARKPARSER_H 16 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/Bitstream/BitstreamReader.h" 20 #include "llvm/Support/Error.h" 21 #include <array> 22 #include <cstdint> 23 #include <optional> 24 25 namespace llvm { 26 namespace remarks { 27 28 /// Helper to parse a META_BLOCK for a bitstream remark container. 29 struct BitstreamMetaParserHelper { 30 /// The Bitstream reader. 31 BitstreamCursor &Stream; 32 /// Reference to the storage for the block info. 33 BitstreamBlockInfo &BlockInfo; 34 /// The parsed content: depending on the container type, some fields might be 35 /// empty. 36 std::optional<uint64_t> ContainerVersion; 37 std::optional<uint8_t> ContainerType; 38 std::optional<StringRef> StrTabBuf; 39 std::optional<StringRef> ExternalFilePath; 40 std::optional<uint64_t> RemarkVersion; 41 42 /// Continue parsing with \p Stream. \p Stream is expected to contain a 43 /// ENTER_SUBBLOCK to the META_BLOCK at the current position. 44 /// \p Stream is expected to have a BLOCKINFO_BLOCK set. 45 BitstreamMetaParserHelper(BitstreamCursor &Stream, 46 BitstreamBlockInfo &BlockInfo); 47 48 /// Parse the META_BLOCK and fill the available entries. 49 /// This helper does not check for the validity of the fields. 50 Error parse(); 51 }; 52 53 /// Helper to parse a REMARK_BLOCK for a bitstream remark container. 54 struct BitstreamRemarkParserHelper { 55 /// The Bitstream reader. 56 BitstreamCursor &Stream; 57 /// The parsed content: depending on the remark, some fields might be empty. 58 std::optional<uint8_t> Type; 59 std::optional<uint64_t> RemarkNameIdx; 60 std::optional<uint64_t> PassNameIdx; 61 std::optional<uint64_t> FunctionNameIdx; 62 std::optional<uint64_t> SourceFileNameIdx; 63 std::optional<uint32_t> SourceLine; 64 std::optional<uint32_t> SourceColumn; 65 std::optional<uint64_t> Hotness; 66 struct Argument { 67 std::optional<uint64_t> KeyIdx; 68 std::optional<uint64_t> ValueIdx; 69 std::optional<uint64_t> SourceFileNameIdx; 70 std::optional<uint32_t> SourceLine; 71 std::optional<uint32_t> SourceColumn; 72 }; 73 std::optional<ArrayRef<Argument>> Args; 74 /// Avoid re-allocating a vector every time. 75 SmallVector<Argument, 8> TmpArgs; 76 77 /// Continue parsing with \p Stream. \p Stream is expected to contain a 78 /// ENTER_SUBBLOCK to the REMARK_BLOCK at the current position. 79 /// \p Stream is expected to have a BLOCKINFO_BLOCK set and to have already 80 /// parsed the META_BLOCK. 81 BitstreamRemarkParserHelper(BitstreamCursor &Stream); 82 83 /// Parse the REMARK_BLOCK and fill the available entries. 84 /// This helper does not check for the validity of the fields. 85 Error parse(); 86 }; 87 88 /// Helper to parse any bitstream remark container. 89 struct BitstreamParserHelper { 90 /// The Bitstream reader. 91 BitstreamCursor Stream; 92 /// The block info block. 93 BitstreamBlockInfo BlockInfo; 94 /// Start parsing at \p Buffer. 95 BitstreamParserHelper(StringRef Buffer); 96 /// Parse the magic number. 97 Expected<std::array<char, 4>> parseMagic(); 98 /// Parse the block info block containing all the abbrevs. 99 /// This needs to be called before calling any other parsing function. 100 Error parseBlockInfoBlock(); 101 /// Return true if the next block is a META_BLOCK. This function does not move 102 /// the cursor. 103 Expected<bool> isMetaBlock(); 104 /// Return true if the next block is a REMARK_BLOCK. This function does not 105 /// move the cursor. 106 Expected<bool> isRemarkBlock(); 107 /// Return true if the parser reached the end of the stream. atEndOfStreamBitstreamParserHelper108 bool atEndOfStream() { return Stream.AtEndOfStream(); } 109 /// Jump to the end of the stream, skipping everything. skipToEndBitstreamParserHelper110 void skipToEnd() { return Stream.skipToEnd(); } 111 }; 112 113 } // end namespace remarks 114 } // end namespace llvm 115 116 #endif // LLVM_REMARKS_BITSTREAMREMARKPARSER_H 117