[clang] [CodeGen] Implement fallback path for backend NPM run (PR #210248)
Vikram Hegde via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 16 23:53:19 PDT 2026
https://github.com/vikramRH updated https://github.com/llvm/llvm-project/pull/210248
>From b66c997367e2ca52c6736fcb3675e0a844642384 Mon Sep 17 00:00:00 2001
From: vikhegde <vikram.hegde at amd.com>
Date: Thu, 16 Jul 2026 16:12:34 +0530
Subject: [PATCH] [CodeGen] Implement fallback path for backend NPM run
---
.../clang/Basic/DiagnosticFrontendKinds.td | 3 +
clang/include/clang/Basic/DiagnosticGroups.td | 1 +
clang/lib/CodeGen/BackendUtil.cpp | 55 ++++++++++++++-----
3 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index cef2fc32a1642..21e230e6177e0 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -129,6 +129,9 @@ def err_fe_unable_to_create_subtarget : Error<
"unable to create subtarget: '%0'%select{ with features '%2'|}1">;
def err_fe_unable_to_interface_with_target : Error<
"unable to interface with target machine">;
+def warn_fe_failed_new_pass_manager : Warning<
+ "new pass manager failed, retrying codegen with legacy PM">,
+ InGroup<NewPassManager>;
def err_fe_unable_to_open_output : Error<
"unable to open output file '%0': '%1'">;
def warn_fe_macro_contains_embedded_newline : Warning<
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 79583534b9bbd..35ed6d82652f9 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1793,6 +1793,7 @@ Results can be filtered by function name by passing
// Compatibility flag name from old versions of Clang.
def : DiagGroup<"frame-larger-than=", [BackendFrameLargerThan]>;
def BackendPlugin : DiagGroup<"backend-plugin">;
+def NewPassManager : DiagGroup<"new-pass-manager">;
def RemarkBackendPlugin : DiagGroup<"remark-backend-plugin">;
def BackendOptimizationRemark : DiagGroup<"pass">;
def BackendOptimizationRemarkMissed : DiagGroup<"pass-missed">;
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 2b755fa916e55..95a73a793898e 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -194,10 +194,10 @@ class EmitAssemblyHelper {
std::unique_ptr<raw_pwrite_stream> &OS,
std::unique_ptr<llvm::ToolOutputFile> &DwoOS,
CodeGenFileType CGFT);
- void RunCodegenPipelineNewPM(BackendAction Action,
- std::unique_ptr<raw_pwrite_stream> &OS,
- std::unique_ptr<llvm::ToolOutputFile> &DwoOS,
- CodeGenFileType CGFT);
+ Error RunCodegenPipelineNewPM(BackendAction Action,
+ std::unique_ptr<raw_pwrite_stream> &OS,
+ std::unique_ptr<llvm::ToolOutputFile> &DwoOS,
+ CodeGenFileType CGFT);
void TimeCodegenPasses(llvm::function_ref<void()> RunPasses);
/// Check whether we should emit a module summary for regular LTO.
@@ -1249,10 +1249,14 @@ void EmitAssemblyHelper::RunCodegenPipeline(
}
if (CodeGenOpts.EnableNewPMCodeGen) {
- RunCodegenPipelineNewPM(Action, OS, DwoOS, CGFT);
- } else {
- RunCodegenPipelineLegacy(Action, OS, DwoOS, CGFT);
+ if (!RunCodegenPipelineNewPM(Action, OS, DwoOS, CGFT))
+ return;
+
+ Diags.Report(diag::warn_fe_failed_new_pass_manager);
}
+
+ // NPM path (if enabled) failed to construct pipeline. retry with legacy PM.
+ RunCodegenPipelineLegacy(Action, OS, DwoOS, CGFT);
}
void EmitAssemblyHelper::RunCodegenPipelineLegacy(
@@ -1292,7 +1296,7 @@ void EmitAssemblyHelper::RunCodegenPipelineLegacy(
TimeCodegenPasses([&] { CodeGenPasses.run(*TheModule); });
}
-void EmitAssemblyHelper::RunCodegenPipelineNewPM(
+Error EmitAssemblyHelper::RunCodegenPipelineNewPM(
BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,
std::unique_ptr<llvm::ToolOutputFile> &DwoOS, CodeGenFileType CGFT) {
ModulePassManager MPM;
@@ -1309,6 +1313,12 @@ void EmitAssemblyHelper::RunCodegenPipelineNewPM(
TargetMachine *TMPointer = TM.get();
PassBuilder PB(TMPointer, PTOptions, std::nullopt, &PIC,
CI.getVirtualFileSystemPtr());
+
+ StandardInstrumentations SI(TheModule->getContext(),
+ CodeGenOpts.DebugPassManager,
+ CodeGenOpts.VerifyEach);
+ SI.registerCallbacks(PIC, &MAM);
+
PB.registerModuleAnalyses(MAM);
PB.registerCGSCCAnalyses(CGAM);
PB.registerFunctionAnalyses(FAM);
@@ -1316,17 +1326,34 @@ void EmitAssemblyHelper::RunCodegenPipelineNewPM(
PB.registerMachineFunctionAnalyses(MFAM);
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);
+ TargetLibraryInfoImpl TLII(TheModule->getTargetTriple());
+ FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); });
MAM.registerPass([&] { return MachineModuleAnalysis(MMI); });
+ MAM.registerPass([&] {
+ const llvm::TargetOptions &Options = TM->Options;
+ return RuntimeLibraryAnalysis(TargetTriple, Options.ExceptionModel,
+ Options.FloatABIType, Options.EABIVersion,
+ Options.MCOptions.ABIName, Options.VecLib);
+ });
+
+ if (Error BuildPipelineError = TM->buildCodeGenPipeline(
+ MPM, MAM, *OS, DwoOS ? &DwoOS->os() : nullptr, CGFT, Opt,
+ MMI.getContext(), &PIC))
+ return BuildPipelineError;
- Error BuildPipelineError =
- TM->buildCodeGenPipeline(MPM, MAM, *OS, DwoOS ? &DwoOS->os() : nullptr,
- CGFT, Opt, MMI.getContext(), &PIC);
- if (BuildPipelineError) {
- Diags.Report(diag::err_fe_unable_to_interface_with_target);
- 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';
+ return Error::success();
}
TimeCodegenPasses([&] { MPM.run(*TheModule, MAM); });
+ return Error::success();
}
void EmitAssemblyHelper::TimeCodegenPasses(
More information about the cfe-commits
mailing list