aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Passes/PassBuilderPipelines.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Passes/PassBuilderPipelines.cpp')
-rw-r--r--llvm/lib/Passes/PassBuilderPipelines.cpp80
1 files changed, 49 insertions, 31 deletions
diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index de1b0ace7876..a6a36ff25402 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -178,6 +178,10 @@ static cl::opt<bool> EnableNoRerunSimplificationPipeline(
"than once in the case that SCC mutations cause a function to be "
"visited multiple times as long as the function has not been changed"));
+static cl::opt<bool> EnableMergeFunctions(
+ "enable-merge-functions", cl::init(false), cl::Hidden,
+ cl::desc("Enable function merging as part of the optimization pipeline"));
+
PipelineTuningOptions::PipelineTuningOptions() {
LoopInterleaving = true;
LoopVectorization = true;
@@ -187,7 +191,7 @@ PipelineTuningOptions::PipelineTuningOptions() {
LicmMssaOptCap = SetLicmMssaOptCap;
LicmMssaNoAccForPromotionCap = SetLicmMssaNoAccForPromotionCap;
CallGraphProfile = true;
- MergeFunctions = false;
+ MergeFunctions = EnableMergeFunctions;
EagerlyInvalidateAnalyses = EnableEagerlyInvalidateAnalyses;
}
@@ -418,9 +422,9 @@ PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level,
FPM.addPass(CorrelatedValuePropagationPass());
FPM.addPass(SimplifyCFGPass());
+ FPM.addPass(InstCombinePass());
if (Level == OptimizationLevel::O3)
FPM.addPass(AggressiveInstCombinePass());
- FPM.addPass(InstCombinePass());
if (!Level.isOptimizingForSize())
FPM.addPass(LibCallsShrinkWrapPass());
@@ -754,9 +758,11 @@ PassBuilder::buildInlinerPipeline(OptimizationLevel Level,
return MIWP;
}
-ModuleInlinerPass
+ModulePassManager
PassBuilder::buildModuleInlinerPipeline(OptimizationLevel Level,
ThinOrFullLTOPhase Phase) {
+ ModulePassManager MPM;
+
InlineParams IP = getInlineParamsFromOptLevel(Level);
if (Phase == ThinOrFullLTOPhase::ThinLTOPreLink && PGOOpt &&
PGOOpt->Action == PGOOptions::SampleUse)
@@ -773,7 +779,16 @@ PassBuilder::buildModuleInlinerPipeline(OptimizationLevel Level,
// inline deferral logic in module inliner.
IP.EnableDeferral = false;
- return ModuleInlinerPass(IP, UseInlineAdvisor);
+ MPM.addPass(ModuleInlinerPass(IP, UseInlineAdvisor));
+
+ MPM.addPass(createModuleToFunctionPassAdaptor(
+ buildFunctionSimplificationPipeline(Level, Phase),
+ PTO.EagerlyInvalidateAnalyses));
+
+ MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
+ CoroSplitPass(Level != OptimizationLevel::O0)));
+
+ return MPM;
}
ModulePassManager
@@ -980,26 +995,28 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level,
FPM.addPass(InstCombinePass());
if (Level.getSpeedupLevel() > 1 && ExtraVectorizerPasses) {
+ ExtraVectorPassManager ExtraPasses;
// At higher optimization levels, try to clean up any runtime overlap and
// alignment checks inserted by the vectorizer. We want to track correlated
// runtime checks for two inner loops in the same outer loop, fold any
// common computations, hoist loop-invariant aspects out of any outer loop,
// and unswitch the runtime checks if possible. Once hoisted, we may have
// dead (or speculatable) control flows or more combining opportunities.
- FPM.addPass(EarlyCSEPass());
- FPM.addPass(CorrelatedValuePropagationPass());
- FPM.addPass(InstCombinePass());
+ ExtraPasses.addPass(EarlyCSEPass());
+ ExtraPasses.addPass(CorrelatedValuePropagationPass());
+ ExtraPasses.addPass(InstCombinePass());
LoopPassManager LPM;
LPM.addPass(LICMPass(PTO.LicmMssaOptCap, PTO.LicmMssaNoAccForPromotionCap));
LPM.addPass(SimpleLoopUnswitchPass(/* NonTrivial */ Level ==
OptimizationLevel::O3));
- FPM.addPass(
+ ExtraPasses.addPass(
RequireAnalysisPass<OptimizationRemarkEmitterAnalysis, Function>());
- FPM.addPass(
+ ExtraPasses.addPass(
createFunctionToLoopPassAdaptor(std::move(LPM), /*UseMemorySSA=*/true,
/*UseBlockFrequencyInfo=*/true));
- FPM.addPass(SimplifyCFGPass());
- FPM.addPass(InstCombinePass());
+ ExtraPasses.addPass(SimplifyCFGPass());
+ ExtraPasses.addPass(InstCombinePass());
+ FPM.addPass(std::move(ExtraPasses));
}
// Now that we've formed fast to execute loop structures, we do further
@@ -1149,8 +1166,9 @@ PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level,
// Disable header duplication at -Oz.
LPM.addPass(LoopRotatePass(Level != OptimizationLevel::Oz, LTOPreLink));
// Some loops may have become dead by now. Try to delete them.
- // FIXME: see disscussion in https://reviews.llvm.org/D112851
- // this may need to be revisited once GVN is more powerful.
+ // FIXME: see discussion in https://reviews.llvm.org/D112851,
+ // this may need to be revisited once we run GVN before loop deletion
+ // in the simplification pipeline.
LPM.addPass(LoopDeletionPass());
OptimizePM.addPass(createFunctionToLoopPassAdaptor(
std::move(LPM), /*UseMemorySSA=*/false, /*UseBlockFrequencyInfo=*/false));
@@ -1167,23 +1185,6 @@ PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level,
addVectorPasses(Level, OptimizePM, /* IsFullLTO */ false);
- // Split out cold code. Splitting is done late to avoid hiding context from
- // other optimizations and inadvertently regressing performance. The tradeoff
- // is that this has a higher code size cost than splitting early.
- if (EnableHotColdSplit && !LTOPreLink)
- MPM.addPass(HotColdSplittingPass());
-
- // Search the code for similar regions of code. If enough similar regions can
- // be found where extracting the regions into their own function will decrease
- // the size of the program, we extract the regions, a deduplicate the
- // structurally similar regions.
- if (EnableIROutliner)
- MPM.addPass(IROutlinerPass());
-
- // Merge functions if requested.
- if (PTO.MergeFunctions)
- MPM.addPass(MergeFunctionsPass());
-
// LoopSink pass sinks instructions hoisted by LICM, which serves as a
// canonicalization pass that enables other optimizations. As a result,
// LoopSink pass needs to be a very late IR pass to avoid undoing LICM
@@ -1211,6 +1212,23 @@ PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level,
for (auto &C : OptimizerLastEPCallbacks)
C(MPM, Level);
+ // Split out cold code. Splitting is done late to avoid hiding context from
+ // other optimizations and inadvertently regressing performance. The tradeoff
+ // is that this has a higher code size cost than splitting early.
+ if (EnableHotColdSplit && !LTOPreLink)
+ MPM.addPass(HotColdSplittingPass());
+
+ // Search the code for similar regions of code. If enough similar regions can
+ // be found where extracting the regions into their own function will decrease
+ // the size of the program, we extract the regions, a deduplicate the
+ // structurally similar regions.
+ if (EnableIROutliner)
+ MPM.addPass(IROutlinerPass());
+
+ // Merge functions if requested.
+ if (PTO.MergeFunctions)
+ MPM.addPass(MergeFunctionsPass());
+
if (PTO.CallGraphProfile)
MPM.addPass(CGProfilePass());
@@ -1521,9 +1539,9 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
// function pointers. When this happens, we often have to resolve varargs
// calls, etc, so let instcombine do this.
FunctionPassManager PeepholeFPM;
+ PeepholeFPM.addPass(InstCombinePass());
if (Level == OptimizationLevel::O3)
PeepholeFPM.addPass(AggressiveInstCombinePass());
- PeepholeFPM.addPass(InstCombinePass());
invokePeepholeEPCallbacks(PeepholeFPM, Level);
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(PeepholeFPM),