diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -468,6 +468,15 @@ PipelineEarlySimplificationEPCallbacks.push_back(C); } + /// Register a callback for a default optimizer pipeline extension point + /// + /// This extension point allows adding optimizations before the function + /// optimization pipeline. + void registerOptimizerEarlyEPCallback( + const std::function &C) { + OptimizerEarlyEPCallbacks.push_back(C); + } + /// Register a callback for a default optimizer pipeline extension point /// /// This extension point allows adding optimizations at the very end of the @@ -616,13 +625,15 @@ CGSCCOptimizerLateEPCallbacks; SmallVector, 2> VectorizerStartEPCallbacks; + // Module callbacks + SmallVector, 2> + OptimizerEarlyEPCallbacks; SmallVector, 2> OptimizerLastEPCallbacks; SmallVector, 2> FullLinkTimeOptimizationEarlyEPCallbacks; SmallVector, 2> FullLinkTimeOptimizationLastEPCallbacks; - // Module callbacks SmallVector, 2> PipelineStartEPCallbacks; SmallVector, 2> diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -1169,6 +1169,9 @@ // memory operations. MPM.addPass(RecomputeGlobalsAAPass()); + for (auto &C : OptimizerEarlyEPCallbacks) + C(MPM, Level); + FunctionPassManager OptimizePM; OptimizePM.addPass(Float2IntPass()); OptimizePM.addPass(LowerConstantIntrinsicsPass()); @@ -1809,6 +1812,10 @@ if (!FPM.isEmpty()) MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); } + + for (auto &C : OptimizerEarlyEPCallbacks) + C(MPM, Level); + if (!VectorizerStartEPCallbacks.empty()) { FunctionPassManager FPM; for (auto &C : VectorizerStartEPCallbacks) diff --git a/llvm/test/Other/new-pm-O0-ep-callbacks.ll b/llvm/test/Other/new-pm-O0-ep-callbacks.ll --- a/llvm/test/Other/new-pm-O0-ep-callbacks.ll +++ b/llvm/test/Other/new-pm-O0-ep-callbacks.ll @@ -5,6 +5,7 @@ ; RUN: opt -disable-output -debug-pass-manager -passes-ep-vectorizer-start=no-op-function -passes='default' 2>&1 < %s | FileCheck %s ; RUN: opt -disable-output -debug-pass-manager -passes-ep-pipeline-start=no-op-module -passes='default' 2>&1 < %s | FileCheck %s ; RUN: opt -disable-output -debug-pass-manager -passes-ep-pipeline-early-simplification=no-op-module -passes='default' 2>&1 < %s | FileCheck %s +; RUN: opt -disable-output -debug-pass-manager -passes-ep-optimizer-early=no-op-module -passes='default' 2>&1 < %s | FileCheck %s ; RUN: opt -disable-output -debug-pass-manager -passes-ep-optimizer-last=no-op-module -passes='default' 2>&1 < %s | FileCheck %s ; RUN: opt -disable-output -debug-pass-manager -passes-ep-full-link-time-optimization-early=no-op-module -passes='lto' 2>&1 < %s | FileCheck %s ; RUN: opt -disable-output -debug-pass-manager -passes-ep-full-link-time-optimization-last=no-op-module -passes='lto' 2>&1 < %s | FileCheck %s diff --git a/llvm/test/Other/new-pm-defaults.ll b/llvm/test/Other/new-pm-defaults.ll --- a/llvm/test/Other/new-pm-defaults.ll +++ b/llvm/test/Other/new-pm-defaults.ll @@ -63,6 +63,10 @@ ; RUN: -passes='lto-pre-link' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-LTO,CHECK-O3,%llvmcheckext,CHECK-EP-PIPELINE-START,CHECK-O23SZ ; RUN: opt -disable-verify -verify-cfg-preserved=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ +; RUN: -passes-ep-optimizer-early='no-op-module' \ +; RUN: -passes='default' -S %s 2>&1 \ +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-DEFAULT,CHECK-O3,%llvmcheckext,CHECK-EP-OPTIMIZER-EARLY,CHECK-O23SZ +; RUN: opt -disable-verify -verify-cfg-preserved=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -passes-ep-optimizer-last='no-op-module' \ ; RUN: -passes='default' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-DEFAULT,CHECK-O3,%llvmcheckext,CHECK-EP-OPTIMIZER-LAST,CHECK-O23SZ @@ -217,6 +221,7 @@ ; CHECK-LTO-NOT: Running pass: EliminateAvailableExternallyPass ; CHECK-O-NEXT: Running pass: ReversePostOrderFunctionAttrsPass ; CHECK-O-NEXT: Running pass: RecomputeGlobalsAAPass +; CHECK-EP-OPTIMIZER-EARLY: Running pass: NoOpModulePass ; CHECK-O-NEXT: Running pass: Float2IntPass ; CHECK-O-NEXT: Running pass: LowerConstantIntrinsicsPass on foo ; CHECK-MATRIX: Running pass: LowerMatrixIntrinsicsPass on f diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp --- a/llvm/tools/opt/NewPMDriver.cpp +++ b/llvm/tools/opt/NewPMDriver.cpp @@ -117,6 +117,11 @@ cl::desc("A textual description of the module pass pipeline inserted at " "the EarlySimplification extension point into default pipelines"), cl::Hidden); +static cl::opt OptimizerEarlyEPPipeline( + "passes-ep-optimizer-early", + cl::desc("A textual description of the module pass pipeline inserted at " + "the OptimizerEarly extension point into default pipelines"), + cl::Hidden); static cl::opt OptimizerLastEPPipeline( "passes-ep-optimizer-last", cl::desc("A textual description of the module pass pipeline inserted at " @@ -230,6 +235,12 @@ ExitOnError Err("Unable to parse EarlySimplification pipeline: "); Err(PB.parsePassPipeline(PM, PipelineEarlySimplificationEPPipeline)); }); + if (tryParsePipelineText(PB, OptimizerEarlyEPPipeline)) + PB.registerOptimizerEarlyEPCallback( + [&PB](ModulePassManager &PM, OptimizationLevel) { + ExitOnError Err("Unable to parse OptimizerEarlyEP pipeline: "); + Err(PB.parsePassPipeline(PM, OptimizerEarlyEPPipeline)); + }); if (tryParsePipelineText(PB, OptimizerLastEPPipeline)) PB.registerOptimizerLastEPCallback( [&PB](ModulePassManager &PM, OptimizationLevel) {