diff options
Diffstat (limited to '0233-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch')
-rw-r--r-- | 0233-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/0233-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch b/0233-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch new file mode 100644 index 0000000..95b50de --- /dev/null +++ b/0233-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch @@ -0,0 +1,140 @@ +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 + |