From: steven Date: Tue, 3 Jan 2006 06:20:21 +0000 (+0000) Subject: * fold-const.c (operand_equal_p): Accept a NULL operand 0 for X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=2f16183e45bde2a4c53ef9288a4752b66a1db674 * fold-const.c (operand_equal_p): Accept a NULL operand 0 for COMPONENT_REFs. * emit-rtl.c (mem_attrs_htab_eq): Use iterative_hash_expr for hashing trees instead of a pointer hash. (mem_attrs_htab_eq): Do a deep compare instead of a pointer compare for MEM_EXPR. PR rtl-optimization/25130 * cse.c (exp_equiv_p): Compare MEM_ATTRS instead of MEM_ALIAS_SET when comparing MEMs for GCSE git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@109264 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c451a7eac1c..da0843d3467 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2006-01-03 Steven Bosscher + + * fold-const.c (operand_equal_p): Accept a NULL operand 0 for + COMPONENT_REFs. + * emit-rtl.c (mem_attrs_htab_eq): Use iterative_hash_expr for + hashing trees instead of a pointer hash. + (mem_attrs_htab_eq): Do a deep compare instead of a pointer + compare for MEM_EXPR. + + PR rtl-optimization/25130 + * cse.c (exp_equiv_p): Compare MEM_ATTRS instead of MEM_ALIAS_SET + when comparing MEMs for GCSE + 2006-01-03 Ben Elliston * targhooks.h (default_decimal_float_supported_p): Declare. diff --git a/gcc/cse.c b/gcc/cse.c index 284f3fd5bea..a352c0efadf 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -2538,16 +2538,26 @@ exp_equiv_p (rtx x, rtx y, int validate, bool for_gcse) case MEM: if (for_gcse) { - /* Can't merge two expressions in different alias sets, since we - can decide that the expression is transparent in a block when - it isn't, due to it being set with the different alias set. */ - if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y)) - return 0; - /* A volatile mem should not be considered equivalent to any other. */ if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y)) return 0; + + /* Can't merge two expressions in different alias sets, since we + can decide that the expression is transparent in a block when + it isn't, due to it being set with the different alias set. + + Also, can't merge two expressions with different MEM_ATTRS. + They could e.g. be two different entities allocated into the + same space on the stack (see e.g. PR25130). In that case, the + MEM addresses can be the same, even though the two MEMs are + absolutely not equivalent. + + But because really all MEM attributes should be the same for + equivalent MEMs, we just use the invariant that MEMs that have + the same attributes share the same mem_attrs data structure. */ + if (MEM_ATTRS (x) != MEM_ATTRS (y)) + return 0; } break; diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 828651041a0..aaab19ed4d3 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -254,7 +254,7 @@ mem_attrs_htab_hash (const void *x) return (p->alias ^ (p->align * 1000) ^ ((p->offset ? INTVAL (p->offset) : 0) * 50000) ^ ((p->size ? INTVAL (p->size) : 0) * 2500000) - ^ (size_t) p->expr); + ^ (size_t) iterative_hash_expr (p->expr, 0)); } /* Returns nonzero if the value represented by X (which is really a @@ -267,8 +267,11 @@ mem_attrs_htab_eq (const void *x, const void *y) mem_attrs *p = (mem_attrs *) x; mem_attrs *q = (mem_attrs *) y; - return (p->alias == q->alias && p->expr == q->expr && p->offset == q->offset - && p->size == q->size && p->align == q->align); + return (p->alias == q->alias && p->offset == q->offset + && p->size == q->size && p->align == q->align + && (p->expr == q->expr + || (p->expr != NULL_TREE && q->expr != NULL_TREE + && operand_equal_p (p->expr, q->expr, 0)))); } /* Allocate a new mem_attrs structure and insert it into the hash table if diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 2366c754dda..7cab3c464be 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -2635,8 +2635,11 @@ operand_equal_p (tree arg0, tree arg1, unsigned int flags) && OP_SAME_WITH_NULL (3)); case COMPONENT_REF: - /* Handle operand 2 the same as for ARRAY_REF. */ - return OP_SAME (0) && OP_SAME (1) && OP_SAME_WITH_NULL (2); + /* Handle operand 2 the same as for ARRAY_REF. Operand 0 + may be NULL when we're called to compare MEM_EXPRs. */ + return OP_SAME_WITH_NULL (0) + && OP_SAME (1) + && OP_SAME_WITH_NULL (2); case BIT_FIELD_REF: return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);