diff --git a/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h b/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h index a4e7bce8ef4ae..ac1602ffabd7f 100644 --- a/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h +++ b/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h @@ -133,6 +133,11 @@ class PassManagerBuilder { bool MergeFunctions; bool PrepareForLTO; + /// Profile data file name that the instrumentation will be written to. + std::string PGOInstrGen; + /// Path of the profile data file. + std::string PGOInstrUse; + private: /// ExtensionList - This is list of all of the extensions that are registered. std::vector > Extensions; @@ -152,6 +157,7 @@ class PassManagerBuilder { void addInitialAliasAnalysisPasses(legacy::PassManagerBase &PM) const; void addLTOOptimizationPasses(legacy::PassManagerBase &PM); void addLateLTOOptimizationPasses(legacy::PassManagerBase &PM); + void addPGOInstrPasses(legacy::PassManagerBase &MPM); public: /// populateFunctionPassManager - This fills in the function pass manager, diff --git a/llvm/lib/Transforms/IPO/LLVMBuild.txt b/llvm/lib/Transforms/IPO/LLVMBuild.txt index b5410f5f77577..bc3df98d504ca 100644 --- a/llvm/lib/Transforms/IPO/LLVMBuild.txt +++ b/llvm/lib/Transforms/IPO/LLVMBuild.txt @@ -20,4 +20,4 @@ type = Library name = IPO parent = Transforms library_name = ipo -required_libraries = Analysis Core InstCombine IRReader Linker Object ProfileData Scalar Support TransformUtils Vectorize +required_libraries = Analysis Core InstCombine IRReader Linker Object ProfileData Scalar Support TransformUtils Vectorize Instrumentation diff --git a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp index b5b948b3001cf..9d4fa68c67ca8 100644 --- a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -34,6 +34,7 @@ #include "llvm/Transforms/IPO/InferFunctionAttrs.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Vectorize.h" +#include "llvm/Transforms/Instrumentation.h" using namespace llvm; @@ -105,6 +106,16 @@ static cl::opt EnableLoopLoadElim( "enable-loop-load-elim", cl::init(false), cl::Hidden, cl::desc("Enable the new, experimental LoopLoadElimination Pass")); +static cl::opt RunPGOInstrGen( + "profile-generate", cl::init(""), cl::Hidden, + cl::desc("Enable generation phase of PGO instrumentation and specify the " + "path of profile data file")); + +static cl::opt RunPGOInstrUse( + "profile-use", cl::init(""), cl::Hidden, cl::value_desc("filename"), + cl::desc("Enable use phase of PGO instrumentation and specify the path " + "of profile data file")); + PassManagerBuilder::PassManagerBuilder() { OptLevel = 2; SizeLevel = 0; @@ -123,6 +134,8 @@ PassManagerBuilder::PassManagerBuilder() { VerifyOutput = false; MergeFunctions = false; PrepareForLTO = false; + PGOInstrGen = RunPGOInstrGen; + PGOInstrUse = RunPGOInstrUse; } PassManagerBuilder::~PassManagerBuilder() { @@ -186,6 +199,19 @@ void PassManagerBuilder::populateFunctionPassManager( FPM.add(createLowerExpectIntrinsicPass()); } +// Do PGO instrumentation generation or use pass as the option specified. +void PassManagerBuilder::addPGOInstrPasses(legacy::PassManagerBase &MPM) { + if (!PGOInstrGen.empty()) { + MPM.add(createPGOInstrumentationGenPass()); + // Add the profile lowering pass. + InstrProfOptions Options; + Options.InstrProfileOutput = PGOInstrGen; + MPM.add(createInstrProfilingPass(Options)); + } + if (!PGOInstrUse.empty()) + MPM.add(createPGOInstrumentationUsePass(PGOInstrUse)); +} + void PassManagerBuilder::populateModulePassManager( legacy::PassManagerBase &MPM) { // Allow forcing function attributes as a debugging and tuning aid. @@ -194,6 +220,7 @@ void PassManagerBuilder::populateModulePassManager( // If all optimizations are disabled, just run the always-inline pass and, // if enabled, the function merging pass. if (OptLevel == 0) { + addPGOInstrPasses(MPM); if (Inliner) { MPM.add(Inliner); Inliner = nullptr; @@ -237,6 +264,8 @@ void PassManagerBuilder::populateModulePassManager( MPM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE } + addPGOInstrPasses(MPM); + if (EnableNonLTOGlobalsModRef) // We add a module alias analysis pass here. In part due to bugs in the // analysis infrastructure this "works" in that the analysis stays alive