diff options
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/alias.c | 51 | ||||
-rw-r--r-- | gcc/cse.c | 31 | ||||
-rw-r--r-- | gcc/rtl.h | 1 |
4 files changed, 69 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0088fd1..18da14b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/alias.c b/gcc/alias.c index d413ec2..db89ecc 100644 --- a/gcc/alias.c +++ b/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. */ - - 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)); + /* Some RTL can be compared without a recursive examination. */ + switch (code) + { + case REG: + return REGNO (x) == REGNO (y); + + 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. */ @@ -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; @@ -1761,6 +1761,7 @@ extern void fancy_abort PARAMS ((const char *, int, const char *)) #endif /* In alias.c */ +extern rtx canon_rtx PARAMS ((rtx)); extern int true_dependence PARAMS ((rtx, enum machine_mode, rtx, int (*)(rtx))); extern int read_dependence PARAMS ((rtx, rtx)); |