[llvm-branch-commits] [llvm] [LTO] Add support for NewPM CodeGen (PR #210249)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Aug 12 22:01:41 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
Author: Vikram Hegde (vikramRH)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/210249.diff
2 Files Affected:
- (modified) llvm/lib/LTO/LTOBackend.cpp (+65-4)
- (modified) llvm/test/CodeGen/AMDGPU/lto-lower-module-lds.ll (+44)
``````````diff
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 73697a9d0d446..94f7dacc62c34 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -22,8 +22,10 @@
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/CGData/CodeGenData.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/IR/LLVMRemarkStreamer.h"
#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Verifier.h"
#include "llvm/LTO/LTO.h"
@@ -74,6 +76,10 @@ static cl::opt<bool> ThinLTOAssumeMerged(
cl::desc("Assume the input has already undergone ThinLTO function "
"importing and the other pre-optimization pipeline changes."));
+static cl::opt<bool> EnableNPMForBackend("enable-npm-for-backend",
+ cl::init(false),
+ cl::desc("Disable NPM for backend"));
+
static cl::list<std::string>
SaveModulesList("filter-save-modules", cl::value_desc("module names"),
cl::desc("Only save bitcode for module whose name without "
@@ -480,7 +486,62 @@ static void codegen(const Config &Conf, TargetMachine *TM,
// Stream->commit() is called. The commit function of CacheStream deletes
// the raw stream, which is too early as streamers (e.g. MCAsmStreamer)
// keep the pointer and may use it until their destruction. See #138194.
- {
+ if (EnableNPMForBackend) {
+ MachineModuleInfo MMI(TM);
+ PassInstrumentationCallbacks PIC;
+ MachineFunctionAnalysisManager MFAM;
+ LoopAnalysisManager LAM;
+ FunctionAnalysisManager FAM;
+ CGSCCAnalysisManager CGAM;
+ ModuleAnalysisManager MAM;
+ PassBuilder PB(TM, PipelineTuningOptions(), std::nullopt, &PIC);
+
+ StandardInstrumentations SI(Mod.getContext(), Conf.DebugPassManager,
+ Conf.VerifyEach);
+ SI.registerCallbacks(PIC, &MAM);
+
+ TargetLibraryInfoImpl TLII(Mod.getTargetTriple(), TM->Options.VecLib);
+ FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); });
+ MAM.registerPass([&] { return MachineModuleAnalysis(MMI); });
+ MAM.registerPass([&] {
+ return RuntimeLibraryAnalysis(
+ Mod.getTargetTriple(), TM->Options.ExceptionModel,
+ TM->Options.FloatABIType, TM->Options.EABIVersion,
+ TM->Options.MCOptions.ABIName, TM->Options.VecLib);
+ });
+
+ if (!isEmptyModule(Mod))
+ MAM.registerPass(
+ [&] { return ImmutableModuleSummaryIndexAnalysis(&CombinedIndex); });
+
+ PB.registerModuleAnalyses(MAM);
+ PB.registerCGSCCAnalyses(CGAM);
+ PB.registerFunctionAnalyses(FAM);
+ PB.registerLoopAnalyses(LAM);
+ PB.registerMachineFunctionAnalyses(MFAM);
+ PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);
+
+ ModulePassManager MPM;
+ FunctionPassManager FPM;
+
+ if (Error Err = TM->buildCodeGenPipeline(
+ MPM, MAM, *Stream->OS, DwoOut ? &DwoOut->os() : nullptr,
+ Conf.CGFileType, CGPassBuilderOption(), MMI.getContext(), &PIC))
+ return;
+
+ if (PrintPipelinePasses) {
+ std::string PipelineStr;
+ raw_string_ostream OutS(PipelineStr);
+ MPM.printPipeline(OutS, [&PIC](StringRef ClassName) {
+ auto PassName = PIC.getPassNameForClassName(ClassName);
+ return PassName.empty() ? ClassName : PassName;
+ });
+ outs() << PipelineStr << '\n';
+ } else {
+ MPM.run(Mod, MAM);
+ }
+
+ } else {
legacy::PassManager CodeGenPasses;
TargetLibraryInfoImpl TLII(Mod.getTargetTriple(), TM->Options.VecLib);
CodeGenPasses.add(new TargetLibraryInfoWrapperPass(TLII));
@@ -504,11 +565,11 @@ static void codegen(const Config &Conf, TargetMachine *TM,
Conf.CGFileType))
report_fatal_error("Failed to setup codegen");
CodeGenPasses.run(Mod);
-
- if (DwoOut)
- DwoOut->keep();
}
+ if (DwoOut)
+ DwoOut->keep();
+
if (Error Err = Stream->commit())
report_fatal_error(std::move(Err));
}
diff --git a/llvm/test/CodeGen/AMDGPU/lto-lower-module-lds.ll b/llvm/test/CodeGen/AMDGPU/lto-lower-module-lds.ll
index a2e3a84f7c064..ed75f4482aeec 100644
--- a/llvm/test/CodeGen/AMDGPU/lto-lower-module-lds.ll
+++ b/llvm/test/CodeGen/AMDGPU/lto-lower-module-lds.ll
@@ -38,6 +38,50 @@
; CHECK: ModulePass Manager
; CHECK: Lower uses of LDS variables from non-kernel functions
+; Test -enable-npm-for-backend.
+
+; NPM Default O0
+; RUN: opt -mtriple=amdgpu10.30-- %s -o %t.bc
+; RUN: llvm-lto2 run -O0 -cg-opt-level 0 %t.bc -o %t.s -r %t.bc,test,px -enable-npm-for-backend -debug-pass-manager 2>&1 | FileCheck --check-prefix=NPM %s
+
+; NPM Unified O0
+; RUN: opt -unified-lto -thinlto-split-lto-unit -thinlto-bc -mtriple=amdgpu10.30-- %s -o %t.bc
+; RUN: llvm-lto2 run -unified-lto=full -O0 -cg-opt-level 0 %t.bc -o %t.s -r %t.bc,test,px -enable-npm-for-backend -debug-pass-manager 2>&1 | FileCheck --check-prefix=NPM %s
+
+; NPM Default O2
+; RUN: opt -mtriple=amdgpu10.30-- %s -o %t.bc
+; RUN: llvm-lto2 run -O2 -cg-opt-level 2 %t.bc -o %t.s -r %t.bc,test,px -enable-npm-for-backend -debug-pass-manager 2>&1 | FileCheck --check-prefix=NPM %s
+
+; NPM Unified O2
+; RUN: opt -unified-lto -thinlto-split-lto-unit -thinlto-bc -mtriple=amdgpu10.30-- %s -o %t.bc
+; RUN: llvm-lto2 run -unified-lto=full -O2 -cg-opt-level 2 %t.bc -o %t.s -r %t.bc,test,px -enable-npm-for-backend -debug-pass-manager 2>&1 | FileCheck --check-prefix=NPM %s
+
+; The New PM full-LTO pipeline still runs the module-LDS lowering, and the CG
+; pipeline is now driven by the New PM (no legacy "ModulePass Manager" structure).
+; NPM-NOT: ModulePass Manager
+; NPM: Running pass: AMDGPULowerModuleLDSPass on [module]
+; NPM: Running pass: SelectionDAGISelPass on test
+; NPM: Running pass: PrologEpilogInserterPass on test
+; NPM: Running pass: AMDGPUAsmPrinterPass on test
+
+; Test -print-pipeline-passes prints the New PM codegen pipeline.
+
+; PP Default O2
+; RUN: opt -mtriple=amdgpu10.30-- %s -o %t.bc
+; RUN: llvm-lto2 run -O2 -cg-opt-level 2 %t.bc -o %t.s -r %t.bc,test,px -enable-npm-for-backend -print-pipeline-passes 2>&1 | FileCheck --check-prefix=PP %s
+
+; PP Unified O2
+; RUN: opt -unified-lto -thinlto-split-lto-unit -thinlto-bc -mtriple=amdgpu10.30-- %s -o %t.bc
+; RUN: llvm-lto2 run -unified-lto=full -O2 -cg-opt-level 2 %t.bc -o %t.s -r %t.bc,test,px -enable-npm-for-backend -print-pipeline-passes 2>&1 | FileCheck --check-prefix=PP %s
+
+; First line is the full-LTO (IR) pipeline, second line is the codegen (machine)
+; pipeline. Check a few codegen-specific passes (in order) on the second line.
+; PP: amdgpu-lower-module-lds
+; PP: require<MachineModuleAnalysis>
+; PP-SAME: amdgpu-isel
+; PP-SAME: prolog-epilog
+; PP-SAME: amdgpu-asm-printer
+
@lds = internal unnamed_addr addrspace(3) global i32 poison, align 4
define amdgpu_kernel void @test() {
``````````
</details>
https://github.com/llvm/llvm-project/pull/210249
More information about the llvm-branch-commits
mailing list