[clang] [llvm] [PassBuilder] Add `ThinOrFullLTOPhase` to early simplication EP call backs (PR #114547)
Shilei Tian via cfe-commits
cfe-commits at lists.llvm.org
Sun Nov 3 18:58:31 PST 2024
https://github.com/shiltian updated https://github.com/llvm/llvm-project/pull/114547
>From 3da52a072583f835b69694b9649ccc66986cd346 Mon Sep 17 00:00:00 2001
From: Shilei Tian <i at 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));
});
More information about the cfe-commits
mailing list