mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-17 15:39:40 +08:00
alias.c (canon_rtx): Make it global.
* alias.c (canon_rtx): Make it global. (rtx_equal_for_memref_p): CONST_INT equality is now pointer equality. * cse.c (struct table_elt): Add canon_exp. (insert): Clear it. (invalidate): Canonicalize expressions only once. * rtl.h (canon_rtx): Declare. From-SVN: r32845
This commit is contained in:
parent
c13e821047
commit
db048faf78
@ -1,3 +1,13 @@
|
||||
2000-03-31 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* alias.c (canon_rtx): Make it global.
|
||||
(rtx_equal_for_memref_p): CONST_INT equality is now pointer
|
||||
equality.
|
||||
* cse.c (struct table_elt): Add canon_exp.
|
||||
(insert): Clear it.
|
||||
(invalidate): Canonicalize expressions only once.
|
||||
* rtl.h (canon_rtx): Declare.
|
||||
|
||||
2000-03-30 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* Makefile.in (emit-rtl.o): Depend on HASHTAB_H.
|
||||
|
49
gcc/alias.c
49
gcc/alias.c
@ -79,7 +79,6 @@ typedef struct alias_set_entry
|
||||
splay_tree children;
|
||||
} *alias_set_entry;
|
||||
|
||||
static rtx canon_rtx PARAMS ((rtx));
|
||||
static int rtx_equal_for_memref_p PARAMS ((rtx, rtx));
|
||||
static rtx find_symbolic_term PARAMS ((rtx));
|
||||
static rtx get_addr PARAMS ((rtx));
|
||||
@ -544,7 +543,12 @@ record_base_value (regno, val, invariant)
|
||||
reg_base_value[regno] = find_base_value (val);
|
||||
}
|
||||
|
||||
static rtx
|
||||
/* Returns a canonical version of X, from the point of view alias
|
||||
analysis. (For example, if X is a MEM whose address is a register,
|
||||
and the register has a known value (say a SYMBOL_REF), then a MEM
|
||||
whose address is the SYMBOL_REF is returned.) */
|
||||
|
||||
rtx
|
||||
canon_rtx (x)
|
||||
rtx x;
|
||||
{
|
||||
@ -627,23 +631,32 @@ rtx_equal_for_memref_p (x, y)
|
||||
if (GET_MODE (x) != GET_MODE (y))
|
||||
return 0;
|
||||
|
||||
/* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively. */
|
||||
/* Some RTL can be compared without a recursive examination. */
|
||||
switch (code)
|
||||
{
|
||||
case REG:
|
||||
return REGNO (x) == REGNO (y);
|
||||
|
||||
if (code == REG)
|
||||
return REGNO (x) == REGNO (y);
|
||||
if (code == LABEL_REF)
|
||||
return XEXP (x, 0) == XEXP (y, 0);
|
||||
if (code == SYMBOL_REF)
|
||||
return XSTR (x, 0) == XSTR (y, 0);
|
||||
if (code == CONST_INT)
|
||||
return INTVAL (x) == INTVAL (y);
|
||||
/* There's no need to compare the contents of CONST_DOUBLEs because
|
||||
they're unique. */
|
||||
if (code == CONST_DOUBLE)
|
||||
return 0;
|
||||
if (code == ADDRESSOF)
|
||||
return (REGNO (XEXP (x, 0)) == REGNO (XEXP (y, 0))
|
||||
&& XINT (x, 1) == XINT (y, 1));
|
||||
case LABEL_REF:
|
||||
return XEXP (x, 0) == XEXP (y, 0);
|
||||
|
||||
case SYMBOL_REF:
|
||||
return XSTR (x, 0) == XSTR (y, 0);
|
||||
|
||||
case CONST_INT:
|
||||
case CONST_DOUBLE:
|
||||
/* There's no need to compare the contents of CONST_DOUBLEs or
|
||||
CONST_INTs because pointer equality is a good enough
|
||||
comparison for these nodes. */
|
||||
return 0;
|
||||
|
||||
case ADDRESSOF:
|
||||
return (REGNO (XEXP (x, 0)) == REGNO (XEXP (y, 0))
|
||||
&& XINT (x, 1) == XINT (y, 1));
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* For commutative operations, the RTX match if the operand match in any
|
||||
order. Also handle the simple binary and unary cases without a loop. */
|
||||
|
31
gcc/cse.c
31
gcc/cse.c
@ -408,6 +408,9 @@ static int hash_arg_in_memory;
|
||||
each recording one expression's information.
|
||||
That expression is in the `exp' field.
|
||||
|
||||
The canon_exp field contains a canonical (from the point of view of
|
||||
alias analysis) version of the `exp' field.
|
||||
|
||||
Those elements with the same hash code are chained in both directions
|
||||
through the `next_same_hash' and `prev_same_hash' fields.
|
||||
|
||||
@ -447,6 +450,7 @@ static int hash_arg_in_memory;
|
||||
struct table_elt
|
||||
{
|
||||
rtx exp;
|
||||
rtx canon_exp;
|
||||
struct table_elt *next_same_hash;
|
||||
struct table_elt *prev_same_hash;
|
||||
struct table_elt *next_same_value;
|
||||
@ -1498,6 +1502,7 @@ insert (x, classp, hash, mode)
|
||||
}
|
||||
|
||||
elt->exp = x;
|
||||
elt->canon_exp = NULL_RTX;
|
||||
elt->cost = COST (x);
|
||||
elt->next_same_value = 0;
|
||||
elt->prev_same_value = 0;
|
||||
@ -1823,6 +1828,10 @@ invalidate (x, full_mode)
|
||||
return;
|
||||
|
||||
case MEM:
|
||||
/* Calculate the canonical version of X here so that
|
||||
true_dependence doesn't generate new RTL for X on each call. */
|
||||
x = canon_rtx (x);
|
||||
|
||||
/* Remove all hash table elements that refer to overlapping pieces of
|
||||
memory. */
|
||||
if (full_mode == VOIDmode)
|
||||
@ -1835,11 +1844,23 @@ invalidate (x, full_mode)
|
||||
for (p = table[i]; p; p = next)
|
||||
{
|
||||
next = p->next_same_hash;
|
||||
if (p->in_memory
|
||||
&& (GET_CODE (p->exp) != MEM
|
||||
|| true_dependence (x, full_mode, p->exp,
|
||||
cse_rtx_varies_p)))
|
||||
remove_from_table (p, i);
|
||||
if (p->in_memory)
|
||||
{
|
||||
if (GET_CODE (p->exp) != MEM)
|
||||
remove_from_table (p, i);
|
||||
else
|
||||
{
|
||||
/* Just canonicalize the expression once;
|
||||
otherwise each time we call invalidate
|
||||
true_dependence will canonicalize the
|
||||
expression again. */
|
||||
if (!p->canon_exp)
|
||||
p->canon_exp = canon_rtx (p->exp);
|
||||
if (true_dependence (x, full_mode, p->canon_exp,
|
||||
cse_rtx_varies_p))
|
||||
remove_from_table (p, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user