Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mlir] Add mlirTranslateModuleToLLVMIR to MLIR-C #73117

Merged
merged 5 commits into from
Nov 23, 2023

Conversation

edg-l
Copy link
Contributor

@edg-l edg-l commented Nov 22, 2023

Fixes #73008

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

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 22, 2023

@llvm/pr-subscribers-mlir-llvm

@llvm/pr-subscribers-mlir

Author: Edgar (edg-l)

Changes

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

@edg-l edg-l changed the title [mlir] Add mlirTranslateModuleToLLVMIR to MLIC-C [mlir] Add mlirTranslateModuleToLLVMIR to MLIR-C Nov 22, 2023
@llvm llvm deleted a comment from ChillerDragon Nov 22, 2023
Copy link
Member

@ftynse ftynse left a comment

Choose a reason for hiding this comment

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

Thanks for your contribution! Please address a couple of comments.

mlir/include/mlir-c/Target/LLVMIR.h Outdated Show resolved Hide resolved
mlir/include/mlir-c/Target/LLVMIR.h Outdated Show resolved Hide resolved
mlir/lib/CAPI/Target/LLVMIR.cpp Outdated Show resolved Hide resolved
mlir/lib/CAPI/Target/LLVMIR.cpp Outdated Show resolved Hide resolved
mlir/lib/CAPI/Target/LLVMIR.cpp Outdated Show resolved Hide resolved
mlir/test/CAPI/llvm.c Outdated Show resolved Hide resolved
mlir/test/CAPI/llvm.c Outdated Show resolved Hide resolved
mlir/test/CAPI/llvm.c Outdated Show resolved Hide resolved
mlir/lib/CAPI/Target/CMakeLists.txt Show resolved Hide resolved
@edg-l
Copy link
Contributor Author

edg-l commented Nov 22, 2023

Fixed everything (i think)

Copy link
Member

@ftynse ftynse left a comment

Choose a reason for hiding this comment

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

LGTM, please allow some time for other folks to chime and let me know if you need help merging this.

mlir/lib/CAPI/Target/LLVMIR.cpp Outdated Show resolved Hide resolved
@joker-eph
Copy link
Collaborator

Thanks for the patch :)

@edg-l
Copy link
Contributor Author

edg-l commented Nov 23, 2023

Updated the PR removing the llvmModuleName argument as discussed (#73117 (comment))

@ftynse ftynse merged commit c43c885 into llvm:main Nov 23, 2023
3 checks passed
@edg-l edg-l deleted the add_mlir_translate branch November 23, 2023 11:51
@vitalybuka
Copy link
Collaborator

This bot is still broken https://lab.llvm.org/buildbot/#/builders/5/builds/38560

@vitalybuka
Copy link
Collaborator

Reverted @edg-l

@joker-eph
Copy link
Collaborator

Thanks for doing the maintenance here @vitalybuka , feel free to revert faster (immediately) as needed to keep the buildbots green!

@edg-l
Copy link
Contributor Author

edg-l commented Nov 28, 2023

Did something go wrong?

@joker-eph
Copy link
Collaborator

@edg-l : have you checked the link above? https://lab.llvm.org/buildbot/#/builders/5/builds/38560

******************** TEST 'MLIR :: CAPI/translation.c' FAILED ********************
Exit Code: 1
Command Output (stdout):
--
# RUN: at line 10
/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/mlir-capi-translation-test 2>&1 | /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/FileCheck /b/sanitizer-x86_64-linux-fast/build/llvm-project/mlir/test/CAPI/translation.c
# executed command: /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/mlir-capi-translation-test
# note: command had no output on stdout or stderr
# error: command failed with exit status: 1
# executed command: /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/FileCheck /b/sanitizer-x86_64-linux-fast/build/llvm-project/mlir/test/CAPI/translation.c

It's a bit sad that the sanitizer don't provide any output here... :(

I also don't quite understand why there is a build failure but we still ran the tests?

/b/sanitizer-x86_64-linux-fast/build/llvm-project/mlir/lib/ExecutionEngine/ArmSMEStubs.cpp:36:6: error: expected ')'
   36 | bool MLIR_ARMSMEABISTUBS_EXPORTED __aarch64_sme_accessible() {
      |      ^
/b/sanitizer-x86_64-linux-fast/build/llvm-project/mlir/lib/ExecutionEngine/ArmSMEStubs.cpp:24:76: note: expanded from macro 'MLIR_ARMSMEABISTUBS_EXPORTED'
   24 | #define MLIR_ARMSMEABISTUBS_EXPORTED __attribute__((visibility("default")) LLVM_ATTRIBUTE_WEAK
      |                                                                            ^
/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/include/llvm/Support/Compiler.h:190:29: note: expanded from macro 'LLVM_ATTRIBUTE_WEAK'
  190 | #define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__))
      |                             ^
/b/sanitizer-x86_64-linux-fast/build/llvm-project/mlir/lib/ExecutionEngine/ArmSMEStubs.cpp:46:1: error: unknown type name 'sme_state'
   46 | sme_state MLIR_ARMSMEABISTUBS_EXPORTED __arm_sme_state() {
      | ^
/b/sanitizer-x86_64-linux-fast/build/llvm-project/mlir/lib/ExecutionEngine/ArmSMEStubs.cpp:46:11: error: expected ')'
   46 | sme_state MLIR_ARMSMEABISTUBS_EXPORTED __arm_sme_state() {
      |           ^
/b/sanitizer-x86_64-linux-fast/build/llvm-project/mlir/lib/ExecutionEngine/ArmSMEStubs.cpp:24:76: note: expanded from macro 'MLIR_ARMSMEABISTUBS_EXPORTED'
   24 | #define MLIR_ARMSMEABISTUBS_EXPORTED __attribute__((visibility("default")) LLVM_ATTRIBUTE_WEAK
      |                                                                            ^
/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/include/llvm/Support/Compiler.h:190:29: note: expanded from macro 'LLVM_ATTRIBUTE_WEAK'
  190 | #define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__))
      |                             ^
/b/sanitizer-x86_64-linux-fast/build/llvm-project/mlir/lib/ExecutionEngine/ArmSMEStubs.cpp:62:1: error: expected unqualified-id
   62 | }

@edg-l edg-l restored the add_mlir_translate branch November 28, 2023 07:34
@edg-l
Copy link
Contributor Author

edg-l commented Nov 28, 2023

Opened #73627

joker-eph pushed a commit that referenced this pull request Nov 29, 2023
The test was checking something unrelated to what it controlled so it
failed after that part changed, i removed that.

See #73117
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[MLIR] Feature request: translate from LLVM Dialect to LLVMIR using the C API
6 participants