diff --git a/mlir/include/mlir/Dialect/ControlFlow/CMakeLists.txt b/mlir/include/mlir/Dialect/ControlFlow/CMakeLists.txt --- a/mlir/include/mlir/Dialect/ControlFlow/CMakeLists.txt +++ b/mlir/include/mlir/Dialect/ControlFlow/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(IR) +add_subdirectory(TransformOps) diff --git a/mlir/include/mlir/Dialect/ControlFlow/TransformOps/CMakeLists.txt b/mlir/include/mlir/Dialect/ControlFlow/TransformOps/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/mlir/include/mlir/Dialect/ControlFlow/TransformOps/CMakeLists.txt @@ -0,0 +1,6 @@ +set(LLVM_TARGET_DEFINITIONS ControlFlowTransformOps.td) +mlir_tablegen(ControlFlowTransformOps.h.inc -gen-op-decls) +mlir_tablegen(ControlFlowTransformOps.cpp.inc -gen-op-defs) +add_public_tablegen_target(MLIRControlFlowTransformOpsIncGen) + +add_mlir_doc(ControlFlowTransformOps ControlFlowTransformOps Dialects/ -gen-op-doc) diff --git a/mlir/include/mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.h b/mlir/include/mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.h new file mode 100644 --- /dev/null +++ b/mlir/include/mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.h @@ -0,0 +1,27 @@ +//===- ControlFlowTransformOps.h - CF transformation ops --------*- 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_CONTROLFLOW_TRANSFORMOPS_CONTROLFLOWTRANSFORMOPS_H +#define MLIR_DIALECT_CONTROLFLOW_TRANSFORMOPS_CONTROLFLOWTRANSFORMOPS_H + +#include "mlir/Bytecode/BytecodeOpInterface.h" +#include "mlir/Dialect/Transform/IR/TransformInterfaces.h" +#include "mlir/IR/OpImplementation.h" + +#define GET_OP_CLASSES +#include "mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.h.inc" + +namespace mlir { +class DialectRegistry; + +namespace cf { +void registerTransformDialectExtension(DialectRegistry ®istry); +} // namespace cf +} // namespace mlir + +#endif // MLIR_DIALECT_CONTROLFLOW_TRANSFORMOPS_CONTROLFLOWTRANSFORMOPS_H diff --git a/mlir/include/mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.td b/mlir/include/mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.td new file mode 100644 --- /dev/null +++ b/mlir/include/mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.td @@ -0,0 +1,29 @@ +//===- ControlFlowTransformOps.td - CF transformation ops -*- 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 CONTROLFLOW_TRANSFORM_OPS +#define CONTROLFLOW_TRANSFORM_OPS + +include "mlir/Dialect/Transform/IR/TransformDialect.td" +include "mlir/Dialect/Transform/IR/TransformInterfaces.td" +include "mlir/Dialect/Transform/IR/TransformTypes.td" +include "mlir/IR/OpBase.td" + +def ApplyControlFlowToLLVMConversionPatternsOp : Op]> { + let description = [{ + Collects patterns that convert arith dialect ops to LLVM dialect ops. These + patterns require an "LLVMTypeConverter". + }]; + + let assemblyFormat = "attr-dict"; +} + +#endif // CONTROLFLOW_TRANSFORM_OPS diff --git a/mlir/include/mlir/InitAllDialects.h b/mlir/include/mlir/InitAllDialects.h --- a/mlir/include/mlir/InitAllDialects.h +++ b/mlir/include/mlir/InitAllDialects.h @@ -32,6 +32,7 @@ #include "mlir/Dialect/Bufferization/Transforms/FuncBufferizableOpInterfaceImpl.h" #include "mlir/Dialect/Complex/IR/Complex.h" #include "mlir/Dialect/ControlFlow/IR/ControlFlow.h" +#include "mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.h" #include "mlir/Dialect/DLTI/DLTI.h" #include "mlir/Dialect/EmitC/IR/EmitC.h" #include "mlir/Dialect/Func/IR/FuncOps.h" @@ -139,6 +140,7 @@ arith::registerTransformDialectExtension(registry); affine::registerTransformDialectExtension(registry); bufferization::registerTransformDialectExtension(registry); + cf::registerTransformDialectExtension(registry); gpu::registerTransformDialectExtension(registry); linalg::registerTransformDialectExtension(registry); memref::registerTransformDialectExtension(registry); diff --git a/mlir/lib/Dialect/ControlFlow/CMakeLists.txt b/mlir/lib/Dialect/ControlFlow/CMakeLists.txt --- a/mlir/lib/Dialect/ControlFlow/CMakeLists.txt +++ b/mlir/lib/Dialect/ControlFlow/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(IR) +add_subdirectory(TransformOps) diff --git a/mlir/lib/Dialect/ControlFlow/TransformOps/CMakeLists.txt b/mlir/lib/Dialect/ControlFlow/TransformOps/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/mlir/lib/Dialect/ControlFlow/TransformOps/CMakeLists.txt @@ -0,0 +1,17 @@ +add_mlir_dialect_library(MLIRControlFlowTransformOps + ArithTransformOps.cpp + + ADDITIONAL_HEADER_DIRS + ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/ControlFlow/TransformOps + + DEPENDS + MLIRControlFlowTransformOpsIncGen + + LINK_LIBS PUBLIC + MLIRControlFlowDialect + MLIRControlFlowToLLVM + MLIRIR + MLIRLLVMCommonConversion + MLIRLLVMDialect + MLIRTransformDialect +) diff --git a/mlir/lib/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.cpp b/mlir/lib/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.cpp new file mode 100644 --- /dev/null +++ b/mlir/lib/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.cpp @@ -0,0 +1,66 @@ +//===- ControlFlowTransformOps.cpp - Implementation of CF transform 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 +// +//===----------------------------------------------------------------------===// + +#include "mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.h" + +#include "mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h" +#include "mlir/Conversion/LLVMCommon/TypeConverter.h" +#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h" +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "mlir/Dialect/Transform/IR/TransformDialect.h" +#include "mlir/Dialect/Transform/IR/TransformInterfaces.h" +#include "mlir/Dialect/Transform/IR/TransformOps.h" + +using namespace mlir; + +//===----------------------------------------------------------------------===// +// Apply...ConversionPatternsOp +//===----------------------------------------------------------------------===// + +void transform::ApplyControlFlowToLLVMConversionPatternsOp::populatePatterns( + TypeConverter &typeConverter, RewritePatternSet &patterns) { + cf::populateControlFlowToLLVMConversionPatterns( + static_cast(typeConverter), patterns); +} + +LogicalResult +transform::ApplyControlFlowToLLVMConversionPatternsOp::verifyTypeConverter( + transform::TypeConverterBuilderOpInterface builder) { + if (builder.getTypeConverterType() != "LLVMTypeConverter") + return emitOpError("expected LLVMTypeConverter"); + return success(); +} + +//===----------------------------------------------------------------------===// +// Transform op registration +//===----------------------------------------------------------------------===// + +namespace { +class ControlFlowTransformDialectExtension + : public transform::TransformDialectExtension< + ControlFlowTransformDialectExtension> { +public: + using Base::Base; + + void init() { + declareGeneratedDialect(); + + registerTransformOps< +#define GET_OP_LIST +#include "mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.cpp.inc" + >(); + } +}; +} // namespace + +#define GET_OP_CLASSES +#include "mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.cpp.inc" + +void mlir::cf::registerTransformDialectExtension(DialectRegistry ®istry) { + registry.addExtensions(); +} diff --git a/mlir/test/Dialect/ControlFlow/transform-op-cf-to-llvm.mlir b/mlir/test/Dialect/ControlFlow/transform-op-cf-to-llvm.mlir new file mode 100644 --- /dev/null +++ b/mlir/test/Dialect/ControlFlow/transform-op-cf-to-llvm.mlir @@ -0,0 +1,20 @@ +// RUN: mlir-opt %s -test-transform-dialect-interpreter -verify-diagnostics -allow-unregistered-dialect -split-input-file | FileCheck %s + +// CHECK-LABEL: func @lower_to_llvm +// CHECK-NOT: cf.assert +// CHECK: llvm.cond_br +// CHECK: llvm.call @abort +func.func @lower_to_llvm(%arg0: i1) { + cf.assert %arg0, "assertion foo" + return +} + +transform.sequence failures(propagate) { +^bb1(%arg1: !transform.any_op): + %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op + transform.apply_conversion_patterns to %0 { + transform.apply_conversion_patterns.cf.cf_to_llvm + } with type_converter { + transform.apply_conversion_patterns.memref.memref_to_llvm_type_converter + } {legal_dialects = ["func", "llvm"]} : !transform.any_op +} diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel @@ -3950,6 +3950,57 @@ ], ) +td_library( + name = "ControlFlowTransformOpsTdFiles", + srcs = [ + "include/mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.td", + ], + includes = ["include"], + deps = [ + ":TransformDialectTdFiles", + ], +) + +gentbl_cc_library( + name = "ControlFlowTransformOpsIncGen", + strip_include_prefix = "include", + tbl_outs = [ + ( + ["-gen-op-decls"], + "include/mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.h.inc", + ), + ( + ["-gen-op-defs"], + "include/mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.cpp.inc", + ), + ], + tblgen = ":mlir-tblgen", + td_file = "include/mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.td", + deps = [ + ":ControlFlowTransformOpsTdFiles", + ], +) + +cc_library( + name = "ControlFlowTransformOps", + srcs = [ + "lib/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.cpp", + ], + hdrs = [ + "include/mlir/Dialect/ControlFlow/TransformOps/ControlFlowTransformOps.h", + ], + includes = ["include"], + deps = [ + ":ControlFlowDialect", + ":ControlFlowToLLVM", + ":ControlFlowTransformOpsIncGen", + ":IR", + ":LLVMCommonConversion", + ":LLVMDialect", + ":TransformDialect", + ], +) + cc_library( name = "FuncDialect", srcs = glob( @@ -7926,6 +7977,7 @@ ":ComplexToLibm", ":ComplexToSPIRV", ":ControlFlowDialect", + ":ControlFlowTransformOps", ":ConversionPasses", ":DLTIDialect", ":EmitCDialect",