155 lines · cpp
1//===- LLVMDialectBytecode.cpp - LLVM Bytecode Implementation -------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "LLVMDialectBytecode.h"10#include "mlir/Bytecode/BytecodeImplementation.h"11#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"12#include "mlir/Dialect/LLVMIR/LLVMDialect.h"13#include "mlir/Dialect/LLVMIR/LLVMTypes.h"14#include "mlir/IR/Diagnostics.h"15#include "llvm/ADT/APFloat.h"16#include "llvm/ADT/SmallVector.h"17#include "llvm/ADT/TypeSwitch.h"18#include <type_traits>19 20using namespace mlir;21using namespace mlir::LLVM;22 23namespace {24 25// Provide some forward declarations of the functions that will be generated by26// the include below.27static void write(DIExpressionElemAttr attribute,28 DialectBytecodeWriter &writer);29static LogicalResult writeAttribute(Attribute attribute,30 DialectBytecodeWriter &writer);31 32//===--------------------------------------------------------------------===//33// Optional ArrayRefs34//35// Note that both the writer and reader functions consider attributes to be36// optional. This is because the attribute may be present or empty.37//===--------------------------------------------------------------------===//38 39template <class EntryTy>40static void writeOptionalArrayRef(DialectBytecodeWriter &writer,41 ArrayRef<EntryTy> storage) {42 if (storage.empty()) {43 writer.writeOwnedBool(false);44 return;45 }46 47 writer.writeOwnedBool(true);48 writer.writeList(storage, [&](EntryTy val) {49 if constexpr (std::is_base_of_v<Attribute, EntryTy>) {50 (void)writer.writeOptionalAttribute(val);51 } else if constexpr (std::is_integral_v<EntryTy>) {52 (void)writer.writeVarInt(val);53 } else {54 static_assert(true, "EntryTy not supported");55 }56 });57}58 59template <class EntryTy>60static LogicalResult readOptionalArrayRef(DialectBytecodeReader &reader,61 SmallVectorImpl<EntryTy> &storage) {62 bool isPresent = false;63 if (failed(reader.readBool(isPresent)))64 return failure();65 // Nothing to do here, the array is empty.66 if (!isPresent)67 return success();68 69 auto readEntry = [&]() -> FailureOr<EntryTy> {70 EntryTy temp;71 if constexpr (std::is_base_of_v<Attribute, EntryTy>) {72 if (succeeded(reader.readOptionalAttribute(temp)))73 return temp;74 } else if constexpr (std::is_integral_v<EntryTy>) {75 if (succeeded(reader.readVarInt(temp)))76 return temp;77 } else {78 static_assert(true, "EntryTy not supported");79 }80 return failure();81 };82 83 return reader.readList(storage, readEntry);84}85 86//===--------------------------------------------------------------------===//87// Optional integral types88//===--------------------------------------------------------------------===//89 90template <class EntryTy>91static void writeOptionalInt(DialectBytecodeWriter &writer,92 std::optional<EntryTy> storage) {93 static_assert(std::is_integral_v<EntryTy>,94 "EntryTy must be an integral type");95 EntryTy val = storage.value_or(0);96 writer.writeVarIntWithFlag(val, storage.has_value());97}98 99template <class EntryTy>100static LogicalResult readOptionalInt(DialectBytecodeReader &reader,101 std::optional<EntryTy> &storage) {102 static_assert(std::is_integral_v<EntryTy>,103 "EntryTy must be an integral type");104 uint64_t result = 0;105 bool flag = false;106 if (failed(reader.readVarIntWithFlag(result, flag)))107 return failure();108 if (flag)109 storage = static_cast<EntryTy>(result);110 else111 storage = std::nullopt;112 return success();113}114 115//===--------------------------------------------------------------------===//116// Tablegen generated bytecode functions117//===--------------------------------------------------------------------===//118 119#include "mlir/Dialect/LLVMIR/LLVMDialectBytecode.cpp.inc"120 121//===--------------------------------------------------------------------===//122// LLVMDialectBytecodeInterface123//===--------------------------------------------------------------------===//124 125/// This class implements the bytecode interface for the LLVM dialect.126struct LLVMDialectBytecodeInterface : public BytecodeDialectInterface {127 LLVMDialectBytecodeInterface(Dialect *dialect)128 : BytecodeDialectInterface(dialect) {}129 130 // Attributes131 Attribute readAttribute(DialectBytecodeReader &reader) const override {132 return ::readAttribute(getContext(), reader);133 }134 135 LogicalResult writeAttribute(Attribute attr,136 DialectBytecodeWriter &writer) const override {137 return ::writeAttribute(attr, writer);138 }139 140 // Types141 Type readType(DialectBytecodeReader &reader) const override {142 return ::readType(getContext(), reader);143 }144 145 LogicalResult writeType(Type type,146 DialectBytecodeWriter &writer) const override {147 return ::writeType(type, writer);148 }149};150} // namespace151 152void LLVM::detail::addBytecodeInterface(LLVMDialect *dialect) {153 dialect->addInterfaces<LLVMDialectBytecodeInterface>();154}155