[llvm] [CalcSpillWeights] Simplify copy hint register collection. NFC. (PR #114236)

Valery Pykhtin via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 1 02:40:13 PDT 2024


https://github.com/vpykhtin updated https://github.com/llvm/llvm-project/pull/114236

>From 06e5544b95995cbec59406a406fa3c9284602ab7 Mon Sep 17 00:00:00 2001
From: Valery Pykhtin <valery.pykhtin at gmail.com>
Date: Thu, 31 Oct 2024 08:39:03 +0100
Subject: [PATCH 1/2] [CalcSpillWeights] Simplify copy hint register
 collection. NFC.

---
 llvm/lib/CodeGen/CalcSpillWeights.cpp | 56 +++++++++++----------------
 1 file changed, 22 insertions(+), 34 deletions(-)

diff --git a/llvm/lib/CodeGen/CalcSpillWeights.cpp b/llvm/lib/CodeGen/CalcSpillWeights.cpp
index f361c956092e88..baa4dec9075e1a 100644
--- a/llvm/lib/CodeGen/CalcSpillWeights.cpp
+++ b/llvm/lib/CodeGen/CalcSpillWeights.cpp
@@ -207,24 +207,8 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
     NumInstr += 2;
   }
 
-  // CopyHint is a sortable hint derived from a COPY instruction.
-  struct CopyHint {
-    const Register Reg;
-    const float Weight;
-    CopyHint(Register R, float W) : Reg(R), Weight(W) {}
-    bool operator<(const CopyHint &Rhs) const {
-      // Always prefer any physreg hint.
-      if (Reg.isPhysical() != Rhs.Reg.isPhysical())
-        return Reg.isPhysical();
-      if (Weight != Rhs.Weight)
-        return (Weight > Rhs.Weight);
-      return Reg.id() < Rhs.Reg.id(); // Tie-breaker.
-    }
-  };
-
   bool IsExiting = false;
-  std::set<CopyHint> CopyHints;
-  SmallDenseMap<unsigned, float, 8> Hint;
+  SmallDenseMap<Register, float, 8> Hint;
   for (MachineRegisterInfo::reg_instr_nodbg_iterator
            I = MRI.reg_instr_nodbg_begin(LI.reg()),
            E = MRI.reg_instr_nodbg_end();
@@ -260,8 +244,7 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
       return -1.0f;
     }
 
-    // Force Weight onto the stack so that x86 doesn't add hidden precision,
-    // similar to HWeight below.
+    // Force Weight onto the stack so that x86 doesn't add hidden precision.
     stack_float_t Weight = 1.0f;
     if (IsSpillable) {
       // Get loop info for mi.
@@ -287,29 +270,34 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
     if (!TII.isCopyInstr(*MI))
       continue;
     Register HintReg = copyHint(MI, LI.reg(), TRI, MRI);
-    if (!HintReg)
-      continue;
-    // Force HWeight onto the stack so that x86 doesn't add hidden precision,
-    // making the comparison incorrectly pass (i.e., 1 > 1 == true??).
-    stack_float_t HWeight = Hint[HintReg] += Weight;
-    if (HintReg.isVirtual() || MRI.isAllocatable(HintReg))
-      CopyHints.insert(CopyHint(HintReg, HWeight));
+    if (HintReg && (HintReg.isVirtual() || MRI.isAllocatable(HintReg)))
+      Hint[HintReg] += Weight;
   }
 
   // Pass all the sorted copy hints to mri.
