aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meissner <meissner@gcc.gnu.org>2020-02-03 18:25:07 -0500
committerMichael Meissner <meissner@gcc.gnu.org>2020-02-03 18:25:07 -0500
commite181ffc92a355d1854a413f27354e519f93e126a (patch)
tree00836d49c47a2d6f89cacbd1def4d9eee11062d2
parentfb47dc28d2d38f56af65e9f244af8870bd568b0b (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/config/rs6000/rs6000.c59
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)