tobiasvk created this revision.
Herald added subscribers: eraman, inglorion.

With https://reviews.llvm.org/D33921, we gained the ability to have module 
summaries in regular
LTO modules without triggering ThinLTO compilation. There is however,
currently, no way to trigger the emission of a module summary with
regular LTO in Clang. This patch adds a flag -femit-summary-index which
makes that possible.

Why would you want a summary with regular LTO?

The Qualcomm Linker performs a two-phase garbage collection (a.k.a. dead
stripping): firstly, before LTO compilation, and then again afterwards.
The key advantage of already running GC before LTO is that in links that
involve a heavy mix of ELF objects and bitcode (a critical use case for
us), we can prune some of the dependences between bitcode and ELF and
thus internalize more symbols in LTO.

For this to work, the linker needs to be able to inspect the reference
graphs for bitcode modules and the module summary provides exactly that.


https://reviews.llvm.org/D34156

Files:
  clang/include/clang/Driver/Options.td
  clang/include/clang/Frontend/CodeGenOptions.def
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/emit-summary-index.c
  clang/test/Misc/thinlto.c

Index: clang/test/Misc/thinlto.c
===================================================================
--- clang/test/Misc/thinlto.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: %clang_cc1 -flto=thin -emit-llvm-bc < %s | llvm-bcanalyzer -dump | FileCheck %s
-// ; Check that the -flto=thin option emits a summary
-// CHECK: <GLOBALVAL_SUMMARY_BLOCK
-int main() {}
Index: clang/test/CodeGen/emit-summary-index.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/emit-summary-index.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -flto=thin -emit-llvm-bc < %s | llvm-bcanalyzer -dump | FileCheck %s
+// ; Check that the -flto=thin option emits a ThinLTO summary
+// CHECK: <GLOBALVAL_SUMMARY_BLOCK
+//
+// RUN: %clang_cc1 -flto -emit-llvm-bc < %s | llvm-bcanalyzer -dump | FileCheck --check-prefix=LTO %s
+// ; Check that we do not emit a summary by default for regular LTO
+// LTO-NOT: GLOBALVAL_SUMMARY_BLOCK
+//
+// RUN: %clang -flto -femit-summary-index -o - -c %s | llvm-bcanalyzer -dump | FileCheck --check-prefix=LTOINDEX %s
+// ; Check that -femit-summary-index creates a summary with regular LTO
+// RUN: %clang -emit-llvm -femit-summary-index -o - -c %s | llvm-bcanalyzer -dump | FileCheck --check-prefix=LTOINDEX %s
+// ; Check that -femit-summary-index creates a summary with -emit-llvm
+// LTOINDEX: <FULL_LTO_GLOBALVAL_SUMMARY_BLOCK
+int main() {}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -649,8 +649,10 @@
   Opts.NoUseJumpTables = Args.hasArg(OPT_fno_jump_tables);
 
   Opts.PrepareForLTO = Args.hasArg(OPT_flto, OPT_flto_EQ);
+  Opts.EmitSummaryIndex = Args.hasArg(OPT_femit_summary_index);
   const Arg *A = Args.getLastArg(OPT_flto, OPT_flto_EQ);
-  Opts.EmitSummaryIndex = A && A->containsValue("thin");
+  if (A && A->containsValue("thin"))
+    Opts.PrepareForThinLTO = Opts.EmitSummaryIndex = true;
   Opts.LTOUnit = Args.hasFlag(OPT_flto_unit, OPT_fno_lto_unit, false);
   if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
     if (IK.getLanguage() != InputKind::LLVM_IR)
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -2057,6 +2057,8 @@
     if (JA.getType() == types::TY_LLVM_BC)
       CmdArgs.push_back("-emit-llvm-uselists");
 
+    Args.AddLastArg(CmdArgs, options::OPT_femit_summary_index);
+
     if (D.isUsingLTO()) {
       Args.AddLastArg(CmdArgs, options::OPT_flto, options::OPT_flto_EQ);
 
Index: clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -486,7 +486,7 @@
     PMBuilder.Inliner = createFunctionInliningPass(
         CodeGenOpts.OptimizationLevel, CodeGenOpts.OptimizeSize,
         (!CodeGenOpts.SampleProfileFile.empty() &&
-         CodeGenOpts.EmitSummaryIndex));
+         CodeGenOpts.PrepareForThinLTO));
   }
 
   PMBuilder.OptLevel = CodeGenOpts.OptimizationLevel;
