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" 16*db7cc034SRafael 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 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); 37*db7cc034SRafael 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. 56185ce8cdSUday Bondhugula auto llvmOptLevel = static_cast<llvm::CodeGenOpt::Level>(optLevel); 577ccd026cSArthur Eubanks auto transformer = mlir::makeOptimizingTransformer( 587ccd026cSArthur Eubanks llvmOptLevel, /*sizeLevel=*/0, /*targetMachine=*/tmOrError->get()); 59a7db3c61SEmilio Cota ExecutionEngineOptions jitOptions; 60a7db3c61SEmilio Cota jitOptions.transformer = transformer; 61a7db3c61SEmilio Cota jitOptions.jitCodeGenOptLevel = llvmOptLevel; 62a7db3c61SEmilio Cota jitOptions.sharedLibPaths = libPaths; 6395c083f5SDenys Shabalin jitOptions.enableObjectDump = enableObjectDump; 64a7db3c61SEmilio Cota auto jitOrError = ExecutionEngine::create(unwrap(op), jitOptions); 6586c8a785SMehdi Amini if (!jitOrError) { 6686c8a785SMehdi Amini consumeError(jitOrError.takeError()); 6786c8a785SMehdi Amini return MlirExecutionEngine{nullptr}; 6886c8a785SMehdi Amini } 6986c8a785SMehdi Amini return wrap(jitOrError->release()); 7086c8a785SMehdi Amini } 7186c8a785SMehdi Amini 7286c8a785SMehdi Amini extern "C" void mlirExecutionEngineDestroy(MlirExecutionEngine jit) { 7386c8a785SMehdi Amini delete (unwrap(jit)); 7486c8a785SMehdi Amini } 7586c8a785SMehdi Amini 7686c8a785SMehdi Amini extern "C" MlirLogicalResult 7786c8a785SMehdi Amini mlirExecutionEngineInvokePacked(MlirExecutionEngine jit, MlirStringRef name, 7886c8a785SMehdi Amini void **arguments) { 7986c8a785SMehdi Amini const std::string ifaceName = ("_mlir_ciface_" + unwrap(name)).str(); 8086c8a785SMehdi Amini llvm::Error error = unwrap(jit)->invokePacked( 8186c8a785SMehdi Amini ifaceName, MutableArrayRef<void *>{arguments, (size_t)0}); 8286c8a785SMehdi Amini if (error) 8386c8a785SMehdi Amini return wrap(failure()); 8486c8a785SMehdi Amini return wrap(success()); 8586c8a785SMehdi Amini } 8613cb4317SMehdi Amini 87106f3074STres Popp extern "C" void *mlirExecutionEngineLookupPacked(MlirExecutionEngine jit, 88106f3074STres Popp MlirStringRef name) { 89106f3074STres Popp auto expectedFPtr = unwrap(jit)->lookupPacked(unwrap(name)); 90106f3074STres Popp if (!expectedFPtr) 91106f3074STres Popp return nullptr; 92106f3074STres Popp return reinterpret_cast<void *>(*expectedFPtr); 93106f3074STres Popp } 94106f3074STres Popp 9513cb4317SMehdi Amini extern "C" void *mlirExecutionEngineLookup(MlirExecutionEngine jit, 9613cb4317SMehdi Amini MlirStringRef name) { 9713cb4317SMehdi Amini auto expectedFPtr = unwrap(jit)->lookup(unwrap(name)); 9813cb4317SMehdi Amini if (!expectedFPtr) 9913cb4317SMehdi Amini return nullptr; 10013cb4317SMehdi Amini return reinterpret_cast<void *>(*expectedFPtr); 10113cb4317SMehdi Amini } 1027a4d6307SMehdi Amini 1037a4d6307SMehdi Amini extern "C" void mlirExecutionEngineRegisterSymbol(MlirExecutionEngine jit, 1047a4d6307SMehdi Amini MlirStringRef name, 1057a4d6307SMehdi Amini void *sym) { 1067a4d6307SMehdi Amini unwrap(jit)->registerSymbols([&](llvm::orc::MangleAndInterner interner) { 1077a4d6307SMehdi Amini llvm::orc::SymbolMap symbolMap; 1087a4d6307SMehdi Amini symbolMap[interner(unwrap(name))] = 109557a0ea8SLang Hames { llvm::orc::ExecutorAddr::fromPtr(sym), 110557a0ea8SLang Hames llvm::JITSymbolFlags::Exported }; 1117a4d6307SMehdi Amini return symbolMap; 1127a4d6307SMehdi Amini }); 1137a4d6307SMehdi Amini } 1141dc533ceSNicolas Vasilache 1151dc533ceSNicolas Vasilache extern "C" void mlirExecutionEngineDumpToObjectFile(MlirExecutionEngine jit, 1161dc533ceSNicolas Vasilache MlirStringRef name) { 1171dc533ceSNicolas Vasilache unwrap(jit)->dumpToObjectFile(unwrap(name)); 1181dc533ceSNicolas Vasilache } 119