186c8a785SMehdi Amini //===- ExecutionEngine.cpp - C API for MLIR JIT ---------------------------===//
286c8a785SMehdi Amini //
386c8a785SMehdi Amini // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
486c8a785SMehdi Amini // See https://llvm.org/LICENSE.txt for license information.
586c8a785SMehdi Amini // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
686c8a785SMehdi Amini //
786c8a785SMehdi Amini //===----------------------------------------------------------------------===//
886c8a785SMehdi Amini
986c8a785SMehdi Amini #include "mlir-c/ExecutionEngine.h"
1086c8a785SMehdi Amini #include "mlir/CAPI/ExecutionEngine.h"
1186c8a785SMehdi Amini #include "mlir/CAPI/IR.h"
1286c8a785SMehdi Amini #include "mlir/CAPI/Support.h"
13185ce8cdSUday Bondhugula #include "mlir/ExecutionEngine/OptUtils.h"
140e9523efSSergio Afonso #include "mlir/Target/LLVMIR/Dialect/Builtin/BuiltinToLLVMIRTranslation.h"
1519db802eSAlex Zinenko #include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h"
16db7cc034SRafael Ubal Tena #include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
177a4d6307SMehdi Amini #include "llvm/ExecutionEngine/Orc/Mangling.h"
1886c8a785SMehdi Amini #include "llvm/Support/TargetSelect.h"
1986c8a785SMehdi Amini
2086c8a785SMehdi Amini using namespace mlir;
2186c8a785SMehdi Amini
22c8b8e8e0SUday Bondhugula extern "C" MlirExecutionEngine
mlirExecutionEngineCreate(MlirModule op,int optLevel,int numPaths,const MlirStringRef * sharedLibPaths,bool enableObjectDump)23c8b8e8e0SUday Bondhugula mlirExecutionEngineCreate(MlirModule op, int optLevel, int numPaths,
2495c083f5SDenys Shabalin const MlirStringRef *sharedLibPaths,
2595c083f5SDenys Shabalin bool enableObjectDump) {
26185ce8cdSUday Bondhugula static bool initOnce = [] {
2786c8a785SMehdi Amini llvm::InitializeNativeTarget();
28050cc1cdSNicolas Vasilache llvm::InitializeNativeTargetAsmParser(); // needed for inline_asm
2986c8a785SMehdi Amini llvm::InitializeNativeTargetAsmPrinter();
3086c8a785SMehdi Amini return true;
3186c8a785SMehdi Amini }();
32185ce8cdSUday Bondhugula (void)initOnce;
3386c8a785SMehdi Amini
340e9523efSSergio Afonso auto &ctx = *unwrap(op)->getContext();
350e9523efSSergio Afonso mlir::registerBuiltinDialectTranslation(ctx);
360e9523efSSergio Afonso mlir::registerLLVMDialectTranslation(ctx);
37db7cc034SRafael Ubal Tena mlir::registerOpenMPDialectTranslation(ctx);
38185ce8cdSUday Bondhugula
39185ce8cdSUday Bondhugula auto tmBuilderOrError = llvm::orc::JITTargetMachineBuilder::detectHost();
40185ce8cdSUday Bondhugula if (!tmBuilderOrError) {
41185ce8cdSUday Bondhugula llvm::errs() << "Failed to create a JITTargetMachineBuilder for the host\n";
42185ce8cdSUday Bondhugula return MlirExecutionEngine{nullptr};
43185ce8cdSUday Bondhugula }
44185ce8cdSUday Bondhugula auto tmOrError = tmBuilderOrError->createTargetMachine();
45185ce8cdSUday Bondhugula if (!tmOrError) {
46185ce8cdSUday Bondhugula llvm::errs() << "Failed to create a TargetMachine for the host\n";
47185ce8cdSUday Bondhugula return MlirExecutionEngine{nullptr};
48185ce8cdSUday Bondhugula }
49185ce8cdSUday Bondhugula
50c8b8e8e0SUday Bondhugula SmallVector<StringRef> libPaths;
51c8b8e8e0SUday Bondhugula for (unsigned i = 0; i < static_cast<unsigned>(numPaths); ++i)
52c8b8e8e0SUday Bondhugula libPaths.push_back(sharedLibPaths[i].data);
53c8b8e8e0SUday Bondhugula
54185ce8cdSUday Bondhugula // Create a transformer to run all LLVM optimization passes at the
55185ce8cdSUday Bondhugula // specified optimization level.
567ccd026cSArthur Eubanks auto transformer = mlir::makeOptimizingTransformer(
57*0a1aa6cdSArthur Eubanks optLevel, /*sizeLevel=*/0, /*targetMachine=*/tmOrError->get());
58a7db3c61SEmilio Cota ExecutionEngineOptions jitOptions;
59a7db3c61SEmilio Cota jitOptions.transformer = transformer;
60*0a1aa6cdSArthur Eubanks jitOptions.jitCodeGenOptLevel = static_cast<llvm::CodeGenOptLevel>(optLevel);
61a7db3c61SEmilio Cota jitOptions.sharedLibPaths = libPaths;
6295c083f5SDenys Shabalin jitOptions.enableObjectDump = enableObjectDump;
63a7db3c61SEmilio Cota auto jitOrError = ExecutionEngine::create(unwrap(op), jitOptions);
6486c8a785SMehdi Amini if (!jitOrError) {
6586c8a785SMehdi Amini consumeError(jitOrError.takeError());
6686c8a785SMehdi Amini return MlirExecutionEngine{nullptr};
6786c8a785SMehdi Amini }
6886c8a785SMehdi Amini return wrap(jitOrError->release());
6986c8a785SMehdi Amini }
7086c8a785SMehdi Amini
mlirExecutionEngineDestroy(MlirExecutionEngine jit)7186c8a785SMehdi Amini extern "C" void mlirExecutionEngineDestroy(MlirExecutionEngine jit) {
7286c8a785SMehdi Amini delete (unwrap(jit));
7386c8a785SMehdi Amini }
7486c8a785SMehdi Amini
7586c8a785SMehdi Amini extern "C" MlirLogicalResult
mlirExecutionEngineInvokePacked(MlirExecutionEngine jit,MlirStringRef name,void ** arguments)7686c8a785SMehdi Amini mlirExecutionEngineInvokePacked(MlirExecutionEngine jit, MlirStringRef name,
7786c8a785SMehdi Amini void **arguments) {
7886c8a785SMehdi Amini const std::string ifaceName = ("_mlir_ciface_" + unwrap(name)).str();
7986c8a785SMehdi Amini llvm::Error error = unwrap(jit)->invokePacked(
8086c8a785SMehdi Amini ifaceName, MutableArrayRef<void *>{arguments, (size_t)0});
8186c8a785SMehdi Amini if (error)
8286c8a785SMehdi Amini return wrap(failure());
8386c8a785SMehdi Amini return wrap(success());
8486c8a785SMehdi Amini }
8513cb4317SMehdi Amini
mlirExecutionEngineLookupPacked(MlirExecutionEngine jit,MlirStringRef name)86106f3074STres Popp extern "C" void *mlirExecutionEngineLookupPacked(MlirExecutionEngine jit,
87106f3074STres Popp MlirStringRef name) {
88106f3074STres Popp auto expectedFPtr = unwrap(jit)->lookupPacked(unwrap(name));
89106f3074STres Popp if (!expectedFPtr)
90106f3074STres Popp return nullptr;
91106f3074STres Popp return reinterpret_cast<void *>(*expectedFPtr);
92106f3074STres Popp }
93106f3074STres Popp
mlirExecutionEngineLookup(MlirExecutionEngine jit,MlirStringRef name)9413cb4317SMehdi Amini extern "C" void *mlirExecutionEngineLookup(MlirExecutionEngine jit,
9513cb4317SMehdi Amini MlirStringRef name) {
9613cb4317SMehdi Amini auto expectedFPtr = unwrap(jit)->lookup(unwrap(name));
9713cb4317SMehdi Amini if (!expectedFPtr)
9813cb4317SMehdi Amini return nullptr;
9913cb4317SMehdi Amini return reinterpret_cast<void *>(*expectedFPtr);
10013cb4317SMehdi Amini }
1017a4d6307SMehdi Amini
mlirExecutionEngineRegisterSymbol(MlirExecutionEngine jit,MlirStringRef name,void * sym)1027a4d6307SMehdi Amini extern "C" void mlirExecutionEngineRegisterSymbol(MlirExecutionEngine jit,
1037a4d6307SMehdi Amini MlirStringRef name,
1047a4d6307SMehdi Amini void *sym) {
1057a4d6307SMehdi Amini unwrap(jit)->registerSymbols([&](llvm::orc::MangleAndInterner interner) {
1067a4d6307SMehdi Amini llvm::orc::SymbolMap symbolMap;
1077a4d6307SMehdi Amini symbolMap[interner(unwrap(name))] =
108557a0ea8SLang Hames { llvm::orc::ExecutorAddr::fromPtr(sym),
109557a0ea8SLang Hames llvm::JITSymbolFlags::Exported };
1107a4d6307SMehdi Amini return symbolMap;
1117a4d6307SMehdi Amini });
1127a4d6307SMehdi Amini }
1131dc533ceSNicolas Vasilache
mlirExecutionEngineDumpToObjectFile(MlirExecutionEngine jit,MlirStringRef name)1141dc533ceSNicolas Vasilache extern "C" void mlirExecutionEngineDumpToObjectFile(MlirExecutionEngine jit,
1151dc533ceSNicolas Vasilache MlirStringRef name) {
1161dc533ceSNicolas Vasilache unwrap(jit)->dumpToObjectFile(unwrap(name));
1171dc533ceSNicolas Vasilache }
118