This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tuples] the intermittent bootstrap problem.
- From: "Rafael Espindola" <espindola at google dot com>
- To: "Bill Maddox" <maddox at google dot com>, "Diego Novillo" <dnovillo at google dot com>, GCC <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 24 Apr 2008 17:16:03 +0100
- Subject: [tuples] the intermittent bootstrap problem.
Doing a bit of archeology I found the the assert that is sometimes
breaking the bootstrap was first introduced by Jeff Law
(http://gcc.gnu.org/ml/gcc-cvs/2003-06/msg00564.html).
The way we crash is:
*) lookup_avail_expr is called on a stmt. We compute the stmt hash
(H1) and put in on slot S of the avail_exprs hash table.
*) we modify stmt (i.e., the stmt itself, not the pointer)
*) lookup_avail_expr is called on a stmt again. We compute the stmt
hash (H2). We are unlucky and H2 is mapped to the same slot S.
htab_find_slot_with_hash calls avail_expr_eq to check if the element
we are looking for is the same as the one on the table.
*) on avail_expr_eq, smt1 == stmt2, but the hashes are different since
one was computed before the element was modified and one after. This
causes the assert to fail.
I can't find out why this doesn't happen in mainline. Do we avoid
modifying things that are in the table? Do we remove them?
One hack is to assume that the hash will always change and so we don't
need to remove the element from the hash. In this case, we just need
to return false if the hashes don't match in avail_expr_eq. The
attached patch does that. It bootstraps cleanly with both C and
Fortran enabled.
Cheers,
--
Rafael Avila de Espindola
Google Ireland Ltd.
Gordon House
Barrow Street
Dublin 4
Ireland
Registered in Dublin, Ireland
Registration Number: 368047
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index f558676..33477f7 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -2470,6 +2470,10 @@ avail_expr_eq (const void *p1, const void *p2)
if (stamp1 == stamp2)
return true;
+ if (((const struct expr_hash_elt *)p1)->hash
+ != ((const struct expr_hash_elt *)p2)->hash)
+ return false;
+
/* In case of a collision, both RHS have to be identical and have the
same VUSE operands. */
if (hashable_expr_equal_p (expr1, expr2)
@@ -2477,9 +2481,6 @@ avail_expr_eq (const void *p1, const void *p2)
{
/* Note that STMT1 and/or STMT2 may be NULL. */
bool ret = compare_ssa_operands_equal (stmt1, stmt2, SSA_OP_VUSE);
- gcc_assert (!ret ||
- (((const struct expr_hash_elt *)p1)->hash
- == ((const struct expr_hash_elt *)p2)->hash));
return ret;
}