Skip to content

Commit f649f24

Browse files
committed
[RAGreedy] Enable -consider-local-interval-cost for AArch64
Summary: The greedy register allocator occasionally decides to insert a large number of unnecessary copies, see below for an example. The -consider-local-interval-cost option (which X86 already enables by default) fixes this. We enable this option for AArch64 only after receiving feedback that this change is not beneficial for PowerPC. We evaluated the impact of this change on compile time, code size and performance benchmarks. This option has a small impact on compile time, measured on CTMark. A 0.1% geomean regression on -O1 and -O2, and 0.2% geomean for -O3, with at most 0.5% on individual benchmarks. The effect on both code size and performance on AArch64 for the LLVM test suite is nil on the geomean with individual outliers (ignoring short exec_times) between: best worst size..text -3.3% +0.0% exec_time -5.8% +2.3% On SPEC CPU® 2017 (compiled for AArch64) there is a minor reduction (-0.2% at most) in code size on some benchmarks, with a tiny movement (-0.01%) on the geomean. Neither intrate nor fprate show any change in performance. This patch makes the following changes. - For the AArch64 target, enableAdvancedRASplitCost() now returns true. - Ensures that -consider-local-interval-cost=false can disable the new behaviour if necessary. This matrix multiply example: $ cat test.c long A[8][8]; long B[8][8]; long C[8][8]; void run_test() { for (int k = 0; k < 8; k++) { for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { C[i][j] += A[i][k] * B[k][j]; } } } } results in the following generated code on AArch64: $ clang --target=aarch64-arm-none-eabi -O3 -S test.c -o - [...] // %for.cond1.preheader // =>This Inner Loop Header: Depth=1 add x14, x11, x9 str q0, [sp, llvm#16] // 16-byte Folded Spill ldr q0, [x14] mov v2.16b, v15.16b mov v15.16b, v14.16b mov v14.16b, v13.16b mov v13.16b, v12.16b mov v12.16b, v11.16b mov v11.16b, v10.16b mov v10.16b, v9.16b mov v9.16b, v8.16b mov v8.16b, v31.16b mov v31.16b, v30.16b mov v30.16b, v29.16b mov v29.16b, v28.16b mov v28.16b, v27.16b mov v27.16b, v26.16b mov v26.16b, v25.16b mov v25.16b, v24.16b mov v24.16b, v23.16b mov v23.16b, v22.16b mov v22.16b, v21.16b mov v21.16b, v20.16b mov v20.16b, v19.16b mov v19.16b, v18.16b mov v18.16b, v17.16b mov v17.16b, v16.16b mov v16.16b, v7.16b mov v7.16b, v6.16b mov v6.16b, v5.16b mov v5.16b, v4.16b mov v4.16b, v3.16b mov v3.16b, v1.16b mov x12, v0.d[1] fmov x15, d0 ldp q1, q0, [x14, llvm#16] ldur x1, [x10, #-256] ldur x2, [x10, #-192] add x9, x9, llvm#64 // =64 mov x13, v1.d[1] fmov x16, d1 ldr q1, [x14, llvm#48] mul x3, x15, x1 mov x14, v0.d[1] fmov x17, d0 mov x18, v1.d[1] fmov x0, d1 mov v1.16b, v3.16b mov v3.16b, v4.16b mov v4.16b, v5.16b mov v5.16b, v6.16b mov v6.16b, v7.16b mov v7.16b, v16.16b mov v16.16b, v17.16b mov v17.16b, v18.16b mov v18.16b, v19.16b mov v19.16b, v20.16b mov v20.16b, v21.16b mov v21.16b, v22.16b mov v22.16b, v23.16b mov v23.16b, v24.16b mov v24.16b, v25.16b mov v25.16b, v26.16b mov v26.16b, v27.16b mov v27.16b, v28.16b mov v28.16b, v29.16b mov v29.16b, v30.16b mov v30.16b, v31.16b mov v31.16b, v8.16b mov v8.16b, v9.16b mov v9.16b, v10.16b mov v10.16b, v11.16b mov v11.16b, v12.16b mov v12.16b, v13.16b mov v13.16b, v14.16b mov v14.16b, v15.16b mov v15.16b, v2.16b ldr q2, [sp] // 16-byte Folded Reload fmov d0, x3 mul x3, x12, x1 [...] With -consider-local-interval-cost the same section of code results in the following: $ clang --target=aarch64-arm-none-eabi -mllvm -consider-local-interval-cost -O3 -S test.c -o - [...] .LBB0_1: // %for.cond1.preheader // =>This Inner Loop Header: Depth=1 add x14, x11, x9 ldp q0, q1, [x14] ldur x1, [x10, #-256] ldur x2, [x10, #-192] add x9, x9, llvm#64 // =64 mov x12, v0.d[1] fmov x15, d0 mov x13, v1.d[1] fmov x16, d1 ldp q0, q1, [x14, llvm#32] mul x3, x15, x1 cmp x9, llvm#512 // =512 mov x14, v0.d[1] fmov x17, d0 fmov d0, x3 mul x3, x12, x1 [...] Reviewers: SjoerdMeijer, samparker, dmgreen, qcolombet Reviewed By: dmgreen Subscribers: ZhangKang, jsji, wuzish, ppc-slack, lkail, steven.zhang, MatzeB, qcolombet, kristof.beyls, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D69437
1 parent f95273f commit f649f24