@@ -497,7 +497,7 @@
 
   PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;
   PMBuilder.MergeFunctions = CodeGenOpts.MergeFunctions;
-  PMBuilder.PrepareForThinLTO = CodeGenOpts.EmitSummaryIndex;
+  PMBuilder.PrepareForThinLTO = CodeGenOpts.PrepareForThinLTO;
   PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO;
   PMBuilder.RerollLoops = CodeGenOpts.RerollLoops;
 
@@ -738,7 +738,7 @@
     break;
 
   case Backend_EmitBC:
-    if (CodeGenOpts.EmitSummaryIndex) {
+    if (CodeGenOpts.PrepareForThinLTO) {
       if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
         std::error_code EC;
         ThinLinkOS.reset(new llvm::raw_fd_ostream(
@@ -752,10 +752,13 @@
       }
       PerModulePasses.add(
           createWriteThinLTOBitcodePass(*OS, ThinLinkOS.get()));
-    }
-    else
+    } else {
+      if (CodeGenOpts.EmitSummaryIndex)
+         TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
       PerModulePasses.add(
-          createBitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists));
+          createBitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
+                                  CodeGenOpts.EmitSummaryIndex));
+    }
     break;
 
   case Backend_EmitLL:
@@ -907,7 +910,7 @@
     break;
 
   case Backend_EmitBC:
-    if (CodeGenOpts.EmitSummaryIndex) {
+    if (CodeGenOpts.PrepareForThinLTO) {
       if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
         std::error_code EC;
         ThinLinkOS.emplace(CodeGenOpts.ThinLinkBitcodeFile, EC,
@@ -921,8 +924,9 @@
       MPM.addPass(
           ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &*ThinLinkOS : nullptr));
     } else {
+      if (CodeGenOpts.EmitSummaryIndex)
+         TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
       MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
-                                    CodeGenOpts.EmitSummaryIndex,
                                     CodeGenOpts.EmitSummaryIndex));
     }
     break;
Index: clang/include/clang/Frontend/CodeGenOptions.def
===================================================================
--- clang/include/clang/Frontend/CodeGenOptions.def
+++ clang/include/clang/Frontend/CodeGenOptions.def
@@ -88,8 +88,10 @@
                                      ///< be generated.
 CODEGENOPT(PrepareForLTO     , 1, 0) ///< Set when -flto is enabled on the
                                      ///< compile step.
-CODEGENOPT(EmitSummaryIndex, 1, 0)   ///< Set when -flto=thin is enabled on the
+CODEGENOPT(PrepareForThinLTO , 1, 0) ///< Set when -flto=thin is enabled on the
                                      ///< compile step.
+CODEGENOPT(EmitSummaryIndex  , 1, 0) ///< Emit a module summary. This is enabled
+                                     ///< by default for ThinLTO.
 CODEGENOPT(LTOUnit, 1, 0) ///< Emit IR to support LTO unit features (CFI, whole
                           ///< program vtable opt).
 CODEGENOPT(IncrementalLinkerCompatible, 1, 0) ///< Emit an object file which can
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1013,6 +1013,8 @@
 def fthinlto_index_EQ : Joined<["-"], "fthinlto-index=">,
   Flags<[CC1Option]>, Group<f_Group>,
   HelpText<"Perform ThinLTO importing using provided function summary index">;
+def femit_summary_index : Flag<["-"], "femit-summary-index">, Group<f_Group>,
+  Flags<[CC1Option]>, HelpText<"Emit a module summary (default for ThinLTO)">;
 def fmacro_backtrace_limit_EQ : Joined<["-"], "fmacro-backtrace-limit=">,
                                 Group<f_Group>, Flags<[DriverOption, CoreOption]>;
 def fmerge_all_constants : Flag<["-"], "fmerge-all-constants">, Group<f_Group>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to