[PATCH] Fix PR55489, memory-hog bug in GCSE

Paolo Bonzini bonzini@gnu.org
Tue Nov 27 16:00:00 GMT 2012


Hi,

this bug triggers in the compilation of QEMU with GCC 4.7.2.  It is
latent on trunk because reg_known_value is completely broken.  I'll
send a separate patch, but this one applies there too.

The problem arises when you have -fPIE (or -fPIC) and a huge function
with a lot of references to global variables.  Canonicalization of
position-independent addresses is then done over and over for the
same addresses, resulting in quadratic time and memory complexity for
GCSE's compute_transp; hundreds of megabytes of memory are allocated
in plus_constant,

The fix is to canonicalize the addresses outside the loop, similar to
what is done by the RTL DSE pass.

gcc 4.4.6:
 PRE :   3.83 (24%) usr   0.15 (17%) sys   3.99 (24%) wall  267307 kB (33%) ggc

gcc 4.7.2:
 PRE :   7.95 (41%) usr   0.40 (40%) sys   8.31 (41%) wall  821017 kB (80%) ggc

gcc 4.8.0:
 PRE :   6.94 (26%) usr   0.02 ( 4%) sys   6.98 (26%) wall     731 kB ( 0%) ggc

gcc 4.7.2 + patch:
 PRE :   5.90 (34%) usr   0.02 ( 3%) sys   6.41 (35%) wall    1670 kB ( 1%) ggc

Note that the bug is present on older branches too, but it became much
worse sometime between 4.4 and 4.7.

Bootstrap finished on x86_64-pc-linux-gnu, regtest in progress; ok for
4.7 and trunk if it passes?

Paolo

2012-11-26  Paolo Bonzini  <pbonzini@redhat.com>

	PR rtl-optimization/55489
	* gcse.c (compute_transp): Precompute a canonical version
	of XEXP (x, 0), and pass it to canon_true_dependence.

Index: gcse.c
===================================================================
--- gcse.c	(revisione 193848)
+++ gcse.c	(copia locale)
@@ -1658,7 +1658,11 @@ compute_transp (const_rtx x, int indx, sbitmap *bm
 	{
 	  bitmap_iterator bi;
 	  unsigned bb_index;
+	  rtx x_addr;
 
+	  x_addr = get_addr (XEXP (x, 0));
+	  x_addr = canon_rtx (x_addr);
+
 	  /* First handle all the blocks with calls.  We don't need to
 	     do any list walking for them.  */
 	  EXECUTE_IF_SET_IN_BITMAP (blocks_with_calls, 0, bb_index, bi)
@@ -1683,7 +1687,7 @@
 		    rtx dest_addr = pair->dest_addr;
 
 		    if (canon_true_dependence (dest, GET_MODE (dest),
-					       dest_addr, x, NULL_RTX))
+					       dest_addr, x, x_addr))
 		      RESET_BIT (bmap[bb_index], indx);
 	          }
 	      }



More information about the Gcc-patches mailing list