diff options
author | Jakub Jelinek <jakub@redhat.com> | 2005-01-19 10:31:16 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2005-01-19 10:31:16 +0100 |
commit | 49c3b9a84696a13e3ef71708ef80552606dd08c4 (patch) | |
tree | ef90a2aa86b89aceaa4c818ff027effc25d5f55e /gcc/combine.c | |
parent | e89be13bdf98cff1cbbdd9490e4b4d5e20e68baf (diff) | |
download | gcc-49c3b9a84696a13e3ef71708ef80552606dd08c4.zip gcc-49c3b9a84696a13e3ef71708ef80552606dd08c4.tar.gz gcc-49c3b9a84696a13e3ef71708ef80552606dd08c4.tar.bz2 |
re PR rtl-optimization/15139 (cc1 uses excessive amounts of memory compiling small routine)
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
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 49 |
1 files changed, 49 insertions, 0 deletions
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); } |