[Mlir-commits] [mlir] merge code for llvm.emit_c_interface into convertFuncOpToLLVMFuncOp (PR #92986)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed May 22 07:07:57 PDT 2024
https://github.com/fengxie updated https://github.com/llvm/llvm-project/pull/92986
>From 2287e3622aa8971161e1d94453467fa15afd54af Mon Sep 17 00:00:00 2001
From: Fung Xie <ftse at nvidia.com>
Date: Wed, 22 May 2024 10:59:37 +0800
Subject: [PATCH 1/5] merge code for llvm.emit_c_interface into
convertFuncOpToLLVMFuncOp
---
mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp | 40 ++++++------
.../test/Transforms/test-convert-func-op.mlir | 12 ++++
.../lib/Conversion/FuncToLLVM/CMakeLists.txt | 1 +
.../FuncToLLVM/TestConvertFuncOp.cpp | 62 +++++++++++++++++++
mlir/tools/mlir-opt/mlir-opt.cpp | 2 +
5 files changed, 97 insertions(+), 20 deletions(-)
create mode 100644 mlir/test/Transforms/test-convert-func-op.mlir
create mode 100644 mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp
diff --git a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
index 53b44aa3241bb..202bbd6fd17ab 100644
--- a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
+++ b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
@@ -449,6 +449,26 @@ mlir::convertFuncOpToLLVMFuncOp(FunctionOpInterface funcOp,
"region types conversion failed");
}
+ if (!shouldUseBarePtrCallConv(funcOp, &converter)) {
+ if (funcOp->getAttrOfType<UnitAttr>(
+ LLVM::LLVMDialect::getEmitCWrapperAttrName())) {
+ if (newFuncOp.isVarArg())
+ return funcOp.emitError("C interface for variadic functions is not "
+ "supported yet.");
+
+ if (newFuncOp.isExternal())
+ wrapExternalFunction(rewriter, funcOp->getLoc(), converter, funcOp,
+ newFuncOp);
+ else
+ wrapForExternalCallers(rewriter, funcOp->getLoc(), converter, funcOp,
+ newFuncOp);
+ }
+ } else {
+ modifyFuncOpToUseBarePtrCallingConv(
+ rewriter, funcOp->getLoc(), converter, newFuncOp,
+ llvm::cast<FunctionType>(funcOp.getFunctionType()).getInputs());
+ }
+
return newFuncOp;
}
@@ -484,26 +504,6 @@ struct FuncOpConversion : public FuncOpConversionBase {
if (failed(newFuncOp))
return rewriter.notifyMatchFailure(funcOp, "Could not convert funcop");
- if (!shouldUseBarePtrCallConv(funcOp, this->getTypeConverter())) {
- if (funcOp->getAttrOfType<UnitAttr>(
- LLVM::LLVMDialect::getEmitCWrapperAttrName())) {
- if (newFuncOp->isVarArg())
- return funcOp->emitError("C interface for variadic functions is not "
- "supported yet.");
-
- if (newFuncOp->isExternal())
- wrapExternalFunction(rewriter, funcOp->getLoc(), *getTypeConverter(),
- funcOp, *newFuncOp);
- else
- wrapForExternalCallers(rewriter, funcOp->getLoc(),
- *getTypeConverter(), funcOp, *newFuncOp);
- }
- } else {
- modifyFuncOpToUseBarePtrCallingConv(rewriter, funcOp->getLoc(),
- *getTypeConverter(), *newFuncOp,
- funcOp.getFunctionType().getInputs());
- }
-
rewriter.eraseOp(funcOp);
return success();
}
diff --git a/mlir/test/Transforms/test-convert-func-op.mlir b/mlir/test/Transforms/test-convert-func-op.mlir
new file mode 100644
index 0000000000000..6e96703cda578
--- /dev/null
+++ b/mlir/test/Transforms/test-convert-func-op.mlir
@@ -0,0 +1,12 @@
+// RUN: mlir-opt %s -test-convert-func-op | FileCheck %s
+
+// CHECK-LABEL: llvm.func @add
+func.func @add(%arg0: i32, %arg1: i32) -> i32 attributes { llvm.emit_c_interface } {
+ %res = arith.addi %arg0, %arg1 : i32
+ return %res : i32
+}
+// CHECK-LABEL: llvm.func @_mlir_ciface_add
+// CHECK-SAME: [[ARG0:%[a-zA-Z0-9_]+]]: i32
+// CHECK-SAME: [[ARG1:%[a-zA-Z0-9_]+]]: i32
+// CHECK-NEXT: [[RES:%.*]] = llvm.call @add([[ARG0]], [[ARG1]])
+// CHECK-NEXT: llvm.return [[RES]]
diff --git a/mlir/test/lib/Conversion/FuncToLLVM/CMakeLists.txt b/mlir/test/lib/Conversion/FuncToLLVM/CMakeLists.txt
index 45ba62d839d36..d3dbc94a99bc7 100644
--- a/mlir/test/lib/Conversion/FuncToLLVM/CMakeLists.txt
+++ b/mlir/test/lib/Conversion/FuncToLLVM/CMakeLists.txt
@@ -1,6 +1,7 @@
# Exclude tests from libMLIR.so
add_mlir_library(MLIRTestFuncToLLVM
TestConvertCallOp.cpp
+ TestConvertFuncOp.cpp
EXCLUDE_FROM_LIBMLIR
diff --git a/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp b/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp
new file mode 100644
index 0000000000000..a801cf6528621
--- /dev/null
+++ b/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp
@@ -0,0 +1,62 @@
+//===- TestConvertCallOp.cpp - Test LLVM Conversion of Func CallOp --------===//
+//
+// 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 "TestDialect.h"
+#include "TestOps.h"
+#include "TestTypes.h"
+#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h"
+#include "mlir/Conversion/LLVMCommon/Pattern.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Pass/Pass.h"
+
+using namespace mlir;
+
+namespace {
+
+struct TestConvertFuncOp
+ : public PassWrapper<TestConvertFuncOp, OperationPass<ModuleOp>> {
+ MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestConvertFuncOp)
+
+ void getDependentDialects(DialectRegistry ®istry) const final {
+ registry.insert<LLVM::LLVMDialect>();
+ }
+ [[nodiscard]] StringRef getArgument() const final { return "test-convert-func-op"; }
+ [[nodiscard]] StringRef getDescription() const final {
+ return "Tests conversion of `func.func` to `llvm.func` for different attributes"
+ ;
+ }
+
+ void runOnOperation() override {
+ ModuleOp m = getOperation();
+
+ LowerToLLVMOptions options(m.getContext());
+
+ // Populate type conversions.
+ LLVMTypeConverter typeConverter(m.getContext(), options);
+
+ // Populate patterns.
+ RewritePatternSet patterns(m.getContext());
+ populateFuncToLLVMConversionPatterns(typeConverter, patterns);
+
+ // Set target.
+ ConversionTarget target(getContext());
+ target.addLegalDialect<LLVM::LLVMDialect>();
+ target.addIllegalDialect<func::FuncDialect>();
+
+ if (failed(applyPartialConversion(m, target, std::move(patterns))))
+ signalPassFailure();
+ }
+};
+
+} // namespace
+
+
+namespace mlir::test {
+void registerConvertFuncOpPass() { PassRegistration<TestConvertFuncOp>(); }
+} // namespace mlir::test
diff --git a/mlir/tools/mlir-opt/mlir-opt.cpp b/mlir/tools/mlir-opt/mlir-opt.cpp
index 1dfc5d178b614..0e8b161d51345 100644
--- a/mlir/tools/mlir-opt/mlir-opt.cpp
+++ b/mlir/tools/mlir-opt/mlir-opt.cpp
@@ -71,6 +71,7 @@ namespace test {
void registerTestCompositePass();
void registerCommutativityUtils();
void registerConvertCallOpPass();
+void registerConvertFuncOpPass();
void registerInliner();
void registerMemRefBoundCheck();
void registerPatternsTestPass();
@@ -199,6 +200,7 @@ void registerTestPasses() {
mlir::test::registerTestCompositePass();
mlir::test::registerCommutativityUtils();
mlir::test::registerConvertCallOpPass();
+ mlir::test::registerConvertFuncOpPass();
mlir::test::registerInliner();
mlir::test::registerMemRefBoundCheck();
mlir::test::registerPatternsTestPass();
>From 319ef33ca5dcd26e77ca479b622e81fc5db6effb Mon Sep 17 00:00:00 2001
From: Fung Xie <ftse at nvidia.com>
Date: Wed, 22 May 2024 11:08:01 +0800
Subject: [PATCH 2/5] fixed comments and remove un-used headers
---
.../Conversion/FuncToLLVM/TestConvertFuncOp.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp b/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp
index a801cf6528621..87fbf2dd15917 100644
--- a/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp
+++ b/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp
@@ -1,4 +1,4 @@
-//===- TestConvertCallOp.cpp - Test LLVM Conversion of Func CallOp --------===//
+//===- TestConvertFuncOp.cpp - Test LLVM Conversion of Func FuncOp --------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,8 +7,7 @@
//===----------------------------------------------------------------------===//
#include "TestDialect.h"
-#include "TestOps.h"
-#include "TestTypes.h"
+
#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h"
#include "mlir/Conversion/LLVMCommon/Pattern.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
@@ -26,10 +25,12 @@ struct TestConvertFuncOp
void getDependentDialects(DialectRegistry ®istry) const final {
registry.insert<LLVM::LLVMDialect>();
}
- [[nodiscard]] StringRef getArgument() const final { return "test-convert-func-op"; }
+ [[nodiscard]] StringRef getArgument() const final {
+ return "test-convert-func-op";
+ }
[[nodiscard]] StringRef getDescription() const final {
- return "Tests conversion of `func.func` to `llvm.func` for different attributes"
- ;
+ return "Tests conversion of `func.func` to `llvm.func` for different "
+ "attributes";
}
void runOnOperation() override {
@@ -56,7 +57,6 @@ struct TestConvertFuncOp
} // namespace
-
namespace mlir::test {
void registerConvertFuncOpPass() { PassRegistration<TestConvertFuncOp>(); }
} // namespace mlir::test
>From 0849489f44d2ba587b54fca2b363e13b7a5a72cb Mon Sep 17 00:00:00 2001
From: Fung Xie <ftse at nvidia.com>
Date: Wed, 22 May 2024 12:51:59 +0800
Subject: [PATCH 3/5] updated test to only test mlir::convertFuncOpToLLVMFuncOp
and remove FuncOpConversionBase
---
.../Conversion/FuncToLLVM/ConvertFuncToLLVM.h | 1 +
mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp | 24 +++-------
.../FuncToLLVM/TestConvertFuncOp.cpp | 45 ++++++++++++++-----
3 files changed, 39 insertions(+), 31 deletions(-)
diff --git a/mlir/include/mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h b/mlir/include/mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h
index 107718eeba873..6b56ed5f19077 100644
--- a/mlir/include/mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h
+++ b/mlir/include/mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h
@@ -14,6 +14,7 @@
#ifndef MLIR_CONVERSION_FUNCTOLLVM_CONVERTFUNCTOLLVM_H
#define MLIR_CONVERSION_FUNCTOLLVM_CONVERTFUNCTOLLVM_H
+#include "mlir/IR/PatternMatch.h"
#include "mlir/Interfaces/FunctionInterfaces.h"
#include "mlir/Support/LogicalResult.h"
diff --git a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
index 202bbd6fd17ab..94b7c8d4f2fdf 100644
--- a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
+++ b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
@@ -474,33 +474,19 @@ mlir::convertFuncOpToLLVMFuncOp(FunctionOpInterface funcOp,
namespace {
-struct FuncOpConversionBase : public ConvertOpToLLVMPattern<func::FuncOp> {
-protected:
- using ConvertOpToLLVMPattern<func::FuncOp>::ConvertOpToLLVMPattern;
-
- // Convert input FuncOp to LLVMFuncOp by using the LLVMTypeConverter provided
- // to this legalization pattern.
- FailureOr<LLVM::LLVMFuncOp>
- convertFuncOpToLLVMFuncOp(func::FuncOp funcOp,
- ConversionPatternRewriter &rewriter) const {
- return mlir::convertFuncOpToLLVMFuncOp(
- cast<FunctionOpInterface>(funcOp.getOperation()), rewriter,
- *getTypeConverter());
- }
-};
-
/// FuncOp legalization pattern that converts MemRef arguments to pointers to
/// MemRef descriptors (LLVM struct data types) containing all the MemRef type
/// information.
-struct FuncOpConversion : public FuncOpConversionBase {
+struct FuncOpConversion : public ConvertOpToLLVMPattern<func::FuncOp> {
FuncOpConversion(const LLVMTypeConverter &converter)
- : FuncOpConversionBase(converter) {}
+ : ConvertOpToLLVMPattern(converter) {}
LogicalResult
matchAndRewrite(func::FuncOp funcOp, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
- FailureOr<LLVM::LLVMFuncOp> newFuncOp =
- convertFuncOpToLLVMFuncOp(funcOp, rewriter);
+ FailureOr<LLVM::LLVMFuncOp> newFuncOp = mlir::convertFuncOpToLLVMFuncOp(
+ cast<FunctionOpInterface>(funcOp.getOperation()), rewriter,
+ *getTypeConverter());
if (failed(newFuncOp))
return rewriter.notifyMatchFailure(funcOp, "Could not convert funcop");
diff --git a/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp b/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp
index 87fbf2dd15917..864554cdbc744 100644
--- a/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp
+++ b/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp
@@ -9,15 +9,37 @@
#include "TestDialect.h"
#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h"
+#include "mlir/Conversion/LLVMCommon/ConversionTarget.h"
#include "mlir/Conversion/LLVMCommon/Pattern.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/IR/PatternMatch.h"
#include "mlir/Pass/Pass.h"
using namespace mlir;
namespace {
+/// Test helper Conversion Pattern to directly call `convertFuncOpToLLVMFuncOp`
+/// to verify this utility function includes all functionalities of conversion
+struct FuncOpConversion : public ConvertOpToLLVMPattern<func::FuncOp> {
+ FuncOpConversion(const LLVMTypeConverter &converter)
+ : ConvertOpToLLVMPattern(converter) {}
+
+ LogicalResult
+ matchAndRewrite(func::FuncOp funcOp, OpAdaptor adaptor,
+ ConversionPatternRewriter &rewriter) const override {
+ FailureOr<LLVM::LLVMFuncOp> newFuncOp = mlir::convertFuncOpToLLVMFuncOp(
+ cast<FunctionOpInterface>(funcOp.getOperation()), rewriter,
+ *getTypeConverter());
+ if (failed(newFuncOp))
+ return rewriter.notifyMatchFailure(funcOp, "Could not convert funcop");
+
+ rewriter.eraseOp(funcOp);
+ return success();
+ }
+};
+
struct TestConvertFuncOp
: public PassWrapper<TestConvertFuncOp, OperationPass<ModuleOp>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestConvertFuncOp)
@@ -25,32 +47,31 @@ struct TestConvertFuncOp
void getDependentDialects(DialectRegistry ®istry) const final {
registry.insert<LLVM::LLVMDialect>();
}
+
[[nodiscard]] StringRef getArgument() const final {
return "test-convert-func-op";
}
+
[[nodiscard]] StringRef getDescription() const final {
return "Tests conversion of `func.func` to `llvm.func` for different "
"attributes";
}
void runOnOperation() override {
- ModuleOp m = getOperation();
-
- LowerToLLVMOptions options(m.getContext());
+ MLIRContext *ctx = &getContext();
+ LowerToLLVMOptions options(ctx);
// Populate type conversions.
- LLVMTypeConverter typeConverter(m.getContext(), options);
+ LLVMTypeConverter typeConverter(ctx, options);
- // Populate patterns.
- RewritePatternSet patterns(m.getContext());
- populateFuncToLLVMConversionPatterns(typeConverter, patterns);
+ RewritePatternSet patterns(ctx);
+ patterns.add<FuncOpConversion>(ctx);
- // Set target.
- ConversionTarget target(getContext());
- target.addLegalDialect<LLVM::LLVMDialect>();
- target.addIllegalDialect<func::FuncDialect>();
+ populateFuncToLLVMConversionPatterns(typeConverter, patterns, nullptr);
- if (failed(applyPartialConversion(m, target, std::move(patterns))))
+ LLVMConversionTarget target(getContext());
+ if (failed(applyPartialConversion(getOperation(), target,
+ std::move(patterns))))
signalPassFailure();
}
};
>From 0ee4c5432762b40b651c85a92aeb2c54b29d98d1 Mon Sep 17 00:00:00 2001
From: Fung Xie <ftse at nvidia.com>
Date: Wed, 22 May 2024 12:56:05 +0800
Subject: [PATCH 4/5] delete unused include
---
mlir/include/mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/mlir/include/mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h b/mlir/include/mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h
index 6b56ed5f19077..107718eeba873 100644
--- a/mlir/include/mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h
+++ b/mlir/include/mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h
@@ -14,7 +14,6 @@
#ifndef MLIR_CONVERSION_FUNCTOLLVM_CONVERTFUNCTOLLVM_H
#define MLIR_CONVERSION_FUNCTOLLVM_CONVERTFUNCTOLLVM_H
-#include "mlir/IR/PatternMatch.h"
#include "mlir/Interfaces/FunctionInterfaces.h"
#include "mlir/Support/LogicalResult.h"
>From f12d1a0aa701634fb2b027a33d90752957d43199 Mon Sep 17 00:00:00 2001
From: Fung Xie <ftse at nvidia.com>
Date: Wed, 22 May 2024 22:07:41 +0800
Subject: [PATCH 5/5] remove nodiscard
---
mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp b/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp
index 864554cdbc744..d240bccf6b7b8 100644
--- a/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp
+++ b/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp
@@ -48,11 +48,9 @@ struct TestConvertFuncOp
registry.insert<LLVM::LLVMDialect>();
}
- [[nodiscard]] StringRef getArgument() const final {
- return "test-convert-func-op";
- }
+ StringRef getArgument() const final { return "test-convert-func-op"; }
- [[nodiscard]] StringRef getDescription() const final {
+ StringRef getDescription() const final {
return "Tests conversion of `func.func` to `llvm.func` for different "
"attributes";
}
More information about the Mlir-commits
mailing list