Skip to content
Open
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
97 changes: 97 additions & 0 deletions mlir/test/Analysis/test-backwardslice.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// RUN: mlir-opt --allow-unregistered-dialect --transform-interpreter --split-input-file --verify-diagnostics %s | FileCheck %s

func.func @simple() {
%0 = "other"() : () -> (f32)
%1 = "root"(%0) : (f32) -> (f32)
}
// CHECK-LABEL: func @simple__backward_slice__()
// CHECK: %[[OTHER:.+]] = "other"
// CHECK: %[[ROOT:.+]] = "root"(%[[OTHER]])
// CHECK: return

module attributes {transform.with_named_sequence} {
transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {
%op = transform.structured.match ops{["root"]} in %arg0
: (!transform.any_op) -> !transform.any_op
transform.test.get_backward_slice %op : !transform.any_op
transform.yield
}
}

// -----
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have to split the input file here? If not, we can do add a TransformEachOpTrait to the transform op and have it apply to all roots one-by-one...


func.func @across_blocks() {
%0 = "other"() : () -> (f32)
cf.br ^bb1
^bb1() :
%1 = "root"(%0) : (f32) -> (f32)
}
// CHECK-LABEL: func @across_blocks__backward_slice__()
// CHECK: %[[OTHER:.+]] = "other"
// CHECK: %[[ROOT:.+]] = "root"(%[[OTHER]])
// CHECK: return

module attributes {transform.with_named_sequence} {
transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {
%op = transform.structured.match ops{["root"]} in %arg0
: (!transform.any_op) -> !transform.any_op
transform.test.get_backward_slice %op : !transform.any_op
transform.yield
}
}

// -----

func.func @large_slice() {
%0 = "not_in_slice"() : () -> (f32)
%1 = "sliced_op0"() : () -> (f32)
%2 = "sliced_op1"() : () -> (f32)
%3 = "sliced_op"(%1, %2) : (f32, f32) -> (f32)
%4 = "not_in_slice"() : () -> (f32)
%5 = "root"(%3) : (f32) -> (f32)
%6 = "not_in_slice"() : () -> (f32)
}
// CHECK-LABEL: func @large_slice__backward_slice__()
// CHECK-NOT: "not_in_slice"
// CHECK-DAG: %[[OP0:.+]] = "sliced_op0"
// CHECK-DAG: %[[OP1:.+]] = "sliced_op1"
// CHECK-NOT: "not_in_slice"
// CHECK: %[[OP2:.+]] = "sliced_op"(%[[OP0]], %[[OP1]])
// CHECK: %[[ROOT:.+]] = "root"(%[[OP2]])
// CHECK-NOT: "not_in_slice"
// CHECK: return

module attributes {transform.with_named_sequence} {
transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {
%op = transform.structured.match ops{["root"]} in %arg0
: (!transform.any_op) -> !transform.any_op
transform.test.get_backward_slice %op : !transform.any_op
transform.yield
}
}

// -----

func.func @include_uses_from_above() {
%0 = "sliced_op"() : () -> (f32)
%1 = "sliced_op" () ({
^bb0():
"yield" (%0) : (f32) -> ()
}): () -> (f32)
%2 = "root"(%1) : (f32) -> (f32)
}
// CHECK-LABEL: func @include_uses_from_above__backward_slice__()
// CHECK: %[[OP0:.+]] = "sliced_op"
// CHECK: %[[OP1:.+]] = "sliced_op"
// CHECK-NEXT: "yield"(%[[OP0]])
// CHECK: %[[ROOT:.+]] = "root"(%[[OP1]])
// CHECK: return

module attributes {transform.with_named_sequence} {
transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {
%op = transform.structured.match ops{["root"]} in %arg0
: (!transform.any_op) -> !transform.any_op
transform.test.get_backward_slice %op : !transform.any_op
transform.yield
}
}
61 changes: 0 additions & 61 deletions mlir/test/IR/slice.mlir

This file was deleted.

36 changes: 0 additions & 36 deletions mlir/test/IR/slice_multiple_blocks.mlir

This file was deleted.

9 changes: 9 additions & 0 deletions mlir/test/lib/Analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
set(LLVM_TARGET_DEFINITIONS TestAnalysisOps.td)
mlir_tablegen(TestAnalysisOps.h.inc -gen-op-decls)
mlir_tablegen(TestAnalysisOps.cpp.inc -gen-op-defs)
add_public_tablegen_target(MLIRTestAnalysisOpsIncGen)

