[clang] 869385b - [flang][driver] Add support for `-O{0|1|2|3}`

Andrzej Warzynski via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 27 03:09:11 PDT 2022


Author: Andrzej Warzynski
Date: 2022-06-27T10:06:14Z
New Revision: 869385b11c32032d02f5f24fcd21c694fb073850

URL: https://github.com/llvm/llvm-project/commit/869385b11c32032d02f5f24fcd21c694fb073850
DIFF: https://github.com/llvm/llvm-project/commit/869385b11c32032d02f5f24fcd21c694fb073850.diff

LOG: [flang][driver] Add support for `-O{0|1|2|3}`

This patch adds support for most common optimisation compiler flags:
`-O{0|1|2|3}`. This is implemented in both the compiler and frontend
drivers. At this point, these options are only used to configure the
LLVM optimisation pipelines (aka middle-end). LLVM backend or MLIR/FIR
optimisations are not supported yet.

Previously, the middle-end pass manager was only required when
generating LLVM bitcode (i.e. for `flang-new -c -emit-llvm <file>` or
`flang-new -fc1 -emit-llvm-bc <file>`). With this change, it becomes
required for all frontend actions that are represented as
`CodeGenAction` and `CodeGenAction::executeAction` is refactored
accordingly (in the spirit of better code re-use).

Additionally, the `-fdebug-pass-manager` option is enabled to facilitate
testing. This flag can be used to configure the pass manager to print
the middle-end passes that are being run. Similar option exists in Clang
and the semantics in Flang are identical. This option translates to
extra configuration when setting up the pass manager. This is
implemented in `CodeGenAction::runOptimizationPipeline`.

This patch also adds some bolier plate code to manage code-gen options
("code-gen" refers to generating machine code in LLVM in this context).
This was extracted from Clang. In Clang, it simplifies defining code-gen
options and enables option marshalling. In Flang, option marshalling is
not yet supported (we might do at some point), but being able to
auto-generate some code with macros is beneficial. This will become
particularly apparent when we start adding more options (at least in
Clang, the list of code-gen options is rather long).

Differential Revision: https://reviews.llvm.org/D128043

Added: 
    flang/include/flang/Frontend/CodeGenOptions.def
    flang/include/flang/Frontend/CodeGenOptions.h
    flang/lib/Frontend/CodeGenOptions.cpp
    flang/test/Driver/default-optimization-pipelines.f90
    flang/test/Driver/flang_f_opts.f90

Modified: 
    clang/include/clang/Driver/Options.td
    clang/lib/Driver/ToolChains/Flang.cpp
    flang/include/flang/Frontend/CompilerInvocation.h
    flang/include/flang/Frontend/FrontendActions.h
    flang/lib/Frontend/CMakeLists.txt
    flang/lib/Frontend/CompilerInvocation.cpp
    flang/lib/Frontend/FrontendActions.cpp
    flang/test/Driver/driver-help.f90

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 5d5f886ea7534..06c7e415384cd 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -721,14 +721,14 @@ def MV : Flag<["-"], "MV">, Group<M_Group>, Flags<[CC1Option]>,
     MarshallingInfoFlag<DependencyOutputOpts<"OutputFormat">, "DependencyOutputFormat::Make">,
     Normalizer<"makeFlagToValueNormalizer(DependencyOutputFormat::NMake)">;
 def Mach : Flag<["-"], "Mach">, Group<Link_Group>;
-def O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[CC1Option, HelpHidden]>;
-def O4 : Flag<["-"], "O4">, Group<O_Group>, Flags<[CC1Option, HelpHidden]>;
+def O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[CC1Option, FC1Option, HelpHidden]>;
+def O4 : Flag<["-"], "O4">, Group<O_Group>, Flags<[CC1Option, FC1Option, HelpHidden]>;
 def ObjCXX : Flag<["-"], "ObjC++">, Flags<[NoXarchOption]>,
   HelpText<"Treat source input files as Objective-C++ inputs">;
 def ObjC : Flag<["-"], "ObjC">, Flags<[NoXarchOption]>,
   HelpText<"Treat source input files as Objective-C inputs">;
