In particular for Graph Regions, the terminator needs is just a historical artifact of the generalization of MLIR from CFG region. Operations like Module don't need a terminator, and before Module migrated to be an operation with region there wasn't any needed. To validate the feature, the ModuleOp is migrated to use this trait and the ModuleTerminator operation is deleted. This patch is likely to break clients, if you're in this case: - you may iterate on a ModuleOp with `getBody()->without_terminator()`, the solution is simple: just remove the ->without_terminator! - you created a builder with `Builder::atBlockTerminator(module_body)`, just use `Builder::atBlockEnd(module_body)` instead. - you were handling ModuleTerminator: it isn't needed anymore. - for generic code, a `Block::mayNotHaveTerminator()` may be used. Differential Revision: https://reviews.llvm.org/D98468
63 lines
2.4 KiB
C++
63 lines
2.4 KiB
C++
//===- Bufferize.cpp - Bufferization for std ops --------------------------===//
|
|
//
|
|
// 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 implements bufferization of std.func's and std.call's.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "PassDetail.h"
|
|
#include "mlir/Dialect/MemRef/IR/MemRef.h"
|
|
#include "mlir/Dialect/StandardOps/IR/Ops.h"
|
|
#include "mlir/Dialect/StandardOps/Transforms/FuncConversions.h"
|
|
#include "mlir/Dialect/StandardOps/Transforms/Passes.h"
|
|
#include "mlir/Transforms/Bufferize.h"
|
|
#include "mlir/Transforms/DialectConversion.h"
|
|
|
|
using namespace mlir;
|
|
|
|
namespace {
|
|
struct FuncBufferizePass : public FuncBufferizeBase<FuncBufferizePass> {
|
|
using FuncBufferizeBase<FuncBufferizePass>::FuncBufferizeBase;
|
|
void runOnOperation() override {
|
|
auto module = getOperation();
|
|
auto *context = &getContext();
|
|
|
|
BufferizeTypeConverter typeConverter;
|
|
RewritePatternSet patterns(context);
|
|
ConversionTarget target(*context);
|
|
|
|
populateFuncOpTypeConversionPattern(patterns, typeConverter);
|
|
target.addDynamicallyLegalOp<FuncOp>([&](FuncOp op) {
|
|
return typeConverter.isSignatureLegal(op.getType()) &&
|
|
typeConverter.isLegal(&op.getBody());
|
|
});
|
|
populateCallOpTypeConversionPattern(patterns, typeConverter);
|
|
target.addDynamicallyLegalOp<CallOp>(
|
|
[&](CallOp op) { return typeConverter.isLegal(op); });
|
|
|
|
populateBranchOpInterfaceTypeConversionPattern(patterns, typeConverter);
|
|
populateReturnOpTypeConversionPattern(patterns, typeConverter);
|
|
target.addLegalOp<ModuleOp, memref::TensorLoadOp, memref::BufferCastOp>();
|
|
|
|
target.markUnknownOpDynamicallyLegal([&](Operation *op) {
|
|
return isNotBranchOpInterfaceOrReturnLikeOp(op) ||
|
|
isLegalForBranchOpInterfaceTypeConversionPattern(op,
|
|
typeConverter) ||
|
|
isLegalForReturnOpTypeConversionPattern(op, typeConverter);
|
|
});
|
|
|
|
if (failed(applyFullConversion(module, target, std::move(patterns))))
|
|
signalPassFailure();
|
|
}
|
|
};
|
|
} // namespace
|
|
|
|
std::unique_ptr<Pass> mlir::createFuncBufferizePass() {
|
|
return std::make_unique<FuncBufferizePass>();
|
|
}
|