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 @@ -477,6 +477,24 @@ OptimizerLastEPCallbacks.push_back(C); } + /// Register a callback for a default optimizer pipeline extension point + /// + /// This extension point allows adding optimizations at the start of the full + /// LTO pipeline. + void registerFullLinkTimeOptimizationEarlyEPCallback( + const std::function &C) { + FullLinkTimeOptimizationEarlyEPCallbacks.push_back(C); + } + + /// Register a callback for a default optimizer pipeline extension point + /// + /// This extension point allows adding optimizations at the end of the full + /// LTO pipeline. + void registerFullLinkTimeOptimizationLastEPCallback( + const std::function &C) { + FullLinkTimeOptimizationLastEPCallbacks.push_back(C); + } + /// Register a callback for parsing an AliasAnalysis Name to populate /// the given AAManager \p AA void registerParseAACallback( @@ -600,6 +618,10 @@ VectorizerStartEPCallbacks; SmallVector, 2> OptimizerLastEPCallbacks; + SmallVector, 2> + FullLinkTimeOptimizationEarlyEPCallbacks; + SmallVector, 2> + FullLinkTimeOptimizationLastEPCallbacks; // Module callbacks SmallVector, 2> PipelineStartEPCallbacks; 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 @@ -1451,6 +1451,9 @@ // Convert @llvm.global.annotations to !annotation metadata. MPM.addPass(Annotation2MetadataPass()); + for (auto &C : FullLinkTimeOptimizationEarlyEPCallbacks) + C(MPM, Level); + // Create a function that performs CFI checks for cross-DSO calls with targets // in the current module. MPM.addPass(CrossDSOCFIPass()); @@ -1464,6 +1467,9 @@ // in ICP. MPM.addPass(LowerTypeTestsPass(nullptr, nullptr, true)); + for (auto &C : FullLinkTimeOptimizationLastEPCallbacks) + C(MPM, Level); + // Emit annotation remarks. addAnnotationRemarksPass(MPM); @@ -1543,6 +1549,9 @@ // pipeline). MPM.addPass(LowerTypeTestsPass(nullptr, nullptr, true)); + for (auto &C : FullLinkTimeOptimizationLastEPCallbacks) + C(MPM, Level); + // Emit annotation remarks. addAnnotationRemarksPass(MPM); @@ -1714,6 +1723,9 @@ if (PTO.MergeFunctions) MPM.addPass(MergeFunctionsPass()); + for (auto &C : FullLinkTimeOptimizationLastEPCallbacks) + C(MPM, Level); + // Emit annotation remarks. addAnnotationRemarksPass(MPM); 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 @@ -6,6 +6,8 @@ ; 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-last=no-op-function -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 ; CHECK: Running pass: NoOp diff --git a/llvm/test/Other/new-pm-lto-defaults.ll b/llvm/test/Other/new-pm-lto-defaults.ll --- a/llvm/test/Other/new-pm-lto-defaults.ll +++ b/llvm/test/Other/new-pm-lto-defaults.ll @@ -6,10 +6,19 @@ ; RUN: -passes='lto' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O1 ; RUN: opt -disable-verify -verify-cfg-preserved=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ +; RUN: -passes='lto' -S %s -passes-ep-full-link-time-optimization-early=no-op-module \ +; RUN: -passes-ep-full-link-time-optimization-last=no-op-module 2>&1 \ +; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O1 --check-prefix=CHECK-EP +; RUN: opt -disable-verify -verify-cfg-preserved=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -passes='lto' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O23SZ \ ; RUN: --check-prefix=CHECK-O2 ; RUN: opt -disable-verify -verify-cfg-preserved=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ +; RUN: -passes='lto' -S %s -passes-ep-full-link-time-optimization-early=no-op-module \ +; RUN: -passes-ep-full-link-time-optimization-last=no-op-module 2>&1 \ +; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O23SZ \ +; RUN: --check-prefix=CHECK-O2 --check-prefix=CHECK-EP +; RUN: opt -disable-verify -verify-cfg-preserved=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -passes='lto' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O23SZ \ ; RUN: --check-prefix=CHECK-O3 @@ -26,6 +35,7 @@ ; RUN: --check-prefix=CHECK-O3 --check-prefix=CHECK-EP-Peephole ; CHECK-O: Running pass: Annotation2Metadata +; CHECK-EP-NEXT: Running pass: NoOpModulePass ; CHECK-O-NEXT: Running pass: CrossDSOCFIPass ; CHECK-O-NEXT: Running pass: OpenMPOptPass ; CHECK-O-NEXT: Running pass: GlobalDCEPass @@ -134,6 +144,7 @@ ; CHECK-O23SZ-NEXT: Running pass: SimplifyCFGPass ; CHECK-O23SZ-NEXT: Running pass: EliminateAvailableExternallyPass ; CHECK-O23SZ-NEXT: Running pass: GlobalDCEPass +; CHECK-EP-NEXT: Running pass: NoOpModulePass ; CHECK-O-NEXT: Running pass: AnnotationRemarksPass on foo ; CHECK-O-NEXT: Running pass: PrintModulePass 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 @@ -127,6 +127,18 @@ cl::desc("A textual description of the module pass pipeline inserted at " "the OptimizerLast extension point into default pipelines"), cl::Hidden); +static cl::opt FullLinkTimeOptimizationEarlyEPPipeline( + "passes-ep-full-link-time-optimization-early", + cl::desc("A textual description of the module pass pipeline inserted at " + "the FullLinkTimeOptimizationEarly extension point into default " + "pipelines"), + cl::Hidden); +static cl::opt FullLinkTimeOptimizationLastEPPipeline( + "passes-ep-full-link-time-optimization-last", + cl::desc("A textual description of the module pass pipeline inserted at " + "the FullLinkTimeOptimizationLast extension point into default " + "pipelines"), + cl::Hidden); // Individual pipeline tuning options. extern cl::opt DisableLoopUnrolling; @@ -229,6 +241,23 @@ ExitOnError Err("Unable to parse OptimizerLastEP pipeline: "); Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline)); }); + if (tryParsePipelineText( + PB, FullLinkTimeOptimizationEarlyEPPipeline)) + PB.registerFullLinkTimeOptimizationEarlyEPCallback( + [&PB](ModulePassManager &PM, OptimizationLevel) { + ExitOnError Err( + "Unable to parse FullLinkTimeOptimizationEarlyEP pipeline: "); + Err(PB.parsePassPipeline(PM, + FullLinkTimeOptimizationEarlyEPPipeline)); + }); + if (tryParsePipelineText( + PB, FullLinkTimeOptimizationLastEPPipeline)) + PB.registerFullLinkTimeOptimizationLastEPCallback( + [&PB](ModulePassManager &PM, OptimizationLevel) { + ExitOnError Err( + "Unable to parse FullLinkTimeOptimizationLastEP pipeline: "); + Err(PB.parsePassPipeline(PM, FullLinkTimeOptimizationLastEPPipeline)); + }); } #define HANDLE_EXTENSION(Ext) \