This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] Sanity checking + hashing fix
- From: law at redhat dot com
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 12 Jun 2003 15:28:35 -0600
- Subject: [tree-ssa] Sanity checking + hashing fix
- Reply-to: law at redhat dot com
This patch adds some sanity checking to detect cases where objects
compare equal, but which have different hash values. Catching them
with an explicit ENABLE_CHECKING abort takes a couple steps out of
the debugging process for a certain class of failures.
Not surprisingly, the new checking found a problem :-) It also happens
to look like the same problem Diego has been struggling with today.
operand_equal_p doesn't look at the types of NOP_EXPRs and friends --
it looks at the signedness of the type and the object being converted.
iterative_hash_expr hashed the type using the type's address.
The net result was that we had equivalent nodes according to
operand_equal_p, but which had different hash values.
* tree-ssa.c (avail_expr_eq): Add some checking code to
detect when equal expressions have different hash values.
* tree.c (iterative_hash_expr): Don't hash types associated
with conversions. Instead hash on the signedness of the
toplevel object and the operand of the conversion.
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.91
diff -c -3 -p -r1.1.4.91 tree-ssa.c
*** tree-ssa.c 11 Jun 2003 15:01:49 -0000 1.1.4.91
--- tree-ssa.c 12 Jun 2003 19:47:24 -0000
*************** avail_expr_eq (const void *p1, const voi
*** 2625,2631 ****
varray_type ops2 = vuse_ops (s2);
if (ops1 == NULL && ops2 == NULL)
! return true;
if (VARRAY_ACTIVE_SIZE (ops1) == VARRAY_ACTIVE_SIZE (ops2))
{
--- 2625,2637 ----
varray_type ops2 = vuse_ops (s2);
if (ops1 == NULL && ops2 == NULL)
! {
! #ifdef ENABLE_CHECKING
! if (avail_expr_hash (s1) != avail_expr_hash (s2))
! abort ();
! #endif
! return true;
! }
if (VARRAY_ACTIVE_SIZE (ops1) == VARRAY_ACTIVE_SIZE (ops2))
{
*************** avail_expr_eq (const void *p1, const voi
*** 2634,2639 ****
--- 2640,2649 ----
if (VARRAY_GENERIC_PTR (ops1, i) != VARRAY_GENERIC_PTR (ops2, i))
return false;
+ #ifdef ENABLE_CHECKING
+ if (avail_expr_hash (s1) != avail_expr_hash (s2))
+ abort ();
+ #endif
return true;
}
}
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.263.2.36
diff -c -3 -p -r1.263.2.36 tree.c
*** tree.c 3 Jun 2003 16:50:52 -0000 1.263.2.36
--- tree.c 12 Jun 2003 19:47:36 -0000
*************** iterative_hash_expr (tree t, hashval_t v
*** 3575,3583 ****
{
val = iterative_hash_object (code, val);
! if (code == NOP_EXPR || code == CONVERT_EXPR
! || code == NON_LVALUE_EXPR)
! val = iterative_hash_object (TREE_TYPE (t), val);
if (code == PLUS_EXPR || code == MULT_EXPR || code == MIN_EXPR
|| code == MAX_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR
--- 3575,3589 ----
{
val = iterative_hash_object (code, val);
! /* Don't hash the type, that can lead to having nodes which
! compare equal according to operand_equal_p, but which
! have different hash codes. */
! if (code == NOP_EXPR || code == CONVERT_EXPR || code ==
NON_LVALUE_EXPR)
! {
! /* Make sure to include signness in the hash computation. */
! val += TREE_UNSIGNED (TREE_TYPE (t));
! val = iterative_hash_expr (TREE_OPERAND (t, 0), val);
! }
if (code == PLUS_EXPR || code == MULT_EXPR || code == MIN_EXPR
|| code == MAX_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR