xref: /llvm-project/mlir/lib/IR/BuiltinDialectBytecode.cpp (revision 01e75646a5d4977a9e441e3db1042df0beccc4bb)
102c2ecb9SRiver Riddle //===- BuiltinDialectBytecode.cpp - Builtin Bytecode Implementation -------===//
202c2ecb9SRiver Riddle //
302c2ecb9SRiver Riddle // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
402c2ecb9SRiver Riddle // See https://llvm.org/LICENSE.txt for license information.
502c2ecb9SRiver Riddle // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
602c2ecb9SRiver Riddle //
702c2ecb9SRiver Riddle //===----------------------------------------------------------------------===//
802c2ecb9SRiver Riddle 
902c2ecb9SRiver Riddle #include "BuiltinDialectBytecode.h"
10728a8d5aSTobias Gysi #include "AttributeDetail.h"
1102c2ecb9SRiver Riddle #include "mlir/Bytecode/BytecodeImplementation.h"
1209115580SJacques Pienaar #include "mlir/IR/BuiltinAttributes.h"
1302c2ecb9SRiver Riddle #include "mlir/IR/BuiltinDialect.h"
1402c2ecb9SRiver Riddle #include "mlir/IR/BuiltinTypes.h"
1502c2ecb9SRiver Riddle #include "mlir/IR/Diagnostics.h"
166ab2bcffSRiver Riddle #include "mlir/IR/DialectResourceBlobManager.h"
17*01e75646SJacques Pienaar #include "mlir/IR/Location.h"
18*01e75646SJacques Pienaar #include "mlir/Support/LLVM.h"
1902c2ecb9SRiver Riddle #include "llvm/ADT/TypeSwitch.h"
20*01e75646SJacques Pienaar #include <cstdint>
2102c2ecb9SRiver Riddle 
2202c2ecb9SRiver Riddle using namespace mlir;
2302c2ecb9SRiver Riddle 
2402c2ecb9SRiver Riddle //===----------------------------------------------------------------------===//
2502c2ecb9SRiver Riddle // BuiltinDialectBytecodeInterface
2602c2ecb9SRiver Riddle //===----------------------------------------------------------------------===//
2702c2ecb9SRiver Riddle 
2802c2ecb9SRiver Riddle namespace {
2909115580SJacques Pienaar 
3009115580SJacques Pienaar //===----------------------------------------------------------------------===//
3109115580SJacques Pienaar // Utility functions
3209115580SJacques Pienaar 
3309115580SJacques Pienaar // TODO: Move these to separate file.
3409115580SJacques Pienaar 
3509115580SJacques Pienaar // Returns the bitwidth if known, else return 0.
3609115580SJacques Pienaar static unsigned getIntegerBitWidth(DialectBytecodeReader &reader, Type type) {
3709115580SJacques Pienaar   if (auto intType = dyn_cast<IntegerType>(type)) {
3809115580SJacques Pienaar     return intType.getWidth();
39b39958c2SMehdi Amini   }
40b39958c2SMehdi Amini   if (llvm::isa<IndexType>(type)) {
4109115580SJacques Pienaar     return IndexType::kInternalStorageBitWidth;
4209115580SJacques Pienaar   }
4309115580SJacques Pienaar   reader.emitError()
4409115580SJacques Pienaar       << "expected integer or index type for IntegerAttr, but got: " << type;
4509115580SJacques Pienaar   return 0;
4609115580SJacques Pienaar }
4709115580SJacques Pienaar 
4809115580SJacques Pienaar static LogicalResult readAPIntWithKnownWidth(DialectBytecodeReader &reader,
4909115580SJacques Pienaar                                              Type type, FailureOr<APInt> &val) {
5009115580SJacques Pienaar   unsigned bitWidth = getIntegerBitWidth(reader, type);
5109115580SJacques Pienaar   val = reader.readAPIntWithKnownWidth(bitWidth);
5209115580SJacques Pienaar   return val;
5309115580SJacques Pienaar }
5409115580SJacques Pienaar 
5509115580SJacques Pienaar static LogicalResult
5609115580SJacques Pienaar readAPFloatWithKnownSemantics(DialectBytecodeReader &reader, Type type,
5709115580SJacques Pienaar                               FailureOr<APFloat> &val) {
5809115580SJacques Pienaar   auto ftype = dyn_cast<FloatType>(type);
5909115580SJacques Pienaar   if (!ftype)
6009115580SJacques Pienaar     return failure();
6109115580SJacques Pienaar   val = reader.readAPFloatWithKnownSemantics(ftype.getFloatSemantics());
6209115580SJacques Pienaar   return success();
6309115580SJacques Pienaar }
6409115580SJacques Pienaar 
6509115580SJacques Pienaar LogicalResult
6609115580SJacques Pienaar readPotentiallySplatString(DialectBytecodeReader &reader, ShapedType type,
6709115580SJacques Pienaar                            bool isSplat,
6809115580SJacques Pienaar                            SmallVectorImpl<StringRef> &rawStringData) {
6909115580SJacques Pienaar   rawStringData.resize(isSplat ? 1 : type.getNumElements());
7009115580SJacques Pienaar   for (StringRef &value : rawStringData)
7109115580SJacques Pienaar     if (failed(reader.readString(value)))
7209115580SJacques Pienaar       return failure();
7309115580SJacques Pienaar   return success();
7409115580SJacques Pienaar }
7509115580SJacques Pienaar 
76*01e75646SJacques Pienaar static void writePotentiallySplatString(DialectBytecodeWriter &writer,
7709115580SJacques Pienaar                                         DenseStringElementsAttr attr) {
7809115580SJacques Pienaar   bool isSplat = attr.isSplat();
7909115580SJacques Pienaar   if (isSplat)
8009115580SJacques Pienaar     return writer.writeOwnedString(attr.getRawStringData().front());
8109115580SJacques Pienaar 
8209115580SJacques Pienaar   for (StringRef str : attr.getRawStringData())
8309115580SJacques Pienaar     writer.writeOwnedString(str);
8409115580SJacques Pienaar }
8509115580SJacques Pienaar 
86*01e75646SJacques Pienaar static FileLineColRange getFileLineColRange(MLIRContext *context,
87*01e75646SJacques Pienaar                                             StringAttr filename,
88*01e75646SJacques Pienaar                                             ArrayRef<uint64_t> lineCols) {
89*01e75646SJacques Pienaar   switch (lineCols.size()) {
90*01e75646SJacques Pienaar   case 0:
91*01e75646SJacques Pienaar     return FileLineColRange::get(filename);
92*01e75646SJacques Pienaar   case 1:
93*01e75646SJacques Pienaar     return FileLineColRange::get(filename, lineCols[0]);
94*01e75646SJacques Pienaar   case 2:
95*01e75646SJacques Pienaar     return FileLineColRange::get(filename, lineCols[0], lineCols[1]);
96*01e75646SJacques Pienaar   case 3:
97*01e75646SJacques Pienaar     return FileLineColRange::get(filename, lineCols[0], lineCols[1],
98*01e75646SJacques Pienaar                                  lineCols[2]);
99*01e75646SJacques Pienaar   case 4:
100*01e75646SJacques Pienaar     return FileLineColRange::get(filename, lineCols[0], lineCols[1],
101*01e75646SJacques Pienaar                                  lineCols[2], lineCols[3]);
102*01e75646SJacques Pienaar   default:
103*01e75646SJacques Pienaar     return {};
104*01e75646SJacques Pienaar   }
105*01e75646SJacques Pienaar }
106*01e75646SJacques Pienaar 
107*01e75646SJacques Pienaar static LogicalResult
108*01e75646SJacques Pienaar readFileLineColRangeLocs(DialectBytecodeReader &reader,
109*01e75646SJacques Pienaar                          SmallVectorImpl<uint64_t> &lineCols) {
110*01e75646SJacques Pienaar   return reader.readList(
111*01e75646SJacques Pienaar       lineCols, [&reader](uint64_t &val) { return reader.readVarInt(val); });
112*01e75646SJacques Pienaar }
113*01e75646SJacques Pienaar 
114*01e75646SJacques Pienaar static void writeFileLineColRangeLocs(DialectBytecodeWriter &writer,
115*01e75646SJacques Pienaar                                       FileLineColRange range) {
116*01e75646SJacques Pienaar   if (range.getStartLine() == 0 && range.getStartColumn() == 0 &&
117*01e75646SJacques Pienaar       range.getEndLine() == 0 && range.getEndColumn() == 0) {
118*01e75646SJacques Pienaar     writer.writeVarInt(0);
119*01e75646SJacques Pienaar     return;
120*01e75646SJacques Pienaar   }
121*01e75646SJacques Pienaar   if (range.getStartColumn() == 0 &&
122*01e75646SJacques Pienaar       range.getStartLine() == range.getEndLine()) {
123*01e75646SJacques Pienaar     writer.writeVarInt(1);
124*01e75646SJacques Pienaar     writer.writeVarInt(range.getStartLine());
125*01e75646SJacques Pienaar     return;
126*01e75646SJacques Pienaar   }
127*01e75646SJacques Pienaar   // The single file:line:col is handled by other writer, but checked here for
128*01e75646SJacques Pienaar   // completeness.
129*01e75646SJacques Pienaar   if (range.getEndColumn() == range.getStartColumn() &&
130*01e75646SJacques Pienaar       range.getStartLine() == range.getEndLine()) {
131*01e75646SJacques Pienaar     writer.writeVarInt(2);
132*01e75646SJacques Pienaar     writer.writeVarInt(range.getStartLine());
133*01e75646SJacques Pienaar     writer.writeVarInt(range.getStartColumn());
134*01e75646SJacques Pienaar     return;
135*01e75646SJacques Pienaar   }
136*01e75646SJacques Pienaar   if (range.getStartLine() == range.getEndLine()) {
137*01e75646SJacques Pienaar     writer.writeVarInt(3);
138*01e75646SJacques Pienaar     writer.writeVarInt(range.getStartLine());
139*01e75646SJacques Pienaar     writer.writeVarInt(range.getStartColumn());
140*01e75646SJacques Pienaar     writer.writeVarInt(range.getEndColumn());
141*01e75646SJacques Pienaar     return;
142*01e75646SJacques Pienaar   }
143*01e75646SJacques Pienaar   writer.writeVarInt(4);
144*01e75646SJacques Pienaar   writer.writeVarInt(range.getStartLine());
145*01e75646SJacques Pienaar   writer.writeVarInt(range.getStartColumn());
146*01e75646SJacques Pienaar   writer.writeVarInt(range.getEndLine());
147*01e75646SJacques Pienaar   writer.writeVarInt(range.getEndColumn());
148*01e75646SJacques Pienaar }
149*01e75646SJacques Pienaar 
15009115580SJacques Pienaar #include "mlir/IR/BuiltinDialectBytecode.cpp.inc"
15109115580SJacques Pienaar 
15202c2ecb9SRiver Riddle /// This class implements the bytecode interface for the builtin dialect.
15302c2ecb9SRiver Riddle struct BuiltinDialectBytecodeInterface : public BytecodeDialectInterface {
15402c2ecb9SRiver Riddle   BuiltinDialectBytecodeInterface(Dialect *dialect)
15502c2ecb9SRiver Riddle       : BytecodeDialectInterface(dialect) {}
15602c2ecb9SRiver Riddle 
15702c2ecb9SRiver Riddle   //===--------------------------------------------------------------------===//
15802c2ecb9SRiver Riddle   // Attributes
15902c2ecb9SRiver Riddle 
16009115580SJacques Pienaar   Attribute readAttribute(DialectBytecodeReader &reader) const override {
16109115580SJacques Pienaar     return ::readAttribute(getContext(), reader);
16209115580SJacques Pienaar   }
163772994f1SRiver Riddle 
16402c2ecb9SRiver Riddle   LogicalResult writeAttribute(Attribute attr,
16509115580SJacques Pienaar                                DialectBytecodeWriter &writer) const override {
16609115580SJacques Pienaar     return ::writeAttribute(attr, writer);
16709115580SJacques Pienaar   }
168772994f1SRiver Riddle 
16902c2ecb9SRiver Riddle   //===--------------------------------------------------------------------===//
17002c2ecb9SRiver Riddle   // Types
17102c2ecb9SRiver Riddle 
17209115580SJacques Pienaar   Type readType(DialectBytecodeReader &reader) const override {
17309115580SJacques Pienaar     return ::readType(getContext(), reader);
17409115580SJacques Pienaar   }
17502c2ecb9SRiver Riddle 
17602c2ecb9SRiver Riddle   LogicalResult writeType(Type type,
17709115580SJacques Pienaar                           DialectBytecodeWriter &writer) const override {
17809115580SJacques Pienaar     return ::writeType(type, writer);
17909115580SJacques Pienaar   }
18002c2ecb9SRiver Riddle };
18102c2ecb9SRiver Riddle } // namespace
18202c2ecb9SRiver Riddle 
18302c2ecb9SRiver Riddle void builtin_dialect_detail::addBytecodeInterface(BuiltinDialect *dialect) {
18402c2ecb9SRiver Riddle   dialect->addInterfaces<BuiltinDialectBytecodeInterface>();
18502c2ecb9SRiver Riddle }
186