[RFC] nonzero_bits (was Re: Another Java sparc-sun-solaris2.8 bootstrap failure)

Jakub Jelinek jakub@redhat.com
Wed Mar 27 14:33:00 GMT 2002


On Wed, Mar 27, 2002 at 08:54:32PM +0100, Jakub Jelinek wrote:
> On Tue, Mar 26, 2002 at 05:08:29PM +0100, Gerald Pfeifer wrote:
> > This sparc-sun-solaris2.8 box has 512MB of physical memory plus 1024MB of
> > swap, so this seems to be an internal error.
> > 
> > I got this for a "plain" make bootstrap with just --enable-libgcj on the
> > gcc-3.1 branch. This is a regression from GCC 3.0.
> > 
> > 
> > /bin/ksh ./libtool --tag=CXX --mode=compile /files/pfeifer/OBJ-0326-11:41/gcc/xgcc -shared-libgcc -B/files/pfeifer/OBJ-0326-11:41/gcc/ -nostdinc++ -L/files/pfeifer/OBJ-0326-11:41/sparc-sun-solaris2.8/sparcv9/libstdc++-v3/src -L/files/pfeifer/OBJ-0326-11:41/sparc-sun-solaris2.8/sparcv9/libstdc++-v3/src/.libs -B/sw/test/gcc/SunOS/sparc-sun-solaris2.8/bin/ -B/sw/test/gcc/SunOS/sparc-sun-solaris2.8/lib/ -isystem /sw/test/gcc/SunOS/sparc-sun-solaris2.8/include  -m64 -DHAVE_CONFIG_H -I. -I/sw/test/gcc/cvs-3.1/libjava -I./include -I./gcj -I/sw/test/gcc/cvs-3.1/libjava -Iinclude -I/sw/test/gcc/cvs-3.1/libjava/include -I/sw/test/gcc/cvs-3.1/libjava/../boehm-gc/include  -DGC_SOLARIS_THREADS=1 -DGC_SOLARIS_PTHREADS=1 -DSILENT=1 -DNO_SIGNALS=1 -DNO_EXECUTE_PERMISSION=1 -DALL_INTERIOR_POINTERS=1 -DJAVA_FINALIZATION=1 -DGC_GCJ_SUPPORT=1 -DATOMIC_UNCOLLECTABLE=1   -I/sw/test/gcc/cvs-3.1/libjava/libltdl -I/sw/test/gcc/cvs-3.1/libjava/libltdl -I/sw/test/gcc/cvs-3.1/libjava/.././libjava/../gc!
> > c -I/sw/test/gcc/cvs-3.1/libjava/../zlib -I/sw/test/gcc/cvs-3.1/libjava/../libffi/include -I../../libffi/include   -fno-rtti -fnon-call-exceptions -fdollars-in-identifiers -I/usr/openwin/include -W -Wall -D_GNU_SOURCE -DPREFIX="\"/sw/test/gcc/SunOS\"" -g -O2  -m64 -MD -MT gnu/gcj/io/shs.lo -MF gnu/gcj/io/shs.pp -c -o gnu/gcj/io/shs.lo /sw/test/gcc/cvs-3.1/libjava/gnu/gcj/io/shs.cc
> > /files/pfeifer/OBJ-0326-11:41/gcc/xgcc -shared-libgcc -B/files/pfeifer/OBJ-0326-11:41/gcc/ -nostdinc++ -L/files/pfeifer/OBJ-0326-11:41/sparc-sun-solaris2.8/sparcv9/libstdc++-v3/src -L/files/pfeifer/OBJ-0326-11:41/sparc-sun-solaris2.8/sparcv9/libstdc++-v3/src/.libs -B/sw/test/gcc/SunOS/sparc-sun-solaris2.8/bin/ -B/sw/test/gcc/SunOS/sparc-sun-solaris2.8/lib/ -isystem /sw/test/gcc/SunOS/sparc-sun-solaris2.8/include -m64 -DHAVE_CONFIG_H -I. -I/sw/test/gcc/cvs-3.1/libjava -I./include -I./gcj -I/sw/test/gcc/cvs-3.1/libjava -Iinclude -I/sw/test/gcc/cvs-3.1/libjava/include -I/sw/test/gcc/cvs-3.1/libjava/../boehm-gc/include -DGC_SOLARIS_THREADS=1 -DGC_SOLARIS_PTHREADS=1 -DSILENT=1 -DNO_SIGNALS=1 -DNO_EXECUTE_PERMISSION=1 -DALL_INTERIOR_POINTERS=1 -DJAVA_FINALIZATION=1 -DGC_GCJ_SUPPORT=1 -DATOMIC_UNCOLLECTABLE=1 -I/sw/test/gcc/cvs-3.1/libjava/libltdl -I/sw/test/gcc/cvs-3.1/libjava/libltdl -I/sw/test/gcc/cvs-3.1/libjava/.././libjava/../gcc -I/sw/test/gcc/cvs-3.1/libjava/../zlib -I/sw/t!
> > est/gcc/cvs-3.1/libjava/../libffi/include -I../../libffi/include -fno-rtti -fnon-call-exceptions -fdollars-in-identifiers -I/usr/openwin/include -W -Wall -D_GNU_SOURCE "-DPREFIX=\"/sw/test/gcc/SunOS\"" -g -O2 -m64 -MD -MT gnu/gcj/io/shs.lo -MF gnu/gcj/io/shs.pp -c /sw/test/gcc/cvs-3.1/libjava/gnu/gcj/io/shs.cc  -fPIC -DPIC -o gnu/gcj/io/.libs/shs.o
> > 
> > cc1plus: Cannot allocate 131072 bytes after allocating 200237056 bytes
> 
> My bet is this is because of very deep nonzero_bits recursion.
> In i386->sparc64 cross I counted 12456534 nonzero_bits calls on this
> single routine.

