diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-02-01 23:39:31 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-02-01 23:39:31 +0100 |
commit | d0268b37f87359ebf5d6f8bd95fe9829b520749a (patch) | |
tree | 6d20c4dc8d9379e506a9c5f4d19e1a1aa2108f84 /gcc | |
parent | e1b81f2ba000a61a3d845f0d3bb038b62d43673f (diff) | |
download | gcc-d0268b37f87359ebf5d6f8bd95fe9829b520749a.zip gcc-d0268b37f87359ebf5d6f8bd95fe9829b520749a.tar.gz gcc-d0268b37f87359ebf5d6f8bd95fe9829b520749a.tar.bz2 |
re PR rtl-optimization/69592 (Compile-time and memory-use hog in combine)
PR rtl-optimization/69592
* rtlanal.c (nonzero_bits_binary_arith_p): New inline function.
(cached_nonzero_bits): Use it instead of ARITHMETIC_P.
(num_sign_bit_copies_binary_arith_p): New inline function.
(cached_num_sign_bit_copies): Use it instead of ARITHMETIC_P.
* gcc.dg/pr69592.c: New test.
From-SVN: r233059
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/rtlanal.c | 72 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr69592.c | 16 |
4 files changed, 93 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 68b9043..2493946 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-02-01 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/69592 + * rtlanal.c (nonzero_bits_binary_arith_p): New inline function. + (cached_nonzero_bits): Use it instead of ARITHMETIC_P. + (num_sign_bit_copies_binary_arith_p): New inline function. + (cached_num_sign_bit_copies): Use it instead of ARITHMETIC_P. + 2016-02-01 Jeff Law <law@redhat.com> PR tree-optimization/69580 diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 71dfd33..642611f 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -4163,6 +4163,36 @@ num_sign_bit_copies (const_rtx x, machine_mode mode) return cached_num_sign_bit_copies (x, mode, NULL_RTX, VOIDmode, 0); } +/* Return true if nonzero_bits1 might recurse into both operands + of X. */ + +static inline bool +nonzero_bits_binary_arith_p (const_rtx x) +{ + if (!ARITHMETIC_P (x)) + return false; + switch (GET_CODE (x)) + { + case AND: + case XOR: + case IOR: + case UMIN: + case UMAX: + case SMIN: + case SMAX: + case PLUS: + case MINUS: + case MULT: + case DIV: + case UDIV: + case MOD: + case UMOD: + return true; + default: + return false; + } +} + /* The function cached_nonzero_bits is a wrapper around nonzero_bits1. It avoids exponential behavior in nonzero_bits1 when X has identical subexpressions on the first or the second level. */ @@ -4179,7 +4209,7 @@ cached_nonzero_bits (const_rtx x, machine_mode mode, const_rtx known_x, nonzero_bits1 on X with the subexpressions as KNOWN_X and the precomputed value for the subexpression as KNOWN_RET. */ - if (ARITHMETIC_P (x)) + if (nonzero_bits_binary_arith_p (x)) { rtx x0 = XEXP (x, 0); rtx x1 = XEXP (x, 1); @@ -4191,13 +4221,13 @@ cached_nonzero_bits (const_rtx x, machine_mode mode, const_rtx known_x, known_mode, known_ret)); /* Check the second level. */ - if (ARITHMETIC_P (x0) + if (nonzero_bits_binary_arith_p (x0) && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1))) return nonzero_bits1 (x, mode, x1, mode, cached_nonzero_bits (x1, mode, known_x, known_mode, known_ret)); - if (ARITHMETIC_P (x1) + if (nonzero_bits_binary_arith_p (x1) && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1))) return nonzero_bits1 (x, mode, x0, mode, cached_nonzero_bits (x0, mode, known_x, @@ -4269,6 +4299,8 @@ nonzero_bits1 (const_rtx x, machine_mode mode, const_rtx known_x, return nonzero; } + /* Please keep nonzero_bits_binary_arith_p above in sync with + the code in the switch below. */ code = GET_CODE (x); switch (code) { @@ -4672,6 +4704,32 @@ nonzero_bits1 (const_rtx x, machine_mode mode, const_rtx known_x, #undef cached_num_sign_bit_copies +/* Return true if num_sign_bit_copies1 might recurse into both operands + of X. */ + +static inline bool +num_sign_bit_copies_binary_arith_p (const_rtx x) +{ + if (!ARITHMETIC_P (x)) + return false; + switch (GET_CODE (x)) + { + case IOR: + case AND: + case XOR: + case SMIN: + case SMAX: + case UMIN: + case UMAX: + case PLUS: + case MINUS: + case MULT: + return true; + default: + return false; + } +} + /* The function cached_num_sign_bit_copies is a wrapper around num_sign_bit_copies1. It avoids exponential behavior in num_sign_bit_copies1 when X has identical subexpressions on the @@ -4689,7 +4747,7 @@ cached_num_sign_bit_copies (const_rtx x, machine_mode mode, const_rtx known_x, num_sign_bit_copies1 on X with the subexpressions as KNOWN_X and the precomputed value for the subexpression as KNOWN_RET. */ - if (ARITHMETIC_P (x)) + if (num_sign_bit_copies_binary_arith_p (x)) { rtx x0 = XEXP (x, 0); rtx x1 = XEXP (x, 1); @@ -4703,7 +4761,7 @@ cached_num_sign_bit_copies (const_rtx x, machine_mode mode, const_rtx known_x, known_ret)); /* Check the second level. */ - if (ARITHMETIC_P (x0) + if (num_sign_bit_copies_binary_arith_p (x0) && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1))) return num_sign_bit_copies1 (x, mode, x1, mode, @@ -4711,7 +4769,7 @@ cached_num_sign_bit_copies (const_rtx x, machine_mode mode, const_rtx known_x, known_mode, known_ret)); - if (ARITHMETIC_P (x1) + if (num_sign_bit_copies_binary_arith_p (x1) && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1))) return num_sign_bit_copies1 (x, mode, x0, mode, @@ -4777,6 +4835,8 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x, return 1; } + /* Please keep num_sign_bit_copies_binary_arith_p above in sync with + the code in the switch below. */ switch (code) { case REG: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 73b0ce8..1f8ddd0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2016-02-01 Jakub Jelinek <jakub@redhat.com> + PR rtl-optimization/69592 + * gcc.dg/pr69592.c: New test. + PR preprocessor/69543 PR c/69558 * gcc.dg/pr69543.c: New test. diff --git a/gcc/testsuite/gcc.dg/pr69592.c b/gcc/testsuite/gcc.dg/pr69592.c new file mode 100644 index 0000000..c791fe9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr69592.c @@ -0,0 +1,16 @@ +/* PR rtl-optimization/69592 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +unsigned int +foo (unsigned int a, unsigned int *b, unsigned int c) +{ + unsigned int d; +#define A(n) d = a + b[n]; if (d < a) c++; a = d; +#define B(n) A(n##0) A(n##1) A(n##2) A(n##3) A(n##4) A(n##5) A(n##6) A(n##7) A(n##8) A(n##9) +#define C(n) B(n##0) B(n##1) B(n##2) B(n##3) B(n##4) B(n##5) B(n##6) B(n##7) B(n##8) B(n##9) +#define D(n) C(n##0) C(n##1) C(n##2) C(n##3) C(n##4) C(n##5) C(n##6) C(n##7) C(n##8) C(n##9) +#define E(n) D(n##0) D(n##1) D(n##2) D(n##3) D(n##4) D(n##5) D(n##6) D(n##7) D(n##8) D(n##9) + C(1) C(2) C(3) C(4) C(5) C(6) + return d + c; +} |