-  if (ShouldUpdateLI && CopyHints.size()) {
+  if (ShouldUpdateLI && Hint.size()) {
     // Remove a generic hint if previously added by target.
     if (TargetHint.first == 0 && TargetHint.second)
       MRI.clearSimpleHint(LI.reg());
 
-    SmallSet<Register, 4> HintedRegs;
-    for (const auto &Hint : CopyHints) {
-      if (!HintedRegs.insert(Hint.Reg).second ||
-          (TargetHint.first != 0 && Hint.Reg == TargetHint.second))
-        // Don't add the same reg twice or the target-type hint again.
-        continue;
-      MRI.addRegAllocationHint(LI.reg(), Hint.Reg);
+    // Don't add the target-type hint again.
+    Register SkipReg = TargetHint.first != 0 ? TargetHint.second : Register();
+    SmallVector<std::pair<float, Register>, 4> FRegHints, VRegHints;
+    for (const auto &[Reg, Weight] : Hint) {
+      if (Reg != SkipReg)
+        (Reg.isPhysical() ? &FRegHints : &VRegHints)->emplace_back(Weight, Reg);
     }
+    auto HeavyFirst = [](const auto &LHS, const auto &RHS) {
+      if (LHS.first != RHS.first)
+        return LHS.first > RHS.first;
+      return LHS.second.id() < RHS.second.id();
+    };
+    sort(FRegHints, HeavyFirst);
+    sort(VRegHints, HeavyFirst);
+    for (const auto &[Weight, Reg] : FRegHints) // Prefer physregs hints first.
+      MRI.addRegAllocationHint(LI.reg(), Reg);
+    for (const auto &[Weight, Reg] : VRegHints)
+      MRI.addRegAllocationHint(LI.reg(), Reg);
 
     // Weakly boost the spill weight of hinted registers.
     TotalWeight *= 1.01F;

>From d321b1229ec393ab8ee747b0e1922925db9f2e13 Mon Sep 17 00:00:00 2001
From: Valery Pykhtin <valery.pykhtin at gmail.com>
Date: Fri, 1 Nov 2024 10:43:12 +0100
Subject: [PATCH 2/2] Use one lists for all hints

---
 llvm/lib/CodeGen/CalcSpillWeights.cpp | 31 ++++++++++++++++-----------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/CodeGen/CalcSpillWeights.cpp b/llvm/lib/CodeGen/CalcSpillWeights.cpp
index baa4dec9075e1a..d1b22b60c0e88e 100644
--- a/llvm/lib/CodeGen/CalcSpillWeights.cpp
+++ b/llvm/lib/CodeGen/CalcSpillWeights.cpp
@@ -207,6 +207,21 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
     NumInstr += 2;
   }
 
+  // CopyHint is a sortable hint derived from a COPY instruction.
+  struct CopyHint {
+    Register Reg;
+    float Weight;
+    CopyHint(Register R, float W) : Reg(R), Weight(W) {}
+    bool operator<(const CopyHint &Rhs) const {
+      // Always prefer any physreg hint.
+      if (Reg.isPhysical() != Rhs.Reg.isPhysical())
+        return Reg.isPhysical();
+      if (Weight != Rhs.Weight)
+        return (Weight > Rhs.Weight);
+      return Reg.id() < Rhs.Reg.id(); // Tie-breaker.
+    }
+  };
+
   bool IsExiting = false;
   SmallDenseMap<Register, float, 8> Hint;
   for (MachineRegisterInfo::reg_instr_nodbg_iterator
@@ -282,21 +297,13 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
 
     // Don't add the target-type hint again.
     Register SkipReg = TargetHint.first != 0 ? TargetHint.second : Register();
-    SmallVector<std::pair<float, Register>, 4> FRegHints, VRegHints;
+    SmallVector<CopyHint, 8> RegHints;
     for (const auto &[Reg, Weight] : Hint) {
       if (Reg != SkipReg)
-        (Reg.isPhysical() ? &FRegHints : &VRegHints)->emplace_back(Weight, Reg);
+        RegHints.emplace_back(Reg, Weight);
     }
-    auto HeavyFirst = [](const auto &LHS, const auto &RHS) {
-      if (LHS.first != RHS.first)
-        return LHS.first > RHS.first;
-      return LHS.second.id() < RHS.second.id();
-    };
-    sort(FRegHints, HeavyFirst);
-    sort(VRegHints, HeavyFirst);
-    for (const auto &[Weight, Reg] : FRegHints) // Prefer physregs hints first.
-      MRI.addRegAllocationHint(LI.reg(), Reg);
-    for (const auto &[Weight, Reg] : VRegHints)
+    sort(RegHints);
+    for (const auto &[Reg, Weight] : RegHints)
       MRI.addRegAllocationHint(LI.reg(), Reg);
 
     // Weakly boost the spill weight of hinted registers.



More information about the llvm-commits mailing list