reload1.c (reload_cse_noop_set_p): Return false if mode of SET_DEST is not the same as that returned by...
* reload1.c (reload_cse_noop_set_p): Return false if mode of SET_DEST is not the same as that returned by... * cselib.h (cselib_reg_set_mode): ... new function. * cselib.c (cselib_reg_set_mode): Define it. (REG_VALUES): Document semantics of first element as set mode. (cselib_subst_to_values): Skip first element if ELT is NULL. (cselib_lookup): Likewise. Insert past the first element. (cselib_invalidate_regno): NULLify first element. (cselib_record_set): Set first element. From-SVN: r65713
This commit is contained in:
parent
e34d367d2d
commit
60fa6660d8
4 changed files with 88 additions and 16 deletions
|
@ -1,3 +1,15 @@
|
|||
2003-04-16 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* reload1.c (reload_cse_noop_set_p): Return false if mode of
|
||||
SET_DEST is not the same as that returned by...
|
||||
* cselib.h (cselib_reg_set_mode): ... new function.
|
||||
* cselib.c (cselib_reg_set_mode): Define it.
|
||||
(REG_VALUES): Document semantics of first element as set mode.
|
||||
(cselib_subst_to_values): Skip first element if ELT is NULL.
|
||||
(cselib_lookup): Likewise. Insert past the first element.
|
||||
(cselib_invalidate_regno): NULLify first element.
|
||||
(cselib_record_set): Set first element.
|
||||
|
||||
2003-04-16 Olivier Hainque <hainque@act-europe.fr>
|
||||
|
||||
* tree.c (skip_simple_arithmetics_at, saved_expr_p): New functions.
|
||||
|
|
86
gcc/cselib.c
86
gcc/cselib.c
|
@ -1,6 +1,6 @@
|
|||
/* Common subexpression elimination library for GNU compiler.
|
||||
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
@ -99,9 +99,13 @@ static int n_useless_values;
|
|||
/* Number of useless values before we remove them from the hash table. */
|
||||
#define MAX_USELESS_VALUES 32
|
||||
|
||||
/* This table maps from register number to values. It does not contain
|
||||
pointers to cselib_val structures, but rather elt_lists. The purpose is
|
||||
to be able to refer to the same register in different modes. */
|
||||
/* This table maps from register number to values. It does not
|
||||
contain pointers to cselib_val structures, but rather elt_lists.
|
||||
The purpose is to be able to refer to the same register in
|
||||
different modes. The first element of the list defines the mode in
|
||||
which the register was set; if the mode is unknown or the value is
|
||||
no longer valid in that mode, ELT will be NULL for the first
|
||||
element. */
|
||||
static GTY(()) varray_type reg_values;
|
||||
static GTY((deletable (""))) varray_type reg_values_old;
|
||||
#define REG_VALUES(I) VARRAY_ELT_LIST (reg_values, (I))
|
||||
|
@ -402,6 +406,25 @@ remove_useless_values ()
|
|||
abort ();
|
||||
}
|
||||
|
||||
/* Return the mode in which a register was last set. If X is not a
|
||||
register, return its mode. If the mode in which the register was
|
||||
set is not known, or the value was already clobbered, return
|
||||
VOIDmode. */
|
||||
|
||||
enum machine_mode
|
||||
cselib_reg_set_mode (x)
|
||||
rtx x;
|
||||
{
|
||||
if (GET_CODE (x) != REG)
|
||||
return GET_MODE (x);
|
||||
|
||||
if (REG_VALUES (REGNO (x)) == NULL
|
||||
|| REG_VALUES (REGNO (x))->elt == NULL)
|
||||
return VOIDmode;
|
||||
|
||||
return GET_MODE (REG_VALUES (REGNO (x))->elt->u.val_rtx);
|
||||
}
|
||||
|
||||
/* Return nonzero if we can prove that X and Y contain the same value, taking
|
||||
our gathered information into account. */
|
||||
|
||||
|
@ -812,7 +835,10 @@ cselib_subst_to_values (x)
|
|||
switch (code)
|
||||
{
|
||||
case REG:
|
||||
for (l = REG_VALUES (REGNO (x)); l; l = l->next)
|
||||
l = REG_VALUES (REGNO (x));
|
||||
if (l && l->elt == NULL)
|
||||
l = l->next;
|
||||
for (; l; l = l->next)
|
||||
if (GET_MODE (l->elt->u.val_rtx) == GET_MODE (x))
|
||||
return l->elt->u.val_rtx;
|
||||
|
||||
|
@ -909,7 +935,10 @@ cselib_lookup (x, mode, create)
|
|||
struct elt_list *l;
|
||||
unsigned int i = REGNO (x);
|
||||
|
||||
for (l = REG_VALUES (i); l; l = l->next)
|
||||
l = REG_VALUES (i);
|
||||
if (l && l->elt == NULL)
|
||||
l = l->next;
|
||||
for (; l; l = l->next)
|
||||
if (mode == GET_MODE (l->elt->u.val_rtx))
|
||||
return l->elt;
|
||||
|
||||
|
@ -927,8 +956,14 @@ cselib_lookup (x, mode, create)
|
|||
e = new_cselib_val (++next_unknown_value, GET_MODE (x));
|
||||
e->locs = new_elt_loc_list (e->locs, x);
|
||||
if (REG_VALUES (i) == 0)
|
||||
VARRAY_PUSH_UINT (used_regs, i);
|
||||
REG_VALUES (i) = new_elt_list (REG_VALUES (i), e);
|
||||
{
|
||||
/* Maintain the invariant that the first entry of
|
||||
REG_VALUES, if present, must be the value used to set the
|
||||
register, or NULL. */
|
||||
VARRAY_PUSH_UINT (used_regs, i);
|
||||
REG_VALUES (i) = new_elt_list (REG_VALUES (i), NULL);
|
||||
}
|
||||
REG_VALUES (i)->next = new_elt_list (REG_VALUES (i)->next, e);
|
||||
slot = htab_find_slot_with_hash (hash_table, x, e->value, INSERT);
|
||||
*slot = e;
|
||||
return e;
|
||||
|
@ -1011,17 +1046,28 @@ cselib_invalidate_regno (regno, mode)
|
|||
struct elt_loc_list **p;
|
||||
unsigned int this_last = i;
|
||||
|
||||
if (i < FIRST_PSEUDO_REGISTER)
|
||||
if (i < FIRST_PSEUDO_REGISTER && v != NULL)
|
||||
this_last += HARD_REGNO_NREGS (i, GET_MODE (v->u.val_rtx)) - 1;
|
||||
|
||||
if (this_last < regno)
|
||||
if (this_last < regno || v == NULL)
|
||||
{
|
||||
l = &(*l)->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We have an overlap. */
|
||||
unchain_one_elt_list (l);
|
||||
if (*l == REG_VALUES (i))
|
||||
{
|
||||
/* Maintain the invariant that the first entry of
|
||||
REG_VALUES, if present, must be the value used to set
|
||||
the register, or NULL. This is also nice because
|
||||
then we won't push the same regno onto user_regs
|
||||
multiple times. */
|
||||
(*l)->elt = NULL;
|
||||
l = &(*l)->next;
|
||||
}
|
||||
else
|
||||
unchain_one_elt_list (l);
|
||||
|
||||
/* Now, we clear the mapping from value to reg. It must exist, so
|
||||
this code will crash intentionally if it doesn't. */
|
||||
|
@ -1213,9 +1259,6 @@ cselib_record_set (dest, src_elt, dest_addr_elt)
|
|||
|
||||
if (dreg >= 0)
|
||||
{
|
||||
if (REG_VALUES (dreg) == 0)
|
||||
VARRAY_PUSH_UINT (used_regs, dreg);
|
||||
|
||||
if (dreg < FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
unsigned int n = HARD_REGNO_NREGS (dreg, GET_MODE (dest));
|
||||
|
@ -1224,7 +1267,20 @@ cselib_record_set (dest, src_elt, dest_addr_elt)
|
|||
max_value_regs = n;
|
||||
}
|
||||
|
||||
REG_VALUES (dreg) = new_elt_list (REG_VALUES (dreg), src_elt);
|
||||
if (REG_VALUES (dreg) == 0)
|
||||
{
|
||||
VARRAY_PUSH_UINT (used_regs, dreg);
|
||||
REG_VALUES (dreg) = new_elt_list (REG_VALUES (dreg), src_elt);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (REG_VALUES (dreg)->elt == 0)
|
||||
REG_VALUES (dreg)->elt = src_elt;
|
||||
else
|
||||
/* The register should have been invalidated. */
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (src_elt->locs == 0)
|
||||
n_useless_values--;
|
||||
src_elt->locs = new_elt_loc_list (src_elt->locs, dest);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Common subexpression elimination for GNU compiler.
|
||||
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999 Free Software Foundation, Inc.
|
||||
1999, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
@ -67,6 +67,7 @@ extern void cselib_update_varray_sizes PARAMS ((void));
|
|||
extern void cselib_init PARAMS ((void));
|
||||
extern void cselib_finish PARAMS ((void));
|
||||
extern void cselib_process_insn PARAMS ((rtx));
|
||||
extern enum machine_mode cselib_reg_set_mode PARAMS ((rtx));
|
||||
extern int rtx_equal_for_cselib_p PARAMS ((rtx, rtx));
|
||||
extern int references_value_p PARAMS ((rtx, int));
|
||||
extern rtx cselib_subst_to_values PARAMS ((rtx));
|
||||
|
|
|
@ -8025,6 +8025,9 @@ static int
|
|||
reload_cse_noop_set_p (set)
|
||||
rtx set;
|
||||
{
|
||||
if (cselib_reg_set_mode (SET_DEST (set)) != GET_MODE (SET_DEST (set)))
|
||||
return 0;
|
||||
|
||||
return rtx_equal_for_cselib_p (SET_DEST (set), SET_SRC (set));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue