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