diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3264,6 +3264,8 @@ def mllvm : Separate<["-"], "mllvm">,Flags<[CC1Option,CC1AsOption,CoreOption,FC1Option,FlangOption]>, HelpText<"Additional arguments to forward to LLVM's option processing">, MarshallingInfoStringVector>; +def mmlir : Separate<["-"], "mmlir">, Flags<[CoreOption,FC1Option,FlangOption]>, + HelpText<"Additional arguments to forward to MLIR's option processing">; def ffuchsia_api_level_EQ : Joined<["-"], "ffuchsia-api-level=">, Group, Flags<[CC1Option]>, HelpText<"Set Fuchsia API level">, MarshallingInfoInt>; diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -113,6 +113,11 @@ A->render(Args, CmdArgs); } + for (const Arg *A : Args.filtered(options::OPT_mmlir)) { + A->claim(); + A->render(Args, CmdArgs); + } + if (Output.isFilename()) { CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); diff --git a/flang/include/flang/Frontend/FrontendOptions.h b/flang/include/flang/Frontend/FrontendOptions.h --- a/flang/include/flang/Frontend/FrontendOptions.h +++ b/flang/include/flang/Frontend/FrontendOptions.h @@ -273,6 +273,10 @@ /// should only be used for debugging and experimental features. std::vector llvmArgs; + /// A list of arguments to forward to MLIR's option processing; this + /// should only be used for debugging and experimental features. + std::vector mlirArgs; + // Return the appropriate input kind for a file extension. For example, /// "*.f" would return Language::Fortran. /// diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -597,6 +597,9 @@ res.frontendOpts_.llvmArgs = args.getAllArgValues(clang::driver::options::OPT_mllvm); + res.frontendOpts_.mlirArgs = + args.getAllArgValues(clang::driver::options::OPT_mmlir); + return success; } diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -427,6 +427,7 @@ // Create the pass pipeline fir::createMLIRToLLVMPassPipeline(pm); + mlir::applyPassManagerCLOptions(pm); // Run the pass manager if (!mlir::succeeded(pm.run(*mlirModule))) { diff --git a/flang/lib/FrontendTool/CMakeLists.txt b/flang/lib/FrontendTool/CMakeLists.txt --- a/flang/lib/FrontendTool/CMakeLists.txt +++ b/flang/lib/FrontendTool/CMakeLists.txt @@ -11,6 +11,7 @@ flangFrontend clangBasic clangDriver + MLIRPass LINK_COMPONENTS Option diff --git a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp --- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -19,6 +19,8 @@ #include "llvm/Option/Option.h" #include "llvm/Support/BuryPointer.h" #include "llvm/Support/CommandLine.h" +#include "mlir/IR/MLIRContext.h" +#include "mlir/Pass/PassManager.h" namespace Fortran::frontend { @@ -150,6 +152,21 @@ llvm::cl::ParseCommandLineOptions(numArgs + 1, args.get()); } + // Honor -mmlir. This should happen AFTER plugins have been loaded! + if (!flang->frontendOpts().mlirArgs.empty()) { + mlir::registerMLIRContextCLOptions(); + mlir::registerPassManagerCLOptions(); + unsigned numArgs = flang->frontendOpts().mlirArgs.size(); + auto args = std::make_unique(numArgs + 2); + args[0] = "flang (MLIR option parsing)"; + + for (unsigned i = 0; i != numArgs; ++i) + args[i + 1] = flang->frontendOpts().mlirArgs[i].c_str(); + + args[numArgs + 1] = nullptr; + llvm::cl::ParseCommandLineOptions(numArgs + 1, args.get()); + } + // If there were errors in processing arguments, don't do anything else. if (flang->diagnostics().hasErrorOccurred()) { return false; diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90 --- a/flang/test/Driver/driver-help-hidden.f90 +++ b/flang/test/Driver/driver-help-hidden.f90 @@ -48,6 +48,7 @@ ! CHECK-NEXT: -help Display available options ! CHECK-NEXT: -I Add directory to the end of the list of include search paths ! CHECK-NEXT: -mllvm Additional arguments to forward to LLVM's option processing +! CHECK-NEXT: -mmlir Additional arguments to forward to MLIR's option processing ! CHECK-NEXT: -module-dir Put MODULE files in ! CHECK-NEXT: -nocpp Disable predefined and command line preprocessor macros ! CHECK-NEXT: -o Write output to diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 --- a/flang/test/Driver/driver-help.f90 +++ b/flang/test/Driver/driver-help.f90 @@ -48,6 +48,7 @@ ! HELP-NEXT: -help Display available options ! HELP-NEXT: -I Add directory to the end of the list of include search paths ! HELP-NEXT: -mllvm Additional arguments to forward to LLVM's option processing +! HELP-NEXT: -mmlir Additional arguments to forward to MLIR's option processing ! HELP-NEXT: -module-dir Put MODULE files in ! HELP-NEXT: -nocpp Disable predefined and command line preprocessor macros ! HELP-NEXT: -o Write output to @@ -124,6 +125,7 @@ ! HELP-FC1-NEXT: -I Add directory to the end of the list of include search paths ! HELP-FC1-NEXT: -load Load the named plugin (dynamic shared object) ! HELP-FC1-NEXT: -mllvm Additional arguments to forward to LLVM's option processing +! HELP-FC1-NEXT: -mmlir Additional arguments to forward to MLIR's option processing ! HELP-FC1-NEXT: -module-dir Put MODULE files in ! HELP-FC1-NEXT: -module-suffix Use as the suffix for module files (the default value is `.mod`) ! HELP-FC1-NEXT: -nocpp Disable predefined and command line preprocessor macros diff --git a/flang/test/Driver/mllvm_vs_mmlir.f90 b/flang/test/Driver/mllvm_vs_mmlir.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Driver/mllvm_vs_mmlir.f90 @@ -0,0 +1,19 @@ +! Verify that `-mllvm` options are forwarded to LLVM and `-mmlir` to MLIR. + +! In practice, '-mmlir --help' is a super-set of '-mllvm --help' and that limits what we can test here. With a better seperation of +! LLVM, MLIR and Flang global options, we should be able to write a stricter test. + +!------------ +! RUN COMMAND +!------------ +! RUN: %flang_fc1 -mmlir --help | FileCheck %s --check-prefix=MLIR +! RUN: %flang_fc1 -mllvm --help | FileCheck %s --check-prefix=MLLVM + +!---------------- +! EXPECTED OUTPUT +!---------------- +! MLIR: flang (MLIR option parsing) [options] +! MLIR: --mlir-{{.*}} + +! MLLVM: flang (LLVM option parsing) [options] +! MLLVM-NOT: --mlir-{{.*}}