-def O : Joined<["-"], "O">, Group<O_Group>, Flags<[CC1Option]>;
-def O_flag : Flag<["-"], "O">, Flags<[CC1Option]>, Alias<O>, AliasArgs<["1"]>;
+def O : Joined<["-"], "O">, Group<O_Group>, Flags<[CC1Option,FC1Option]>;
+def O_flag : Flag<["-"], "O">, Flags<[CC1Option,FC1Option]>, Alias<O>, AliasArgs<["1"]>;
 def Ofast : Joined<["-"], "Ofast">, Group<O_Group>, Flags<[CC1Option]>;
 def P : Flag<["-"], "P">, Flags<[CC1Option,FlangOption,FC1Option]>, Group<Preprocessor_Group>,
   HelpText<"Disable linemarker output in -E mode">,
@@ -5473,10 +5473,6 @@ defm lto_unit : BoolOption<"f", "lto-unit",
   CodeGenOpts<"LTOUnit">, DefaultFalse,
   PosFlag<SetTrue, [CC1Option], "Emit IR to support LTO unit features (CFI, whole program vtable opt)">,
   NegFlag<SetFalse>>;
-defm debug_pass_manager : BoolOption<"f", "debug-pass-manager",
-  CodeGenOpts<"DebugPassManager">, DefaultFalse,
-  PosFlag<SetTrue, [], "Prints debug information for the new pass manager">,
-  NegFlag<SetFalse, [], "Disables debug printing for the new pass manager">>;
 def fverify_debuginfo_preserve
     : Flag<["-"], "fverify-debuginfo-preserve">,
       HelpText<"Enable Debug Info Metadata preservation testing in "
@@ -6280,6 +6276,10 @@ def load : Separate<["-"], "load">, MetaVarName<"<dsopath>">,
   HelpText<"Load the named plugin (dynamic shared object)">;
 def plugin : Separate<["-"], "plugin">, MetaVarName<"<name>">,
   HelpText<"Use the named plugin action instead of the default action (use \"help\" to list available options)">;
+defm debug_pass_manager : BoolOption<"f", "debug-pass-manager",
+  CodeGenOpts<"DebugPassManager">, DefaultFalse,
+  PosFlag<SetTrue, [], "Prints debug information for the new pass manager">,
+  NegFlag<SetFalse, [], "Disables debug printing for the new pass manager">>;
 
 } // let Flags = [CC1Option, FC1Option, NoDriverOption]
 

diff  --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index aeab9d5fc417f..3368f67857180 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -135,6 +135,16 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
     A->render(Args, CmdArgs);
   }
 
