summaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorwilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4>1997-04-14 18:46:37 +0000
committerwilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4>1997-04-14 18:46:37 +0000
commit5bc781143a11a5f3505555e6a3b37d802239de66 (patch)
tree7e68ff83fffc11fcda2dd324a23e77fecea27369 /gcc/combine.c
parentea85204aa7959631b7fc61c4946b3b6f781c3d07 (diff)
downloadgcc-5bc781143a11a5f3505555e6a3b37d802239de66.tar.gz
(get_last_value_validate): New argument insn.
Add check for memory reference clobbered by later store. (record_value_for_reg, get_last_values): Pass in new argument. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@13900 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index a2d63ea82fc..31efa5b84b6 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -445,7 +445,7 @@ static void update_table_tick PROTO((rtx));
static void record_value_for_reg PROTO((rtx, rtx, rtx));
static void record_dead_and_set_regs_1 PROTO((rtx, rtx));
static void record_dead_and_set_regs PROTO((rtx));
-static int get_last_value_validate PROTO((rtx *, int, int));
+static int get_last_value_validate PROTO((rtx *, rtx, int, int));
static rtx get_last_value PROTO((rtx));
static int use_crosses_set_p PROTO((rtx, int));
static void reg_dead_at_p_1 PROTO((rtx, rtx));
@@ -10203,11 +10203,12 @@ record_value_for_reg (reg, insn, value)
/* The value being assigned might refer to X (like in "x++;"). In that
case, we must replace it with (clobber (const_int 0)) to prevent
infinite loops. */
- if (value && ! get_last_value_validate (&value,
+ if (value && ! get_last_value_validate (&value, insn,
reg_last_set_label[regno], 0))
{
value = copy_rtx (value);
- if (! get_last_value_validate (&value, reg_last_set_label[regno], 1))
+ if (! get_last_value_validate (&value, insn,
+ reg_last_set_label[regno], 1))
value = 0;
}
@@ -10328,8 +10329,9 @@ record_dead_and_set_regs (insn)
we don't know exactly what registers it was produced from. */
static int
-get_last_value_validate (loc, tick, replace)
+get_last_value_validate (loc, insn, tick, replace)
rtx *loc;
+ rtx insn;
int tick;
int replace;
{
@@ -10359,10 +10361,20 @@ get_last_value_validate (loc, tick, replace)
return 1;
}
+ /* If this is a memory reference, make sure that there were
+ no stores after it that might have clobbered the value. We don't
+ have alias info, so we assume any store invalidates it. */
+ else if (GET_CODE (x) == MEM && ! RTX_UNCHANGING_P (x)
+ && INSN_CUID (insn) <= mem_last_set)
+ {
+ if (replace)
+ *loc = gen_rtx (CLOBBER, GET_MODE (x), const0_rtx);
+ return replace;
+ }
for (i = 0; i < len; i++)
if ((fmt[i] == 'e'
- && get_last_value_validate (&XEXP (x, i), tick, replace) == 0)
+ && get_last_value_validate (&XEXP (x, i), insn, tick, replace) == 0)
/* Don't bother with these. They shouldn't occur anyway. */
|| fmt[i] == 'E')
return 0;
@@ -10459,14 +10471,16 @@ get_last_value (x)
}
/* If the value has all its registers valid, return it. */
- if (get_last_value_validate (&value, reg_last_set_label[regno], 0))
+ if (get_last_value_validate (&value, reg_last_set[regno],
+ reg_last_set_label[regno], 0))
return value;
/* Otherwise, make a copy and replace any invalid register with
(clobber (const_int 0)). If that fails for some reason, return 0. */
value = copy_rtx (value);
- if (get_last_value_validate (&value, reg_last_set_label[regno], 1))
+ if (get_last_value_validate (&value, reg_last_set[regno],
+ reg_last_set_label[regno], 1))
return value;
return 0;