mirror of
https://github.com/intel/llvm.git
synced 2026-01-31 07:27:33 +08:00
[MLIR] Add native Bytecode support for properties
This is adding a new interface (`BytecodeOpInterface`) to allow operations to
opt-in skipping conversion to attribute and serializing properties to native
bytecode.
The scheme relies on a new section where properties are stored in sequence
{ size, serialize_properties }, ...
The operations are storing the index of a properties, a table of offset is
built when loading the properties section the first time.
This is a re-commit of 837d1ce0dc which conflicted with another patch upgrading
the bytecode and the collision wasn't properly resolved before.
Differential Revision: https://reviews.llvm.org/D151065
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
#ifndef STANDALONE_STANDALONEDIALECT_H
|
#ifndef STANDALONE_STANDALONEDIALECT_H
|
||||||
#define STANDALONE_STANDALONEDIALECT_H
|
#define STANDALONE_STANDALONEDIALECT_H
|
||||||
|
|
||||||
|
#include "mlir/Bytecode/BytecodeOpInterface.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
|
|
||||||
#include "Standalone/StandaloneOpsDialect.h.inc"
|
#include "Standalone/StandaloneOpsDialect.h.inc"
|
||||||
|
|||||||
@@ -74,6 +74,10 @@ public:
|
|||||||
|
|
||||||
/// Read a reference to the given attribute.
|
/// Read a reference to the given attribute.
|
||||||
virtual LogicalResult readAttribute(Attribute &result) = 0;
|
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>
|
template <typename T>
|
||||||
LogicalResult readAttributes(SmallVectorImpl<T> &attrs) {
|
LogicalResult readAttributes(SmallVectorImpl<T> &attrs) {
|
||||||
return readList(attrs, [this](T &attr) { return readAttribute(attr); });
|
return readList(attrs, [this](T &attr) { return readAttribute(attr); });
|
||||||
@@ -88,6 +92,18 @@ public:
|
|||||||
return emitError() << "expected " << llvm::getTypeName<T>()
|
return emitError() << "expected " << llvm::getTypeName<T>()
|
||||||
<< ", but got: " << baseResult;
|
<< ", 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.
|
/// Read a reference to the given type.
|
||||||
virtual LogicalResult readType(Type &result) = 0;
|
virtual LogicalResult readType(Type &result) = 0;
|
||||||
@@ -179,6 +195,7 @@ public:
|
|||||||
|
|
||||||
/// Write a reference to the given attribute.
|
/// Write a reference to the given attribute.
|
||||||
virtual void writeAttribute(Attribute attr) = 0;
|
virtual void writeAttribute(Attribute attr) = 0;
|
||||||
|
virtual void writeOptionalAttribute(Attribute attr) = 0;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void writeAttributes(ArrayRef<T> attrs) {
|
void writeAttributes(ArrayRef<T> attrs) {
|
||||||
writeList(attrs, [this](T attr) { writeAttribute(attr); });
|
writeList(attrs, [this](T attr) { writeAttribute(attr); });
|
||||||
|
|||||||
27
mlir/include/mlir/Bytecode/BytecodeOpInterface.h
Normal file
27
mlir/include/mlir/Bytecode/BytecodeOpInterface.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
//===- BytecodeOpInterface.h - Bytecode interface for MLIR Op ---*- 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
|
||||||
43
mlir/include/mlir/Bytecode/BytecodeOpInterface.td
Normal file
43
mlir/include/mlir/Bytecode/BytecodeOpInterface.td
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
//===- 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
|
||||||
@@ -46,6 +46,9 @@ public:
|
|||||||
/// is returned by bytecode writer entry point.
|
/// is returned by bytecode writer entry point.
|
||||||
void setDesiredBytecodeVersion(int64_t bytecodeVersion);
|
void setDesiredBytecodeVersion(int64_t bytecodeVersion);
|
||||||
|
|
||||||
|
/// Get the set desired bytecode version to emit.
|
||||||
|
int64_t getDesiredBytecodeVersion() const;
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Resources
|
// Resources
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|||||||
1
mlir/include/mlir/Bytecode/CMakeLists.txt
Normal file
1
mlir/include/mlir/Bytecode/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
add_mlir_interface(BytecodeOpInterface)
|
||||||
@@ -29,7 +29,7 @@ enum {
|
|||||||
kMinSupportedVersion = 0,
|
kMinSupportedVersion = 0,
|
||||||
|
|
||||||
/// The current bytecode version.
|
/// The current bytecode version.
|
||||||
kVersion = 4,
|
kVersion = 5,
|
||||||
|
|
||||||
/// An arbitrary value used to fill alignment padding.
|
/// An arbitrary value used to fill alignment padding.
|
||||||
kAlignmentByte = 0xCB,
|
kAlignmentByte = 0xCB,
|
||||||
@@ -69,8 +69,11 @@ enum ID : uint8_t {
|
|||||||
/// This section contains the versions of each dialect.
|
/// This section contains the versions of each dialect.
|
||||||
kDialectVersions = 7,
|
kDialectVersions = 7,
|
||||||
|
|
||||||
|
/// This section contains the properties for the operations.
|
||||||
|
kProperties = 8,
|
||||||
|
|
||||||
/// The total number of section types.
|
/// The total number of section types.
|
||||||
kNumSections = 8,
|
kNumSections = 9,
|
||||||
};
|
};
|
||||||
} // namespace Section
|
} // namespace Section
|
||||||
|
|
||||||
@@ -90,6 +93,7 @@ enum : uint8_t {
|
|||||||
kHasSuccessors = 0b00001000,
|
kHasSuccessors = 0b00001000,
|
||||||
kHasInlineRegions = 0b00010000,
|
kHasInlineRegions = 0b00010000,
|
||||||
kHasUseListOrders = 0b00100000,
|
kHasUseListOrders = 0b00100000,
|
||||||
|
kHasProperties = 0b01000000,
|
||||||
// clang-format on
|
// clang-format on
|
||||||
};
|
};
|
||||||
} // namespace OpEncodingMask
|
} // namespace OpEncodingMask
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
add_subdirectory(Bytecode)
|
||||||
add_subdirectory(Conversion)
|
add_subdirectory(Conversion)
|
||||||
add_subdirectory(Dialect)
|
add_subdirectory(Dialect)
|
||||||
add_subdirectory(IR)
|
add_subdirectory(IR)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#ifndef MLIR_DIALECT_AMDGPU_IR_AMDGPUDIALECT_H_
|
#ifndef MLIR_DIALECT_AMDGPU_IR_AMDGPUDIALECT_H_
|
||||||
#define 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/BuiltinTypes.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
#include "mlir/IR/OpDefinition.h"
|
#include "mlir/IR/OpDefinition.h"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#ifndef MLIR_DIALECT_AMX_AMXDIALECT_H_
|
#ifndef MLIR_DIALECT_AMX_AMXDIALECT_H_
|
||||||
#define MLIR_DIALECT_AMX_AMXDIALECT_H_
|
#define MLIR_DIALECT_AMX_AMXDIALECT_H_
|
||||||
|
|
||||||
|
#include "mlir/Bytecode/BytecodeOpInterface.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
#include "mlir/IR/OpDefinition.h"
|
#include "mlir/IR/OpDefinition.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_AFFINE_TRANSFORMOPS_AFFINETRANSFORMOPS_H
|
#ifndef MLIR_DIALECT_AFFINE_TRANSFORMOPS_AFFINETRANSFORMOPS_H
|
||||||
#define 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/TransformInterfaces.h"
|
||||||
#include "mlir/Dialect/Transform/IR/TransformTypes.h"
|
#include "mlir/Dialect/Transform/IR/TransformTypes.h"
|
||||||
#include "mlir/IR/OpImplementation.h"
|
#include "mlir/IR/OpImplementation.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_ARITH_IR_ARITH_H_
|
#ifndef MLIR_DIALECT_ARITH_IR_ARITH_H_
|
||||||
#define 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/Dialect.h"
|
||||||
#include "mlir/IR/OpDefinition.h"
|
#include "mlir/IR/OpDefinition.h"
|
||||||
#include "mlir/IR/OpImplementation.h"
|
#include "mlir/IR/OpImplementation.h"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#ifndef MLIR_DIALECT_ARMNEON_ARMNEONDIALECT_H_
|
#ifndef MLIR_DIALECT_ARMNEON_ARMNEONDIALECT_H_
|
||||||
#define MLIR_DIALECT_ARMNEON_ARMNEONDIALECT_H_
|
#define MLIR_DIALECT_ARMNEON_ARMNEONDIALECT_H_
|
||||||
|
|
||||||
|
#include "mlir/Bytecode/BytecodeOpInterface.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
#include "mlir/IR/OpDefinition.h"
|
#include "mlir/IR/OpDefinition.h"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#ifndef MLIR_DIALECT_ARMSVE_ARMSVEDIALECT_H
|
#ifndef MLIR_DIALECT_ARMSVE_ARMSVEDIALECT_H
|
||||||
#define MLIR_DIALECT_ARMSVE_ARMSVEDIALECT_H
|
#define MLIR_DIALECT_ARMSVE_ARMSVEDIALECT_H
|
||||||
|
|
||||||
|
#include "mlir/Bytecode/BytecodeOpInterface.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
#include "mlir/IR/OpDefinition.h"
|
#include "mlir/IR/OpDefinition.h"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#ifndef MLIR_DIALECT_ASYNC_IR_ASYNC_H
|
#ifndef MLIR_DIALECT_ASYNC_IR_ASYNC_H
|
||||||
#define 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/Dialect/Async/IR/AsyncTypes.h"
|
||||||
#include "mlir/IR/Builders.h"
|
#include "mlir/IR/Builders.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_BUFFERIZATION_IR_BUFFERIZATION_H_
|
#ifndef MLIR_DIALECT_BUFFERIZATION_IR_BUFFERIZATION_H_
|
||||||
#define 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/AllocationOpInterface.h"
|
||||||
#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
|
#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
|
||||||
#include "mlir/Interfaces/CopyOpInterface.h"
|
#include "mlir/Interfaces/CopyOpInterface.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_BUFFERIZATION_TRANSFORMOPS_BUFFERIZATIONTRANSFORMOPS_H
|
#ifndef MLIR_DIALECT_BUFFERIZATION_TRANSFORMOPS_BUFFERIZATIONTRANSFORMOPS_H
|
||||||
#define 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/Bufferization/IR/BufferizableOpInterface.h"
|
||||||
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
|
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
|
||||||
#include "mlir/Dialect/Transform/IR/TransformTypes.h"
|
#include "mlir/Dialect/Transform/IR/TransformTypes.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_COMPLEX_IR_COMPLEX_H_
|
#ifndef MLIR_DIALECT_COMPLEX_IR_COMPLEX_H_
|
||||||
#define 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/BuiltinTypes.h"
|
||||||
#include "mlir/IR/OpImplementation.h"
|
#include "mlir/IR/OpImplementation.h"
|
||||||
#include "mlir/Interfaces/InferTypeOpInterface.h"
|
#include "mlir/Interfaces/InferTypeOpInterface.h"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#ifndef MLIR_DIALECT_CONTROLFLOW_IR_CONTROLFLOW_H
|
#ifndef MLIR_DIALECT_CONTROLFLOW_IR_CONTROLFLOW_H
|
||||||
#define 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/IR/Dialect.h"
|
||||||
|
|
||||||
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOpsDialect.h.inc"
|
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOpsDialect.h.inc"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#ifndef MLIR_DIALECT_CONTROLFLOW_IR_CONTROLFLOWOPS_H
|
#ifndef MLIR_DIALECT_CONTROLFLOW_IR_CONTROLFLOWOPS_H
|
||||||
#define 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/Dialect/ControlFlow/IR/ControlFlow.h"
|
||||||
#include "mlir/IR/Builders.h"
|
#include "mlir/IR/Builders.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#ifndef MLIR_DIALECT_EMITC_IR_EMITC_H
|
#ifndef MLIR_DIALECT_EMITC_IR_EMITC_H
|
||||||
#define 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/BuiltinOps.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_FUNC_IR_OPS_H
|
#ifndef MLIR_DIALECT_FUNC_IR_OPS_H
|
||||||
#define 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/Builders.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#ifndef MLIR_DIALECT_GPU_IR_GPUDIALECT_H
|
#ifndef MLIR_DIALECT_GPU_IR_GPUDIALECT_H
|
||||||
#define 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/Dialect/DLTI/Traits.h"
|
||||||
#include "mlir/IR/Builders.h"
|
#include "mlir/IR/Builders.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
|
|||||||
@@ -13,11 +13,13 @@
|
|||||||
#ifndef MLIR_DIALECT_IRDL_IR_IRDL_H_
|
#ifndef MLIR_DIALECT_IRDL_IR_IRDL_H_
|
||||||
#define 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/IRDLInterfaces.h"
|
||||||
#include "mlir/Dialect/IRDL/IR/IRDLTraits.h"
|
#include "mlir/Dialect/IRDL/IR/IRDLTraits.h"
|
||||||
#include "mlir/IR/SymbolTable.h"
|
#include "mlir/IR/SymbolTable.h"
|
||||||
#include "mlir/Interfaces/InferTypeOpInterface.h"
|
#include "mlir/Interfaces/InferTypeOpInterface.h"
|
||||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
// Forward declaration.
|
// Forward declaration.
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_INDEX_IR_INDEXOPS_H
|
#ifndef MLIR_DIALECT_INDEX_IR_INDEXOPS_H
|
||||||
#define 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/Dialect/Index/IR/IndexAttrs.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
#include "mlir/IR/OpDefinition.h"
|
#include "mlir/IR/OpDefinition.h"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#ifndef MLIR_DIALECT_LLVMIR_LLVMDIALECT_H_
|
#ifndef MLIR_DIALECT_LLVMIR_LLVMDIALECT_H_
|
||||||
#define 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/LLVMAttrs.h"
|
||||||
#include "mlir/Dialect/LLVMIR/LLVMInterfaces.h"
|
#include "mlir/Dialect/LLVMIR/LLVMInterfaces.h"
|
||||||
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
|
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#ifndef MLIR_DIALECT_LLVMIR_NVVMDIALECT_H_
|
#ifndef MLIR_DIALECT_LLVMIR_NVVMDIALECT_H_
|
||||||
#define MLIR_DIALECT_LLVMIR_NVVMDIALECT_H_
|
#define MLIR_DIALECT_LLVMIR_NVVMDIALECT_H_
|
||||||
|
|
||||||
|
#include "mlir/Bytecode/BytecodeOpInterface.h"
|
||||||
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
|
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
#include "mlir/IR/OpDefinition.h"
|
#include "mlir/IR/OpDefinition.h"
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#ifndef MLIR_DIALECT_LLVMIR_ROCDLDIALECT_H_
|
#ifndef MLIR_DIALECT_LLVMIR_ROCDLDIALECT_H_
|
||||||
#define MLIR_DIALECT_LLVMIR_ROCDLDIALECT_H_
|
#define MLIR_DIALECT_LLVMIR_ROCDLDIALECT_H_
|
||||||
|
|
||||||
|
#include "mlir/Bytecode/BytecodeOpInterface.h"
|
||||||
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
|
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
#include "mlir/IR/OpDefinition.h"
|
#include "mlir/IR/OpDefinition.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_LINALG_IR_LINALG_H
|
#ifndef MLIR_DIALECT_LINALG_IR_LINALG_H
|
||||||
#define 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/ReshapeOpsUtils.h"
|
||||||
#include "mlir/Dialect/Utils/StructuredOpsUtils.h"
|
#include "mlir/Dialect/Utils/StructuredOpsUtils.h"
|
||||||
#include "mlir/IR/AffineExpr.h"
|
#include "mlir/IR/AffineExpr.h"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#ifndef MLIR_DIALECT_MLPROGRAM_IR_MLPROGRAM_H_
|
#ifndef MLIR_DIALECT_MLPROGRAM_IR_MLPROGRAM_H_
|
||||||
#define 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/MLProgramAttributes.h"
|
||||||
#include "mlir/Dialect/MLProgram/IR/MLProgramTypes.h"
|
#include "mlir/Dialect/MLProgram/IR/MLProgramTypes.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_MATH_IR_MATH_H_
|
#ifndef MLIR_DIALECT_MATH_IR_MATH_H_
|
||||||
#define 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/Dialect/Arith/IR/Arith.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_MEMREF_IR_MEMREF_H_
|
#ifndef MLIR_DIALECT_MEMREF_IR_MEMREF_H_
|
||||||
#define 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/Arith/IR/Arith.h"
|
||||||
#include "mlir/Dialect/Utils/ReshapeOpsUtils.h"
|
#include "mlir/Dialect/Utils/ReshapeOpsUtils.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
@@ -21,6 +22,7 @@
|
|||||||
#include "mlir/Interfaces/ShapedOpInterfaces.h"
|
#include "mlir/Interfaces/ShapedOpInterfaces.h"
|
||||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||||
#include "mlir/Interfaces/ViewLikeInterface.h"
|
#include "mlir/Interfaces/ViewLikeInterface.h"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
namespace mlir {
|
namespace mlir {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_MEMREF_TRANSFORMOPS_MEMREFTRANSFORMOPS_H
|
#ifndef MLIR_DIALECT_MEMREF_TRANSFORMOPS_MEMREFTRANSFORMOPS_H
|
||||||
#define 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/Dialect/Transform/IR/TransformInterfaces.h"
|
||||||
#include "mlir/IR/OpImplementation.h"
|
#include "mlir/IR/OpImplementation.h"
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#ifndef MLIR_DIALECT_NVGPU_NVGPUDIALECT_H_
|
#ifndef MLIR_DIALECT_NVGPU_NVGPUDIALECT_H_
|
||||||
#define MLIR_DIALECT_NVGPU_NVGPUDIALECT_H_
|
#define MLIR_DIALECT_NVGPU_NVGPUDIALECT_H_
|
||||||
|
|
||||||
|
#include "mlir/Bytecode/BytecodeOpInterface.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
#include "mlir/IR/OpDefinition.h"
|
#include "mlir/IR/OpDefinition.h"
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "mlir/IR/OpDefinition.h"
|
#include "mlir/IR/OpDefinition.h"
|
||||||
#include "mlir/IR/SymbolTable.h"
|
#include "mlir/IR/SymbolTable.h"
|
||||||
|
|
||||||
|
#include "mlir/Bytecode/BytecodeOpInterface.h"
|
||||||
#include "mlir/Dialect/OpenACC/OpenACCOpsDialect.h.inc"
|
#include "mlir/Dialect/OpenACC/OpenACCOpsDialect.h.inc"
|
||||||
#include "mlir/Dialect/OpenACC/OpenACCOpsEnums.h.inc"
|
#include "mlir/Dialect/OpenACC/OpenACCOpsEnums.h.inc"
|
||||||
#include "mlir/Dialect/OpenACC/OpenACCTypeInterfaces.h.inc"
|
#include "mlir/Dialect/OpenACC/OpenACCTypeInterfaces.h.inc"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#ifndef MLIR_DIALECT_PDL_IR_PDLOPS_H_
|
#ifndef MLIR_DIALECT_PDL_IR_PDLOPS_H_
|
||||||
#define 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/Dialect/PDL/IR/PDLTypes.h"
|
||||||
#include "mlir/IR/Builders.h"
|
#include "mlir/IR/Builders.h"
|
||||||
#include "mlir/IR/OpImplementation.h"
|
#include "mlir/IR/OpImplementation.h"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#ifndef MLIR_DIALECT_PDLINTERP_IR_PDLINTERP_H_
|
#ifndef MLIR_DIALECT_PDLINTERP_IR_PDLINTERP_H_
|
||||||
#define 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/PDL.h"
|
||||||
#include "mlir/Dialect/PDL/IR/PDLTypes.h"
|
#include "mlir/Dialect/PDL/IR/PDLTypes.h"
|
||||||
#include "mlir/IR/FunctionInterfaces.h"
|
#include "mlir/IR/FunctionInterfaces.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_SCF_TRANSFORMOPS_SCFTRANSFORMOPS_H
|
#ifndef MLIR_DIALECT_SCF_TRANSFORMOPS_SCFTRANSFORMOPS_H
|
||||||
#define 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/TransformInterfaces.h"
|
||||||
#include "mlir/Dialect/Transform/IR/TransformTypes.h"
|
#include "mlir/Dialect/Transform/IR/TransformTypes.h"
|
||||||
#include "mlir/IR/OpImplementation.h"
|
#include "mlir/IR/OpImplementation.h"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#ifndef MLIR_DIALECT_SPIRV_IR_SPIRVOPS_H_
|
#ifndef MLIR_DIALECT_SPIRV_IR_SPIRVOPS_H_
|
||||||
#define 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/SPIRVAttributes.h"
|
||||||
#include "mlir/Dialect/SPIRV/IR/SPIRVOpTraits.h"
|
#include "mlir/Dialect/SPIRV/IR/SPIRVOpTraits.h"
|
||||||
#include "mlir/Dialect/SPIRV/IR/SPIRVTypes.h"
|
#include "mlir/Dialect/SPIRV/IR/SPIRVTypes.h"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#ifndef MLIR_DIALECT_SHAPE_IR_SHAPE_H
|
#ifndef MLIR_DIALECT_SHAPE_IR_SHAPE_H
|
||||||
#define 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/BuiltinOps.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
#include "mlir/IR/FunctionInterfaces.h"
|
#include "mlir/IR/FunctionInterfaces.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_SPARSETENSOR_IR_SPARSETENSOR_H_
|
#ifndef MLIR_DIALECT_SPARSETENSOR_IR_SPARSETENSOR_H_
|
||||||
#define 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/Dialect/SparseTensor/IR/Enums.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_TENSOR_IR_TENSOR_H_
|
#ifndef MLIR_DIALECT_TENSOR_IR_TENSOR_H_
|
||||||
#define 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/Dialect/Utils/ReshapeOpsUtils.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#ifndef MLIR_DIALECT_TOSA_IR_TOSAOPS_H
|
#ifndef MLIR_DIALECT_TOSA_IR_TOSAOPS_H
|
||||||
#define 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/Dialect/Traits.h"
|
||||||
#include "mlir/IR/OpImplementation.h"
|
#include "mlir/IR/OpImplementation.h"
|
||||||
#include "mlir/Interfaces/InferTypeOpInterface.h"
|
#include "mlir/Interfaces/InferTypeOpInterface.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_TRANSFORM_IR_TRANSFORMOPS_H
|
#ifndef MLIR_DIALECT_TRANSFORM_IR_TRANSFORMOPS_H
|
||||||
#define 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/MatchInterfaces.h"
|
||||||
#include "mlir/Dialect/Transform/IR/TransformAttrs.h"
|
#include "mlir/Dialect/Transform/IR/TransformAttrs.h"
|
||||||
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
|
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef MLIR_DIALECT_TRANSFORM_PDLEXTENSION_PDLEXTENSIONOPS_H
|
#ifndef MLIR_DIALECT_TRANSFORM_PDLEXTENSION_PDLEXTENSIONOPS_H
|
||||||
#define 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/TransformDialect.h"
|
||||||
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
|
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
|
||||||
#include "mlir/IR/OpDefinition.h"
|
#include "mlir/IR/OpDefinition.h"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#ifndef MLIR_DIALECT_VECTOR_IR_VECTOROPS_H
|
#ifndef MLIR_DIALECT_VECTOR_IR_VECTOROPS_H
|
||||||
#define 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/MaskableOpInterface.h"
|
||||||
#include "mlir/Dialect/Vector/Interfaces/MaskingOpInterface.h"
|
#include "mlir/Dialect/Vector/Interfaces/MaskingOpInterface.h"
|
||||||
#include "mlir/IR/AffineMap.h"
|
#include "mlir/IR/AffineMap.h"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#ifndef MLIR_DIALECT_X86VECTOR_X86VECTORDIALECT_H_
|
#ifndef MLIR_DIALECT_X86VECTOR_X86VECTORDIALECT_H_
|
||||||
#define MLIR_DIALECT_X86VECTOR_X86VECTORDIALECT_H_
|
#define MLIR_DIALECT_X86VECTOR_X86VECTORDIALECT_H_
|
||||||
|
|
||||||
|
#include "mlir/Bytecode/BytecodeOpInterface.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
#include "mlir/IR/OpDefinition.h"
|
#include "mlir/IR/OpDefinition.h"
|
||||||
|
|||||||
@@ -238,6 +238,25 @@ class Property<string storageTypeParam = "", string desc = ""> {
|
|||||||
llvm::hash_value($_storage);
|
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.
|
// Default value for the property.
|
||||||
string defaultValue = ?;
|
string defaultValue = ?;
|
||||||
}
|
}
|
||||||
@@ -1156,6 +1175,20 @@ class DefaultValuedOptionalStrAttr<Attr attr, string val>
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Primitive property kinds
|
// 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 = ""> :
|
class ArrayProperty<string storageTypeParam = "", int n, string desc = ""> :
|
||||||
Property<storageTypeParam # "[" # n # "]", desc> {
|
Property<storageTypeParam # "[" # n # "]", desc> {
|
||||||
let interfaceType = "::llvm::ArrayRef<" # storageTypeParam # ">";
|
let interfaceType = "::llvm::ArrayRef<" # storageTypeParam # ">";
|
||||||
|
|||||||
@@ -58,6 +58,14 @@ public:
|
|||||||
// in the provided interface type and assign it to the storage.
|
// in the provided interface type and assign it to the storage.
|
||||||
StringRef getConvertFromAttributeCall() const;
|
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.
|
// Returns the code to compute the hash for this property.
|
||||||
StringRef getHashPropertyCall() const;
|
StringRef getHashPropertyCall() const;
|
||||||
|
|
||||||
|
|||||||
17
mlir/lib/Bytecode/BytecodeOpInterface.cpp
Normal file
17
mlir/lib/Bytecode/BytecodeOpInterface.cpp
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//===- 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"
|
||||||
@@ -1,2 +1,13 @@
|
|||||||
add_subdirectory(Reader)
|
add_subdirectory(Reader)
|
||||||
add_subdirectory(Writer)
|
add_subdirectory(Writer)
|
||||||
|
|
||||||
|
add_mlir_library(MLIRBytecodeOpInterface
|
||||||
|
BytecodeOpInterface.cpp
|
||||||
|
|
||||||
|
ADDITIONAL_HEADER_DIRS
|
||||||
|
${MLIR_MAIN_INCLUDE_DIR}/mlir/Bytecode
|
||||||
|
|
||||||
|
LINK_LIBS PUBLIC
|
||||||
|
MLIRIR
|
||||||
|
MLIRSupport
|
||||||
|
)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "mlir/Bytecode/BytecodeReader.h"
|
#include "mlir/Bytecode/BytecodeReader.h"
|
||||||
#include "mlir/AsmParser/AsmParser.h"
|
#include "mlir/AsmParser/AsmParser.h"
|
||||||
#include "mlir/Bytecode/BytecodeImplementation.h"
|
#include "mlir/Bytecode/BytecodeImplementation.h"
|
||||||
|
#include "mlir/Bytecode/BytecodeOpInterface.h"
|
||||||
#include "mlir/Bytecode/Encoding.h"
|
#include "mlir/Bytecode/Encoding.h"
|
||||||
#include "mlir/IR/BuiltinDialect.h"
|
#include "mlir/IR/BuiltinDialect.h"
|
||||||
#include "mlir/IR/BuiltinOps.h"
|
#include "mlir/IR/BuiltinOps.h"
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
#include "mlir/IR/Visitors.h"
|
#include "mlir/IR/Visitors.h"
|
||||||
#include "mlir/Support/LLVM.h"
|
#include "mlir/Support/LLVM.h"
|
||||||
#include "mlir/Support/LogicalResult.h"
|
#include "mlir/Support/LogicalResult.h"
|
||||||
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/MapVector.h"
|
#include "llvm/ADT/MapVector.h"
|
||||||
#include "llvm/ADT/ScopeExit.h"
|
#include "llvm/ADT/ScopeExit.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
@@ -28,6 +30,7 @@
|
|||||||
#include "llvm/Support/MemoryBufferRef.h"
|
#include "llvm/Support/MemoryBufferRef.h"
|
||||||
#include "llvm/Support/SaveAndRestore.h"
|
#include "llvm/Support/SaveAndRestore.h"
|
||||||
#include "llvm/Support/SourceMgr.h"
|
#include "llvm/Support/SourceMgr.h"
|
||||||
|
#include <cstddef>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
@@ -56,13 +59,15 @@ static std::string toString(bytecode::Section::ID sectionID) {
|
|||||||
return "ResourceOffset (6)";
|
return "ResourceOffset (6)";
|
||||||
case bytecode::Section::kDialectVersions:
|
case bytecode::Section::kDialectVersions:
|
||||||
return "DialectVersions (7)";
|
return "DialectVersions (7)";
|
||||||
|
case bytecode::Section::kProperties:
|
||||||
|
return "Properties (8)";
|
||||||
default:
|
default:
|
||||||
return ("Unknown (" + Twine(static_cast<unsigned>(sectionID)) + ")").str();
|
return ("Unknown (" + Twine(static_cast<unsigned>(sectionID)) + ")").str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the given top-level section ID is optional.
|
/// Returns true if the given top-level section ID is optional.
|
||||||
static bool isSectionOptional(bytecode::Section::ID sectionID) {
|
static bool isSectionOptional(bytecode::Section::ID sectionID, int version) {
|
||||||
switch (sectionID) {
|
switch (sectionID) {
|
||||||
case bytecode::Section::kString:
|
case bytecode::Section::kString:
|
||||||
case bytecode::Section::kDialect:
|
case bytecode::Section::kDialect:
|
||||||
@@ -74,6 +79,8 @@ static bool isSectionOptional(bytecode::Section::ID sectionID) {
|
|||||||
case bytecode::Section::kResourceOffset:
|
case bytecode::Section::kResourceOffset:
|
||||||
case bytecode::Section::kDialectVersions:
|
case bytecode::Section::kDialectVersions:
|
||||||
return true;
|
return true;
|
||||||
|
case bytecode::Section::kProperties:
|
||||||
|
return version < 5;
|
||||||
default:
|
default:
|
||||||
llvm_unreachable("unknown section ID");
|
llvm_unreachable("unknown section ID");
|
||||||
}
|
}
|
||||||
@@ -362,6 +369,17 @@ public:
|
|||||||
return parseEntry(reader, strings, result, "string");
|
return parseEntry(reader, strings, result, "string");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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
|
/// Parse a shared string from the string section. The shared string is
|
||||||
/// encoded using an index to a corresponding string in the string section.
|
/// encoded using an index to a corresponding string in the string section.
|
||||||
LogicalResult parseStringAtIndex(EncodingReader &reader, uint64_t index,
|
LogicalResult parseStringAtIndex(EncodingReader &reader, uint64_t index,
|
||||||
@@ -459,8 +477,9 @@ struct BytecodeDialect {
|
|||||||
|
|
||||||
/// This struct represents an operation name entry within the bytecode.
|
/// This struct represents an operation name entry within the bytecode.
|
||||||
struct BytecodeOperationName {
|
struct BytecodeOperationName {
|
||||||
BytecodeOperationName(BytecodeDialect *dialect, StringRef name)
|
BytecodeOperationName(BytecodeDialect *dialect, StringRef name,
|
||||||
: dialect(dialect), name(name) {}
|
std::optional<bool> wasRegistered)
|
||||||
|
: dialect(dialect), name(name), wasRegistered(wasRegistered) {}
|
||||||
|
|
||||||
/// The loaded operation name, or std::nullopt if it hasn't been processed
|
/// The loaded operation name, or std::nullopt if it hasn't been processed
|
||||||
/// yet.
|
/// yet.
|
||||||
@@ -471,6 +490,10 @@ struct BytecodeOperationName {
|
|||||||
|
|
||||||
/// The name of the operation, without the dialect prefix.
|
/// The name of the operation, without the dialect prefix.
|
||||||
StringRef name;
|
StringRef name;
|
||||||
|
|
||||||
|
/// Whether this operation was registered when the bytecode was produced.
|
||||||
|
/// This flag is populated when bytecode version >=5.
|
||||||
|
std::optional<bool> wasRegistered;
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -791,6 +814,18 @@ public:
|
|||||||
result = resolveAttribute(attrIdx);
|
result = resolveAttribute(attrIdx);
|
||||||
return success(!!result);
|
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) {
|
LogicalResult parseType(EncodingReader &reader, Type &result) {
|
||||||
uint64_t typeIdx;
|
uint64_t typeIdx;
|
||||||
if (failed(reader.parseVarInt(typeIdx)))
|
if (failed(reader.parseVarInt(typeIdx)))
|
||||||
@@ -870,7 +905,9 @@ public:
|
|||||||
LogicalResult readAttribute(Attribute &result) override {
|
LogicalResult readAttribute(Attribute &result) override {
|
||||||
return attrTypeReader.parseAttribute(reader, result);
|
return attrTypeReader.parseAttribute(reader, result);
|
||||||
}
|
}
|
||||||
|
LogicalResult readOptionalAttribute(Attribute &result) override {
|
||||||
|
return attrTypeReader.parseOptionalAttribute(reader, result);
|
||||||
|
}
|
||||||
LogicalResult readType(Type &result) override {
|
LogicalResult readType(Type &result) override {
|
||||||
return attrTypeReader.parseType(reader, result);
|
return attrTypeReader.parseType(reader, result);
|
||||||
}
|
}
|
||||||
@@ -957,6 +994,87 @@ private:
|
|||||||
ResourceSectionReader &resourceReader;
|
ResourceSectionReader &resourceReader;
|
||||||
EncodingReader &reader;
|
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);
|
||||||
|
size_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;
|
||||||
|
size_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
|
} // namespace
|
||||||
|
|
||||||
LogicalResult
|
LogicalResult
|
||||||
@@ -1194,7 +1312,9 @@ private:
|
|||||||
lazyLoadableOps.erase(it->getSecond());
|
lazyLoadableOps.erase(it->getSecond());
|
||||||
lazyLoadableOpsMap.erase(it);
|
lazyLoadableOpsMap.erase(it);
|
||||||
auto result = parseRegions(regionStack, regionStack.back());
|
auto result = parseRegions(regionStack, regionStack.back());
|
||||||
assert(regionStack.empty());
|
assert((regionStack.empty() || failed(result)) &&
|
||||||
|
"broken invariant: regionStack should be empty when parseRegions "
|
||||||
|
"succeeds");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1209,8 +1329,11 @@ private:
|
|||||||
|
|
||||||
LogicalResult parseDialectSection(ArrayRef<uint8_t> sectionData);
|
LogicalResult parseDialectSection(ArrayRef<uint8_t> sectionData);
|
||||||
|
|
||||||
/// Parse an operation name reference using the given reader.
|
/// Parse an operation name reference using the given reader, and set the
|
||||||
FailureOr<OperationName> parseOpName(EncodingReader &reader);
|
/// `wasRegistered` flag that indicates if the bytecode was produced by a
|
||||||
|
/// context where opName was registered.
|
||||||
|
FailureOr<OperationName> parseOpName(EncodingReader &reader,
|
||||||
|
std::optional<bool> &wasRegistered);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Attribute/Type Section
|
// Attribute/Type Section
|
||||||
@@ -1398,6 +1521,9 @@ private:
|
|||||||
/// The table of strings referenced within the bytecode file.
|
/// The table of strings referenced within the bytecode file.
|
||||||
StringSectionReader stringReader;
|
StringSectionReader stringReader;
|
||||||
|
|
||||||
|
/// The table of properties referenced by the operation in the bytecode file.
|
||||||
|
PropertiesSectionReader propertiesReader;
|
||||||
|
|
||||||
/// The current set of available IR value scopes.
|
/// The current set of available IR value scopes.
|
||||||
std::vector<ValueScope> valueScopes;
|
std::vector<ValueScope> valueScopes;
|
||||||
|
|
||||||
@@ -1466,7 +1592,7 @@ LogicalResult BytecodeReader::Impl::read(
|
|||||||
// Check that all of the required sections were found.
|
// Check that all of the required sections were found.
|
||||||
for (int i = 0; i < bytecode::Section::kNumSections; ++i) {
|
for (int i = 0; i < bytecode::Section::kNumSections; ++i) {
|
||||||
bytecode::Section::ID sectionID = static_cast<bytecode::Section::ID>(i);
|
bytecode::Section::ID sectionID = static_cast<bytecode::Section::ID>(i);
|
||||||
if (!sectionDatas[i] && !isSectionOptional(sectionID)) {
|
if (!sectionDatas[i] && !isSectionOptional(sectionID, version)) {
|
||||||
return reader.emitError("missing data for top-level section: ",
|
return reader.emitError("missing data for top-level section: ",
|
||||||
::toString(sectionID));
|
::toString(sectionID));
|
||||||
}
|
}
|
||||||
@@ -1477,6 +1603,12 @@ LogicalResult BytecodeReader::Impl::read(
|
|||||||
fileLoc, *sectionDatas[bytecode::Section::kString])))
|
fileLoc, *sectionDatas[bytecode::Section::kString])))
|
||||||
return failure();
|
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.
|
// Process the dialect section.
|
||||||
if (failed(parseDialectSection(*sectionDatas[bytecode::Section::kDialect])))
|
if (failed(parseDialectSection(*sectionDatas[bytecode::Section::kDialect])))
|
||||||
return failure();
|
return failure();
|
||||||
@@ -1598,9 +1730,20 @@ BytecodeReader::Impl::parseDialectSection(ArrayRef<uint8_t> sectionData) {
|
|||||||
// Parse the operation names, which are grouped by dialect.
|
// Parse the operation names, which are grouped by dialect.
|
||||||
auto parseOpName = [&](BytecodeDialect *dialect) {
|
auto parseOpName = [&](BytecodeDialect *dialect) {
|
||||||
StringRef opName;
|
StringRef opName;
|
||||||
if (failed(stringReader.parseString(sectionReader, opName)))
|
std::optional<bool> wasRegistered;
|
||||||
return failure();
|
// Prior to version 5, the information about wheter an op was registered or
|
||||||
opNames.emplace_back(dialect, opName);
|
// not wasn't encoded.
|
||||||
|
if (version < 5) {
|
||||||
|
if (failed(stringReader.parseString(sectionReader, opName)))
|
||||||
|
return failure();
|
||||||
|
} else {
|
||||||
|
bool wasRegisteredFlag;
|
||||||
|
if (failed(stringReader.parseStringWithFlag(sectionReader, opName,
|
||||||
|
wasRegisteredFlag)))
|
||||||
|
return failure();
|
||||||
|
wasRegistered = wasRegisteredFlag;
|
||||||
|
}
|
||||||
|
opNames.emplace_back(dialect, opName, wasRegistered);
|
||||||
return success();
|
return success();
|
||||||
};
|
};
|
||||||
// Avoid re-allocation in bytecode version > 3 where the number of ops are
|
// Avoid re-allocation in bytecode version > 3 where the number of ops are
|
||||||
@@ -1618,11 +1761,12 @@ BytecodeReader::Impl::parseDialectSection(ArrayRef<uint8_t> sectionData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FailureOr<OperationName>
|
FailureOr<OperationName>
|
||||||
BytecodeReader::Impl::parseOpName(EncodingReader &reader) {
|
BytecodeReader::Impl::parseOpName(EncodingReader &reader,
|
||||||
|
std::optional<bool> &wasRegistered) {
|
||||||
BytecodeOperationName *opName = nullptr;
|
BytecodeOperationName *opName = nullptr;
|
||||||
if (failed(parseEntry(reader, opNames, opName, "operation name")))
|
if (failed(parseEntry(reader, opNames, opName, "operation name")))
|
||||||
return failure();
|
return failure();
|
||||||
|
wasRegistered = opName->wasRegistered;
|
||||||
// Check to see if this operation name has already been resolved. If we
|
// Check to see if this operation name has already been resolved. If we
|
||||||
// haven't, load the dialect and build the operation name.
|
// haven't, load the dialect and build the operation name.
|
||||||
if (!opName->opName) {
|
if (!opName->opName) {
|
||||||
@@ -1994,7 +2138,8 @@ BytecodeReader::Impl::parseOpWithoutRegions(EncodingReader &reader,
|
|||||||
RegionReadState &readState,
|
RegionReadState &readState,
|
||||||
bool &isIsolatedFromAbove) {
|
bool &isIsolatedFromAbove) {
|
||||||
// Parse the name of the operation.
|
// Parse the name of the operation.
|
||||||
FailureOr<OperationName> opName = parseOpName(reader);
|
std::optional<bool> wasRegistered;
|
||||||
|
FailureOr<OperationName> opName = parseOpName(reader, wasRegistered);
|
||||||
if (failed(opName))
|
if (failed(opName))
|
||||||
return failure();
|
return failure();
|
||||||
|
|
||||||
@@ -2021,6 +2166,31 @@ BytecodeReader::Impl::parseOpWithoutRegions(EncodingReader &reader,
|
|||||||
opState.attributes = dictAttr;
|
opState.attributes = dictAttr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opMask & bytecode::OpEncodingMask::kHasProperties) {
|
||||||
|
// kHasProperties wasn't emitted in older bytecode, we should never get
|
||||||
|
// there without also having the `wasRegistered` flag available.
|
||||||
|
if (!wasRegistered)
|
||||||
|
return emitError(fileLoc,
|
||||||
|
"Unexpected missing `wasRegistered` opname flag at "
|
||||||
|
"bytecode version ")
|
||||||
|
<< version << " with properties.";
|
||||||
|
// When an operation is emitted without being registered, the properties are
|
||||||
|
// stored as an attribute. Otherwise the op must implement the bytecode
|
||||||
|
// interface and control the serialization.
|
||||||
|
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.
|
/// Parse the results of the operation.
|
||||||
if (opMask & bytecode::OpEncodingMask::kHasResults) {
|
if (opMask & bytecode::OpEncodingMask::kHasResults) {
|
||||||
uint64_t numResults;
|
uint64_t numResults;
|
||||||
|
|||||||
@@ -9,11 +9,23 @@
|
|||||||
#include "mlir/Bytecode/BytecodeWriter.h"
|
#include "mlir/Bytecode/BytecodeWriter.h"
|
||||||
#include "IRNumbering.h"
|
#include "IRNumbering.h"
|
||||||
#include "mlir/Bytecode/BytecodeImplementation.h"
|
#include "mlir/Bytecode/BytecodeImplementation.h"
|
||||||
|
#include "mlir/Bytecode/BytecodeOpInterface.h"
|
||||||
#include "mlir/Bytecode/Encoding.h"
|
#include "mlir/Bytecode/Encoding.h"
|
||||||
|
#include "mlir/IR/Attributes.h"
|
||||||
|
#include "mlir/IR/Diagnostics.h"
|
||||||
#include "mlir/IR/OpImplementation.h"
|
#include "mlir/IR/OpImplementation.h"
|
||||||
|
#include "mlir/Support/LogicalResult.h"
|
||||||
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/CachedHashString.h"
|
#include "llvm/ADT/CachedHashString.h"
|
||||||
#include "llvm/ADT/MapVector.h"
|
#include "llvm/ADT/MapVector.h"
|
||||||
#include "llvm/ADT/SmallString.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"
|
#define DEBUG_TYPE "mlir-bytecode-writer"
|
||||||
|
|
||||||
@@ -58,6 +70,10 @@ void BytecodeWriterConfig::setDesiredBytecodeVersion(int64_t bytecodeVersion) {
|
|||||||
std::min<int64_t>(bytecodeVersion, bytecode::kVersion);
|
std::min<int64_t>(bytecodeVersion, bytecode::kVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t BytecodeWriterConfig::getDesiredBytecodeVersion() const {
|
||||||
|
return impl->bytecodeVersion;
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// EncodingEmitter
|
// EncodingEmitter
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@@ -318,6 +334,14 @@ public:
|
|||||||
void writeAttribute(Attribute attr) override {
|
void writeAttribute(Attribute attr) override {
|
||||||
emitter.emitVarInt(numberingState.getNumber(attr));
|
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 {
|
void writeType(Type type) override {
|
||||||
emitter.emitVarInt(numberingState.getNumber(type));
|
emitter.emitVarInt(numberingState.getNumber(type));
|
||||||
}
|
}
|
||||||
@@ -382,6 +406,105 @@ private:
|
|||||||
StringSectionBuilder &stringSection;
|
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
|
/// 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
|
/// to go through an intermediate buffer when interacting with code that wants a
|
||||||
/// raw_ostream.
|
/// raw_ostream.
|
||||||
@@ -435,11 +558,12 @@ void EncodingEmitter::emitMultiByteVarInt(uint64_t value) {
|
|||||||
namespace {
|
namespace {
|
||||||
class BytecodeWriter {
|
class BytecodeWriter {
|
||||||
public:
|
public:
|
||||||
BytecodeWriter(Operation *op, const BytecodeWriterConfig::Impl &config)
|
BytecodeWriter(Operation *op, const BytecodeWriterConfig &config)
|
||||||
: numberingState(op), config(config) {}
|
: numberingState(op, config), config(config.getImpl()),
|
||||||
|
propertiesSection(numberingState, stringSection, config.getImpl()) {}
|
||||||
|
|
||||||
/// Write the bytecode for the given root operation.
|
/// Write the bytecode for the given root operation.
|
||||||
void write(Operation *rootOp, raw_ostream &os);
|
LogicalResult write(Operation *rootOp, raw_ostream &os);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
@@ -455,10 +579,10 @@ private:
|
|||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Operations
|
// Operations
|
||||||
|
|
||||||
void writeBlock(EncodingEmitter &emitter, Block *block);
|
LogicalResult writeBlock(EncodingEmitter &emitter, Block *block);
|
||||||
void writeOp(EncodingEmitter &emitter, Operation *op);
|
LogicalResult writeOp(EncodingEmitter &emitter, Operation *op);
|
||||||
void writeRegion(EncodingEmitter &emitter, Region *region);
|
LogicalResult writeRegion(EncodingEmitter &emitter, Region *region);
|
||||||
void writeIRSection(EncodingEmitter &emitter, Operation *op);
|
LogicalResult writeIRSection(EncodingEmitter &emitter, Operation *op);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Resources
|
// Resources
|
||||||
@@ -470,6 +594,11 @@ private:
|
|||||||
|
|
||||||
void writeStringSection(EncodingEmitter &emitter);
|
void writeStringSection(EncodingEmitter &emitter);
|
||||||
|
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
// Properties
|
||||||
|
|
||||||
|
void writePropertiesSection(EncodingEmitter &emitter);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
@@ -487,10 +616,13 @@ private:
|
|||||||
|
|
||||||
/// Configuration dictating bytecode emission.
|
/// Configuration dictating bytecode emission.
|
||||||
const BytecodeWriterConfig::Impl &config;
|
const BytecodeWriterConfig::Impl &config;
|
||||||
|
|
||||||
|
/// Storage for the properties section
|
||||||
|
PropertiesSectionBuilder propertiesSection;
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void BytecodeWriter::write(Operation *rootOp, raw_ostream &os) {
|
LogicalResult BytecodeWriter::write(Operation *rootOp, raw_ostream &os) {
|
||||||
EncodingEmitter emitter;
|
EncodingEmitter emitter;
|
||||||
|
|
||||||
// Emit the bytecode file header. This is how we identify the output as a
|
// Emit the bytecode file header. This is how we identify the output as a
|
||||||
@@ -510,7 +642,8 @@ void BytecodeWriter::write(Operation *rootOp, raw_ostream &os) {
|
|||||||
writeAttrTypeSection(emitter);
|
writeAttrTypeSection(emitter);
|
||||||
|
|
||||||
// Emit the IR section.
|
// Emit the IR section.
|
||||||
writeIRSection(emitter, rootOp);
|
if (failed(writeIRSection(emitter, rootOp)))
|
||||||
|
return failure();
|
||||||
|
|
||||||
// Emit the resources section.
|
// Emit the resources section.
|
||||||
writeResourceSection(rootOp, emitter);
|
writeResourceSection(rootOp, emitter);
|
||||||
@@ -518,8 +651,17 @@ void BytecodeWriter::write(Operation *rootOp, raw_ostream &os) {
|
|||||||
// Emit the string section.
|
// Emit the string section.
|
||||||
writeStringSection(emitter);
|
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.
|
// Write the generated bytecode to the provided output stream.
|
||||||
emitter.writeTo(os);
|
emitter.writeTo(os);
|
||||||
|
|
||||||
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@@ -590,7 +732,11 @@ void BytecodeWriter::writeDialectSection(EncodingEmitter &emitter) {
|
|||||||
|
|
||||||
// Emit the referenced operation names grouped by dialect.
|
// Emit the referenced operation names grouped by dialect.
|
||||||
auto emitOpName = [&](OpNameNumbering &name) {
|
auto emitOpName = [&](OpNameNumbering &name) {
|
||||||
dialectEmitter.emitVarInt(stringSection.insert(name.name.stripDialect()));
|
size_t stringId = stringSection.insert(name.name.stripDialect());
|
||||||
|
if (config.bytecodeVersion < 5)
|
||||||
|
dialectEmitter.emitVarInt(stringId);
|
||||||
|
else
|
||||||
|
dialectEmitter.emitVarIntWithFlag(stringId, name.name.isRegistered());
|
||||||
};
|
};
|
||||||
writeDialectGrouping(dialectEmitter, numberingState.getOpNames(), emitOpName);
|
writeDialectGrouping(dialectEmitter, numberingState.getOpNames(), emitOpName);
|
||||||
|
|
||||||
@@ -659,7 +805,8 @@ void BytecodeWriter::writeAttrTypeSection(EncodingEmitter &emitter) {
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Operations
|
// Operations
|
||||||
|
|
||||||
void BytecodeWriter::writeBlock(EncodingEmitter &emitter, Block *block) {
|
LogicalResult BytecodeWriter::writeBlock(EncodingEmitter &emitter,
|
||||||
|
Block *block) {
|
||||||
ArrayRef<BlockArgument> args = block->getArguments();
|
ArrayRef<BlockArgument> args = block->getArguments();
|
||||||
bool hasArgs = !args.empty();
|
bool hasArgs = !args.empty();
|
||||||
|
|
||||||
@@ -696,10 +843,12 @@ void BytecodeWriter::writeBlock(EncodingEmitter &emitter, Block *block) {
|
|||||||
|
|
||||||
// Emit the operations within the block.
|
// Emit the operations within the block.
|
||||||
for (Operation &op : *block)
|
for (Operation &op : *block)
|
||||||
writeOp(emitter, &op);
|
if (failed(writeOp(emitter, &op)))
|
||||||
|
return failure();
|
||||||
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeWriter::writeOp(EncodingEmitter &emitter, Operation *op) {
|
LogicalResult BytecodeWriter::writeOp(EncodingEmitter &emitter, Operation *op) {
|
||||||
emitter.emitVarInt(numberingState.getNumber(op->getName()));
|
emitter.emitVarInt(numberingState.getNumber(op->getName()));
|
||||||
|
|
||||||
// Emit a mask for the operation components. We need to fill this in later
|
// Emit a mask for the operation components. We need to fill this in later
|
||||||
@@ -713,10 +862,24 @@ void BytecodeWriter::writeOp(EncodingEmitter &emitter, Operation *op) {
|
|||||||
emitter.emitVarInt(numberingState.getNumber(op->getLoc()));
|
emitter.emitVarInt(numberingState.getNumber(op->getLoc()));
|
||||||
|
|
||||||
// Emit the attributes of this operation.
|
// Emit the attributes of this operation.
|
||||||
DictionaryAttr attrs = op->getAttrDictionary();
|
DictionaryAttr attrs = op->getDiscardableAttrDictionary();
|
||||||
|
// Allow deployment to version <5 by merging inherent attribute with the
|
||||||
|
// discardable ones. We should fail if there are any conflicts.
|
||||||
|
if (config.bytecodeVersion < 5)
|
||||||
|
attrs = op->getAttrDictionary();
|
||||||
if (!attrs.empty()) {
|
if (!attrs.empty()) {
|
||||||
opEncodingMask |= bytecode::OpEncodingMask::kHasAttrs;
|
opEncodingMask |= bytecode::OpEncodingMask::kHasAttrs;
|
||||||
emitter.emitVarInt(numberingState.getNumber(op->getAttrDictionary()));
|
emitter.emitVarInt(numberingState.getNumber(attrs));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emit the properties of this operation, for now we still support deployment
|
||||||
|
// to version <5.
|
||||||
|
if (config.bytecodeVersion >= 5) {
|
||||||
|
std::optional<ssize_t> propertiesId = propertiesSection.emit(op);
|
||||||
|
if (propertiesId.has_value()) {
|
||||||
|
opEncodingMask |= bytecode::OpEncodingMask::kHasProperties;
|
||||||
|
emitter.emitVarInt(*propertiesId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit the result types of the operation.
|
// Emit the result types of the operation.
|
||||||
@@ -768,15 +931,18 @@ void BytecodeWriter::writeOp(EncodingEmitter &emitter, Operation *op) {
|
|||||||
// If the region is not isolated from above, or we are emitting bytecode
|
// If the region is not isolated from above, or we are emitting bytecode
|
||||||
// targeting version <2, we don't use a section.
|
// targeting version <2, we don't use a section.
|
||||||
if (!isIsolatedFromAbove || config.bytecodeVersion < 2) {
|
if (!isIsolatedFromAbove || config.bytecodeVersion < 2) {
|
||||||
writeRegion(emitter, ®ion);
|
if (failed(writeRegion(emitter, ®ion)))
|
||||||
|
return failure();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
EncodingEmitter regionEmitter;
|
EncodingEmitter regionEmitter;
|
||||||
writeRegion(regionEmitter, ®ion);
|
if (failed(writeRegion(regionEmitter, ®ion)))
|
||||||
|
return failure();
|
||||||
emitter.emitSection(bytecode::Section::kIR, std::move(regionEmitter));
|
emitter.emitSection(bytecode::Section::kIR, std::move(regionEmitter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeWriter::writeUseListOrders(EncodingEmitter &emitter,
|
void BytecodeWriter::writeUseListOrders(EncodingEmitter &emitter,
|
||||||
@@ -867,11 +1033,14 @@ void BytecodeWriter::writeUseListOrders(EncodingEmitter &emitter,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeWriter::writeRegion(EncodingEmitter &emitter, Region *region) {
|
LogicalResult BytecodeWriter::writeRegion(EncodingEmitter &emitter,
|
||||||
|
Region *region) {
|
||||||
// If the region is empty, we only need to emit the number of blocks (which is
|
// If the region is empty, we only need to emit the number of blocks (which is
|
||||||
// zero).
|
// zero).
|
||||||
if (region->empty())
|
if (region->empty()) {
|
||||||
return emitter.emitVarInt(/*numBlocks*/ 0);
|
emitter.emitVarInt(/*numBlocks*/ 0);
|
||||||
|
return success();
|
||||||
|
}
|
||||||
|
|
||||||
// Emit the number of blocks and values within the region.
|
// Emit the number of blocks and values within the region.
|
||||||
unsigned numBlocks, numValues;
|
unsigned numBlocks, numValues;
|
||||||
@@ -881,10 +1050,13 @@ void BytecodeWriter::writeRegion(EncodingEmitter &emitter, Region *region) {
|
|||||||
|
|
||||||
// Emit the blocks within the region.
|
// Emit the blocks within the region.
|
||||||
for (Block &block : *region)
|
for (Block &block : *region)
|
||||||
writeBlock(emitter, &block);
|
if (failed(writeBlock(emitter, &block)))
|
||||||
|
return failure();
|
||||||
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeWriter::writeIRSection(EncodingEmitter &emitter, Operation *op) {
|
LogicalResult BytecodeWriter::writeIRSection(EncodingEmitter &emitter,
|
||||||
|
Operation *op) {
|
||||||
EncodingEmitter irEmitter;
|
EncodingEmitter irEmitter;
|
||||||
|
|
||||||
// Write the IR section the same way as a block with no arguments. Note that
|
// Write the IR section the same way as a block with no arguments. Note that
|
||||||
@@ -893,9 +1065,11 @@ void BytecodeWriter::writeIRSection(EncodingEmitter &emitter, Operation *op) {
|
|||||||
irEmitter.emitVarIntWithFlag(/*numOps*/ 1, /*hasArgs*/ false);
|
irEmitter.emitVarIntWithFlag(/*numOps*/ 1, /*hasArgs*/ false);
|
||||||
|
|
||||||
// Emit the operations.
|
// Emit the operations.
|
||||||
writeOp(irEmitter, op);
|
if (failed(writeOp(irEmitter, op)))
|
||||||
|
return failure();
|
||||||
|
|
||||||
emitter.emitSection(bytecode::Section::kIR, std::move(irEmitter));
|
emitter.emitSection(bytecode::Section::kIR, std::move(irEmitter));
|
||||||
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@@ -1011,14 +1185,22 @@ void BytecodeWriter::writeStringSection(EncodingEmitter &emitter) {
|
|||||||
emitter.emitSection(bytecode::Section::kString, std::move(stringEmitter));
|
emitter.emitSection(bytecode::Section::kString, std::move(stringEmitter));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Properties
|
||||||
|
|
||||||
|
void BytecodeWriter::writePropertiesSection(EncodingEmitter &emitter) {
|
||||||
|
EncodingEmitter propertiesEmitter;
|
||||||
|
propertiesSection.write(propertiesEmitter);
|
||||||
|
emitter.emitSection(bytecode::Section::kProperties,
|
||||||
|
std::move(propertiesEmitter));
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Entry Points
|
// Entry Points
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
LogicalResult mlir::writeBytecodeToFile(Operation *op, raw_ostream &os,
|
LogicalResult mlir::writeBytecodeToFile(Operation *op, raw_ostream &os,
|
||||||
const BytecodeWriterConfig &config) {
|
const BytecodeWriterConfig &config) {
|
||||||
BytecodeWriter writer(op, config.getImpl());
|
BytecodeWriter writer(op, config);
|
||||||
writer.write(op, os);
|
return writer.write(op, os);
|
||||||
// Currently there is no failure case.
|
|
||||||
return success();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ add_mlir_library(MLIRBytecodeWriter
|
|||||||
LINK_LIBS PUBLIC
|
LINK_LIBS PUBLIC
|
||||||
MLIRIR
|
MLIRIR
|
||||||
MLIRSupport
|
MLIRSupport
|
||||||
|
MLIRBytecodeOpInterface
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "IRNumbering.h"
|
#include "IRNumbering.h"
|
||||||
#include "mlir/Bytecode/BytecodeImplementation.h"
|
#include "mlir/Bytecode/BytecodeImplementation.h"
|
||||||
|
#include "mlir/Bytecode/BytecodeOpInterface.h"
|
||||||
#include "mlir/IR/AsmState.h"
|
#include "mlir/IR/AsmState.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
#include "mlir/IR/OpDefinition.h"
|
#include "mlir/IR/OpDefinition.h"
|
||||||
@@ -24,6 +25,10 @@ struct IRNumberingState::NumberingDialectWriter : public DialectBytecodeWriter {
|
|||||||
NumberingDialectWriter(IRNumberingState &state) : state(state) {}
|
NumberingDialectWriter(IRNumberingState &state) : state(state) {}
|
||||||
|
|
||||||
void writeAttribute(Attribute attr) override { state.number(attr); }
|
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 writeType(Type type) override { state.number(type); }
|
||||||
void writeResourceHandle(const AsmDialectResourceHandle &resource) override {
|
void writeResourceHandle(const AsmDialectResourceHandle &resource) override {
|
||||||
state.number(resource.getDialect(), resource);
|
state.number(resource.getDialect(), resource);
|
||||||
@@ -106,7 +111,9 @@ static void groupByDialectPerByte(T range) {
|
|||||||
value->number = idx;
|
value->number = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
IRNumberingState::IRNumberingState(Operation *op) {
|
IRNumberingState::IRNumberingState(Operation *op,
|
||||||
|
const BytecodeWriterConfig &config)
|
||||||
|
: config(config) {
|
||||||
// Compute a global operation ID numbering according to the pre-order walk of
|
// 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.
|
// the IR. This is used as reference to construct use-list orders.
|
||||||
unsigned operationID = 0;
|
unsigned operationID = 0;
|
||||||
@@ -276,10 +283,30 @@ void IRNumberingState::number(Operation &op) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only number the operation's dictionary if it isn't empty.
|
// Only number the operation's dictionary if it isn't empty.
|
||||||
DictionaryAttr dictAttr = op.getAttrDictionary();
|
DictionaryAttr dictAttr = op.getDiscardableAttrDictionary();
|
||||||
|
// Prior to version 5 we need to number also the merged dictionnary
|
||||||
|
// containing both the inherent and discardable attribute.
|
||||||
|
if (config.getDesiredBytecodeVersion() < 5)
|
||||||
|
dictAttr = op.getAttrDictionary();
|
||||||
if (!dictAttr.empty())
|
if (!dictAttr.empty())
|
||||||
number(dictAttr);
|
number(dictAttr);
|
||||||
|
|
||||||
|
// Visit the operation properties (if any) to make sure referenced attributes
|
||||||
|
// are numbered.
|
||||||
|
if (config.getDesiredBytecodeVersion() >= 5 &&
|
||||||
|
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.
|
||||||
|
if (Attribute prop = *op.getPropertiesStorage().as<Attribute *>())
|
||||||
|
number(prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
number(op.getLoc());
|
number(op.getLoc());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
#include "llvm/ADT/MapVector.h"
|
#include "llvm/ADT/MapVector.h"
|
||||||
#include "llvm/ADT/SetVector.h"
|
#include "llvm/ADT/SetVector.h"
|
||||||
#include "llvm/ADT/StringMap.h"
|
#include "llvm/ADT/StringMap.h"
|
||||||
|
#include "llvm/CodeGen/NonRelocatableStringpool.h"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace mlir {
|
namespace mlir {
|
||||||
class BytecodeDialectInterface;
|
class BytecodeDialectInterface;
|
||||||
@@ -133,7 +135,7 @@ struct DialectNumbering {
|
|||||||
/// emission.
|
/// emission.
|
||||||
class IRNumberingState {
|
class IRNumberingState {
|
||||||
public:
|
public:
|
||||||
IRNumberingState(Operation *op);
|
IRNumberingState(Operation *op, const BytecodeWriterConfig &config);
|
||||||
|
|
||||||
/// Return the numbered dialects.
|
/// Return the numbered dialects.
|
||||||
auto getDialects() {
|
auto getDialects() {
|
||||||
@@ -241,6 +243,9 @@ private:
|
|||||||
|
|
||||||
/// The next value ID to assign when numbering.
|
/// The next value ID to assign when numbering.
|
||||||
unsigned nextValueID = 0;
|
unsigned nextValueID = 0;
|
||||||
|
|
||||||
|
// Configuration: useful to query the required version to emit.
|
||||||
|
const BytecodeWriterConfig &config;
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace bytecode
|
} // namespace bytecode
|
||||||
|
|||||||
@@ -72,6 +72,16 @@ StringRef Property::getConvertFromAttributeCall() const {
|
|||||||
return getValueAsString(init);
|
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 {
|
StringRef Property::getHashPropertyCall() const {
|
||||||
return getValueAsString(def->getValueInit("hashProperty"));
|
return getValueAsString(def->getValueInit("hashProperty"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
||||||
// RUN: not mlir-opt %S/invalid-structure-version.mlirbc 2>&1 | FileCheck %s --check-prefix=VERSION
|
// 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
|
// VERSION: bytecode version 127 is newer than the current version {{[0-9]+}}
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Producer
|
// Producer
|
||||||
|
|||||||
@@ -28,12 +28,14 @@
|
|||||||
#include "mlir/IR/Verifier.h"
|
#include "mlir/IR/Verifier.h"
|
||||||
#include "mlir/Interfaces/InferIntRangeInterface.h"
|
#include "mlir/Interfaces/InferIntRangeInterface.h"
|
||||||
#include "mlir/Reducer/ReductionPatternInterface.h"
|
#include "mlir/Reducer/ReductionPatternInterface.h"
|
||||||
|
#include "mlir/Support/LogicalResult.h"
|
||||||
#include "mlir/Transforms/FoldUtils.h"
|
#include "mlir/Transforms/FoldUtils.h"
|
||||||
#include "mlir/Transforms/InliningUtils.h"
|
#include "mlir/Transforms/InliningUtils.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/ADT/StringSwitch.h"
|
#include "llvm/ADT/StringSwitch.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
@@ -62,6 +64,44 @@ llvm::hash_code MyPropStruct::hash() const {
|
|||||||
return hash_value(StringRef(content));
|
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,
|
static LogicalResult setPropertiesFromAttribute(PropertiesWithCustomPrint &prop,
|
||||||
Attribute attr,
|
Attribute attr,
|
||||||
InFlightDiagnostic *diagnostic);
|
InFlightDiagnostic *diagnostic);
|
||||||
|
|||||||
@@ -3324,7 +3324,7 @@ def TestVersionedOpB : TEST_Op<"versionedB"> {
|
|||||||
def TestOpWithProperties : TEST_Op<"with_properties"> {
|
def TestOpWithProperties : TEST_Op<"with_properties"> {
|
||||||
let assemblyFormat = "prop-dict attr-dict";
|
let assemblyFormat = "prop-dict attr-dict";
|
||||||
let arguments = (ins
|
let arguments = (ins
|
||||||
Property<"int64_t">:$a,
|
IntProperty<"int64_t">:$a,
|
||||||
StrAttr:$b, // Attributes can directly be used here.
|
StrAttr:$b, // Attributes can directly be used here.
|
||||||
ArrayProperty<"int64_t", 4>:$array // example of an array
|
ArrayProperty<"int64_t", 4>:$array // example of an array
|
||||||
);
|
);
|
||||||
@@ -3369,8 +3369,31 @@ def TestOpWithNiceProperties : TEST_Op<"with_nice_properties"> {
|
|||||||
const Properties &prop);
|
const Properties &prop);
|
||||||
static ::mlir::ParseResult parseProperties(::mlir::OpAsmParser &parser,
|
static ::mlir::ParseResult parseProperties(::mlir::OpAsmParser &parser,
|
||||||
::mlir::OperationState &result);
|
::mlir::OperationState &result);
|
||||||
|
static ::mlir::LogicalResult readFromMlirBytecode(
|
||||||
|
::mlir::DialectBytecodeReader &,
|
||||||
|
test::PropertiesWithCustomPrint &prop);
|
||||||
|
static void writeToMlirBytecode(
|
||||||
|
::mlir::DialectBytecodeWriter &,
|
||||||
|
const test::PropertiesWithCustomPrint &prop);
|
||||||
}];
|
}];
|
||||||
let extraClassDefinition = [{
|
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,
|
void TestOpWithNiceProperties::printProperties(::mlir::MLIRContext *ctx,
|
||||||
::mlir::OpAsmPrinter &p, const Properties &prop) {
|
::mlir::OpAsmPrinter &p, const Properties &prop) {
|
||||||
customPrintProperties(p, prop.prop);
|
customPrintProperties(p, prop.prop);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#ifndef MLIR_TESTTRANSFORMDIALECTEXTENSION_H
|
#ifndef MLIR_TESTTRANSFORMDIALECTEXTENSION_H
|
||||||
#define MLIR_TESTTRANSFORMDIALECTEXTENSION_H
|
#define MLIR_TESTTRANSFORMDIALECTEXTENSION_H
|
||||||
|
|
||||||
|
#include "mlir/Bytecode/BytecodeOpInterface.h"
|
||||||
#include "mlir/Dialect/PDL/IR/PDLTypes.h"
|
#include "mlir/Dialect/PDL/IR/PDLTypes.h"
|
||||||
#include "mlir/Dialect/Transform/IR/MatchInterfaces.h"
|
#include "mlir/Dialect/Transform/IR/MatchInterfaces.h"
|
||||||
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
|
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
|
||||||
|
|||||||
@@ -1103,6 +1103,21 @@ void OpEmitter::genPropertiesSupport() {
|
|||||||
"getDiag"))
|
"getDiag"))
|
||||||
->body();
|
->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");
|
opClass.declare<UsingDeclaration>("Properties", "FoldAdaptor::Properties");
|
||||||
|
|
||||||
// Convert the property to the attribute form.
|
// Convert the property to the attribute form.
|
||||||
@@ -1304,6 +1319,66 @@ void OpEmitter::genPropertiesSupport() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
verifyInherentAttrsMethod << " return ::mlir::success();";
|
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() {
|
void OpEmitter::genAttrGetters() {
|
||||||
@@ -3303,6 +3378,9 @@ void OpEmitter::genTraits() {
|
|||||||
// native/interface traits and after all the traits with `StructuralOpTrait`.
|
// native/interface traits and after all the traits with `StructuralOpTrait`.
|
||||||
opClass.addTrait("::mlir::OpTrait::OpInvariants");
|
opClass.addTrait("::mlir::OpTrait::OpInvariants");
|
||||||
|
|
||||||
|
if (emitHelper.hasProperties())
|
||||||
|
opClass.addTrait("::mlir::BytecodeOpInterface::Trait");
|
||||||
|
|
||||||
// Add the native and interface traits.
|
// Add the native and interface traits.
|
||||||
for (const auto &trait : op.getTraits()) {
|
for (const auto &trait : op.getTraits()) {
|
||||||
if (auto *opTrait = dyn_cast<tblgen::NativeTrait>(&trait)) {
|
if (auto *opTrait = dyn_cast<tblgen::NativeTrait>(&trait)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user