Skip to content

Commit 74e8f29

Browse files
[RegAlloc] Sort CopyHint by IsCSR (#131046)
`weightCalcHelper` is responsible for adding hints to MRI. Prior to this PR, we fell back on register ID as the last tie breaker for sorting hints. However, there is an opportunity to add an additional sorting characteristic: whether or not a register is a callee-saved-register. I thought of this idea because I saw that `AllocationOrder::create` calls `RegisterClassInfo::getOrder`, which returns a list of registers such that the registers which alias callee-saved-registers come last. From this, I conclude that the register allocator prefers an order such that callee-saved-registers are allocated after non-callee-saved-registers to avoid having to spill the CSR. This sorting characteristic occurs only as a tie breaker to the Weight calculation. This is a good idea since the weight calculation is pretty complex and I'm sure it is a pretty stable metric. I think its pretty reasonable to agree that whether a register is callee-saved or not is a better tie breaker than register ID. I think this is evident by the test diff, since the changes all seem to have no impact or improve the register allocation.
1 parent efe9cb0 commit 74e8f29

20 files changed

+147
-135
lines changed

llvm/lib/CodeGen/CalcSpillWeights.cpp

+10-3
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,18 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
210210
struct CopyHint {
211211
Register Reg;
212212
float Weight;
213-
CopyHint(Register R, float W) : Reg(R), Weight(W) {}
213+
bool IsCSR;
214+
CopyHint(Register R, float W, bool IsCSR)
215+
: Reg(R), Weight(W), IsCSR(IsCSR) {}
214216
bool operator<(const CopyHint &Rhs) const {
215217
// Always prefer any physreg hint.
216218
if (Reg.isPhysical() != Rhs.Reg.isPhysical())
217219
return Reg.isPhysical();
218220
if (Weight != Rhs.Weight)
219221
return (Weight > Rhs.Weight);
222+
// Prefer non-CSR to CSR.
223+
if (Reg.isPhysical() && IsCSR != Rhs.IsCSR)
224+
return !IsCSR;
220225
return Reg.id() < Rhs.Reg.id(); // Tie-breaker.
221226
}
222227
};
@@ -299,10 +304,12 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
299304
SmallVector<CopyHint, 8> RegHints;
300305
for (const auto &[Reg, Weight] : Hint) {
301306
if (Reg != SkipReg)
302-
RegHints.emplace_back(Reg, Weight);
307+
RegHints.emplace_back(
308+
Reg, Weight,
309+
Reg.isPhysical() ? TRI.isCalleeSavedPhysReg(Reg, MF) : false);
303310
}
304311
sort(RegHints);
305-
for (const auto &[Reg, Weight] : RegHints)
312+
for (const auto &[Reg, _, __] : RegHints)
306313
MRI.addRegAllocationHint(LI.reg(), Reg);
307314

308315
// Weakly boost the spill weight of hinted registers.

llvm/test/CodeGen/AArch64/aarch64-signedreturnaddress.ll

+3-7
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@ entry:
1515
; CHECK-NEXT: mov x0, x30
1616
; CHECK-NEXT: ldr x30, [sp], #16
1717
; CHECK-NEXT: ret
18-
; CHECKV83: str x30, [sp, #-16]!
19-
; CHECKV83-NEXT: xpaci x30
20-
; CHECKV83-NEXT: mov x0, x30
21-
; CHECKV83-NEXT: ldr x30, [sp], #16
18+
; CHECKV83: mov x0, x30
19+
; CHECKV83-NEXT: xpaci x0
2220
; CHECKV83-NEXT: ret
2321
%0 = tail call ptr @llvm.returnaddress(i32 0)
2422
ret ptr %0
@@ -35,10 +33,8 @@ entry:
3533
; CHECK-NEXT: hint #29
3634
; CHECK-NEXT: ret
3735
; CHECKV83: paciasp
38-
; CHECKV83-NEXT: str x30, [sp, #-16]!
39-
; CHECKV83-NEXT: xpaci x30
4036
; CHECKV83-NEXT: mov x0, x30
41-
; CHECKV83-NEXT: ldr x30, [sp], #16
37+
; CHECKV83-NEXT: xpaci x0
4238
; CHECKV83-NEXT: retaa
4339
%0 = tail call ptr @llvm.returnaddress(i32 0)
4440
ret ptr %0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2+
# RUN: llc -mtriple=arm64-eabi -mattr=v8.3a -stop-after=virtregmap -o - %s | FileCheck %s
3+
4+
---
5+
name: ra0
6+
tracksRegLiveness: true
7+
isSSA: true
8+
body: |
9+
bb.0.entry:
10+
liveins: $lr
11+
12+
; CHECK-LABEL: name: ra0
13+
; CHECK: liveins: $lr
14+
; CHECK-NEXT: {{ $}}
15+
; CHECK-NEXT: $x0 = ORRXrs $xzr, $lr, 0
16+
; CHECK-NEXT: renamable $x0 = XPACI killed renamable $x0
17+
; CHECK-NEXT: RET undef $lr, implicit killed $x0
18+
%0:gpr64 = COPY killed $lr
19+
%1:gpr64 = XPACI killed %0
20+
$x0 = COPY killed %1
21+
RET_ReallyLR implicit killed $x0
22+
...

llvm/test/CodeGen/AArch64/ptrauth-ret.ll

+2-5
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,9 @@ define void @test_noframe() #0 {
112112
define ptr @test_returnaddress_0() #0 {
113113
; CHECK-LABEL: test_returnaddress_0:
114114
; CHECK: %bb.0:
115-
; CHECK-NEXT: pacibsp
116-
; CHECK-NEXT: str x30, [sp, #-16]!
117-
; CHECK-NEXT: xpaci x30
118115
; CHECK-NEXT: mov x0, x30
119-
; CHECK-NEXT: ldr x30, [sp], #16
120-
; CHECK-NEXT: retab
116+
; CHECK-NEXT: xpaci x0
117+
; CHECK-NEXT: ret
121118
%r = call ptr @llvm.returnaddress(i32 0)
122119
ret ptr %r
123120
}

llvm/test/CodeGen/AVR/calling-conv/c/basic_aggr.ll

+2-4
Original file line numberDiff line numberDiff line change
@@ -132,17 +132,15 @@ define i8 @foo2([6 x i8] %0, [6 x i8] %1, [6 x i8] %2) {
132132
define i8 @foo3([9 x i8] %0, [9 x i8] %1) {
133133
; CHECK-LABEL: foo3:
134134
; CHECK: ; %bb.0:
135-
; CHECK-NEXT: push r16
136135
; CHECK-NEXT: push r28
137136
; CHECK-NEXT: push r29
138137
; CHECK-NEXT: in r28, 61
139138
; CHECK-NEXT: in r29, 62
140-
; CHECK-NEXT: ldd r24, Y+6
141-
; CHECK-NEXT: sub r16, r24
142139
; CHECK-NEXT: mov r24, r16
140+
; CHECK-NEXT: ldd r25, Y+5
141+
; CHECK-NEXT: sub r24, r25
143142
; CHECK-NEXT: pop r29
144143
; CHECK-NEXT: pop r28
145-
; CHECK-NEXT: pop r16
146144
; CHECK-NEXT: ret
147145
%3 = extractvalue [9 x i8] %0, 0
148146
%4 = extractvalue [9 x i8] %1, 0

llvm/test/CodeGen/AVR/calling-conv/c/stack.ll

+7-9
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,15 @@ define i8 @foo1([19 x i8] %a, i8 %b) {
7474
define i8 @foo2([17 x i8] %a, i8 %b) {
7575
; CHECK-LABEL: foo2:
7676
; CHECK: ; %bb.0:
77-
; CHECK-NEXT: push r8
7877
; CHECK-NEXT: push r28
7978
; CHECK-NEXT: push r29
80-
; CHECK-NEXT: in r28, 61
81-
; CHECK-NEXT: in r29, 62
82-
; CHECK-NEXT: ldd r24, Y+6
83-
; CHECK-NEXT: sub r8, r24
84-
; CHECK-NEXT: mov r24, r8
85-
; CHECK-NEXT: pop r29
86-
; CHECK-NEXT: pop r28
87-
; CHECK-NEXT: pop r8
79+
; CHECK-NEXT: in r28, 61
80+
; CHECK-NEXT: in r29, 62
81+
; CHECK-NEXT: mov r24, r8
82+
; CHECK-NEXT: ldd r25, Y+5
83+
; CHECK-NEXT: sub r24, r25
84+
; CHECK-NEXT: pop r29
85+
; CHECK-NEXT: pop r28
8886
; CHECK-NEXT: ret
8987
%c = extractvalue [17 x i8] %a, 0
9088
%d = sub i8 %c, %b

llvm/test/CodeGen/AVR/dynalloca.ll

+10-10
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,16 @@ define void @dynalloca2(i16 %x) {
6464
; CHECK-NEXT: out 63, r0
6565
; CHECK-NEXT: out 61, {{.*}}
6666
; Store values on the stack
67-
; CHECK: ldi r16, 0
68-
; CHECK: ldi r17, 0
69-
; CHECK: std Z+8, r17
70-
; CHECK: std Z+7, r16
71-
; CHECK: std Z+6, r17
72-
; CHECK: std Z+5, r16
73-
; CHECK: std Z+4, r17
74-
; CHECK: std Z+3, r16
75-
; CHECK: std Z+2, r17
76-
; CHECK: std Z+1, r16
67+
; CHECK: ldi r20, 0
68+
; CHECK: ldi r21, 0
69+
; CHECK: std Z+8, r21
70+
; CHECK: std Z+7, r20
71+
; CHECK: std Z+6, r21
72+
; CHECK: std Z+5, r20
73+
; CHECK: std Z+4, r21
74+
; CHECK: std Z+3, r20
75+
; CHECK: std Z+2, r21
76+
; CHECK: std Z+1, r20
7777
; CHECK: call
7878
; Call frame restore
7979
; CHECK-NEXT: in r30, 61

llvm/test/CodeGen/AVR/return.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ define i32 @return32_arg(i32 %x) {
126126
define i32 @return32_arg2(i32 %x, i32 %y, i32 %z) {
127127
; AVR-LABEL: return32_arg2:
128128
; AVR: ; %bb.0:
129-
; AVR-NEXT: movw r22, r14
130129
; AVR-NEXT: movw r24, r16
130+
; AVR-NEXT: movw r22, r14
131131
; AVR-NEXT: ret
132132
;
133133
; TINY-LABEL: return32_arg2:

llvm/test/CodeGen/SPARC/2011-01-19-DelaySlot.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ entry:
6060
;CHECK: sethi
6161
;CHECK: !NO_APP
6262
;CHECK-NEXT: ble
63-
;CHECK-NEXT: mov
63+
;CHECK-NEXT: nop
6464
tail call void asm sideeffect "sethi 0, %g0", ""() nounwind
6565
%0 = icmp slt i32 %a, 0
6666
br i1 %0, label %bb, label %bb1

llvm/test/CodeGen/SPARC/32abi.ll

+20-20
Original file line numberDiff line numberDiff line change
@@ -143,28 +143,28 @@ define double @floatarg(double %a0, ; %i0,%i1
143143
; CHECK-LABEL: call_floatarg:
144144
; HARD: save %sp, -112, %sp
145145
; HARD: mov %i2, %o1
146+
; HARD-NEXT: mov %i0, %o2
146147
; HARD-NEXT: mov %i1, %o0
147148
; HARD-NEXT: st %i0, [%sp+104]
148149
; HARD-NEXT: std %o0, [%sp+96]
149150
; HARD-NEXT: st %o1, [%sp+92]
150-
; HARD-NEXT: mov %i0, %o2
151151
; HARD-NEXT: mov %i1, %o3
152152
; HARD-NEXT: mov %o1, %o4
153153
; HARD-NEXT: mov %i1, %o5
154154
; HARD-NEXT: call floatarg
155155
; HARD: std %f0, [%i4]
156-
; SOFT: st %i0, [%sp+104]
157-
; SOFT-NEXT: st %i2, [%sp+100]
158-
; SOFT-NEXT: st %i1, [%sp+96]
159-
; SOFT-NEXT: st %i2, [%sp+92]
160-
; SOFT-NEXT: mov %i1, %o0
161-
; SOFT-NEXT: mov %i2, %o1
162-
; SOFT-NEXT: mov %i0, %o2
163-
; SOFT-NEXT: mov %i1, %o3
164-
; SOFT-NEXT: mov %i2, %o4
165-
; SOFT-NEXT: mov %i1, %o5
166-
; SOFT-NEXT: call floatarg
167-
; SOFT: std %o0, [%i4]
156+
; SOFT: mov %i2, %o1
157+
; SOFT-NEXT: mov %i1, %o0
158+
; SOFT-NEXT: mov %i0, %o2
159+
; SOFT-NEXT: st %i0, [%sp+104]
160+
; SOFT-NEXT: st %i2, [%sp+100]
161+
; SOFT-NEXT: st %i1, [%sp+96]
162+
; SOFT-NEXT: st %i2, [%sp+92]
163+
; SOFT-NEXT: mov %i1, %o3
164+
; SOFT-NEXT: mov %i2, %o4
165+
; SOFT-NEXT: mov %i1, %o5
166+
; SOFT-NEXT: call floatarg
167+
; SOFT: std %o0, [%i4]
168168
; CHECK: restore
169169
define void @call_floatarg(float %f1, double %d2, float %f5, ptr %p) {
170170
%r = call double @floatarg(double %d2, float %f1, double %d2, double %d2,
@@ -228,16 +228,16 @@ define i64 @i64arg(i64 %a0, ; %i0,%i1
228228

229229
; CHECK-LABEL: call_i64arg:
230230
; CHECK: save %sp, -112, %sp
231-
; CHECK: st %i0, [%sp+104]
231+
; CHECK: mov %i2, %o1
232+
; CHECK-NEXT: mov %i1, %o0
233+
; CHECK-NEXT: mov %i0, %o2
234+
; CHECK-NEXT: st %i0, [%sp+104]
232235
; CHECK-NEXT: st %i2, [%sp+100]
233236
; CHECK-NEXT: st %i1, [%sp+96]
234237
; CHECK-NEXT: st %i2, [%sp+92]
235-
; CHECK-NEXT: mov %i1, %o0
236-
; CHECK-NEXT: mov %i2, %o1
237-
; CHECK-NEXT: mov %i0, %o2
238-
; CHECK-NEXT: mov %i1, %o3
239-
; CHECK-NEXT: mov %i2, %o4
240-
; CHECK-NEXT: mov %i1, %o5
238+
; CHECK-NEXT: mov %i1, %o3
239+
; CHECK-NEXT: mov %i2, %o4
240+
; CHECK-NEXT: mov %i1, %o5
241241
; CHECK-NEXT: call i64arg
242242
; CHECK: std %o0, [%i3]
243243
; CHECK-NEXT: restore

llvm/test/CodeGen/SPARC/64abi.ll

+5-9
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,10 @@ define double @floatarg(float %a0, ; %f1
118118
; SOFT: stx %i2, [%sp+2239]
119119
; SOFT: stx %i2, [%sp+2231]
120120
; SOFT: stx %i2, [%sp+2223]
121-
; SOFT: mov %i2, %o0
122-
; SOFT: mov %i1, %o1
123-
; SOFT: mov %i1, %o2
124-
; SOFT: mov %i1, %o3
125-
; SOFT: mov %i2, %o4
126-
; SOFT: mov %i2, %o5
121+
; SOFT: mov %i1, %o2
122+
; SOFT: mov %i1, %o3
123+
; SOFT: mov %i2, %o4
124+
; SOFT: mov %i2, %o5
127125
; CHECK: call floatarg
128126
; CHECK-NOT: add %sp
129127
; CHECK: restore
@@ -174,11 +172,9 @@ define void @mixedarg(i8 %a0, ; %i0
174172

175173
; CHECK-LABEL: call_mixedarg:
176174
; CHECK: stx %i2, [%sp+2247]
177-
; SOFT: stx %i1, [%sp+2239]
178175
; CHECK: stx %i0, [%sp+2223]
179176
; HARD: fmovd %f2, %f6
180177
; HARD: fmovd %f2, %f16
181-
; SOFT: mov %i1, %o3
182178
; CHECK: call mixedarg
183179
; CHECK-NOT: add %sp
184180
; CHECK: restore
@@ -262,8 +258,8 @@ define i32 @inreg_if(float inreg %a0, ; %f0
262258
}
263259

264260
; CHECK-LABEL: call_inreg_if:
265-
; HARD: fmovs %f3, %f0
266261
; HARD: mov %i2, %o0
262+
; HARD: fmovs %f3, %f0
267263
; SOFT: srl %i2, 0, %i0
268264
; SOFT: sllx %i1, 32, %i1
269265
; SOFT: or %i1, %i0, %o0

llvm/test/CodeGen/SPARC/bigreturn.ll

+7-7
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@ define i32 @call_ret_i32_arr(i32 %0) {
9292
; SPARC-NEXT: .cfi_def_cfa_register %fp
9393
; SPARC-NEXT: .cfi_window_save
9494
; SPARC-NEXT: .cfi_register %o7, %i7
95-
; SPARC-NEXT: add %fp, -64, %i1
96-
; SPARC-NEXT: st %i1, [%sp+64]
9795
; SPARC-NEXT: mov %i0, %o0
96+
; SPARC-NEXT: add %fp, -64, %i0
97+
; SPARC-NEXT: st %i0, [%sp+64]
9898
; SPARC-NEXT: call ret_i32_arr
9999
; SPARC-NEXT: nop
100100
; SPARC-NEXT: unimp 64
@@ -110,8 +110,8 @@ define i32 @call_ret_i32_arr(i32 %0) {
110110
; SPARC64-NEXT: .cfi_def_cfa_register %fp
111111
; SPARC64-NEXT: .cfi_window_save
112112
; SPARC64-NEXT: .cfi_register %o7, %i7
113-
; SPARC64-NEXT: add %fp, 1983, %o0
114113
; SPARC64-NEXT: mov %i0, %o1
114+
; SPARC64-NEXT: add %fp, 1983, %o0
115115
; SPARC64-NEXT: call ret_i32_arr
116116
; SPARC64-NEXT: nop
117117
; SPARC64-NEXT: ld [%fp+2043], %i0
@@ -220,10 +220,10 @@ define i64 @call_ret_i64_arr(i64 %0) {
220220
; SPARC-NEXT: .cfi_def_cfa_register %fp
221221
; SPARC-NEXT: .cfi_window_save
222222
; SPARC-NEXT: .cfi_register %o7, %i7
223-
; SPARC-NEXT: add %fp, -128, %i2
224-
; SPARC-NEXT: st %i2, [%sp+64]
225-
; SPARC-NEXT: mov %i0, %o0
226223
; SPARC-NEXT: mov %i1, %o1
224+
; SPARC-NEXT: mov %i0, %o0
225+
; SPARC-NEXT: add %fp, -128, %i0
226+
; SPARC-NEXT: st %i0, [%sp+64]
227227
; SPARC-NEXT: call ret_i64_arr
228228
; SPARC-NEXT: nop
229229
; SPARC-NEXT: unimp 128
@@ -239,8 +239,8 @@ define i64 @call_ret_i64_arr(i64 %0) {
239239
; SPARC64-NEXT: .cfi_def_cfa_register %fp
240240
; SPARC64-NEXT: .cfi_window_save
241241
; SPARC64-NEXT: .cfi_register %o7, %i7
242-
; SPARC64-NEXT: add %fp, 1919, %o0
243242
; SPARC64-NEXT: mov %i0, %o1
243+
; SPARC64-NEXT: add %fp, 1919, %o0
244244
; SPARC64-NEXT: call ret_i64_arr
245245
; SPARC64-NEXT: nop
246246
; SPARC64-NEXT: ldx [%fp+2039], %i0

0 commit comments

Comments
 (0)