diff --git a/llvm/include/llvm/Pass.h b/llvm/include/llvm/Pass.h index 463137bdbfcaf..9e1d79dc81bbf 100644 --- a/llvm/include/llvm/Pass.h +++ b/llvm/include/llvm/Pass.h @@ -86,6 +86,23 @@ enum class ThinOrFullLTOPhase { FullLTOPostLink }; +#ifndef NDEBUG +constexpr 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/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 { 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..78e75f888c99c 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 Functions; for (Function &F : M) { if (!F.isIntrinsic()) @@ -1378,9 +1379,13 @@ 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({ + StringRef LTOPhaseStr = to_string(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(IRPosition::function(*F)); @@ -1433,7 +1438,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 +1460,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" -debug-only=amdgpu-attributor -o - %s 2>&1 | FileCheck %s --check-prefix=NO-CW -; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes="lto" -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" -debug-only=amdgpu-attributor -o - %s 2>&1 | FileCheck %s --check-prefixes=NO-CW,LTO +; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes="lto" -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() {