diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/Passes/PassBuilder.h | 7 | ||||
-rw-r--r-- | llvm/lib/Passes/PassBuilder.cpp | 81 | ||||
-rw-r--r-- | llvm/test/Other/new-pm-pgo-O0.ll | 21 |
3 files changed, 87 insertions, 22 deletions
diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h index 5e6660599f9..f73e4b42dd4 100644 --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -629,6 +629,12 @@ public: TopLevelPipelineParsingCallbacks.push_back(C); } + /// Add PGOInstrumenation passes for O0 only. + void addPGOInstrPassesForO0(ModulePassManager &MPM, bool DebugLogging, + bool RunProfileGen, bool IsCS, + std::string ProfileFile, + std::string ProfileRemappingFile); + private: static Optional<std::vector<PipelineElement>> parsePipelineText(StringRef Text); @@ -660,7 +666,6 @@ private: OptimizationLevel Level, bool RunProfileGen, bool IsCS, std::string ProfileFile, std::string ProfileRemappingFile); - void invokePeepholeEPCallbacks(FunctionPassManager &, OptimizationLevel); // Extension Point callbacks diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index eef94bf9012..6cb6afa00d8 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -541,6 +541,7 @@ void PassBuilder::addPGOInstrPasses(ModulePassManager &MPM, bool DebugLogging, bool RunProfileGen, bool IsCS, std::string ProfileFile, std::string ProfileRemappingFile) { + assert(Level != O0 && "Not expecting O0 here!"); // 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 @@ -571,34 +572,62 @@ void PassBuilder::addPGOInstrPasses(ModulePassManager &MPM, bool DebugLogging, CGPipeline.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM))); MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPipeline))); + + // Delete anything that is now dead to make sure that we don't instrument + // dead code. Instrumentation can end up keeping dead code around and + // dramatically increase code size. + MPM.addPass(GlobalDCEPass()); } - // Delete anything that is now dead to make sure that we don't instrument - // dead code. Instrumentation can end up keeping dead code around and - // dramatically increase code size. - MPM.addPass(GlobalDCEPass()); + if (!RunProfileGen) { + assert(!ProfileFile.empty() && "Profile use expecting a profile file!"); + MPM.addPass(PGOInstrumentationUse(ProfileFile, ProfileRemappingFile, IsCS)); + // Cache ProfileSummaryAnalysis once to avoid the potential need to insert + // RequireAnalysisPass for PSI before subsequent non-module passes. + MPM.addPass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>()); + return; + } - if (RunProfileGen) { - MPM.addPass(PGOInstrumentationGen(IsCS)); + // Perform PGO instrumentation. + MPM.addPass(PGOInstrumentationGen(IsCS)); - FunctionPassManager FPM; - FPM.addPass( - createFunctionToLoopPassAdaptor(LoopRotatePass(), DebugLogging)); - MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); - - // Add the profile lowering pass. - InstrProfOptions Options; - if (!ProfileFile.empty()) - Options.InstrProfileOutput = ProfileFile; - Options.DoCounterPromotion = true; - Options.UseBFIInPromotion = IsCS; - MPM.addPass(InstrProfiling(Options, IsCS)); - } else if (!ProfileFile.empty()) { + FunctionPassManager FPM; + FPM.addPass(createFunctionToLoopPassAdaptor(LoopRotatePass(), DebugLogging)); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); + + // Add the profile lowering pass. + InstrProfOptions Options; + if (!ProfileFile.empty()) + Options.InstrProfileOutput = ProfileFile; + // Do counter promotion at Level greater than O0. + Options.DoCounterPromotion = true; + Options.UseBFIInPromotion = IsCS; + MPM.addPass(InstrProfiling(Options, IsCS)); +} + +void PassBuilder::addPGOInstrPassesForO0(ModulePassManager &MPM, + bool DebugLogging, bool RunProfileGen, + bool IsCS, std::string ProfileFile, + std::string ProfileRemappingFile) { + if (!RunProfileGen) { + assert(!ProfileFile.empty() && "Profile use expecting a profile file!"); MPM.addPass(PGOInstrumentationUse(ProfileFile, ProfileRemappingFile, IsCS)); // Cache ProfileSummaryAnalysis once to avoid the potential need to insert // RequireAnalysisPass for PSI before subsequent non-module passes. MPM.addPass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>()); + return; } + + // Perform PGO instrumentation. + MPM.addPass(PGOInstrumentationGen(IsCS)); + // Add the profile lowering pass. + InstrProfOptions Options; + if (!ProfileFile.empty()) + Options.InstrProfileOutput = ProfileFile; + // Do not do counter promotion at O0. + Options.DoCounterPromotion = false; + Options.UseBFIInPromotion = IsCS; + MPM.addPass(InstrProfiling(Options, IsCS)); } static InlineParams @@ -1801,9 +1830,19 @@ Error PassBuilder::parseModulePass(ModulePassManager &MPM, .Case("O3", O3) .Case("Os", Os) .Case("Oz", Oz); - if (L == O0) - // At O0 we do nothing at all! + if (L == O0) { + // Add instrumentation PGO passes -- at O0 we can still do PGO. + if (PGOOpt && Matches[1] != "thinlto" && + (PGOOpt->Action == PGOOptions::IRInstr || + PGOOpt->Action == PGOOptions::IRUse)) + addPGOInstrPassesForO0( + MPM, DebugLogging, + /* RunProfileGen */ (PGOOpt->Action == PGOOptions::IRInstr), + /* IsCS */ false, PGOOpt->ProfileFile, + PGOOpt->ProfileRemappingFile); + // Do nothing else at all! return Error::success(); + } if (Matches[1] == "default") { MPM.addPass(buildPerModuleDefaultPipeline(L, DebugLogging)); diff --git a/llvm/test/Other/new-pm-pgo-O0.ll b/llvm/test/Other/new-pm-pgo-O0.ll new file mode 100644 index 00000000000..6a6da67bb12 --- /dev/null +++ b/llvm/test/Other/new-pm-pgo-O0.ll @@ -0,0 +1,21 @@ +; RUN: opt -debug-pass-manager -passes='default<O0>' -pgo-kind=pgo-instr-gen-pipeline -profile-file='temp' %s 2>&1 |FileCheck %s --check-prefixes=GEN +; RUN: llvm-profdata merge %S/Inputs/new-pm-pgo.proftext -o %t.profdata +; RUN: opt -debug-pass-manager -passes='default<O0>' -pgo-kind=pgo-instr-use-pipeline -profile-file='%t.profdata' %s 2>&1 |FileCheck %s --check-prefixes=USE_DEFAULT,USE +; RUN: opt -debug-pass-manager -passes='thinlto-pre-link<O0>' -pgo-kind=pgo-instr-use-pipeline -profile-file='%t.profdata' %s 2>&1 \ +; RUN: |FileCheck %s --check-prefixes=USE_PRE_LINK,USE +; RUN: opt -debug-pass-manager -passes='lto-pre-link<O0>' -pgo-kind=pgo-instr-use-pipeline -profile-file='%t.profdata' %s 2>&1 \ +; RUN: |FileCheck %s --check-prefixes=USE_PRE_LINK,USE +; RUN: opt -debug-pass-manager -passes='thinlto<O0>' -pgo-kind=pgo-instr-use-pipeline -profile-file='%t.profdata' %s 2>&1 \ +; RUN: |FileCheck %s --check-prefixes=USE_POST_LINK,USE + +; +; GEN: Running pass: PGOInstrumentationGen +; USE_DEFAULT: Running pass: PGOInstrumentationUse +; USE_PRE_LINK: Running pass: PGOInstrumentationUse +; USE_POST_LINK-NOT: Running pass: PGOInstrumentationUse +; USE-NOT: Running pass: PGOIndirectCallPromotion +; USE-NOT: Running pass: PGOMemOPSizeOpt + +define void @foo() { + ret void +} |