diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-02-12 11:37:38 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2013-02-12 11:37:38 +0100 |
commit | 6da26889318467b3df29c215f15d0c8369c969e3 (patch) | |
tree | f65fc19aa8ddb84c4b86e34d59f3e05f225bb1c1 /gcc | |
parent | 1590a83511111c9621a72800b361589aa11734b9 (diff) | |
download | gcc-6da26889318467b3df29c215f15d0c8369c969e3.zip gcc-6da26889318467b3df29c215f15d0c8369c969e3.tar.gz gcc-6da26889318467b3df29c215f15d0c8369c969e3.tar.bz2 |
re PR rtl-optimization/56151 (Performance degradation after r194054 on x86 Atom.)
PR rtl-optimization/56151
* optabs.c (add_equal_note): Don't return 0 if target is a MEM,
equal to op0 or op1, and last_insn pattern is CODE operation
with MEM dest and one of the operands matches that MEM.
* gcc.target/i386/pr56151.c: New test.
Co-Authored-By: Steven Bosscher <steven@gcc.gnu.org>
From-SVN: r195972
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/optabs.c | 35 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr56151.c | 17 |
4 files changed, 59 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 360514e..d959c9c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2013-02-12 Jakub Jelinek <jakub@redhat.com> + Steven Bosscher <steven@gcc.gnu.org> + + PR rtl-optimization/56151 + * optabs.c (add_equal_note): Don't return 0 if target is a MEM, + equal to op0 or op1, and last_insn pattern is CODE operation + with MEM dest and one of the operands matches that MEM. + 2013-02-11 Sriraman Tallam <tmsriramgoogle.com> * doc/extend.texi: Document Function Multiversioning and "default" diff --git a/gcc/optabs.c b/gcc/optabs.c index 8a3d3a9..c1dacf4 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -190,17 +190,40 @@ add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1) if (GET_CODE (target) == ZERO_EXTRACT) return 1; - /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing - a value changing in the insn, so the note would be invalid for CSE. */ - if (reg_overlap_mentioned_p (target, op0) - || (op1 && reg_overlap_mentioned_p (target, op1))) - return 0; - for (last_insn = insns; NEXT_INSN (last_insn) != NULL_RTX; last_insn = NEXT_INSN (last_insn)) ; + /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing + a value changing in the insn, so the note would be invalid for CSE. */ + if (reg_overlap_mentioned_p (target, op0) + || (op1 && reg_overlap_mentioned_p (target, op1))) + { + if (MEM_P (target) + && (rtx_equal_p (target, op0) + || (op1 && rtx_equal_p (target, op1)))) + { + /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note + over expanding it as temp = MEM op X, MEM = temp. If the target + supports MEM = MEM op X instructions, it is sometimes too hard + to reconstruct that form later, especially if X is also a memory, + and due to multiple occurrences of addresses the address might + be forced into register unnecessarily. + Note that not emitting the REG_EQUIV note might inhibit + CSE in some cases. */ + set = single_set (last_insn); + if (set + && GET_CODE (SET_SRC (set)) == code + && MEM_P (SET_DEST (set)) + && (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0)) + || (op1 && rtx_equal_p (SET_DEST (set), + XEXP (SET_SRC (set), 1))))) + return 1; + } + return 0; + } + set = single_set (last_insn); if (set == NULL_RTX) return 1; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4aa1b4c..e9ab329 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-02-12 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/56151 + * gcc.target/i386/pr56151.c: New test. + 2013-02-11 Sriraman Tallam <tmsriramgoogle.com> * g++.dg/ext/mv12.C: New test. diff --git a/gcc/testsuite/gcc.target/i386/pr56151.c b/gcc/testsuite/gcc.target/i386/pr56151.c new file mode 100644 index 0000000..24a1b8a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr56151.c @@ -0,0 +1,17 @@ +/* PR rtl-optimization/56151 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int vara, varb; + +void +foo (int i, int j) +{ + vara = varb | vara; +} + +/* Verify the above is compiled into movl varb, %reg; orl %reg, vara instead + of longer movl vara, %reg; orl varb, %reg; movl %reg, vara. */ +/* { dg-final { scan-assembler-not "mov\[^\n\r]*vara" { target nonpic } } } */ +/* { dg-final { scan-assembler-times "mov\[^\n\r]*varb" 1 { target nonpic } } } */ +/* { dg-final { scan-assembler-times "or\[^\n\r]*vara" 1 { target nonpic } } } */ |