OSDN Git Service

* fold-const.c (operand_equal_p): Accept a NULL operand 0 for
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Jan 2006 06:20:21 +0000 (06:20 +0000)
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Jan 2006 06:20:21 +0000 (06:20 +0000)
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

gcc/ChangeLog
gcc/cse.c
gcc/emit-rtl.c
gcc/fold-const.c

index c451a7e..da0843d 100644 (file)
@@ -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.
index 284f3fd..a352c0e 100644 (file)
--- 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;
 
index 8286510..aaab19e 100644 (file)
@@ -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
index 2366c75..7cab3c4 100644 (file)
@@ -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);