forked from OSchip/llvm-project
[mlir][NFC] Wrap the cl::opts in JitRunner within a struct to avoid global initializers.
Summary: This avoids the need for having global static initializers within the JITRunner support library, and only constructs the options when the runner is invoked. Differential Revision: https://reviews.llvm.org/D77760
This commit is contained in:
parent
7baad0c53c
commit
293c5210ec
|
@ -41,54 +41,58 @@
|
|||
using namespace mlir;
|
||||
using llvm::Error;
|
||||
|
||||
static llvm::cl::opt<std::string> inputFilename(llvm::cl::Positional,
|
||||
llvm::cl::desc("<input file>"),
|
||||
llvm::cl::init("-"));
|
||||
static llvm::cl::opt<std::string>
|
||||
mainFuncName("e", llvm::cl::desc("The function to be called"),
|
||||
llvm::cl::value_desc("<function name>"),
|
||||
llvm::cl::init("main"));
|
||||
static llvm::cl::opt<std::string> mainFuncType(
|
||||
"entry-point-result",
|
||||
llvm::cl::desc("Textual description of the function type to be called"),
|
||||
llvm::cl::value_desc("f32 | void"), llvm::cl::init("f32"));
|
||||
namespace {
|
||||
/// This options struct prevents the need for global static initializers, and
|
||||
/// is only initialized if the JITRunner is invoked.
|
||||
struct Options {
|
||||
llvm::cl::opt<std::string> inputFilename{llvm::cl::Positional,
|
||||
llvm::cl::desc("<input file>"),
|
||||
llvm::cl::init("-")};
|
||||
llvm::cl::opt<std::string> mainFuncName{
|
||||
"e", llvm::cl::desc("The function to be called"),
|
||||
llvm::cl::value_desc("<function name>"), llvm::cl::init("main")};
|
||||
llvm::cl::opt<std::string> mainFuncType{
|
||||
"entry-point-result",
|
||||
llvm::cl::desc("Textual description of the function type to be called"),
|
||||
llvm::cl::value_desc("f32 | void"), llvm::cl::init("f32")};
|
||||
|
||||
static llvm::cl::OptionCategory optFlags("opt-like flags");
|
||||
llvm::cl::OptionCategory optFlags{"opt-like flags"};
|
||||
|
||||
// CLI list of pass information
|
||||
static llvm::cl::list<const llvm::PassInfo *, bool, llvm::PassNameParser>
|
||||
llvmPasses(llvm::cl::desc("LLVM optimizing passes to run"),
|
||||
llvm::cl::cat(optFlags));
|
||||
// CLI list of pass information
|
||||
llvm::cl::list<const llvm::PassInfo *, bool, llvm::PassNameParser> llvmPasses{
|
||||
llvm::cl::desc("LLVM optimizing passes to run"), llvm::cl::cat(optFlags)};
|
||||
|
||||
// CLI variables for -On options.
|
||||
static llvm::cl::opt<bool>
|
||||
optO0("O0", llvm::cl::desc("Run opt passes and codegen at O0"),
|
||||
llvm::cl::cat(optFlags));
|
||||
static llvm::cl::opt<bool>
|
||||
optO1("O1", llvm::cl::desc("Run opt passes and codegen at O1"),
|
||||
llvm::cl::cat(optFlags));
|
||||
static llvm::cl::opt<bool>
|
||||
optO2("O2", llvm::cl::desc("Run opt passes and codegen at O2"),
|
||||
llvm::cl::cat(optFlags));
|
||||
static llvm::cl::opt<bool>
|
||||
optO3("O3", llvm::cl::desc("Run opt passes and codegen at O3"),
|
||||
llvm::cl::cat(optFlags));
|
||||
// CLI variables for -On options.
|
||||
llvm::cl::opt<bool> optO0{"O0",
|
||||
llvm::cl::desc("Run opt passes and codegen at O0"),
|
||||
llvm::cl::cat(optFlags)};
|
||||
llvm::cl::opt<bool> optO1{"O1",
|
||||
llvm::cl::desc("Run opt passes and codegen at O1"),
|
||||
llvm::cl::cat(optFlags)};
|
||||
llvm::cl::opt<bool> optO2{"O2",
|
||||
llvm::cl::desc("Run opt passes and codegen at O2"),
|
||||
llvm::cl::cat(optFlags)};
|
||||
llvm::cl::opt<bool> optO3{"O3",
|
||||
llvm::cl::desc("Run opt passes and codegen at O3"),
|
||||
llvm::cl::cat(optFlags)};
|
||||
|
||||
static llvm::cl::OptionCategory clOptionsCategory("linking options");
|
||||
static llvm::cl::list<std::string>
|
||||
clSharedLibs("shared-libs", llvm::cl::desc("Libraries to link dynamically"),
|
||||
llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated,
|
||||
llvm::cl::cat(clOptionsCategory));
|
||||
llvm::cl::OptionCategory clOptionsCategory{"linking options"};
|
||||
llvm::cl::list<std::string> clSharedLibs{
|
||||
"shared-libs", llvm::cl::desc("Libraries to link dynamically"),
|
||||
llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated,
|
||||
llvm::cl::cat(clOptionsCategory)};
|
||||
|
||||
// CLI variables for debugging.
|
||||
static llvm::cl::opt<bool> dumpObjectFile(
|
||||
"dump-object-file",
|
||||
llvm::cl::desc("Dump JITted-compiled object to file specified with "
|
||||
"-object-filename (<input file>.o by default)."));
|
||||
/// CLI variables for debugging.
|
||||
llvm::cl::opt<bool> dumpObjectFile{
|
||||
"dump-object-file",
|
||||
llvm::cl::desc("Dump JITted-compiled object to file specified with "
|
||||
"-object-filename (<input file>.o by default).")};
|
||||
|
||||
static llvm::cl::opt<std::string> objectFilename(
|
||||
"object-filename",
|
||||
llvm::cl::desc("Dump JITted-compiled object to file <input file>.o"));
|
||||
llvm::cl::opt<std::string> objectFilename{
|
||||
"object-filename",
|
||||
llvm::cl::desc("Dump JITted-compiled object to file <input file>.o")};
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
static OwningModuleRef parseMLIRInput(StringRef inputFilename,
|
||||
MLIRContext *context) {
|
||||
|
@ -110,10 +114,10 @@ static inline Error make_string_error(const Twine &message) {
|
|||
llvm::inconvertibleErrorCode());
|
||||
}
|
||||
|
||||
static Optional<unsigned> getCommandLineOptLevel() {
|
||||
static Optional<unsigned> getCommandLineOptLevel(Options &options) {
|
||||
Optional<unsigned> optLevel;
|
||||
SmallVector<std::reference_wrapper<llvm::cl::opt<bool>>, 4> optFlags{
|
||||
optO0, optO1, optO2, optO3};
|
||||
options.optO0, options.optO1, options.optO2, options.optO3};
|
||||
|
||||
// Determine if there is an optimization flag present.
|
||||
for (unsigned j = 0; j < 4; ++j) {
|
||||
|
@ -128,14 +132,15 @@ static Optional<unsigned> getCommandLineOptLevel() {
|
|||
|
||||
// JIT-compile the given module and run "entryPoint" with "args" as arguments.
|
||||
static Error
|
||||
compileAndExecute(ModuleOp module, StringRef entryPoint,
|
||||
compileAndExecute(Options &options, ModuleOp module, StringRef entryPoint,
|
||||
std::function<llvm::Error(llvm::Module *)> transformer,
|
||||
void **args) {
|
||||
Optional<llvm::CodeGenOpt::Level> jitCodeGenOptLevel;
|
||||
if (auto clOptLevel = getCommandLineOptLevel())
|
||||
if (auto clOptLevel = getCommandLineOptLevel(options))
|
||||
jitCodeGenOptLevel =
|
||||
static_cast<llvm::CodeGenOpt::Level>(clOptLevel.getValue());
|
||||
SmallVector<StringRef, 4> libs(clSharedLibs.begin(), clSharedLibs.end());
|
||||
SmallVector<StringRef, 4> libs(options.clSharedLibs.begin(),
|
||||
options.clSharedLibs.end());
|
||||
auto expectedEngine = mlir::ExecutionEngine::create(module, transformer,
|
||||
jitCodeGenOptLevel, libs);
|
||||
if (!expectedEngine)
|
||||
|
@ -146,9 +151,10 @@ compileAndExecute(ModuleOp module, StringRef entryPoint,
|
|||
if (!expectedFPtr)
|
||||
return expectedFPtr.takeError();
|
||||
|
||||
if (dumpObjectFile)
|
||||
engine->dumpToObjectFile(objectFilename.empty() ? inputFilename + ".o"
|
||||
: objectFilename);
|
||||
if (options.dumpObjectFile)
|
||||
engine->dumpToObjectFile(options.objectFilename.empty()
|
||||
? options.inputFilename + ".o"
|
||||
: options.objectFilename);
|
||||
|
||||
void (*fptr)(void **) = *expectedFPtr;
|
||||
(*fptr)(args);
|
||||
|
@ -157,17 +163,17 @@ compileAndExecute(ModuleOp module, StringRef entryPoint,
|
|||
}
|
||||
|
||||
static Error compileAndExecuteVoidFunction(
|
||||
ModuleOp module, StringRef entryPoint,
|
||||
Options &options, ModuleOp module, StringRef entryPoint,
|
||||
std::function<llvm::Error(llvm::Module *)> transformer) {
|
||||
auto mainFunction = module.lookupSymbol<LLVM::LLVMFuncOp>(entryPoint);
|
||||
if (!mainFunction || mainFunction.getBlocks().empty())
|
||||
return make_string_error("entry point not found");
|
||||
void *empty = nullptr;
|
||||
return compileAndExecute(module, entryPoint, transformer, &empty);
|
||||
return compileAndExecute(options, module, entryPoint, transformer, &empty);
|
||||
}
|
||||
|
||||
static Error compileAndExecuteSingleFloatReturnFunction(
|
||||
ModuleOp module, StringRef entryPoint,
|
||||
Options &options, ModuleOp module, StringRef entryPoint,
|
||||
std::function<llvm::Error(llvm::Module *)> transformer) {
|
||||
auto mainFunction = module.lookupSymbol<LLVM::LLVMFuncOp>(entryPoint);
|
||||
if (!mainFunction || mainFunction.isExternal())
|
||||
|
@ -184,28 +190,30 @@ static Error compileAndExecuteSingleFloatReturnFunction(
|
|||
void *data;
|
||||
} data;
|
||||
data.data = &res;
|
||||
if (auto error =
|
||||
compileAndExecute(module, entryPoint, transformer, (void **)&data))
|
||||
if (auto error = compileAndExecute(options, module, entryPoint, transformer,
|
||||
(void **)&data))
|
||||
return error;
|
||||
|
||||
// Intentional printing of the output so we can test.
|
||||
llvm::outs() << res << '\n';
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
// Entry point for all CPU runners. Expects the common argc/argv arguments for
|
||||
// standard C++ main functions and an mlirTransformer.
|
||||
// The latter is applied after parsing the input into MLIR IR and before passing
|
||||
// the MLIR module to the ExecutionEngine.
|
||||
/// Entry point for all CPU runners. Expects the common argc/argv arguments for
|
||||
/// standard C++ main functions and an mlirTransformer.
|
||||
/// The latter is applied after parsing the input into MLIR IR and before
|
||||
/// passing the MLIR module to the ExecutionEngine.
|
||||
int mlir::JitRunnerMain(
|
||||
int argc, char **argv,
|
||||
function_ref<LogicalResult(mlir::ModuleOp)> mlirTransformer) {
|
||||
// Create the options struct containing the command line options for the
|
||||
// runner. This must come before the command line options are parsed.
|
||||
Options options;
|
||||
llvm::cl::ParseCommandLineOptions(argc, argv, "MLIR CPU execution driver\n");
|
||||
|
||||
Optional<unsigned> optLevel = getCommandLineOptLevel();
|
||||
Optional<unsigned> optLevel = getCommandLineOptLevel(options);
|
||||
SmallVector<std::reference_wrapper<llvm::cl::opt<bool>>, 4> optFlags{
|
||||
optO0, optO1, optO2, optO3};
|
||||
options.optO0, options.optO1, options.optO2, options.optO3};
|
||||
unsigned optCLIPosition = 0;
|
||||
// Determine if there is an optimization flag present, and its CLI position
|
||||
// (optCLIPosition).
|
||||
|
@ -220,16 +228,16 @@ int mlir::JitRunnerMain(
|
|||
// insert any optimization passes in that vector (optPosition).
|
||||
SmallVector<const llvm::PassInfo *, 4> passes;
|
||||
unsigned optPosition = 0;
|
||||
for (unsigned i = 0, e = llvmPasses.size(); i < e; ++i) {
|
||||
passes.push_back(llvmPasses[i]);
|
||||
if (optCLIPosition < llvmPasses.getPosition(i)) {
|
||||
for (unsigned i = 0, e = options.llvmPasses.size(); i < e; ++i) {
|
||||
passes.push_back(options.llvmPasses[i]);
|
||||
if (optCLIPosition < options.llvmPasses.getPosition(i)) {
|
||||
optPosition = i;
|
||||
optCLIPosition = UINT_MAX; // To ensure we never insert again
|
||||
}
|
||||
}
|
||||
|
||||
MLIRContext context;
|
||||
auto m = parseMLIRInput(inputFilename, &context);
|
||||
auto m = parseMLIRInput(options.inputFilename, &context);
|
||||
if (!m) {
|
||||
llvm::errs() << "could not parse the input IR\n";
|
||||
return 1;
|
||||
|
@ -254,17 +262,19 @@ int mlir::JitRunnerMain(
|
|||
passes, optLevel, /*targetMachine=*/tmOrError->get(), optPosition);
|
||||
|
||||
// Get the function used to compile and execute the module.
|
||||
using CompileAndExecuteFnT = Error (*)(
|
||||
ModuleOp, StringRef, std::function<llvm::Error(llvm::Module *)>);
|
||||
using CompileAndExecuteFnT =
|
||||
Error (*)(Options &, ModuleOp, StringRef,
|
||||
std::function<llvm::Error(llvm::Module *)>);
|
||||
auto compileAndExecuteFn =
|
||||
llvm::StringSwitch<CompileAndExecuteFnT>(mainFuncType.getValue())
|
||||
llvm::StringSwitch<CompileAndExecuteFnT>(options.mainFuncType.getValue())
|
||||
.Case("f32", compileAndExecuteSingleFloatReturnFunction)
|
||||
.Case("void", compileAndExecuteVoidFunction)
|
||||
.Default(nullptr);
|
||||
|
||||
Error error =
|
||||
compileAndExecuteFn
|
||||
? compileAndExecuteFn(m.get(), mainFuncName.getValue(), transformer)
|
||||
? compileAndExecuteFn(options, m.get(),
|
||||
options.mainFuncName.getValue(), transformer)
|
||||
: make_string_error("unsupported function type");
|
||||
|
||||
int exitCode = EXIT_SUCCESS;
|
||||
|
|
Loading…
Reference in New Issue