[Mlir-commits] [mlir] a7db3c6 - [mlir][NFC] Use options struct in ExecutionEngine::create
Emilio Cota
llvmlistbot at llvm.org
Wed Feb 23 07:32:58 PST 2022
Author: Emilio Cota
Date: 2022-02-23T10:21:46-05:00
New Revision: a7db3c611b1e613ae43ef472c2352f2b81a0b607
URL: https://github.com/llvm/llvm-project/commit/a7db3c611b1e613ae43ef472c2352f2b81a0b607
DIFF: https://github.com/llvm/llvm-project/commit/a7db3c611b1e613ae43ef472c2352f2b81a0b607.diff
LOG: [mlir][NFC] Use options struct in ExecutionEngine::create
Its number of optional parameters has grown too large,
which makes adding new optional parameters quite a chore.
Fix this by using an options struct.
Reviewed By: mehdi_amini
Differential Revision: https://reviews.llvm.org/D120380
Added:
Modified:
mlir/examples/toy/Ch6/toyc.cpp
mlir/examples/toy/Ch7/toyc.cpp
mlir/include/mlir/ExecutionEngine/ExecutionEngine.h
mlir/lib/CAPI/ExecutionEngine/ExecutionEngine.cpp
mlir/lib/ExecutionEngine/ExecutionEngine.cpp
mlir/lib/ExecutionEngine/JitRunner.cpp
Removed:
################################################################################
diff --git a/mlir/examples/toy/Ch6/toyc.cpp b/mlir/examples/toy/Ch6/toyc.cpp
index 95b0789a01462..659104032ecc1 100644
--- a/mlir/examples/toy/Ch6/toyc.cpp
+++ b/mlir/examples/toy/Ch6/toyc.cpp
@@ -236,8 +236,9 @@ int runJit(mlir::ModuleOp module) {
// Create an MLIR execution engine. The execution engine eagerly JIT-compiles
// the module.
- auto maybeEngine = mlir::ExecutionEngine::create(
- module, /*llvmModuleBuilder=*/nullptr, optPipeline);
+ mlir::ExecutionEngineOptions engineOptions;
+ engineOptions.transformer = optPipeline;
+ auto maybeEngine = mlir::ExecutionEngine::create(module, engineOptions);
assert(maybeEngine && "failed to construct an execution engine");
auto &engine = maybeEngine.get();
diff --git a/mlir/examples/toy/Ch7/toyc.cpp b/mlir/examples/toy/Ch7/toyc.cpp
index ce8a0f0f432a7..2b976ba97a9e0 100644
--- a/mlir/examples/toy/Ch7/toyc.cpp
+++ b/mlir/examples/toy/Ch7/toyc.cpp
@@ -237,8 +237,9 @@ int runJit(mlir::ModuleOp module) {
// Create an MLIR execution engine. The execution engine eagerly JIT-compiles
// the module.
- auto maybeEngine = mlir::ExecutionEngine::create(
- module, /*llvmModuleBuilder=*/nullptr, optPipeline);
+ mlir::ExecutionEngineOptions engineOptions;
+ engineOptions.transformer = optPipeline;
+ auto maybeEngine = mlir::ExecutionEngine::create(module, engineOptions);
assert(maybeEngine && "failed to construct an execution engine");
auto &engine = maybeEngine.get();
diff --git a/mlir/include/mlir/ExecutionEngine/ExecutionEngine.h b/mlir/include/mlir/ExecutionEngine/ExecutionEngine.h
index 058c55efaaddf..8a2a870aec422 100644
--- a/mlir/include/mlir/ExecutionEngine/ExecutionEngine.h
+++ b/mlir/include/mlir/ExecutionEngine/ExecutionEngine.h
@@ -48,6 +48,39 @@ class SimpleObjectCache : public llvm::ObjectCache {
llvm::StringMap<std::unique_ptr<llvm::MemoryBuffer>> cachedObjects;
};
+struct ExecutionEngineOptions {
+ /// If `llvmModuleBuilder` is provided, it will be used to create LLVM module
+ /// from the given MLIR module. Otherwise, a default `translateModuleToLLVMIR`
+ /// function will be used to translate MLIR module to LLVM IR.
+ llvm::function_ref<std::unique_ptr<llvm::Module>(ModuleOp,
+ llvm::LLVMContext &)>
+ llvmModuleBuilder = nullptr;
+
+ /// If `transformer` is provided, it will be called on the LLVM module during
+ /// JIT-compilation and can be used, e.g., for reporting or optimization.
+ llvm::function_ref<llvm::Error(llvm::Module *)> transformer = {};
+
+ /// `jitCodeGenOptLevel`, when provided, is used as the optimization level for
+ /// target code generation.
+ Optional<llvm::CodeGenOpt::Level> jitCodeGenOptLevel = llvm::None;
+
+ /// If `sharedLibPaths` are provided, the underlying JIT-compilation will
+ /// open and link the shared libraries for symbol resolution.
+ ArrayRef<StringRef> sharedLibPaths = {};
+
+ /// If `enableObjectCache` is set, the JIT compiler will create one to store
+ /// the object generated for the given module.
+ bool enableObjectCache = true;
+
+ /// If enable `enableGDBNotificationListener` is set, the JIT compiler will
+ /// notify the llvm's global GDB notification listener.
+ bool enableGDBNotificationListener = true;
+
+ /// If `enablePerfNotificationListener` is set, the JIT compiler will notify
+ /// the llvm's global Perf notification listener.
+ bool enablePerfNotificationListener = true;
+};
+
/// JIT-backed execution engine for MLIR modules. Assumes the module can be
/// converted to LLVM IR. For each function, creates a wrapper function with
/// the fixed interface
@@ -64,38 +97,8 @@ class ExecutionEngine {
bool enablePerfNotificationListener);
/// Creates an execution engine for the given module.
- ///
- /// If `llvmModuleBuilder` is provided, it will be used to create LLVM module
- /// from the given MLIR module. Otherwise, a default `translateModuleToLLVMIR`
- /// function will be used to translate MLIR module to LLVM IR.
- ///
- /// If `transformer` is provided, it will be called on the LLVM module during
- /// JIT-compilation and can be used, e.g., for reporting or optimization.
- ///
- /// `jitCodeGenOptLevel`, when provided, is used as the optimization level for
- /// target code generation.
- ///
- /// If `sharedLibPaths` are provided, the underlying JIT-compilation will
- /// open and link the shared libraries for symbol resolution.
- ///
- /// If `enableObjectCache` is set, the JIT compiler will create one to store
- /// the object generated for the given module.
- ///
- /// If enable `enableGDBNotificationListener` is set, the JIT compiler will
- /// notify the llvm's global GDB notification listener.
- ///
- /// If `enablePerfNotificationListener` is set, the JIT compiler will notify
- /// the llvm's global Perf notification listener.
static llvm::Expected<std::unique_ptr<ExecutionEngine>>
- create(ModuleOp m,
- llvm::function_ref<std::unique_ptr<llvm::Module>(ModuleOp,
- llvm::LLVMContext &)>
- llvmModuleBuilder = nullptr,
- llvm::function_ref<llvm::Error(llvm::Module *)> transformer = {},
- Optional<llvm::CodeGenOpt::Level> jitCodeGenOptLevel = llvm::None,
- ArrayRef<StringRef> sharedLibPaths = {}, bool enableObjectCache = true,
- bool enableGDBNotificationListener = true,
- bool enablePerfNotificationListener = true);
+ create(ModuleOp m, const ExecutionEngineOptions &options = {});
/// Looks up a packed-argument function wrapping the function with the given
/// name and returns a pointer to it. Propagates errors in case of failure.
diff --git a/mlir/lib/CAPI/ExecutionEngine/ExecutionEngine.cpp b/mlir/lib/CAPI/ExecutionEngine/ExecutionEngine.cpp
index 604cc45221fe4..4c55530870df7 100644
--- a/mlir/lib/CAPI/ExecutionEngine/ExecutionEngine.cpp
+++ b/mlir/lib/CAPI/ExecutionEngine/ExecutionEngine.cpp
@@ -50,9 +50,11 @@ mlirExecutionEngineCreate(MlirModule op, int optLevel, int numPaths,
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);
+ ExecutionEngineOptions jitOptions;
+ jitOptions.transformer = transformer;
+ jitOptions.jitCodeGenOptLevel = llvmOptLevel;
+ jitOptions.sharedLibPaths = libPaths;
+ auto jitOrError = ExecutionEngine::create(unwrap(op), jitOptions);
if (!jitOrError) {
consumeError(jitOrError.takeError());
return MlirExecutionEngine{nullptr};
diff --git a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
index 00569e1d4242c..d8e778b9efb44 100644
--- a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -227,22 +227,16 @@ ExecutionEngine::ExecutionEngine(bool enableObjectCache,
}
}
-Expected<std::unique_ptr<ExecutionEngine>> ExecutionEngine::create(
- ModuleOp m,
- llvm::function_ref<std::unique_ptr<llvm::Module>(ModuleOp,
- llvm::LLVMContext &)>
- llvmModuleBuilder,
- llvm::function_ref<Error(llvm::Module *)> transformer,
- Optional<llvm::CodeGenOpt::Level> jitCodeGenOptLevel,
- ArrayRef<StringRef> sharedLibPaths, bool enableObjectCache,
- bool enableGDBNotificationListener, bool enablePerfNotificationListener) {
+Expected<std::unique_ptr<ExecutionEngine>>
+ExecutionEngine::create(ModuleOp m, const ExecutionEngineOptions &options) {
auto engine = std::make_unique<ExecutionEngine>(
- enableObjectCache, enableGDBNotificationListener,
- enablePerfNotificationListener);
+ options.enableObjectCache, options.enableGDBNotificationListener,
+ options.enablePerfNotificationListener);
std::unique_ptr<llvm::LLVMContext> ctx(new llvm::LLVMContext);
- auto llvmModule = llvmModuleBuilder ? llvmModuleBuilder(m, *ctx)
- : translateModuleToLLVMIR(m, *ctx);
+ auto llvmModule = options.llvmModuleBuilder
+ ? options.llvmModuleBuilder(m, *ctx)
+ : translateModuleToLLVMIR(m, *ctx);
if (!llvmModule)
return makeStringError("could not convert to LLVM IR");
// FIXME: the triple should be passed to the translation or dialect conversion
@@ -276,7 +270,7 @@ Expected<std::unique_ptr<ExecutionEngine>> ExecutionEngine::create(
}
// Resolve symbols from shared libraries.
- for (auto libPath : sharedLibPaths) {
+ for (auto libPath : options.sharedLibPaths) {
auto mb = llvm::MemoryBuffer::getFile(libPath);
if (!mb) {
errs() << "Failed to create MemoryBuffer for: " << libPath
@@ -302,8 +296,8 @@ Expected<std::unique_ptr<ExecutionEngine>> ExecutionEngine::create(
// LLJITWithObjectCache example.
auto compileFunctionCreator = [&](JITTargetMachineBuilder jtmb)
-> Expected<std::unique_ptr<IRCompileLayer::IRCompiler>> {
- if (jitCodeGenOptLevel)
- jtmb.setCodeGenOptLevel(jitCodeGenOptLevel.getValue());
+ if (options.jitCodeGenOptLevel)
+ jtmb.setCodeGenOptLevel(options.jitCodeGenOptLevel.getValue());
auto tm = jtmb.createTargetMachine();
if (!tm)
return tm.takeError();
@@ -320,9 +314,9 @@ Expected<std::unique_ptr<ExecutionEngine>> ExecutionEngine::create(
// Add a ThreadSafemodule to the engine and return.
ThreadSafeModule tsm(std::move(llvmModule), std::move(ctx));
- if (transformer)
+ if (options.transformer)
cantFail(tsm.withModuleDo(
- [&](llvm::Module &module) { return transformer(&module); }));
+ [&](llvm::Module &module) { return options.transformer(&module); }));
cantFail(jit->addIRModule(std::move(tsm)));
engine->jit = std::move(jit);
diff --git a/mlir/lib/ExecutionEngine/JitRunner.cpp b/mlir/lib/ExecutionEngine/JitRunner.cpp
index 37e5e93e2b7ea..79468fc6d63de 100644
--- a/mlir/lib/ExecutionEngine/JitRunner.cpp
+++ b/mlir/lib/ExecutionEngine/JitRunner.cpp
@@ -207,9 +207,12 @@ static Error compileAndExecute(Options &options, ModuleOp module,
return symbolMap;
};
- auto expectedEngine = mlir::ExecutionEngine::create(
- module, config.llvmModuleBuilder, config.transformer, jitCodeGenOptLevel,
- executionEngineLibs);
+ mlir::ExecutionEngineOptions engineOptions;
+ engineOptions.llvmModuleBuilder = config.llvmModuleBuilder;
+ engineOptions.transformer = config.transformer;
+ engineOptions.jitCodeGenOptLevel = jitCodeGenOptLevel;
+ engineOptions.sharedLibPaths = executionEngineLibs;
+ auto expectedEngine = mlir::ExecutionEngine::create(module, engineOptions);
if (!expectedEngine)
return expectedEngine.takeError();
More information about the Mlir-commits
mailing list