[llvm] [MachineScheduler] Improve handling of phys regs in GenericScheduler() (NFC). (PR #187572)
Jonas Paulsson via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 15 08:12:57 PDT 2026
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/187572
>From 0000c29ab83508f4c90a48e37e8c5c1adc8b826e Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Thu, 19 Mar 2026 20:40:40 +0100
Subject: [PATCH 1/4] [MachineScheduler] Improve handling of phys regs in
GenericScheduler().
Factor out the handling of coalesced preg COPYs from SystemZMachineScheduler.cpp
into MachineScheduler.cpp.
This extends the handling to other types of instructions than COPY or
immediate loads, such as Load Address and takes care of maintaining the
original input order if both SUs are biased the same way in the same zone.
This seems to be the best behavior on SystemZ at least and I don't know any
reason to move these physreg defs around just because they are not COPYs or
immloads.
When I enabled this by default a lot of tests on other targets failed which
need updating. Therefore I have suggested wrapping this under a TII hook for
now, returning false by default: biasPRegsExtra().
---
llvm/include/llvm/CodeGen/MachineScheduler.h | 6 +++-
llvm/include/llvm/CodeGen/TargetInstrInfo.h | 4 +++
llvm/lib/CodeGen/MachineScheduler.cpp | 34 +++++++++++++++++--
.../SystemZ/SystemZMachineScheduler.cpp | 19 +----------
4 files changed, 41 insertions(+), 22 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/MachineScheduler.h b/llvm/include/llvm/CodeGen/MachineScheduler.h
index 0c7efd8ab1d8f..244aaefec0ddc 100644
--- a/llvm/include/llvm/CodeGen/MachineScheduler.h
+++ b/llvm/include/llvm/CodeGen/MachineScheduler.h
@@ -1252,8 +1252,12 @@ LLVM_ABI bool tryPressure(const PressureChange &TryP,
GenericSchedulerBase::CandReason Reason,
const TargetRegisterInfo *TRI,
const MachineFunction &MF);
+LLVM_ABI bool tryBiasPhysRegs(GenericSchedulerBase::SchedCandidate &TryCand,
+ GenericSchedulerBase::SchedCandidate &Cand,
+ SchedBoundary *Zone, bool BiasPRegsExtra);
LLVM_ABI unsigned getWeakLeft(const SUnit *SU, bool isTop);
-LLVM_ABI int biasPhysReg(const SUnit *SU, bool isTop);
+LLVM_ABI int biasPhysReg(const SUnit *SU, bool isTop,
+ bool BiasPRegsExtra = false);
/// GenericScheduler shrinks the unscheduled zone using heuristics to balance
/// the schedule.
diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
index 77f710203d1fc..c382e3e6bc7c5 100644
--- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
@@ -1664,6 +1664,10 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
llvm_unreachable("target did not implement shouldClusterMemOps()");
}
+ // GenericScheduler: Handle non COPY/immLoad physreg defs, and maintain
+ // input order if both are biased same way.
+ virtual bool biasPRegsExtra() const { return false; }
+
/// Reverses the branch condition of the specified condition list,
/// returning false on success and true if it cannot be reversed.
virtual bool
diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp
index 482dea0ca0626..5b89577e8ddd9 100644
--- a/llvm/lib/CodeGen/MachineScheduler.cpp
+++ b/llvm/lib/CodeGen/MachineScheduler.cpp
@@ -3837,7 +3837,7 @@ unsigned llvm::getWeakLeft(const SUnit *SU, bool isTop) {
/// copies which can be prescheduled. The rest (e.g. x86 MUL) could be bundled
/// with the operation that produces or consumes the physreg. We'll do this when
/// regalloc has support for parallel copies.
-int llvm::biasPhysReg(const SUnit *SU, bool isTop) {
+int llvm::biasPhysReg(const SUnit *SU, bool isTop, bool BiasPRegsExtra) {
const MachineInstr *MI = SU->getInstr();
if (MI->isCopy()) {
@@ -3870,9 +3870,38 @@ int llvm::biasPhysReg(const SUnit *SU, bool isTop) {
return isTop ? -1 : 1;
}
+ if (BiasPRegsExtra && !isTop && MI->getNumOperands()) {
+ // Register coalescer will create cases of e.g. Load Address of a frame
+ // index directly into a physreg.
+ const MachineOperand &DefMO = MI->getOperand(0);
+ return DefMO.isReg() && DefMO.isDef() && DefMO.getReg().isPhysical();
+ }
+
return 0;
}
+bool llvm::tryBiasPhysRegs(GenericSchedulerBase::SchedCandidate &TryCand,
+ GenericSchedulerBase::SchedCandidate &Cand,
+ SchedBoundary *Zone, bool BiasPRegsExtra) {
+ int TryCandPRegBias = biasPhysReg(TryCand.SU, TryCand.AtTop, BiasPRegsExtra);
+ int CandPRegBias = biasPhysReg(Cand.SU, Cand.AtTop, BiasPRegsExtra);
+ if (tryGreater(TryCandPRegBias, CandPRegBias, TryCand, Cand,
+ GenericSchedulerBase::PhysReg))
+ return true;
+ if (BiasPRegsExtra && Zone != nullptr && TryCandPRegBias &&
+ TryCandPRegBias == CandPRegBias) {
+ // Both biased same way - maintain their input order.
+ if (Zone->isTop())
+ tryLess(TryCand.SU->NodeNum, Cand.SU->NodeNum, TryCand, Cand,
+ GenericSchedulerBase::NodeOrder);
+ else
+ tryGreater(TryCand.SU->NodeNum, Cand.SU->NodeNum, TryCand, Cand,
+ GenericSchedulerBase::NodeOrder);
+ return true;
+ }
+ return false;
+}
+
void GenericScheduler::initCandidate(SchedCandidate &Cand, SUnit *SU,
bool AtTop,
const RegPressureTracker &RPTracker,
@@ -3931,8 +3960,7 @@ bool GenericScheduler::tryCandidate(SchedCandidate &Cand,
}
// Bias PhysReg Defs and copies to their uses and defined respectively.
- if (tryGreater(biasPhysReg(TryCand.SU, TryCand.AtTop),
- biasPhysReg(Cand.SU, Cand.AtTop), TryCand, Cand, PhysReg))
+ if (tryBiasPhysRegs(TryCand, Cand, Zone, DAG->TII->biasPRegsExtra()))
return TryCand.Reason != NoCand;
// Avoid exceeding the target's limit.
diff --git a/llvm/lib/Target/SystemZ/SystemZMachineScheduler.cpp b/llvm/lib/Target/SystemZ/SystemZMachineScheduler.cpp
index 8df9540d1a0e5..1d1cc9dcbdc2b 100644
--- a/llvm/lib/Target/SystemZ/SystemZMachineScheduler.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZMachineScheduler.cpp
@@ -83,16 +83,6 @@ bool SystemZPreRASchedStrategy::definesCmp0Src(const MachineInstr *MI,
return false;
}
-static int biasPhysRegExtra(const SUnit *SU) {
- if (int Res = biasPhysReg(SU, /*isTop=*/false))
- return Res;
-
- // Also recognize Load Address. Most of these are with an FI operand.
- const MachineInstr *MI = SU->getInstr();
- return MI->getNumOperands() && !MI->isCopy() &&
- isPhysRegDef(MI->getOperand(0));
-}
-
bool SystemZPreRASchedStrategy::tryCandidate(SchedCandidate &Cand,
SchedCandidate &TryCand,
SchedBoundary *Zone) const {
@@ -105,15 +95,8 @@ bool SystemZPreRASchedStrategy::tryCandidate(SchedCandidate &Cand,
}
// Bias physreg defs and copies to their uses and definitions respectively.
- int TryCandPRegBias = biasPhysRegExtra(TryCand.SU);
- int CandPRegBias = biasPhysRegExtra(Cand.SU);
- if (tryGreater(TryCandPRegBias, CandPRegBias, TryCand, Cand, PhysReg))
+ if (tryBiasPhysRegs(TryCand, Cand, Zone, /*BiasPRegsExtra=*/true))
return TryCand.Reason != NoCand;
- if (TryCandPRegBias && CandPRegBias) {
- // Both biased same way.
- tryGreater(TryCand.SU->NodeNum, Cand.SU->NodeNum, TryCand, Cand, NodeOrder);
- return TryCand.Reason != NoCand;
- }
// Don't extend the scheduled latency in regions with many nodes in data
// sequences, or for (single block loop) regions that are acyclically
>From 924fdff55e0535841b3281dbeb3dc1f87f12a6b6 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Fri, 20 Mar 2026 17:28:41 +0100
Subject: [PATCH 2/4] Remove unused function in SystemZMachineScheduler.cpp
---
llvm/lib/Target/SystemZ/SystemZMachineScheduler.cpp | 4 ----
1 file changed, 4 deletions(-)
diff --git a/llvm/lib/Target/SystemZ/SystemZMachineScheduler.cpp b/llvm/lib/Target/SystemZ/SystemZMachineScheduler.cpp
index 1d1cc9dcbdc2b..a1aa8bedbb2d2 100644
--- a/llvm/lib/Target/SystemZ/SystemZMachineScheduler.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZMachineScheduler.cpp
@@ -19,10 +19,6 @@ static bool isRegDef(const MachineOperand &MO) {
return MO.isReg() && MO.isDef();
}
-static bool isPhysRegDef(const MachineOperand &MO) {
- return isRegDef(MO) && MO.getReg().isPhysical();
-}
-
void SystemZPreRASchedStrategy::initializeLatencyReduction() {
// Enable latency reduction for a region that has a considerable amount of
// data sequences that should be interlaved. These are SUs that only have
>From 35002ac6440149995e08e2982f3a4917cc193c5b Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Fri, 20 Mar 2026 19:04:51 +0100
Subject: [PATCH 3/4] Use getNumExplicitDefs() instead (NFC).
---
llvm/lib/CodeGen/MachineScheduler.cpp | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp
index 5b89577e8ddd9..f06f6a152fe40 100644
--- a/llvm/lib/CodeGen/MachineScheduler.cpp
+++ b/llvm/lib/CodeGen/MachineScheduler.cpp
@@ -3870,12 +3870,10 @@ int llvm::biasPhysReg(const SUnit *SU, bool isTop, bool BiasPRegsExtra) {
return isTop ? -1 : 1;
}
- if (BiasPRegsExtra && !isTop && MI->getNumOperands()) {
+ if (BiasPRegsExtra && !isTop && MI->getNumExplicitDefs() == 1)
// Register coalescer will create cases of e.g. Load Address of a frame
// index directly into a physreg.
- const MachineOperand &DefMO = MI->getOperand(0);
- return DefMO.isReg() && DefMO.isDef() && DefMO.getReg().isPhysical();
- }
+ return MI->getOperand(0).getReg().isPhysical();
return 0;
}
>From 36c651f506aacdecda3758d8bb4eb069960d7952 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Wed, 15 Apr 2026 17:10:58 +0200
Subject: [PATCH 4/4] Use RegionPolicy.BiasPRegsExtra instead of TII hook.
---
llvm/include/llvm/CodeGen/MachineScheduler.h | 3 +++
llvm/include/llvm/CodeGen/TargetInstrInfo.h | 4 ----
llvm/lib/CodeGen/MachineScheduler.cpp | 2 +-
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/MachineScheduler.h b/llvm/include/llvm/CodeGen/MachineScheduler.h
index 244aaefec0ddc..0f1fa782ec13c 100644
--- a/llvm/include/llvm/CodeGen/MachineScheduler.h
+++ b/llvm/include/llvm/CodeGen/MachineScheduler.h
@@ -218,6 +218,9 @@ struct MachineSchedPolicy {
// Compute DFSResult for use in scheduling heuristics.
bool ComputeDFSResult = false;
+ // If enabled, some extra cases of physreg defs will be biased towards user.
+ bool BiasPRegsExtra = false;
+
MachineSchedPolicy() = default;
};
diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
index c382e3e6bc7c5..77f710203d1fc 100644
--- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
@@ -1664,10 +1664,6 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
llvm_unreachable("target did not implement shouldClusterMemOps()");
}
- // GenericScheduler: Handle non COPY/immLoad physreg defs, and maintain
- // input order if both are biased same way.
- virtual bool biasPRegsExtra() const { return false; }
-
/// Reverses the branch condition of the specified condition list,
/// returning false on success and true if it cannot be reversed.
virtual bool
diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp
index f06f6a152fe40..2c8898ffcd09c 100644
--- a/llvm/lib/CodeGen/MachineScheduler.cpp
+++ b/llvm/lib/CodeGen/MachineScheduler.cpp
@@ -3958,7 +3958,7 @@ bool GenericScheduler::tryCandidate(SchedCandidate &Cand,
}
// Bias PhysReg Defs and copies to their uses and defined respectively.
- if (tryBiasPhysRegs(TryCand, Cand, Zone, DAG->TII->biasPRegsExtra()))
+ if (tryBiasPhysRegs(TryCand, Cand, Zone, RegionPolicy.BiasPRegsExtra))
return TryCand.Reason != NoCand;
// Avoid exceeding the target's limit.
More information about the llvm-commits
mailing list