+  // Optimization level for CodeGen.
+  if (const Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+    if (A->getOption().matches(options::OPT_O4)) {
+      CmdArgs.push_back("-O3");
+      D.Diag(diag::warn_O4_is_O3);
+    } else {
+      A->render(Args, CmdArgs);
+    }
+  }
+
   if (Output.isFilename()) {
     CmdArgs.push_back("-o");
     CmdArgs.push_back(Output.getFilename());

diff  --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def
new file mode 100644
index 0000000000000..d67f3838d446e
--- /dev/null
+++ b/flang/include/flang/Frontend/CodeGenOptions.def
@@ -0,0 +1,22 @@
+//===--- CodeGenOptions.def - Code generation option database ----- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the code generation options. Users of this file
+// must define the CODEGENOPT macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+#ifndef CODEGENOPT
+#  error Define the CODEGENOPT macro to handle language options
+#endif
+
+CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.
+
+CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new
+                                   ///< pass manager.
+
+#undef CODEGENOPT

diff  --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h
new file mode 100644
index 0000000000000..fe25bfdd06aa4
--- /dev/null
+++ b/flang/include/flang/Frontend/CodeGenOptions.h
@@ -0,0 +1,52 @@
+//===--- CodeGenOptions.h ---------------------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the CodeGenOptions interface, which holds the
+//  configuration for LLVM's middle-end and back-end. It controls LLVM's code
+//  generation into assembly or machine code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_CODEGENOPTIONS_H
+#define LLVM_CLANG_BASIC_CODEGENOPTIONS_H
+
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace Fortran::frontend {
+
+/// Bitfields of CodeGenOptions, split out from CodeGenOptions to ensure
+/// that this large collection of bitfields is a trivial class type.
+class CodeGenOptionsBase {
+
+public:
+#define CODEGENOPT(Name, Bits, Default) unsigned Name : Bits;
+#include "flang/Frontend/CodeGenOptions.def"
+
+protected:
+#define CODEGENOPT(Name, Bits, Default)
+#include "flang/Frontend/CodeGenOptions.def"
+};
+
+/// Tracks various options which control how the code is optimized and passed
+/// to the LLVM backend.
+class CodeGenOptions : public CodeGenOptionsBase {
+
+public:
+  CodeGenOptions();
+};
+
+} // end namespace Fortran::frontend
+
+#endif

diff  --git a/flang/include/flang/Frontend/CompilerInvocation.h b/flang/include/flang/Frontend/CompilerInvocation.h
index 55fd5a039b475..cdc7878e93c31 100644
--- a/flang/include/flang/Frontend/CompilerInvocation.h
+++ b/flang/include/flang/Frontend/CompilerInvocation.h
@@ -13,6 +13,7 @@
 #ifndef FORTRAN_FRONTEND_COMPILERINVOCATION_H
 #define FORTRAN_FRONTEND_COMPILERINVOCATION_H
 
+#include "flang/Frontend/CodeGenOptions.h"
 #include "flang/Frontend/FrontendOptions.h"
 #include "flang/Frontend/PreprocessorOptions.h"
 #include "flang/Frontend/TargetOptions.h"
@@ -70,6 +71,9 @@ class CompilerInvocation : public CompilerInvocationBase {
   /// Options controlling the target.
   Fortran::frontend::TargetOptions targetOpts;
 
+  /// Options controlling IRgen and the backend.
+  Fortran::frontend::CodeGenOptions codeGenOpts;
+
   // Semantics context
   std::unique_ptr<Fortran::semantics::SemanticsContext> semanticsContext;
 
@@ -129,6 +133,9 @@ class CompilerInvocation : public CompilerInvocationBase {
   TargetOptions &getTargetOpts() { return targetOpts; }
   const TargetOptions &getTargetOpts() const { return targetOpts; }
 
+  CodeGenOptions &getCodeGenOpts() { return codeGenOpts; }
+  const CodeGenOptions &getCodeGenOpts() const { return codeGenOpts; }
+
   Fortran::semantics::SemanticsContext &getSemanticsContext() {
     return *semanticsContext;
   }

diff  --git a/flang/include/flang/Frontend/FrontendActions.h b/flang/include/flang/Frontend/FrontendActions.h
index 586932df92ad3..975aaa0b9da27 100644
--- a/flang/include/flang/Frontend/FrontendActions.h
+++ b/flang/include/flang/Frontend/FrontendActions.h
@@ -13,6 +13,7 @@
 #ifndef FORTRAN_FRONTEND_FRONTENDACTIONS_H
 #define FORTRAN_FRONTEND_FRONTENDACTIONS_H
 
+#include "flang/Frontend/CodeGenOptions.h"
 #include "flang/Frontend/FrontendAction.h"
 #include "flang/Parser/parsing.h"
 #include "flang/Semantics/semantics.h"
@@ -198,7 +199,11 @@ class CodeGenAction : public FrontendAction {
   void executeAction() override;
   /// Runs prescan, parsing, sema and lowers to MLIR.
   bool beginSourceFileAction() override;
+  /// Sets up LLVM's TargetMachine, configures llvmModule accordingly.
   void setUpTargetMachine();
+  /// Runs the optimization (aka middle-end) pipeline on the LLVM module
+  /// associated with this action.
+  void runOptimizationPipeline(llvm::raw_pwrite_stream &os);
 
 protected:
   CodeGenAction(BackendActionTy act) : action{act} {};

diff  --git a/flang/lib/Frontend/CMakeLists.txt b/flang/lib/Frontend/CMakeLists.txt
index 476dff0a76cfa..96769c707f102 100644
--- a/flang/lib/Frontend/CMakeLists.txt
+++ b/flang/lib/Frontend/CMakeLists.txt
@@ -3,6 +3,7 @@ get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
 add_flang_library(flangFrontend
   CompilerInstance.cpp
   CompilerInvocation.cpp
+  CodeGenOptions.cpp
   FrontendAction.cpp
   FrontendActions.cpp
   FrontendOptions.cpp

diff  --git a/flang/lib/Frontend/CodeGenOptions.cpp b/flang/lib/Frontend/CodeGenOptions.cpp
new file mode 100644
index 0000000000000..87641d94f8c80
--- /dev/null
+++ b/flang/lib/Frontend/CodeGenOptions.cpp
@@ -0,0 +1,23 @@
+//===--- CodeGenOptions.cpp -----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Frontend/CodeGenOptions.h"
+#include <string.h>
+
+namespace Fortran::frontend {
+
+CodeGenOptions::CodeGenOptions() {
+#define CODEGENOPT(Name, Bits, Default) Name = Default;
+#include "flang/Frontend/CodeGenOptions.def"
+}
+
+} // end namespace Fortran::frontend

diff  --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index f665daf7a9b10..f6fde9f4aaf56 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -12,6 +12,7 @@
 
 #include "flang/Frontend/CompilerInvocation.h"
 #include "flang/Common/Fortran-features.h"
+#include "flang/Frontend/CodeGenOptions.h"
 #include "flang/Frontend/PreprocessorOptions.h"
 #include "flang/Frontend/TargetOptions.h"
 #include "flang/Semantics/semantics.h"
@@ -20,6 +21,7 @@
 #include "clang/Basic/DiagnosticDriver.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/OptionUtils.h"
 #include "clang/Driver/Options.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSwitch.h"
@@ -95,6 +97,18 @@ bool Fortran::frontend::parseDiagnosticArgs(clang::DiagnosticOptions &opts,
   return true;
 }
 
+static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
+                             llvm::opt::ArgList &args,
+                             clang::DiagnosticsEngine &diags) {
+  unsigned defaultOpt = llvm::CodeGenOpt::None;
+  opts.OptimizationLevel = clang::getLastArgIntValue(
+      args, clang::driver::options::OPT_O, defaultOpt, diags);
+
+  if (args.hasFlag(clang::driver::options::OPT_fdebug_pass_manager,
+                   clang::driver::options::OPT_fno_debug_pass_manager, false))
+    opts.DebugPassManager = 1;
+}
+
 /// Parses all target input arguments and populates the target
 /// options accordingly.
 ///
@@ -616,6 +630,7 @@ bool CompilerInvocation::createFromArgs(
   success &= parseFrontendArgs(res.getFrontendOpts(), args, diags);
   parseTargetArgs(res.getTargetOpts(), args);
   parsePreprocessorArgs(res.getPreprocessorOpts(), args);
+  parseCodeGenArgs(res.getCodeGenOpts(), args, diags);
   success &= parseSemaArgs(res, args, diags);
   success &= parseDialectArgs(res, args, diags);
   success &= parseDiagArgs(res, args, diags);

diff  --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index a842420be887a..ae7150900ecf0 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -46,6 +46,7 @@
 #include "llvm/IRReader/IRReader.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Passes/PassBuilder.h"
+#include "llvm/Passes/StandardInstrumentations.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Target/TargetMachine.h"
@@ -538,7 +539,6 @@ void CodeGenAction::setUpTargetMachine() {
                                           /*Features=*/"",
                                           llvm::TargetOptions(), llvm::None));
   assert(tm && "Failed to create TargetMachine");
-  llvmModule->setDataLayout(tm->createDataLayout());
 }
 
 static std::unique_ptr<llvm::raw_pwrite_stream>
@@ -610,23 +610,59 @@ static void generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags,
   codeGenPasses.run(llvmModule);
 }
 
-/// Generate LLVM byte code file from the input LLVM module.
-///
-/// \param [in] tm Target machine to aid the code-gen pipeline set-up
-/// \param [in] llvmModule LLVM module to lower to assembly/machine-code
-/// \param [out] os Output stream to emit the generated code to
-static void generateLLVMBCImpl(llvm::TargetMachine &tm,
-                               llvm::Module &llvmModule,
-                               llvm::raw_pwrite_stream &os) {
-  // Set-up the pass manager
-  llvm::ModulePassManager mpm;
+static llvm::OptimizationLevel
+mapToLevel(const Fortran::frontend::CodeGenOptions &opts) {
+  switch (opts.OptimizationLevel) {
+  default:
+    llvm_unreachable("Invalid optimization level!");
+  case 0:
+    return llvm::OptimizationLevel::O0;
+  case 1:
+    return llvm::OptimizationLevel::O1;
+  case 2:
+    return llvm::OptimizationLevel::O2;
+  case 3:
+    return llvm::OptimizationLevel::O3;
+  }
+}
+
+void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
+  auto opts = getInstance().getInvocation().getCodeGenOpts();
+  llvm::OptimizationLevel level = mapToLevel(opts);
+
+  // Create the analysis managers.
+  llvm::LoopAnalysisManager lam;
+  llvm::FunctionAnalysisManager fam;
+  llvm::CGSCCAnalysisManager cgam;
   llvm::ModuleAnalysisManager mam;
-  llvm::PassBuilder pb(&tm);
+
+  // Create the pass manager builder.
+  llvm::PassInstrumentationCallbacks pic;
+  llvm::PipelineTuningOptions pto;
+  llvm::Optional<llvm::PGOOptions> pgoOpt;
+  llvm::StandardInstrumentations si(opts.DebugPassManager);
+  si.registerCallbacks(pic, &fam);
+  llvm::PassBuilder pb(tm.get(), pto, pgoOpt, &pic);
+
+  // Register all the basic analyses with the managers.
   pb.registerModuleAnalyses(mam);
-  mpm.addPass(llvm::BitcodeWriterPass(os));
+  pb.registerCGSCCAnalyses(cgam);
+  pb.registerFunctionAnalyses(fam);
+  pb.registerLoopAnalyses(lam);
+  pb.crossRegisterProxies(lam, fam, cgam, mam);
+
+  // Create the pass manager.
+  llvm::ModulePassManager mpm;
+  if (opts.OptimizationLevel == 0)
+    mpm = pb.buildO0DefaultPipeline(level, false);
+  else
+    mpm = pb.buildPerModuleDefaultPipeline(level);
 
-  // run the passes
-  mpm.run(llvmModule, mam);
+  if (action == BackendActionTy::Backend_EmitBC)
+    mpm.addPass(llvm::BitcodeWriterPass(os));
+
+  // Run the passes.
+  mpm.run(*llvmModule, mam);
 }
 
 void CodeGenAction::executeAction() {
@@ -661,11 +697,14 @@ void CodeGenAction::executeAction() {
     return;
   }
 
-  // generate an LLVM module if it's not already present (it will already be
+  // Generate an LLVM module if it's not already present (it will already be
   // present if the input file is an LLVM IR/BC file).
   if (!llvmModule)
     generateLLVMIR();
 
+  // Run LLVM's middle-end (i.e. the optimizer).
+  runOptimizationPipeline(*os);
+
   if (action == BackendActionTy::Backend_EmitLL) {
     llvmModule->print(ci.isOutputStreamNull() ? *os : ci.getOutputStream(),
                       /*AssemblyAnnotationWriter=*/nullptr);
@@ -673,11 +712,14 @@ void CodeGenAction::executeAction() {
   }
 
   setUpTargetMachine();
+  llvmModule->setDataLayout(tm->createDataLayout());
+
   if (action == BackendActionTy::Backend_EmitBC) {
-    generateLLVMBCImpl(*tm, *llvmModule, *os);
+    // This action has effectively been completed in runOptimizationPipeline.
     return;
   }
 
+  // Run LLVM's backend and generate either assembly or machine code
   if (action == BackendActionTy::Backend_EmitAssembly ||
       action == BackendActionTy::Backend_EmitObj) {
     generateMachineCodeOrAssemblyImpl(

diff  --git a/flang/test/Driver/default-optimization-pipelines.f90 b/flang/test/Driver/default-optimization-pipelines.f90
new file mode 100644
index 0000000000000..d46acf4965be6
--- /dev/null
+++ b/flang/test/Driver/default-optimization-pipelines.f90
@@ -0,0 +1,27 @@
+! Verify that`-O{n}` is indeed taken into account when defining the LLVM optimization/middle-end pass pipeline.
+
+!-----------
+! RUN LINES
+!-----------
+! RUN: %flang -S -O0 %s -Xflang -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O0
+! RUN: %flang_fc1 -S -O0 %s -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O0
+
+! RUN: %flang -S -O2 %s -Xflang -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O2
+! RUN: %flang_fc1 -S -O2 %s -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O2
+
+!-----------------------
+! EXPECTED OUTPUT
+!-----------------------
+! CHECK-O0-NOT: Running pass: SimplifyCFGPass on simple_loop_
+! CHECK-O0: Running analysis: TargetLibraryAnalysis on simple_loop_
+
+! CHECK-O2: Running pass: SimplifyCFGPass on simple_loop_
+
+!-------
+! INPUT
+!-------
+subroutine simple_loop
+  integer :: i
+  do i=1,5
+  end do
+end subroutine

diff  --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90
index fade5abc3b2a5..9d55c0570958d 100644
--- a/flang/test/Driver/driver-help.f90
+++ b/flang/test/Driver/driver-help.f90
@@ -96,6 +96,7 @@
 ! HELP-FC1-NEXT: -fdebug-measure-parse-tree
 ! HELP-FC1-NEXT:                         Measure the parse tree
 ! HELP-FC1-NEXT: -fdebug-module-writer   Enable debug messages while writing module files
+! HELP-FC1-NEXT: -fdebug-pass-manager    Prints debug information for the new pass manage
 ! HELP-FC1-NEXT: -fdebug-pre-fir-tree    Dump the pre-FIR tree
 ! HELP-FC1-NEXT: -fdebug-unparse-no-sema Unparse and stop (skips the semantic checks)
 ! HELP-FC1-NEXT: -fdebug-unparse-with-symbols
@@ -120,6 +121,7 @@
 ! HELP-FC1-NEXT: -fno-analyzed-objects-for-unparse
 ! HELP-FC1-NEXT:                        Do not use the analyzed objects when unparsing
 ! HELP-FC1-NEXT: -fno-automatic         Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE
+! HELP-FC1-NEXT: -fno-debug-pass-manager Disables debug printing for the new pass manager
 ! HELP-FC1-NEXT: -fno-reformat          Dump the cooked character stream in -E mode
 ! HELP-FC1-NEXT: -fopenacc              Enable OpenACC
 ! HELP-FC1-NEXT: -fopenmp               Parse OpenMP pragmas and generate parallel code.

diff  --git a/flang/test/Driver/flang_f_opts.f90 b/flang/test/Driver/flang_f_opts.f90
new file mode 100644
index 0000000000000..d06e2a342d7da
--- /dev/null
+++ b/flang/test/Driver/flang_f_opts.f90
@@ -0,0 +1,14 @@
+! Test for warnings generated when parsing driver options. You can use this file for relatively small tests and to avoid creating
+! new test files.
+
+!-----------
+! RUN LINES
+!-----------
+! RUN: %flang -### -S -O4 %s 2>&1 | FileCheck %s
+
+!-----------------------
+! EXPECTED OUTPUT
+!-----------------------
+! CHECK: warning: -O4 is equivalent to -O3
+! CHECK-LABEL: "-fc1"
+! CHECK: -O3


        


More information about the cfe-commits mailing list