Skip to content

Commit b68f7fd

Browse files
committed
[Remarks] Add parser for bitstream remarks
The bitstream remark serializer landed in r367372. This adds a bitstream remark parser that parser bitstream remark files to llvm::remarks::Remark objects through the RemarkParser interface. A few interesting things to point out: * There are parsing helpers to parse the different types of blocks * The main parsing helper allows us to parse remark metadata and open an external file containing the encoded remarks * This adds a dependency from the Remarks library to the BitstreamReader library * The testing strategy is to create a remark entry through YAML, parse it, serialize it to bitstream, parse that back and compare the objects. * There are close to no tests for malformed bitstream remarks, due to the lack of textual format for the bitstream format. * This adds a new C API for parsing bitstream remarks: LLVMRemarkParserCreateBitstream. * This bumps the REMARKS_API_VERSION to 1. Differential Revision: https://reviews.llvm.org/D67134 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@371429 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent c77e934 commit b68f7fd

File tree

11 files changed

+1217
-8
lines changed

11 files changed

+1217
-8
lines changed

include/llvm-c/Remarks.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ extern "C" {
3030
* @{
3131
*/
3232

33-
#define REMARKS_API_VERSION 0
33+
// 0 -> 1: Bitstream remarks support.
34+
#define REMARKS_API_VERSION 1
3435

3536
/**
3637
* The type of the emitted remark.
@@ -240,6 +241,20 @@ typedef struct LLVMRemarkOpaqueParser *LLVMRemarkParserRef;
240241
extern LLVMRemarkParserRef LLVMRemarkParserCreateYAML(const void *Buf,
241242
uint64_t Size);
242243

244+
/**
245+
* Creates a remark parser that can be used to parse the buffer located in \p
246+
* Buf of size \p Size bytes.
247+
*
248+
* \p Buf cannot be `NULL`.
249+
*
250+
* This function should be paired with LLVMRemarkParserDispose() to avoid
251+
* leaking resources.
252+
*
253+
* \since REMARKS_API_VERSION=1
254+
*/
255+
extern LLVMRemarkParserRef LLVMRemarkParserCreateBitstream(const void *Buf,
256+
uint64_t Size);
257+
243258
/**
244259
* Returns the next remark in the file.
245260
*

include/llvm/Bitstream/BitstreamReader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ class BitstreamCursor : SimpleBitstreamCursor {
379379
using SimpleBitstreamCursor::ReadVBR;
380380
using SimpleBitstreamCursor::ReadVBR64;
381381
using SimpleBitstreamCursor::SizeInBytes;
382+
using SimpleBitstreamCursor::skipToEnd;
382383

383384
/// Return the number of bits used to encode an abbrev #.
384385
unsigned getAbbrevIDWidth() const { return CurCodeSize; }
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
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_BITSTREAM_REMARK_PARSER_H
15+
#define LLVM_REMARKS_BITSTREAM_REMARK_PARSER_H
16+
17+
#include "llvm/ADT/StringRef.h"
18+
#include "llvm/Bitstream/BitstreamReader.h"
19+
#include "llvm/Remarks/BitstreamRemarkContainer.h"
20+
#include "llvm/Remarks/Remark.h"
21+
#include "llvm/Remarks/RemarkParser.h"
22+
#include "llvm/Support/Error.h"
23+
#include <array>
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+
Optional<uint64_t> ContainerVersion;
37+
Optional<uint8_t> ContainerType;
38+
Optional<StringRef> StrTabBuf;
39+
Optional<StringRef> ExternalFilePath;
40+
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+
Optional<uint8_t> Type;
59+
Optional<uint64_t> RemarkNameIdx;
60+
Optional<uint64_t> PassNameIdx;
61+
Optional<uint64_t> FunctionNameIdx;
62+
Optional<uint64_t> SourceFileNameIdx;
63+
Optional<uint32_t> SourceLine;
64+
Optional<uint32_t> SourceColumn;
65+
Optional<uint64_t> Hotness;
66+
struct Argument {
67+
Optional<uint64_t> KeyIdx;
68+
Optional<uint64_t> ValueIdx;
69+
Optional<uint64_t> SourceFileNameIdx;
70+
Optional<uint32_t> SourceLine;
71+
Optional<uint32_t> SourceColumn;
72+
};
73+
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.
108+
bool atEndOfStream() { return Stream.AtEndOfStream(); }
109+
/// Jump to the end of the stream, skipping everything.
110+
void skipToEnd() { return Stream.skipToEnd(); }
111+
};
112+
113+
} // end namespace remarks
114+
} // end namespace llvm
115+
116+
#endif /* LLVM_REMARKS_BITSTREAM_REMARK_PARSER_H */

0 commit comments

Comments
 (0)