From fad596aa8195fb390a4ff6cdc016c26007743dfa Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Wed, 25 May 2016 21:26:14 +0000 Subject: [PATCH] Move whole-program virtual call optimization pass after function attribute inference in LTO pipeline. As a result of D18634 we no longer infer certain attributes on linkonce_odr functions at compile time, and may only infer them at LTO time. The readnone attribute in particular is required for virtual constant propagation (part of whole-program virtual call optimization) to work correctly. This change moves the whole-program virtual call optimization pass after the function attribute inference passes, and enables the attribute inference passes at opt level 1, so that virtual constant propagation has a chance to work correctly for linkonce_odr functions. Differential Revision: http://reviews.llvm.org/D20643 llvm-svn: 270765 --- .../llvm/Transforms/IPO/PassManagerBuilder.h | 1 - .../lib/Transforms/IPO/PassManagerBuilder.cpp | 49 ++++++++++--------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h b/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h index 005fd38adfc4..4f483deeefe5 100644 --- a/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h +++ b/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h @@ -161,7 +161,6 @@ private: legacy::PassManagerBase &PM) const; void addInitialAliasAnalysisPasses(legacy::PassManagerBase &PM) const; void addLTOOptimizationPasses(legacy::PassManagerBase &PM); - void addEarlyLTOOptimizationPasses(legacy::PassManagerBase &PM); void addLateLTOOptimizationPasses(legacy::PassManagerBase &PM); void addPGOInstrPasses(legacy::PassManagerBase &MPM); void addFunctionSimplificationPasses(legacy::PassManagerBase &MPM); diff --git a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp index 983bae8ab1d2..96282171c9fd 100644 --- a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -567,6 +567,10 @@ void PassManagerBuilder::populateModulePassManager( } void PassManagerBuilder::addLTOOptimizationPasses(legacy::PassManagerBase &PM) { + // Remove unused virtual tables to improve the quality of code generated by + // whole-program devirtualization and bitset lowering. + PM.add(createGlobalDCEPass()); + // Provide AliasAnalysis services for optimizations. addInitialAliasAnalysisPasses(PM); @@ -579,20 +583,32 @@ void PassManagerBuilder::addLTOOptimizationPasses(legacy::PassManagerBase &PM) { // Infer attributes about declarations if possible. PM.add(createInferFunctionAttrsLegacyPass()); - // Indirect call promotion. This should promote all the targets that are left - // by the earlier promotion pass that promotes intra-module targets. - // This two-step promotion is to save the compile time. For LTO, it should - // produce the same result as if we only do promotion here. - PM.add(createPGOIndirectCallPromotionLegacyPass(true)); + if (OptLevel > 1) { + // Indirect call promotion. This should promote all the targets that are + // left by the earlier promotion pass that promotes intra-module targets. + // This two-step promotion is to save the compile time. For LTO, it should + // produce the same result as if we only do promotion here. + PM.add(createPGOIndirectCallPromotionLegacyPass(true)); - // Propagate constants at call sites into the functions they call. This - // opens opportunities for globalopt (and inlining) by substituting function - // pointers passed as arguments to direct uses of functions. - PM.add(createIPSCCPPass()); + // Propagate constants at call sites into the functions they call. This + // opens opportunities for globalopt (and inlining) by substituting function + // pointers passed as arguments to direct uses of functions. + PM.add(createIPSCCPPass()); + } - // Now that we internalized some globals, see if we can hack on them! + // Infer attributes about definitions. The readnone attribute in particular is + // required for virtual constant propagation. PM.add(createPostOrderFunctionAttrsLegacyPass()); PM.add(createReversePostOrderFunctionAttrsPass()); + + // Apply whole-program devirtualization and virtual constant propagation. + PM.add(createWholeProgramDevirtPass()); + + // That's all we need at opt level 1. + if (OptLevel == 1) + return; + + // Now that we internalized some globals, see if we can hack on them! PM.add(createGlobalOptimizerPass()); // Promote any localized global vars. PM.add(createPromoteMemoryToRegisterPass()); @@ -694,16 +710,6 @@ void PassManagerBuilder::addLTOOptimizationPasses(legacy::PassManagerBase &PM) { PM.add(createJumpThreadingPass()); } -void PassManagerBuilder::addEarlyLTOOptimizationPasses( - legacy::PassManagerBase &PM) { - // Remove unused virtual tables to improve the quality of code generated by - // whole-program devirtualization and bitset lowering. - PM.add(createGlobalDCEPass()); - - // Apply whole-program devirtualization and virtual constant propagation. - PM.add(createWholeProgramDevirtPass()); -} - void PassManagerBuilder::addLateLTOOptimizationPasses( legacy::PassManagerBase &PM) { // Delete basic blocks, which optimization passes may have killed. @@ -746,9 +752,6 @@ void PassManagerBuilder::populateLTOPassManager(legacy::PassManagerBase &PM) { PM.add(createVerifierPass()); if (OptLevel != 0) - addEarlyLTOOptimizationPasses(PM); - - if (OptLevel > 1) addLTOOptimizationPasses(PM); // Create a function that performs CFI checks for cross-DSO calls with targets