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

Reply via email to