1 //===- ExecutionEngine.cpp - C API for MLIR JIT ---------------------------===//
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
7 //===----------------------------------------------------------------------===//
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"
22 extern "C" MlirExecutionEngine
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();
34 auto &ctx
= *unwrap(op
)->getContext();
35 mlir::registerBuiltinDialectTranslation(ctx
);
36 mlir::registerLLVMDialectTranslation(ctx
);
37 mlir::registerOpenMPDialectTranslation(ctx
);
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};
44 auto tmOrError
= tmBuilderOrError
->createTargetMachine();
46 llvm::errs() << "Failed to create a TargetMachine for the host\n";
47 return MlirExecutionEngine
{nullptr};
50 SmallVector
<StringRef
> libPaths
;
51 for (unsigned i
= 0; i
< static_cast<unsigned>(numPaths
); ++i
)
52 libPaths
.push_back(sharedLibPaths
[i
].data
);
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
);
65 consumeError(jitOrError
.takeError());
66 return MlirExecutionEngine
{nullptr};
68 return wrap(jitOrError
->release());
71 extern "C" void mlirExecutionEngineDestroy(MlirExecutionEngine jit
) {
75 extern "C" MlirLogicalResult
76 mlirExecutionEngineInvokePacked(MlirExecutionEngine jit
, MlirStringRef name
,
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});
82 return wrap(failure());
83 return wrap(success());
86 extern "C" void *mlirExecutionEngineLookupPacked(MlirExecutionEngine jit
,
88 auto expectedFPtr
= unwrap(jit
)->lookupPacked(unwrap(name
));
91 return reinterpret_cast<void *>(*expectedFPtr
);
94 extern "C" void *mlirExecutionEngineLookup(MlirExecutionEngine jit
,
96 auto expectedFPtr
= unwrap(jit
)->lookup(unwrap(name
));
99 return reinterpret_cast<void *>(*expectedFPtr
);
102 extern "C" void mlirExecutionEngineRegisterSymbol(MlirExecutionEngine jit
,
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
};
114 extern "C" void mlirExecutionEngineDumpToObjectFile(MlirExecutionEngine jit
,
115 MlirStringRef name
) {
116 unwrap(jit
)->dumpToObjectFile(unwrap(name
));