Skip to content

[mlir][bufferization][WIP] Use BufferOriginAnalysis to fold away dealloc runtime checks #79602

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===- BufferViewFlowOpInterfaceImpl.h - Buffer View Analysis ---*- 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_ARITH_TRANSFORMS_BUFFERVIEWFLOWOPINTERFACEIMPL_H
#define MLIR_DIALECT_ARITH_TRANSFORMS_BUFFERVIEWFLOWOPINTERFACEIMPL_H

namespace mlir {
class DialectRegistry;

namespace arith {
void registerBufferViewFlowOpInterfaceExternalModels(DialectRegistry &registry);
} // namespace arith
} // namespace mlir

#endif // MLIR_DIALECT_ARITH_TRANSFORMS_BUFFERVIEWFLOWOPINTERFACEIMPL_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//===- BufferViewFlowOpInterface.h - Buffer View Flow Analysis --*- 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_BUFFERIZATION_IR_BUFFERVIEWFLOWOPINTERFACE_H_
#define MLIR_DIALECT_BUFFERIZATION_IR_BUFFERVIEWFLOWOPINTERFACE_H_

#include "mlir/IR/OpDefinition.h"
#include "mlir/Support/LLVM.h"

namespace mlir {
class ValueRange;

namespace bufferization {

using RegisterDependenciesFn = std::function<void(ValueRange, ValueRange)>;

} // namespace bufferization
} // namespace mlir

#include "mlir/Dialect/Bufferization/IR/BufferViewFlowOpInterface.h.inc"

#endif // MLIR_DIALECT_BUFFERIZATION_IR_BUFFERVIEWFLOWOPINTERFACE_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//===-- BufferViewFlowOpInterface.td - Buffer View Flow ----*- 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 BUFFER_VIEW_FLOW_OP_INTERFACE
#define BUFFER_VIEW_FLOW_OP_INTERFACE

include "mlir/IR/OpBase.td"

def BufferViewFlowOpInterface :
OpInterface<"BufferViewFlowOpInterface"> {
let description = [{
An op interface for the buffer view flow analysis. This interface describes
buffer dependencies between operands and op results/region entry block
arguments.
}];
let cppNamespace = "::mlir::bufferization";
let methods = [
InterfaceMethod<
/*desc=*/[{
Populate buffer dependencies between operands and op results/region
entry block arguments.

Implementations should register dependencies between an operand ("X")
and an op result/region entry block argument ("Y") if Y may depend
on X. Y depends on X if Y and X are the same buffer or if Y is a
subview of X.

Example:
```
%r = arith.select %c, %m1, %m2 : memref<5xf32>
```
In the above example, %0 may depend on %m1 or %m2 and a correct
interface implementation should call:
- "registerDependenciesFn(%m1, %r)".
- "registerDependenciesFn(%m2, %r)"
}],
/*retType=*/"void",
/*methodName=*/"populateDependencies",
/*args=*/(ins
"::mlir::bufferization::RegisterDependenciesFn"
:$registerDependenciesFn)
>,
InterfaceMethod<
/*desc=*/[{
Return "true" if the given value is a terminal buffer. A buffer value
is "terminal" if it cannot be traced back any further in the buffer
view flow analysis. E.g., because the value is a newly allocated
buffer or because there is not enough information available.

Implementations can assume that the given SSA value is an OpResult of
this operation or a region entry block argument of this operation.
}],
/*retType=*/"bool",
/*methodName=*/"isTerminalBuffer",
/*args=*/(ins "Value":$value),
/*methodBody=*/"",
/*defaultImplementation=*/"return false;"
>,
];
}

#endif // BUFFER_VIEW_FLOW_OP_INTERFACE
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define BUFFERIZATION_OPS

include "mlir/Dialect/Bufferization/IR/AllocationOpInterface.td"
include "mlir/Dialect/Bufferization/IR/BufferViewFlowOpInterface.td"
include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.td"
include "mlir/Dialect/Bufferization/IR/BufferizationBase.td"
include "mlir/Interfaces/DestinationStyleOpInterface.td"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ add_mlir_doc(BufferizationOps BufferizationOps Dialects/ -gen-dialect-doc)
add_mlir_interface(AllocationOpInterface)
add_mlir_interface(BufferDeallocationOpInterface)
add_mlir_interface(BufferizableOpInterface)
add_mlir_interface(BufferViewFlowOpInterface)

set(LLVM_TARGET_DEFINITIONS BufferizationEnums.td)
mlir_tablegen(BufferizationEnums.h.inc -gen-enum-decls)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class BufferViewFlowAnalysis {
///
/// Results in resolve(B) returning {B, C}
ValueSetT resolve(Value value) const;
ValueSetT resolveReverse(Value value) const;

/// Removes the given values from all alias sets.
void remove(const SetVector<Value> &aliasValues);
Expand All @@ -63,13 +64,20 @@ class BufferViewFlowAnalysis {
/// results have to be changed.
void rename(Value from, Value to);

/// Returns "true" if the given value is a terminal.
bool isTerminalBuffer(Value value) const;

private:
/// This function constructs a mapping from values to its immediate
/// dependencies.
void build(Operation *op);

/// Maps values to all immediate dependencies this value can have.
ValueMapT dependencies;
ValueMapT reverseDependencies;

/// A set of all terminal values. I.e., values where the analysis stopped.
DenseSet<Value> terminals;
};

} // namespace mlir
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===- BufferViewFlowOpInterfaceImpl.h - Buffer View Analysis ---*- 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_MEMREF_TRANSFORMS_BUFFERVIEWFLOWOPINTERFACEIMPL_H
#define MLIR_DIALECT_MEMREF_TRANSFORMS_BUFFERVIEWFLOWOPINTERFACEIMPL_H