The following patch cuts down the number of nonzero_bits calls from
12456534 down to ~306000, but I wonder if it is a safe things to do.
For shs.ii it creates identical output as before, haven't tried on sparc64
yet. The issue is that set_nonzero_bits_and_sign_copies calls nonzero_bits
with DImode (for each pseudo) while reg_last_set_nonzero_bits are computed
using nonzero_bits (..., SImode) calls.
The first hunk is actually a different thing (it was the first thing I tried
and it only saved ~400000 nonzero_bits calls from the original
~1.25m), but maybe it might be worthy on other sources (it makes no sense
to call nonzero_bits if reg_nonzero_bits is already all ones).

--- gcc/combine.c.jj	Tue Mar 26 17:54:46 2002
+++ gcc/combine.c	Wed Mar 27 22:33:47 2002
@@ -904,8 +904,9 @@ set_nonzero_bits_and_sign_copies (x, set
 			      << GET_MODE_BITSIZE (GET_MODE (x))));
 #endif
 
-	  reg_nonzero_bits[REGNO (x)]
-	    |= nonzero_bits (src, nonzero_bits_mode);
+	  if (reg_nonzero_bits[REGNO (x)] != ~(unsigned HOST_WIDE_INT) 0)
+	    reg_nonzero_bits[REGNO (x)]
+	      |= nonzero_bits (src, nonzero_bits_mode);
 	  num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
 	  if (reg_sign_bit_copies[REGNO (x)] == 0
 	      || reg_sign_bit_copies[REGNO (x)] > num)
@@ -8035,7 +8036,9 @@ nonzero_bits (x, mode)
 	 for this register.  */
 
       if (reg_last_set_value[REGNO (x)] != 0
-	  && reg_last_set_mode[REGNO (x)] == mode
+	  && (reg_last_set_mode[REGNO (x)] == mode
+	      || (GET_MODE_CLASS (reg_last_set_mode[REGNO (x)]) == MODE_INT
+		  && GET_MODE_CLASS (mode) == MODE_INT))
 	  && (reg_last_set_label[REGNO (x)] == label_tick
 	      || (REGNO (x) >= FIRST_PSEUDO_REGISTER
 		  && REG_N_SETS (REGNO (x)) == 1
@@ -11204,9 +11207,12 @@ record_value_for_reg (reg, insn, value)
 
   if (value)
     {
+      enum machine_mode mode = GET_MODE (reg);
       subst_low_cuid = INSN_CUID (insn);
-      reg_last_set_mode[regno] = GET_MODE (reg);
-      reg_last_set_nonzero_bits[regno] = nonzero_bits (value, GET_MODE (reg));
+      reg_last_set_mode[regno] = mode;
+      if (GET_MODE_CLASS (mode) == MODE_INT)
+	mode = nonzero_bits_mode;
+      reg_last_set_nonzero_bits[regno] = nonzero_bits (value, mode);
       reg_last_set_sign_bit_copies[regno]
 	= num_sign_bit_copies (value, GET_MODE (reg));
     }
@@ -11347,6 +11353,9 @@ record_promoted_value (insn, subreg)
       if (reg_last_set[regno] == insn)
 	{
 	  if (SUBREG_PROMOTED_UNSIGNED_P (subreg))
+	    /* XXX Is this correct even for MODE_INT modes
+	       if reg_last_set_nonzero_bits was computed for
+	       nonzero_bits_mode larger than reg_last_set_mode?  */
 	    reg_last_set_nonzero_bits[regno] &= GET_MODE_MASK (mode);
 	}
 


	Jakub



More information about the Gcc mailing list