summaryrefslogtreecommitdiff
path: root/gcc/fwprop.c
diff options
context:
space:
mode:
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2009-08-30 06:09:42 +0000
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2009-08-30 06:09:42 +0000
commit42ed3b17575bde68a30b779ca99ed07ac4dbfa83 (patch)
tree85c88ae5c0ec2c25cfc07833f8954fc9586ed4be /gcc/fwprop.c
parent2ae90fb85a80fc692c40268896e2926c742edeb5 (diff)
downloadgcc-42ed3b17575bde68a30b779ca99ed07ac4dbfa83.tar.gz
PR target/41081
* fwprop.c (get_reg_use_in): Delete. (free_load_extend): New function. (forward_propagate_subreg): Use it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151221 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fwprop.c')
-rw-r--r--gcc/fwprop.c59
1 files changed, 38 insertions, 21 deletions
diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index 50daed2fc88..df8c45d3b6b 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -1014,24 +1014,54 @@ try_fwprop_subst (df_ref use, rtx *loc, rtx new_rtx, rtx def_insn, bool set_reg_
return ok;
}
-#ifdef LOAD_EXTEND_OP
-static df_ref
-get_reg_use_in (rtx insn, rtx reg)
+/* For the given single_set INSN, containing SRC known to be a
+ ZERO_EXTEND or SIGN_EXTEND of a register, return true if INSN
+ is redundant due to the register being set by a LOAD_EXTEND_OP
+ load from memory. */
+
+static bool
+free_load_extend (rtx src, rtx insn)
{
+ rtx reg;
df_ref *use_vec;
+ df_ref use, def;
+
+ reg = XEXP (src, 0);
+#ifdef LOAD_EXTEND_OP
+ if (LOAD_EXTEND_OP (GET_MODE (reg)) != GET_CODE (src))
+#endif
+ return false;
for (use_vec = DF_INSN_USES (insn); *use_vec; use_vec++)
{
- df_ref use = *use_vec;
+ use = *use_vec;
if (!DF_REF_IS_ARTIFICIAL (use)
&& DF_REF_TYPE (use) == DF_REF_REG_USE
&& DF_REF_REG (use) == reg)
- return use;
+ break;
}
- return NULL;
+ if (!use)
+ return false;
+
+ def = get_def_for_use (use);
+ if (!def)
+ return false;
+
+ if (DF_REF_IS_ARTIFICIAL (def))
+ return false;
+
+ if (NONJUMP_INSN_P (DF_REF_INSN (def)))
+ {
+ rtx patt = PATTERN (DF_REF_INSN (def));
+
+ if (GET_CODE (patt) == SET
+ && GET_CODE (SET_SRC (patt)) == MEM
+ && rtx_equal_p (SET_DEST (patt), reg))
+ return true;
+ }
+ return false;
}
-#endif
/* If USE is a subreg, see if it can be replaced by a pseudo. */
@@ -1073,26 +1103,13 @@ forward_propagate_subreg (df_ref use, rtx def_insn, rtx def_set)
be removed due to it matching a LOAD_EXTEND_OP load from memory. */
else if (subreg_lowpart_p (use_reg))
{
-#ifdef LOAD_EXTEND_OP
- df_ref prev_use, prev_def;
-#endif
use_insn = DF_REF_INSN (use);
src = SET_SRC (def_set);
if ((GET_CODE (src) == ZERO_EXTEND
|| GET_CODE (src) == SIGN_EXTEND)
&& REG_P (XEXP (src, 0))
&& GET_MODE (XEXP (src, 0)) == use_mode
-#ifdef LOAD_EXTEND_OP
- && !(LOAD_EXTEND_OP (use_mode) == GET_CODE (src)
- && (prev_use = get_reg_use_in (def_insn, XEXP (src, 0))) != NULL
- && (prev_def = get_def_for_use (prev_use)) != NULL
- && !DF_REF_IS_ARTIFICIAL (prev_def)
- && NONJUMP_INSN_P (DF_REF_INSN (prev_def))
- && GET_CODE (PATTERN (DF_REF_INSN (prev_def))) == SET
- && GET_CODE (SET_SRC (PATTERN (DF_REF_INSN (prev_def)))) == MEM
- && rtx_equal_p (SET_DEST (PATTERN (DF_REF_INSN (prev_def))),
- XEXP (src, 0)))
-#endif
+ && !free_load_extend (src, def_insn)
&& all_uses_available_at (def_insn, use_insn))
return try_fwprop_subst (use, DF_REF_LOC (use), XEXP (src, 0),
def_insn, false);