llvm-project/mlir/lib/CAPI/ExecutionEngine/ExecutionEngine.cpp
Tres Popp 106f307499 Rename MlirExecutionEngine lookup to lookupPacked
The purpose of the change is to make clear whether the user is
retrieving the original function or the wrapper function, in line with
the invoke commands. This new functionality is useful for users that
already have defined their own packed interface, so they do not want the
extra layer of indirection, or for users wanting to the look at the
resulting primary function rather than the wrapper function.

All locations, except the python bindings now have a `lookupPacked`
method that matches the original `lookup` functionality. `lookup`
still exists, but with new semantics.

- `lookup` returns the function with a given name. If `bool f(int,int)`
is compiled, `lookup` will return a reference to `bool(*f)(int,int)`.
- `lookupPacked` returns the packed wrapper of the function with the
given name. If `bool f(int,int)` is compiled, `lookupPacked` will return
`void(*mlir_f)(void**)`.

Differential Revision: https://reviews.llvm.org/D114352
2021-11-22 14:12:09 +01:00

109 lines
4.0 KiB
C++

//===- ExecutionEngine.cpp - C API for MLIR JIT ---------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "mlir-c/ExecutionEngine.h"
#include "mlir/CAPI/ExecutionEngine.h"
#include "mlir/CAPI/IR.h"
#include "mlir/CAPI/Support.h"
#include "mlir/ExecutionEngine/OptUtils.h"
#include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h"
#include "llvm/ExecutionEngine/Orc/Mangling.h"
#include "llvm/Support/TargetSelect.h"
using namespace mlir;
extern "C" MlirExecutionEngine
mlirExecutionEngineCreate(MlirModule op, int optLevel, int numPaths,
const MlirStringRef *sharedLibPaths) {
static bool initOnce = [] {
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmParser(); // needed for inline_asm
llvm::InitializeNativeTargetAsmPrinter();
return true;
}();
(void)initOnce;
mlir::registerLLVMDialectTranslation(*unwrap(op)->getContext());
auto tmBuilderOrError = llvm::orc::JITTargetMachineBuilder::detectHost();
if (!tmBuilderOrError) {
llvm::errs() << "Failed to create a JITTargetMachineBuilder for the host\n";
return MlirExecutionEngine{nullptr};
}
auto tmOrError = tmBuilderOrError->createTargetMachine();
if (!tmOrError) {
llvm::errs() << "Failed to create a TargetMachine for the host\n";
return MlirExecutionEngine{nullptr};
}
SmallVector<StringRef> libPaths;
for (unsigned i = 0; i < static_cast<unsigned>(numPaths); ++i)
libPaths.push_back(sharedLibPaths[i].data);
// Create a transformer to run all LLVM optimization passes at the
// specified optimization level.
auto llvmOptLevel = static_cast<llvm::CodeGenOpt::Level>(optLevel);
auto transformer = mlir::makeLLVMPassesTransformer(
/*passes=*/{}, llvmOptLevel, /*targetMachine=*/tmOrError->get());
auto jitOrError =
ExecutionEngine::create(unwrap(op), /*llvmModuleBuilder=*/{}, transformer,
llvmOptLevel, libPaths);
if (!jitOrError) {
consumeError(jitOrError.takeError());
return MlirExecutionEngine{nullptr};
}
return wrap(jitOrError->release());
}
extern "C" void mlirExecutionEngineDestroy(MlirExecutionEngine jit) {
delete (unwrap(jit));
}
extern "C" MlirLogicalResult
mlirExecutionEngineInvokePacked(MlirExecutionEngine jit, MlirStringRef name,
void **arguments) {
const std::string ifaceName = ("_mlir_ciface_" + unwrap(name)).str();
llvm::Error error = unwrap(jit)->invokePacked(
ifaceName, MutableArrayRef<void *>{arguments, (size_t)0});
if (error)
return wrap(failure());
return wrap(success());
}
extern "C" void *mlirExecutionEngineLookupPacked(MlirExecutionEngine jit,
MlirStringRef name) {
auto expectedFPtr = unwrap(jit)->lookupPacked(unwrap(name));
if (!expectedFPtr)
return nullptr;
return reinterpret_cast<void *>(*expectedFPtr);
}
extern "C" void *mlirExecutionEngineLookup(MlirExecutionEngine jit,
MlirStringRef name) {
auto expectedFPtr = unwrap(jit)->lookup(unwrap(name));
if (!expectedFPtr)
return nullptr;
return reinterpret_cast<void *>(*expectedFPtr);
}
extern "C" void mlirExecutionEngineRegisterSymbol(MlirExecutionEngine jit,
MlirStringRef name,
void *sym) {
unwrap(jit)->registerSymbols([&](llvm::orc::MangleAndInterner interner) {
llvm::orc::SymbolMap symbolMap;
symbolMap[interner(unwrap(name))] =
llvm::JITEvaluatedSymbol::fromPointer(sym);
return symbolMap;
});
}
extern "C" void mlirExecutionEngineDumpToObjectFile(MlirExecutionEngine jit,
MlirStringRef name) {
unwrap(jit)->dumpToObjectFile(unwrap(name));
}