From 9c8b7028ac956395a283ec6366ac87e468891d79 Mon Sep 17 00:00:00 2001 From: jakub Date: Wed, 19 Jan 2005 09:31:16 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@93892 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 11 +++++++++ gcc/Makefile.in | 2 +- gcc/combine.c | 49 +++++++++++++++++++++++++++++++++++++++ gcc/doc/invoke.texi | 6 +++++ gcc/params.def | 5 ++++ gcc/params.h | 2 ++ gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gcc.dg/20050111-2.c | 21 +++++++++++++++++ 8 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/20050111-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ccb0faa..d015dac 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,16 @@ 2005-01-19 Jakub Jelinek + 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. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index be193d2..fb857cf 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -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) \ diff --git a/gcc/combine.c b/gcc/combine.c index 594c468..984c45e 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -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); } +/* 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; +} + /* 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); } diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index d13feda..7013bb2 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 diff --git a/gcc/params.def b/gcc/params.def index 7ac263c..3ef5893 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -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. */ diff --git a/gcc/params.h b/gcc/params.h index d1e5832..1a668e0 100644 --- a/gcc/params.h +++ b/gcc/params.h @@ -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 */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 922b428..e6749d6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2005-01-19 Jakub Jelinek + 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 index 0000000..17e59ce --- /dev/null +++ b/gcc/testsuite/gcc.dg/20050111-2.c @@ -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]; +} -- 2.7.4