diff options
author | Michael Meissner <meissner@gcc.gnu.org> | 2020-02-03 18:25:07 -0500 |
---|---|---|
committer | Michael Meissner <meissner@gcc.gnu.org> | 2020-02-03 18:25:07 -0500 |
commit | e181ffc92a355d1854a413f27354e519f93e126a (patch) | |
tree | 00836d49c47a2d6f89cacbd1def4d9eee11062d2 | |
parent | fb47dc28d2d38f56af65e9f244af8870bd568b0b (diff) | |
download | gcc-e181ffc92a355d1854a413f27354e519f93e126a.zip gcc-e181ffc92a355d1854a413f27354e519f93e126a.tar.gz gcc-e181ffc92a355d1854a413f27354e519f93e126a.tar.bz2 |
Optimize vec_extract of vectors in memory with a PC-relative address.
2020-02-03 Michael Meissner <meissner@linux.ibm.com>
* config/rs6000/rs6000.c (adjust_vec_address_pcrel): New helper
function to adjust PC-relative vector addresses.
(rs6000_adjust_vec_address): Call adjust_vec_address_pcrel to
handle vectors with PC-relative addresses.
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 59 |
2 files changed, 66 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 927968f..350f18d1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2020-02-03 Michael Meissner <meissner@linux.ibm.com> + * config/rs6000/rs6000.c (adjust_vec_address_pcrel): New helper + function to adjust PC-relative vector addresses. + (rs6000_adjust_vec_address): Call adjust_vec_address_pcrel to + handle vectors with PC-relative addresses. + +2020-02-03 Michael Meissner <meissner@linux.ibm.com> + * config/rs6000/rs6000.c (reg_to_non_prefixed): Add forward reference. (hard_reg_and_mode_to_addr_mask): Delete. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 0cd9cd1..bf0dc97 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -6767,6 +6767,60 @@ get_vector_offset (rtx mem, rtx element, rtx base_tmp, unsigned scalar_size) return base_tmp; } +/* Helper function update PC-relative addresses when we are adjusting a memory + address (ADDR) to a vector to point to a scalar field within the vector with + a constant offset (ELEMENT_OFFSET). If the address is not valid, we can + use the base register temporary (BASE_TMP) to form the address. */ + +static rtx +adjust_vec_address_pcrel (rtx addr, rtx element_offset, rtx base_tmp) +{ + rtx new_addr = NULL; + + gcc_assert (CONST_INT_P (element_offset)); + + if (GET_CODE (addr) == CONST) + addr = XEXP (addr, 0); + + if (GET_CODE (addr) == PLUS) + { + rtx op0 = XEXP (addr, 0); + rtx op1 = XEXP (addr, 1); + + if (CONST_INT_P (op1)) + { + HOST_WIDE_INT offset + = INTVAL (XEXP (addr, 1)) + INTVAL (element_offset); + + if (offset == 0) + new_addr = op0; + + else + { + rtx plus = gen_rtx_PLUS (Pmode, op0, GEN_INT (offset)); + new_addr = gen_rtx_CONST (Pmode, plus); + } + } + + else + { + emit_move_insn (base_tmp, addr); + new_addr = gen_rtx_PLUS (Pmode, base_tmp, element_offset); + } + } + + else if (SYMBOL_REF_P (addr) || LABEL_REF_P (addr)) + { + rtx plus = gen_rtx_PLUS (Pmode, addr, element_offset); + new_addr = gen_rtx_CONST (Pmode, plus); + } + + else + gcc_unreachable (); + + return new_addr; +} + /* Adjust a memory address (MEM) of a vector type to point to a scalar field within the vector (ELEMENT) with a mode (SCALAR_MODE). Use a base register temporary (BASE_TMP) to fixup the address. Return the new memory address @@ -6807,6 +6861,11 @@ rs6000_adjust_vec_address (rtx scalar_reg, else if (REG_P (addr) || SUBREG_P (addr)) new_addr = gen_rtx_PLUS (Pmode, addr, element_offset); + /* For references to local static variables, fold a constant offset into the + address. */ + else if (pcrel_local_address (addr, Pmode) && CONST_INT_P (element_offset)) + new_addr = adjust_vec_address_pcrel (addr, element_offset, base_tmp); + /* Optimize D-FORM addresses with constant offset with a constant element, to include the element offset in the address directly. */ else if (GET_CODE (addr) == PLUS) |