timshen updated this revision to Diff 104533. timshen marked 5 inline comments as done. timshen added a comment.
Added -fexperimental-new-pass-manager=off/on/debug for printing debug information. Added a Clang test. Do tell if you want me to split this patch. I didn't, becuase then I don't have to write a test for each of them. :) https://reviews.llvm.org/D34728 Files: clang/include/clang/Driver/Options.td clang/include/clang/Frontend/CodeGenOptions.def clang/include/clang/Frontend/CodeGenOptions.h clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGen/lto-newpm-pipeline.c llvm/include/llvm/Option/ArgList.h llvm/lib/Option/ArgList.cpp llvm/lib/Passes/PassBuilder.cpp llvm/test/Other/new-pm-thinlto-defaults.ll
Index: llvm/test/Other/new-pm-thinlto-defaults.ll =================================================================== --- llvm/test/Other/new-pm-thinlto-defaults.ll +++ llvm/test/Other/new-pm-thinlto-defaults.ll @@ -9,19 +9,19 @@ ; ; Prelink pipelines: ; RUN: opt -disable-verify -debug-pass-manager \ -; RUN: -passes='thinlto-pre-link<O1>' -S %s 2>&1 \ +; RUN: -passes='thinlto-pre-link<O1>,name-anon-globals' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O1,CHECK-PRELINK-O,CHECK-PRELINK-O1 ; RUN: opt -disable-verify -debug-pass-manager \ -; RUN: -passes='thinlto-pre-link<O2>' -S %s 2>&1 \ +; RUN: -passes='thinlto-pre-link<O2>,name-anon-globals' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O2,CHECK-PRELINK-O,CHECK-PRELINK-O2 ; RUN: opt -disable-verify -debug-pass-manager \ -; RUN: -passes='thinlto-pre-link<O3>' -S %s 2>&1 \ +; RUN: -passes='thinlto-pre-link<O3>,name-anon-globals' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-PRELINK-O,CHECK-PRELINK-O3 ; RUN: opt -disable-verify -debug-pass-manager \ -; RUN: -passes='thinlto-pre-link<Os>' -S %s 2>&1 \ +; RUN: -passes='thinlto-pre-link<Os>,name-anon-globals' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-Os,CHECK-PRELINK-O,CHECK-PRELINK-Os ; RUN: opt -disable-verify -debug-pass-manager \ -; RUN: -passes='thinlto-pre-link<Oz>' -S %s 2>&1 \ +; RUN: -passes='thinlto-pre-link<Oz>,name-anon-globals' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-Oz,CHECK-PRELINK-O,CHECK-PRELINK-Oz ; ; Postlink pipelines: @@ -154,7 +154,6 @@ ; CHECK-O-NEXT: Finished CGSCC pass manager run. ; CHECK-O-NEXT: Finished llvm::Module pass manager run. ; CHECK-PRELINK-O-NEXT: Running pass: GlobalOptPass -; CHECK-PRELINK-O-NEXT: Running pass: NameAnonGlobalPass ; CHECK-POSTLINK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}> ; CHECK-POSTLINK-O-NEXT: Starting llvm::Module pass manager run. ; CHECK-POSTLINK-O-NEXT: Running pass: GlobalOptPass @@ -188,6 +187,7 @@ ; CHECK-POSTLINK-O-NEXT: Running pass: ConstantMergePass ; CHECK-POSTLINK-O-NEXT: Finished llvm::Module pass manager run. ; CHECK-O-NEXT: Finished llvm::Module pass manager run. +; CHECK-PRELINK-O-NEXT: Running pass: NameAnonGlobalPass ; CHECK-O-NEXT: Running pass: PrintModulePass ; Make sure we get the IR back out without changes when we print the module. Index: llvm/lib/Passes/PassBuilder.cpp =================================================================== --- llvm/lib/Passes/PassBuilder.cpp +++ llvm/lib/Passes/PassBuilder.cpp @@ -751,9 +751,6 @@ // Reduce the size of the IR as much as possible. MPM.addPass(GlobalOptPass()); - // Rename anon globals to be able to export them in the summary. - MPM.addPass(NameAnonGlobalPass()); - return MPM; } Index: llvm/lib/Option/ArgList.cpp =================================================================== --- llvm/lib/Option/ArgList.cpp +++ llvm/lib/Option/ArgList.cpp @@ -95,21 +95,6 @@ return std::vector<std::string>(Values.begin(), Values.end()); } -void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const { - if (Arg *A = getLastArg(Id)) { - A->claim(); - A->render(*this, Output); - } -} - -void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id0, - OptSpecifier Id1) const { - if (Arg *A = getLastArg(Id0, Id1)) { - A->claim(); - A->render(*this, Output); - } -} - void ArgList::AddAllArgsExcept(ArgStringList &Output, ArrayRef<OptSpecifier> Ids, ArrayRef<OptSpecifier> ExcludeIds) const { Index: llvm/include/llvm/Option/ArgList.h =================================================================== --- llvm/include/llvm/Option/ArgList.h +++ llvm/include/llvm/Option/ArgList.h @@ -306,9 +306,13 @@ bool Default = true) const; /// AddLastArg - Render only the last argument match \p Id0, if present. - void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const; - void AddLastArg(ArgStringList &Output, OptSpecifier Id0, - OptSpecifier Id1) const; + template <typename ...OptSpecifiers> + void AddLastArg(ArgStringList &Output, OptSpecifiers ...Ids) const { + if (Arg *A = getLastArg(Ids...)) { + A->claim(); + A->render(*this, Output); + } + } /// AddAllArgsExcept - Render all arguments matching any of the given ids /// and not matching any of the excluded ids. Index: clang/test/CodeGen/lto-newpm-pipeline.c =================================================================== --- /dev/null +++ clang/test/CodeGen/lto-newpm-pipeline.c @@ -0,0 +1,26 @@ +// REQUIRES: x86-registered-target + +// RUN: %clang -target x86_64-unknown-linux-gnu -c -o /dev/null -fexperimental-new-pass-manager=debug -flto=full -O0 %s 2>&1 | FileCheck %s \ +// RUN: -check-prefix=CHECK-FULL-O0 +// RUN: %clang -target x86_64-unknown-linux-gnu -c -o /dev/null -fexperimental-new-pass-manager=debug -flto=full -O2 %s 2>&1 | FileCheck %s \ +// RUN: -check-prefix=CHECK-FULL-O2 +// RUN: %clang -target x86_64-unknown-linux-gnu -c -o /dev/null -fexperimental-new-pass-manager=debug -flto=thin -O0 %s 2>&1 | FileCheck %s \ +// RUN: -check-prefix=CHECK-THIN-O0 +// RUN: %clang -target x86_64-unknown-linux-gnu -c -o /dev/null -fexperimental-new-pass-manager=debug -flto=thin -O2 %s 2>&1 | FileCheck %s \ +// RUN: -check-prefix=CHECK-THIN-O2 + +// CHECK-FULL-O0: Running pass: AlwaysInlinerPass +// CHECK-FULL-O0-NEXT: Running pass: BitcodeWriterPass + +// CHECK-THIN-O0: Running pass: AlwaysInlinerPass +// CHECK-THIN-O0-NEXT: Running pass: NameAnonGlobalPass +// CHECK-THIN-O0-NEXT: Running pass: ThinLTOBitcodeWriterPass + +// CHECK-FULL-O2: Running pass: GlobalOptPass +// CHECK-FULL-O2: Running pass: BitcodeWriterPass + +// CHECK-THIN-O2: Running pass: GlobalOptPass +// CHECK-THIN-O2: Running pass: NameAnonGlobalPass +// CHECK-THIN-O2-NEXT: Running pass: ThinLTOBitcodeWriterPass + +void Foo() {} Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -472,9 +472,23 @@ } } - Opts.ExperimentalNewPassManager = Args.hasFlag( - OPT_fexperimental_new_pass_manager, OPT_fno_experimental_new_pass_manager, - /* Default */ false); + if (Args.hasFlag(OPT_fexperimental_new_pass_manager, + OPT_fno_experimental_new_pass_manager, false)) + Opts.setExperimentalNewPassManager(CodeGenOptions::NewPM_On); + else + Opts.setExperimentalNewPassManager(CodeGenOptions::NewPM_Off); + + if (Arg *A = Args.getLastArg(OPT_fexperimental_new_pass_manager_EQ)) { + StringRef Name = A->getValue(); + if (Name == "on") + Opts.setExperimentalNewPassManager(CodeGenOptions::NewPM_On); + else if (Name == "off") + Opts.setExperimentalNewPassManager(CodeGenOptions::NewPM_Off); + else if (Name == "debug") + Opts.setExperimentalNewPassManager(CodeGenOptions::NewPM_Debug); + else + Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name; + } if (Arg *A = Args.getLastArg(OPT_fveclib)) { StringRef Name = A->getValue(); Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -3794,7 +3794,8 @@ InlineArg->render(Args, CmdArgs); Args.AddLastArg(CmdArgs, options::OPT_fexperimental_new_pass_manager, - options::OPT_fno_experimental_new_pass_manager); + options::OPT_fno_experimental_new_pass_manager, + options::OPT_fexperimental_new_pass_manager_EQ); ObjCRuntime objcRuntime = AddObjCRuntimeArgs(Args, CmdArgs, rewriteKind); Index: clang/lib/CodeGen/BackendUtil.cpp =================================================================== --- clang/lib/CodeGen/BackendUtil.cpp +++ clang/lib/CodeGen/BackendUtil.cpp @@ -54,6 +54,7 @@ #include "llvm/Transforms/ObjCARC.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/GVN.h" +#include "llvm/Transforms/Utils/NameAnonGlobals.h" #include "llvm/Transforms/Utils/SymbolRewriter.h" #include <memory> using namespace clang; @@ -878,20 +879,33 @@ PB.registerLoopAnalyses(LAM); PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); - ModulePassManager MPM; + const bool DebugLogging = CodeGenOpts.getExperimentalNewPassManager() == + CodeGenOptions::NewPM_Debug; + ModulePassManager MPM(DebugLogging); if (!CodeGenOpts.DisableLLVMPasses) { + bool IsThinLTO = CodeGenOpts.EmitSummaryIndex; + bool IsLTO = CodeGenOpts.PrepareForLTO; + 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()); + if (IsThinLTO) + MPM.addPass(NameAnonGlobalPass()); } 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. + // Map our optimization levels into one of the distinct levels used to + // configure the pipeline. PassBuilder::OptimizationLevel Level = mapToLevel(CodeGenOpts); - MPM = PB.buildPerModuleDefaultPipeline(Level); + if (IsThinLTO) { + MPM = PB.buildThinLTOPreLinkDefaultPipeline(Level, DebugLogging); + MPM.addPass(NameAnonGlobalPass()); + } else if (IsLTO) { + MPM = PB.buildLTOPreLinkDefaultPipeline(Level, DebugLogging); + } else { + MPM = PB.buildPerModuleDefaultPipeline(Level, DebugLogging); + } } } @@ -1047,7 +1061,8 @@ Conf.CGOptLevel = getCGOptLevel(CGOpts); initTargetOptions(Conf.Options, CGOpts, TOpts, LOpts, HeaderOpts); Conf.SampleProfile = std::move(SampleProfile); - Conf.UseNewPM = CGOpts.ExperimentalNewPassManager; + Conf.UseNewPM = + CGOpts.getExperimentalNewPassManager() != CodeGenOptions::NewPM_Off; switch (Action) { case Backend_EmitNothing: Conf.PreCodeGenModuleHook = [](size_t Task, const Module &Mod) { @@ -1114,7 +1129,7 @@ EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M); - if (CGOpts.ExperimentalNewPassManager) + if (CGOpts.getExperimentalNewPassManager() != CodeGenOptions::NewPM_Off) AsmHelper.EmitAssemblyWithNewPassManager(Action, std::move(OS)); else AsmHelper.EmitAssembly(Action, std::move(OS)); Index: clang/include/clang/Frontend/CodeGenOptions.h =================================================================== --- clang/include/clang/Frontend/CodeGenOptions.h +++ clang/include/clang/Frontend/CodeGenOptions.h @@ -89,6 +89,12 @@ Embed_Marker // Embed a marker as a placeholder for bitcode. }; + enum NewPassManagerKind { + NewPM_Off, + NewPM_On, + NewPM_Debug, + }; + /// The code model to use (-mcmodel). std::string CodeModel; Index: clang/include/clang/Frontend/CodeGenOptions.def =================================================================== --- clang/include/clang/Frontend/CodeGenOptions.def +++ clang/include/clang/Frontend/CodeGenOptions.def @@ -55,8 +55,7 @@ ///< frontend. CODEGENOPT(DisableLifetimeMarkers, 1, 0) ///< Don't emit any lifetime markers CODEGENOPT(DisableO0ImplyOptNone , 1, 0) ///< Don't annonate function with optnone at O0 -CODEGENOPT(ExperimentalNewPassManager, 1, 0) ///< Enables the new, experimental - ///< pass manager. +ENUM_CODEGENOPT(ExperimentalNewPassManager, NewPassManagerKind, 2, NewPM_Off) ///< 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 Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -968,6 +968,9 @@ 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 fexperimental_new_pass_manager_EQ : Joined<["-"], "fexperimental-new-pass-manager=">, + Group<f_clang_Group>, Flags<[CC1Option]>, + HelpText<"Enables an experimental new pass manager in LLVM.">, Values<"on,off,debug">; 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]>,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits