#ifndef STANDALONE_STANDALONEDIALECT_H
#define STANDALONE_STANDALONEDIALECT_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/Dialect.h"
#include "Standalone/StandaloneOpsDialect.h.inc"
/// Read a reference to the given attribute.
virtual LogicalResult readAttribute(Attribute &result) = 0;
- /// Read an optional reference to the given attribute. Returns success even if
- /// the Attribute isn't present.
- virtual LogicalResult readOptionalAttribute(Attribute &attr) = 0;
-
template <typename T>
LogicalResult readAttributes(SmallVectorImpl<T> &attrs) {
return readList(attrs, [this](T &attr) { return readAttribute(attr); });
return emitError() << "expected " << llvm::getTypeName<T>()
<< ", but got: " << baseResult;
}
- template <typename T>
- LogicalResult readOptionalAttribute(T &result) {
- Attribute baseResult;
- if (failed(readOptionalAttribute(baseResult)))
- return failure();
- if (!baseResult)
- return success();
- if ((result = dyn_cast<T>(baseResult)))
- return success();
- return emitError() << "expected " << llvm::getTypeName<T>()
- << ", but got: " << baseResult;
- }
/// Read a reference to the given type.
virtual LogicalResult readType(Type &result) = 0;
/// Write a reference to the given attribute.
virtual void writeAttribute(Attribute attr) = 0;
- virtual void writeOptionalAttribute(Attribute attr) = 0;
template <typename T>
void writeAttributes(ArrayRef<T> attrs) {
writeList(attrs, [this](T attr) { writeAttribute(attr); });
+++ /dev/null
-//===- CallInterfaces.h - Call Interfaces for MLIR --------------*- C++ -*-===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the definitions of the BytecodeOpInterface defined in
-// `BytecodeOpInterface.td`.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef MLIR_BYTECODE_BYTECODEOPINTERFACE_H
-#define MLIR_BYTECODE_BYTECODEOPINTERFACE_H
-
-#include "mlir/Bytecode/BytecodeImplementation.h"
-#include "mlir/Bytecode/BytecodeOpInterface.h"
-#include "mlir/Bytecode/BytecodeReader.h"
-#include "mlir/Bytecode/BytecodeWriter.h"
-#include "mlir/IR/OpDefinition.h"
-#include "mlir/Support/LogicalResult.h"
-
-/// Include the generated interface declarations.
-#include "mlir/Bytecode/BytecodeOpInterface.h.inc"
-
-#endif // MLIR_BYTECODE_BYTECODEOPINTERFACE_H
+++ /dev/null
-//===- BytecodeOpInterface.td - Bytecode OpInterface -------*- tablegen -*-===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains an interface for operation interactions with the bytecode
-// serialization/deserialization, in particular for properties.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef MLIR_BYTECODE_BYTECODEOPINTERFACES
-#define MLIR_BYTECODE_BYTECODEOPINTERFACES
-
-include "mlir/IR/OpBase.td"
-
-// `BytecodeOpInterface`
-def BytecodeOpInterface : OpInterface<"BytecodeOpInterface"> {
- let description = [{
- This interface allows operation to control the serialization of their
- properties.
- }];
- let cppNamespace = "::mlir";
-
- let methods = [
- StaticInterfaceMethod<[{
- Read the properties for this operation from the bytecode and populate the state.
- }],
- "LogicalResult", "readProperties", (ins
- "::mlir::DialectBytecodeReader &":$reader,
- "::mlir::OperationState &":$state)
- >,
- InterfaceMethod<[{
- Write the properties for this operation to the bytecode.
- }],
- "void", "writeProperties", (ins "::mlir::DialectBytecodeWriter &":$writer)
- >,
- ];
-}
-
-#endif // MLIR_BYTECODE_BYTECODEOPINTERFACES
/// is returned by bytecode writer entry point.
void setDesiredBytecodeVersion(int64_t bytecodeVersion);
- /// Get the set desired bytecode version to emit.
- int64_t getDesiredBytecodeVersion() const;
-
//===--------------------------------------------------------------------===//
// Resources
//===--------------------------------------------------------------------===//
+++ /dev/null
-add_mlir_interface(BytecodeOpInterface)
kMinSupportedVersion = 0,
/// The current bytecode version.
- kVersion = 5,
+ kVersion = 4,
/// An arbitrary value used to fill alignment padding.
kAlignmentByte = 0xCB,
/// This section contains the versions of each dialect.
kDialectVersions = 7,
- /// This section contains the properties for the operations.
- kProperties = 8,
-
/// The total number of section types.
- kNumSections = 9,
+ kNumSections = 8,
};
} // namespace Section
kHasSuccessors = 0b00001000,
kHasInlineRegions = 0b00010000,
kHasUseListOrders = 0b00100000,
- kHasProperties = 0b01000000,
// clang-format on
};
} // namespace OpEncodingMask
-add_subdirectory(Bytecode)
add_subdirectory(Conversion)
add_subdirectory(Dialect)
add_subdirectory(IR)
#ifndef MLIR_DIALECT_AMDGPU_IR_AMDGPUDIALECT_H_
#define MLIR_DIALECT_AMDGPU_IR_AMDGPUDIALECT_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#ifndef MLIR_DIALECT_AMX_AMXDIALECT_H_
#define MLIR_DIALECT_AMX_AMXDIALECT_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#ifndef MLIR_DIALECT_AFFINE_TRANSFORMOPS_AFFINETRANSFORMOPS_H
#define MLIR_DIALECT_AFFINE_TRANSFORMOPS_AFFINETRANSFORMOPS_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
#include "mlir/Dialect/Transform/IR/TransformTypes.h"
#include "mlir/IR/OpImplementation.h"
#ifndef MLIR_DIALECT_ARITH_IR_ARITH_H_
#define MLIR_DIALECT_ARITH_IR_ARITH_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/OpImplementation.h"
#ifndef MLIR_DIALECT_ARMNEON_ARMNEONDIALECT_H_
#define MLIR_DIALECT_ARMNEON_ARMNEONDIALECT_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#ifndef MLIR_DIALECT_ARMSVE_ARMSVEDIALECT_H
#define MLIR_DIALECT_ARMSVE_ARMSVEDIALECT_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#ifndef MLIR_DIALECT_ASYNC_IR_ASYNC_H
#define MLIR_DIALECT_ASYNC_IR_ASYNC_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/Async/IR/AsyncTypes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#ifndef MLIR_DIALECT_BUFFERIZATION_IR_BUFFERIZATION_H_
#define MLIR_DIALECT_BUFFERIZATION_IR_BUFFERIZATION_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/Bufferization/IR/AllocationOpInterface.h"
#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
#include "mlir/Interfaces/CopyOpInterface.h"
#ifndef MLIR_DIALECT_BUFFERIZATION_TRANSFORMOPS_BUFFERIZATIONTRANSFORMOPS_H
#define MLIR_DIALECT_BUFFERIZATION_TRANSFORMOPS_BUFFERIZATIONTRANSFORMOPS_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
#include "mlir/Dialect/Transform/IR/TransformTypes.h"
#ifndef MLIR_DIALECT_COMPLEX_IR_COMPLEX_H_
#define MLIR_DIALECT_COMPLEX_IR_COMPLEX_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/Interfaces/InferTypeOpInterface.h"
#ifndef MLIR_DIALECT_CONTROLFLOW_IR_CONTROLFLOW_H
#define MLIR_DIALECT_CONTROLFLOW_IR_CONTROLFLOW_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/Dialect.h"
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOpsDialect.h.inc"
#ifndef MLIR_DIALECT_CONTROLFLOW_IR_CONTROLFLOWOPS_H
#define MLIR_DIALECT_CONTROLFLOW_IR_CONTROLFLOWOPS_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/ControlFlow/IR/ControlFlow.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#ifndef MLIR_DIALECT_EMITC_IR_EMITC_H
#define MLIR_DIALECT_EMITC_IR_EMITC_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#ifndef MLIR_DIALECT_FUNC_IR_OPS_H
#define MLIR_DIALECT_FUNC_IR_OPS_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#ifndef MLIR_DIALECT_GPU_IR_GPUDIALECT_H
#define MLIR_DIALECT_GPU_IR_GPUDIALECT_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/DLTI/Traits.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#ifndef MLIR_DIALECT_IRDL_IR_IRDL_H_
#define MLIR_DIALECT_IRDL_IR_IRDL_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/IRDL/IR/IRDLInterfaces.h"
#include "mlir/Dialect/IRDL/IR/IRDLTraits.h"
#include "mlir/IR/SymbolTable.h"
#include "mlir/Interfaces/InferTypeOpInterface.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
-
#include <memory>
// Forward declaration.
#ifndef MLIR_DIALECT_INDEX_IR_INDEXOPS_H
#define MLIR_DIALECT_INDEX_IR_INDEXOPS_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/Index/IR/IndexAttrs.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpDefinition.h"
#ifndef MLIR_DIALECT_LLVMIR_LLVMDIALECT_H_
#define MLIR_DIALECT_LLVMIR_LLVMDIALECT_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
#include "mlir/Dialect/LLVMIR/LLVMInterfaces.h"
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
#ifndef MLIR_DIALECT_LLVMIR_NVVMDIALECT_H_
#define MLIR_DIALECT_LLVMIR_NVVMDIALECT_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#ifndef MLIR_DIALECT_LLVMIR_ROCDLDIALECT_H_
#define MLIR_DIALECT_LLVMIR_ROCDLDIALECT_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#ifndef MLIR_DIALECT_LINALG_IR_LINALG_H
#define MLIR_DIALECT_LINALG_IR_LINALG_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/Utils/ReshapeOpsUtils.h"
#include "mlir/Dialect/Utils/StructuredOpsUtils.h"
#include "mlir/IR/AffineExpr.h"
#ifndef MLIR_DIALECT_MLPROGRAM_IR_MLPROGRAM_H_
#define MLIR_DIALECT_MLPROGRAM_IR_MLPROGRAM_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/MLProgram/IR/MLProgramAttributes.h"
#include "mlir/Dialect/MLProgram/IR/MLProgramTypes.h"
#include "mlir/IR/Dialect.h"
#ifndef MLIR_DIALECT_MATH_IR_MATH_H_
#define MLIR_DIALECT_MATH_IR_MATH_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#ifndef MLIR_DIALECT_MEMREF_IR_MEMREF_H_
#define MLIR_DIALECT_MEMREF_IR_MEMREF_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Utils/ReshapeOpsUtils.h"
#include "mlir/IR/Dialect.h"
#include "mlir/Interfaces/ShapedOpInterfaces.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
#include "mlir/Interfaces/ViewLikeInterface.h"
-
#include <optional>
namespace mlir {
#ifndef MLIR_DIALECT_MEMREF_TRANSFORMOPS_MEMREFTRANSFORMOPS_H
#define MLIR_DIALECT_MEMREF_TRANSFORMOPS_MEMREFTRANSFORMOPS_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
#include "mlir/IR/OpImplementation.h"
#ifndef MLIR_DIALECT_NVGPU_NVGPUDIALECT_H_
#define MLIR_DIALECT_NVGPU_NVGPUDIALECT_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/SymbolTable.h"
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/OpenACC/OpenACCOpsDialect.h.inc"
#include "mlir/Dialect/OpenACC/OpenACCOpsEnums.h.inc"
#include "mlir/Dialect/OpenACC/OpenACCTypeInterfaces.h.inc"
#ifndef MLIR_DIALECT_PDL_IR_PDLOPS_H_
#define MLIR_DIALECT_PDL_IR_PDLOPS_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/PDL/IR/PDLTypes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/OpImplementation.h"
#ifndef MLIR_DIALECT_PDLINTERP_IR_PDLINTERP_H_
#define MLIR_DIALECT_PDLINTERP_IR_PDLINTERP_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/PDL/IR/PDL.h"
#include "mlir/Dialect/PDL/IR/PDLTypes.h"
#include "mlir/IR/FunctionInterfaces.h"
#ifndef MLIR_DIALECT_SCF_TRANSFORMOPS_SCFTRANSFORMOPS_H
#define MLIR_DIALECT_SCF_TRANSFORMOPS_SCFTRANSFORMOPS_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
#include "mlir/Dialect/Transform/IR/TransformTypes.h"
#include "mlir/IR/OpImplementation.h"
#ifndef MLIR_DIALECT_SPIRV_IR_SPIRVOPS_H_
#define MLIR_DIALECT_SPIRV_IR_SPIRVOPS_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/SPIRV/IR/SPIRVAttributes.h"
#include "mlir/Dialect/SPIRV/IR/SPIRVOpTraits.h"
#include "mlir/Dialect/SPIRV/IR/SPIRVTypes.h"
#ifndef MLIR_DIALECT_SHAPE_IR_SHAPE_H
#define MLIR_DIALECT_SHAPE_IR_SHAPE_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/FunctionInterfaces.h"
#ifndef MLIR_DIALECT_SPARSETENSOR_IR_SPARSETENSOR_H_
#define MLIR_DIALECT_SPARSETENSOR_IR_SPARSETENSOR_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/SparseTensor/IR/Enums.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#ifndef MLIR_DIALECT_TENSOR_IR_TENSOR_H_
#define MLIR_DIALECT_TENSOR_IR_TENSOR_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/Utils/ReshapeOpsUtils.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#ifndef MLIR_DIALECT_TOSA_IR_TOSAOPS_H
#define MLIR_DIALECT_TOSA_IR_TOSAOPS_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/Traits.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/Interfaces/InferTypeOpInterface.h"
#ifndef MLIR_DIALECT_TRANSFORM_IR_TRANSFORMOPS_H
#define MLIR_DIALECT_TRANSFORM_IR_TRANSFORMOPS_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/Transform/IR/MatchInterfaces.h"
#include "mlir/Dialect/Transform/IR/TransformAttrs.h"
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
#ifndef MLIR_DIALECT_TRANSFORM_PDLEXTENSION_PDLEXTENSIONOPS_H
#define MLIR_DIALECT_TRANSFORM_PDLEXTENSION_PDLEXTENSIONOPS_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/Transform/IR/TransformDialect.h"
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
#include "mlir/IR/OpDefinition.h"
#ifndef MLIR_DIALECT_VECTOR_IR_VECTOROPS_H
#define MLIR_DIALECT_VECTOR_IR_VECTOROPS_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/Vector/Interfaces/MaskableOpInterface.h"
#include "mlir/Dialect/Vector/Interfaces/MaskingOpInterface.h"
#include "mlir/IR/AffineMap.h"
#ifndef MLIR_DIALECT_X86VECTOR_X86VECTORDIALECT_H_
#define MLIR_DIALECT_X86VECTOR_X86VECTORDIALECT_H_
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
llvm::hash_value($_storage);
}];
- // The call expression to emit the storage type to bytecode.
- //
- // Format:
- // - `$_storage` is the storage type value.
- // - `$_writer` is a `DialectBytecodeWriter`.
- code writeToMlirBytecode = [{
- writeToMlirBytecode($_writer, $_storage)
- }];
-
- // The call expression to read the storage type from bytecode.
- //
- // Format:
- // - `$_storage` is the storage type value.
- // - `$_reader` is a `DialectBytecodeReader`.
- code readFromMlirBytecode = [{
- if (failed(readFromMlirBytecode($_reader, $_storage)))
- return failure();
- }];
-
// Default value for the property.
string defaultValue = ?;
}
//===----------------------------------------------------------------------===//
// Primitive property kinds
-// Any kind of integer stored as properties.
-class IntProperty<string storageTypeParam = "", string desc = ""> :
- Property<storageTypeParam, desc> {
- code writeToMlirBytecode = [{
- $_writer.writeVarInt($_storage);
- }];
- code readFromMlirBytecode = [{
- uint64_t val;
- if (failed($_reader.readVarInt(val)))
- return ::mlir::failure();
- $_storage = val;
- }];
-}
-
class ArrayProperty<string storageTypeParam = "", int n, string desc = ""> :
Property<storageTypeParam # "[" # n # "]", desc> {
let interfaceType = "::llvm::ArrayRef<" # storageTypeParam # ">";
// in the provided interface type and assign it to the storage.
StringRef getConvertFromAttributeCall() const;
- // Returns the method call which reads this property from
- // bytecode and assign it to the storage.
- StringRef getReadFromMlirBytecodeCall() const;
-
- // Returns the method call which write this property's
- // to the the bytecode.
- StringRef getWriteToMlirBytecodeCall() const;
-
// Returns the code to compute the hash for this property.
StringRef getHashPropertyCall() const;
+++ /dev/null
-//===- BytecodeOpInterface.cpp - Bytecode Op Interfaces -------------------===//
-//
-// 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 "mlir/Bytecode/BytecodeOpInterface.h"
-
-using namespace mlir;
-
-//===----------------------------------------------------------------------===//
-// BytecodeOpInterface
-//===----------------------------------------------------------------------===//
-
-#include "mlir/Bytecode/BytecodeOpInterface.cpp.inc"
add_subdirectory(Reader)
add_subdirectory(Writer)
-
-add_mlir_library(MLIRBytecodeOpInterface
- BytecodeOpInterface.cpp
-
- ADDITIONAL_HEADER_DIRS
- ${MLIR_MAIN_INCLUDE_DIR}/mlir/Bytecode
-
- LINK_LIBS PUBLIC
- MLIRIR
- MLIRSupport
- )
#include "mlir/Bytecode/BytecodeReader.h"
#include "mlir/AsmParser/AsmParser.h"
#include "mlir/Bytecode/BytecodeImplementation.h"
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Bytecode/Encoding.h"
#include "mlir/IR/BuiltinDialect.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/Visitors.h"
#include "mlir/Support/LLVM.h"
#include "mlir/Support/LogicalResult.h"
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/MemoryBufferRef.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/SourceMgr.h"
-#include <cstddef>
#include <list>
#include <memory>
#include <numeric>
return "ResourceOffset (6)";
case bytecode::Section::kDialectVersions:
return "DialectVersions (7)";
- case bytecode::Section::kProperties:
- return "Properties (8)";
default:
return ("Unknown (" + Twine(static_cast<unsigned>(sectionID)) + ")").str();
}
}
/// Returns true if the given top-level section ID is optional.
-static bool isSectionOptional(bytecode::Section::ID sectionID, int version) {
+static bool isSectionOptional(bytecode::Section::ID sectionID) {
switch (sectionID) {
case bytecode::Section::kString:
case bytecode::Section::kDialect:
case bytecode::Section::kResourceOffset:
case bytecode::Section::kDialectVersions:
return true;
- case bytecode::Section::kProperties:
- return version < 4;
default:
llvm_unreachable("unknown section ID");
}
/// Parse a shared string from the string section. The shared string is
/// encoded using an index to a corresponding string in the string section.
- /// This variant parses a flag compressed with the index.
- LogicalResult parseStringWithFlag(EncodingReader &reader, StringRef &result,
- bool &flag) {
- uint64_t entryIdx;
- if (failed(reader.parseVarIntWithFlag(entryIdx, flag)))
- return failure();
- return parseStringAtIndex(reader, entryIdx, result);
- }
-
- /// Parse a shared string from the string section. The shared string is
- /// encoded using an index to a corresponding string in the string section.
LogicalResult parseStringAtIndex(EncodingReader &reader, uint64_t index,
StringRef &result) {
return resolveEntry(reader, strings, index, result, "string");
/// This struct represents an operation name entry within the bytecode.
struct BytecodeOperationName {
- BytecodeOperationName(BytecodeDialect *dialect, StringRef name,
- bool wasRegistered)
- : dialect(dialect), name(name), wasRegistered(wasRegistered) {}
+ BytecodeOperationName(BytecodeDialect *dialect, StringRef name)
+ : dialect(dialect), name(name) {}
/// The loaded operation name, or std::nullopt if it hasn't been processed
/// yet.
/// The name of the operation, without the dialect prefix.
StringRef name;
-
- /// Whether this operation was registered when the bytecode was produced.
- /// This flag is populated when bytecode version >=4.
- bool wasRegistered;
};
} // namespace
result = resolveAttribute(attrIdx);
return success(!!result);
}
- LogicalResult parseOptionalAttribute(EncodingReader &reader,
- Attribute &result) {
- uint64_t attrIdx;
- bool flag;
- if (failed(reader.parseVarIntWithFlag(attrIdx, flag)))
- return failure();
- if (!flag)
- return success();
- result = resolveAttribute(attrIdx);
- return success(!!result);
- }
-
LogicalResult parseType(EncodingReader &reader, Type &result) {
uint64_t typeIdx;
if (failed(reader.parseVarInt(typeIdx)))
LogicalResult readAttribute(Attribute &result) override {
return attrTypeReader.parseAttribute(reader, result);
}
- LogicalResult readOptionalAttribute(Attribute &result) override {
- return attrTypeReader.parseOptionalAttribute(reader, result);
- }
+
LogicalResult readType(Type &result) override {
return attrTypeReader.parseType(reader, result);
}
ResourceSectionReader &resourceReader;
EncodingReader &reader;
};
-
-/// Wraps the properties section and handles reading properties out of it.
-class PropertiesSectionReader {
-public:
- /// Initialize the properties section reader with the given section data.
- LogicalResult initialize(Location fileLoc, ArrayRef<uint8_t> sectionData) {
- if (sectionData.empty())
- return success();
- EncodingReader propReader(sectionData, fileLoc);
- uint64_t count;
- if (failed(propReader.parseVarInt(count)))
- return failure();
- // Parse the raw properties buffer.
- if (failed(propReader.parseBytes(propReader.size(), propertiesBuffers)))
- return failure();
-
- EncodingReader offsetsReader(propertiesBuffers, fileLoc);
- offsetTable.reserve(count);
- for (auto idx : llvm::seq<int64_t>(0, count)) {
- (void)idx;
- offsetTable.push_back(propertiesBuffers.size() - offsetsReader.size());
- ArrayRef<uint8_t> rawProperties;
- uint64_t dataSize;
- if (failed(offsetsReader.parseVarInt(dataSize)) ||
- failed(offsetsReader.parseBytes(dataSize, rawProperties)))
- return failure();
- }
- if (!offsetsReader.empty())
- return offsetsReader.emitError()
- << "Broken properties section: didn't exhaust the offsets table";
- return success();
- }
-
- LogicalResult read(Location fileLoc, DialectReader &dialectReader,
- OperationName *opName, OperationState &opState) {
- uint64_t propertiesIdx;
- if (failed(dialectReader.readVarInt(propertiesIdx)))
- return failure();
- if (propertiesIdx >= offsetTable.size())
- return dialectReader.emitError("Properties idx out-of-bound for ")
- << opName->getStringRef();
- size_t propertiesOffset = offsetTable[propertiesIdx];
- if (propertiesIdx >= propertiesBuffers.size())
- return dialectReader.emitError("Properties offset out-of-bound for ")
- << opName->getStringRef();
-
- // Acquire the sub-buffer that represent the requested properties.
- ArrayRef<char> rawProperties;
- {
- // "Seek" to the requested offset by getting a new reader with the right
- // sub-buffer.
- EncodingReader reader(propertiesBuffers.drop_front(propertiesOffset),
- fileLoc);
- // Properties are stored as a sequence of {size + raw_data}.
- if (failed(
- dialectReader.withEncodingReader(reader).readBlob(rawProperties)))
- return failure();
- }
- // Setup a new reader to read from the `rawProperties` sub-buffer.
- EncodingReader reader(
- StringRef(rawProperties.begin(), rawProperties.size()), fileLoc);
- DialectReader propReader = dialectReader.withEncodingReader(reader);
-
- auto *iface = opName->getInterface<BytecodeOpInterface>();
- if (iface)
- return iface->readProperties(propReader, opState);
- if (opName->isRegistered())
- return propReader.emitError(
- "has properties but missing BytecodeOpInterface for ")
- << opName->getStringRef();
- // Unregistered op are storing properties as an attribute.
- return propReader.readAttribute(opState.propertiesAttr);
- }
-
-private:
- /// The properties buffer referenced within the bytecode file.
- ArrayRef<uint8_t> propertiesBuffers;
-
- /// Table of offset in the buffer above.
- SmallVector<int64_t> offsetTable;
-};
} // namespace
LogicalResult
lazyLoadableOps.erase(it->getSecond());
lazyLoadableOpsMap.erase(it);
auto result = parseRegions(regionStack, regionStack.back());
- assert((regionStack.empty() || failed(result)) &&
- "broken invariant: regionStack should be empty when parseRegions "
- "succeeds");
+ assert(regionStack.empty());
return result;
}
LogicalResult parseDialectSection(ArrayRef<uint8_t> sectionData);
/// Parse an operation name reference using the given reader.
- FailureOr<OperationName> parseOpName(EncodingReader &reader,
- bool &wasRegistered);
+ FailureOr<OperationName> parseOpName(EncodingReader &reader);
//===--------------------------------------------------------------------===//
// Attribute/Type Section
/// The table of strings referenced within the bytecode file.
StringSectionReader stringReader;
- /// The table of properties referenced by the operation in the bytecode file.
- PropertiesSectionReader propertiesReader;
-
/// The current set of available IR value scopes.
std::vector<ValueScope> valueScopes;
// Check that all of the required sections were found.
for (int i = 0; i < bytecode::Section::kNumSections; ++i) {
bytecode::Section::ID sectionID = static_cast<bytecode::Section::ID>(i);
- if (!sectionDatas[i] && !isSectionOptional(sectionID, version)) {
+ if (!sectionDatas[i] && !isSectionOptional(sectionID)) {
return reader.emitError("missing data for top-level section: ",
::toString(sectionID));
}
fileLoc, *sectionDatas[bytecode::Section::kString])))
return failure();
- // Process the properties section.
- if (sectionDatas[bytecode::Section::kProperties] &&
- failed(propertiesReader.initialize(
- fileLoc, *sectionDatas[bytecode::Section::kProperties])))
- return failure();
-
// Process the dialect section.
if (failed(parseDialectSection(*sectionDatas[bytecode::Section::kDialect])))
return failure();
// Parse the operation names, which are grouped by dialect.
auto parseOpName = [&](BytecodeDialect *dialect) {
StringRef opName;
- bool wasRegistered;
- // Prior to version 4, the information about wheter an op was registered or
- // not wasn't encoded.
- if (version < 4) {
- if (failed(stringReader.parseString(sectionReader, opName)))
- return failure();
- } else {
- if (failed(stringReader.parseStringWithFlag(sectionReader, opName,
- wasRegistered)))
- return failure();
- }
- opNames.emplace_back(dialect, opName, wasRegistered);
+ if (failed(stringReader.parseString(sectionReader, opName)))
+ return failure();
+ opNames.emplace_back(dialect, opName);
return success();
};
// Avoid re-allocation in bytecode version > 3 where the number of ops are
}
FailureOr<OperationName>
-BytecodeReader::Impl::parseOpName(EncodingReader &reader, bool &wasRegistered) {
+BytecodeReader::Impl::parseOpName(EncodingReader &reader) {
BytecodeOperationName *opName = nullptr;
if (failed(parseEntry(reader, opNames, opName, "operation name")))
return failure();
- wasRegistered = opName->wasRegistered;
+
// Check to see if this operation name has already been resolved. If we
// haven't, load the dialect and build the operation name.
if (!opName->opName) {
RegionReadState &readState,
bool &isIsolatedFromAbove) {
// Parse the name of the operation.
- bool wasRegistered;
- FailureOr<OperationName> opName = parseOpName(reader, wasRegistered);
+ FailureOr<OperationName> opName = parseOpName(reader);
if (failed(opName))
return failure();
opState.attributes = dictAttr;
}
- if (opMask & bytecode::OpEncodingMask::kHasProperties) {
- if (wasRegistered) {
- DialectReader dialectReader(attrTypeReader, stringReader, resourceReader,
- reader);
- if (failed(
- propertiesReader.read(fileLoc, dialectReader, &*opName, opState)))
- return failure();
- } else {
- // If the operation wasn't registered when it was emitted, the properties
- // was serialized as an attribute.
- if (failed(parseAttribute(reader, opState.propertiesAttr)))
- return failure();
- }
- }
-
/// Parse the results of the operation.
if (opMask & bytecode::OpEncodingMask::kHasResults) {
uint64_t numResults;
#include "mlir/Bytecode/BytecodeWriter.h"
#include "IRNumbering.h"
#include "mlir/Bytecode/BytecodeImplementation.h"
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Bytecode/Encoding.h"
-#include "mlir/IR/Attributes.h"
-#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/OpImplementation.h"
-#include "mlir/Support/LogicalResult.h"
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstddef>
-#include <cstdint>
-#include <cstring>
-#include <optional>
-#include <sys/types.h>
#define DEBUG_TYPE "mlir-bytecode-writer"
std::min<int64_t>(bytecodeVersion, bytecode::kVersion);
}
-int64_t BytecodeWriterConfig::getDesiredBytecodeVersion() const {
- return impl->bytecodeVersion;
-}
-
//===----------------------------------------------------------------------===//
// EncodingEmitter
//===----------------------------------------------------------------------===//
void writeAttribute(Attribute attr) override {
emitter.emitVarInt(numberingState.getNumber(attr));
}
- void writeOptionalAttribute(Attribute attr) override {
- if (!attr) {
- emitter.emitVarInt(0);
- return;
- }
- emitter.emitVarIntWithFlag(numberingState.getNumber(attr), true);
- }
-
void writeType(Type type) override {
emitter.emitVarInt(numberingState.getNumber(type));
}
StringSectionBuilder &stringSection;
};
-namespace {
-class PropertiesSectionBuilder {
-public:
- PropertiesSectionBuilder(IRNumberingState &numberingState,
- StringSectionBuilder &stringSection,
- const BytecodeWriterConfig::Impl &config)
- : numberingState(numberingState), stringSection(stringSection),
- config(config) {}
-
- /// Emit the op properties in the properties section and return the index of
- /// the properties within the section. Return -1 if no properties was emitted.
- std::optional<ssize_t> emit(Operation *op) {
- EncodingEmitter propertiesEmitter;
- if (!op->getPropertiesStorageSize())
- return std::nullopt;
- if (!op->isRegistered()) {
- // Unregistered op are storing properties as an optional attribute.
- Attribute prop = *op->getPropertiesStorage().as<Attribute *>();
- if (!prop)
- return std::nullopt;
- EncodingEmitter sizeEmitter;
- sizeEmitter.emitVarInt(numberingState.getNumber(prop));
- scratch.clear();
- llvm::raw_svector_ostream os(scratch);
- sizeEmitter.writeTo(os);
- return emit(scratch);
- }
-
- EncodingEmitter emitter;
- DialectWriter propertiesWriter(config.bytecodeVersion, emitter,
- numberingState, stringSection);
- auto iface = cast<BytecodeOpInterface>(op);
- iface.writeProperties(propertiesWriter);
- scratch.clear();
- llvm::raw_svector_ostream os(scratch);
- emitter.writeTo(os);
- return emit(scratch);
- }
-
- /// Write the current set of properties to the given emitter.
- void write(EncodingEmitter &emitter) {
- emitter.emitVarInt(propertiesStorage.size());
- if (propertiesStorage.empty())
- return;
- for (const auto &storage : propertiesStorage) {
- if (storage.empty()) {
- emitter.emitBytes(ArrayRef<uint8_t>());
- continue;
- }
- emitter.emitBytes(ArrayRef(reinterpret_cast<const uint8_t *>(&storage[0]),
- storage.size()));
- }
- }
-
- /// Returns true if the section is empty.
- bool empty() { return propertiesStorage.empty(); }
-
-private:
- /// Emit raw data and returns the offset in the internal buffer.
- /// Data are deduplicated and will be copied in the internal buffer only if
- /// they don't exist there already.
- ssize_t emit(ArrayRef<char> rawProperties) {
- // Populate a scratch buffer with the properties size.
- SmallVector<char> sizeScratch;
- {
- EncodingEmitter sizeEmitter;
- sizeEmitter.emitVarInt(rawProperties.size());
- llvm::raw_svector_ostream os(sizeScratch);
- sizeEmitter.writeTo(os);
- }
- // Append a new storage to the table now.
- size_t index = propertiesStorage.size();
- propertiesStorage.emplace_back();
- std::vector<char> &newStorage = propertiesStorage.back();
- size_t propertiesSize = sizeScratch.size() + rawProperties.size();
- newStorage.reserve(propertiesSize);
- newStorage.insert(newStorage.end(), sizeScratch.begin(), sizeScratch.end());
- newStorage.insert(newStorage.end(), rawProperties.begin(),
- rawProperties.end());
-
- // Try to de-duplicate the new serialized properties.
- // If the properties is a duplicate, pop it back from the storage.
- auto inserted = propertiesUniquing.insert(
- std::make_pair(ArrayRef<char>(newStorage), index));
- if (!inserted.second)
- propertiesStorage.pop_back();
- return inserted.first->getSecond();
- }
-
- /// Storage for properties.
- std::vector<std::vector<char>> propertiesStorage;
- SmallVector<char> scratch;
- DenseMap<ArrayRef<char>, int64_t> propertiesUniquing;
- IRNumberingState &numberingState;
- StringSectionBuilder &stringSection;
- const BytecodeWriterConfig::Impl &config;
-};
-} // namespace
-
/// A simple raw_ostream wrapper around a EncodingEmitter. This removes the need
/// to go through an intermediate buffer when interacting with code that wants a
/// raw_ostream.
namespace {
class BytecodeWriter {
public:
- BytecodeWriter(Operation *op, const BytecodeWriterConfig &config)
- : numberingState(op, config), config(config.getImpl()),
- propertiesSection(numberingState, stringSection, config.getImpl()) {}
+ BytecodeWriter(Operation *op, const BytecodeWriterConfig::Impl &config)
+ : numberingState(op), config(config) {}
/// Write the bytecode for the given root operation.
- LogicalResult write(Operation *rootOp, raw_ostream &os);
+ void write(Operation *rootOp, raw_ostream &os);
private:
//===--------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//
// Operations
- LogicalResult writeBlock(EncodingEmitter &emitter, Block *block);
- LogicalResult writeOp(EncodingEmitter &emitter, Operation *op);
- LogicalResult writeRegion(EncodingEmitter &emitter, Region *region);
- LogicalResult writeIRSection(EncodingEmitter &emitter, Operation *op);
+ void writeBlock(EncodingEmitter &emitter, Block *block);
+ void writeOp(EncodingEmitter &emitter, Operation *op);
+ void writeRegion(EncodingEmitter &emitter, Region *region);
+ void writeIRSection(EncodingEmitter &emitter, Operation *op);
//===--------------------------------------------------------------------===//
// Resources
void writeStringSection(EncodingEmitter &emitter);
//===--------------------------------------------------------------------===//
- // Properties
-
- void writePropertiesSection(EncodingEmitter &emitter);
-
- //===--------------------------------------------------------------------===//
// Helpers
void writeUseListOrders(EncodingEmitter &emitter, uint8_t &opEncodingMask,
/// Configuration dictating bytecode emission.
const BytecodeWriterConfig::Impl &config;
-
- /// Storage for the properties section
- PropertiesSectionBuilder propertiesSection;
};
} // namespace
-LogicalResult BytecodeWriter::write(Operation *rootOp, raw_ostream &os) {
+void BytecodeWriter::write(Operation *rootOp, raw_ostream &os) {
EncodingEmitter emitter;
// Emit the bytecode file header. This is how we identify the output as a
writeAttrTypeSection(emitter);
// Emit the IR section.
- if (failed(writeIRSection(emitter, rootOp)))
- return failure();
+ writeIRSection(emitter, rootOp);
// Emit the resources section.
writeResourceSection(rootOp, emitter);
// Emit the string section.
writeStringSection(emitter);
- // Emit the properties section.
- if (config.bytecodeVersion >= 5)
- writePropertiesSection(emitter);
- else if (!propertiesSection.empty())
- return rootOp->emitError(
- "unexpected properties emitted incompatible with bytecode <5");
-
// Write the generated bytecode to the provided output stream.
emitter.writeTo(os);
-
- return success();
}
//===----------------------------------------------------------------------===//
// Emit the referenced operation names grouped by dialect.
auto emitOpName = [&](OpNameNumbering &name) {
- size_t stringId = stringSection.insert(name.name.stripDialect());
- if (config.bytecodeVersion < 4)
- dialectEmitter.emitVarInt(stringId);
- else
- dialectEmitter.emitVarIntWithFlag(stringId, name.name.isRegistered());
+ dialectEmitter.emitVarInt(stringSection.insert(name.name.stripDialect()));
};
writeDialectGrouping(dialectEmitter, numberingState.getOpNames(), emitOpName);
//===----------------------------------------------------------------------===//
// Operations
-LogicalResult BytecodeWriter::writeBlock(EncodingEmitter &emitter,
- Block *block) {
+void BytecodeWriter::writeBlock(EncodingEmitter &emitter, Block *block) {
ArrayRef<BlockArgument> args = block->getArguments();
bool hasArgs = !args.empty();
// Emit the operations within the block.
for (Operation &op : *block)
- if (failed(writeOp(emitter, &op)))
- return failure();
- return success();
+ writeOp(emitter, &op);
}
-LogicalResult BytecodeWriter::writeOp(EncodingEmitter &emitter, Operation *op) {
+void BytecodeWriter::writeOp(EncodingEmitter &emitter, Operation *op) {
emitter.emitVarInt(numberingState.getNumber(op->getName()));
// Emit a mask for the operation components. We need to fill this in later
emitter.emitVarInt(numberingState.getNumber(op->getLoc()));
// Emit the attributes of this operation.
- DictionaryAttr attrs = op->getDiscardableAttrDictionary();
- // Allow deployment to version <4 by merging inherent attribute with the
- // discardable ones. We should fail if there are any conflicts.
- if (config.bytecodeVersion < 4)
- attrs = op->getAttrDictionary();
+ DictionaryAttr attrs = op->getAttrDictionary();
if (!attrs.empty()) {
opEncodingMask |= bytecode::OpEncodingMask::kHasAttrs;
- emitter.emitVarInt(numberingState.getNumber(attrs));
- }
-
- // Emit the properties of this operation, for now we still support deployment
- // to version <4.
- if (config.bytecodeVersion >= 4) {
- std::optional<ssize_t> propertiesId = propertiesSection.emit(op);
- if (propertiesId.has_value()) {
- opEncodingMask |= bytecode::OpEncodingMask::kHasProperties;
- emitter.emitVarInt(*propertiesId);
- }
+ emitter.emitVarInt(numberingState.getNumber(op->getAttrDictionary()));
}
// Emit the result types of the operation.
// If the region is not isolated from above, or we are emitting bytecode
// targeting version <2, we don't use a section.
if (!isIsolatedFromAbove || config.bytecodeVersion < 2) {
- if (failed(writeRegion(emitter, ®ion)))
- return failure();
+ writeRegion(emitter, ®ion);
continue;
}
EncodingEmitter regionEmitter;
- if (failed(writeRegion(regionEmitter, ®ion)))
- return failure();
+ writeRegion(regionEmitter, ®ion);
emitter.emitSection(bytecode::Section::kIR, std::move(regionEmitter));
}
}
- return success();
}
void BytecodeWriter::writeUseListOrders(EncodingEmitter &emitter,
}
}
-LogicalResult BytecodeWriter::writeRegion(EncodingEmitter &emitter,
- Region *region) {
+void BytecodeWriter::writeRegion(EncodingEmitter &emitter, Region *region) {
// If the region is empty, we only need to emit the number of blocks (which is
// zero).
- if (region->empty()) {
- emitter.emitVarInt(/*numBlocks*/ 0);
- return success();
- }
+ if (region->empty())
+ return emitter.emitVarInt(/*numBlocks*/ 0);
// Emit the number of blocks and values within the region.
unsigned numBlocks, numValues;
// Emit the blocks within the region.
for (Block &block : *region)
- if (failed(writeBlock(emitter, &block)))
- return failure();
- return success();
+ writeBlock(emitter, &block);
}
-LogicalResult BytecodeWriter::writeIRSection(EncodingEmitter &emitter,
- Operation *op) {
+void BytecodeWriter::writeIRSection(EncodingEmitter &emitter, Operation *op) {
EncodingEmitter irEmitter;
// Write the IR section the same way as a block with no arguments. Note that
irEmitter.emitVarIntWithFlag(/*numOps*/ 1, /*hasArgs*/ false);
// Emit the operations.
- if (failed(writeOp(irEmitter, op)))
- return failure();
+ writeOp(irEmitter, op);
emitter.emitSection(bytecode::Section::kIR, std::move(irEmitter));
- return success();
}
//===----------------------------------------------------------------------===//
}
//===----------------------------------------------------------------------===//
-// Properties
-
-void BytecodeWriter::writePropertiesSection(EncodingEmitter &emitter) {
- EncodingEmitter propertiesEmitter;
- propertiesSection.write(propertiesEmitter);
- emitter.emitSection(bytecode::Section::kProperties,
- std::move(propertiesEmitter));
-}
-
-//===----------------------------------------------------------------------===//
// Entry Points
//===----------------------------------------------------------------------===//
LogicalResult mlir::writeBytecodeToFile(Operation *op, raw_ostream &os,
const BytecodeWriterConfig &config) {
- BytecodeWriter writer(op, config);
- return writer.write(op, os);
+ BytecodeWriter writer(op, config.getImpl());
+ writer.write(op, os);
+ // Currently there is no failure case.
+ return success();
}
LINK_LIBS PUBLIC
MLIRIR
MLIRSupport
- MLIRBytecodeOpInterface
)
#include "IRNumbering.h"
#include "mlir/Bytecode/BytecodeImplementation.h"
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/AsmState.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpDefinition.h"
NumberingDialectWriter(IRNumberingState &state) : state(state) {}
void writeAttribute(Attribute attr) override { state.number(attr); }
- void writeOptionalAttribute(Attribute attr) override {
- if (attr)
- state.number(attr);
- }
void writeType(Type type) override { state.number(type); }
void writeResourceHandle(const AsmDialectResourceHandle &resource) override {
state.number(resource.getDialect(), resource);
value->number = idx;
}
-IRNumberingState::IRNumberingState(Operation *op,
- const BytecodeWriterConfig &config)
- : config(config) {
+IRNumberingState::IRNumberingState(Operation *op) {
// Compute a global operation ID numbering according to the pre-order walk of
// the IR. This is used as reference to construct use-list orders.
unsigned operationID = 0;
}
// Only number the operation's dictionary if it isn't empty.
- DictionaryAttr dictAttr = op.getDiscardableAttrDictionary();
- if (config.getDesiredBytecodeVersion() < 4)
- dictAttr = op.getAttrDictionary();
+ DictionaryAttr dictAttr = op.getAttrDictionary();
if (!dictAttr.empty())
number(dictAttr);
- // Visit the operation properties (if any) to make sure referenced attributes
- // are numbered.
- if (config.getDesiredBytecodeVersion() >= 4 &&
- op.getPropertiesStorageSize()) {
- if (op.isRegistered()) {
- // Operation that have properties *must* implement this interface.
- auto iface = cast<BytecodeOpInterface>(op);
- NumberingDialectWriter writer(*this);
- iface.writeProperties(writer);
- } else {
- // Unregistered op are storing properties as an optional attribute.
- Attribute prop = *op.getPropertiesStorage().as<Attribute *>();
- if (prop)
- number(prop);
- }
- }
-
number(op.getLoc());
}
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/CodeGen/NonRelocatableStringpool.h"
-#include <cstdint>
namespace mlir {
class BytecodeDialectInterface;
/// emission.
class IRNumberingState {
public:
- IRNumberingState(Operation *op, const BytecodeWriterConfig &config);
+ IRNumberingState(Operation *op);
/// Return the numbered dialects.
auto getDialects() {
/// The next value ID to assign when numbering.
unsigned nextValueID = 0;
-
- // Configuration: useful to query the required version to emit.
- const BytecodeWriterConfig &config;
};
} // namespace detail
} // namespace bytecode
return getValueAsString(init);
}
-StringRef Property::getReadFromMlirBytecodeCall() const {
- const auto *init = def->getValueInit("readFromMlirBytecode");
- return getValueAsString(init);
-}
-
-StringRef Property::getWriteToMlirBytecodeCall() const {
- const auto *init = def->getValueInit("writeToMlirBytecode");
- return getValueAsString(init);
-}
-
StringRef Property::getHashPropertyCall() const {
return getValueAsString(def->getValueInit("hashProperty"));
}
//===--------------------------------------------------------------------===//
// RUN: not mlir-opt %S/invalid-structure-version.mlirbc 2>&1 | FileCheck %s --check-prefix=VERSION
-// VERSION: bytecode version 127 is newer than the current version {{[0-9]+}}
+// VERSION: bytecode version 127 is newer than the current version
//===--------------------------------------------------------------------===//
// Producer
#include "mlir/IR/Verifier.h"
#include "mlir/Interfaces/InferIntRangeInterface.h"
#include "mlir/Reducer/ReductionPatternInterface.h"
-#include "mlir/Support/LogicalResult.h"
#include "mlir/Transforms/FoldUtils.h"
#include "mlir/Transforms/InliningUtils.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
-#include <cstdint>
#include <numeric>
#include <optional>
return hash_value(StringRef(content));
}
-static LogicalResult readFromMlirBytecode(DialectBytecodeReader &reader,
- MyPropStruct &prop) {
- StringRef str;
- if (failed(reader.readString(str)))
- return failure();
- prop.content = str.str();
- return success();
-}
-
-static void writeToMlirBytecode(::mlir::DialectBytecodeWriter &writer,
- MyPropStruct &prop) {
- writer.writeOwnedString(prop.content);
-}
-
-static LogicalResult readFromMlirBytecode(DialectBytecodeReader &reader,
- MutableArrayRef<int64_t> prop) {
- uint64_t size;
- if (failed(reader.readVarInt(size)))
- return failure();
- if (size != prop.size())
- return reader.emitError("array size mismach when reading properties: ")
- << size << " vs expected " << prop.size();
- for (auto &elt : prop) {
- uint64_t value;
- if (failed(reader.readVarInt(value)))
- return failure();
- elt = value;
- }
- return success();
-}
-
-static void writeToMlirBytecode(::mlir::DialectBytecodeWriter &writer,
- ArrayRef<int64_t> prop) {
- writer.writeVarInt(prop.size());
- for (auto elt : prop)
- writer.writeVarInt(elt);
-}
-
static LogicalResult setPropertiesFromAttribute(PropertiesWithCustomPrint &prop,
Attribute attr,
InFlightDiagnostic *diagnostic);
def TestOpWithProperties : TEST_Op<"with_properties"> {
let assemblyFormat = "prop-dict attr-dict";
let arguments = (ins
- IntProperty<"int64_t">:$a,
+ Property<"int64_t">:$a,
StrAttr:$b, // Attributes can directly be used here.
ArrayProperty<"int64_t", 4>:$array // example of an array
);
const Properties &prop);
static ::mlir::ParseResult parseProperties(::mlir::OpAsmParser &parser,
::mlir::OperationState &result);
- static ::mlir::LogicalResult readFromMlirBytecode(
- ::mlir::DialectBytecodeReader &,
- test::PropertiesWithCustomPrint &prop);
- static void writeToMlirBytecode(
- ::mlir::DialectBytecodeWriter &,
- const test::PropertiesWithCustomPrint &prop);
}];
let extraClassDefinition = [{
- ::mlir::LogicalResult TestOpWithNiceProperties::readFromMlirBytecode(
- ::mlir::DialectBytecodeReader &reader,
- test::PropertiesWithCustomPrint &prop) {
- StringRef label;
- uint64_t value;
- if (failed(reader.readString(label)) || failed(reader.readVarInt(value)))
- return failure();
- prop.label = std::make_shared<std::string>(label.str());
- prop.value = value;
- return success();
- }
- void TestOpWithNiceProperties::writeToMlirBytecode(
- ::mlir::DialectBytecodeWriter &writer,
- const test::PropertiesWithCustomPrint &prop) {
- writer.writeOwnedString(*prop.label);
- writer.writeVarInt(prop.value);
- }
void TestOpWithNiceProperties::printProperties(::mlir::MLIRContext *ctx,
::mlir::OpAsmPrinter &p, const Properties &prop) {
customPrintProperties(p, prop.prop);
#ifndef MLIR_TESTTRANSFORMDIALECTEXTENSION_H
#define MLIR_TESTTRANSFORMDIALECTEXTENSION_H
-#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/PDL/IR/PDLTypes.h"
#include "mlir/Dialect/Transform/IR/MatchInterfaces.h"
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
"getDiag"))
->body();
- auto &readPropertiesMethod =
- opClass
- .addStaticMethod(
- "::mlir::LogicalResult", "readProperties",
- MethodParameter("::mlir::DialectBytecodeReader &", "reader"),
- MethodParameter("::mlir::OperationState &", "state"))
- ->body();
-
- auto &writePropertiesMethod =
- opClass
- .addMethod(
- "void", "writeProperties",
- MethodParameter("::mlir::DialectBytecodeWriter &", "writer"))
- ->body();
-
opClass.declare<UsingDeclaration>("Properties", "FoldAdaptor::Properties");
// Convert the property to the attribute form.
}
}
verifyInherentAttrsMethod << " return ::mlir::success();";
-
- // Populate bytecode serialization logic.
- readPropertiesMethod
- << " auto &prop = state.getOrAddProperties<Properties>(); (void)prop;";
- writePropertiesMethod << " auto &prop = getProperties(); (void)prop;\n";
- for (const auto &attrOrProp : attrOrProperties) {
- if (const auto *namedProperty =
- attrOrProp.dyn_cast<const NamedProperty *>()) {
- StringRef name = namedProperty->name;
- FmtContext fctx;
- fctx.addSubst("_reader", "reader")
- .addSubst("_writer", "writer")
- .addSubst("_storage", propertyStorage);
- readPropertiesMethod << formatv(
- R"(
- {{
- auto &propStorage = prop.{0};
- auto readProp = [&]() {
- {1};
- return ::mlir::success();
- };
- if (failed(readProp()))
- return ::mlir::failure();
- }
-)",
- name,
- tgfmt(namedProperty->prop.getReadFromMlirBytecodeCall(), &fctx));
- writePropertiesMethod << formatv(
- R"(
- {{
- auto &propStorage = prop.{0};
- {1};
- }
-)",
- name, tgfmt(namedProperty->prop.getWriteToMlirBytecodeCall(), &fctx));
- continue;
- }
- const auto *namedAttr = attrOrProp.dyn_cast<const AttributeMetadata *>();
- StringRef name = namedAttr->attrName;
- if (namedAttr->isRequired) {
- readPropertiesMethod << formatv(R"(
- if (failed(reader.readAttribute(prop.{0})))
- return failure();
-)",
- name);
- writePropertiesMethod
- << formatv(" writer.writeAttribute(prop.{0});\n", name);
- } else {
- readPropertiesMethod << formatv(R"(
- if (failed(reader.readOptionalAttribute(prop.{0})))
- return failure();
-)",
- name);
- writePropertiesMethod << formatv(R"(
- writer.writeOptionalAttribute(prop.{0});
-)",
- name);
- }
- }
- readPropertiesMethod << " return success();";
}
void OpEmitter::genAttrGetters() {
// native/interface traits and after all the traits with `StructuralOpTrait`.
opClass.addTrait("::mlir::OpTrait::OpInvariants");
- if (emitHelper.hasProperties())
- opClass.addTrait("::mlir::BytecodeOpInterface::Trait");
-
// Add the native and interface traits.
for (const auto &trait : op.getTraits()) {
if (auto *opTrait = dyn_cast<tblgen::NativeTrait>(&trait)) {