namespace mlir {
class DialectRegistry;

namespace memref {
void registerBufferViewFlowOpInterfaceExternalModels(DialectRegistry &registry);
} // namespace memref
} // namespace mlir

#endif // MLIR_DIALECT_MEMREF_TRANSFORMS_BUFFERVIEWFLOWOPINTERFACEIMPL_H
4 changes: 4 additions & 0 deletions mlir/include/mlir/InitAllDialects.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Arith/IR/ValueBoundsOpInterfaceImpl.h"
#include "mlir/Dialect/Arith/Transforms/BufferDeallocationOpInterfaceImpl.h"
#include "mlir/Dialect/Arith/Transforms/BufferViewFlowOpInterfaceImpl.h"
#include "mlir/Dialect/Arith/Transforms/BufferizableOpInterfaceImpl.h"
#include "mlir/Dialect/ArmNeon/ArmNeonDialect.h"
#include "mlir/Dialect/ArmSME/IR/ArmSME.h"
Expand Down Expand Up @@ -53,6 +54,7 @@
#include "mlir/Dialect/MemRef/IR/MemRefMemorySlot.h"
#include "mlir/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.h"
#include "mlir/Dialect/MemRef/Transforms/AllocationOpInterfaceImpl.h"
#include "mlir/Dialect/MemRef/Transforms/BufferViewFlowOpInterfaceImpl.h"
#include "mlir/Dialect/MemRef/Transforms/RuntimeOpVerification.h"
#include "mlir/Dialect/Mesh/IR/MeshOps.h"
#include "mlir/Dialect/NVGPU/IR/NVGPUDialect.h"
Expand Down Expand Up @@ -145,6 +147,7 @@ inline void registerAllDialects(DialectRegistry &registry) {
affine::registerValueBoundsOpInterfaceExternalModels(registry);
arith::registerBufferDeallocationOpInterfaceExternalModels(registry);
arith::registerBufferizableOpInterfaceExternalModels(registry);
arith::registerBufferViewFlowOpInterfaceExternalModels(registry);
arith::registerValueBoundsOpInterfaceExternalModels(registry);
bufferization::func_ext::registerBufferizableOpInterfaceExternalModels(
registry);
Expand All @@ -157,6 +160,7 @@ inline void registerAllDialects(DialectRegistry &registry) {
linalg::registerTilingInterfaceExternalModels(registry);
linalg::registerValueBoundsOpInterfaceExternalModels(registry);
memref::registerAllocationOpInterfaceExternalModels(registry);
memref::registerBufferViewFlowOpInterfaceExternalModels(registry);
memref::registerRuntimeVerifiableOpInterfaceExternalModels(registry);
memref::registerValueBoundsOpInterfaceExternalModels(registry);
memref::registerMemorySlotExternalModels(registry);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//===- BufferViewFlowOpInterfaceImpl.cpp - Buffer View Flow Analysis ------===//
//
// 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/Arith/Transforms/BufferViewFlowOpInterfaceImpl.h"

#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Bufferization/IR/BufferViewFlowOpInterface.h"

using namespace mlir;
using namespace mlir::bufferization;

namespace mlir {
namespace arith {
namespace {

struct SelectOpInterface
: public BufferViewFlowOpInterface::ExternalModel<SelectOpInterface,
SelectOp> {
void
populateDependencies(Operation *op,
RegisterDependenciesFn registerDependenciesFn) const {
auto selectOp = cast<SelectOp>(op);

// Either one of the true/false value may be selected at runtime.
registerDependenciesFn(selectOp.getTrueValue(), selectOp.getResult());
registerDependenciesFn(selectOp.getFalseValue(), selectOp.getResult());
}
};

} // namespace
} // namespace arith
} // namespace mlir

void arith::registerBufferViewFlowOpInterfaceExternalModels(
DialectRegistry &registry) {
registry.addExtension(+[](MLIRContext *ctx, arith::ArithDialect *dialect) {
SelectOp::attachInterface<SelectOpInterface>(*ctx);
});
}
1 change: 1 addition & 0 deletions mlir/lib/Dialect/Arith/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ add_mlir_dialect_library(MLIRArithTransforms
BufferDeallocationOpInterfaceImpl.cpp
BufferizableOpInterfaceImpl.cpp
Bufferize.cpp
BufferViewFlowOpInterfaceImpl.cpp
EmulateUnsupportedFloats.cpp
EmulateWideInt.cpp
EmulateNarrowType.cpp
Expand Down
18 changes: 18 additions & 0 deletions mlir/lib/Dialect/Bufferization/IR/BufferViewFlowOpInterface.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===- BufferViewFlowOpInterface.cpp - Buffer View Flow Analysis ----------===//
//
// 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/Bufferization/IR/BufferViewFlowOpInterface.h"
#include "mlir/Dialect/Bufferization/IR/Bufferization.h"

namespace mlir {
namespace bufferization {

#include "mlir/Dialect/Bufferization/IR/BufferViewFlowOpInterface.cpp.inc"

} // namespace bufferization
} // namespace mlir
1 change: 1 addition & 0 deletions mlir/lib/Dialect/Bufferization/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ add_mlir_dialect_library(MLIRBufferizationDialect
BufferDeallocationOpInterface.cpp
BufferizationOps.cpp
BufferizationDialect.cpp
BufferViewFlowOpInterface.cpp
UnstructuredControlFlow.cpp

ADDITIONAL_HEADER_DIRS
Expand Down
Loading