File tree

3 files changed

+19
-69
lines changed

3 files changed

+19
-69
lines changed

llvm/lib/CodeGen/RegAllocGreedy.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -3225,8 +3225,10 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
32253225
MF->getSubtarget().enableRALocalReassignment(
32263226
MF->getTarget().getOptLevel());
32273227

3228-
EnableAdvancedRASplitCost = ConsiderLocalIntervalCost ||
3229-
MF->getSubtarget().enableAdvancedRASplitCost();
3228+
EnableAdvancedRASplitCost =
3229+
ConsiderLocalIntervalCost.getNumOccurrences()
3230+
? ConsiderLocalIntervalCost
3231+
: MF->getSubtarget().enableAdvancedRASplitCost();
32303232

32313233
if (VerifyEnabled)
32323234
MF->verify(this, "Before greedy register allocator");

llvm/lib/Target/AArch64/AArch64Subtarget.h

+2
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,8 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo {
475475

476476
bool enableEarlyIfConversion() const override;
477477

478+
bool enableAdvancedRASplitCost() const override { return true; }
479+
478480
std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const override;
479481

480482
bool isCallingConvWin64(CallingConv::ID CC) const {

llvm/test/CodeGen/AArch64/ragreedy-local-interval-cost.ll

+13-67
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ define dso_local void @run_test() local_unnamed_addr #0 {
2626
; CHECK-NEXT: adrp x11, A
2727
; CHECK-NEXT: mov x8, xzr
2828
; CHECK-NEXT: mov x9, xzr
29-
; CHECK-NEXT: movi v14.2d, #0000000000000000
29+
; CHECK-NEXT: movi v0.2d, #0000000000000000
3030
; CHECK-NEXT: add x10, x10, :lo12:B+48
3131
; CHECK-NEXT: add x11, x11, :lo12:A
32+
; CHECK-NEXT: str q0, [sp] // 16-byte Folded Spill
3233
; CHECK-NEXT: // implicit-def: $q1
3334
; CHECK-NEXT: // implicit-def: $q2
3435
; CHECK-NEXT: // implicit-def: $q3
@@ -47,8 +48,8 @@ define dso_local void @run_test() local_unnamed_addr #0 {
4748
; CHECK-NEXT: // implicit-def: $q24
4849
; CHECK-NEXT: // implicit-def: $q25
4950
; CHECK-NEXT: // implicit-def: $q26
50-
; CHECK-NEXT: // implicit-def: $q28
5151
; CHECK-NEXT: // implicit-def: $q27
52+
; CHECK-NEXT: // implicit-def: $q28
5253
; CHECK-NEXT: // implicit-def: $q29
5354
; CHECK-NEXT: // implicit-def: $q30
5455
; CHECK-NEXT: // implicit-def: $q31
@@ -60,78 +61,20 @@ define dso_local void @run_test() local_unnamed_addr #0 {
6061
; CHECK-NEXT: // implicit-def: $q13
6162
; CHECK-NEXT: .LBB0_1: // %for.cond1.preheader
6263
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
63-
; CHECK-NEXT: str q13, [sp] // 16-byte Folded Spill
6464
; CHECK-NEXT: mov x12, xzr
6565
; CHECK-NEXT: ldr q15, [x8]
66-
; CHECK-NEXT: mov v13.16b, v12.16b
67-
; CHECK-NEXT: mov v12.16b, v11.16b
68-
; CHECK-NEXT: mov v11.16b, v10.16b
69-
; CHECK-NEXT: mov v10.16b, v9.16b
70-
; CHECK-NEXT: mov v9.16b, v8.16b
71-
; CHECK-NEXT: mov v8.16b, v31.16b
72-
; CHECK-NEXT: mov v31.16b, v30.16b
73-
; CHECK-NEXT: mov v30.16b, v29.16b
74-
; CHECK-NEXT: mov v29.16b, v27.16b
75-
; CHECK-NEXT: mov v27.16b, v26.16b
76-
; CHECK-NEXT: mov v26.16b, v25.16b
77-
; CHECK-NEXT: mov v25.16b, v24.16b
78-
; CHECK-NEXT: mov v24.16b, v23.16b
79-
; CHECK-NEXT: mov v23.16b, v22.16b
80-
; CHECK-NEXT: mov v22.16b, v21.16b
81-
; CHECK-NEXT: mov v21.16b, v20.16b
82-
; CHECK-NEXT: mov v20.16b, v19.16b
83-
; CHECK-NEXT: mov v19.16b, v18.16b
84-
; CHECK-NEXT: mov v18.16b, v17.16b
85-
; CHECK-NEXT: mov v17.16b, v16.16b
86-
; CHECK-NEXT: mov v16.16b, v7.16b
87-
; CHECK-NEXT: mov v7.16b, v6.16b
88-
; CHECK-NEXT: mov v6.16b, v5.16b
89-
; CHECK-NEXT: mov v5.16b, v4.16b
90-
; CHECK-NEXT: mov v4.16b, v3.16b
91-
; CHECK-NEXT: mov v3.16b, v2.16b
92-
; CHECK-NEXT: mov v2.16b, v1.16b
93-
; CHECK-NEXT: mov v1.16b, v14.16b
9466
; CHECK-NEXT: ldr q14, [x12]
9567
; CHECK-NEXT: ldr q0, [x10], #64
9668
; CHECK-NEXT: ldr x18, [x12]
9769
; CHECK-NEXT: fmov x15, d15
9870
; CHECK-NEXT: mov x14, v15.d[1]
99-
; CHECK-NEXT: mov x12, v14.d[1]
100-
; CHECK-NEXT: mul x1, x15, x18
10171
; CHECK-NEXT: fmov x13, d14
102-
; CHECK-NEXT: mov v14.16b, v1.16b
103-
; CHECK-NEXT: mov v1.16b, v2.16b
104-
; CHECK-NEXT: mov v2.16b, v3.16b
105-
; CHECK-NEXT: mov v3.16b, v4.16b
106-
; CHECK-NEXT: mov v4.16b, v5.16b
107-
; CHECK-NEXT: mov v5.16b, v6.16b
108-
; CHECK-NEXT: mov v6.16b, v7.16b
109-
; CHECK-NEXT: mov v7.16b, v16.16b
110-
; CHECK-NEXT: mov v16.16b, v17.16b
111-
; CHECK-NEXT: mov v17.16b, v18.16b
112-
; CHECK-NEXT: mov v18.16b, v19.16b
113-
; CHECK-NEXT: mov v19.16b, v20.16b
114-
; CHECK-NEXT: mov v20.16b, v21.16b
115-
; CHECK-NEXT: mov v21.16b, v22.16b
116-
; CHECK-NEXT: mov v22.16b, v23.16b
117-
; CHECK-NEXT: mov v23.16b, v24.16b
118-
; CHECK-NEXT: mov v24.16b, v25.16b
119-
; CHECK-NEXT: mov v25.16b, v26.16b
120-
; CHECK-NEXT: mov v26.16b, v27.16b
121-
; CHECK-NEXT: mov v27.16b, v29.16b
122-
; CHECK-NEXT: mov v29.16b, v30.16b
123-
; CHECK-NEXT: mov v30.16b, v31.16b
124-
; CHECK-NEXT: mov v31.16b, v8.16b
125-
; CHECK-NEXT: mov v8.16b, v9.16b
126-
; CHECK-NEXT: mov v9.16b, v10.16b
127-
; CHECK-NEXT: mov v10.16b, v11.16b
128-
; CHECK-NEXT: mov v11.16b, v12.16b
129-
; CHECK-NEXT: mov v12.16b, v13.16b
130-
; CHECK-NEXT: ldr q13, [sp] // 16-byte Folded Reload
72+
; CHECK-NEXT: mul x1, x15, x18
13173
; CHECK-NEXT: mov x16, v0.d[1]
13274
; CHECK-NEXT: fmov x17, d0
13375
; CHECK-NEXT: fmov d0, x1
13476
; CHECK-NEXT: mul x1, x14, x18
77+
; CHECK-NEXT: mov x12, v14.d[1]
13578
; CHECK-NEXT: ldr x0, [x8]
13679
; CHECK-NEXT: mov v0.d[1], x1
13780
; CHECK-NEXT: mul x1, x13, x18
@@ -144,6 +87,7 @@ define dso_local void @run_test() local_unnamed_addr #0 {
14487
; CHECK-NEXT: add v11.2d, v11.2d, v0.2d
14588
; CHECK-NEXT: fmov d0, x1
14689
; CHECK-NEXT: mul x18, x16, x18
90+
; CHECK-NEXT: ldr q14, [sp] // 16-byte Folded Reload
14791
; CHECK-NEXT: mov v0.d[1], x18
14892
; CHECK-NEXT: mul x18, x15, x0
14993
; CHECK-NEXT: add x1, x11, x8
@@ -194,28 +138,29 @@ define dso_local void @run_test() local_unnamed_addr #0 {
194138
; CHECK-NEXT: mul x17, x17, x1
195139
; CHECK-NEXT: mov v0.d[1], x12
196140
; CHECK-NEXT: mul x16, x16, x1
197-
; CHECK-NEXT: add v27.2d, v27.2d, v0.2d
141+
; CHECK-NEXT: add v28.2d, v28.2d, v0.2d
198142
; CHECK-NEXT: fmov d0, x17
199143
; CHECK-NEXT: mov v0.d[1], x16
200144
; CHECK-NEXT: add x8, x8, #8 // =8
201-
; CHECK-NEXT: add v28.2d, v28.2d, v0.2d
145+
; CHECK-NEXT: add v27.2d, v27.2d, v0.2d
202146
; CHECK-NEXT: cmp x8, #64 // =64
203147
; CHECK-NEXT: add x9, x9, #1 // =1
148+
; CHECK-NEXT: str q14, [sp] // 16-byte Folded Spill
204149
; CHECK-NEXT: b.ne .LBB0_1
205150
; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
206151
; CHECK-NEXT: adrp x8, C
207152
; CHECK-NEXT: add x8, x8, :lo12:C
153+
; CHECK-NEXT: ldr q0, [sp] // 16-byte Folded Reload
208154
; CHECK-NEXT: stp q13, q12, [x8]
209155
; CHECK-NEXT: stp q11, q10, [x8, #32]
210156
; CHECK-NEXT: stp q9, q8, [x8, #64]
211-
; CHECK-NEXT: stp q14, q2, [x8, #464]
212157
; CHECK-NEXT: ldp d9, d8, [sp, #64] // 16-byte Folded Reload
213158
; CHECK-NEXT: ldp d11, d10, [sp, #48] // 16-byte Folded Reload
214159
; CHECK-NEXT: ldp d13, d12, [sp, #32] // 16-byte Folded Reload
215160
; CHECK-NEXT: ldp d15, d14, [sp, #16] // 16-byte Folded Reload
216161
; CHECK-NEXT: stp q31, q30, [x8, #96]
217-
; CHECK-NEXT: stp q29, q27, [x8, #144]
218-
; CHECK-NEXT: stp q28, q26, [x8, #176]
162+
; CHECK-NEXT: stp q29, q28, [x8, #144]
163+
; CHECK-NEXT: stp q27, q26, [x8, #176]
219164
; CHECK-NEXT: str q25, [x8, #208]
220165
; CHECK-NEXT: stp q24, q23, [x8, #240]
221166
; CHECK-NEXT: stp q22, q21, [x8, #272]
@@ -224,6 +169,7 @@ define dso_local void @run_test() local_unnamed_addr #0 {
224169
; CHECK-NEXT: stp q16, q7, [x8, #368]
225170
; CHECK-NEXT: stp q6, q5, [x8, #400]
226171
; CHECK-NEXT: stp q4, q3, [x8, #432]
172+
; CHECK-NEXT: stp q0, q2, [x8, #464]
227173
; CHECK-NEXT: str q1, [x8, #496]
228174
; CHECK-NEXT: add sp, sp, #80 // =80
229175
; CHECK-NEXT: ret

0 commit comments

Comments
 (0)