]> gcc.gnu.org Git - gcc.git/commitdiff
re PR rtl-optimization/15139 (cc1 uses excessive amounts of memory compiling small...
authorJakub Jelinek <jakub@redhat.com>
Wed, 19 Jan 2005 09:31:16 +0000 (10:31 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 19 Jan 2005 09:31:16 +0000 (10:31 +0100)
PR rtl-optimization/15139
* combine.c: Include params.h.
(count_rtxs): New function.
(record_value_for_reg): If replace_rtx would replace at least
2 occurrences of REG in VALUE and TEM is really large, replace REG with
(clobber (const_int 0)) instead of TEM.
* params.def (PARAM_MAX_LAST_VALUE_RTL): New.
* params.h (MAX_LAST_VALUE_RTL): New.
* Makefile.in (combine.o): Depend on $(PARAMS_H).
* doc/invoke.texi (--param max-last-value-rtl=N): Document.

* gcc.dg/20050111-2.c: New test.

From-SVN: r93892

gcc/ChangeLog
gcc/Makefile.in
gcc/combine.c
gcc/doc/invoke.texi
gcc/params.def
gcc/params.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20050111-2.c [new file with mode: 0644]

index ccb0faa7529069ce9c086d0ca6f05db6066e6fe2..d015dac1dd27a18b6153282a25b7080f9178bf34 100644 (file)
@@ -1,5 +1,16 @@
 2005-01-19  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/15139
+       * combine.c: Include params.h.
+       (count_rtxs): New function.
+       (record_value_for_reg): If replace_rtx would replace at least
+       2 occurrences of REG in VALUE and TEM is really large, replace REG with
+       (clobber (const_int 0)) instead of TEM.
+       * params.def (PARAM_MAX_LAST_VALUE_RTL): New.
+       * params.h (MAX_LAST_VALUE_RTL): New.
+       * Makefile.in (combine.o): Depend on $(PARAMS_H).
+       * doc/invoke.texi (--param max-last-value-rtl=N): Document.
+
        PR c/17297
        * c-typeck.c (digest_init): Only call build_vector if all constructor
        elements are *_CST nodes.
index be193d2a774ad633de6bcddb3f200069e302257c..fb857cf2128dbed0986b25c7a68e5bf4eb8f21e0 100644 (file)
@@ -2046,7 +2046,7 @@ et-forest.o : et-forest.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) et-forest.
 combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(FLAGS_H) function.h insn-config.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \
    rtlhooks-def.h $(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h \
-   toplev.h $(TM_P_H) $(TREE_H) $(TARGET_H) output.h
+   toplev.h $(TM_P_H) $(TREE_H) $(TARGET_H) output.h $(PARAMS_H)
 regclass.o : regclass.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(REGS_H) insn-config.h \
    $(RECOG_H) reload.h real.h toplev.h function.h output.h $(GGC_H) \
index 594c468651741337091f27e6f0cd8aad414bd1f1..984c45e10ea6e1dc82c8742003772b0118f73614 100644 (file)
@@ -93,6 +93,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "rtlhooks-def.h"
 /* Include output.h for dump_file.  */
 #include "output.h"
+#include "params.h"
 
 /* Number of attempts to combine instructions in this function.  */
 
@@ -10733,6 +10734,47 @@ reversed_comparison (rtx exp, enum machine_mode mode, rtx op0, rtx op1)
     return gen_binary (reversed_code, mode, op0, op1);
 }
 \f
+/* Utility function for record_value_for_reg.  Count number of
+   rtxs in X.  */
+static int
+count_rtxs (rtx x)
+{
+  enum rtx_code code = GET_CODE (x);
+  const char *fmt;
+  int i, ret = 1;
+
+  if (GET_RTX_CLASS (code) == '2'
+      || GET_RTX_CLASS (code) == 'c')
+    {
+      rtx x0 = XEXP (x, 0);
+      rtx x1 = XEXP (x, 1);
+
+      if (x0 == x1)
+       return 1 + 2 * count_rtxs (x0);
+
+      if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
+          || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
+         && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
+       return 2 + 2 * count_rtxs (x0)
+              + count_rtxs (x == XEXP (x1, 0)
+                            ? XEXP (x1, 1) : XEXP (x1, 0));
+
+      if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
+          || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
+         && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
+       return 2 + 2 * count_rtxs (x1)
+              + count_rtxs (x == XEXP (x0, 0)
+                            ? XEXP (x0, 1) : XEXP (x0, 0));
+    }
+
+  fmt = GET_RTX_FORMAT (code);
+  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+    if (fmt[i] == 'e')
+      ret += count_rtxs (XEXP (x, i));
+
+  return ret;
+}
+\f
 /* Utility function for following routine.  Called when X is part of a value
    being stored into last_set_value.  Sets last_set_table_tick
    for each register mentioned.  Similar to mention_regs in cse.c  */
@@ -10835,6 +10877,13 @@ record_value_for_reg (rtx reg, rtx insn, rtx value)
              && GET_CODE (XEXP (tem, 0)) == CLOBBER
              && GET_CODE (XEXP (tem, 1)) == CLOBBER)
            tem = XEXP (tem, 0);
