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