[Mlir-commits] [mlir] a672319 - [mlir][linalg][bufferize] Add BufferizableOpInterface
Matthias Springer
llvmlistbot at llvm.org
Tue Nov 2 02:20:05 PDT 2021
Author: Matthias Springer
Date: 2021-11-02T18:19:58+09:00
New Revision: a672319c2edfcf617301b3d4f936c2d7a3b23fab
URL: https://github.com/llvm/llvm-project/commit/a672319c2edfcf617301b3d4f936c2d7a3b23fab
DIFF: https://github.com/llvm/llvm-project/commit/a672319c2edfcf617301b3d4f936c2d7a3b23fab.diff
LOG: [mlir][linalg][bufferize] Add BufferizableOpInterface
This commit adds a new op interface: BufferizableOpInterface. In the future, ops that implement this interface can be bufferized using Comprehensive Bufferize.
Note: The interface methods of this interface correspond to the "op interface" in ComprehensiveBufferize.cpp.
Differential Revision: https://reviews.llvm.org/D112974
Added:
mlir/include/mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.h
mlir/include/mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.td
mlir/include/mlir/Dialect/Linalg/Transforms/CMakeLists.txt
mlir/lib/Dialect/Linalg/Transforms/BufferizableOpInterface.cpp
Modified:
mlir/include/mlir/Dialect/Linalg/CMakeLists.txt
mlir/include/mlir/Dialect/Linalg/Transforms/ComprehensiveBufferize.h
mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt
mlir/lib/Dialect/Linalg/Transforms/ComprehensiveBufferize.cpp
utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/Linalg/CMakeLists.txt b/mlir/include/mlir/Dialect/Linalg/CMakeLists.txt
index d8a082f10db3f..ae300dd7d27ac 100644
--- a/mlir/include/mlir/Dialect/Linalg/CMakeLists.txt
+++ b/mlir/include/mlir/Dialect/Linalg/CMakeLists.txt
@@ -1,4 +1,5 @@
add_subdirectory(IR)
+add_subdirectory(Transforms)
set(LLVM_TARGET_DEFINITIONS Passes.td)
mlir_tablegen(Passes.h.inc -gen-pass-decls -name Linalg)
diff --git a/mlir/include/mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.h b/mlir/include/mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.h
new file mode 100644
index 0000000000000..bbdeeb9c90f84
--- /dev/null
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.h
@@ -0,0 +1,36 @@
+//===- BufferizableOpInterface.h - Comprehensive Bufferize ------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_LINALG_TRANSFORMS_BUFFERIZABLEOPINTERFACE_H_
+#define MLIR_DIALECT_LINALG_TRANSFORMS_BUFFERIZABLEOPINTERFACE_H_
+
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/Operation.h"
+#include "mlir/Support/LLVM.h"
+
+namespace mlir {
+class BlockAndValueMapping;
+
+namespace linalg {
+class AllocationCallbacks;
+class BufferizationAliasInfo;
+
+/// Specify fine-grain relationship between buffers to enable more analysis.
+enum class BufferRelation {
+ None,
+ // TODO: ResultContainsOperand,
+ // TODO: OperandContainsResult,
+ Equivalent
+};
+} // namespace linalg
+} // namespace mlir
+
+#include "mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.h.inc"
+
+#endif // MLIR_DIALECT_LINALG_TRANSFORMS_BUFFERIZABLEOPINTERFACE_H_
diff --git a/mlir/include/mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.td b/mlir/include/mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.td
new file mode 100644
index 0000000000000..39c40c788074a
--- /dev/null
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.td
@@ -0,0 +1,183 @@
+//===-- BufferizableOpInterface.td - Compreh. Bufferize ----*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_LINALG_TRANSFORMS_BUFFERIZABLEOPINTERFACE
+#define MLIR_DIALECT_LINALG_TRANSFORMS_BUFFERIZABLEOPINTERFACE
+
+include "mlir/IR/OpBase.td"
+
+def BufferizableOpInterface : OpInterface<"BufferizableOpInterface"> {
+ let description = [{
+ An op interface for Comprehensive Bufferization. Ops that implement this
+ interface can be bufferized using Comprehensive Bufferization.
+ }];
+ let cppNamespace = "::mlir::linalg";
+ let methods = [
+ InterfaceMethod<
+ /*desc=*/[{
+ Return `true` if the given OpOperand bufferizes to a memory read. This
+ method will never be called on OpOperands that do not have a tensor
+ type.
+
+ Note: It is always safe to consider an OpOperand as a memory read,
+ even if it does actually not read; however, this can introduce
+ unnecessary out-of-place bufferization decisions. The analysis of
+ Comprehensive Bufferize considers OpOperands of unknown ops (that do
+ not implement this interface) as reading OpOperands.
+ }],
+ /*retType=*/"bool",
+ /*methodName=*/"bufferizesToMemoryRead",
+ /*args=*/(ins "OpOperand &":$opOperand),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ // Does not have to be implemented for ops without tensor OpOperands.
+ llvm_unreachable("bufferizesToMemoryRead not implemented");
+ }]
+ >,
+ InterfaceMethod<
+ /*desc=*/[{
+ Return `true` if the given OpOperand bufferizes to a memory write.
+ This method will never be called on OpOperands that do not have a
+ tensor type.
+
+ Note: It is always safe to consider an OpOperand as a memory write,
+ even if it does actually not write; however, this can introduce
+ unnecessary out-of-place bufferization decisions. The analysis of
+ Comprehensive Bufferize considers OpOperands of unknown ops (that do
+ not implement this interface) as writing OpOperands.
+ }],
+ /*retType=*/"bool",
+ /*methodName=*/"bufferizesToMemoryWrite",
+ /*args=*/(ins "OpOperand &":$opOperand),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ // Does not have to be implemented for ops without tensor OpOperands.
+ llvm_unreachable("bufferizesToMemoryWrite not implemented");
+ }]
+ >,
+ // TODO: Simplify this interface by removing `bufferizesToAliasOnly` and
+ // `getInplaceableOpResult`. Instead, always use `getAliasingOpResult`. If
+ // `getAliasingOpResult` returns a non-null value, we know that an alias
+ // is created. If `bufferizesToMemoryRead` and `bufferizesToMemoryWrite`
+ // return `false`, we know that the operands "bufferizes to alias only".
+ InterfaceMethod<
+ /*desc=*/[{
+ Return `true` if the given OpOperand creates an alias but does neither
+ read nor write. This implies that `bufferizesToMemoryRead` and
+ `bufferizesToMemoryWrite` must return `false`. This method will never
+ be called on OpOperands that do not have a tensor type.
+
+ Examples of such ops are `tensor.extract_slice` and `tensor.cast`.
+ }],
+ /*retType=*/"bool",
+ /*methodName=*/"bufferizesToAliasOnly",
+ /*args=*/(ins "OpOperand &":$opOperand),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ // For better debugging, run `bufferizesToMemoryWrite`, which fires an
+ // assertion when called on an op that should not have tensor
+ // OpOperands.
+ (void) cast<BufferizableOpInterface>($_op.getOperation())
+ .bufferizesToMemoryWrite(opOperand);
+ // Return `false` by default, as most ops are not "alias only".
+ return false;
+ }]
+ >,
+ InterfaceMethod<
+ /*desc=*/[{
+ Return the OpResult that can bufferize in-place with a given
+ OpOperand. Return a null value if the OpOperand cannot bufferize
+ in-place. This method will never be called on OpOperands that do not
+ have a tensor type.
+ }],
+ /*retType=*/"OpResult",
+ /*methodName=*/"getInplaceableOpResult",
+ /*args=*/(ins "OpOperand &":$opOperand),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ // Does not have to be implemented for ops without tensor OpOperands.
+ llvm_unreachable("getInplaceableOpResult not implemented");
+ }]
+ >,
+ InterfaceMethod<
+ /*desc=*/[{
+ Return the OpResult that aliases with a given OpOperand when
+ bufferized in-place. This is a superset of `getInplaceableOpResult`.
+ This method will never be called on OpOperands that do not have a
+ tensor type.
+ }],
+ /*retType=*/"OpResult",
+ /*methodName=*/"getAliasingOpResult",
+ /*args=*/(ins "OpOperand &":$opOperand),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ return cast<BufferizableOpInterface>($_op.getOperation())
+ .getInplaceableOpResult(opOperand);
+ }]
+ >,
+ InterfaceMethod<
+ /*desc=*/[{
+ Return the OpOperands that alias with a given OpResult when
+ bufferized in-place. This method will never be called on OpResults
+ that do not have a tensor type.
+
+ Note: This method can return multiple OpOperands, indicating that the
+ given OpResult may at runtime alias with any of the OpOperands. This
+ is useful for branches and for ops such as `std.select`.
+ }],
+ /*retType=*/"SmallVector<OpOperand *>",
+ /*methodName=*/"getAliasingOpOperand",
+ /*args=*/(ins "OpResult":$opResult),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ // Does not have to be implemented for ops without tensor OpResults.
+ llvm_unreachable("getInplaceableOpResult not implemented");
+ }]
+ >,
+ InterfaceMethod<
+ /*desc=*/[{
+ Return the buffer relation between the given OpOperand and its
+ aliasing OpResult when bufferized in-place. Most OpOperands have an
+ "equivalence" relation.
+
+ TODO: Support other relations such as "OpOperand is included in
+ OpResult".
+ }],
+ /*retType=*/"BufferRelation",
+ /*methodName=*/"bufferRelation",
+ /*args=*/(ins "OpOperand &":$opOperand),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ // Does not have to be implemented for ops without tensor OpOperands.
+ llvm_unreachable("bufferRelation not implemented");
+ }]
+ >,
+ // TODO: Simplify method signature: Pass an OpBuilder and a
+ // BufferizationState object.
+ InterfaceMethod<
+ /*desc=*/[{
+ Bufferize this op, i.e., rewrite it into a memref-based equivalent.
+ `bvm` maps tensor values to memref values and this method should map
+ tensor results to memref results after creating/modifying ops.
+ }],
+ /*retType=*/"LogicalResult",
+ /*methodName=*/"bufferize",
+ /*args=*/(ins "OpBuilder &":$b,
+ "BlockAndValueMapping &":$bvm,
+ "BufferizationAliasInfo &":$aliasInfo,
+ "AllocationCallbacks &":$allocationFn),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ llvm_unreachable("bufferize not implemented");
+ return failure();
+ }]
+ >,
+ ];
+}
+
+#endif // MLIR_DIALECT_LINALG_TRANSFORMS_BUFFERIZABLEOPINTERFACE
diff --git a/mlir/include/mlir/Dialect/Linalg/Transforms/CMakeLists.txt b/mlir/include/mlir/Dialect/Linalg/Transforms/CMakeLists.txt
new file mode 100644
index 0000000000000..c2a58e98061b1
--- /dev/null
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(LLVM_TARGET_DEFINITIONS BufferizableOpInterface.td)
+mlir_tablegen(BufferizableOpInterface.h.inc -gen-op-interface-decls)
+mlir_tablegen(BufferizableOpInterface.cpp.inc -gen-op-interface-defs)
+add_public_tablegen_target(MLIRBufferizableOpInterfaceIncGen)
+add_dependencies(mlir-headers MLIRBufferizableOpInterfaceIncGen)
diff --git a/mlir/include/mlir/Dialect/Linalg/Transforms/ComprehensiveBufferize.h b/mlir/include/mlir/Dialect/Linalg/Transforms/ComprehensiveBufferize.h
index f793ae4eec9c2..fbb168e05545e 100644
--- a/mlir/include/mlir/Dialect/Linalg/Transforms/ComprehensiveBufferize.h
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/ComprehensiveBufferize.h
@@ -34,14 +34,6 @@ namespace linalg {
/// uses BufferizationAliasInfo.
class BufferizationAliasInfo {
public:
- /// Specify fine-grain relationship between buffers to enable more analysis.
- enum class BufferRelation {
- None,
- // TODO: ResultContainsOperand,
- // TODO: OperandContainsResult,
- Equivalent
- };
-
explicit BufferizationAliasInfo(Operation *rootOp);
/// Add a new entry for `v` in the `aliasInfo` and `equivalentInfo`. In the
diff --git a/mlir/lib/Dialect/Linalg/Transforms/BufferizableOpInterface.cpp b/mlir/lib/Dialect/Linalg/Transforms/BufferizableOpInterface.cpp
new file mode 100644
index 0000000000000..2d49c6c1d1fb0
--- /dev/null
+++ b/mlir/lib/Dialect/Linalg/Transforms/BufferizableOpInterface.cpp
@@ -0,0 +1,17 @@
+//===- BufferizableOpInterface.cpp - Comprehensive Bufferize --------------===//
+//
+// 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/Dialect/Linalg/Transforms/BufferizableOpInterface.h"
+
+namespace mlir {
+namespace linalg {
+
+#include "mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.cpp.inc"
+
+} // namespace linalg
+} // namespace mlir
diff --git a/mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt b/mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt
index 840978bf56484..fa0c3469d80f1 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt
+++ b/mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt
@@ -1,3 +1,38 @@
+set(LLVM_OPTIONAL_SOURCES
+ Bufferize.cpp
+ BufferizableOpInterface.cpp
+ CodegenStrategy.cpp
+ ComprehensiveBufferize.cpp
+ Detensorize.cpp
+ Distribution.cpp
+ DropUnitDims.cpp
+ ElementwiseOpFusion.cpp
+ ElementwiseToLinalg.cpp
+ Fusion.cpp
+ FusionOnTensors.cpp
+ Generalization.cpp
+ Hoisting.cpp
+ HoistPadding.cpp
+ InlineScalarOperands.cpp
+ Interchange.cpp
+ Loops.cpp
+ LinalgStrategyPasses.cpp
+ Promotion.cpp
+ Tiling.cpp
+ Transforms.cpp
+ Vectorization.cpp
+)
+
+add_mlir_dialect_library(MLIRBufferizableOpInterface
+ BufferizableOpInterface.cpp
+
+ DEPENDS
+ MLIRBufferizableOpInterfaceIncGen
+
+ LINK_LIBS PUBLIC
+ MLIRIR
+)
+
add_mlir_dialect_library(MLIRLinalgTransforms
Bufferize.cpp
CodegenStrategy.cpp
@@ -32,6 +67,7 @@ add_mlir_dialect_library(MLIRLinalgTransforms
MLIRAffineUtils
MLIRAnalysis
MLIRArithmetic
+ MLIRBufferizableOpInterface
MLIRComplex
MLIRInferTypeOpInterface
MLIRIR
diff --git a/mlir/lib/Dialect/Linalg/Transforms/ComprehensiveBufferize.cpp b/mlir/lib/Dialect/Linalg/Transforms/ComprehensiveBufferize.cpp
index 691d56f7ab3e3..82424c897b4e5 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/ComprehensiveBufferize.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/ComprehensiveBufferize.cpp
@@ -112,6 +112,7 @@
#include "PassDetail.h"
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
#include "mlir/Dialect/Linalg/Passes.h"
+#include "mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.h"
#include "mlir/Dialect/Linalg/Transforms/Transforms.h"
#include "mlir/Dialect/Linalg/Utils/Utils.h"
#include "mlir/Dialect/MemRef/IR/MemRef.h"
@@ -138,8 +139,6 @@ using namespace mlir;
using namespace linalg;
using namespace tensor;
-using BufferRelation = BufferizationAliasInfo::BufferRelation;
-
#define DBGS() (llvm::dbgs() << '[' << DEBUG_TYPE << "] ")
#define LDBG(X) LLVM_DEBUG(DBGS() << X)
diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
index a5a59eb9cd632..ea1dd5845fcbb 100644
--- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
@@ -6126,6 +6126,54 @@ gentbl_cc_library(
deps = [":LinalgStructuredOpsTdFiles"],
)
+td_library(
+ name = "BufferizableOpInterfaceTdFiles",
+ srcs = [
+ "include/mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.td",
+ ],
+ includes = ["include"],
+ deps = [
+ ":OpBaseTdFiles",
+ ],
+)
+
+gentbl_cc_library(
+ name = "BufferizableOpInterfaceIncGen",
+ strip_include_prefix = "include",
+ tbl_outs = [
+ (
+ ["-gen-op-interface-decls"],
+ "include/mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.h.inc",
+ ),
+ (
+ ["-gen-op-interface-defs"],
+ "include/mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.cpp.inc",
+ ),
+ ],
+ tblgen = ":mlir-tblgen",
+ td_file = "include/mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.td",
+ deps = [
+ ":BufferizableOpInterfaceTdFiles",
+ ],
+)
+
+cc_library(
+ name = "BufferizableOpInterface",
+ srcs = [
+ "lib/Dialect/Linalg/Transforms/BufferizableOpInterface.cpp",
+ ],
+ hdrs = [
+ "include/mlir/Dialect/Linalg/Transforms/BufferizableOpInterface.h",
+ ],
+ includes = ["include"],
+ deps = [
+ ":BufferizableOpInterfaceIncGen",
+ ":IR",
+ ":Support",
+ "//llvm:Support",
+ ],
+)
+
td_library(
name = "LinalgDocTdFiles",
srcs = ["include/mlir/Dialect/Linalg/IR/LinalgDoc.td"],
@@ -6304,10 +6352,13 @@ gentbl_cc_library(
cc_library(
name = "LinalgTransforms",
- srcs = glob([
- "lib/Dialect/Linalg/Transforms/*.cpp",
- "lib/Dialect/Linalg/Transforms/*.h",
- ]) + [
+ srcs = glob(
+ [
+ "lib/Dialect/Linalg/Transforms/*.cpp",
+ "lib/Dialect/Linalg/Transforms/*.h",
+ ],
+ exclude = ["lib/Dialect/Linalg/Transforms/BufferizableOpInterface.cpp"],
+ ) + [
"lib/Dialect/Linalg/Analysis/DependenceAnalysis.cpp",
"lib/Dialect/Linalg/Utils/Utils.cpp",
],
@@ -6327,6 +6378,7 @@ cc_library(
":AffineUtils",
":Analysis",
":ArithmeticDialect",
+ ":BufferizableOpInterface",
":ComplexDialect",
":DialectUtils",
":IR",
More information about the Mlir-commits
mailing list