[llvm] r292863 - [PM] Flesh out the new pass manager LTO pipeline.

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 23 16:57:40 PST 2017


Author: davide
Date: Mon Jan 23 18:57:39 2017
New Revision: 292863

URL: http://llvm.org/viewvc/llvm-project?rev=292863&view=rev
Log:
[PM] Flesh out the new pass manager LTO pipeline.

Differential Revision:  https://reviews.llvm.org/D28996

Added:
    llvm/trunk/test/Other/new-pm-lto-defaults.ll
Modified:
    llvm/trunk/lib/Passes/PassBuilder.cpp
    llvm/trunk/test/Other/new-pass-manager.ll

Modified: llvm/trunk/lib/Passes/PassBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=292863&r1=292862&r2=292863&view=diff
==============================================================================
--- llvm/trunk/lib/Passes/PassBuilder.cpp (original)
+++ llvm/trunk/lib/Passes/PassBuilder.cpp Mon Jan 23 18:57:39 2017
@@ -547,13 +547,166 @@ ModulePassManager PassBuilder::buildLTOD
   assert(Level != O0 && "Must request optimizations for the default pipeline!");
   ModulePassManager MPM(DebugLogging);
 
-  // FIXME: Finish fleshing this out to match the legacy LTO pipelines.
-  FunctionPassManager LateFPM(DebugLogging);
-  LateFPM.addPass(InstCombinePass());
-  LateFPM.addPass(SimplifyCFGPass());
+  // Remove unused virtual tables to improve the quality of code generated by
+  // whole-program devirtualization and bitset lowering.
+  MPM.addPass(GlobalDCEPass());
 
-  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(LateFPM)));
+  // Force any function attributes we want the rest of the pipeline to observe.
+  MPM.addPass(ForceFunctionAttrsPass());
 
+  // Do basic inference of function attributes from known properties of system
+  // libraries and other oracles.
+  MPM.addPass(InferFunctionAttrsPass());
+
+  if (Level > 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.
+    MPM.addPass(PGOIndirectCallPromotion(true /* InLTO */));
+
+    // 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.
+   MPM.addPass(IPSCCPPass());
+  }
+
+  // Now deduce any function attributes based in the current code.
+  MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
+              PostOrderFunctionAttrsPass()));
+
+  // Do RPO function attribute inference across the module to forward-propagate
+  // attributes where applicable.
+  // FIXME: Is this really an optimization rather than a canonicalization?
+  MPM.addPass(ReversePostOrderFunctionAttrsPass());
+
+  // Use inragne annotations on GEP indices to split globals where beneficial.
+  MPM.addPass(GlobalSplitPass());
+
+  // Run whole program optimization of virtual call when the list of callees
+  // is fixed.
+  MPM.addPass(WholeProgramDevirtPass());
+
+  // Stop here at -O1.
+  if (Level == 1)
+    return MPM;
+
+  // Optimize globals to try and fold them into constants.
+  MPM.addPass(GlobalOptPass());
+
+  // Promote any localized globals to SSA registers.
+  MPM.addPass(createModuleToFunctionPassAdaptor(PromotePass()));
+
+  // Linking modules together can lead to duplicate global constant, only
+  // keep one copy of each constant.
+  MPM.addPass(ConstantMergePass());
+
+  // Remove unused arguments from functions.
+  MPM.addPass(DeadArgumentEliminationPass());
+
+  // Reduce the code after globalopt and ipsccp.  Both can open up significant
+  // simplification opportunities, and both can propagate functions through
+  // function pointers.  When this happens, we often have to resolve varargs
+  // calls, etc, so let instcombine do this.
+  // FIXME: add peephole extensions here as the legacy PM does.
+  MPM.addPass(createModuleToFunctionPassAdaptor(InstCombinePass()));
+
+  // Note: historically, the PruneEH pass was run first to deduce nounwind and
+  // generally clean up exception handling overhead. It isn't clear this is
+  // valuable as the inliner doesn't currently care whether it is inlining an
+  // invoke or a call.
+  // Run the inliner now.
+  MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(InlinerPass()));
+
+  // Optimize globals again after we ran the inliner.
+  MPM.addPass(GlobalOptPass());
+
+  // Garbage collect dead functions.
+  // FIXME: Add ArgumentPromotion pass after once it's ported.
+  MPM.addPass(GlobalDCEPass());
+
+  FunctionPassManager FPM(DebugLogging);
+
+  // The IPO Passes may leave cruft around. Clean up after them.
+  // FIXME: add peephole extensions here as the legacy PM does.
+  FPM.addPass(InstCombinePass());
+  FPM.addPass(JumpThreadingPass());
+
+  // Break up allocas
+  FPM.addPass(SROA());
+
+  // Run a few AA driver optimizations here and now to cleanup the code.
+  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+
+  MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
+              PostOrderFunctionAttrsPass()));
+  // FIXME: here we run IP alias analysis in the legacy PM.
+
+  FunctionPassManager MainFPM;
+
+  // FIXME: once we fix LoopPass Manager, add LICM here.
+  // FIXME: once we provide support for enabling MLSM, add it here.
+  // FIXME: once we provide support for enabling NewGVN, add it here.
+  MainFPM.addPass(GVN());
+
+  // Remove dead memcpy()'s.
+  MainFPM.addPass(MemCpyOptPass());
+
+  // Nuke dead stores.
+  MainFPM.addPass(DSEPass());
+
+  // FIXME: at this point, we run a bunch of loop passes:
+  // indVarSimplify, loopDeletion, loopInterchange, loopUnrool,
+  // loopVectorize. Enable them once the remaining issue with LPM
+  // are sorted out.
+
+  MainFPM.addPass(InstCombinePass());
+  MainFPM.addPass(SimplifyCFGPass());
+  MainFPM.addPass(SCCPPass());
+  MainFPM.addPass(InstCombinePass());
+  MainFPM.addPass(BDCEPass());
+
+  // FIXME: We may want to run SLPVectorizer here.
+  // After vectorization, assume intrinsics may tell us more
+  // about pointer alignments.
+#if 0
+  MainFPM.add(AlignmentFromAssumptionsPass());
+#endif
+
+  // FIXME: Conditionally run LoadCombine here, after it's ported
+  // (in case we still have this pass, given its questionable usefulness).
+
+  // FIXME: add peephole extensions to the PM here.
+  MainFPM.addPass(InstCombinePass());
+  MainFPM.addPass(JumpThreadingPass());
+  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(MainFPM)));
+
+  // Create a function that performs CFI checks for cross-DSO calls with
+  // targets in the current module.
+  MPM.addPass(CrossDSOCFIPass());
+
+  // Lower type metadata and the type.test intrinsic. This pass supports
+  // clang's control flow integrity mechanisms (-fsanitize=cfi*) and needs
+  // to be run at link time if CFI is enabled. This pass does nothing if
+  // CFI is disabled.
+  // Enable once we add support for the summary in the new PM.
+#if 0
+  MPM.addPass(LowerTypeTestsPass(Summary ? LowerTypeTestsSummaryAction::Export :
+                                           LowerTypeTestsSummaryAction::None,
+                                Summary));
+#endif
+
+  // Add late LTO optimization passes.
+  // Delete basic blocks, which optimization passes may have killed.
+  MPM.addPass(createModuleToFunctionPassAdaptor(SimplifyCFGPass()));
+
+  // Drop bodies of available eternally objects to improve GlobalDCE.
+  MPM.addPass(EliminateAvailableExternallyPass());
+
+  // Now that we have optimized the program, discard unreachable functions.
+  MPM.addPass(GlobalDCEPass());
+
+  // FIXME: Enable MergeFuncs, conditionally, after ported, maybe.
   return MPM;
 }
 

Modified: llvm/trunk/test/Other/new-pass-manager.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pass-manager.ll?rev=292863&r1=292862&r2=292863&view=diff
==============================================================================
--- llvm/trunk/test/Other/new-pass-manager.ll (original)
+++ llvm/trunk/test/Other/new-pass-manager.ll Mon Jan 23 18:57:39 2017
@@ -384,13 +384,6 @@
 ; CHECK-O0-NEXT: Finished llvm::Module pass manager run
 
 ; RUN: opt -disable-output -disable-verify -debug-pass-manager \
-; RUN:     -passes='lto<O2>' %s 2>&1 \
-; RUN:     | FileCheck %s --check-prefix=CHECK-LTO-O2
-; CHECK-LTO-O2: Starting llvm::Module pass manager run
-; CHECK-LTO-O2: Running pass: InstCombinePass
-; CHECK-LTO-O2: Running pass: SimplifyCFGPass
-
-; RUN: opt -disable-output -disable-verify -debug-pass-manager \
 ; RUN:     -passes='repeat<3>(no-op-module)' %s 2>&1 \
 ; RUN:     | FileCheck %s --check-prefix=CHECK-REPEAT-MODULE-PASS
 ; CHECK-REPEAT-MODULE-PASS: Starting llvm::Module pass manager run

Added: llvm/trunk/test/Other/new-pm-lto-defaults.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pm-lto-defaults.ll?rev=292863&view=auto
==============================================================================
--- llvm/trunk/test/Other/new-pm-lto-defaults.ll (added)
+++ llvm/trunk/test/Other/new-pm-lto-defaults.ll Mon Jan 23 18:57:39 2017
@@ -0,0 +1,105 @@
+; Basic test for the new LTO pipeline.
+; For now the only difference is between -O1 and everything else, so
+; -O2, -O3, -Os, -Oz are the same.
+
+; RUN: opt -disable-verify -debug-pass-manager \
+; RUN:     -passes='lto<O1>' -S %s 2>&1 \
+; RUN:     | FileCheck %s --check-prefix=CHECK-O
+; RUN: opt -disable-verify -debug-pass-manager \
+; RUN:     -passes='lto<O2>' -S  %s 2>&1 \
+; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O2
+; RUN: opt -disable-verify -debug-pass-manager \
+; RUN:     -passes='lto<O3>' -S  %s 2>&1 \
+; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O2
+; RUN: opt -disable-verify -debug-pass-manager \
+; RUN:     -passes='lto<Os>' -S %s 2>&1 \
+; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O2
+; RUN: opt -disable-verify -debug-pass-manager \
+; RUN:     -passes='lto<Oz>' -S %s 2>&1 \
+; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O2
+
+; CHECK-O: Starting llvm::Module pass manager run.
+; CHECK-O-NEXT: Running pass: PassManager<llvm::Module
+; CHECK-O-NEXT: Starting llvm::Module pass manager run.
+; CHECK-O-NEXT: Running pass: GlobalDCEPass
+; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass
+; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass
+; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
+; CHECK-O2-NEXT: PGOIndirectCallPromotion
+; CHECK-O2-NEXT: Running pass: IPSCCPPass
+; CHECK-O-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor<llvm::PostOrderFunctionAttrsPass>
+; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy<llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::Module>
+; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy<llvm::AnalysisManager<llvm::Function>, llvm::Module>
+; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis
+; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy
+; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<llvm::AnalysisManager<llvm::Module>, llvm::LazyCallGraph::SCC>
+; CHECK-O-NEXT: Running analysis: AAManager
+; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
+; CHECK-O-NEXT: Running pass: ReversePostOrderFunctionAttrsPass
+; CHECK-O-NEXT: Running analysis: CallGraphAnalysis
+; CHECK-O-NEXT: Invalidating analysis: CallGraphAnalysis
+; CHECK-O-NEXT: Running pass: GlobalSplitPass
+; CHECK-O-NEXT: Running pass: WholeProgramDevirtPass
+; CHECK-O2-NEXT: Running pass: GlobalOptPass
+; CHECK-O2-NEXT: Running pass: ModuleToFunctionPassAdaptor<llvm::PromotePass>
+; CHECK-O2-NEXT: Running analysis: DominatorTreeAnalysis
+; CHECK-O2-NEXT: Running analysis: AssumptionAnalysis
+; CHECK-O2-NEXT: Running pass: ConstantMergePass
+; CHECK-O2-NEXT: Running pass: DeadArgumentEliminationPass
+; CHECK-O2-NEXT: Running pass: ModuleToFunctionPassAdaptor<llvm::InstCombinePass>
+; CHECK-O2-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor<llvm::InlinerPass>
+; CHECK-O2-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis
+; CHECK-O2-NEXT: Running pass: GlobalOptPass
+; CHECK-O2-NEXT: Running pass: GlobalDCEPass
+; CHECK-O2-NEXT: Running pass: ModuleToFunctionPassAdaptor<llvm::PassManager<llvm::Function> >
+; CHECK-O2-NEXT: Starting llvm::Function pass manager run.
+; CHECK-O2-NEXT: Running pass: InstCombinePass
+; CHECK-O2-NEXT: Running pass: JumpThreadingPass
+; CHECK-O2-NEXT: Running analysis: LazyValueAnalysis
+; CHECK-O2-NEXT: Invalidating analysis: LazyValueAnalysis
+; CHECK-O2-NEXT: Running pass: SROA on foo
+; CHECK-O2-NEXT: Finished llvm::Function pass manager run.
+; CHECK-O2-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor<llvm::PostOrderFunctionAttrsPass>
+; CHECK-O2-NEXT: Running pass: ModuleToFunctionPassAdaptor<llvm::PassManager<llvm::Function> >
+; CHECK-O2-NEXT: Running analysis: MemoryDependenceAnalysis
+; CHECK-O2-NEXT: Running analysis: TargetIRAnalysis
+; CHECK-O2-NEXT: Running analysis: DemandedBitsAnalysis
+; CHECK-O2-NEXT: Running analysis: LazyValueAnalysis
+; CHECK-O2-NEXT: Invalidating analysis: LazyValueAnalysis
+; CHECK-O2-NEXT: Running pass: CrossDSOCFIPass
+; CHECK-O2-NEXT: Running pass: ModuleToFunctionPassAdaptor<llvm::SimplifyCFGPass>
+; CHECK-O2-NEXT: Running pass: EliminateAvailableExternallyPass
+; CHECK-O2-NEXT: Running pass: GlobalDCEPass
+; CHECK-O-NEXT: Finished llvm::Module pass manager run.
+; CHECK-O-NEXT: Running pass: PrintModulePass
+
+; Make sure we get the IR back out without changes when we print the module.
+; CHECK-O-LABEL: define void @foo(i32 %n) local_unnamed_addr {
+; CHECK-O-NEXT: entry:
+; CHECK-O-NEXT:   br label %loop
+; CHECK-O:      loop:
+; CHECK-O-NEXT:   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+; CHECK-O-NEXT:   %iv.next = add i32 %iv, 1
+; CHECK-O-NEXT:   tail call void @bar()
+; CHECK-O-NEXT:   %cmp = icmp eq i32 %iv, %n
+; CHECK-O-NEXT:   br i1 %cmp, label %exit, label %loop
+; CHECK-O:      exit:
+; CHECK-O-NEXT:   ret void
+; CHECK-O-NEXT: }
+;
+; CHECK-O-NEXT: Finished llvm::Module pass manager run.
+
+declare void @bar() local_unnamed_addr
+
+define void @foo(i32 %n) local_unnamed_addr {
+entry:
+  br label %loop
+loop:
+  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+  %iv.next = add i32 %iv, 1
+  tail call void @bar()
+  %cmp = icmp eq i32 %iv, %n
+  br i1 %cmp, label %exit, label %loop
+exit:
+  ret void
+}




More information about the llvm-commits mailing list