[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