+         else if (count_occurrences (value, reg, 1) >= 2)
+           {
+             /* If there are two or more occurrences of REG in VALUE,
+                prevent the value from growing too much.  */
+             if (count_rtxs (tem) > MAX_LAST_VALUE_RTL)
+               tem = gen_rtx_CLOBBER (GET_MODE (tem), const0_rtx);
+           }
 
          value = replace_rtx (copy_rtx (value), reg, tem);
        }
index d13feda555e150721129d7b44531e54dfc158334..7013bb2e29e9c1023bf14821f6709415ddeae224 100644 (file)
@@ -5615,6 +5615,12 @@ interblock scheduling.  The default value is 10.
 The maximum number of insns in a region to be considered for
 interblock scheduling.  The default value is 100.
 
+@item max-last-value-rtl
+
+The maximum size measured as number of RTLs that can be recorded in an expression
+in combiner for a pseudo register as last known value of that register.  The default
+is 10000.
+
 @item integer-share-limit
 Small integer constants can use a shared data structure, reducing the
 compiler's memory usage and increasing its speed.  This sets the maximum
index 7ac263cdc2467f987675d2da53dfbaf45589954d..3ef5893fd42fb6980232a63ec6375fa0836d8622 100644 (file)
@@ -408,6 +408,11 @@ DEFPARAM(PARAM_MAX_SCHED_REGION_INSNS,
         "The maximum number of insns in a region to be considered for interblock scheduling",
         100, 0, 0)
 
+DEFPARAM(PARAM_MAX_LAST_VALUE_RTL,
+        "max-last-value-rtl",
+        "The maximum number of RTL nodes that can be recorded as combiner's last value",
+        10000, 0, 0)
+
 /* INTEGER_CST nodes are shared for values [{-1,0} .. N) for
    {signed,unsigned} integral types.  This determines N.
    Experimentation shows 256 to be a good value.  */
index d1e583245ab62b58ee0fa52994658e908e0ec418..1a668e0deff4a89216a3d42c4be9f516262c7d5e 100644 (file)
@@ -135,4 +135,6 @@ typedef enum compiler_param
   PARAM_VALUE (PARAM_MAX_ALIASED_VOPS)
 #define INTEGER_SHARE_LIMIT \
   PARAM_VALUE (PARAM_INTEGER_SHARE_LIMIT)
+#define MAX_LAST_VALUE_RTL \
+  PARAM_VALUE (PARAM_MAX_LAST_VALUE_RTL)
 #endif /* ! GCC_PARAMS_H */
index 922b4287d9004e355d9310fbeee40d7a30a6ed47..e6749d6518cc0d7653d601fd0449dd66c142a6a5 100644 (file)
@@ -1,5 +1,8 @@
 2005-01-19  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/15139
+       * gcc.dg/20050111-2.c: New test.
+
        PR c/17297
        * gcc.c-torture/compile/20050113-1.c: New testcase.
 
diff --git a/gcc/testsuite/gcc.dg/20050111-2.c b/gcc/testsuite/gcc.dg/20050111-2.c
new file mode 100644 (file)
index 0000000..17e59ce
--- /dev/null
@@ -0,0 +1,21 @@
+/* PR rtl-optimization/15139 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -funroll-loops" } */
+
+void
+foo (double **a, double **z)
+{
+  long int i, j;
+  double d = -1.0;
+
+  for (i = 0; i < 6; i++)
+    for (j = 0; j < 5; j++)
+      d = z[i][j] > d ? z[i][j] : d;
+
+  for (i = 0; i < 6; i++)
+    for (j = 0; j < 5; j++)
+      z[i][j] /= d;
+
+  for (i = 0; i < 5; i++)
+    a[i][j] = z[i][j];
+}
This page took 0.086748 seconds and 5 git commands to generate.