[llvm] d0b7827 - [MachineScheduler] Improve handling of phys regs in GenericScheduler. (NFC). (#187572)

via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 15 10:20:11 PDT 2026


Author: Jonas Paulsson
Date: 2026-04-15T18:20:06+01:00
New Revision: d0b78277f0322b627e192324ac77274ebfedc210

URL: https://github.com/llvm/llvm-project/commit/d0b78277f0322b627e192324ac77274ebfedc210
DIFF: https://github.com/llvm/llvm-project/commit/d0b78277f0322b627e192324ac77274ebfedc210.diff

LOG: [MachineScheduler] Improve handling of phys regs in GenericScheduler. (NFC). (#187572)

Factor out the handling of coalesced preg COPYs from SystemZMachineScheduler.cpp into MachineScheduler.cpp. 

This extends the handling to other types of instructions than COPYs 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.

Another target that uses GenericScheduler can enable this by setting the new
MachineSchedPolicy member BiasPRegsExtra to true (default false). In a derived
scheduling strategy, this could be used either by passing /*BiasPRegsExtra=*/true
to biasPhysReg() (extra instruction detection), or by calling tryBiasPhysRegs()
instead which also preserves the original order if biased the same way.

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/MachineScheduler.h
    llvm/lib/CodeGen/MachineScheduler.cpp
    llvm/lib/Target/SystemZ/SystemZMachineScheduler.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/MachineScheduler.h b/llvm/include/llvm/CodeGen/MachineScheduler.h
index 0c7efd8ab1d8f..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;
 };
 
@@ -1252,8 +1255,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/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp
index 482dea0ca0626..2c8898ffcd09c 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,36 @@ int llvm::biasPhysReg(const SUnit *SU, bool isTop) {
       return isTop ? -1 : 1;
   }
 
+  if (BiasPRegsExtra && !isTop && MI->getNumExplicitDefs() == 1)
+    // Register coalescer will create cases of e.g. Load Address of a frame
+    // index directly into a physreg.
+    return MI->getOperand(0).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 +3958,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, RegionPolicy.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..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
@@ -83,16 +79,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 +91,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))
-    return TryCand.Reason != NoCand;
-  if (TryCandPRegBias && CandPRegBias) {
-    // Both biased same way.
-    tryGreater(TryCand.SU->NodeNum, Cand.SU->NodeNum, TryCand, Cand, NodeOrder);
+  if (tryBiasPhysRegs(TryCand, Cand, Zone, /*BiasPRegsExtra=*/true))
     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


        


More information about the llvm-commits mailing list