//===- BuiltinDialectBytecode.cpp - Builtin Bytecode Implementation -------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "BuiltinDialectBytecode.h" #include "AttributeDetail.h" #include "mlir/Bytecode/BytecodeImplementation.h" #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/BuiltinDialect.h" #include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/Diagnostics.h" #include "mlir/IR/DialectResourceBlobManager.h" #include "mlir/IR/Location.h" #include "mlir/Support/LLVM.h" #include "llvm/ADT/TypeSwitch.h" #include using namespace mlir; //===----------------------------------------------------------------------===// // BuiltinDialectBytecodeInterface //===----------------------------------------------------------------------===// namespace { //===----------------------------------------------------------------------===// // Utility functions // TODO: Move these to separate file. // Returns the bitwidth if known, else return 0. static unsigned getIntegerBitWidth(DialectBytecodeReader &reader, Type type) { if (auto intType = dyn_cast(type)) { return intType.getWidth(); } if (llvm::isa(type)) { return IndexType::kInternalStorageBitWidth; } reader.emitError() << "expected integer or index type for IntegerAttr, but got: " << type; return 0; } static LogicalResult readAPIntWithKnownWidth(DialectBytecodeReader &reader, Type type, FailureOr &val) { unsigned bitWidth = getIntegerBitWidth(reader, type); val = reader.readAPIntWithKnownWidth(bitWidth); return val; } static LogicalResult readAPFloatWithKnownSemantics(DialectBytecodeReader &reader, Type type, FailureOr &val) { auto ftype = dyn_cast(type); if (!ftype) return failure(); val = reader.readAPFloatWithKnownSemantics(ftype.getFloatSemantics()); return success(); } LogicalResult readPotentiallySplatString(DialectBytecodeReader &reader, ShapedType type, bool isSplat, SmallVectorImpl &rawStringData) { rawStringData.resize(isSplat ? 1 : type.getNumElements()); for (StringRef &value : rawStringData) if (failed(reader.readString(value))) return failure(); return success(); } static void writePotentiallySplatString(DialectBytecodeWriter &writer, DenseStringElementsAttr attr) { bool isSplat = attr.isSplat(); if (isSplat) return writer.writeOwnedString(attr.getRawStringData().front()); for (StringRef str : attr.getRawStringData()) writer.writeOwnedString(str); } static FileLineColRange getFileLineColRange(MLIRContext *context, StringAttr filename, ArrayRef lineCols) { switch (lineCols.size()) { case 0: return FileLineColRange::get(filename); case 1: return FileLineColRange::get(filename, lineCols[0]); case 2: return FileLineColRange::get(filename, lineCols[0], lineCols[1]); case 3: return FileLineColRange::get(filename, lineCols[0], lineCols[1], lineCols[2]); case 4: return FileLineColRange::get(filename, lineCols[0], lineCols[1], lineCols[2], lineCols[3]); default: return {}; } } static LogicalResult readFileLineColRangeLocs(DialectBytecodeReader &reader, SmallVectorImpl &lineCols) { return reader.readList( lineCols, [&reader](uint64_t &val) { return reader.readVarInt(val); }); } static void writeFileLineColRangeLocs(DialectBytecodeWriter &writer, FileLineColRange range) { if (range.getStartLine() == 0 && range.getStartColumn() == 0 && range.getEndLine() == 0 && range.getEndColumn() == 0) { writer.writeVarInt(0); return; } if (range.getStartColumn() == 0 && range.getStartLine() == range.getEndLine()) { writer.writeVarInt(1); writer.writeVarInt(range.getStartLine()); return; } // The single file:line:col is handled by other writer, but checked here for // completeness. if (range.getEndColumn() == range.getStartColumn() && range.getStartLine() == range.getEndLine()) { writer.writeVarInt(2); writer.writeVarInt(range.getStartLine()); writer.writeVarInt(range.getStartColumn()); return; } if (range.getStartLine() == range.getEndLine()) { writer.writeVarInt(3); writer.writeVarInt(range.getStartLine()); writer.writeVarInt(range.getStartColumn()); writer.writeVarInt(range.getEndColumn()); return; } writer.writeVarInt(4); writer.writeVarInt(range.getStartLine()); writer.writeVarInt(range.getStartColumn()); writer.writeVarInt(range.getEndLine()); writer.writeVarInt(range.getEndColumn()); } #include "mlir/IR/BuiltinDialectBytecode.cpp.inc" /// This class implements the bytecode interface for the builtin dialect. struct BuiltinDialectBytecodeInterface : public BytecodeDialectInterface { BuiltinDialectBytecodeInterface(Dialect *dialect) : BytecodeDialectInterface(dialect) {} //===--------------------------------------------------------------------===// // Attributes Attribute readAttribute(DialectBytecodeReader &reader) const override { return ::readAttribute(getContext(), reader); } LogicalResult writeAttribute(Attribute attr, DialectBytecodeWriter &writer) const override { return ::writeAttribute(attr, writer); } //===--------------------------------------------------------------------===// // Types Type readType(DialectBytecodeReader &reader) const override { return ::readType(getContext(), reader); } LogicalResult writeType(Type type, DialectBytecodeWriter &writer) const override { return ::writeType(type, writer); } }; } // namespace void builtin_dialect_detail::addBytecodeInterface(BuiltinDialect *dialect) { dialect->addInterfaces(); }