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/optabs.c | |
parent | 1590a83511111c9621a72800b361589aa11734b9 (diff) | |
download | gcc-6da26889318467b3df29c215f15d0c8369c969e3.tar.gz |
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/optabs.c')
-rw-r--r-- | gcc/optabs.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index 8a3d3a921ab..c1dacf487a0 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; |