# Exclude tests from libMLIR.so
add_mlir_library(MLIRTestAnalysis
TestAliasAnalysis.cpp
Expand All @@ -11,6 +16,7 @@ add_mlir_library(MLIRTestAnalysis
TestMemRefStrideCalculation.cpp
TestSlice.cpp
TestTopologicalSort.cpp
TestAnalysisOps.cpp

DataFlow/TestDeadCodeAnalysis.cpp
DataFlow/TestDenseBackwardDataFlowAnalysis.cpp
Expand All @@ -20,6 +26,9 @@ add_mlir_library(MLIRTestAnalysis

EXCLUDE_FROM_LIBMLIR

DEPENDS
MLIRTestAnalysisOpsIncGen

LINK_LIBS PUBLIC
MLIRTestDialect
)
Expand Down
98 changes: 98 additions & 0 deletions mlir/test/lib/Analysis/TestAnalysisOps.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//===- TestAnalysisOps.cpp - Test Transforms ----------------------------===//
//
// 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 defines transform dialect operations for testing MLIR
// analyses.
//
//===----------------------------------------------------------------------===//

#include "mlir/Analysis/SliceAnalysis.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/Transform/IR/TransformDialect.h"
#include "mlir/Dialect/Transform/Interfaces/TransformInterfaces.h"
#include "mlir/IR/IRMapping.h"
#include "mlir/IR/OpDefinition.h"

#define GET_OP_CLASSES
#include "TestAnalysisOps.h.inc"

using namespace mlir;
using namespace transform;

#define GET_OP_CLASSES
#include "TestAnalysisOps.cpp.inc"

/// 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,
const BackwardSliceOptions &options) {
func::FuncOp parentFuncOp = op->getParentOfType<func::FuncOp>();
if (!parentFuncOp)
return failure();
OpBuilder builder(parentFuncOp);
Location loc = op->getLoc();
std::string clonedFuncOpName = parentFuncOp.getName().str() + suffix.str();
func::FuncOp clonedFuncOp = func::FuncOp::create(
builder, 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()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I think .map can take two lists of values.

SetVector<Operation *> slice;
LogicalResult result = getBackwardSlice(op, &slice, options);
assert(result.succeeded() && "expected a backward slice");
(void)result;
for (Operation *slicedOp : slice)
builder.clone(*slicedOp, mapper);
func::ReturnOp::create(builder, loc);
return success();
}

DiagnosedSilenceableFailure
transform::TestGetBackwardSlice::apply(TransformRewriter &rewriter,
TransformResults &transformResults,
TransformState &state) {
Operation *op = *state.getPayloadOps(getOp()).begin();
StringRef suffix = "__backward_slice__";
BackwardSliceOptions options;
options.omitBlockArguments = true;
// TODO: Make this default.
options.omitUsesFromAbove = false;
options.inclusive = true;
if (failed(createBackwardSliceFunction(op, suffix, options)))
return DiagnosedSilenceableFailure::definiteFailure();
return DiagnosedSilenceableFailure::success();
}

//===----------------------------------------------------------------------===//
// Extension
//===----------------------------------------------------------------------===//
namespace {

class TestAnalysisDialectExtension
: public transform::TransformDialectExtension<
TestAnalysisDialectExtension> {
public:
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestAnalysisDialectExtension)
using Base::Base;

void init() {
registerTransformOps<
#define GET_OP_LIST
#include "TestAnalysisOps.cpp.inc"
>();
}
};
} // namespace

namespace test {
void registerTestAnalysisTransformDialectExtension(DialectRegistry &registry) {
registry.addExtensions<TestAnalysisDialectExtension>();
}
} // namespace test
39 changes: 39 additions & 0 deletions mlir/test/lib/Analysis/TestAnalysisOps.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//===- TestAnalysisOps.td ---------------------------------*- 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 TEST_ANALYSIS_OPS
#define TEST_ANALYSIS_OPS

include "mlir/Dialect/Transform/IR/TransformDialect.td"
include "mlir/Dialect/Transform/Interfaces/TransformInterfaces.td"
include "mlir/Dialect/Transform/IR/TransformTypes.td"
include "mlir/Interfaces/SideEffectInterfaces.td"
include "mlir/IR/OpBase.td"

/// Transform dialect operations for testing analysis in MLIR

def TestGetBackwardSlice :
Op<Transform_Dialect, "test.get_backward_slice",
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
DeclareOpInterfaceMethods<TransformOpInterface>,
ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Test `getBackwardSlice` by cloning the slice starting at `op`.
}];

let arguments =
(ins TransformHandleTypeInterface:$op);

let results = (outs);

let assemblyFormat = [{
$op attr-dict `:` type($op)
}];
}

#endif // TEST_ANALYSIS_OPS
1 change: 1 addition & 0 deletions mlir/test/lib/Analysis/lit.local.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
config.suffixes.remove(".td")
1 change: 0 additions & 1 deletion mlir/test/lib/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ add_mlir_library(MLIRTestIR
TestPrintInvalid.cpp
TestPrintNesting.cpp
TestSideEffects.cpp
TestSlicing.cpp
TestSymbolUses.cpp
TestRegions.cpp
TestTypes.cpp
Expand Down
Loading