Chandler Carruth via cfe-commits <cfe-commits@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@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits