Index: include/llvm/Passes/PassBuilder.h =================================================================== --- include/llvm/Passes/PassBuilder.h +++ include/llvm/Passes/PassBuilder.h @@ -27,6 +27,13 @@ class AAManager; class TargetMachine; +/// A struct capturing PGO tunables. +struct PGOOptions { + std::string ProfileGenFile = ""; + std::string ProfileUseFile = ""; + bool RunProfileGen = false; +}; + /// \brief This class provides access to building LLVM's passes. /// /// It's members provide the baseline state available to passes during their @@ -35,6 +42,7 @@ /// construction. class PassBuilder { TargetMachine *TM; + PGOOptions *PGOOpt; public: /// \brief LLVM-provided high-level optimization levels. @@ -123,7 +131,9 @@ Oz }; - explicit PassBuilder(TargetMachine *TM = nullptr) : TM(TM) {} + explicit PassBuilder(TargetMachine *TM = nullptr, + PGOOptions *PGOOpt = nullptr) + : TM(TM), PGOOpt(PGOOpt) {} /// \brief Cross register the analysis managers through their proxies. /// Index: lib/Passes/PassBuilder.cpp =================================================================== --- lib/Passes/PassBuilder.cpp +++ lib/Passes/PassBuilder.cpp @@ -377,6 +377,56 @@ return FPM; } +static void addPGOInstrPasses(ModulePassManager &MPM, bool DebugLogging, + PassBuilder::OptimizationLevel Level, + bool RunProfileGen, std::string ProfileGenFile, + std::string ProfileUseFile) { + // Generally running simplification passes and the inliner with an high + // threshold results in smaller executables, but there may be cases where + // the size grows, so let's be conservative here and skip this simplification + // at -Os/Oz. + if (!isOptimizingForSize(Level)) { + InlineParams IP; + + // In the old pass manager, this is a cl::opt. Should still this be one? + IP.DefaultThreshold = 75; + + // FIXME: The hint threshold has the same value used by the regular inliner. + // This should probably be lowered after performance testing. + // FIXME: this comment is cargo culted from the old pass manager, revisit). + IP.HintThreshold = 325; + + CGSCCPassManager CGPipeline(DebugLogging); + + CGPipeline.addPass(InlinerPass(IP)); + + FunctionPassManager FPM; + FPM.addPass(SROA()); + FPM.addPass(EarlyCSEPass()); // Catch trivial redundancies. + FPM.addPass(SimplifyCFGPass()); // Merge & remove basic blocks. + FPM.addPass(InstCombinePass()); // Combine silly sequences. + + // FIXME: Here the old pass manager inserts peephole extensions. + // Add them when they're supported. + CGPipeline.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM))); + + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPipeline))); + } + + if (RunProfileGen) { + MPM.addPass(PGOInstrumentationGen()); + + // Add the profile lowering pass. + InstrProfOptions Options; + if (!ProfileGenFile.empty()) + Options.InstrProfileOutput = ProfileGenFile; + MPM.addPass(InstrProfiling(Options)); + } + + if (!ProfileUseFile.empty()) + MPM.addPass(PGOInstrumentationUse(ProfileUseFile)); +} + ModulePassManager PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level, bool DebugLogging) { @@ -427,6 +477,16 @@ GlobalCleanupPM.addPass(SimplifyCFGPass()); MPM.addPass(createModuleToFunctionPassAdaptor(std::move(GlobalCleanupPM))); + // Add all the requested passes for PGO Instrumentation, if requested. + if (PGOOpt) { + assert(PGOOpt->RunProfileGen || !PGOOpt->ProfileUseFile.empty()); + addPGOInstrPasses(MPM, DebugLogging, Level, PGOOpt->RunProfileGen, + PGOOpt->ProfileGenFile, PGOOpt->ProfileUseFile); + } + + // Indirect call promotion that promotes intra-module targes only. + MPM.addPass(PGOIndirectCallPromotion()); + // FIXME: Enable this when cross-IR-unit analysis invalidation is working. #if 0 MPM.addPass(RequireAnalysisPass()); Index: test/Other/new-pm-defaults.ll =================================================================== --- test/Other/new-pm-defaults.ll +++ test/Other/new-pm-defaults.ll @@ -57,6 +57,7 @@ ; CHECK-O-NEXT: Running pass: InstCombinePass ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Finished llvm::Function pass manager run. +; CHECK-O-NEXT: Running pass: PGOIndirectCallPromotion ; CHECK-O-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor<{{.*}}LazyCallGraph{{.*}}> ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis