[llvm-branch-commits] [llvm] [MachinePipeliner] Add PipelinerLoopInfo hooks to reuse the reg-pressure detector (PR #212538)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Jul 29 09:51:32 PDT 2026
https://github.com/hjagasiaAMD updated https://github.com/llvm/llvm-project/pull/212538
>From 6ce0e9325dd29bebfea5991c7779e0f6139cc75b Mon Sep 17 00:00:00 2001
From: Harsha Jagasia <harsha.jagasia at amd.com>
Date: Mon, 13 Jul 2026 21:29:07 +0000
Subject: [PATCH] [MachinePipeliner] Add PipelinerLoopInfo hooks to reuse the
reg-pressure detector
The generic MachinePipeliner register-pressure detector (added in #74807)
was only reachable via the global -pipeliner-register-pressure flag, which
cannot be enabled per-target, and it judges pressure against generic
per-pressure-set limits. Add two PipelinerLoopInfo hooks so a target can
reuse that detector on its own terms:
- shouldLimitRegPressure(): A target can opt the loop into the detector without
the global flag.
- isScheduleRegPressureTooHigh(MaxSetPressure): let the target replace the
detector's generic per-pressure-set limit check with its own verdict, or
return nullopt to keep that check.
Both hooks default to preserving current behavior, so targets that do not
override them are unaffected.
Exercised by the AMDGPU adoption in the following commit.
---
llvm/include/llvm/CodeGen/TargetInstrInfo.h | 14 ++++++++++
llvm/lib/CodeGen/MachinePipeliner.cpp | 31 +++++++++++++++------
2 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
index 50c95a2208284..0c61709faf6f4 100644
--- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
@@ -846,6 +846,20 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
/// An explicit -pipeliner-max-mii takes precedence over this hook.
virtual std::optional<unsigned> getMaxMII() const { return std::nullopt; }
+ /// Return true to run the generic register-pressure detector for this loop
+ /// even without -pipeliner-register-pressure. A rejected schedule then
+ /// retries at a higher II instead of disabling pipelining.
+ virtual bool shouldLimitRegPressure() const { return false; }
+
+ /// Given the detector's per-pressure-set maxima \p MaxSetPressure for a
+ /// candidate schedule, return whether it uses too many registers, or
+ /// nullopt to defer to the detector's default per-set limit check. A
+ /// non-nullopt verdict takes precedence over that check (and its margin).
+ virtual std::optional<bool>
+ isScheduleRegPressureTooHigh(ArrayRef<unsigned> MaxSetPressure) const {
+ return std::nullopt;
+ }
+
/// Create a condition to determine if the trip count of the loop is greater
/// than TC, where TC is always one more than for the previous prologue or
/// 0 if this is being called for the outermost prologue.
diff --git a/llvm/lib/CodeGen/MachinePipeliner.cpp b/llvm/lib/CodeGen/MachinePipeliner.cpp
index d715e1e966998..75fad800a2061 100644
--- a/llvm/lib/CodeGen/MachinePipeliner.cpp
+++ b/llvm/lib/CodeGen/MachinePipeliner.cpp
@@ -1900,9 +1900,11 @@ class HighRegisterPressureDetector {
}
// Calculate the maximum register pressures of the loop and check if they
- // exceed the limit
+ // exceed the limit, or defer to the target's verdict via
+ // PipelinerLoopInfo::isScheduleRegPressureTooHigh.
bool detect(const SwingSchedulerDAG *SSD, SMSchedule &Schedule,
- const unsigned MaxStage) const {
+ const unsigned MaxStage,
+ const TargetInstrInfo::PipelinerLoopInfo *PLI) const {
assert(0 <= RegPressureMargin && RegPressureMargin <= 100 &&
"the percentage of the margin must be between 0 to 100");
@@ -1920,6 +1922,18 @@ class HighRegisterPressureDetector {
dbgs() << '\n';
});
+ if (PLI) {
+ if (std::optional<bool> TooHigh =
+ PLI->isScheduleRegPressureTooHigh(MaxSetPressure)) {
+ LLVM_DEBUG(dbgs() << (*TooHigh
+ ? "Rejected the schedule because of too high "
+ "register pressure (per target verdict)\n"
+ : "Accepted the schedule (per target "
+ "verdict)\n"));
+ return *TooHigh;
+ }
+ }
+
for (unsigned PSet = 0; PSet < PSetNum; PSet++) {
unsigned Limit = PressureSetLimit[PSet];
unsigned Margin = Limit * RegPressureMargin / 100;
@@ -2798,7 +2812,8 @@ bool SwingSchedulerDAG::schedulePipeline(SMSchedule &Schedule) {
bool scheduleFound = false;
std::unique_ptr<HighRegisterPressureDetector> HRPDetector;
- if (LimitRegPressure) {
+ if (LimitRegPressure ||
+ (LoopPipelinerInfo && LoopPipelinerInfo->shouldLimitRegPressure())) {
HRPDetector =
std::make_unique<HighRegisterPressureDetector>(Loop.getHeader(), MF);
HRPDetector->init(RegClassInfo);
@@ -2882,11 +2897,11 @@ bool SwingSchedulerDAG::schedulePipeline(SMSchedule &Schedule) {
if (scheduleFound)
scheduleFound = Schedule.isValidSchedule(this);
- // If a schedule was found and the option is enabled, check if the schedule
- // might generate additional register spills/fills.
- if (scheduleFound && LimitRegPressure)
- scheduleFound =
- !HRPDetector->detect(this, Schedule, Schedule.getMaxStageCount());
+ // If a schedule was found and the detector is enabled, check if the
+ // schedule might generate additional register spills/fills.
+ if (scheduleFound && HRPDetector)
+ scheduleFound = !HRPDetector->detect(
+ this, Schedule, Schedule.getMaxStageCount(), LoopPipelinerInfo);
}
LLVM_DEBUG(dbgs() << "Schedule Found? " << scheduleFound
More information about the llvm-branch-commits
mailing list