[llvm] [CodeGen][NPM] Support generic regalloc-npm option (PR #172485)
Teja Alaghari via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 16 06:47:41 PST 2025
https://github.com/TejaX-Alaghari created https://github.com/llvm/llvm-project/pull/172485
This PR is a port of [PR#135149](https://github.com/llvm/llvm-project/pull/135149) and provides the `--regalloc-npm` option as an override to register allocation passes added in the New PM codegen pipeline.
>From b7b67c32556417d86d31f573c9b7f336bc5bc730 Mon Sep 17 00:00:00 2001
From: vikhegde <vikram.hegde at amd.com>
Date: Tue, 16 Dec 2025 19:52:01 +0530
Subject: [PATCH 1/2] [CodeGen][NPM] Support generic --regalloc-npm option
This provides the `--regalloc-npm` option as an override to register
allocation passes added in the NewPM codegen pipeline. It accepts a
comma-separated list of passes using the normal `--passes` syntax.
Example: `llc --regalloc-npm='default,default,regallocfast<filter=vgpr>'`
will replace only the third regalloc pass with RAFast.
Key changes:
- Introduce `RA_PASS_WITH_PARAMS` macro to distinguish RA passes from
other MachineFunction passes in MachinePassRegistry.def
- Add `addRegAllocPassFromOpt()` and `addRegAllocPassOrOpt()` helpers
to CodeGenPassBuilder for consuming the option
- Replace `RegAllocType` enum usage with `StringRef RegAllocPipeline`
field in CGPassBuilderOption
- Change parser signatures to accept `const PassBuilder &` for filter
parsing
- Add `PassBuilder &` parameter to `CodeGenPassBuilder` constructor
and `buildCodeGenPipeline` API
- Add X86 tile-register filter support (`tile-reg`)
The number of passes in `--regalloc-npm` should match what the target
pipeline adds. The special value "default" uses the pipeline's default.
Extra passes cause an error.
Co-authored-by: optimisan <76596238+optimisan at users.noreply.github.com>
---
llvm/include/llvm/Passes/CodeGenPassBuilder.h | 86 ++++++++++++----
.../llvm/Passes/MachinePassRegistry.def | 41 +++++---
llvm/include/llvm/Passes/PassBuilder.h | 29 ++++--
.../llvm/Passes/TargetPassRegistry.inc | 2 +-
.../include/llvm/Target/CGPassBuilderOption.h | 2 +-
llvm/include/llvm/Target/TargetMachine.h | 5 +-
llvm/lib/Passes/PassBuilder.cpp | 98 +++++++++++--------
.../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 31 +++---
llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h | 5 +-
llvm/lib/Target/AMDGPU/R600TargetMachine.cpp | 14 +--
llvm/lib/Target/AMDGPU/R600TargetMachine.h | 5 +-
llvm/lib/Target/BPF/BPFTargetMachine.cpp | 3 +-
llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp | 34 +++++--
llvm/lib/Target/X86/X86TargetMachine.cpp | 15 ++-
llvm/lib/Target/X86/X86TargetMachine.h | 11 ++-
.../test/tools/llc/new-pm/regalloc-amdgpu.mir | 5 +
.../llc/new-pm/x86_64-regalloc-pipeline.mir | 28 +++++-
llvm/tools/llc/NewPMDriver.cpp | 21 ++--
18 files changed, 300 insertions(+), 135 deletions(-)
diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index 0e14f2e50ae04..8ac021cb369e7 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -128,6 +128,8 @@
#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
#include "llvm/Transforms/Utils/LowerInvoke.h"
#include <cassert>
+#include <tuple>
+#include <type_traits>
#include <utility>
namespace llvm {
@@ -168,8 +170,9 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
public:
explicit CodeGenPassBuilder(TargetMachineT &TM,
const CGPassBuilderOption &Opts,
- PassInstrumentationCallbacks *PIC)
- : TM(TM), Opt(Opts), PIC(PIC) {
+ PassInstrumentationCallbacks *PIC,
+ PassBuilder &PB)
+ : TM(TM), Opt(Opts), PIC(PIC), PB(PB) {
// Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
// substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
@@ -356,6 +359,8 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
TargetMachineT &TM;
CGPassBuilderOption Opt;
PassInstrumentationCallbacks *PIC;
+ PassBuilder &PB;
+ mutable IntrusiveRefCntPtr<AsmPrinter> PrinterImpl;
template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
CodeGenOptLevel getOptLevel() const { return TM.getOptLevel(); }
@@ -563,6 +568,15 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
/// addMachinePasses helper to create the target-selected or overriden
/// regalloc pass.
void addRegAllocPass(AddMachinePass &, bool Optimized) const;
+ /// Read the --regalloc-npm option to add the next pass in line.
+ /// Returns false if no pass is left in the option.
+ bool addRegAllocPassFromOpt(AddMachinePass &,
+ StringRef MatchPassTo = StringRef{}) const;
+ /// Add the next pass in the cli option or the pass specified if no pass is
+ /// left in the option.
+ template <typename RegAllocPassBuilderT>
+ void addRegAllocPassOrOpt(AddMachinePass &,
+ RegAllocPassBuilderT PassBuilder) const;
/// Add core register alloator passes which do the actual register assignment
/// and rewriting. \returns true if any passes were added.
@@ -667,6 +681,11 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
if (PrintMIR)
addPass(PrintMIRPass(Out), /*Force=*/true);
+ if (!Opt.RegAllocPipeline.empty())
+ return make_error<StringError>(
+ "extra passes in regalloc pipeline: " + Opt.RegAllocPipeline,
+ std::make_error_code(std::errc::invalid_argument));
+
return verifyStartStop(*StartStopInfo);
}
@@ -1176,6 +1195,48 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
addPass(RegAllocFastPass());
}
+template <typename Derived, typename TargetMachineT>
+template <typename RegAllocPassBuilderT>
+void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPassOrOpt(
+ AddMachinePass &addPass, RegAllocPassBuilderT PassBuilder) const {
+ if (!addRegAllocPassFromOpt(addPass))
+ addPass(std::move(PassBuilder()));
+}
+
+template <typename Derived, typename TargetMachineT>
+bool CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPassFromOpt(
+ AddMachinePass &addPass, StringRef MatchPassTo) const {
+ if (!Opt.RegAllocPipeline.empty()) {
+ StringRef PassOpt;
+ std::tie(PassOpt, Opt.RegAllocPipeline) = Opt.RegAllocPipeline.split(',');
+ // Reuse the registered parser to parse the pass name.
+#define RA_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
+ if (PB.checkParametrizedPassName(PassOpt, NAME)) { \
+ auto Params = PB.parsePassParameters(PARSER, PassOpt, NAME, \
+ const_cast<const PassBuilder &>(PB)); \
+ if (!Params) { \
+ auto Err = Params.takeError(); \
+ ExitOnError()(std::move(Err)); \
+ } \
+ if (!MatchPassTo.empty()) { \
+ if (MatchPassTo != CLASS) \
+ report_fatal_error("expected " + \
+ PIC->getPassNameForClassName(MatchPassTo) + \
+ " in option --regalloc-npm", \
+ false); \
+ } \
+ addPass(CREATE_PASS(Params.get())); \
+ return true; \
+ }
+#include "llvm/Passes/MachinePassRegistry.def"
+ if (PassOpt != "default") {
+ report_fatal_error("unknown register allocator pass: " + PassOpt, false);
+ }
+ }
+ // If user did not give a specific pass, use the default provided.
+ return false;
+}
+
/// Find and instantiate the register allocation pass requested by this target
/// at the current optimization level. Different register allocators are
/// defined as separate passes because they may require different analysis.
@@ -1186,22 +1247,13 @@ template <typename Derived, typename TargetMachineT>
void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPass(
AddMachinePass &addPass, bool Optimized) const {
// Use the specified -regalloc-npm={basic|greedy|fast|pbqp}
- if (Opt.RegAlloc > RegAllocType::Default) {
- switch (Opt.RegAlloc) {
- case RegAllocType::Fast:
- addPass(RegAllocFastPass());
- break;
- case RegAllocType::Greedy:
- addPass(RAGreedyPass());
- break;
- default:
- reportFatalUsageError("register allocator not supported yet");
- }
- return;
+ StringRef RegAllocPassName;
+ if (!Optimized)
+ RegAllocPassName = RegAllocFastPass::name();
+
+ if (!addRegAllocPassFromOpt(addPass, RegAllocPassName)) {
+ derived().addTargetRegisterAllocator(addPass, Optimized);
}
- // -regalloc=default or unspecified, so pick based on the optimization level
- // or ask the target for the regalloc pass.
- derived().addTargetRegisterAllocator(addPass, Optimized);
}
template <typename Derived, typename TargetMachineT>
diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index 04a0da06fb6ec..94ce9cf25d6db 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -194,8 +194,8 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
MACHINE_FUNCTION_PASS_WITH_PARAMS(
"branch-folder", "BranchFolderPass",
[](bool EnableTailMerge) { return BranchFolderPass(EnableTailMerge); },
- [](StringRef Params) {
- return parseSinglePassOption(Params, "enable-tail-merge",
+ [](StringRef Params, const PassBuilder &) {
+ return PassBuilder::parseSinglePassOption(Params, "enable-tail-merge",
"BranchFolderPass");
},
"enable-tail-merge")
@@ -205,8 +205,8 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
[](bool ShouldEmitDebugEntryValues) {
return LiveDebugValuesPass(ShouldEmitDebugEntryValues);
},
- [](StringRef Params) {
- return parseSinglePassOption(Params, "emit-debug-entry-values",
+ [](StringRef Params, const PassBuilder &) {
+ return PassBuilder::parseSinglePassOption(Params, "emit-debug-entry-values",
"LiveDebugValuesPass");
},
"emit-debug-entry-values")
@@ -219,27 +219,36 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
parseMachineSinkingPassOptions, "enable-sink-fold")
MACHINE_FUNCTION_PASS_WITH_PARAMS(
+ "virt-reg-rewriter", "VirtRegRewriterPass",
+ [](bool ClearVirtRegs) { return VirtRegRewriterPass(ClearVirtRegs); },
+ parseVirtRegRewriterPassOptions, "no-clear-vregs;clear-vregs")
+
+#ifndef RA_PASS_WITH_PARAMS
+// Define MachineFunction passes that are register allocators.
+// This is to differentiate them from other MachineFunction passes
+// to be used in the --regalloc-npm option.
+#define RA_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
+ MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS)
+#endif
+
+RA_PASS_WITH_PARAMS(
"regallocfast", "RegAllocFastPass",
[](RegAllocFastPass::Options Opts) { return RegAllocFastPass(Opts); },
- [PB = this](StringRef Params) {
- return parseRegAllocFastPassOptions(*PB, Params);
+ [](StringRef Params, const PassBuilder &PB) {
+ return parseRegAllocFastPassOptions(PB, Params);
},
"filter=reg-filter;no-clear-vregs")
// 'all' is the default filter.
-MACHINE_FUNCTION_PASS_WITH_PARAMS(
+RA_PASS_WITH_PARAMS(
"greedy", "RAGreedyPass",
[](RAGreedyPass::Options Opts) { return RAGreedyPass(Opts); },
- [PB = this](StringRef Params) {
- return parseRegAllocGreedyFilterFunc(*PB, Params);
- }, "reg-filter"
-)
-
-MACHINE_FUNCTION_PASS_WITH_PARAMS(
- "virt-reg-rewriter", "VirtRegRewriterPass",
- [](bool ClearVirtRegs) { return VirtRegRewriterPass(ClearVirtRegs); },
- parseVirtRegRewriterPassOptions, "no-clear-vregs;clear-vregs")
+ [](StringRef Params, const PassBuilder &PB) {
+ return parseRegAllocGreedyFilterFunc(PB, Params);
+ },
+ "reg-filter")
+#undef RA_PASS_WITH_PARAMS
#undef MACHINE_FUNCTION_PASS_WITH_PARAMS
// After a pass is converted to new pass manager, its entry should be moved from
diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h
index 00d4874d5109b..2ad596c6c5739 100644
--- a/llvm/include/llvm/Passes/PassBuilder.h
+++ b/llvm/include/llvm/Passes/PassBuilder.h
@@ -18,6 +18,7 @@
#include "llvm/Analysis/CGSCCPassManager.h"
#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/RegAllocCommon.h"
+#include "llvm/CodeGen/RegAllocGreedyPass.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Passes/OptimizationLevel.h"
#include "llvm/Support/Compiler.h"
@@ -409,7 +410,7 @@ class PassBuilder {
/// Parse RegAllocFilterName to get RegAllocFilterFunc.
LLVM_ABI std::optional<RegAllocFilterFunc>
- parseRegAllocFilter(StringRef RegAllocFilterName);
+ parseRegAllocFilter(StringRef RegAllocFilterName) const;
/// Print pass names.
LLVM_ABI void printPassNames(raw_ostream &OS);
@@ -708,11 +709,13 @@ class PassBuilder {
/// parameter list in a form of a custom parameters type, all wrapped into
/// Expected<> template class.
///
- template <typename ParametersParseCallableT>
+ template <typename ParametersParseCallableT, typename... ExtraArgs>
static auto parsePassParameters(ParametersParseCallableT &&Parser,
- StringRef Name, StringRef PassName)
- -> decltype(Parser(StringRef{})) {
- using ParametersT = typename decltype(Parser(StringRef{}))::value_type;
+ StringRef Name, StringRef PassName,
+ ExtraArgs &&...Args)
+ -> decltype(Parser(StringRef{}, std::forward<ExtraArgs>(Args)...)) {
+ using ParametersT = typename decltype(Parser(
+ StringRef{}, std::forward<ExtraArgs>(Args)...))::value_type;
StringRef Params = Name;
if (!Params.consume_front(PassName)) {
@@ -724,7 +727,8 @@ class PassBuilder {
llvm_unreachable("invalid format for parametrized pass name");
}
- Expected<ParametersT> Result = Parser(Params);
+ Expected<ParametersT> Result =
+ Parser(Params, std::forward<ExtraArgs>(Args)...);
assert((Result || Result.template errorIsA<StringError>()) &&
"Pass parameter parser can only return StringErrors.");
return Result;
@@ -1000,6 +1004,19 @@ class NoOpLoopAnalysis : public AnalysisInfoMixin<NoOpLoopAnalysis> {
/// Common option used by multiple tools to print pipeline passes
LLVM_ABI extern cl::opt<bool> PrintPipelinePasses;
+
+Expected<RAGreedyPass::Options>
+parseRegAllocGreedyFilterFunc(const PassBuilder &PB, StringRef Params);
+
+Expected<RegAllocFastPass::Options>
+parseRegAllocFastPassOptions(const PassBuilder &PB, StringRef Params);
+
+Expected<bool> parseMachineSinkingPassOptions(StringRef Params,
+ const PassBuilder &);
+Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params,
+ const PassBuilder &);
+Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params,
+ const PassBuilder &);
}
#endif
diff --git a/llvm/include/llvm/Passes/TargetPassRegistry.inc b/llvm/include/llvm/Passes/TargetPassRegistry.inc
index 068b27794191c..b50857eca31b6 100644
--- a/llvm/include/llvm/Passes/TargetPassRegistry.inc
+++ b/llvm/include/llvm/Passes/TargetPassRegistry.inc
@@ -83,7 +83,7 @@ if (PIC) {
#define ADD_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \
if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
- auto Params = PassBuilder::parsePassParameters(PARSER, Name, NAME); \
+ auto Params = PassBuilder::parsePassParameters(PARSER, Name, NAME, PB); \
if (!Params) { \
errs() << NAME ": " << toString(Params.takeError()) << '\n'; \
return false; \
diff --git a/llvm/include/llvm/Target/CGPassBuilderOption.h b/llvm/include/llvm/Target/CGPassBuilderOption.h
index 54bee9de7a093..d2c72351c60d4 100644
--- a/llvm/include/llvm/Target/CGPassBuilderOption.h
+++ b/llvm/include/llvm/Target/CGPassBuilderOption.h
@@ -79,7 +79,7 @@ struct CGPassBuilderOption {
bool RequiresCodeGenSCCOrder = false;
RunOutliner EnableMachineOutliner = RunOutliner::TargetDefault;
- RegAllocType RegAlloc = RegAllocType::Unset;
+ mutable StringRef RegAllocPipeline;
std::optional<GlobalISelAbortMode> EnableGlobalISelAbort;
std::string FSProfileFile;
std::string FSRemappingFile;
diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h
index d0fd483a8ddaa..41afd28a20b74 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -487,8 +487,9 @@ class LLVM_ABI TargetMachine {
virtual Error buildCodeGenPipeline(ModulePassManager &, raw_pwrite_stream &,
raw_pwrite_stream *, CodeGenFileType,
- const CGPassBuilderOption &,
- PassInstrumentationCallbacks *) {
+ const CGPassBuilderOption &, MCContext &,
+ PassInstrumentationCallbacks *,
+ PassBuilder &) {
return make_error<StringError>("buildCodeGenPipeline is not overridden",
inconvertibleErrorCode());
}
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index f5281ea69b512..d2c16d4085fcd 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -1545,39 +1545,6 @@ Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
}
-Expected<RegAllocFastPass::Options>
-parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
- RegAllocFastPass::Options Opts;
- while (!Params.empty()) {
- StringRef ParamName;
- std::tie(ParamName, Params) = Params.split(';');
-
- if (ParamName.consume_front("filter=")) {
- std::optional<RegAllocFilterFunc> Filter =
- PB.parseRegAllocFilter(ParamName);
- if (!Filter) {
- return make_error<StringError>(
- formatv("invalid regallocfast register filter '{}'", ParamName)
- .str(),
- inconvertibleErrorCode());
- }
- Opts.Filter = *Filter;
- Opts.FilterName = ParamName;
- continue;
- }
-
- if (ParamName == "no-clear-vregs") {
- Opts.ClearVRegs = false;
- continue;
- }
-
- return make_error<StringError>(
- formatv("invalid regallocfast pass parameter '{}'", ParamName).str(),
- inconvertibleErrorCode());
- }
- return Opts;
-}
-
Expected<BoundsCheckingPass::Options>
parseBoundsCheckingOptions(StringRef Params) {
BoundsCheckingPass::Options Options;
@@ -1632,6 +1599,7 @@ parseBoundsCheckingOptions(StringRef Params) {
}
return Options;
}
+} // namespace
Expected<CodeGenOptLevel> parseExpandFpOptions(StringRef Param) {
if (Param.empty())
@@ -1668,12 +1636,15 @@ parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
inconvertibleErrorCode());
}
-Expected<bool> parseMachineSinkingPassOptions(StringRef Params) {
+Expected<bool> llvm::parseMachineSinkingPassOptions(StringRef Params,
+ const PassBuilder &) {
return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
"MachineSinkingPass");
}
-Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
+Expected<bool>
+llvm::parseMachineBlockPlacementPassOptions(StringRef Params,
+ const PassBuilder &) {
bool AllowTailMerge = true;
if (!Params.empty()) {
AllowTailMerge = !Params.consume_front("no-");
@@ -1686,7 +1657,8 @@ Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
return AllowTailMerge;
}
-Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
+Expected<bool> llvm::parseVirtRegRewriterPassOptions(StringRef Params,
+ const PassBuilder &) {
bool ClearVirtRegs = true;
if (!Params.empty()) {
ClearVirtRegs = !Params.consume_front("no-");
@@ -1698,6 +1670,53 @@ Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
return ClearVirtRegs;
}
+Expected<RegAllocFastPass::Options>
+llvm::parseRegAllocFastPassOptions(const PassBuilder &PB, StringRef Params) {
+ RegAllocFastPass::Options Opts;
+ while (!Params.empty()) {
+ StringRef ParamName;
+ std::tie(ParamName, Params) = Params.split(';');
+
+ if (ParamName.consume_front("filter=")) {
+ std::optional<RegAllocFilterFunc> Filter =
+ PB.parseRegAllocFilter(ParamName);
+ if (!Filter) {
+ return make_error<StringError>(
+ formatv("invalid regallocfast register filter '{0}' ", ParamName)
+ .str(),
+ inconvertibleErrorCode());
+ }
+ Opts.Filter = *Filter;
+ Opts.FilterName = ParamName;
+ continue;
+ }
+
+ if (ParamName == "no-clear-vregs") {
+ Opts.ClearVRegs = false;
+ continue;
+ }
+
+ return make_error<StringError>(
+ formatv("invalid regallocfast pass parameter '{0}' ", ParamName).str(),
+ inconvertibleErrorCode());
+ }
+ return Opts;
+}
+
+Expected<RAGreedyPass::Options>
+llvm::parseRegAllocGreedyFilterFunc(const PassBuilder &PB, StringRef Params) {
+ if (Params.empty() || Params == "all")
+ return RAGreedyPass::Options();
+
+ std::optional<RegAllocFilterFunc> Filter = PB.parseRegAllocFilter(Params);
+ if (Filter)
+ return RAGreedyPass::Options{*Filter, Params};
+
+ return make_error<StringError>(
+ formatv("invalid regallocgreedy register filter '{0}' ", Params).str(),
+ inconvertibleErrorCode());
+}
+
struct FatLTOOptions {
OptimizationLevel OptLevel;
bool ThinLTO = false;
@@ -1733,8 +1752,6 @@ Expected<FatLTOOptions> parseFatLTOOptions(StringRef Params) {
return Result;
}
-} // namespace
-
/// Tests whether registered callbacks will accept a given pass name.
///
/// When parsing a pipeline text, the type of the outermost pipeline may be
@@ -2478,7 +2495,8 @@ Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
PARAMS) \
if (checkParametrizedPassName(Name, NAME)) { \
- auto Params = parsePassParameters(PARSER, Name, NAME); \
+ auto Params = parsePassParameters(PARSER, Name, NAME, \
+ const_cast<const PassBuilder &>(*this)); \
if (!Params) \
return Params.takeError(); \
MFPM.addPass(CREATE_PASS(Params.get())); \
@@ -2744,7 +2762,7 @@ Error PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
}
std::optional<RegAllocFilterFunc>
-PassBuilder::parseRegAllocFilter(StringRef FilterName) {
+PassBuilder::parseRegAllocFilter(StringRef FilterName) const {
if (FilterName == "all")
return nullptr;
for (auto &C : RegClassFilterParsingCallbacks)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 8a831f7915882..279d66f4d969d 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -140,7 +140,8 @@ class AMDGPUCodeGenPassBuilder
public:
AMDGPUCodeGenPassBuilder(GCNTargetMachine &TM,
const CGPassBuilderOption &Opts,
- PassInstrumentationCallbacks *PIC);
+ PassInstrumentationCallbacks *PIC,
+ PassBuilder &PB);
void addIRPasses(AddIRPass &) const;
void addCodeGenPrepare(AddIRPass &) const;
@@ -817,7 +818,7 @@ void AMDGPUTargetMachine::registerDefaultAliasAnalyses(AAManager &AAM) {
}
static Expected<ScanOptions>
-parseAMDGPUAtomicOptimizerStrategy(StringRef Params) {
+parseAMDGPUAtomicOptimizerStrategy(StringRef Params, const PassBuilder &) {
if (Params.empty())
return ScanOptions::Iterative;
Params.consume_front("strategy=");
@@ -831,8 +832,8 @@ parseAMDGPUAtomicOptimizerStrategy(StringRef Params) {
return make_error<StringError>("invalid parameter", inconvertibleErrorCode());
}
-Expected<AMDGPUAttributorOptions>
-parseAMDGPUAttributorPassOptions(StringRef Params) {
+static Expected<AMDGPUAttributorOptions>
+parseAMDGPUAttributorPassOptions(StringRef Params, const PassBuilder &PB) {
AMDGPUAttributorOptions Result;
while (!Params.empty()) {
StringRef ParamName;
@@ -1159,10 +1160,10 @@ GCNTargetMachine::getTargetTransformInfo(const Function &F) const {
Error GCNTargetMachine::buildCodeGenPipeline(
ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
- CodeGenFileType FileType, const CGPassBuilderOption &Opts,
- PassInstrumentationCallbacks *PIC) {
- AMDGPUCodeGenPassBuilder CGPB(*this, Opts, PIC);
- return CGPB.buildPipeline(MPM, Out, DwoOut, FileType);
+ CodeGenFileType FileType, const CGPassBuilderOption &Opts, MCContext &Ctx,
+ PassInstrumentationCallbacks *PIC, PassBuilder &PB) {
+ AMDGPUCodeGenPassBuilder CGPB(*this, Opts, PIC, PB);
+ return CGPB.buildPipeline(MPM, Out, DwoOut, FileType, Ctx);
}
ScheduleDAGInstrs *
@@ -2089,8 +2090,8 @@ bool GCNTargetMachine::parseMachineFunctionInfo(
AMDGPUCodeGenPassBuilder::AMDGPUCodeGenPassBuilder(
GCNTargetMachine &TM, const CGPassBuilderOption &Opts,
- PassInstrumentationCallbacks *PIC)
- : CodeGenPassBuilder(TM, Opts, PIC) {
+ PassInstrumentationCallbacks *PIC, PassBuilder &PB)
+ : CodeGenPassBuilder(TM, Opts, PIC, PB) {
Opt.MISchedPostRA = true;
Opt.RequiresCodeGenSCCOrder = true;
// Exceptions and StackMaps are not supported, so these passes will never do
@@ -2341,7 +2342,8 @@ Error AMDGPUCodeGenPassBuilder::addRegAssignmentOptimized(
addPass(GCNPreRALongBranchRegPass());
- addPass(RAGreedyPass({onlyAllocateSGPRs, "sgpr"}));
+ addRegAllocPassOrOpt(
+ addPass, []() { return RAGreedyPass({onlyAllocateSGPRs, "sgpr"}); });
// Commit allocated register changes. This is mostly necessary because too
// many things rely on the use lists of the physical registers, such as the
@@ -2361,14 +2363,15 @@ Error AMDGPUCodeGenPassBuilder::addRegAssignmentOptimized(
addPass(SIPreAllocateWWMRegsPass());
// For allocating other wwm register operands.
- addPass(RAGreedyPass({onlyAllocateWWMRegs, "wwm"}));
+ addRegAllocPassOrOpt(
+ addPass, []() { return RAGreedyPass({onlyAllocateWWMRegs, "wwm"}); });
addPass(SILowerWWMCopiesPass());
addPass(VirtRegRewriterPass(false));
addPass(AMDGPUReserveWWMRegsPass());
// For allocating per-thread VGPRs.
- addPass(RAGreedyPass({onlyAllocateVGPRs, "vgpr"}));
-
+ addRegAllocPassOrOpt(
+ addPass, []() { return RAGreedyPass({onlyAllocateVGPRs, "vgpr"}); });
addPreRewrite(addPass);
addPass(VirtRegRewriterPass(true));
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h
index 06a3047196b8a..34e7a189291ed 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h
@@ -100,8 +100,9 @@ class GCNTargetMachine final : public AMDGPUTargetMachine {
Error buildCodeGenPipeline(ModulePassManager &MPM, raw_pwrite_stream &Out,
raw_pwrite_stream *DwoOut,
CodeGenFileType FileType,
- const CGPassBuilderOption &Opts,
- PassInstrumentationCallbacks *PIC) override;
+ const CGPassBuilderOption &Opts, MCContext &Ctx,
+ PassInstrumentationCallbacks *PIC,
+ PassBuilder &) override;
void registerMachineRegisterInfoCallback(MachineFunction &MF) const override;
diff --git a/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp b/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
index c20487ebd8fc9..8ac8d3addb374 100644
--- a/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
@@ -55,7 +55,7 @@ class R600CodeGenPassBuilder
: public CodeGenPassBuilder<R600CodeGenPassBuilder, R600TargetMachine> {
public:
R600CodeGenPassBuilder(R600TargetMachine &TM, const CGPassBuilderOption &Opts,
- PassInstrumentationCallbacks *PIC);
+ PassInstrumentationCallbacks *PIC, PassBuilder &PB);
void addPreISel(AddIRPass &addPass) const;
void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
@@ -164,10 +164,10 @@ TargetPassConfig *R600TargetMachine::createPassConfig(PassManagerBase &PM) {
Error R600TargetMachine::buildCodeGenPipeline(
ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
- CodeGenFileType FileType, const CGPassBuilderOption &Opts,
- PassInstrumentationCallbacks *PIC) {
- R600CodeGenPassBuilder CGPB(*this, Opts, PIC);
- return CGPB.buildPipeline(MPM, Out, DwoOut, FileType);
+ CodeGenFileType FileType, const CGPassBuilderOption &Opts, MCContext &Ctx,
+ PassInstrumentationCallbacks *PIC, PassBuilder &PB) {
+ R600CodeGenPassBuilder CGPB(*this, Opts, PIC, PB);
+ return CGPB.buildPipeline(MPM, Out, DwoOut, FileType, Ctx);
}
MachineFunctionInfo *R600TargetMachine::createMachineFunctionInfo(
@@ -183,8 +183,8 @@ MachineFunctionInfo *R600TargetMachine::createMachineFunctionInfo(
R600CodeGenPassBuilder::R600CodeGenPassBuilder(
R600TargetMachine &TM, const CGPassBuilderOption &Opts,
- PassInstrumentationCallbacks *PIC)
- : CodeGenPassBuilder(TM, Opts, PIC) {
+ PassInstrumentationCallbacks *PIC, PassBuilder &PB)
+ : CodeGenPassBuilder(TM, Opts, PIC, PB) {
Opt.RequiresCodeGenSCCOrder = true;
}
diff --git a/llvm/lib/Target/AMDGPU/R600TargetMachine.h b/llvm/lib/Target/AMDGPU/R600TargetMachine.h
index 7985ef136cead..b4ef4aaef4490 100644
--- a/llvm/lib/Target/AMDGPU/R600TargetMachine.h
+++ b/llvm/lib/Target/AMDGPU/R600TargetMachine.h
@@ -41,8 +41,9 @@ class R600TargetMachine final : public AMDGPUTargetMachine {
Error buildCodeGenPipeline(ModulePassManager &MPM, raw_pwrite_stream &Out,
raw_pwrite_stream *DwoOut,
CodeGenFileType FileType,
- const CGPassBuilderOption &Opt,
- PassInstrumentationCallbacks *PIC) override;
+ const CGPassBuilderOption &Opt, MCContext &Ctx,
+ PassInstrumentationCallbacks *PIC,
+ PassBuilder &) override;
const TargetSubtargetInfo *getSubtargetImpl(const Function &) const override;
diff --git a/llvm/lib/Target/BPF/BPFTargetMachine.cpp b/llvm/lib/Target/BPF/BPFTargetMachine.cpp
index ad3df2c879fe7..0bcfdb5f53855 100644
--- a/llvm/lib/Target/BPF/BPFTargetMachine.cpp
+++ b/llvm/lib/Target/BPF/BPFTargetMachine.cpp
@@ -114,7 +114,8 @@ TargetPassConfig *BPFTargetMachine::createPassConfig(PassManagerBase &PM) {
return new BPFPassConfig(*this, PM);
}
-static Expected<bool> parseBPFPreserveStaticOffsetOptions(StringRef Params) {
+static Expected<bool> parseBPFPreserveStaticOffsetOptions(StringRef Params,
+ const PassBuilder &) {
return PassBuilder::parseSinglePassOption(Params, "allow-partial",
"BPFPreserveStaticOffsetPass");
}
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index 2c0443da673a8..864cdc0b4547a 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -27,13 +27,27 @@ class X86CodeGenPassBuilder
public:
explicit X86CodeGenPassBuilder(X86TargetMachine &TM,
const CGPassBuilderOption &Opts,
- PassInstrumentationCallbacks *PIC)
- : CodeGenPassBuilder(TM, Opts, PIC) {}
+ PassInstrumentationCallbacks *PIC,
+ PassBuilder &PB)
+ : CodeGenPassBuilder(TM, Opts, PIC, PB) {}
+ using Base = CodeGenPassBuilder<X86CodeGenPassBuilder, X86TargetMachine>;
void addPreISel(AddIRPass &addPass) const;
void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
Error addInstSelector(AddMachinePass &) const;
+ Error addRegAssignmentOptimized(AddMachinePass &addPass) const;
};
+Error X86CodeGenPassBuilder::addRegAssignmentOptimized(
+ AddMachinePass &addPass) const {
+ if (EnableTileRAPass) {
+ addRegAllocPassOrOpt(addPass, []() {
+ return RAGreedyPass({onlyAllocateTileRegisters, "tile-reg"});
+ });
+ // TODO: addPass(X86TileConfigPass());
+ }
+ return Base::addRegAssignmentOptimized(addPass);
+}
+
void X86CodeGenPassBuilder::addPreISel(AddIRPass &addPass) const {
// TODO: Add passes pre instruction selection.
}
@@ -54,12 +68,20 @@ Error X86CodeGenPassBuilder::addInstSelector(AddMachinePass &addPass) const {
void X86TargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
#define GET_PASS_REGISTRY "X86PassRegistry.def"
#include "llvm/Passes/TargetPassRegistry.inc"
+
+PB.registerRegClassFilterParsingCallback(
+ [](StringRef FilterName) -> RegAllocFilterFunc {
+ if (FilterName == "tile-reg") {
+ return onlyAllocateTileRegisters;
+ }
+ return nullptr;
+ });
}
Error X86TargetMachine::buildCodeGenPipeline(
ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
- CodeGenFileType FileType, const CGPassBuilderOption &Opt,
- PassInstrumentationCallbacks *PIC) {
- auto CGPB = X86CodeGenPassBuilder(*this, Opt, PIC);
- return CGPB.buildPipeline(MPM, Out, DwoOut, FileType);
+ CodeGenFileType FileType, const CGPassBuilderOption &Opt, MCContext &Ctx,
+ PassInstrumentationCallbacks *PIC, PassBuilder &PB) {
+ auto CGPB = X86CodeGenPassBuilder(*this, Opt, PIC, PB);
+ return CGPB.buildPipeline(MPM, Out, DwoOut, FileType, Ctx);
}
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index 713df63479987..dab5d53402722 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -56,11 +56,10 @@ using namespace llvm;
static cl::opt<bool> EnableMachineCombinerPass("x86-machine-combiner",
cl::desc("Enable the machine combiner pass"),
cl::init(true), cl::Hidden);
-
-static cl::opt<bool>
- EnableTileRAPass("x86-tile-ra",
- cl::desc("Enable the tile register allocation pass"),
- cl::init(true), cl::Hidden);
+cl::opt<bool>
+ llvm::EnableTileRAPass("x86-tile-ra",
+ cl::desc("Enable the tile register allocation pass"),
+ cl::init(true), cl::Hidden);
extern "C" LLVM_C_ABI void LLVMInitializeX86Target() {
// Register the target.
@@ -635,9 +634,9 @@ std::unique_ptr<CSEConfigBase> X86PassConfig::getCSEConfig() const {
return getStandardCSEConfigForOpt(TM->getOptLevel());
}
-static bool onlyAllocateTileRegisters(const TargetRegisterInfo &TRI,
- const MachineRegisterInfo &MRI,
- const Register Reg) {
+bool llvm::onlyAllocateTileRegisters(const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI,
+ const Register Reg) {
const TargetRegisterClass *RC = MRI.getRegClass(Reg);
return static_cast<const X86RegisterInfo &>(TRI).isTileRegisterClass(RC);
}
diff --git a/llvm/lib/Target/X86/X86TargetMachine.h b/llvm/lib/Target/X86/X86TargetMachine.h
index ced0a9c71fdd8..47c75c1b4d48b 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.h
+++ b/llvm/lib/Target/X86/X86TargetMachine.h
@@ -22,9 +22,15 @@
namespace llvm {
+extern cl::opt<bool> EnableTileRAPass;
+
class StringRef;
class TargetTransformInfo;
+bool onlyAllocateTileRegisters(const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI,
+ const Register Reg);
+
class X86TargetMachine final : public CodeGenTargetMachineImpl {
std::unique_ptr<TargetLoweringObjectFile> TLOF;
mutable StringMap<std::unique_ptr<X86Subtarget>> SubtargetMap;
@@ -73,8 +79,9 @@ class X86TargetMachine final : public CodeGenTargetMachineImpl {
Error buildCodeGenPipeline(ModulePassManager &, raw_pwrite_stream &,
raw_pwrite_stream *, CodeGenFileType,
- const CGPassBuilderOption &,
- PassInstrumentationCallbacks *) override;
+ const CGPassBuilderOption &, MCContext &,
+ PassInstrumentationCallbacks *,
+ PassBuilder &) override;
bool isJIT() const { return IsJIT; }
diff --git a/llvm/test/tools/llc/new-pm/regalloc-amdgpu.mir b/llvm/test/tools/llc/new-pm/regalloc-amdgpu.mir
index 07f2d350ffd9c..7c8b9a9e04dc1 100644
--- a/llvm/test/tools/llc/new-pm/regalloc-amdgpu.mir
+++ b/llvm/test/tools/llc/new-pm/regalloc-amdgpu.mir
@@ -2,11 +2,16 @@
# RUN: llc -mtriple=amdgcn --passes='regallocfast<filter=sgpr>,regallocfast<filter=wwm>,regallocfast<filter=vgpr>' --print-pipeline-passes --filetype=null %s | FileCheck %s --check-prefix=PASS
# RUN: not llc -mtriple=amdgcn --passes='regallocfast<filter=bad-filter>' --print-pipeline-passes --filetype=null %s 2>&1 | FileCheck %s --check-prefix=BAD-FILTER
+# RUN: llc -mtriple=amdgcn -enable-new-pm --regalloc-npm="regallocfast<filter=sgpr;no-clear-vregs>,greedy<wwm>" --print-pipeline-passes --filetype=null %s | FileCheck %s --check-prefix=RA-NPM
+
# PASS: regallocfast<filter=sgpr>
# PASS: regallocfast<filter=wwm>
# PASS: regallocfast<filter=vgpr>
# BAD-FILTER: invalid regallocfast register filter 'bad-filter'
+# RA-NPM: regallocfast<filter=sgpr;no-clear-vregs>
+# RA-NPM: greedy<wwm>
+# RA-NPM: greedy<vgpr>
---
name: f
...
diff --git a/llvm/test/tools/llc/new-pm/x86_64-regalloc-pipeline.mir b/llvm/test/tools/llc/new-pm/x86_64-regalloc-pipeline.mir
index 7a50bcaf212c7..6de98c5f14f26 100644
--- a/llvm/test/tools/llc/new-pm/x86_64-regalloc-pipeline.mir
+++ b/llvm/test/tools/llc/new-pm/x86_64-regalloc-pipeline.mir
@@ -1,6 +1,28 @@
# REQUIRES: x86-registered-target
-# RUN: llc -mtriple=x86_64-unknown-linux-gnu -enable-new-pm -O3 -regalloc-npm=fast -print-pipeline-passes %s -o - 2>&1 | FileCheck %s
-# RUN: llc -mtriple=x86_64-unknown-linux-gnu -enable-new-pm -O3 -regalloc-npm=greedy -print-pipeline-passes %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-GREEDY
+# Test default pipeline
+# RUN: llc -mtriple=x86_64-unknown-linux-gnu -enable-new-pm -O3 -print-pipeline-passes %s -o - 2>&1 | FileCheck %s
-# CHECK: regallocfast
+# Test the -regalloc-npm option
+# RUN: llc -mtriple=x86_64-unknown-linux-gnu -enable-new-pm -O3 -regalloc-npm=regallocfast -print-pipeline-passes %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-FAST
+
+# RUN: llc -mtriple=x86_64-unknown-linux-gnu -enable-new-pm -O3 -regalloc-npm='greedy<tile-reg>' -print-pipeline-passes %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-GREEDY-FILTER
+
+# This test attempts to bypass the tile register filter pass, inserts the default greedy<all> pass and then
+# attempts to insert an extraneous pass.
+# RUN: not llc -mtriple=x86_64-unknown-linux-gnu -enable-new-pm -O3 -regalloc-npm='default,default,basic' 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
+
+# RUN: not llc -mtriple=x86_64-unknown-linux-gnu -enable-new-pm -O3 -regalloc-npm='machine-cp' -print-pipeline-passes %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID
+# RUN: not llc -mtriple=x86_64-unknown-linux-gnu -enable-new-pm -passes='machine-sink' -regalloc-npm='greedy' -print-pipeline-passes %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-BOTH-INVALID
+
+# RUN: not llc -mtriple=x86_64-unknown-linux-gnu -enable-new-pm -O0 -regalloc-npm='greedy' -print-pipeline-passes %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-FAST
+
+# CHECK: greedy<tile-reg>
+# CHECK: greedy<all>
+
+# CHECK-FAST: regallocfast
# CHECK-GREEDY: greedy<all>
+# CHECK-GREEDY-FILTER: greedy<tile-reg>
+# CHECK-ERROR: extra passes in regalloc pipeline: basic
+# CHECK-INVALID: unknown register allocator pass: machine-cp
+# CHECK-BOTH-INVALID: --passes and --regalloc-npm cannot be used together
+# CHECK-ONLY-FAST: expected regallocfast in option --regalloc-npm
diff --git a/llvm/tools/llc/NewPMDriver.cpp b/llvm/tools/llc/NewPMDriver.cpp
index 6d4989e278fc1..2caaf956e50c6 100644
--- a/llvm/tools/llc/NewPMDriver.cpp
+++ b/llvm/tools/llc/NewPMDriver.cpp
@@ -50,10 +50,11 @@
using namespace llvm;
-static cl::opt<RegAllocType, false, RegAllocTypeParser>
- RegAlloc("regalloc-npm",
- cl::desc("Register allocator to use for new pass manager"),
- cl::Hidden, cl::init(RegAllocType::Unset));
+static cl::opt<std::string> RegAllocPasses(
+ "regalloc-npm",
+ cl::desc("Register allocator pipeline for the new pass manager. Same as "
+ "--passes, but only regalloc passes can be used here."),
+ cl::Hidden);
static cl::opt<bool>
DebugPM("debug-pass-manager", cl::Hidden,
@@ -100,6 +101,11 @@ int llvm::compileModuleWithNewPM(
<< TargetPassConfig::getLimitedCodeGenPipelineReason() << ".\n";
return 1;
}
+ if (!PassPipeline.empty() && !RegAllocPasses.empty()) {
+ WithColor::error(errs(), Arg0)
+ << "--passes and --regalloc-npm cannot be used together.\n";
+ return 1;
+ }
raw_pwrite_stream *OS = &Out->os();
@@ -114,7 +120,7 @@ int llvm::compileModuleWithNewPM(
CGPassBuilderOption Opt = getCGPassBuilderOption();
Opt.DisableVerify = VK != VerifierKind::InputOutput;
Opt.DebugPM = DebugPM;
- Opt.RegAlloc = RegAlloc;
+ Opt.RegAllocPipeline = RegAllocPasses;
MachineModuleInfo MMI(Target.get());
@@ -173,8 +179,9 @@ int llvm::compileModuleWithNewPM(
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
} else {
- ExitOnErr(Target->buildCodeGenPipeline(
- MPM, *OS, DwoOut ? &DwoOut->os() : nullptr, FileType, Opt, &PIC));
+ ExitOnErr(
+ Target->buildCodeGenPipeline(MPM, *OS, DwoOut ? &DwoOut->os() : nullptr,
+ FileType, Opt, MMI.getContext(), &PIC, PB));
}
// If user only wants to print the pipeline, print it before parsing the MIR.
>From 3f84dc4b87e4e8e3453a1bf71255efd2f3e8a165 Mon Sep 17 00:00:00 2001
From: Teja Alaghari <teja.alaghari at amd.com>
Date: Tue, 16 Dec 2025 19:54:10 +0530
Subject: [PATCH 2/2] [NFC] Cleanup and formatting fixes
- Add missing "PassBuilder.h" header in CodeGenPassBuilder.h
- Add MCContext& parameter to buildPipeline() for consistency with
buildCodeGenPipeline() API
- Remove unused mutable PrinterImpl member
- Fix formatting
---
llvm/include/llvm/Passes/CodeGenPassBuilder.h | 8 ++++----
llvm/lib/Passes/PassBuilder.cpp | 2 +-
llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 3 +--
llvm/lib/Target/AMDGPU/R600TargetMachine.cpp | 2 +-
llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp | 2 +-
llvm/tools/llc/NewPMDriver.cpp | 6 +++---
6 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index 8ac021cb369e7..d3b9bdbd807e6 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -126,6 +126,7 @@
#include "llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h"
#include "llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h"
#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
+#include "llvm/Passes/PassBuilder.h"
#include "llvm/Transforms/Utils/LowerInvoke.h"
#include <cassert>
#include <tuple>
@@ -193,8 +194,8 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
}
Error buildPipeline(ModulePassManager &MPM, raw_pwrite_stream &Out,
- raw_pwrite_stream *DwoOut,
- CodeGenFileType FileType) const;
+ raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
+ MCContext &Ctx) const;
PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
return PIC;
@@ -360,7 +361,6 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
CGPassBuilderOption Opt;
PassInstrumentationCallbacks *PIC;
PassBuilder &PB;
- mutable IntrusiveRefCntPtr<AsmPrinter> PrinterImpl;
template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
CodeGenOptLevel getOptLevel() const { return TM.getOptLevel(); }
@@ -635,7 +635,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
template <typename Derived, typename TargetMachineT>
Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
- CodeGenFileType FileType) const {
+ CodeGenFileType FileType, MCContext &Ctx) const {
auto StartStopInfo = TargetPassConfig::getStartStopInfo(*PIC);
if (!StartStopInfo)
return StartStopInfo.takeError();
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index d2c16d4085fcd..74a9559261032 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -1637,7 +1637,7 @@ parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
}
Expected<bool> llvm::parseMachineSinkingPassOptions(StringRef Params,
- const PassBuilder &) {
+ const PassBuilder &) {
return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
"MachineSinkingPass");
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 279d66f4d969d..9bc3c1ab668ff 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -140,8 +140,7 @@ class AMDGPUCodeGenPassBuilder
public:
AMDGPUCodeGenPassBuilder(GCNTargetMachine &TM,
const CGPassBuilderOption &Opts,
- PassInstrumentationCallbacks *PIC,
- PassBuilder &PB);
+ PassInstrumentationCallbacks *PIC, PassBuilder &PB);
void addIRPasses(AddIRPass &) const;
void addCodeGenPrepare(AddIRPass &) const;
diff --git a/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp b/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
index 8ac8d3addb374..d401e2d3f213e 100644
--- a/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
@@ -55,7 +55,7 @@ class R600CodeGenPassBuilder
: public CodeGenPassBuilder<R600CodeGenPassBuilder, R600TargetMachine> {
public:
R600CodeGenPassBuilder(R600TargetMachine &TM, const CGPassBuilderOption &Opts,
- PassInstrumentationCallbacks *PIC, PassBuilder &PB);
+ PassInstrumentationCallbacks *PIC, PassBuilder &PB);
void addPreISel(AddIRPass &addPass) const;
void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index 864cdc0b4547a..e3a4c54d4e534 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -69,7 +69,7 @@ void X86TargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
#define GET_PASS_REGISTRY "X86PassRegistry.def"
#include "llvm/Passes/TargetPassRegistry.inc"
-PB.registerRegClassFilterParsingCallback(
+ PB.registerRegClassFilterParsingCallback(
[](StringRef FilterName) -> RegAllocFilterFunc {
if (FilterName == "tile-reg") {
return onlyAllocateTileRegisters;
diff --git a/llvm/tools/llc/NewPMDriver.cpp b/llvm/tools/llc/NewPMDriver.cpp
index 2caaf956e50c6..c81836ef7e357 100644
--- a/llvm/tools/llc/NewPMDriver.cpp
+++ b/llvm/tools/llc/NewPMDriver.cpp
@@ -179,9 +179,9 @@ int llvm::compileModuleWithNewPM(
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
} else {
- ExitOnErr(
- Target->buildCodeGenPipeline(MPM, *OS, DwoOut ? &DwoOut->os() : nullptr,
- FileType, Opt, MMI.getContext(), &PIC, PB));
+ ExitOnErr(Target->buildCodeGenPipeline(
+ MPM, *OS, DwoOut ? &DwoOut->os() : nullptr, FileType, Opt,
+ MMI.getContext(), &PIC, PB));
}
// If user only wants to print the pipeline, print it before parsing the MIR.
More information about the llvm-commits
mailing list