[llvm-branch-commits] [llvm] Greedy: Take hints from copy to physical subreg (PR #160467)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Sep 26 08:48:27 PDT 2025
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/160467
>From f409ccc1223fc7965f52e522d260295cb6053e4f Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 24 Sep 2025 16:53:33 +0900
Subject: [PATCH 1/2] Greedy: Take hints from copy to physical subreg
Previously this took hints from subregister extract of physreg,
like %vreg.sub = COPY $physreg
This now also handles the rarer case:
$physreg_sub = COPY %vreg
Also make an accidental bug here before explicit; this was
only using the superregister as a hint if it was already
in the copy, and not if using the existing assignment. There are
a handful of regressions in that case, so leave that extension
for a future change.
---
llvm/lib/CodeGen/RegAllocGreedy.cpp | 35 ++++++++++++++++-------------
llvm/test/CodeGen/X86/shift-i128.ll | 3 +--
2 files changed, 20 insertions(+), 18 deletions(-)
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 6e0585b2e9e55..0df8713dd892b 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -2439,25 +2439,28 @@ void RAGreedy::collectHintInfo(Register Reg, HintsInfo &Out) {
unsigned SubReg = Opnd.getSubReg();
// Get the current assignment.
- MCRegister OtherPhysReg =
- OtherReg.isPhysical() ? OtherReg.asMCReg() : VRM->getPhys(OtherReg);
- if (OtherSubReg) {
- if (OtherReg.isPhysical()) {
- MCRegister Tuple =
- TRI->getMatchingSuperReg(OtherPhysReg, OtherSubReg, RC);
- if (!Tuple)
- continue;
- OtherPhysReg = Tuple;
- } else {
- // TODO: There should be a hinting mechanism for subregisters
- if (SubReg != OtherSubReg)
- continue;
- }
+ MCRegister OtherPhysReg;
+ if (OtherReg.isPhysical()) {
+ if (OtherSubReg)
+ OtherPhysReg = TRI->getMatchingSuperReg(OtherReg, OtherSubReg, RC);
+ else if (SubReg)
+ OtherPhysReg = TRI->getMatchingSuperReg(OtherReg, SubReg, RC);
+ else
+ OtherPhysReg = OtherReg;
+ } else {
+ OtherPhysReg = VRM->getPhys(OtherReg);
+ // TODO: Should find matching superregister, but applying this in the
+ // non-hint case currently causes regressions
+
+ if (SubReg && OtherSubReg && SubReg != OtherSubReg)
+ continue;
}
// Push the collected information.
- Out.push_back(HintInfo(MBFI->getBlockFreq(Instr.getParent()), OtherReg,
- OtherPhysReg));
+ if (OtherPhysReg) {
+ Out.push_back(HintInfo(MBFI->getBlockFreq(Instr.getParent()), OtherReg,
+ OtherPhysReg));
+ }
}
}
diff --git a/llvm/test/CodeGen/X86/shift-i128.ll b/llvm/test/CodeGen/X86/shift-i128.ll
index 7462c77482827..049ee47af9681 100644
--- a/llvm/test/CodeGen/X86/shift-i128.ll
+++ b/llvm/test/CodeGen/X86/shift-i128.ll
@@ -613,8 +613,7 @@ define void @test_shl_v2i128(<2 x i128> %x, <2 x i128> %a, ptr nocapture %r) nou
; i686-NEXT: shldl %cl, %esi, %ebx
; i686-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %edi # 4-byte Reload
; i686-NEXT: movl %edi, %esi
-; i686-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Reload
-; i686-NEXT: movl %eax, %ecx
+; i686-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
; i686-NEXT: shll %cl, %esi
; i686-NEXT: shldl %cl, %edi, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Spill
; i686-NEXT: negl %edx
>From 0581982382d14b2451abfc6f2fc593d5d15e22a0 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 24 Sep 2025 18:54:59 +0900
Subject: [PATCH 2/2] XXX scale block frequencies by subreg
---
llvm/lib/CodeGen/RegAllocGreedy.cpp | 32 ++++++++++++++++++++++++++++-
llvm/lib/CodeGen/RegAllocGreedy.h | 13 +++++++++++-
2 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 0df8713dd892b..9d3165b790642 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -2458,7 +2458,28 @@ void RAGreedy::collectHintInfo(Register Reg, HintsInfo &Out) {
// Push the collected information.
if (OtherPhysReg) {
- Out.push_back(HintInfo(MBFI->getBlockFreq(Instr.getParent()), OtherReg,
+ BlockFrequency Freq = MBFI->getBlockFreq(Instr.getParent());
+
+ if (OtherSubReg) {
+ const TargetRegisterClass *OtherRC = MRI->getRegClass(OtherReg);
+ unsigned FullRegCopyCost = OtherRC->getCopyCost();
+
+ const TargetRegisterClass *OtherSubRC = TRI->getSubRegisterClass(OtherRC, OtherSubReg);
+ unsigned SubRegCopyCost = OtherSubRC->getCopyCost();
+
+ BranchProbability Scaling(SubRegCopyCost, FullRegCopyCost);
+ Freq *= Scaling;
+ } else if (SubReg) {
+ unsigned FullRegCopyCost = RC->getCopyCost();
+ const TargetRegisterClass *SubRC = TRI->getSubRegisterClass(RC, SubReg);
+ unsigned SubRegCopyCost = SubRC->getCopyCost();
+
+ BranchProbability Scaling(SubRegCopyCost, FullRegCopyCost);
+ Freq *= Scaling;
+
+ }
+
+ Out.push_back(HintInfo(Freq, OtherReg,
OtherPhysReg));
}
}
@@ -2471,6 +2492,13 @@ BlockFrequency RAGreedy::getBrokenHintFreq(const HintsInfo &List,
MCRegister PhysReg) {
BlockFrequency Cost = BlockFrequency(0);
for (const HintInfo &Info : List) {
+
+ if (!Info.PhysReg) {
+ // Apply subreg hint
+ continue;
+ }
+
+
if (Info.PhysReg != PhysReg)
Cost += Info.Freq;
}
@@ -2536,6 +2564,8 @@ void RAGreedy::tryHintRecoloring(const LiveInterval &VirtReg) {
// non-identity copies.
if (CurrPhys != PhysReg) {
LLVM_DEBUG(dbgs() << "Checking profitability:\n");
+
+ // TODO: Scale by copy cost
BlockFrequency OldCopiesCost = getBrokenHintFreq(Info, CurrPhys);
BlockFrequency NewCopiesCost = getBrokenHintFreq(Info, PhysReg);
LLVM_DEBUG(dbgs() << "Old Cost: " << printBlockFreq(*MBFI, OldCopiesCost)
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.h b/llvm/lib/CodeGen/RegAllocGreedy.h
index 7f013d1f1f726..e0bb26e63e323 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.h
+++ b/llvm/lib/CodeGen/RegAllocGreedy.h
@@ -385,12 +385,23 @@ class LLVM_LIBRARY_VISIBILITY RAGreedy : public RegAllocBase,
BlockFrequency Freq;
/// The virtual register or physical register.
Register Reg;
+ unsigned SubReg = 0;
+
+ Register HintReg;
+ unsigned HintSubReg = 0;
+
/// Its currently assigned register.
/// In case of a physical register Reg == PhysReg.
MCRegister PhysReg;
HintInfo(BlockFrequency Freq, Register Reg, MCRegister PhysReg)
- : Freq(Freq), Reg(Reg), PhysReg(PhysReg) {}
+ : Freq(Freq), Reg(Reg), PhysReg(PhysReg) {}
+
+ HintInfo(BlockFrequency Freq,
+ Register Reg, unsigned SubReg,
+ Register HintReg, unsigned HintSubReg)
+ : Freq(Freq), Reg(Reg), SubReg(SubReg),
+ HintReg(HintReg), HintSubReg(HintSubReg) {}
};
using HintsInfo = SmallVector<HintInfo, 4>;
More information about the llvm-branch-commits
mailing list