1//===- ExecutionEngine.cpp - C API for MLIR JIT ---------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "mlir-c/ExecutionEngine.h"
10#include "mlir/CAPI/ExecutionEngine.h"
11#include "mlir/CAPI/IR.h"
12#include "mlir/CAPI/Support.h"
13#include "mlir/ExecutionEngine/OptUtils.h"
14#include "mlir/Target/LLVMIR/Dialect/Builtin/BuiltinToLLVMIRTranslation.h"
15#include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h"
16#include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
17#include "llvm/ExecutionEngine/Orc/Mangling.h"
18#include "llvm/Support/TargetSelect.h"
19
20using namespace mlir;
21
22extern "C" MlirExecutionEngine
23mlirExecutionEngineCreate(MlirModule op, int optLevel, int numPaths,
24 const MlirStringRef *sharedLibPaths,
25 bool enableObjectDump) {
26 static bool initOnce = [] {
27 llvm::InitializeNativeTarget();
28 llvm::InitializeNativeTargetAsmParser(); // needed for inline_asm
29 llvm::InitializeNativeTargetAsmPrinter();
30 return true;
31 }();
32 (void)initOnce;
33
34 auto &ctx = *unwrap(op)->getContext();
35 mlir::registerBuiltinDialectTranslation(ctx);
36 mlir::registerLLVMDialectTranslation(ctx);
37 mlir::registerOpenMPDialectTranslation(ctx);
38
39 auto tmBuilderOrError = llvm::orc::JITTargetMachineBuilder::detectHost();
40 if (!tmBuilderOrError) {
41 llvm::errs() << "Failed to create a JITTargetMachineBuilder for the host\n";
42 return MlirExecutionEngine{.ptr: nullptr};
43 }
44 auto tmOrError = tmBuilderOrError->createTargetMachine();
45 if (!tmOrError) {
46 llvm::errs() << "Failed to create a TargetMachine for the host\n";
47 return MlirExecutionEngine{.ptr: nullptr};
48 }
49
50 SmallVector<StringRef> libPaths;
51 for (unsigned i = 0; i < static_cast<unsigned>(numPaths); ++i)
52 libPaths.push_back(Elt: sharedLibPaths[i].data);
53
54 // Create a transformer to run all LLVM optimization passes at the
55 // specified optimization level.
56 auto transformer = mlir::makeOptimizingTransformer(
57 optLevel, /*sizeLevel=*/0, /*targetMachine=*/tmOrError->get());
58 ExecutionEngineOptions jitOptions;
59 jitOptions.transformer = transformer;
60 jitOptions.jitCodeGenOptLevel = static_cast<llvm::CodeGenOptLevel>(optLevel);
61 jitOptions.sharedLibPaths = libPaths;
62 jitOptions.enableObjectDump = enableObjectDump;
63 auto jitOrError = ExecutionEngine::create(op: unwrap(op), options: jitOptions);
64 if (!jitOrError) {
65 consumeError(jitOrError.takeError());
66 return MlirExecutionEngine{.ptr: nullptr};
67 }
68 return wrap(jitOrError->release());
69}
70
71extern "C" void mlirExecutionEngineDestroy(MlirExecutionEngine jit) {
72 delete (unwrap(c: jit));
73}
74
75extern "C" MlirLogicalResult
76mlirExecutionEngineInvokePacked(MlirExecutionEngine jit, MlirStringRef name,
77 void **arguments) {
78 const std::string ifaceName = ("_mlir_ciface_" + unwrap(ref: name)).str();
79 llvm::Error error = unwrap(c: jit)->invokePacked(
80 name: ifaceName, args: MutableArrayRef<void *>{arguments, (size_t)0});
81 if (error)
82 return wrap(res: failure());
83 return wrap(res: success());
84}
85
86extern "C" void *mlirExecutionEngineLookupPacked(MlirExecutionEngine jit,
87 MlirStringRef name) {
88 auto expectedFPtr = unwrap(c: jit)->lookupPacked(name: unwrap(ref: name));
89 if (!expectedFPtr)
90 return nullptr;
91 return reinterpret_cast<void *>(*expectedFPtr);
92}
93
94extern "C" void *mlirExecutionEngineLookup(MlirExecutionEngine jit,
95 MlirStringRef name) {
96 auto expectedFPtr = unwrap(c: jit)->lookup(name: unwrap(ref: name));
97 if (!expectedFPtr)
98 return nullptr;
99 return reinterpret_cast<void *>(*expectedFPtr);
100}
101
102extern "C" void mlirExecutionEngineRegisterSymbol(MlirExecutionEngine jit,
103 MlirStringRef name,
104 void *sym) {
105 unwrap(c: jit)->registerSymbols(symbolMap: [&](llvm::orc::MangleAndInterner interner) {
106 llvm::orc::SymbolMap symbolMap;
107 symbolMap[interner(unwrap(ref: name))] =
108 { llvm::orc::ExecutorAddr::fromPtr(Ptr: sym),
109 llvm::JITSymbolFlags::Exported };
110 return symbolMap;
111 });
112}
113
114extern "C" void mlirExecutionEngineDumpToObjectFile(MlirExecutionEngine jit,
115 MlirStringRef name) {
116 unwrap(c: jit)->dumpToObjectFile(filename: unwrap(ref: name));
117}
118

source code of mlir/lib/CAPI/ExecutionEngine/ExecutionEngine.cpp