xref: /llvm-project/mlir/lib/CAPI/ExecutionEngine/ExecutionEngine.cpp (revision 0a1aa6cda2758b0926a95f87d39ffefb1cb90200)
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 
20 using namespace mlir;
21 
22 extern "C" MlirExecutionEngine
mlirExecutionEngineCreate(MlirModule op,int optLevel,int numPaths,const MlirStringRef * sharedLibPaths,bool enableObjectDump)23 mlirExecutionEngineCreate(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{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{nullptr};
48   }
49 
50   SmallVector<StringRef> libPaths;
51   for (unsigned i = 0; i < static_cast<unsigned>(numPaths); ++i)
52     libPaths.push_back(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(unwrap(op), jitOptions);
64   if (!jitOrError) {
65     consumeError(jitOrError.takeError());
66     return MlirExecutionEngine{nullptr};
67   }
68   return wrap(jitOrError->release());
69 }
70 
mlirExecutionEngineDestroy(MlirExecutionEngine jit)71 extern "C" void mlirExecutionEngineDestroy(MlirExecutionEngine jit) {
72   delete (unwrap(jit));
73 }
74 
75 extern "C" MlirLogicalResult
mlirExecutionEngineInvokePacked(MlirExecutionEngine jit,MlirStringRef name,void ** arguments)76 mlirExecutionEngineInvokePacked(MlirExecutionEngine jit, MlirStringRef name,
77                                 void **arguments) {
78   const std::string ifaceName = ("_mlir_ciface_" + unwrap(name)).str();
79   llvm::Error error = unwrap(jit)->invokePacked(
80       ifaceName, MutableArrayRef<void *>{arguments, (size_t)0});
81   if (error)
82     return wrap(failure());
83   return wrap(success());
84 }
85 
mlirExecutionEngineLookupPacked(MlirExecutionEngine jit,MlirStringRef name)86 extern "C" void *mlirExecutionEngineLookupPacked(MlirExecutionEngine jit,
87                                                  MlirStringRef name) {
88   auto expectedFPtr = unwrap(jit)->lookupPacked(unwrap(name));
89   if (!expectedFPtr)
90     return nullptr;
91   return reinterpret_cast<void *>(*expectedFPtr);
92 }
93 
mlirExecutionEngineLookup(MlirExecutionEngine jit,MlirStringRef name)94 extern "C" void *mlirExecutionEngineLookup(MlirExecutionEngine jit,
95                                            MlirStringRef name) {
96   auto expectedFPtr = unwrap(jit)->lookup(unwrap(name));
97   if (!expectedFPtr)
98     return nullptr;
99   return reinterpret_cast<void *>(*expectedFPtr);
100 }
101 
mlirExecutionEngineRegisterSymbol(MlirExecutionEngine jit,MlirStringRef name,void * sym)102 extern "C" void mlirExecutionEngineRegisterSymbol(MlirExecutionEngine jit,
103                                                   MlirStringRef name,
104                                                   void *sym) {
105   unwrap(jit)->registerSymbols([&](llvm::orc::MangleAndInterner interner) {
106     llvm::orc::SymbolMap symbolMap;
107     symbolMap[interner(unwrap(name))] =
108         { llvm::orc::ExecutorAddr::fromPtr(sym),
109           llvm::JITSymbolFlags::Exported };
110     return symbolMap;
111   });
112 }
113 
mlirExecutionEngineDumpToObjectFile(MlirExecutionEngine jit,MlirStringRef name)114 extern "C" void mlirExecutionEngineDumpToObjectFile(MlirExecutionEngine jit,
115                                                     MlirStringRef name) {
116   unwrap(jit)->dumpToObjectFile(unwrap(name));
117 }
118