Skip to content

Commit fe8865c

Browse files
[AArch64] Prioritize regalloc hints over movprfx hints (#167480)
This is a follow-up from #166926 that ensures the hints are only added once, and ensures that hints inserted by the register allocator take priority over hints to reduce movprfx.
1 parent d02a5ae commit fe8865c

File tree

2 files changed

+83
-13
lines changed

2 files changed

+83
-13
lines changed

llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,9 @@ bool AArch64RegisterInfo::getRegAllocationHints(
11571157
// a movprfx.
11581158
const TargetRegisterClass *RegRC = MRI.getRegClass(VirtReg);
11591159
if (AArch64::ZPRRegClass.hasSubClassEq(RegRC)) {
1160+
bool ConsiderOnlyHints = TargetRegisterInfo::getRegAllocationHints(
1161+
VirtReg, Order, Hints, MF, VRM);
1162+
11601163
for (const MachineOperand &DefOp : MRI.def_operands(VirtReg)) {
11611164
const MachineInstr &Def = *DefOp.getParent();
11621165
if (DefOp.isImplicit() ||
@@ -1168,26 +1171,28 @@ bool AArch64RegisterInfo::getRegAllocationHints(
11681171
TII->get(AArch64::getSVEPseudoMap(Def.getOpcode())).TSFlags;
11691172

11701173
for (MCPhysReg R : Order) {
1171-
auto AddHintIfSuitable = [&](MCPhysReg R, const MachineOperand &MO) {
1172-
// R is a suitable register hint if there exists an operand for the
1173-
// instruction that is not yet allocated a register or if R matches
1174-
// one of the other source operands.
1175-
if (!VRM->hasPhys(MO.getReg()) || VRM->getPhys(MO.getReg()) == R)
1176-
Hints.push_back(R);
1174+
auto AddHintIfSuitable = [&](MCPhysReg R,
1175+
const MachineOperand &MO) -> bool {
1176+
// R is a suitable register hint if R can reuse one of the other
1177+
// source operands.
1178+
if (VRM->getPhys(MO.getReg()) != R)
1179+
return false;
1180+
Hints.push_back(R);
1181+
return true;
11771182
};
11781183

11791184
switch (InstFlags & AArch64::DestructiveInstTypeMask) {
11801185
default:
11811186
break;
11821187
case AArch64::DestructiveTernaryCommWithRev:
1183-
AddHintIfSuitable(R, Def.getOperand(2));
1184-
AddHintIfSuitable(R, Def.getOperand(3));
1185-
AddHintIfSuitable(R, Def.getOperand(4));
1188+
AddHintIfSuitable(R, Def.getOperand(2)) ||
1189+
AddHintIfSuitable(R, Def.getOperand(3)) ||
1190+
AddHintIfSuitable(R, Def.getOperand(4));
11861191
break;
11871192
case AArch64::DestructiveBinaryComm:
11881193
case AArch64::DestructiveBinaryCommWithRev:
1189-
AddHintIfSuitable(R, Def.getOperand(2));
1190-
AddHintIfSuitable(R, Def.getOperand(3));
1194+
AddHintIfSuitable(R, Def.getOperand(2)) ||
1195+
AddHintIfSuitable(R, Def.getOperand(3));
11911196
break;
11921197
case AArch64::DestructiveBinary:
11931198
case AArch64::DestructiveBinaryImm:
@@ -1198,8 +1203,7 @@ bool AArch64RegisterInfo::getRegAllocationHints(
11981203
}
11991204

12001205
if (Hints.size())
1201-
return TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints,
1202-
MF, VRM);
1206+
return ConsiderOnlyHints;
12031207
}
12041208

12051209
if (!ST.hasSME() || !ST.isStreaming())
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# RUN: llc -mtriple=aarch64 -mattr=+sve -start-before=greedy -stop-after=virtregrewriter -debug-only=regalloc %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=DBG
2+
3+
# Check that the register allocator gets hints to reuse registers of one of it's operands.
4+
---
5+
name: prioritize_movprfx_hints
6+
tracksRegLiveness: true
7+
isSSA: false
8+
noVRegs: false
9+
body: |
10+
bb.0.entry:
11+
liveins: $z0, $z1, $z2, $z3, $p0
12+
13+
; DBG: Machine code for function prioritize_movprfx_hints
14+
;
15+
; DBG: selectOrSplit ZPR:%4
16+
; DBG-NEXT: hints: $z0 $z1{{$}}
17+
;
18+
; DBG: selectOrSplit ZPR:%5
19+
; DBG-NEXT: hints: $z2 $z3{{$}}
20+
;
21+
; DBG: [%0 -> $z3] ZPR
22+
; DBG: [%1 -> $z2] ZPR
23+
; DBG: [%2 -> $z1] ZPR
24+
; DBG: [%3 -> $z0] ZPR
25+
; DBG: [%4 -> $z0] ZPR
26+
; DBG: [%5 -> $z2] ZPR
27+
; DBG: [%6 -> $z0] ZPR
28+
%0:zpr = COPY $z3
29+
%1:zpr = COPY $z2
30+
%2:zpr = COPY $z1
31+
%3:zpr = COPY $z0
32+
%4:zpr = SDIV_ZPZZ_D_UNDEF $p0, %3:zpr, %2:zpr
33+
%5:zpr = MUL_ZPZZ_D_UNDEF $p0, %1:zpr, %0:zpr
34+
%6:zpr = MUL_ZPZZ_D_UNDEF $p0, %5:zpr, %4:zpr
35+
$z0 = COPY %6:zpr
36+
RET_ReallyLR implicit $z0
37+
...
38+
39+
# Check that the register allocator prioritises hints that are set by the register
40+
# allocator itself (i.e. to use z4 for the result register).
41+
---
42+
name: prioritize_regalloc_hints
43+
isSSA: false
44+
noVRegs: false
45+
body: |
46+
bb.0.entry:
47+
%0:zpr = FDUP_ZI_S 0, implicit $vg
48+
%1:zpr = FDUP_ZI_S 16, implicit $vg
49+
%2:zpr = FDUP_ZI_S 32, implicit $vg
50+
%3:ppr_3b = PTRUE_S 31, implicit $vg
51+
52+
; DBG: Machine code for function prioritize_regalloc_hints
53+
;
54+
; DBG: selectOrSplit ZPR:%4
55+
; DBG-NEXT: hints: $z4{{$}}
56+
;
57+
; DBG: [%0 -> $z0] ZPR
58+
; DBG: [%1 -> $z1] ZPR
59+
; DBG: [%2 -> $z2] ZPR
60+
; DBG: [%3 -> $p0] PPR_3b
61+
; DBG: [%4 -> $z4] ZPR
62+
63+
%4:zpr = FMLA_ZPZZZ_S_UNDEF %3, %0, %1, %2
64+
$z4 = COPY %4
65+
RET_ReallyLR implicit $z4
66+
...

0 commit comments

Comments
 (0)