Files
clang-p2996/mlir/test/lib/IR/TestSlicing.cpp
Mahesh Ravishankar 641b12e94b [mlir][SliceAnalysis] Add an options object to forward and backward slice.
Add an options object to allow control of the slice computation (for
both forward and backward slice). This makes the ABI stable, and also
allows avoiding an assert that makes the slice analysis unusable for
operations with multiple blocks.

Reviewed By: hanchung, nicolasvasilache

Differential Revision: https://reviews.llvm.org/D151520
2023-06-08 18:40:20 +00:00

96 lines
3.5 KiB
C++

//===- TestSlicing.cpp - Testing slice functionality ----------------------===//
//
// 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 a simple testing pass for slicing.
//
//===----------------------------------------------------------------------===//
#include "mlir/Analysis/SliceAnalysis.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/Linalg/IR/Linalg.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/IRMapping.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Support/LLVM.h"
using namespace mlir;
/// Create a function with the same signature as the parent function of `op`
/// with name being the function name and a `suffix`.
static LogicalResult createBackwardSliceFunction(Operation *op,
StringRef suffix,
bool omitBlockArguments) {
func::FuncOp parentFuncOp = op->getParentOfType<func::FuncOp>();
OpBuilder builder(parentFuncOp);
Location loc = op->getLoc();
std::string clonedFuncOpName = parentFuncOp.getName().str() + suffix.str();
func::FuncOp clonedFuncOp = builder.create<func::FuncOp>(
loc, clonedFuncOpName, parentFuncOp.getFunctionType());
IRMapping mapper;
builder.setInsertionPointToEnd(clonedFuncOp.addEntryBlock());
for (const auto &arg : enumerate(parentFuncOp.getArguments()))
mapper.map(arg.value(), clonedFuncOp.getArgument(arg.index()));
SetVector<Operation *> slice;
BackwardSliceOptions options;
options.omitBlockArguments = omitBlockArguments;
getBackwardSlice(op, &slice, options);
for (Operation *slicedOp : slice)
builder.clone(*slicedOp, mapper);
builder.create<func::ReturnOp>(loc);
return success();
}
namespace {
/// Pass to test slice generated from slice analysis.
struct SliceAnalysisTestPass
: public PassWrapper<SliceAnalysisTestPass, OperationPass<ModuleOp>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(SliceAnalysisTestPass)
StringRef getArgument() const final { return "slice-analysis-test"; }
StringRef getDescription() const final {
return "Test Slice analysis functionality.";
}
Option<bool> omitBlockArguments{
*this, "omit-block-arguments",
llvm::cl::desc("Test Slice analysis with multiple blocks but slice "
"omiting block arguments"),
llvm::cl::init(true)};
void runOnOperation() override;
SliceAnalysisTestPass() = default;
SliceAnalysisTestPass(const SliceAnalysisTestPass &) {}
};
} // namespace
void SliceAnalysisTestPass::runOnOperation() {
ModuleOp module = getOperation();
auto funcOps = module.getOps<func::FuncOp>();
unsigned opNum = 0;
for (auto funcOp : funcOps) {
// TODO: For now this is just looking for Linalg ops. It can be generalized
// to look for other ops using flags.
funcOp.walk([&](Operation *op) {
if (!isa<linalg::LinalgOp>(op))
return WalkResult::advance();
std::string append =
std::string("__backward_slice__") + std::to_string(opNum);
(void)createBackwardSliceFunction(op, append, omitBlockArguments);
opNum++;
return WalkResult::advance();
});
}
}
namespace mlir {
void registerSliceAnalysisTestPass() {
PassRegistration<SliceAnalysisTestPass>();
}
} // namespace mlir