Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Passes/PassBuilder.cpp
Show First 20 Lines • Show All 377 Lines • ▼ Show 20 Lines | |||||
#define LOOP_ANALYSIS(NAME, CREATE_PASS) \ | #define LOOP_ANALYSIS(NAME, CREATE_PASS) \ | ||||
LAM.registerPass([&] { return CREATE_PASS; }); | LAM.registerPass([&] { return CREATE_PASS; }); | ||||
#include "PassRegistry.def" | #include "PassRegistry.def" | ||||
for (auto &C : LoopAnalysisRegistrationCallbacks) | for (auto &C : LoopAnalysisRegistrationCallbacks) | ||||
C(LAM); | C(LAM); | ||||
} | } | ||||
FunctionPassManager | FunctionPassManager PassBuilder::buildFunctionSimplificationPipeline( | ||||
PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level, | OptimizationLevel Level, LTOPhase Phase, bool DebugLogging) { | ||||
ThinLTOPhase Phase, | |||||
bool DebugLogging) { | |||||
assert(Level != O0 && "Must request optimizations!"); | assert(Level != O0 && "Must request optimizations!"); | ||||
FunctionPassManager FPM(DebugLogging); | FunctionPassManager FPM(DebugLogging); | ||||
// Form SSA out of local memory accesses after breaking apart aggregates into | // Form SSA out of local memory accesses after breaking apart aggregates into | ||||
// scalars. | // scalars. | ||||
FPM.addPass(SROA()); | FPM.addPass(SROA()); | ||||
// Catch trivial redundancies | // Catch trivial redundancies | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | FunctionPassManager PassBuilder::buildFunctionSimplificationPipeline( | ||||
LPM1.addPass(SimpleLoopUnswitchPass()); | LPM1.addPass(SimpleLoopUnswitchPass()); | ||||
LPM2.addPass(IndVarSimplifyPass()); | LPM2.addPass(IndVarSimplifyPass()); | ||||
LPM2.addPass(LoopIdiomRecognizePass()); | LPM2.addPass(LoopIdiomRecognizePass()); | ||||
for (auto &C : LateLoopOptimizationsEPCallbacks) | for (auto &C : LateLoopOptimizationsEPCallbacks) | ||||
C(LPM2, Level); | C(LPM2, Level); | ||||
LPM2.addPass(LoopDeletionPass()); | LPM2.addPass(LoopDeletionPass()); | ||||
// Do not enable unrolling in PreLinkThinLTO phase during sample PGO | // Do not enable unrolling in PreLink LTO phase during sample PGO | ||||
// because it changes IR to makes profile annotation in back compile | // because it changes IR to makes profile annotation in back compile | ||||
// inaccurate. | // inaccurate. | ||||
if ((Phase != ThinLTOPhase::PreLink || !PGOOpt || | if ((Phase != LTOPhase::PreLink || !PGOOpt || | ||||
PGOOpt->Action != PGOOptions::SampleUse) && | PGOOpt->Action != PGOOptions::SampleUse) && | ||||
PTO.LoopUnrolling) | PTO.LoopUnrolling) | ||||
LPM2.addPass(LoopFullUnrollPass(Level, /*OnlyWhenForced=*/false, | LPM2.addPass(LoopFullUnrollPass(Level, /*OnlyWhenForced=*/false, | ||||
PTO.ForgetAllSCEVInLoopUnroll)); | PTO.ForgetAllSCEVInLoopUnroll)); | ||||
for (auto &C : LoopOptimizerEndEPCallbacks) | for (auto &C : LoopOptimizerEndEPCallbacks) | ||||
C(LPM2, Level); | C(LPM2, Level); | ||||
▲ Show 20 Lines • Show All 163 Lines • ▼ Show 20 Lines | |||||
static InlineParams | static InlineParams | ||||
getInlineParamsFromOptLevel(PassBuilder::OptimizationLevel Level) { | getInlineParamsFromOptLevel(PassBuilder::OptimizationLevel Level) { | ||||
auto O3 = PassBuilder::O3; | auto O3 = PassBuilder::O3; | ||||
unsigned OptLevel = Level > O3 ? 2 : Level; | unsigned OptLevel = Level > O3 ? 2 : Level; | ||||
unsigned SizeLevel = Level > O3 ? Level - O3 : 0; | unsigned SizeLevel = Level > O3 ? Level - O3 : 0; | ||||
return getInlineParams(OptLevel, SizeLevel); | return getInlineParams(OptLevel, SizeLevel); | ||||
} | } | ||||
ModulePassManager | ModulePassManager PassBuilder::buildModuleSimplificationPipeline( | ||||
PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level, | OptimizationLevel Level, LTOPhase Phase, bool DebugLogging) { | ||||
ThinLTOPhase Phase, | |||||
bool DebugLogging) { | |||||
ModulePassManager MPM(DebugLogging); | ModulePassManager MPM(DebugLogging); | ||||
bool HasSampleProfile = PGOOpt && (PGOOpt->Action == PGOOptions::SampleUse); | bool HasSampleProfile = PGOOpt && (PGOOpt->Action == PGOOptions::SampleUse); | ||||
// In ThinLTO mode, when flattened profile is used, all the available | // In ThinLTO mode, when flattened profile is used, all the available | ||||
// profile information will be annotated in PreLink phase so there is | // profile information will be annotated in PreLink phase so there is | ||||
// no need to load the profile again in PostLink. | // no need to load the profile again in PostLink. | ||||
bool LoadSampleProfile = | bool LoadSampleProfile = HasSampleProfile && !(FlattenedProfileUsed && | ||||
HasSampleProfile && | Phase == LTOPhase::PostLink); | ||||
!(FlattenedProfileUsed && Phase == ThinLTOPhase::PostLink); | |||||
// During the ThinLTO backend phase we perform early indirect call promotion | // During the ThinLTO backend phase we perform early indirect call promotion | ||||
// here, before globalopt. Otherwise imported available_externally functions | // here, before globalopt. Otherwise imported available_externally functions | ||||
// look unreferenced and are removed. If we are going to load the sample | // look unreferenced and are removed. If we are going to load the sample | ||||
// profile then defer until later. | // profile then defer until later. | ||||
// TODO: See if we can move later and consolidate with the location where | // TODO: See if we can move later and consolidate with the location where | ||||
// we perform ICP when we are loading a sample profile. | // we perform ICP when we are loading a sample profile. | ||||
// TODO: We pass HasSampleProfile (whether there was a sample profile file | // TODO: We pass HasSampleProfile (whether there was a sample profile file | ||||
// passed to the compile) to the SamplePGO flag of ICP. This is used to | // passed to the compile) to the SamplePGO flag of ICP. This is used to | ||||
// determine whether the new direct calls are annotated with prof metadata. | // determine whether the new direct calls are annotated with prof metadata. | ||||
// Ideally this should be determined from whether the IR is annotated with | // Ideally this should be determined from whether the IR is annotated with | ||||
// sample profile, and not whether the a sample profile was provided on the | // sample profile, and not whether the a sample profile was provided on the | ||||
// command line. E.g. for flattened profiles where we will not be reloading | // command line. E.g. for flattened profiles where we will not be reloading | ||||
// the sample profile in the ThinLTO backend, we ideally shouldn't have to | // the sample profile in the ThinLTO backend, we ideally shouldn't have to | ||||
// provide the sample profile file. | // provide the sample profile file. | ||||
if (Phase == ThinLTOPhase::PostLink && !LoadSampleProfile) | if (Phase == LTOPhase::PostLink && !LoadSampleProfile) | ||||
MPM.addPass(PGOIndirectCallPromotion(true /* InLTO */, HasSampleProfile)); | MPM.addPass(PGOIndirectCallPromotion(true /* InLTO */, HasSampleProfile)); | ||||
// Do basic inference of function attributes from known properties of system | // Do basic inference of function attributes from known properties of system | ||||
// libraries and other oracles. | // libraries and other oracles. | ||||
MPM.addPass(InferFunctionAttrsPass()); | MPM.addPass(InferFunctionAttrsPass()); | ||||
// Create an early function pass manager to cleanup the output of the | // Create an early function pass manager to cleanup the output of the | ||||
// frontend. | // frontend. | ||||
Show All 15 Lines | if (LoadSampleProfile) | ||||
EarlyFPM.addPass(InstCombinePass()); | EarlyFPM.addPass(InstCombinePass()); | ||||
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(EarlyFPM))); | MPM.addPass(createModuleToFunctionPassAdaptor(std::move(EarlyFPM))); | ||||
if (LoadSampleProfile) { | if (LoadSampleProfile) { | ||||
// Annotate sample profile right after early FPM to ensure freshness of | // Annotate sample profile right after early FPM to ensure freshness of | ||||
// the debug info. | // the debug info. | ||||
MPM.addPass(SampleProfileLoaderPass(PGOOpt->ProfileFile, | MPM.addPass(SampleProfileLoaderPass(PGOOpt->ProfileFile, | ||||
PGOOpt->ProfileRemappingFile, | PGOOpt->ProfileRemappingFile, | ||||
Phase == ThinLTOPhase::PreLink)); | Phase == LTOPhase::PreLink)); | ||||
// Cache ProfileSummaryAnalysis once to avoid the potential need to insert | // Cache ProfileSummaryAnalysis once to avoid the potential need to insert | ||||
// RequireAnalysisPass for PSI before subsequent non-module passes. | // RequireAnalysisPass for PSI before subsequent non-module passes. | ||||
MPM.addPass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>()); | MPM.addPass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>()); | ||||
// Do not invoke ICP in the ThinLTOPrelink phase as it makes it hard | // Do not invoke ICP in the LTOPrelink phase as it makes it hard | ||||
// for the profile annotation to be accurate in the ThinLTO backend. | // for the profile annotation to be accurate in the LTO backend. | ||||
if (Phase != ThinLTOPhase::PreLink) | if (Phase != LTOPhase::PreLink) | ||||
// We perform early indirect call promotion here, before globalopt. | // We perform early indirect call promotion here, before globalopt. | ||||
// This is important for the ThinLTO backend phase because otherwise | // This is important for the ThinLTO backend phase because otherwise | ||||
// imported available_externally functions look unreferenced and are | // imported available_externally functions look unreferenced and are | ||||
// removed. | // removed. | ||||
MPM.addPass(PGOIndirectCallPromotion(Phase == ThinLTOPhase::PostLink, | MPM.addPass(PGOIndirectCallPromotion(Phase == LTOPhase::PostLink, | ||||
true /* SamplePGO */)); | true /* SamplePGO */)); | ||||
} | } | ||||
// Interprocedural constant propagation now that basic cleanup has occurred | // Interprocedural constant propagation now that basic cleanup has occurred | ||||
// and prior to optimizing globals. | // and prior to optimizing globals. | ||||
// FIXME: This position in the pipeline hasn't been carefully considered in | // FIXME: This position in the pipeline hasn't been carefully considered in | ||||
// years, it should be re-analyzed. | // years, it should be re-analyzed. | ||||
MPM.addPass(IPSCCPPass()); | MPM.addPass(IPSCCPPass()); | ||||
Show All 21 Lines | ModulePassManager PassBuilder::buildModuleSimplificationPipeline( | ||||
FunctionPassManager GlobalCleanupPM(DebugLogging); | FunctionPassManager GlobalCleanupPM(DebugLogging); | ||||
GlobalCleanupPM.addPass(InstCombinePass()); | GlobalCleanupPM.addPass(InstCombinePass()); | ||||
invokePeepholeEPCallbacks(GlobalCleanupPM, Level); | invokePeepholeEPCallbacks(GlobalCleanupPM, Level); | ||||
GlobalCleanupPM.addPass(SimplifyCFGPass()); | GlobalCleanupPM.addPass(SimplifyCFGPass()); | ||||
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(GlobalCleanupPM))); | MPM.addPass(createModuleToFunctionPassAdaptor(std::move(GlobalCleanupPM))); | ||||
// Add all the requested passes for instrumentation PGO, if requested. | // Add all the requested passes for instrumentation PGO, if requested. | ||||
if (PGOOpt && Phase != ThinLTOPhase::PostLink && | if (PGOOpt && Phase != LTOPhase::PostLink && | ||||
(PGOOpt->Action == PGOOptions::IRInstr || | (PGOOpt->Action == PGOOptions::IRInstr || | ||||
PGOOpt->Action == PGOOptions::IRUse)) { | PGOOpt->Action == PGOOptions::IRUse)) { | ||||
addPGOInstrPasses(MPM, DebugLogging, Level, | addPGOInstrPasses(MPM, DebugLogging, Level, | ||||
/* RunProfileGen */ PGOOpt->Action == PGOOptions::IRInstr, | /* RunProfileGen */ PGOOpt->Action == PGOOptions::IRInstr, | ||||
/* IsCS */ false, PGOOpt->ProfileFile, | /* IsCS */ false, PGOOpt->ProfileFile, | ||||
PGOOpt->ProfileRemappingFile); | PGOOpt->ProfileRemappingFile); | ||||
MPM.addPass(PGOIndirectCallPromotion(false, false)); | MPM.addPass(PGOIndirectCallPromotion(false, false)); | ||||
} | } | ||||
if (PGOOpt && Phase != ThinLTOPhase::PostLink && | if (PGOOpt && Phase != LTOPhase::PostLink && | ||||
PGOOpt->CSAction == PGOOptions::CSIRInstr) | PGOOpt->CSAction == PGOOptions::CSIRInstr) | ||||
MPM.addPass(PGOInstrumentationGenCreateVar(PGOOpt->CSProfileGenFile)); | MPM.addPass(PGOInstrumentationGenCreateVar(PGOOpt->CSProfileGenFile)); | ||||
// Synthesize function entry counts for non-PGO compilation. | // Synthesize function entry counts for non-PGO compilation. | ||||
if (EnableSyntheticCounts && !PGOOpt) | if (EnableSyntheticCounts && !PGOOpt) | ||||
MPM.addPass(SyntheticCountsPropagation()); | MPM.addPass(SyntheticCountsPropagation()); | ||||
// Require the GlobalsAA analysis for the module so we can query it within | // Require the GlobalsAA analysis for the module so we can query it within | ||||
Show All 16 Lines | ModulePassManager PassBuilder::buildModuleSimplificationPipeline( | ||||
// invoke or a call. | // invoke or a call. | ||||
// Run the inliner first. The theory is that we are walking bottom-up and so | // Run the inliner first. The theory is that we are walking bottom-up and so | ||||
// the callees have already been fully optimized, and we want to inline them | // the callees have already been fully optimized, and we want to inline them | ||||
// into the callers so that our optimizations can reflect that. | // into the callers so that our optimizations can reflect that. | ||||
// For PreLinkThinLTO pass, we disable hot-caller heuristic for sample PGO | // For PreLinkThinLTO pass, we disable hot-caller heuristic for sample PGO | ||||
// because it makes profile annotation in the backend inaccurate. | // because it makes profile annotation in the backend inaccurate. | ||||
InlineParams IP = getInlineParamsFromOptLevel(Level); | InlineParams IP = getInlineParamsFromOptLevel(Level); | ||||
if (Phase == ThinLTOPhase::PreLink && PGOOpt && | if (Phase == LTOPhase::PreLink && PGOOpt && | ||||
PGOOpt->Action == PGOOptions::SampleUse) | PGOOpt->Action == PGOOptions::SampleUse) | ||||
IP.HotCallSiteThreshold = 0; | IP.HotCallSiteThreshold = 0; | ||||
MainCGPipeline.addPass(InlinerPass(IP)); | MainCGPipeline.addPass(InlinerPass(IP)); | ||||
// Now deduce any function attributes based in the current code. | // Now deduce any function attributes based in the current code. | ||||
MainCGPipeline.addPass(PostOrderFunctionAttrsPass()); | MainCGPipeline.addPass(PostOrderFunctionAttrsPass()); | ||||
// When at O3 add argument promotion to the pass pipeline. | // When at O3 add argument promotion to the pass pipeline. | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | OptimizePM.addPass(SimplifyCFGPass(SimplifyCFGOptions(). | ||||
sinkCommonInsts(true))); | sinkCommonInsts(true))); | ||||
// Optimize parallel scalar instruction chains into SIMD instructions. | // Optimize parallel scalar instruction chains into SIMD instructions. | ||||
if (PTO.SLPVectorization) | if (PTO.SLPVectorization) | ||||
OptimizePM.addPass(SLPVectorizerPass()); | OptimizePM.addPass(SLPVectorizerPass()); | ||||
OptimizePM.addPass(InstCombinePass()); | OptimizePM.addPass(InstCombinePass()); | ||||
// Do not enable unrolling in PreLink LTO phase during sample PGO | |||||
// because it changes IR to makes profile annotation in back compile | |||||
// inaccurate. | |||||
bool DoLoopUnrolling = | |||||
(!LTOPreLink || !PGOOpt || PGOOpt->Action != PGOOptions::SampleUse) && | |||||
PTO.LoopUnrolling; | |||||
// Unroll small loops to hide loop backedge latency and saturate any parallel | // Unroll small loops to hide loop backedge latency and saturate any parallel | ||||
// execution resources of an out-of-order processor. We also then need to | // execution resources of an out-of-order processor. We also then need to | ||||
// clean up redundancies and loop invariant code. | // clean up redundancies and loop invariant code. | ||||
// FIXME: It would be really good to use a loop-integrated instruction | // FIXME: It would be really good to use a loop-integrated instruction | ||||
// combiner for cleanup here so that the unrolling and LICM can be pipelined | // combiner for cleanup here so that the unrolling and LICM can be pipelined | ||||
// across the loop nests. | // across the loop nests. | ||||
// We do UnrollAndJam in a separate LPM to ensure it happens before unroll | // We do UnrollAndJam in a separate LPM to ensure it happens before unroll | ||||
if (EnableUnrollAndJam && PTO.LoopUnrolling) { | if (EnableUnrollAndJam && DoLoopUnrolling) { | ||||
OptimizePM.addPass( | OptimizePM.addPass( | ||||
createFunctionToLoopPassAdaptor(LoopUnrollAndJamPass(Level))); | createFunctionToLoopPassAdaptor(LoopUnrollAndJamPass(Level))); | ||||
} | } | ||||
OptimizePM.addPass(LoopUnrollPass( | OptimizePM.addPass(LoopUnrollPass( | ||||
LoopUnrollOptions(Level, /*OnlyWhenForced=*/!PTO.LoopUnrolling, | LoopUnrollOptions(Level, /*OnlyWhenForced=*/!DoLoopUnrolling, | ||||
PTO.ForgetAllSCEVInLoopUnroll))); | PTO.ForgetAllSCEVInLoopUnroll))); | ||||
OptimizePM.addPass(WarnMissedTransformationsPass()); | OptimizePM.addPass(WarnMissedTransformationsPass()); | ||||
OptimizePM.addPass(InstCombinePass()); | OptimizePM.addPass(InstCombinePass()); | ||||
OptimizePM.addPass(RequireAnalysisPass<OptimizationRemarkEmitterAnalysis, Function>()); | OptimizePM.addPass(RequireAnalysisPass<OptimizationRemarkEmitterAnalysis, Function>()); | ||||
OptimizePM.addPass(createFunctionToLoopPassAdaptor( | OptimizePM.addPass(createFunctionToLoopPassAdaptor( | ||||
LICMPass(PTO.LicmMssaOptCap, PTO.LicmMssaNoAccForPromotionCap), | LICMPass(PTO.LicmMssaOptCap, PTO.LicmMssaNoAccForPromotionCap), | ||||
EnableMSSALoopDependency, DebugLogging)); | EnableMSSALoopDependency, DebugLogging)); | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | ModulePassManager PassBuilder::buildModuleOptimizationPipeline( | ||||
MPM.addPass(GlobalDCEPass()); | MPM.addPass(GlobalDCEPass()); | ||||
MPM.addPass(ConstantMergePass()); | MPM.addPass(ConstantMergePass()); | ||||
return MPM; | return MPM; | ||||
} | } | ||||
ModulePassManager | ModulePassManager | ||||
PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level, | PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level, | ||||
bool DebugLogging, bool LTOPreLink) { | bool DebugLogging, LTOPhase Phase) { | ||||
assert(Level != O0 && "Must request optimizations for the default pipeline!"); | assert(Level != O0 && "Must request optimizations for the default pipeline!"); | ||||
ModulePassManager MPM(DebugLogging); | ModulePassManager MPM(DebugLogging); | ||||
// Force any function attributes we want the rest of the pipeline to observe. | // Force any function attributes we want the rest of the pipeline to observe. | ||||
MPM.addPass(ForceFunctionAttrsPass()); | MPM.addPass(ForceFunctionAttrsPass()); | ||||
// Apply module pipeline start EP callback. | // Apply module pipeline start EP callback. | ||||
for (auto &C : PipelineStartEPCallbacks) | for (auto &C : PipelineStartEPCallbacks) | ||||
C(MPM); | C(MPM); | ||||
if (PGOOpt && PGOOpt->SamplePGOSupport) | if (PGOOpt && PGOOpt->SamplePGOSupport) | ||||
MPM.addPass(createModuleToFunctionPassAdaptor(AddDiscriminatorsPass())); | MPM.addPass(createModuleToFunctionPassAdaptor(AddDiscriminatorsPass())); | ||||
// Add the core simplification pipeline. | // Add the core simplification pipeline. | ||||
MPM.addPass(buildModuleSimplificationPipeline(Level, ThinLTOPhase::None, | MPM.addPass(buildModuleSimplificationPipeline(Level, Phase, DebugLogging)); | ||||
DebugLogging)); | |||||
// Now add the optimization pipeline. | // Now add the optimization pipeline. | ||||
MPM.addPass(buildModuleOptimizationPipeline(Level, DebugLogging, LTOPreLink)); | MPM.addPass(buildModuleOptimizationPipeline(Level, DebugLogging, | ||||
Phase == LTOPhase::PreLink)); | |||||
return MPM; | return MPM; | ||||
} | } | ||||
ModulePassManager | ModulePassManager | ||||
PassBuilder::buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level, | PassBuilder::buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level, | ||||
bool DebugLogging) { | bool DebugLogging) { | ||||
assert(Level != O0 && "Must request optimizations for the default pipeline!"); | assert(Level != O0 && "Must request optimizations for the default pipeline!"); | ||||
ModulePassManager MPM(DebugLogging); | ModulePassManager MPM(DebugLogging); | ||||
// Force any function attributes we want the rest of the pipeline to observe. | // Force any function attributes we want the rest of the pipeline to observe. | ||||
MPM.addPass(ForceFunctionAttrsPass()); | MPM.addPass(ForceFunctionAttrsPass()); | ||||
if (PGOOpt && PGOOpt->SamplePGOSupport) | if (PGOOpt && PGOOpt->SamplePGOSupport) | ||||
MPM.addPass(createModuleToFunctionPassAdaptor(AddDiscriminatorsPass())); | MPM.addPass(createModuleToFunctionPassAdaptor(AddDiscriminatorsPass())); | ||||
// Apply module pipeline start EP callback. | // Apply module pipeline start EP callback. | ||||
for (auto &C : PipelineStartEPCallbacks) | for (auto &C : PipelineStartEPCallbacks) | ||||
C(MPM); | C(MPM); | ||||
// If we are planning to perform ThinLTO later, we don't bloat the code with | // If we are planning to perform ThinLTO later, we don't bloat the code with | ||||
// unrolling/vectorization/... now. Just simplify the module as much as we | // unrolling/vectorization/... now. Just simplify the module as much as we | ||||
// can. | // can. | ||||
MPM.addPass(buildModuleSimplificationPipeline(Level, ThinLTOPhase::PreLink, | MPM.addPass(buildModuleSimplificationPipeline(Level, LTOPhase::PreLink, | ||||
DebugLogging)); | DebugLogging)); | ||||
// Run partial inlining pass to partially inline functions that have | // Run partial inlining pass to partially inline functions that have | ||||
// large bodies. | // large bodies. | ||||
// FIXME: It isn't clear whether this is really the right place to run this | // FIXME: It isn't clear whether this is really the right place to run this | ||||
// in ThinLTO. Because there is another canonicalization and simplification | // in ThinLTO. Because there is another canonicalization and simplification | ||||
// phase that will run after the thin link, running this here ends up with | // phase that will run after the thin link, running this here ends up with | ||||
// less information than will be available later and it may grow functions in | // less information than will be available later and it may grow functions in | ||||
Show All 34 Lines | ModulePassManager PassBuilder::buildThinLTODefaultPipeline( | ||||
if (Level == O0) | if (Level == O0) | ||||
return MPM; | return MPM; | ||||
// Force any function attributes we want the rest of the pipeline to observe. | // Force any function attributes we want the rest of the pipeline to observe. | ||||
MPM.addPass(ForceFunctionAttrsPass()); | MPM.addPass(ForceFunctionAttrsPass()); | ||||
// Add the core simplification pipeline. | // Add the core simplification pipeline. | ||||
MPM.addPass(buildModuleSimplificationPipeline(Level, ThinLTOPhase::PostLink, | MPM.addPass(buildModuleSimplificationPipeline(Level, LTOPhase::PostLink, | ||||
DebugLogging)); | DebugLogging)); | ||||
// Now add the optimization pipeline. | // Now add the optimization pipeline. | ||||
MPM.addPass(buildModuleOptimizationPipeline(Level, DebugLogging)); | MPM.addPass(buildModuleOptimizationPipeline(Level, DebugLogging)); | ||||
return MPM; | return MPM; | ||||
} | } | ||||
ModulePassManager | ModulePassManager | ||||
PassBuilder::buildLTOPreLinkDefaultPipeline(OptimizationLevel Level, | PassBuilder::buildLTOPreLinkDefaultPipeline(OptimizationLevel Level, | ||||
bool DebugLogging) { | bool DebugLogging) { | ||||
assert(Level != O0 && "Must request optimizations for the default pipeline!"); | assert(Level != O0 && "Must request optimizations for the default pipeline!"); | ||||
// FIXME: We should use a customized pre-link pipeline! | // FIXME: We should use a customized pre-link pipeline! | ||||
return buildPerModuleDefaultPipeline(Level, DebugLogging, | return buildPerModuleDefaultPipeline(Level, DebugLogging, LTOPhase::PreLink); | ||||
/* LTOPreLink */true); | |||||
} | } | ||||
ModulePassManager | ModulePassManager | ||||
PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level, bool DebugLogging, | PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level, bool DebugLogging, | ||||
ModuleSummaryIndex *ExportSummary) { | ModuleSummaryIndex *ExportSummary) { | ||||
ModulePassManager MPM(DebugLogging); | ModulePassManager MPM(DebugLogging); | ||||
if (Level == O0) { | if (Level == O0) { | ||||
// The WPD and LowerTypeTest passes need to run at -O0 to lower type | // The WPD and LowerTypeTest passes need to run at -O0 to lower type | ||||
// metadata and intrinsics. | // metadata and intrinsics. | ||||
MPM.addPass(WholeProgramDevirtPass(ExportSummary, nullptr)); | MPM.addPass(WholeProgramDevirtPass(ExportSummary, nullptr)); | ||||
MPM.addPass(LowerTypeTestsPass(ExportSummary, nullptr)); | MPM.addPass(LowerTypeTestsPass(ExportSummary, nullptr)); | ||||
return MPM; | return MPM; | ||||
} | } | ||||
if (PGOOpt && PGOOpt->Action == PGOOptions::SampleUse) { | if (PGOOpt && PGOOpt->Action == PGOOptions::SampleUse) { | ||||
// Load sample profile before running the LTO optimization pipeline. | // Load sample profile before running the LTO optimization pipeline. | ||||
MPM.addPass(SampleProfileLoaderPass(PGOOpt->ProfileFile, | MPM.addPass(SampleProfileLoaderPass(PGOOpt->ProfileFile, | ||||
PGOOpt->ProfileRemappingFile, | PGOOpt->ProfileRemappingFile, | ||||
false /* ThinLTOPhase::PreLink */)); | false /* LTOPhase::PreLink */)); | ||||
// Cache ProfileSummaryAnalysis once to avoid the potential need to insert | // Cache ProfileSummaryAnalysis once to avoid the potential need to insert | ||||
// RequireAnalysisPass for PSI before subsequent non-module passes. | // RequireAnalysisPass for PSI before subsequent non-module passes. | ||||
MPM.addPass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>()); | MPM.addPass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>()); | ||||
} | } | ||||
// Remove unused virtual tables to improve the quality of code generated by | // Remove unused virtual tables to improve the quality of code generated by | ||||
// whole-program devirtualization and bitset lowering. | // whole-program devirtualization and bitset lowering. | ||||
MPM.addPass(GlobalDCEPass()); | MPM.addPass(GlobalDCEPass()); | ||||
▲ Show 20 Lines • Show All 1,222 Lines • Show Last 20 Lines |