//===- LLVMDialectBytecode.cpp - LLVM 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 "LLVMDialectBytecode.h" #include "mlir/Bytecode/BytecodeImplementation.h" #include "mlir/Dialect/LLVMIR/LLVMAttrs.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/Dialect/LLVMIR/LLVMTypes.h" #include "mlir/IR/Diagnostics.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/TypeSwitch.h" #include using namespace mlir; using namespace mlir::LLVM; namespace { // Provide some forward declarations of the functions that will be generated by // the include below. static void write(DIExpressionElemAttr attribute, DialectBytecodeWriter &writer); static LogicalResult writeAttribute(Attribute attribute, DialectBytecodeWriter &writer); //===--------------------------------------------------------------------===// // Optional ArrayRefs // // Note that both the writer and reader functions consider attributes to be // optional. This is because the attribute may be present or empty. //===--------------------------------------------------------------------===// template static void writeOptionalArrayRef(DialectBytecodeWriter &writer, ArrayRef storage) { if (storage.empty()) { writer.writeOwnedBool(false); return; } writer.writeOwnedBool(true); writer.writeList(storage, [&](EntryTy val) { if constexpr (std::is_base_of_v) { (void)writer.writeOptionalAttribute(val); } else if constexpr (std::is_integral_v) { (void)writer.writeVarInt(val); } else { static_assert(true, "EntryTy not supported"); } }); } template static LogicalResult readOptionalArrayRef(DialectBytecodeReader &reader, SmallVectorImpl &storage) { bool isPresent = false; if (failed(reader.readBool(isPresent))) return failure(); // Nothing to do here, the array is empty. if (!isPresent) return success(); auto readEntry = [&]() -> FailureOr { EntryTy temp; if constexpr (std::is_base_of_v) { if (succeeded(reader.readOptionalAttribute(temp))) return temp; } else if constexpr (std::is_integral_v) { if (succeeded(reader.readVarInt(temp))) return temp; } else { static_assert(true, "EntryTy not supported"); } return failure(); }; return reader.readList(storage, readEntry); } //===--------------------------------------------------------------------===// // Optional integral types //===--------------------------------------------------------------------===// template static void writeOptionalInt(DialectBytecodeWriter &writer, std::optional storage) { static_assert(std::is_integral_v, "EntryTy must be an integral type"); EntryTy val = storage.value_or(0); writer.writeVarIntWithFlag(val, storage.has_value()); } template static LogicalResult readOptionalInt(DialectBytecodeReader &reader, std::optional &storage) { static_assert(std::is_integral_v, "EntryTy must be an integral type"); uint64_t result = 0; bool flag = false; if (failed(reader.readVarIntWithFlag(result, flag))) return failure(); if (flag) storage = static_cast(result); else storage = std::nullopt; return success(); } //===--------------------------------------------------------------------===// // Tablegen generated bytecode functions //===--------------------------------------------------------------------===// #include "mlir/Dialect/LLVMIR/LLVMDialectBytecode.cpp.inc" //===--------------------------------------------------------------------===// // LLVMDialectBytecodeInterface //===--------------------------------------------------------------------===// /// This class implements the bytecode interface for the LLVM dialect. struct LLVMDialectBytecodeInterface : public BytecodeDialectInterface { LLVMDialectBytecodeInterface(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 LLVM::detail::addBytecodeInterface(LLVMDialect *dialect) { dialect->addInterfaces(); }