aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/cse.c22
-rw-r--r--gcc/emit-rtl.c9
-rw-r--r--gcc/fold-const.c7
4 files changed, 40 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c451a7e..da0843d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2006-01-03 Steven Bosscher <stevenb.gcc@gmail.com>
+
+ * 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 <bje@au.ibm.com>
* targhooks.h (default_decimal_float_supported_p): Declare.
diff --git a/gcc/cse.c b/gcc/cse.c
index 284f3fd..a352c0e 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 8286510..aaab19e 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 2366c75..7cab3c4 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);