https://github.com/shiltian updated https://github.com/llvm/llvm-project/pull/114547
>From 56d807b8e73fca6f507056d2670dc4f4682bc921 Mon Sep 17 00:00:00 2001 From: Shilei Tian <i...@tianshilei.me> Date: Fri, 1 Nov 2024 10:51:20 -0400 Subject: [PATCH] [PassBuilder] Add `LTOPreLink` to early simplication EP call backs The early simplication pipeline is used in non-LTO and (Thin/Full)LTO pre-link stage. There are some passes that we want them in non-LTO mode, but not at LTO pre-link stage. The control is missing currently. This PR adds the support. To demonstrate the use, we only enable the internalization pass in non-LTO mode for AMDGPU because having it run in pre-link stage causes some issues. --- clang/lib/CodeGen/BackendUtil.cpp | 3 ++- llvm/include/llvm/Passes/PassBuilder.h | 10 +++++++--- llvm/lib/Passes/PassBuilderPipelines.cpp | 8 ++++---- .../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 19 +++++++++++++++---- llvm/lib/Target/BPF/BPFTargetMachine.cpp | 2 +- .../CodeGen/AMDGPU/print-pipeline-passes.ll | 8 ++++++++ llvm/tools/opt/NewPMDriver.cpp | 2 +- 7 files changed, 38 insertions(+), 14 deletions(-) diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index ae33554a66b6b5..47a30f00612eb7 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -993,7 +993,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline( createModuleToFunctionPassAdaptor(ObjCARCExpandPass())); }); PB.registerPipelineEarlySimplificationEPCallback( - [](ModulePassManager &MPM, OptimizationLevel Level) { + [](ModulePassManager &MPM, OptimizationLevel Level, + ThinOrFullLTOPhase) { if (Level != OptimizationLevel::O0) MPM.addPass(ObjCARCAPElimPass()); }); diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h index 0ebfdbb7865fdd..565fd2ab2147e5 100644 --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -480,7 +480,8 @@ class PassBuilder { /// This extension point allows adding optimization right after passes that do /// basic simplification of the input IR. void registerPipelineEarlySimplificationEPCallback( - const std::function<void(ModulePassManager &, OptimizationLevel)> &C) { + const std::function<void(ModulePassManager &, OptimizationLevel, + ThinOrFullLTOPhase)> &C) { PipelineEarlySimplificationEPCallbacks.push_back(C); } @@ -639,7 +640,8 @@ class PassBuilder { void invokePipelineStartEPCallbacks(ModulePassManager &MPM, OptimizationLevel Level); void invokePipelineEarlySimplificationEPCallbacks(ModulePassManager &MPM, - OptimizationLevel Level); + OptimizationLevel Level, + ThinOrFullLTOPhase Phase); static bool checkParametrizedPassName(StringRef Name, StringRef PassName) { if (!Name.consume_front(PassName)) @@ -764,7 +766,9 @@ class PassBuilder { FullLinkTimeOptimizationLastEPCallbacks; SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2> PipelineStartEPCallbacks; - SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2> + SmallVector<std::function<void(ModulePassManager &, OptimizationLevel, + ThinOrFullLTOPhase)>, + 2> PipelineEarlySimplificationEPCallbacks; SmallVector<std::function<void(ModuleAnalysisManager &)>, 2> diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp index 466fbcd7bb7703..9c90accd9c376b 100644 --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -384,9 +384,9 @@ void PassBuilder::invokePipelineStartEPCallbacks(ModulePassManager &MPM, C(MPM, Level); } void PassBuilder::invokePipelineEarlySimplificationEPCallbacks( - ModulePassManager &MPM, OptimizationLevel Level) { + ModulePassManager &MPM, OptimizationLevel Level, ThinOrFullLTOPhase Phase) { for (auto &C : PipelineEarlySimplificationEPCallbacks) - C(MPM, Level); + C(MPM, Level, Phase); } // Helper to add AnnotationRemarksPass. @@ -1140,7 +1140,7 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level, MPM.addPass(LowerTypeTestsPass(nullptr, nullptr, lowertypetests::DropTestKind::Assume)); - invokePipelineEarlySimplificationEPCallbacks(MPM, Level); + invokePipelineEarlySimplificationEPCallbacks(MPM, Level, Phase); // Interprocedural constant propagation now that basic cleanup has occurred // and prior to optimizing globals. @@ -2153,7 +2153,7 @@ PassBuilder::buildO0DefaultPipeline(OptimizationLevel Level, if (PGOOpt && PGOOpt->DebugInfoForProfiling) MPM.addPass(createModuleToFunctionPassAdaptor(AddDiscriminatorsPass())); - invokePipelineEarlySimplificationEPCallbacks(MPM, Level); + invokePipelineEarlySimplificationEPCallbacks(MPM, Level, Phase); // Build a minimal pipeline based on the semantics required by LLVM, // which is just that always inlining occurs. Further, disable generating diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp index ad03017aae1c17..6e063756045a80 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -745,7 +745,8 @@ void AMDGPUTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { }); PB.registerPipelineEarlySimplificationEPCallback( - [](ModulePassManager &PM, OptimizationLevel Level) { + [](ModulePassManager &PM, OptimizationLevel Level, + ThinOrFullLTOPhase Phase) { PM.addPass(AMDGPUPrintfRuntimeBindingPass()); if (Level == OptimizationLevel::O0) @@ -753,7 +754,10 @@ void AMDGPUTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { PM.addPass(AMDGPUUnifyMetadataPass()); - if (InternalizeSymbols) { + // We don't want to run internalization at per-module stage. + bool LTOPreLink = Phase == ThinOrFullLTOPhase::FullLTOPreLink || + Phase == ThinOrFullLTOPhase::ThinLTOPreLink; + if (InternalizeSymbols && !LTOPreLink) { PM.addPass(InternalizePass(mustPreserveGV)); PM.addPass(GlobalDCEPass()); } @@ -821,8 +825,15 @@ void AMDGPUTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { PM.addPass(AMDGPUSwLowerLDSPass(*this)); if (EnableLowerModuleLDS) PM.addPass(AMDGPULowerModuleLDSPass(*this)); - if (EnableAMDGPUAttributor && Level != OptimizationLevel::O0) - PM.addPass(AMDGPUAttributorPass(*this)); + if (Level != OptimizationLevel::O0) { + // Do we really need internalization in LTO? + if (InternalizeSymbols) { + PM.addPass(InternalizePass(mustPreserveGV)); + PM.addPass(GlobalDCEPass()); + } + if (EnableAMDGPUAttributor) + PM.addPass(AMDGPUAttributorPass(*this)); + } }); PB.registerRegClassFilterParsingCallback( diff --git a/llvm/lib/Target/BPF/BPFTargetMachine.cpp b/llvm/lib/Target/BPF/BPFTargetMachine.cpp index 7d91fa8bb824cf..578b2d607036b5 100644 --- a/llvm/lib/Target/BPF/BPFTargetMachine.cpp +++ b/llvm/lib/Target/BPF/BPFTargetMachine.cpp @@ -138,7 +138,7 @@ void BPFTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { FPM.addPass(BPFPreserveStaticOffsetPass(false)); }); PB.registerPipelineEarlySimplificationEPCallback( - [=](ModulePassManager &MPM, OptimizationLevel) { + [=](ModulePassManager &MPM, OptimizationLevel, ThinOrFullLTOPhase) { MPM.addPass(BPFAdjustOptPass()); }); } diff --git a/llvm/test/CodeGen/AMDGPU/print-pipeline-passes.ll b/llvm/test/CodeGen/AMDGPU/print-pipeline-passes.ll index b9eda0c1cd3bb6..13e38f1bdd3330 100644 --- a/llvm/test/CodeGen/AMDGPU/print-pipeline-passes.ll +++ b/llvm/test/CodeGen/AMDGPU/print-pipeline-passes.ll @@ -3,9 +3,17 @@ ; RUN: opt -mtriple=amdgcn--amdhsa -S -passes="lto<O2>" -print-pipeline-passes %s -o - | FileCheck %s ; RUN: opt -mtriple=amdgcn--amdhsa -S -passes="lto<O3>" -print-pipeline-passes %s -o - | FileCheck %s +; RUN: opt -mtriple=amdgcn--amdhsa -S -passes="lto-pre-link<O0>" -print-pipeline-passes -amdgpu-internalize-symbols %s -o - | FileCheck --check-prefix=PRE %s +; RUN: opt -mtriple=amdgcn--amdhsa -S -passes="lto-pre-link<O1>" -print-pipeline-passes -amdgpu-internalize-symbols %s -o - | FileCheck --check-prefix=PRE %s +; RUN: opt -mtriple=amdgcn--amdhsa -S -passes="lto-pre-link<O2>" -print-pipeline-passes -amdgpu-internalize-symbols %s -o - | FileCheck --check-prefix=PRE %s +; RUN: opt -mtriple=amdgcn--amdhsa -S -passes="lto-pre-link<O3>" -print-pipeline-passes -amdgpu-internalize-symbols %s -o - | FileCheck --check-prefix=PRE %s + + ; CHECK: amdgpu-attributor ; O0-NOT: amdgpu-attributor +; PRE-NOT: internalize + define amdgpu_kernel void @kernel() { entry: ret void diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp index 9a477193a29365..3f1092433d9f31 100644 --- a/llvm/tools/opt/NewPMDriver.cpp +++ b/llvm/tools/opt/NewPMDriver.cpp @@ -294,7 +294,7 @@ static void registerEPCallbacks(PassBuilder &PB) { if (tryParsePipelineText<ModulePassManager>( PB, PipelineEarlySimplificationEPPipeline)) PB.registerPipelineEarlySimplificationEPCallback( - [&PB](ModulePassManager &PM, OptimizationLevel) { + [&PB](ModulePassManager &PM, OptimizationLevel, ThinOrFullLTOPhase) { ExitOnError Err("Unable to parse EarlySimplification pipeline: "); Err(PB.parsePassPipeline(PM, PipelineEarlySimplificationEPPipeline)); }); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits