[Mlir-commits] [mlir] [mlir] Add mlirTranslateModuleToLLVMIR to MLIC-C (PR #73117)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Nov 22 05:36:22 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir

Author: Edgar (edg-l)

<details>
<summary>Changes</summary>

Fixes #<!-- -->73008

This is my first PR to LLVM, hope everything is okay.

---
Full diff: https://github.com/llvm/llvm-project/pull/73117.diff


6 Files Affected:

- (added) mlir/include/mlir-c/Target/LLVMIR.h (+35) 
- (modified) mlir/lib/CAPI/CMakeLists.txt (+1-1) 
- (added) mlir/lib/CAPI/Target/CMakeLists.txt (+9) 
- (added) mlir/lib/CAPI/Target/LLVMIR.cpp (+34) 
- (modified) mlir/test/CAPI/CMakeLists.txt (+1) 
- (modified) mlir/test/CAPI/llvm.c (+43-1) 


``````````diff
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;
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/73117


More information about the Mlir-commits mailing list