[gcc(refs/users/meissner/heads/work014)] Move checking of non-prefixed offsettable insn to separate function.

Michael Meissner meissner@gcc.gnu.org
Thu Sep 3 17:10:08 GMT 2020


https://gcc.gnu.org/g:f5034fa3186091e045804bc3e3cfc343e5a2260e

commit f5034fa3186091e045804bc3e3cfc343e5a2260e
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Thu Sep 3 13:09:31 2020 -0400

    Move checking of non-prefixed offsettable insn to separate function.
    
    gcc/
    2020-09-03  Michael Meissner  <meissner@linux.ibm.com>
    
            * config/rs6000/pcrel-opt.c (pcrel_opt_load): Use
            offsettable_non_prefixed_memory.
            (pcrel_opt_store): Likewise.
            * config/rs6000/rs6000-protos.h (offsettable_non_prefixed_memory):
            New declaration.
            * config/rs6000/rs6000.c (offsettable_non_prefixed_memory): New
            function.

Diff:
---
 gcc/config/rs6000/pcrel-opt.c     | 36 ++++++++----------------------------
 gcc/config/rs6000/rs6000-protos.h |  1 +
 gcc/config/rs6000/rs6000.c        | 26 ++++++++++++++++++++++++++
 3 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/gcc/config/rs6000/pcrel-opt.c b/gcc/config/rs6000/pcrel-opt.c
index 27f47ec97a7..23a1cc0eba6 100644
--- a/gcc/config/rs6000/pcrel-opt.c
+++ b/gcc/config/rs6000/pcrel-opt.c
@@ -232,8 +232,8 @@ pcrel_opt_load (rtx_insn *addr_insn,		/* insn loading address.  */
 
   /* LWA is a DS format instruction, but LWZ is a D format instruction.  We use
      DImode for the mode to force checking whether the bottom 2 bits are 0.
-     However FPR and vector registers uses the LFIWAX instruction which is
-     indexed only.  */
+     However FPR and vector registers uses the LFIWAX/LXSIWAX instructions
+     which only have indexed forms.  */
   if (GET_CODE (mem) == SIGN_EXTEND && GET_MODE (XEXP (mem, 0)) == SImode)
     {
       if (!INT_REGNO_P (reg_regno))
@@ -254,19 +254,9 @@ pcrel_opt_load (rtx_insn *addr_insn,		/* insn loading address.  */
   if (!MEM_P (mem_inner))
     return;
 
-  /* If this is LFIWAX or similar instructions that are indexed only, we can't
-     do the optimization.  */
-  enum non_prefixed_form non_prefixed = reg_to_non_prefixed (reg, mem_mode);
-  if (non_prefixed == NON_PREFIXED_X)
-    return;
-
-  /* The optimization will only work on non-prefixed offsettable loads.  */
-  rtx addr = XEXP (mem_inner, 0);
-  enum insn_form iform = address_to_insn_form (addr, mem_mode, non_prefixed);
-  if (iform != INSN_FORM_BASE_REG
-      && iform != INSN_FORM_D
-      && iform != INSN_FORM_DS
-      && iform != INSN_FORM_DQ)
+  /* If the address isn't a non-prefixed offsettable instruction, we can't do
+     the optimization.  */
+  if (!offsettable_non_prefixed_memory (reg, mem_mode, mem_inner))
     return;
 
   /* Allocate a new PC-relative label, and update the load external address
@@ -443,19 +433,9 @@ pcrel_opt_store (rtx_insn *addr_insn,		/* insn loading address.  */
       && !reg_set_between_p (reg, addr_insn, store_insn))
     return;
 
-  /* If this is LFIWAX or similar instructions that are indexed only, we can't
-     do the optimization.  */
-  enum non_prefixed_form non_prefixed = reg_to_non_prefixed (reg, mem_mode);
-  if (non_prefixed == NON_PREFIXED_X)
-    return;
-
-  /* The optimization will only work on non-prefixed offsettable loads.  */
-  rtx addr = XEXP (mem, 0);
-  enum insn_form iform = address_to_insn_form (addr, mem_mode, non_prefixed);
-  if (iform != INSN_FORM_BASE_REG
-      && iform != INSN_FORM_D
-      && iform != INSN_FORM_DS
-      && iform != INSN_FORM_DQ)
+  /* If the address isn't a non-prefixed offsettable instruction, we can't do
+     the optimization.  */
+  if (!offsettable_non_prefixed_memory (reg, mem_mode, mem))
     return;
 
   /* Allocate a new PC-relative label, and update the load address insn.
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index c21b37c3f01..71229bcfc51 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -190,6 +190,7 @@ enum non_prefixed_form {
 extern enum insn_form address_to_insn_form (rtx, machine_mode,
 					    enum non_prefixed_form);
 extern enum non_prefixed_form reg_to_non_prefixed (rtx, machine_mode);
+extern bool offsettable_non_prefixed_memory (rtx, machine_mode, rtx);
 extern bool prefixed_load_p (rtx_insn *);
 extern bool prefixed_store_p (rtx_insn *);
 extern bool prefixed_paddi_p (rtx_insn *);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index d5bae285ae5..1d62284eb66 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -25394,6 +25394,32 @@ address_to_insn_form (rtx addr,
   return INSN_FORM_BAD;
 }
 
+/* Return true if an REG with a given MODE is loaded from or stored into a MEM
+   location uses a non-prefixed offsettable address.  This is used to validate
+   the load or store with the PCREL_OPT optimization to make sure it is an
+   instruction that can be optimized.
+
+   We need to specify the MODE separately from the REG to allow for loads that
+   include zero/sign/float extension.  */
+
+bool
+offsettable_non_prefixed_memory (rtx reg, machine_mode mode, rtx mem)
+{
+  /* If the instruction is indexed only like LFIWAX/LXSIWAX, it is not
+     offsettable.  */
+  enum non_prefixed_form non_prefixed = reg_to_non_prefixed (reg, mode);
+  if (non_prefixed == NON_PREFIXED_X)
+    return false;
+
+  /* Check if this is a non-prefixed offsettable instruction.  */
+  rtx addr = XEXP (mem, 0);
+  enum insn_form iform = address_to_insn_form (addr, mode, non_prefixed);
+  return (iform == INSN_FORM_BASE_REG
+	  || iform == INSN_FORM_D
+	  || iform == INSN_FORM_DS
+	  || iform == INSN_FORM_DQ);
+}
+
 /* Helper function to see if we're potentially looking at lfs/stfs.
    - PARALLEL containing a SET and a CLOBBER
    - stfs:


More information about the Gcc-cvs mailing list