186c8a785SMehdi Amini //===- execution_engine.c - Test for the C bindings for the MLIR JIT-------===//
286c8a785SMehdi Amini //
386c8a785SMehdi Amini // Part of the LLVM Project, under the Apache License v2.0 with LLVM
486c8a785SMehdi Amini // Exceptions.
586c8a785SMehdi Amini // See https://llvm.org/LICENSE.txt for license information.
686c8a785SMehdi Amini // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
786c8a785SMehdi Amini //
886c8a785SMehdi Amini //===----------------------------------------------------------------------===//
986c8a785SMehdi Amini 
1086c8a785SMehdi Amini /* RUN: mlir-capi-execution-engine-test 2>&1 | FileCheck %s
1186c8a785SMehdi Amini  */
12*b630bafbSRainer Orth /* REQUIRES: host-supports-jit
135a68a85dSMehdi Amini  */
1486c8a785SMehdi Amini 
1586c8a785SMehdi Amini #include "mlir-c/Conversion.h"
1686c8a785SMehdi Amini #include "mlir-c/ExecutionEngine.h"
1786c8a785SMehdi Amini #include "mlir-c/IR.h"
185e83a5b4SStella Laurenzo #include "mlir-c/RegisterEverything.h"
1986c8a785SMehdi Amini 
2086c8a785SMehdi Amini #include <assert.h>
2186c8a785SMehdi Amini #include <math.h>
2286c8a785SMehdi Amini #include <stdio.h>
2386c8a785SMehdi Amini #include <stdlib.h>
2486c8a785SMehdi Amini #include <string.h>
2586c8a785SMehdi Amini 
registerAllUpstreamDialects(MlirContext ctx)265e83a5b4SStella Laurenzo static void registerAllUpstreamDialects(MlirContext ctx) {
275e83a5b4SStella Laurenzo   MlirDialectRegistry registry = mlirDialectRegistryCreate();
285e83a5b4SStella Laurenzo   mlirRegisterAllDialects(registry);
295e83a5b4SStella Laurenzo   mlirContextAppendDialectRegistry(ctx, registry);
305e83a5b4SStella Laurenzo   mlirDialectRegistryDestroy(registry);
315e83a5b4SStella Laurenzo }
325e83a5b4SStella Laurenzo 
lowerModuleToLLVM(MlirContext ctx,MlirModule module)3386c8a785SMehdi Amini void lowerModuleToLLVM(MlirContext ctx, MlirModule module) {
3486c8a785SMehdi Amini   MlirPassManager pm = mlirPassManagerCreate(ctx);
35a54f4eaeSMogball   MlirOpPassManager opm = mlirPassManagerGetNestedUnder(
3636550692SRiver Riddle       pm, mlirStringRefCreateFromCString("func.func"));
375a7b9194SRiver Riddle   mlirPassManagerAddOwnedPass(pm, mlirCreateConversionConvertFuncToLLVM());
38a54f4eaeSMogball   mlirOpPassManagerAddOwnedPass(opm,
39a54f4eaeSMogball                                 mlirCreateConversionConvertArithmeticToLLVM());
4086c8a785SMehdi Amini   MlirLogicalResult status = mlirPassManagerRun(pm, module);
4186c8a785SMehdi Amini   if (mlirLogicalResultIsFailure(status)) {
4286c8a785SMehdi Amini     fprintf(stderr, "Unexpected failure running pass pipeline\n");
4386c8a785SMehdi Amini     exit(2);
4486c8a785SMehdi Amini   }
4586c8a785SMehdi Amini   mlirPassManagerDestroy(pm);
4686c8a785SMehdi Amini }
4786c8a785SMehdi Amini 
4886c8a785SMehdi Amini // CHECK-LABEL: Running test 'testSimpleExecution'
testSimpleExecution()4986c8a785SMehdi Amini void testSimpleExecution() {
5086c8a785SMehdi Amini   MlirContext ctx = mlirContextCreate();
515e83a5b4SStella Laurenzo   registerAllUpstreamDialects(ctx);
525e83a5b4SStella Laurenzo 
5386c8a785SMehdi Amini   MlirModule module = mlirModuleCreateParse(
5486c8a785SMehdi Amini       ctx, mlirStringRefCreateFromCString(
5586c8a785SMehdi Amini                // clang-format off
5686c8a785SMehdi Amini "module {                                                                    \n"
570fd3a1ceSRiver Riddle "  func.func @add(%arg0 : i32) -> i32 attributes { llvm.emit_c_interface } {     \n"
58a54f4eaeSMogball "    %res = arith.addi %arg0, %arg0 : i32                                        \n"
5986c8a785SMehdi Amini "    return %res : i32                                                           \n"
6086c8a785SMehdi Amini "  }                                                                             \n"
6186c8a785SMehdi Amini "}"));
6286c8a785SMehdi Amini   // clang-format on
6386c8a785SMehdi Amini   lowerModuleToLLVM(ctx, module);
6486c8a785SMehdi Amini   mlirRegisterAllLLVMTranslations(ctx);
65c8b8e8e0SUday Bondhugula   MlirExecutionEngine jit = mlirExecutionEngineCreate(
66c8b8e8e0SUday Bondhugula       module, /*optLevel=*/2, /*numPaths=*/0, /*sharedLibPaths=*/NULL);
6786c8a785SMehdi Amini   if (mlirExecutionEngineIsNull(jit)) {
6886c8a785SMehdi Amini     fprintf(stderr, "Execution engine creation failed");
6986c8a785SMehdi Amini     exit(2);
7086c8a785SMehdi Amini   }
7186c8a785SMehdi Amini   int input = 42;
7286c8a785SMehdi Amini   int result = -1;
7386c8a785SMehdi Amini   void *args[2] = {&input, &result};
7486c8a785SMehdi Amini   if (mlirLogicalResultIsFailure(mlirExecutionEngineInvokePacked(
7586c8a785SMehdi Amini           jit, mlirStringRefCreateFromCString("add"), args))) {
7686c8a785SMehdi Amini     fprintf(stderr, "Execution engine creation failed");
7786c8a785SMehdi Amini     abort();
7886c8a785SMehdi Amini   }
7986c8a785SMehdi Amini   // CHECK: Input: 42 Result: 84
8086c8a785SMehdi Amini   printf("Input: %d Result: %d\n", input, result);
8186c8a785SMehdi Amini   mlirExecutionEngineDestroy(jit);
8286c8a785SMehdi Amini   mlirModuleDestroy(module);
8386c8a785SMehdi Amini   mlirContextDestroy(ctx);
8486c8a785SMehdi Amini }
8586c8a785SMehdi Amini 
main()8686c8a785SMehdi Amini int main() {
8786c8a785SMehdi Amini 
8886c8a785SMehdi Amini #define _STRINGIFY(x) #x
8986c8a785SMehdi Amini #define STRINGIFY(x) _STRINGIFY(x)
9086c8a785SMehdi Amini #define TEST(test)                                                             \
9186c8a785SMehdi Amini   printf("Running test '" STRINGIFY(test) "'\n");                              \
9286c8a785SMehdi Amini   test();
9386c8a785SMehdi Amini 
9486c8a785SMehdi Amini   TEST(testSimpleExecution);
9586c8a785SMehdi Amini   return 0;
9686c8a785SMehdi Amini }
97