141 lines
5.0 KiB
Diff
141 lines
5.0 KiB
Diff
|
|
From 29a71fc5cbfc3b5e4649abf51740daed5ea243bd Mon Sep 17 00:00:00 2001
|
||
|
|
From: Richard Sandiford <richard.sandiford@arm.com>
|
||
|
|
Date: Tue, 5 Dec 2023 09:20:55 +0000
|
||
|
|
Subject: [PATCH 134/157] [Backport][SME] lra: Updates of biggest mode for hard
|
||
|
|
regs [PR112278]
|
||
|
|
|
||
|
|
Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=6e2e0ce6795c863e295eb33559f8dc0500297da3
|
||
|
|
|
||
|
|
LRA keeps track of the biggest mode for both hard registers and
|
||
|
|
pseudos. The updates assume that the modes are ordered, i.e. that
|
||
|
|
we can tell whether one is no bigger than the other at compile time.
|
||
|
|
|
||
|
|
That is (or at least seemed to be) a reasonable restriction for pseudos.
|
||
|
|
But it isn't necessarily so for hard registers, since the uses of hard
|
||
|
|
registers can be logically distinct. The testcase is an example of this.
|
||
|
|
|
||
|
|
The biggest mode of hard registers is also special for other reasons.
|
||
|
|
As the existing comment says:
|
||
|
|
|
||
|
|
/* A reg can have a biggest_mode of VOIDmode if it was only ever seen as
|
||
|
|
part of a multi-word register. In that case, just use the reg_rtx
|
||
|
|
mode. Do the same also if the biggest mode was larger than a register
|
||
|
|
or we can not compare the modes. Otherwise, limit the size to that of
|
||
|
|
the biggest access in the function or to the natural mode at least. */
|
||
|
|
|
||
|
|
This patch applies the same approach to the updates.
|
||
|
|
|
||
|
|
gcc/
|
||
|
|
PR rtl-optimization/112278
|
||
|
|
* lra-int.h (lra_update_biggest_mode): New function.
|
||
|
|
* lra-coalesce.cc (merge_pseudos): Use it.
|
||
|
|
* lra-lives.cc (process_bb_lives): Likewise.
|
||
|
|
* lra.cc (new_insn_reg): Likewise.
|
||
|
|
|
||
|
|
gcc/testsuite/
|
||
|
|
PR rtl-optimization/112278
|
||
|
|
* gcc.target/aarch64/sve/pr112278.c: New test.
|
||
|
|
---
|
||
|
|
gcc/lra-coalesce.cc | 4 +---
|
||
|
|
gcc/lra-int.h | 15 +++++++++++++++
|
||
|
|
gcc/lra-lives.cc | 4 +---
|
||
|
|
gcc/lra.cc | 5 ++---
|
||
|
|
gcc/testsuite/gcc.target/aarch64/sve/pr112278.c | 15 +++++++++++++++
|
||
|
|
5 files changed, 34 insertions(+), 9 deletions(-)
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/pr112278.c
|
||
|
|
|
||
|
|
diff --git a/gcc/lra-coalesce.cc b/gcc/lra-coalesce.cc
|
||
|
|
index c82934569..901a44663 100644
|
||
|
|
--- a/gcc/lra-coalesce.cc
|
||
|
|
+++ b/gcc/lra-coalesce.cc
|
||
|
|
@@ -112,9 +112,7 @@ merge_pseudos (int regno1, int regno2)
|
||
|
|
= (lra_merge_live_ranges
|
||
|
|
(lra_reg_info[first].live_ranges,
|
||
|
|
lra_copy_live_range_list (lra_reg_info[first2].live_ranges)));
|
||
|
|
- if (partial_subreg_p (lra_reg_info[first].biggest_mode,
|
||
|
|
- lra_reg_info[first2].biggest_mode))
|
||
|
|
- lra_reg_info[first].biggest_mode = lra_reg_info[first2].biggest_mode;
|
||
|
|
+ lra_update_biggest_mode (first, lra_reg_info[first2].biggest_mode);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Change pseudos in *LOC on their coalescing group
|
||
|
|
diff --git a/gcc/lra-int.h b/gcc/lra-int.h
|
||
|
|
index 04baefef3..040e87d11 100644
|
||
|
|
--- a/gcc/lra-int.h
|
||
|
|
+++ b/gcc/lra-int.h
|
||
|
|
@@ -525,4 +525,19 @@ lra_assign_reg_val (int from, int to)
|
||
|
|
lra_reg_info[to].offset = lra_reg_info[from].offset;
|
||
|
|
}
|
||
|
|
|
||
|
|
+/* Update REGNO's biggest recorded mode so that it includes a reference
|
||
|
|
+ in mode MODE. */
|
||
|
|
+inline void
|
||
|
|
+lra_update_biggest_mode (int regno, machine_mode mode)
|
||
|
|
+{
|
||
|
|
+ if (!ordered_p (GET_MODE_SIZE (lra_reg_info[regno].biggest_mode),
|
||
|
|
+ GET_MODE_SIZE (mode)))
|
||
|
|
+ {
|
||
|
|
+ gcc_checking_assert (HARD_REGISTER_NUM_P (regno));
|
||
|
|
+ lra_reg_info[regno].biggest_mode = reg_raw_mode[regno];
|
||
|
|
+ }
|
||
|
|
+ else if (partial_subreg_p (lra_reg_info[regno].biggest_mode, mode))
|
||
|
|
+ lra_reg_info[regno].biggest_mode = mode;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
#endif /* GCC_LRA_INT_H */
|
||
|
|
diff --git a/gcc/lra-lives.cc b/gcc/lra-lives.cc
|
||
|
|
index a755464ee..fb4a12304 100644
|
||
|
|
--- a/gcc/lra-lives.cc
|
||
|
|
+++ b/gcc/lra-lives.cc
|
||
|
|
@@ -770,9 +770,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
|
||
|
|
{
|
||
|
|
int regno = reg->regno;
|
||
|
|
|
||
|
|
- if (partial_subreg_p (lra_reg_info[regno].biggest_mode,
|
||
|
|
- reg->biggest_mode))
|
||
|
|
- lra_reg_info[regno].biggest_mode = reg->biggest_mode;
|
||
|
|
+ lra_update_biggest_mode (regno, reg->biggest_mode);
|
||
|
|
if (HARD_REGISTER_NUM_P (regno))
|
||
|
|
lra_hard_reg_usage[regno] += freq;
|
||
|
|
}
|
||
|
|
diff --git a/gcc/lra.cc b/gcc/lra.cc
|
||
|
|
index 1444cb759..8fda432f1 100644
|
||
|
|
--- a/gcc/lra.cc
|
||
|
|
+++ b/gcc/lra.cc
|
||
|
|
@@ -559,9 +559,8 @@ new_insn_reg (rtx_insn *insn, int regno, enum op_type type,
|
||
|
|
lra_insn_reg *ir = lra_insn_reg_pool.allocate ();
|
||
|
|
ir->type = type;
|
||
|
|
ir->biggest_mode = mode;
|
||
|
|
- if (NONDEBUG_INSN_P (insn)
|
||
|
|
- && partial_subreg_p (lra_reg_info[regno].biggest_mode, mode))
|
||
|
|
- lra_reg_info[regno].biggest_mode = mode;
|
||
|
|
+ if (NONDEBUG_INSN_P (insn))
|
||
|
|
+ lra_update_biggest_mode (regno, mode);
|
||
|
|
ir->subreg_p = subreg_p;
|
||
|
|
ir->early_clobber_alts = early_clobber_alts;
|
||
|
|
ir->regno = regno;
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr112278.c b/gcc/testsuite/gcc.target/aarch64/sve/pr112278.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..4f56add2b
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr112278.c
|
||
|
|
@@ -0,0 +1,15 @@
|
||
|
|
+#include <arm_neon.h>
|
||
|
|
+#include <arm_sve.h>
|
||
|
|
+
|
||
|
|
+void
|
||
|
|
+f (void)
|
||
|
|
+{
|
||
|
|
+ {
|
||
|
|
+ register svint8_t v0 asm ("z0");
|
||
|
|
+ asm volatile ("" : "=w" (v0));
|
||
|
|
+ }
|
||
|
|
+ {
|
||
|
|
+ register int8x8x4_t v0 asm ("v0");
|
||
|
|
+ asm volatile ("" : "=w" (v0));
|
||
|
|
+ }
|
||
|
|
+}
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|