1 //===- BuiltinDialectBytecode.cpp - Builtin Bytecode Implementation -------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "BuiltinDialectBytecode.h"
10 #include "AttributeDetail.h"
11 #include "mlir/Bytecode/BytecodeImplementation.h"
12 #include "mlir/IR/BuiltinAttributes.h"
13 #include "mlir/IR/BuiltinDialect.h"
14 #include "mlir/IR/BuiltinTypes.h"
15 #include "mlir/IR/Diagnostics.h"
16 #include "mlir/IR/DialectResourceBlobManager.h"
17 #include "mlir/IR/Location.h"
18 #include "mlir/Support/LLVM.h"
19 #include "llvm/ADT/TypeSwitch.h"
24 //===----------------------------------------------------------------------===//
25 // BuiltinDialectBytecodeInterface
26 //===----------------------------------------------------------------------===//
30 //===----------------------------------------------------------------------===//
33 // TODO: Move these to separate file.
35 // Returns the bitwidth if known, else return 0.
36 static unsigned getIntegerBitWidth(DialectBytecodeReader
&reader
, Type type
) {
37 if (auto intType
= dyn_cast
<IntegerType
>(type
)) {
38 return intType
.getWidth();
40 if (llvm::isa
<IndexType
>(type
)) {
41 return IndexType::kInternalStorageBitWidth
;
44 << "expected integer or index type for IntegerAttr, but got: " << type
;
48 static LogicalResult
readAPIntWithKnownWidth(DialectBytecodeReader
&reader
,
49 Type type
, FailureOr
<APInt
> &val
) {
50 unsigned bitWidth
= getIntegerBitWidth(reader
, type
);
51 val
= reader
.readAPIntWithKnownWidth(bitWidth
);
56 readAPFloatWithKnownSemantics(DialectBytecodeReader
&reader
, Type type
,
57 FailureOr
<APFloat
> &val
) {
58 auto ftype
= dyn_cast
<FloatType
>(type
);
61 val
= reader
.readAPFloatWithKnownSemantics(ftype
.getFloatSemantics());
66 readPotentiallySplatString(DialectBytecodeReader
&reader
, ShapedType type
,
68 SmallVectorImpl
<StringRef
> &rawStringData
) {
69 rawStringData
.resize(isSplat
? 1 : type
.getNumElements());
70 for (StringRef
&value
: rawStringData
)
71 if (failed(reader
.readString(value
)))
76 static void writePotentiallySplatString(DialectBytecodeWriter
&writer
,
77 DenseStringElementsAttr attr
) {
78 bool isSplat
= attr
.isSplat();
80 return writer
.writeOwnedString(attr
.getRawStringData().front());
82 for (StringRef str
: attr
.getRawStringData())
83 writer
.writeOwnedString(str
);
86 static FileLineColRange
getFileLineColRange(MLIRContext
*context
,
88 ArrayRef
<uint64_t> lineCols
) {
89 switch (lineCols
.size()) {
91 return FileLineColRange::get(filename
);
93 return FileLineColRange::get(filename
, lineCols
[0]);
95 return FileLineColRange::get(filename
, lineCols
[0], lineCols
[1]);
97 return FileLineColRange::get(filename
, lineCols
[0], lineCols
[1],
100 return FileLineColRange::get(filename
, lineCols
[0], lineCols
[1],
101 lineCols
[2], lineCols
[3]);
108 readFileLineColRangeLocs(DialectBytecodeReader
&reader
,
109 SmallVectorImpl
<uint64_t> &lineCols
) {
110 return reader
.readList(
111 lineCols
, [&reader
](uint64_t &val
) { return reader
.readVarInt(val
); });
114 static void writeFileLineColRangeLocs(DialectBytecodeWriter
&writer
,
115 FileLineColRange range
) {
116 if (range
.getStartLine() == 0 && range
.getStartColumn() == 0 &&
117 range
.getEndLine() == 0 && range
.getEndColumn() == 0) {
118 writer
.writeVarInt(0);
121 if (range
.getStartColumn() == 0 &&
122 range
.getStartLine() == range
.getEndLine()) {
123 writer
.writeVarInt(1);
124 writer
.writeVarInt(range
.getStartLine());
127 // The single file:line:col is handled by other writer, but checked here for
129 if (range
.getEndColumn() == range
.getStartColumn() &&
130 range
.getStartLine() == range
.getEndLine()) {
131 writer
.writeVarInt(2);
132 writer
.writeVarInt(range
.getStartLine());
133 writer
.writeVarInt(range
.getStartColumn());
136 if (range
.getStartLine() == range
.getEndLine()) {
137 writer
.writeVarInt(3);
138 writer
.writeVarInt(range
.getStartLine());
139 writer
.writeVarInt(range
.getStartColumn());
140 writer
.writeVarInt(range
.getEndColumn());
143 writer
.writeVarInt(4);
144 writer
.writeVarInt(range
.getStartLine());
145 writer
.writeVarInt(range
.getStartColumn());
146 writer
.writeVarInt(range
.getEndLine());
147 writer
.writeVarInt(range
.getEndColumn());
150 #include "mlir/IR/BuiltinDialectBytecode.cpp.inc"
152 /// This class implements the bytecode interface for the builtin dialect.
153 struct BuiltinDialectBytecodeInterface
: public BytecodeDialectInterface
{
154 BuiltinDialectBytecodeInterface(Dialect
*dialect
)
155 : BytecodeDialectInterface(dialect
) {}
157 //===--------------------------------------------------------------------===//
160 Attribute
readAttribute(DialectBytecodeReader
&reader
) const override
{
161 return ::readAttribute(getContext(), reader
);
164 LogicalResult
writeAttribute(Attribute attr
,
165 DialectBytecodeWriter
&writer
) const override
{
166 return ::writeAttribute(attr
, writer
);
169 //===--------------------------------------------------------------------===//
172 Type
readType(DialectBytecodeReader
&reader
) const override
{
173 return ::readType(getContext(), reader
);
176 LogicalResult
writeType(Type type
,
177 DialectBytecodeWriter
&writer
) const override
{
178 return ::writeType(type
, writer
);
183 void builtin_dialect_detail::addBytecodeInterface(BuiltinDialect
*dialect
) {
184 dialect
->addInterfaces
<BuiltinDialectBytecodeInterface
>();