1 | //===- Encoding.h - MLIR binary format encoding information -----*- 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 header defines enum values describing the structure of MLIR bytecode |
10 | // files. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef MLIR_BYTECODE_ENCODING_H |
15 | #define MLIR_BYTECODE_ENCODING_H |
16 | |
17 | #include "mlir/IR/Value.h" |
18 | #include <cstdint> |
19 | #include <type_traits> |
20 | |
21 | namespace mlir { |
22 | namespace bytecode { |
23 | //===----------------------------------------------------------------------===// |
24 | // General constants |
25 | //===----------------------------------------------------------------------===// |
26 | |
27 | enum BytecodeVersion { |
28 | /// The minimum supported version of the bytecode. |
29 | kMinSupportedVersion = 0, |
30 | |
31 | /// Dialects versioning was added in version 1. |
32 | kDialectVersioning = 1, |
33 | |
34 | /// Support for lazy-loading of isolated region was added in version 2. |
35 | kLazyLoading = 2, |
36 | |
37 | /// Use-list ordering started to be encoded in version 3. |
38 | kUseListOrdering = 3, |
39 | |
40 | /// Avoid recording unknown locations on block arguments (compression) started |
41 | /// in version 4. |
42 | kElideUnknownBlockArgLocation = 4, |
43 | |
44 | /// Support for encoding properties natively in bytecode instead of merged |
45 | /// with the discardable attributes. |
46 | kNativePropertiesEncoding = 5, |
47 | |
48 | /// ODS emits operand/result segment_size as native properties instead of |
49 | /// an attribute. |
50 | kNativePropertiesODSSegmentSize = 6, |
51 | |
52 | /// The current bytecode version. |
53 | kVersion = 6, |
54 | |
55 | /// An arbitrary value used to fill alignment padding. |
56 | kAlignmentByte = 0xCB, |
57 | }; |
58 | |
59 | //===----------------------------------------------------------------------===// |
60 | // Sections |
61 | //===----------------------------------------------------------------------===// |
62 | |
63 | namespace Section { |
64 | enum ID : uint8_t { |
65 | /// This section contains strings referenced within the bytecode. |
66 | kString = 0, |
67 | |
68 | /// This section contains the dialects referenced within an IR module. |
69 | kDialect = 1, |
70 | |
71 | /// This section contains the attributes and types referenced within an IR |
72 | /// module. |
73 | kAttrType = 2, |
74 | |
75 | /// This section contains the offsets for the attribute and types within the |
76 | /// AttrType section. |
77 | kAttrTypeOffset = 3, |
78 | |
79 | /// This section contains the list of operations serialized into the bytecode, |
80 | /// and their nested regions/operations. |
81 | kIR = 4, |
82 | |
83 | /// This section contains the resources of the bytecode. |
84 | kResource = 5, |
85 | |
86 | /// This section contains the offsets of resources within the Resource |
87 | /// section. |
88 | kResourceOffset = 6, |
89 | |
90 | /// This section contains the versions of each dialect. |
91 | kDialectVersions = 7, |
92 | |
93 | /// This section contains the properties for the operations. |
94 | kProperties = 8, |
95 | |
96 | /// The total number of section types. |
97 | kNumSections = 9, |
98 | }; |
99 | } // namespace Section |
100 | |
101 | //===----------------------------------------------------------------------===// |
102 | // IR Section |
103 | //===----------------------------------------------------------------------===// |
104 | |
105 | /// This enum represents a mask of all of the potential components of an |
106 | /// operation. This mask is used when encoding an operation to indicate which |
107 | /// components are present in the bytecode. |
108 | namespace OpEncodingMask { |
109 | enum : uint8_t { |
110 | // clang-format off |
111 | kHasAttrs = 0b00000001, |
112 | kHasResults = 0b00000010, |
113 | kHasOperands = 0b00000100, |
114 | kHasSuccessors = 0b00001000, |
115 | kHasInlineRegions = 0b00010000, |
116 | kHasUseListOrders = 0b00100000, |
117 | kHasProperties = 0b01000000, |
118 | // clang-format on |
119 | }; |
120 | } // namespace OpEncodingMask |
121 | |
122 | /// Get the unique ID of a value use. We encode the unique ID combining an owner |
123 | /// number and the argument number such as if ownerID(op1) < ownerID(op2), then |
124 | /// useID(op1) < useID(op2). If uses have the same owner, then argNumber(op1) < |
125 | /// argNumber(op2) implies useID(op1) < useID(op2). |
126 | template <typename OperandT> |
127 | static inline uint64_t getUseID(OperandT &val, unsigned ownerID) { |
128 | uint32_t operandNumberID; |
129 | if constexpr (std::is_same_v<OpOperand, OperandT>) |
130 | operandNumberID = val.getOperandNumber(); |
131 | else if constexpr (std::is_same_v<BlockArgument, OperandT>) |
132 | operandNumberID = val.getArgNumber(); |
133 | else |
134 | llvm_unreachable("unexpected operand type" ); |
135 | return (static_cast<uint64_t>(ownerID) << 32) | operandNumberID; |
136 | } |
137 | |
138 | } // namespace bytecode |
139 | } // namespace mlir |
140 | |
141 | #endif |
142 | |