[Mlir-commits] [mlir] 293c521 - [mlir][NFC] Wrap the cl::opts in JitRunner within a struct to avoid global initializers.

River Riddle llvmlistbot at llvm.org
Wed Apr 8 18:38:50 PDT 2020


Author: River Riddle
Date: 2020-04-08T18:33:37-07:00
New Revision: 293c5210ecb53d706b3d144f9a295a002774ea67

URL: https://github.com/llvm/llvm-project/commit/293c5210ecb53d706b3d144f9a295a002774ea67
DIFF: https://github.com/llvm/llvm-project/commit/293c5210ecb53d706b3d144f9a295a002774ea67.diff

LOG: [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

Added: 
    

Modified: 
    mlir/lib/Support/JitRunner.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Support/JitRunner.cpp b/mlir/lib/Support/JitRunner.cpp
index 066dfae75c44..13d53bce2a49 100644
--- a/mlir/lib/Support/JitRunner.cpp
+++ b/mlir/lib/Support/JitRunner.cpp
@@ -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"));
-
-static 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 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));
-
-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));
-
-// 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)."));
-
-static llvm::cl::opt<std::string> objectFilename(
-    "object-filename",
-    llvm::cl::desc("Dump JITted-compiled object to file <input file>.o"));
+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")};
+
+  llvm::cl::OptionCategory optFlags{"opt-like flags"};
+
+  // 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.
+  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)};
+
+  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.
+  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).")};
+
+  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;


        


More information about the Mlir-commits mailing list