]> git.ipfire.org Git - thirdparty/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 11:18:18 +0000 (12:18 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 19 Jan 2005 11:18:18 +0000 (12:18 +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: r93895

gcc/ChangeLog
gcc/Makefile.in
gcc/combine.c
gcc/doc/invoke.texi
gcc/params.def
gcc/params.h
gcc/testsuite/ChangeLog

index 85510bf8657ae57aeaf786346b22a5a3223c74f8..e00a978f3f95a8bafbd1254f68585856532a7819 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 4f8307dcb20e64013a71641a8841cb04669f1d3d..7fcc7ed12a191cef19596abd5dcfd44b5f644960 100644 (file)
@@ -1744,7 +1744,8 @@ dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
 et-forest.o : et-forest.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) et-forest.h alloc-pool.h
 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) \
-   $(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h toplev.h $(TM_P_H) $(TREE_H) $(TARGET_H)
+   $(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h toplev.h $(TM_P_H) \
+   $(TREE_H) $(TARGET_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) $(TM_P_H) $(EXPR_H) $(TIMEVAR_H)
index f2a123a0d300028233924091d1e9594386d60037..0720f3893e4be030dd6ba08cf8dec195d346a13f 100644 (file)
@@ -90,6 +90,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "real.h"
 #include "toplev.h"
 #include "target.h"
+#include "params.h"
 
 #ifndef SHIFT_COUNT_TRUNCATED
 #define SHIFT_COUNT_TRUNCATED 0
@@ -11380,6 +11381,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 reg_last_set_value.  Sets reg_last_set_table_tick
    for each register mentioned.  Similar to mention_regs in cse.c  */
@@ -11486,6 +11528,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 a55f4a6ad9959690efd812cfc9f855171199e967..ed8665d61f4af2ba6234e05c8957a46a8e84ba96 100644 (file)
@@ -4832,6 +4832,12 @@ order to make tracer effective.
 
 Maximum number of basic blocks on path that cse considers.
 
+@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 ggc-min-expand
 
 GCC uses a garbage collector to manage its own memory allocation.  This
index dc826634af733d2b8ae0a0291775f1505423c34a..bde128b54de8f1cedbca9949f502c64bf5051ebf 100644 (file)
@@ -248,6 +248,15 @@ DEFPARAM(PARAM_MAX_CSELIB_MEMORY_LOCATIONS,
         "The maximum memory locations recorded by cselib",
         500)
 
+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)
+
+  /* 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.  */
 #ifdef ENABLE_GC_ALWAYS_COLLECT
 # define GGC_MIN_EXPAND_DEFAULT 0
 # define GGC_MIN_HEAPSIZE_DEFAULT 0
index 0a784454ccd1d638c90c7e7209433df152cfefbf..3cf392fb45ccdf5aa67b492ef963e4be7fb7c797 100644 (file)
@@ -106,4 +106,6 @@ typedef enum compiler_param
   PARAM_VALUE (PARAM_MAX_GCSE_PASSES)
 #define MAX_UNROLLED_INSNS \
   PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS)
+#define MAX_LAST_VALUE_RTL \
+  PARAM_VALUE (PARAM_MAX_LAST_VALUE_RTL)
 #endif /* ! GCC_PARAMS_H */
index 5261abad4945cac198a0b05c120faa092c7087aa..c3fb9f3497a7264d523f2b2a1d44c786e83a981a 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.