Index: include/llvm/Passes/PassBuilder.h =================================================================== --- include/llvm/Passes/PassBuilder.h +++ include/llvm/Passes/PassBuilder.h @@ -276,6 +276,11 @@ /// returns false. bool parseAAPipeline(AAManager &AA, StringRef PipelineText); + // PGO tunables. + std::string ProfileGenFile = ""; + std::string ProfileUseFile = ""; + bool RunProfileGen = false; + private: /// A struct to capture parsed pass pipeline names. struct PipelineElement { Index: lib/Passes/PassBuilder.cpp =================================================================== --- lib/Passes/PassBuilder.cpp +++ lib/Passes/PassBuilder.cpp @@ -376,6 +376,59 @@ return FPM; } +static void addPGOInstrPasses(ModulePassManager &MPM, bool DebugLogging, + PassBuilder::OptimizationLevel Level, + bool RunProfileGen, std::string ProfileGenFile, + std::string ProfileUseFile) { + if (!RunProfileGen && ProfileUseFile.empty()) + return; + + // In the old pass manager we ran the preinline and cleanup passes only at + // -O1 and above. There's no such thing as running optimizations at -O0 in + // the new pass manager, so we can skip that. + // We skip this step if we're optimizing for size. + 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) { @@ -426,6 +479,13 @@ GlobalCleanupPM.addPass(SimplifyCFGPass()); MPM.addPass(createModuleToFunctionPassAdaptor(std::move(GlobalCleanupPM))); + // Add all the requested passes for PGO Instrumentation, if requested. + addPGOInstrPasses(MPM, DebugLogging, Level, this->RunProfileGen, + this->ProfileGenFile, this->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