This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Solaris bootstrap failure
- To: gcc at gcc dot gnu dot org
- Subject: Re: Solaris bootstrap failure
- From: Colin Howell <chowell at redhat dot com>
- Date: Wed, 7 Mar 2001 22:40:08 -0800 (PST)
Folks,
I have been trying to track down this bootstrap failure on a
sparc-sun-solaris2.6 box. My latest checkout was Mar 6, at 13:33 PST.
I have refrained from doing later checkouts for fear that the
discrepancy may vanish. The resulting bootstrap (using
2.9-gnupro-99r1 as the starting compiler) had the same comparison
failure with cp/tree.o that Mark Mitchell first reported in this
thread.
I have been able to replicate the discrepancy when invoking the
compilation command for cp/tree.o by hand using the stage1 and stage2
compilers. (Make sure you don't use -save-temps to get the cc1
command line, or the discrepancy will vanish.) The difference is a
single extra instruction in the compilation by the stage1 compiler of
no_linkage_helper() within cp/tree.c.
The stage1 and stage2 compilers first start producing divergent RTL
for no_linkage_helper() during the post-reload optimizations phase,
specifically within reload_cse_regs().
The problem appears to be in cselib_lookup(), which is supposed to
find a common subexpression within an insn. The stage1 compiler finds
one for insn 37 of no_linkage_helper() while the stage2 compiler does
not. As a result, the insn is changed by the stage1 compiler but not
by the stage2 compiler. This difference eventually results in the
stage1 compiler generating an extra instruction.
The question is why cselib_lookup() is giving different results in the
two cases. I strongly suspect the hash table used by cselib, but I
can't yet pin down an exact fault in it. While comparing its behavior
in the stage1 and stage2 compilers, however, one thing caught my eye.
Check out lines 2663-2666 of simplify-rtx.c, within the function
hash_rtx():
case SYMBOL_REF:
hash
+= ((unsigned) SYMBOL_REF << 7) + (unsigned long) XSTR (x, 0);
return hash ? hash : (unsigned int) SYMBOL_REF;
This function is using a pointer as part of the hash value. Since the
pointer value differs between the stage1 and stage2 compilers
(presumeably because of differences in the memory map), the computed
hash value differs. Hence, the hash table starts to diverge between
the stage1 and stage2 compilers.
However, I don't think that this divergence of the hash table should
be sufficient to cause the differing behavior in cselib_lookup(),
because the table should still function correctly in both cases.
Is it OK for us to use a pointer as part of the hash value computation
in this way? Doing so certainly makes it harder to compare bootstrap
stages. I'd think that it would also make it harder to compare cross
compilers for the same target on different hosts.
--
Colin Douglas Howell E-mail: chowell@redhat.com
Support Engineer Support line: (408) 542-9601
Red Hat, Inc.