r290450 - [PM] Introduce options to enable the (still experimental) new pass

Justin Bogner via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 10 13:36:39 PST 2017


Chandler Carruth via cfe-commits <cfe-commits at lists.llvm.org> writes:
> Author: chandlerc
> Date: Fri Dec 23 14:44:01 2016
> New Revision: 290450
>
> URL: http://llvm.org/viewvc/llvm-project?rev=290450&view=rev
> Log:
> [PM] Introduce options to enable the (still experimental) new pass
> manager, and a code path to use it.
>
> The option is actually a top-level option but does contain
> 'experimental' in the name. This is the compromise suggested by Richard
> in discussions. We expect this option will be around long enough and
> have enough users towards the end that it merits not being relegated to
> CC1, but it still needs to be clear that this option will go away at
> some point.

I don't really understand why this is a driver option and not just a CC1
option. Using a driver flag makes me think we expect people to be using
this in production before we make the new PM the default, which seems
kind of questionable to me, and I don't see how adding a new
"-fexperimental" is any better than just using the "-Xclang" that people
are already familiar with the implications of.

> The backend code is a fresh codepath dedicated to handling the flow with
> the new pass manager. This was also Richard's suggested code structuring
> to essentially leave a clean path for development rather than carrying
> complexity or idiosyncracies of how we do things just to share code with
> the parts of this in common with the legacy pass manager. And it turns
> out, not much is really in common even though we use the legacy pass
> manager for codegen at this point.
>
> I've switched a couple of tests to run with the new pass manager, and
> they appear to work. There are still plenty of bugs that need squashing
> (just with basic experiments I've found two already!) but they aren't in
> this code, and the whole point is to expose the necessary hooks to start
> experimenting with the pass manager in more realistic scenarios.
>
> That said, I want to *strongly caution* anyone itching to play with
> this: it is still *very shaky*. Several large components have not yet
> been shaken down. For example I have bugs in both the always inliner and
> inliner that I have already spotted and will be fixing independently.
>
> Still, this is a fun milestone. =D
>
> One thing not in this patch (but that might be very reasonable to add)
> is some level of support for raw textual pass pipelines such as what
> Sean had a patch for some time ago. I'm mostly interested in the more
> traditional flow of getting the IR out of Clang and then running it
> through opt, but I can see other use cases so someone may want to add
> it.
>
> And of course, *many* features are not yet supported!
> - O1 is currently more like O2
> - None of the sanitizers are wired up
> - ObjC ARC optimizer isn't wired up
> - ...
>
> So plenty of stuff still lef to do!
>
> Differential Revision: https://reviews.llvm.org/D28077
>
> Modified:
>     cfe/trunk/include/clang/Driver/Options.td
>     cfe/trunk/include/clang/Frontend/CodeGenOptions.def
>     cfe/trunk/lib/CodeGen/BackendUtil.cpp
>     cfe/trunk/lib/Driver/Tools.cpp
>     cfe/trunk/lib/Frontend/CompilerInvocation.cpp
>     cfe/trunk/test/CodeGen/arm64_crypto.c
>     cfe/trunk/test/CodeGen/inline-optim.c
>     cfe/trunk/test/Driver/clang_f_opts.c
>
> Modified: cfe/trunk/include/clang/Driver/Options.td
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=290450&r1=290449&r2=290450&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Driver/Options.td (original)
> +++ cfe/trunk/include/clang/Driver/Options.td Fri Dec 23 14:44:01 2016
> @@ -823,6 +823,9 @@ def finline_functions : Flag<["-"], "fin
>  def finline_hint_functions: Flag<["-"], "finline-hint-functions">, Group<f_clang_Group>, Flags<[CC1Option]>,
>    HelpText<"Inline functions wich are (explicitly or implicitly) marked inline">;
>  def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>;
> +def fexperimental_new_pass_manager : Flag<["-"], "fexperimental-new-pass-manager">,
> +  Group<f_clang_Group>, Flags<[CC1Option]>,
> +  HelpText<"Enables an experimental new pass manager in LLVM.">;
>  def finput_charset_EQ : Joined<["-"], "finput-charset=">, Group<f_Group>;
>  def fexec_charset_EQ : Joined<["-"], "fexec-charset=">, Group<f_Group>;
>  def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>,
> @@ -1000,6 +1003,9 @@ def fno_exceptions : Flag<["-"], "fno-ex
>  def fno_gnu_keywords : Flag<["-"], "fno-gnu-keywords">, Group<f_Group>, Flags<[CC1Option]>;
>  def fno_inline_functions : Flag<["-"], "fno-inline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>;
>  def fno_inline : Flag<["-"], "fno-inline">, Group<f_clang_Group>, Flags<[CC1Option]>;
> +def fno_experimental_new_pass_manager : Flag<["-"], "fno-experimental-new-pass-manager">,
> +  Group<f_clang_Group>, Flags<[CC1Option]>,
> +  HelpText<"Disables an experimental new pass manager in LLVM.">;
>  def fveclib : Joined<["-"], "fveclib=">, Group<f_Group>, Flags<[CC1Option]>,
>      HelpText<"Use the given vector functions library">;
>  def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group<f_Group>,
>
> Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.def
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.def?rev=290450&r1=290449&r2=290450&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Frontend/CodeGenOptions.def (original)
> +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def Fri Dec 23 14:44:01 2016
> @@ -52,6 +52,8 @@ CODEGENOPT(DisableGCov       , 1, 0) ///
>  CODEGENOPT(DisableLLVMPasses , 1, 0) ///< Don't run any LLVM IR passes to get
>                                       ///< the pristine IR generated by the
>                                       ///< frontend.
> +CODEGENOPT(ExperimentalNewPassManager, 1, 0) ///< Enables the new, experimental
> +                                             ///< pass manager.
>  CODEGENOPT(DisableRedZone    , 1, 0) ///< Set when -mno-red-zone is enabled.
>  CODEGENOPT(DisableTailCalls  , 1, 0) ///< Do not emit tail calls.
>  CODEGENOPT(EmitDeclMetadata  , 1, 0) ///< Emit special metadata indicating what
>
> Modified: cfe/trunk/lib/CodeGen/BackendUtil.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/BackendUtil.cpp?rev=290450&r1=290449&r2=290450&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/BackendUtil.cpp (original)
> +++ cfe/trunk/lib/CodeGen/BackendUtil.cpp Fri Dec 23 14:44:01 2016
> @@ -20,20 +20,21 @@
>  #include "llvm/ADT/Triple.h"
>  #include "llvm/Analysis/TargetLibraryInfo.h"
>  #include "llvm/Analysis/TargetTransformInfo.h"
> -#include "llvm/Bitcode/BitcodeWriterPass.h"
> -#include "llvm/Bitcode/BitcodeWriter.h"
>  #include "llvm/Bitcode/BitcodeReader.h"
> +#include "llvm/Bitcode/BitcodeWriter.h"
> +#include "llvm/Bitcode/BitcodeWriterPass.h"
>  #include "llvm/CodeGen/RegAllocRegistry.h"
>  #include "llvm/CodeGen/SchedulerRegistry.h"
>  #include "llvm/IR/DataLayout.h"
> -#include "llvm/IR/ModuleSummaryIndex.h"
>  #include "llvm/IR/IRPrintingPasses.h"
>  #include "llvm/IR/LegacyPassManager.h"
>  #include "llvm/IR/Module.h"
> +#include "llvm/IR/ModuleSummaryIndex.h"
>  #include "llvm/IR/Verifier.h"
>  #include "llvm/LTO/LTOBackend.h"
>  #include "llvm/MC/SubtargetFeature.h"
>  #include "llvm/Object/ModuleSummaryIndexObjectFile.h"
> +#include "llvm/Passes/PassBuilder.h"
>  #include "llvm/Support/CommandLine.h"
>  #include "llvm/Support/MemoryBuffer.h"
>  #include "llvm/Support/PrettyStackTrace.h"
> @@ -114,6 +115,9 @@ public:
>  
>    void EmitAssembly(BackendAction Action,
>                      std::unique_ptr<raw_pwrite_stream> OS);
> +
> +  void EmitAssemblyWithNewPassManager(BackendAction Action,
> +                                      std::unique_ptr<raw_pwrite_stream> OS);
>  };
>  
>  // We need this wrapper to access LangOpts and CGOpts from extension functions
> @@ -709,6 +713,134 @@ void EmitAssemblyHelper::EmitAssembly(Ba
>    }
>  }
>  
> +static PassBuilder::OptimizationLevel mapToLevel(const CodeGenOptions &Opts) {
> +  switch (Opts.OptimizationLevel) {
> +  default:
> +    llvm_unreachable("Invalid optimization level!");
> +
> +  case 1:
> +    return PassBuilder::O1;
> +
> +  case 2:
> +    switch (Opts.OptimizeSize) {
> +    default:
> +      llvm_unreachable("Invalide optimization level for size!");
> +
> +    case 0:
> +      return PassBuilder::O2;
> +
> +    case 1:
> +      return PassBuilder::Os;
> +
> +    case 2:
> +      return PassBuilder::Oz;
> +    }
> +
> +  case 3:
> +    return PassBuilder::O3;
> +  }
> +}
> +
> +/// A clean version of `EmitAssembly` that uses the new pass manager.
> +///
> +/// Not all features are currently supported in this system, but where
> +/// necessary it falls back to the legacy pass manager to at least provide
> +/// basic functionality.
> +///
> +/// This API is planned to have its functionality finished and then to replace
> +/// `EmitAssembly` at some point in the future when the default switches.
> +void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
> +    BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS) {
> +  TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);
> +  setCommandLineOpts();
> +
> +  // The new pass manager always makes a target machine available to passes
> +  // during construction.
> +  CreateTargetMachine(/*MustCreateTM*/ true);
> +  if (!TM)
> +    // This will already be diagnosed, just bail.
> +    return;
> +  TheModule->setDataLayout(TM->createDataLayout());
> +
> +  PassBuilder PB(TM.get());
> +
> +  LoopAnalysisManager LAM;
> +  FunctionAnalysisManager FAM;
> +  CGSCCAnalysisManager CGAM;
> +  ModuleAnalysisManager MAM;
> +
> +  // Register the AA manager first so that our version is the one used.
> +  FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });
> +
> +  // Register all the basic analyses with the managers.
> +  PB.registerModuleAnalyses(MAM);
> +  PB.registerCGSCCAnalyses(CGAM);
> +  PB.registerFunctionAnalyses(FAM);
> +  PB.registerLoopAnalyses(LAM);
> +  PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
> +
> +  ModulePassManager MPM;
> +  if (CodeGenOpts.OptimizationLevel == 0) {
> +    // Build a minimal pipeline based on the semantics required by Clang, which
> +    // is just that always inlining occurs.
> +    MPM.addPass(AlwaysInlinerPass());
> +  } else {
> +    // Otherwise, use the default pass pipeline. We also have to map our
> +    // optimization levels into one of the distinct levels used to configure
> +    // the pipeline.
> +    PassBuilder::OptimizationLevel Level = mapToLevel(CodeGenOpts);
> +
> +    MPM = PB.buildPerModuleDefaultPipeline(Level);
> +  }
> +
> +  // FIXME: We still use the legacy pass manager to do code generation. We
> +  // create that pass manager here and use it as needed below.
> +  legacy::PassManager CodeGenPasses;
> +  bool NeedCodeGen = false;
> +
> +  // Append any output we need to the pass manager.
> +  switch (Action) {
> +  case Backend_EmitNothing:
> +    break;
> +
> +  case Backend_EmitBC:
> +    MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
> +                                  CodeGenOpts.EmitSummaryIndex,
> +                                  CodeGenOpts.EmitSummaryIndex));
> +    break;
> +
> +  case Backend_EmitLL:
> +    MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists));
> +    break;
> +
> +  case Backend_EmitAssembly:
> +  case Backend_EmitMCNull:
> +  case Backend_EmitObj:
> +    NeedCodeGen = true;
> +    CodeGenPasses.add(
> +        createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
> +    if (!AddEmitPasses(CodeGenPasses, Action, *OS))
> +      // FIXME: Should we handle this error differently?
> +      return;
> +    break;
> +  }
> +
> +  // Before executing passes, print the final values of the LLVM options.
> +  cl::PrintOptionValues();
> +
> +  // Now that we have all of the passes ready, run them.
> +  {
> +    PrettyStackTraceString CrashInfo("Optimizer");
> +    MPM.run(*TheModule, MAM);
> +  }
> +
> +  // Now if needed, run the legacy PM for codegen.
> +  if (NeedCodeGen) {
> +    PrettyStackTraceString CrashInfo("Code generation");
> +    CodeGenPasses.run(*TheModule);
> +  }
> +}
> +
>  static void runThinLTOBackend(const CodeGenOptions &CGOpts, Module *M,
>                                std::unique_ptr<raw_pwrite_stream> OS) {
>    // If we are performing a ThinLTO importing compile, load the function index
> @@ -801,7 +933,10 @@ void clang::EmitBackendOutput(Diagnostic
>  
>    EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);
>  
> -  AsmHelper.EmitAssembly(Action, std::move(OS));
> +  if (CGOpts.ExperimentalNewPassManager)
> +    AsmHelper.EmitAssemblyWithNewPassManager(Action, std::move(OS));
> +  else
> +    AsmHelper.EmitAssembly(Action, std::move(OS));
>  
>    // Verify clang's TargetInfo DataLayout against the LLVM TargetMachine's
>    // DataLayout.
>
> Modified: cfe/trunk/lib/Driver/Tools.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=290450&r1=290449&r2=290450&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Driver/Tools.cpp (original)
> +++ cfe/trunk/lib/Driver/Tools.cpp Fri Dec 23 14:44:01 2016
> @@ -5909,6 +5909,9 @@ void Clang::ConstructJob(Compilation &C,
>                                         options::OPT_fno_inline_functions))
>      InlineArg->render(Args, CmdArgs);
>  
> +  Args.AddLastArg(CmdArgs, options::OPT_fexperimental_new_pass_manager,
> +                  options::OPT_fno_experimental_new_pass_manager);
> +
>    ObjCRuntime objcRuntime = AddObjCRuntimeArgs(Args, CmdArgs, rewriteKind);
>  
>    // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and
>
> Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=290450&r1=290449&r2=290450&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
> +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Fri Dec 23 14:44:01 2016
> @@ -462,6 +462,10 @@ static bool ParseCodeGenArgs(CodeGenOpti
>      }
>    }
>  
> +  Opts.ExperimentalNewPassManager = Args.hasFlag(
> +      OPT_fexperimental_new_pass_manager, OPT_fno_experimental_new_pass_manager,
> +      /* Default */ false);
> +
>    if (Arg *A = Args.getLastArg(OPT_fveclib)) {
>      StringRef Name = A->getValue();
>      if (Name == "Accelerate")
>
> Modified: cfe/trunk/test/CodeGen/arm64_crypto.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm64_crypto.c?rev=290450&r1=290449&r2=290450&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGen/arm64_crypto.c (original)
> +++ cfe/trunk/test/CodeGen/arm64_crypto.c Fri Dec 23 14:44:01 2016
> @@ -1,4 +1,5 @@
>  // RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon -target-feature +crypto -ffreestanding -Os -S -o - %s | FileCheck %s
> +// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon -target-feature +crypto -ffreestanding -fexperimental-new-pass-manager -Os -S -o - %s | FileCheck %s
>  // REQUIRES: aarch64-registered-target
>  
>  #include <arm_neon.h>
>
> Modified: cfe/trunk/test/CodeGen/inline-optim.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/inline-optim.c?rev=290450&r1=290449&r2=290450&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGen/inline-optim.c (original)
> +++ cfe/trunk/test/CodeGen/inline-optim.c Fri Dec 23 14:44:01 2016
> @@ -1,9 +1,13 @@
>  // Make sure -finline-functions family flags are behaving correctly.
>  
>  // RUN: %clang_cc1 -triple i686-pc-win32 -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s
> +// RUN: %clang_cc1 -triple i686-pc-win32 -fexperimental-new-pass-manager -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s
>  // RUN: %clang_cc1 -triple i686-pc-win32 -O3 -fno-inline-functions -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s
> +// RUN: %clang_cc1 -triple i686-pc-win32 -fexperimental-new-pass-manager -O3 -fno-inline-functions -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s
>  // RUN: %clang_cc1 -triple i686-pc-win32 -O3 -finline-hint-functions -emit-llvm %s -o - | FileCheck -check-prefix=HINT %s
> +// RUN: %clang_cc1 -triple i686-pc-win32 -fexperimental-new-pass-manager -O3 -finline-hint-functions -emit-llvm %s -o - | FileCheck -check-prefix=HINT %s
>  // RUN: %clang_cc1 -triple i686-pc-win32 -O3 -finline-functions -emit-llvm %s -o - | FileCheck -check-prefix=INLINE %s
> +// RUN: %clang_cc1 -triple i686-pc-win32 -fexperimental-new-pass-manager -O3 -finline-functions -emit-llvm %s -o - | FileCheck -check-prefix=INLINE %s
>  
>  inline int inline_hint(int a, int b) { return(a+b); }
>  
>
> Modified: cfe/trunk/test/Driver/clang_f_opts.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/clang_f_opts.c?rev=290450&r1=290449&r2=290450&view=diff
> ==============================================================================
> --- cfe/trunk/test/Driver/clang_f_opts.c (original)
> +++ cfe/trunk/test/Driver/clang_f_opts.c Fri Dec 23 14:44:01 2016
> @@ -469,3 +469,11 @@
>  // CHECK-WCHAR2: -fshort-wchar
>  // CHECK-WCHAR2-NOT: -fno-short-wchar
>  // DELIMITERS: {{^ *"}}
> +
> +// RUN: %clang -### -fno-experimental-new-pass-manager -fexperimental-new-pass-manager %s 2>&1 | FileCheck --check-prefix=CHECK-PM --check-prefix=CHECK-NEW-PM %s
> +// RUN: %clang -### -fexperimental-new-pass-manager -fno-experimental-new-pass-manager %s 2>&1 | FileCheck --check-prefix=CHECK-PM --check-prefix=CHECK-NO-NEW-PM %s
> +// CHECK-PM-NOT: argument unused
> +// CHECK-NEW-PM: -fexperimental-new-pass-manager
> +// CHECK-NEW-PM-NOT: -fno-experimental-new-pass-manager
> +// CHECK-NO-NEW-PM: -fno-experimental-new-pass-manager
> +// CHECK-NO-NEW-PM-NOT: -fexperimental-new-pass-manager
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


More information about the cfe-commits mailing list