[llvm] [PassManager] Outline pipeline name printing (PR #202655)
David Zbarsky via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 9 07:01:35 PDT 2026
https://github.com/dzbarsky created https://github.com/llvm/llvm-project/pull/202655
PassInfoMixin, RequireAnalysisPass, and InvalidateAnalysisPass instantiate their raw_ostream formatting in every erased pass model. These methods are retained through pass-manager vtables even though pipeline printing is a diagnostic path.
Move the common formatting into two non-template functions in PassManager.cpp. Pass implementations still provide the class name at each call site, preserving pass-name mapping, require/invalidate spelling, and every pass-manager interface while reducing repeated generated code.
In the downstream LLVM 22 all-tool build, the multicall binary shrinks from 161,570,320 to 161,471,536 bytes (-98,784, -0.061%). The minimally stripped binary shrinks from 131,975,944 to 131,876,912 bytes (-99,032, -0.075%). Standalone opt shrinks from 84,127,760 to 84,045,504 bytes (-82,256, -0.098%).
All 41 command forms in llvm/test/Other/new-pm-print-pipeline.ll produce byte-identical stdout, stderr, and exit status. A paired O2 benchmark on large-gep-chain.ll changes CPU time by -0.392% with a 95% confidence interval of [-1.474%, +0.692%].
Work towards #202616
>From 7a768341ca2e55dbef4a15c1a0f7cfb541264a01 Mon Sep 17 00:00:00 2001
From: David Zbarsky <dzbarsky at gmail.com>
Date: Tue, 9 Jun 2026 08:06:23 -0400
Subject: [PATCH] [PassManager] Outline pipeline name printing
PassInfoMixin, RequireAnalysisPass, and InvalidateAnalysisPass instantiate their raw_ostream formatting in every erased pass model. These methods are retained through pass-manager vtables even though pipeline printing is a diagnostic path.
Move the common formatting into two non-template functions in PassManager.cpp. Pass implementations still provide the class name at each call site, preserving pass-name mapping, require/invalidate spelling, and every pass-manager interface while reducing repeated generated code.
In the downstream LLVM 22 all-tool build, the multicall binary shrinks from 161,570,320 to 161,471,536 bytes (-98,784, -0.061%). The minimally stripped binary shrinks from 131,975,944 to 131,876,912 bytes (-99,032, -0.075%). Standalone opt shrinks from 84,127,760 to 84,045,504 bytes (-82,256, -0.098%).
All 41 command forms in llvm/test/Other/new-pm-print-pipeline.ll produce byte-identical stdout, stderr, and exit status. A paired O2 benchmark on large-gep-chain.ll changes CPU time by -0.392% with a 95% confidence interval of [-1.474%, +0.692%].
---
llvm/include/llvm/IR/PassManager.h | 23 ++++++++++++++---------
llvm/lib/IR/PassManager.cpp | 17 +++++++++++++++++
2 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h
index 22e02853bc567..fb4e7bbc5bf78 100644
--- a/llvm/include/llvm/IR/PassManager.h
+++ b/llvm/include/llvm/IR/PassManager.h
@@ -68,6 +68,15 @@ template <typename DerivedT> struct InfoMixin {
return Name;
}
};
+
+LLVM_ABI void
+printPassPipelineName(raw_ostream &OS,
+ function_ref<StringRef(StringRef)> MapClassName2PassName,
+ StringRef ClassName);
+LLVM_ABI void printAnalysisPassPipelineName(
+ raw_ostream &OS,
+ function_ref<StringRef(StringRef)> MapClassName2PassName,
+ StringRef ClassName, bool IsInvalidate);
} // namespace detail
class Function;
@@ -89,9 +98,7 @@ template <typename DerivedT>
struct PassInfoMixin : detail::InfoMixin<DerivedT> {
void printPipeline(raw_ostream &OS,
function_ref<StringRef(StringRef)> MapClassName2PassName) {
- StringRef ClassName = DerivedT::name();
- auto PassName = MapClassName2PassName(ClassName);
- OS << PassName;
+ detail::printPassPipelineName(OS, MapClassName2PassName, DerivedT::name());
}
// TODO: remove once out of tree users are updated.
@@ -936,9 +943,8 @@ struct RequireAnalysisPass
}
void printPipeline(raw_ostream &OS,
function_ref<StringRef(StringRef)> MapClassName2PassName) {
- auto ClassName = AnalysisT::name();
- auto PassName = MapClassName2PassName(ClassName);
- OS << "require<" << PassName << '>';
+ detail::printAnalysisPassPipelineName(
+ OS, MapClassName2PassName, AnalysisT::name(), false);
}
};
@@ -961,9 +967,8 @@ struct InvalidateAnalysisPass
}
void printPipeline(raw_ostream &OS,
function_ref<StringRef(StringRef)> MapClassName2PassName) {
- auto ClassName = AnalysisT::name();
- auto PassName = MapClassName2PassName(ClassName);
- OS << "invalidate<" << PassName << '>';
+ detail::printAnalysisPassPipelineName(
+ OS, MapClassName2PassName, AnalysisT::name(), true);
}
};
diff --git a/llvm/lib/IR/PassManager.cpp b/llvm/lib/IR/PassManager.cpp
index af22b779ddbb0..8f614a0ca5f96 100644
--- a/llvm/lib/IR/PassManager.cpp
+++ b/llvm/lib/IR/PassManager.cpp
@@ -15,6 +15,23 @@
using namespace llvm;
namespace llvm {
+namespace detail {
+void printPassPipelineName(
+ raw_ostream &OS,
+ function_ref<StringRef(StringRef)> MapClassName2PassName,
+ StringRef ClassName) {
+ OS << MapClassName2PassName(ClassName);
+}
+
+void printAnalysisPassPipelineName(
+ raw_ostream &OS,
+ function_ref<StringRef(StringRef)> MapClassName2PassName,
+ StringRef ClassName, bool IsInvalidate) {
+ OS << (IsInvalidate ? "invalidate<" : "require<")
+ << MapClassName2PassName(ClassName) << '>';
+}
+} // namespace detail
+
// Explicit template instantiations and specialization defininitions for core
// template typedefs.
template class LLVM_EXPORT_TEMPLATE AllAnalysesOn<Module>;
More information about the llvm-commits
mailing list