summaryrefslogtreecommitdiff
path: root/gcc/gcse.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2003-02-07 22:57:41 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2003-02-07 22:57:41 +0000
commit3b2818348266ee064e8d2dbce866568ce782f66f (patch)
tree2b5b38168585de67e2af8095d36ab87ec2ffff69 /gcc/gcse.c
parentaaf2d92f959dbf231ede0961c0c66e7f71db4374 (diff)
downloadgcc-3b2818348266ee064e8d2dbce866568ce782f66f.tar.gz
* gcse.c (local_cprop_find_used_regs): New.
(local_cprop_pass): Use it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@62555 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gcse.c')
-rw-r--r--gcc/gcse.c52
1 files changed, 50 insertions, 2 deletions
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 3adaf5ca0ac..2cc7f0b1c67 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -706,6 +706,7 @@ static void free_insn_expr_list_list PARAMS ((rtx *));
static void clear_modify_mem_tables PARAMS ((void));
static void free_modify_mem_tables PARAMS ((void));
static rtx gcse_emit_move_after PARAMS ((rtx, rtx, rtx));
+static void local_cprop_find_used_regs PARAMS ((rtx *, void *));
static bool do_local_cprop PARAMS ((rtx, rtx, int, rtx*));
static bool adjust_libcall_notes PARAMS ((rtx, rtx, rtx, rtx*));
static void local_cprop_pass PARAMS ((int));
@@ -4258,6 +4259,53 @@ cprop_insn (insn, alter_jumps)
return changed;
}
+/* Like find_used_regs, but avoid recording uses that appear in
+ input-output contexts such as zero_extract or pre_dec. This
+ restricts the cases we consider to those for which local cprop
+ can legitimately make replacements. */
+
+static void
+local_cprop_find_used_regs (xptr, data)
+ rtx *xptr;
+ void *data;
+{
+ rtx x = *xptr;
+
+ if (x == 0)
+ return;
+
+ switch (GET_CODE (x))
+ {
+ case ZERO_EXTRACT:
+ case SIGN_EXTRACT:
+ case STRICT_LOW_PART:
+ return;
+
+ case PRE_DEC:
+ case PRE_INC:
+ case POST_DEC:
+ case POST_INC:
+ case PRE_MODIFY:
+ case POST_MODIFY:
+ /* Can only legitimately appear this early in the context of
+ stack pushes for function arguments, but handle all of the
+ codes nonetheless. */
+ return;
+
+ case SUBREG:
+ /* Setting a subreg of a register larger than word_mode leaves
+ the non-written words unchanged. */
+ if (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) > BITS_PER_WORD)
+ return;
+ break;
+
+ default:
+ break;
+ }
+
+ find_used_regs (xptr, data);
+}
+
/* LIBCALL_SP is a zero-terminated array of insns at the end of a libcall;
their REG_EQUAL notes need updating. */
@@ -4413,9 +4461,9 @@ local_cprop_pass (alter_jumps)
do
{
reg_use_count = 0;
- note_uses (&PATTERN (insn), find_used_regs, NULL);
+ note_uses (&PATTERN (insn), local_cprop_find_used_regs, NULL);
if (note)
- find_used_regs (&XEXP (note, 0), NULL);
+ local_cprop_find_used_regs (&XEXP (note, 0), NULL);
for (reg_used = &reg_use_table[0]; reg_use_count > 0;
reg_used++, reg_use_count--)