[Mlir-commits] [mlir] [mlir] Add mlirTranslateModuleToLLVMIR to MLIR-C (PR #73117)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Nov 22 07:53:16 PST 2023
https://github.com/edg-l updated https://github.com/llvm/llvm-project/pull/73117
>From ea8268a65f6ae511dd508c1b3d63da66c445b770 Mon Sep 17 00:00:00 2001
From: Edgar Luque <git at edgarluque.com>
Date: Wed, 22 Nov 2023 14:30:37 +0100
Subject: [PATCH 1/3] [mlir] Add mlirTranslateModuleToLLVMIR to MLIC-C
---
mlir/include/mlir-c/Target/LLVMIR.h | 35 +++++++++++++++++++++++
mlir/lib/CAPI/CMakeLists.txt | 2 +-
mlir/lib/CAPI/Target/CMakeLists.txt | 9 ++++++
mlir/lib/CAPI/Target/LLVMIR.cpp | 34 ++++++++++++++++++++++
mlir/test/CAPI/CMakeLists.txt | 1 +
mlir/test/CAPI/llvm.c | 44 ++++++++++++++++++++++++++++-
6 files changed, 123 insertions(+), 2 deletions(-)
create mode 100644 mlir/include/mlir-c/Target/LLVMIR.h
create mode 100644 mlir/lib/CAPI/Target/CMakeLists.txt
create mode 100644 mlir/lib/CAPI/Target/LLVMIR.cpp
diff --git a/mlir/include/mlir-c/Target/LLVMIR.h b/mlir/include/mlir-c/Target/LLVMIR.h
new file mode 100644
index 000000000000000..96070e5c8c7b033
--- /dev/null
+++ b/mlir/include/mlir-c/Target/LLVMIR.h
@@ -0,0 +1,35 @@
+//===- LLVMIR.h - C Interface for MLIR LLVMIR Target -------------------===//
+//
+// 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 header declares the C interface to target LLVMIR with MLIR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_C_TARGET_LLVMIR_H
+#define MLIR_C_TARGET_LLVMIR_H
+
+#include "mlir-c/IR.h"
+#include "mlir-c/Support.h"
+#include "llvm-c/Support.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Translate operation that satisfies LLVM dialect module requirements into an
+// LLVM IR module living in the given context. This translates operations from
+// any dilalect that has a registered implementation of
+// LLVMTranslationDialectInterface.
+MLIR_CAPI_EXPORTED LLVMModuleRef
+mlirTranslateModuleToLLVMIR(MlirOperation module, LLVMContextRef context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MLIR_C_TARGET_LLVMIR_H
diff --git a/mlir/lib/CAPI/CMakeLists.txt b/mlir/lib/CAPI/CMakeLists.txt
index 707e78ac3d1ea3c..6c438508425b7c3 100644
--- a/mlir/lib/CAPI/CMakeLists.txt
+++ b/mlir/lib/CAPI/CMakeLists.txt
@@ -14,6 +14,7 @@ add_subdirectory(Interfaces)
add_subdirectory(IR)
add_subdirectory(RegisterEverything)
add_subdirectory(Transforms)
+add_subdirectory(Target)
if(MLIR_ENABLE_EXECUTION_ENGINE)
add_subdirectory(ExecutionEngine)
@@ -36,4 +37,3 @@ if(MLIR_BUILD_MLIR_C_DYLIB)
endif()
endif()
endif()
-
diff --git a/mlir/lib/CAPI/Target/CMakeLists.txt b/mlir/lib/CAPI/Target/CMakeLists.txt
new file mode 100644
index 000000000000000..17e8c067f10908b
--- /dev/null
+++ b/mlir/lib/CAPI/Target/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_mlir_upstream_c_api_library(MLIRCAPITarget
+ LLVMIR.cpp
+
+ LINK_LIBS PUBLIC
+ MLIRToLLVMIRTranslationRegistration
+ MLIRCAPIIR
+ MLIRLLVMToLLVMIRTranslation
+ MLIRSupport
+)
diff --git a/mlir/lib/CAPI/Target/LLVMIR.cpp b/mlir/lib/CAPI/Target/LLVMIR.cpp
new file mode 100644
index 000000000000000..bd86192ba36d504
--- /dev/null
+++ b/mlir/lib/CAPI/Target/LLVMIR.cpp
@@ -0,0 +1,34 @@
+//===- LLVMIR.cpp - C Interface for MLIR LLVMIR Target -------------------===//
+//
+// 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-c/Target/LLVMIR.h"
+#include "llvm-c/Support.h"
+
+#include "llvm/IR/LLVMContext.h"
+#include <memory>
+
+#include "mlir/CAPI/IR.h"
+#include "mlir/CAPI/Support.h"
+#include "mlir/CAPI/Wrap.h"
+#include "mlir/Target/LLVMIR/ModuleTranslation.h"
+
+using namespace mlir;
+
+LLVMModuleRef mlirTranslateModuleToLLVMIR(MlirOperation module,
+ LLVMContextRef context) {
+ Operation *moduleOp = unwrap(module);
+
+ llvm::LLVMContext *ctx = reinterpret_cast<llvm::LLVMContext *>(context);
+
+ auto llvmModule = mlir::translateModuleToLLVMIR(moduleOp, *ctx);
+
+ LLVMModuleRef moduleRef = reinterpret_cast<LLVMModuleRef>(
+ const_cast<llvm::Module *>(llvmModule.release()));
+
+ return moduleRef;
+}
diff --git a/mlir/test/CAPI/CMakeLists.txt b/mlir/test/CAPI/CMakeLists.txt
index 16a3d0ed9c62fbf..b13fc613660c71d 100644
--- a/mlir/test/CAPI/CMakeLists.txt
+++ b/mlir/test/CAPI/CMakeLists.txt
@@ -43,6 +43,7 @@ _add_capi_test_executable(mlir-capi-llvm-test
MLIRCAPIIR
MLIRCAPILLVM
MLIRCAPIRegisterEverything
+ MLIRCAPITarget
)
_add_capi_test_executable(mlir-capi-pass-test
diff --git a/mlir/test/CAPI/llvm.c b/mlir/test/CAPI/llvm.c
index aaec7b113f0a976..d3b859619ab4a8d 100644
--- a/mlir/test/CAPI/llvm.c
+++ b/mlir/test/CAPI/llvm.c
@@ -9,9 +9,15 @@
// RUN: mlir-capi-llvm-test 2>&1 | FileCheck %s
-#include "mlir-c/Dialect/LLVM.h"
+#include "llvm-c/Core.h"
+#include "llvm-c/Support.h"
+#include "llvm-c/Types.h"
+
#include "mlir-c/BuiltinTypes.h"
+#include "mlir-c/Dialect/LLVM.h"
#include "mlir-c/IR.h"
+#include "mlir-c/RegisterEverything.h"
+#include "mlir-c/Target/LLVMIR.h"
#include <assert.h>
#include <math.h>
@@ -73,11 +79,47 @@ static void testTypeCreation(MlirContext ctx) {
mlirTypeEqual(i32_i64_s, i32_i64_s_ref));
}
+// CHECK-LABEL: testToLLVMIR()
+static void testToLLVMIR(MlirContext ctx) {
+ fprintf(stderr, "testToLLVMIR()\n");
+ LLVMContextRef llvmCtx = LLVMContextCreate();
+
+ const char *moduleString = "llvm.func @add(%arg0: i64, %arg1: i64) -> i64 { \
+ %0 = llvm.add %arg0, %arg1 : i64 \
+ llvm.return %0 : i64 \
+ }";
+
+ mlirRegisterAllLLVMTranslations(ctx);
+
+ MlirModule module =
+ mlirModuleCreateParse(ctx, mlirStringRefCreateFromCString(moduleString));
+
+ MlirOperation operation = mlirModuleGetOperation(module);
+
+ LLVMModuleRef llvmModule = mlirTranslateModuleToLLVMIR(operation, llvmCtx);
+
+ // clang-format off
+ // CHECK: ; ModuleID = 'LLVMDialectModule'
+ // CHECK-NEXT: source_filename = "LLVMDialectModule"
+ // CHECK: declare ptr @malloc(i64 %0)
+ // CHECK: declare void @free(ptr %0)
+ // CHECK: define i64 @add(i64 %0, i64 %1) {
+ // CHECK-NEXT: %3 = add i64 %0, %1
+ // CHECK-NEXT: ret i64 %3
+ // CHECK-NEXT: }
+ // clang-format on
+ LLVMDumpModule(llvmModule);
+
+ LLVMDisposeModule(llvmModule);
+ mlirModuleDestroy(module);
+}
+
int main(void) {
MlirContext ctx = mlirContextCreate();
mlirDialectHandleRegisterDialect(mlirGetDialectHandle__llvm__(), ctx);
mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("llvm"));
testTypeCreation(ctx);
+ testToLLVMIR(ctx);
mlirContextDestroy(ctx);
return 0;
}
>From aec146bb5669087b757772e4b21b79c7552562c3 Mon Sep 17 00:00:00 2001
From: Edgar Luque <git at edgarluque.com>
Date: Wed, 22 Nov 2023 16:41:07 +0100
Subject: [PATCH 2/3] fix suggestions
---
mlir/include/mlir-c/Target/LLVMIR.h | 20 ++++----
mlir/lib/CAPI/Target/CMakeLists.txt | 3 ++
mlir/lib/CAPI/Target/LLVMIR.cpp | 12 +++--
mlir/test/CAPI/CMakeLists.txt | 10 +++-
mlir/test/CAPI/llvm.c | 44 +-----------------
mlir/test/CAPI/translation.c | 72 +++++++++++++++++++++++++++++
6 files changed, 105 insertions(+), 56 deletions(-)
create mode 100644 mlir/test/CAPI/translation.c
diff --git a/mlir/include/mlir-c/Target/LLVMIR.h b/mlir/include/mlir-c/Target/LLVMIR.h
index 96070e5c8c7b033..978986c11d8e46d 100644
--- a/mlir/include/mlir-c/Target/LLVMIR.h
+++ b/mlir/include/mlir-c/Target/LLVMIR.h
@@ -1,6 +1,7 @@
-//===- LLVMIR.h - C Interface for MLIR LLVMIR Target -------------------===//
+//===-- LLVMIR.h - C Interface for MLIR LLVMIR Target -------------*- C -*-===//
//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// 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
//
@@ -21,12 +22,15 @@
extern "C" {
#endif
-// Translate operation that satisfies LLVM dialect module requirements into an
-// LLVM IR module living in the given context. This translates operations from
-// any dilalect that has a registered implementation of
-// LLVMTranslationDialectInterface.
-MLIR_CAPI_EXPORTED LLVMModuleRef
-mlirTranslateModuleToLLVMIR(MlirOperation module, LLVMContextRef context);
+/// Translate operation that satisfies LLVM dialect module requirements into an
+/// LLVM IR module living in the given context. This translates operations from
+/// any dilalect that has a registered implementation of
+/// LLVMTranslationDialectInterface.
+///
+/// \returns the generated LLVM IR Module from the translated MLIR module, it is
+/// owned by the caller.
+MLIR_CAPI_EXPORTED LLVMModuleRef mlirTranslateModuleToLLVMIR(
+ MlirOperation module, LLVMContextRef context, MlirStringRef llvmModuleName);
#ifdef __cplusplus
}
diff --git a/mlir/lib/CAPI/Target/CMakeLists.txt b/mlir/lib/CAPI/Target/CMakeLists.txt
index 17e8c067f10908b..ce86fd3def964cb 100644
--- a/mlir/lib/CAPI/Target/CMakeLists.txt
+++ b/mlir/lib/CAPI/Target/CMakeLists.txt
@@ -1,6 +1,9 @@
add_mlir_upstream_c_api_library(MLIRCAPITarget
LLVMIR.cpp
+ LINK_COMPONENTS
+ Core
+
LINK_LIBS PUBLIC
MLIRToLLVMIRTranslationRegistration
MLIRCAPIIR
diff --git a/mlir/lib/CAPI/Target/LLVMIR.cpp b/mlir/lib/CAPI/Target/LLVMIR.cpp
index bd86192ba36d504..a192fa14dac0768 100644
--- a/mlir/lib/CAPI/Target/LLVMIR.cpp
+++ b/mlir/lib/CAPI/Target/LLVMIR.cpp
@@ -1,6 +1,7 @@
-//===- LLVMIR.cpp - C Interface for MLIR LLVMIR Target -------------------===//
+//===-- LLVMIR.h - C Interface for MLIR LLVMIR Target ---------------------===//
//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// 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
//
@@ -20,12 +21,15 @@
using namespace mlir;
LLVMModuleRef mlirTranslateModuleToLLVMIR(MlirOperation module,
- LLVMContextRef context) {
+ LLVMContextRef context,
+ MlirStringRef llvmModuleName) {
Operation *moduleOp = unwrap(module);
llvm::LLVMContext *ctx = reinterpret_cast<llvm::LLVMContext *>(context);
- auto llvmModule = mlir::translateModuleToLLVMIR(moduleOp, *ctx);
+ std::unique_ptr<llvm::Module> llvmModule = mlir::translateModuleToLLVMIR(
+ moduleOp, *ctx,
+ llvm::StringRef(llvmModuleName.data, llvmModuleName.length));
LLVMModuleRef moduleRef = reinterpret_cast<LLVMModuleRef>(
const_cast<llvm::Module *>(llvmModule.release()));
diff --git a/mlir/test/CAPI/CMakeLists.txt b/mlir/test/CAPI/CMakeLists.txt
index b13fc613660c71d..1096a3b08066483 100644
--- a/mlir/test/CAPI/CMakeLists.txt
+++ b/mlir/test/CAPI/CMakeLists.txt
@@ -43,7 +43,6 @@ _add_capi_test_executable(mlir-capi-llvm-test
MLIRCAPIIR
MLIRCAPILLVM
MLIRCAPIRegisterEverything
- MLIRCAPITarget
)
_add_capi_test_executable(mlir-capi-pass-test
@@ -86,3 +85,12 @@ _add_capi_test_executable(mlir-capi-transform-test
MLIRCAPIRegisterEverything
MLIRCAPITransformDialect
)
+
+_add_capi_test_executable(mlir-capi-translation-test
+ translation.c
+ LINK_LIBS PRIVATE
+ MLIRCAPIIR
+ MLIRCAPILLVM
+ MLIRCAPIRegisterEverything
+ MLIRCAPITarget
+)
diff --git a/mlir/test/CAPI/llvm.c b/mlir/test/CAPI/llvm.c
index d3b859619ab4a8d..aaec7b113f0a976 100644
--- a/mlir/test/CAPI/llvm.c
+++ b/mlir/test/CAPI/llvm.c
@@ -9,15 +9,9 @@
// RUN: mlir-capi-llvm-test 2>&1 | FileCheck %s
-#include "llvm-c/Core.h"
-#include "llvm-c/Support.h"
-#include "llvm-c/Types.h"
-
-#include "mlir-c/BuiltinTypes.h"
#include "mlir-c/Dialect/LLVM.h"
+#include "mlir-c/BuiltinTypes.h"
#include "mlir-c/IR.h"
-#include "mlir-c/RegisterEverything.h"
-#include "mlir-c/Target/LLVMIR.h"
#include <assert.h>
#include <math.h>
@@ -79,47 +73,11 @@ static void testTypeCreation(MlirContext ctx) {
mlirTypeEqual(i32_i64_s, i32_i64_s_ref));
}
-// CHECK-LABEL: testToLLVMIR()
-static void testToLLVMIR(MlirContext ctx) {
- fprintf(stderr, "testToLLVMIR()\n");
- LLVMContextRef llvmCtx = LLVMContextCreate();
-
- const char *moduleString = "llvm.func @add(%arg0: i64, %arg1: i64) -> i64 { \
- %0 = llvm.add %arg0, %arg1 : i64 \
- llvm.return %0 : i64 \
- }";
-
- mlirRegisterAllLLVMTranslations(ctx);
-
- MlirModule module =
- mlirModuleCreateParse(ctx, mlirStringRefCreateFromCString(moduleString));
-
- MlirOperation operation = mlirModuleGetOperation(module);
-
- LLVMModuleRef llvmModule = mlirTranslateModuleToLLVMIR(operation, llvmCtx);
-
- // clang-format off
- // CHECK: ; ModuleID = 'LLVMDialectModule'
- // CHECK-NEXT: source_filename = "LLVMDialectModule"
- // CHECK: declare ptr @malloc(i64 %0)
- // CHECK: declare void @free(ptr %0)
- // CHECK: define i64 @add(i64 %0, i64 %1) {
- // CHECK-NEXT: %3 = add i64 %0, %1
- // CHECK-NEXT: ret i64 %3
- // CHECK-NEXT: }
- // clang-format on
- LLVMDumpModule(llvmModule);
-
- LLVMDisposeModule(llvmModule);
- mlirModuleDestroy(module);
-}
-
int main(void) {
MlirContext ctx = mlirContextCreate();
mlirDialectHandleRegisterDialect(mlirGetDialectHandle__llvm__(), ctx);
mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("llvm"));
testTypeCreation(ctx);
- testToLLVMIR(ctx);
mlirContextDestroy(ctx);
return 0;
}
diff --git a/mlir/test/CAPI/translation.c b/mlir/test/CAPI/translation.c
new file mode 100644
index 000000000000000..be3ab5582a86f74
--- /dev/null
+++ b/mlir/test/CAPI/translation.c
@@ -0,0 +1,72 @@
+//===- translation.c - Test MLIR Target translations ----------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// RUN: mlir-capi-translation-test 2>&1 | FileCheck %s
+
+#include "llvm-c/Core.h"
+#include "llvm-c/Support.h"
+#include "llvm-c/Types.h"
+
+#include "mlir-c/BuiltinTypes.h"
+#include "mlir-c/Dialect/LLVM.h"
+#include "mlir-c/IR.h"
+#include "mlir-c/RegisterEverything.h"
+#include "mlir-c/Support.h"
+#include "mlir-c/Target/LLVMIR.h"
+
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// CHECK-LABEL: testToLLVMIR()
+static void testToLLVMIR(MlirContext ctx) {
+ fprintf(stderr, "testToLLVMIR()\n");
+ LLVMContextRef llvmCtx = LLVMContextCreate();
+
+ const char *moduleString = "llvm.func @add(%arg0: i64, %arg1: i64) -> i64 { \
+ %0 = llvm.add %arg0, %arg1 : i64 \
+ llvm.return %0 : i64 \
+ }";
+
+ mlirRegisterAllLLVMTranslations(ctx);
+
+ MlirModule module =
+ mlirModuleCreateParse(ctx, mlirStringRefCreateFromCString(moduleString));
+
+ MlirOperation operation = mlirModuleGetOperation(module);
+
+ MlirStringRef name = mlirStringRefCreateFromCString("LLVMDialectModule");
+
+ LLVMModuleRef llvmModule =
+ mlirTranslateModuleToLLVMIR(operation, llvmCtx, name);
+
+ // clang-format off
+ // CHECK: declare ptr @malloc(i64 %{{.*}})
+ // CHECK: declare void @free(ptr %{{.*}})
+ // CHECK: define i64 @add(i64 %[[arg1:.*]], i64 %[[arg2:.*]]) {
+ // CHECK-NEXT: %[[arg3:.*]] = add i64 %[[arg1]], %[[arg2]]
+ // CHECK-NEXT: ret i64 %[[arg3]]
+ // CHECK-NEXT: }
+ // clang-format on
+ LLVMDumpModule(llvmModule);
+
+ LLVMDisposeModule(llvmModule);
+ mlirModuleDestroy(module);
+}
+
+int main(void) {
+ MlirContext ctx = mlirContextCreate();
+ mlirDialectHandleRegisterDialect(mlirGetDialectHandle__llvm__(), ctx);
+ mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("llvm"));
+ testToLLVMIR(ctx);
+ mlirContextDestroy(ctx);
+ return 0;
+}
>From 0f432f337f95945a6dbda37ce9e91e01767b7d9d Mon Sep 17 00:00:00 2001
From: Edgar Luque <git at edgarluque.com>
Date: Wed, 22 Nov 2023 16:53:06 +0100
Subject: [PATCH 3/3] add test to lit.cfg.py
---
mlir/test/lit.cfg.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/mlir/test/lit.cfg.py b/mlir/test/lit.cfg.py
index 87bbe51e95d4c9d..17c29445ba82b13 100644
--- a/mlir/test/lit.cfg.py
+++ b/mlir/test/lit.cfg.py
@@ -106,6 +106,7 @@ def add_runtime(name):
"mlir-capi-quant-test",
"mlir-capi-sparse-tensor-test",
"mlir-capi-transform-test",
+ "mlir-capi-translation-test",
"mlir-cpu-runner",
add_runtime("mlir_runner_utils"),
add_runtime("mlir_c_runner_utils"),
More information about the Mlir-commits
mailing list