[llvm] [AMDGPU][Attributor] Add `ThinOrFullLTOPhase` as an argument (PR #123994)
Shilei Tian via llvm-commits
llvm-commits at lists.llvm.org
Thu May 1 11:14:58 PDT 2025
https://github.com/shiltian updated https://github.com/llvm/llvm-project/pull/123994
>From 3a064cbaf1032ffb6e3dd0da53a8ed890a34f7f4 Mon Sep 17 00:00:00 2001
From: Shilei Tian <i at tianshilei.me>
Date: Wed, 22 Jan 2025 13:17:36 -0500
Subject: [PATCH 1/3] [AMDGPU][Attributor] Add `ThinOrFullLTOPhase` as an
argument
---
llvm/lib/Target/AMDGPU/AMDGPU.h | 7 ++--
llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp | 34 +++++++++++++++----
.../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 9 +++--
.../LTO/AMDGPU/closed-world-assumption.ll | 8 +++--
4 files changed, 43 insertions(+), 15 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.h b/llvm/lib/Target/AMDGPU/AMDGPU.h
index 11f4240581b7b..bbdc8c684e619 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPU.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPU.h
@@ -336,9 +336,12 @@ class AMDGPUAttributorPass : public PassInfoMixin<AMDGPUAttributorPass> {
AMDGPUAttributorOptions Options;
+ const ThinOrFullLTOPhase LTOPhase;
+
public:
- AMDGPUAttributorPass(TargetMachine &TM, AMDGPUAttributorOptions Options = {})
- : TM(TM), Options(Options) {};
+ AMDGPUAttributorPass(TargetMachine &TM, AMDGPUAttributorOptions Options,
+ ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None)
+ : TM(TM), Options(Options), LTOPhase(LTOPhase) {};
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
};
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp
index b9ce8dc0c5cdb..7676886a6f855 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp
@@ -1343,7 +1343,8 @@ static void addPreloadKernArgHint(Function &F, TargetMachine &TM) {
}
static bool runImpl(Module &M, AnalysisGetter &AG, TargetMachine &TM,
- AMDGPUAttributorOptions Options) {
+ AMDGPUAttributorOptions Options,
+ ThinOrFullLTOPhase LTOPhase) {
SetVector<Function *> Functions;
for (Function &F : M) {
if (!F.isIntrinsic())
@@ -1378,9 +1379,27 @@ static bool runImpl(Module &M, AnalysisGetter &AG, TargetMachine &TM,
Attributor A(Functions, InfoCache, AC);
- LLVM_DEBUG(dbgs() << "[AMDGPUAttributor] Module " << M.getName() << " is "
- << (AC.IsClosedWorldModule ? "" : "not ")
- << "assumed to be a closed world.\n");
+ LLVM_DEBUG({
+ auto PhaseToString = [](ThinOrFullLTOPhase LTOPhase) -> StringRef {
+ switch (LTOPhase) {
+ case ThinOrFullLTOPhase::None:
+ return "None";
+ case ThinOrFullLTOPhase::ThinLTOPreLink:
+ return "ThinLTOPreLink";
+ case ThinOrFullLTOPhase::ThinLTOPostLink:
+ return "ThinLTOPostLink";
+ case ThinOrFullLTOPhase::FullLTOPreLink:
+ return "FullLTOPreLink";
+ case ThinOrFullLTOPhase::FullLTOPostLink:
+ return "FullLTOPostLink";
+ }
+ };
+ StringRef LTOPhaseStr = PhaseToString(LTOPhase);
+ dbgs() << "[AMDGPUAttributor] Running at phase " << LTOPhaseStr << '\n'
+ << "[AMDGPUAttributor] Module " << M.getName() << " is "
+ << (AC.IsClosedWorldModule ? "" : "not ")
+ << "assumed to be a closed world.\n";
+ });
for (auto *F : Functions) {
A.getOrCreateAAFor<AAAMDAttributes>(IRPosition::function(*F));
@@ -1433,7 +1452,8 @@ class AMDGPUAttributorLegacy : public ModulePass {
bool runOnModule(Module &M) override {
AnalysisGetter AG(this);
- return runImpl(M, AG, *TM, /*Options=*/{});
+ return runImpl(M, AG, *TM, /*Options=*/{},
+ /*LTOPhase=*/ThinOrFullLTOPhase::None);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -1454,8 +1474,8 @@ PreservedAnalyses llvm::AMDGPUAttributorPass::run(Module &M,
AnalysisGetter AG(FAM);
// TODO: Probably preserves CFG
- return runImpl(M, AG, TM, Options) ? PreservedAnalyses::none()
- : PreservedAnalyses::all();
+ return runImpl(M, AG, TM, Options, LTOPhase) ? PreservedAnalyses::none()
+ : PreservedAnalyses::all();
}
char AMDGPUAttributorLegacy::ID = 0;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 1a5f415f906e6..43e837d9ab7e6 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -884,8 +884,10 @@ void AMDGPUTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
OptimizationLevel Level,
ThinOrFullLTOPhase Phase) {
if (Level != OptimizationLevel::O0) {
- if (!isLTOPreLink(Phase))
- MPM.addPass(AMDGPUAttributorPass(*this));
+ if (!isLTOPreLink(Phase)) {
+ AMDGPUAttributorOptions Opts;
+ MPM.addPass(AMDGPUAttributorPass(*this, Opts, Phase));
+ }
}
});
@@ -914,7 +916,8 @@ void AMDGPUTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
AMDGPUAttributorOptions Opt;
if (HasClosedWorldAssumption)
Opt.IsClosedWorld = true;
- PM.addPass(AMDGPUAttributorPass(*this, Opt));
+ PM.addPass(AMDGPUAttributorPass(
+ *this, Opt, ThinOrFullLTOPhase::FullLTOPostLink));
}
}
if (!NoKernelInfoEndLTO) {
diff --git a/llvm/test/LTO/AMDGPU/closed-world-assumption.ll b/llvm/test/LTO/AMDGPU/closed-world-assumption.ll
index dd084e7f3d9ed..de1e614944d6b 100644
--- a/llvm/test/LTO/AMDGPU/closed-world-assumption.ll
+++ b/llvm/test/LTO/AMDGPU/closed-world-assumption.ll
@@ -1,10 +1,12 @@
-; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -O3 -debug-only=amdgpu-attributor -o - %s 2>&1 | FileCheck %s --check-prefix=NO-CW
-; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes="lto<O3>" -debug-only=amdgpu-attributor -o - %s 2>&1 | FileCheck %s --check-prefix=NO-CW
-; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes="lto<O3>" -debug-only=amdgpu-attributor -amdgpu-link-time-closed-world=1 -o - %s 2>&1 | FileCheck %s --check-prefix=CW
+; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -O3 -debug-only=amdgpu-attributor -o - %s 2>&1 | FileCheck %s --check-prefixes=NO-CW,NO-LTO
+; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes="lto<O3>" -debug-only=amdgpu-attributor -o - %s 2>&1 | FileCheck %s --check-prefixes=NO-CW,LTO
+; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes="lto<O3>" -debug-only=amdgpu-attributor -amdgpu-link-time-closed-world=1 -o - %s 2>&1 | FileCheck %s --check-prefixes=CW,LTO
; REQUIRES: amdgpu-registered-target
; REQUIRES: asserts
+; NO-LTO: Running at phase None
+; LTO: Running at phase FullLTOPostLink
; NO-CW: Module {{.*}} is not assumed to be a closed world.
; CW: Module {{.*}} is assumed to be a closed world.
define hidden noundef i32 @_Z3foov() {
>From 40cb4f4c3dab9e47ef9b0034b0aa3f4af97a47a5 Mon Sep 17 00:00:00 2001
From: Shilei Tian <i at tianshilei.me>
Date: Wed, 26 Mar 2025 12:48:53 -0400
Subject: [PATCH 2/3] Add a new interface function `to_string` for
`ThinOrFullLTOPhase`
---
llvm/include/llvm/Pass.h | 17 +++++++++++++++++
llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp | 16 +---------------
2 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/llvm/include/llvm/Pass.h b/llvm/include/llvm/Pass.h
index 463137bdbfcaf..6e2b942cf94b1 100644
--- a/llvm/include/llvm/Pass.h
+++ b/llvm/include/llvm/Pass.h
@@ -86,6 +86,23 @@ enum class ThinOrFullLTOPhase {
FullLTOPostLink
};
+#ifndef NDEBUG
+static inline const char *to_string(ThinOrFullLTOPhase Phase) {
+ switch (Phase) {
+ case ThinOrFullLTOPhase::None:
+ return "None";
+ case ThinOrFullLTOPhase::ThinLTOPreLink:
+ return "ThinLTOPreLink";
+ case ThinOrFullLTOPhase::ThinLTOPostLink:
+ return "ThinLTOPostLink";
+ case ThinOrFullLTOPhase::FullLTOPreLink:
+ return "FullLTOPreLink";
+ case ThinOrFullLTOPhase::FullLTOPostLink:
+ return "FullLTOPostLink";
+ }
+}
+#endif
+
//===----------------------------------------------------------------------===//
/// Pass interface - Implemented by all 'passes'. Subclass this if you are an
/// interprocedural optimization or you do not fit into any of the more
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp
index 7676886a6f855..78e75f888c99c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp
@@ -1380,21 +1380,7 @@ static bool runImpl(Module &M, AnalysisGetter &AG, TargetMachine &TM,
Attributor A(Functions, InfoCache, AC);
LLVM_DEBUG({
- auto PhaseToString = [](ThinOrFullLTOPhase LTOPhase) -> StringRef {
- switch (LTOPhase) {
- case ThinOrFullLTOPhase::None:
- return "None";
- case ThinOrFullLTOPhase::ThinLTOPreLink:
- return "ThinLTOPreLink";
- case ThinOrFullLTOPhase::ThinLTOPostLink:
- return "ThinLTOPostLink";
- case ThinOrFullLTOPhase::FullLTOPreLink:
- return "FullLTOPreLink";
- case ThinOrFullLTOPhase::FullLTOPostLink:
- return "FullLTOPostLink";
- }
- };
- StringRef LTOPhaseStr = PhaseToString(LTOPhase);
+ StringRef LTOPhaseStr = to_string(LTOPhase);
dbgs() << "[AMDGPUAttributor] Running at phase " << LTOPhaseStr << '\n'
<< "[AMDGPUAttributor] Module " << M.getName() << " is "
<< (AC.IsClosedWorldModule ? "" : "not ")
>From 35fda6505c17074fccab02eeb6e72ac656bc022c Mon Sep 17 00:00:00 2001
From: Shilei Tian <i at tianshilei.me>
Date: Mon, 7 Apr 2025 23:14:02 -0400
Subject: [PATCH 3/3] Use `constexpr` to replace `static inline`
---
llvm/include/llvm/Pass.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/include/llvm/Pass.h b/llvm/include/llvm/Pass.h
index 6e2b942cf94b1..9e1d79dc81bbf 100644
--- a/llvm/include/llvm/Pass.h
+++ b/llvm/include/llvm/Pass.h
@@ -87,7 +87,7 @@ enum class ThinOrFullLTOPhase {
};
#ifndef NDEBUG
-static inline const char *to_string(ThinOrFullLTOPhase Phase) {
+constexpr const char *to_string(ThinOrFullLTOPhase Phase) {
switch (Phase) {
case ThinOrFullLTOPhase::None:
return "None";
More information about the llvm-commits
mailing list