diff options
author | Paul Brook <paul@codesourcery.com> | 2006-07-20 13:57:31 +0000 |
---|---|---|
committer | Paul Brook <pbrook@gcc.gnu.org> | 2006-07-20 13:57:31 +0000 |
commit | 05c433f35af50d8d85785849240eb51977a0030e (patch) | |
tree | b840f7b8a5b246ea76459f17a07eae015b3d7925 /gcc/cse.c | |
parent | b0e46dff1cee9a5d1762a4d5387af1272a3cbe82 (diff) | |
download | gcc-05c433f35af50d8d85785849240eb51977a0030e.zip gcc-05c433f35af50d8d85785849240eb51977a0030e.tar.gz gcc-05c433f35af50d8d85785849240eb51977a0030e.tar.bz2 |
re PR target/27363 (ARM gcc 4.1 optimization bug)
2006-07-20 Paul Brook <paul@codesourcery.com>
PR 27363
gcc/
* cse.c (cse_insn): Add destination addresses to hash table. Check if
they are invalidated by this instruction.
gcc/testsuite/
* gcc.dg/pr27363.c: New test.
From-SVN: r115614
Diffstat (limited to 'gcc/cse.c')
-rw-r--r-- | gcc/cse.c | 48 |
1 files changed, 46 insertions, 2 deletions
@@ -4739,6 +4739,8 @@ struct set unsigned src_const_hash; /* Table entry for constant equivalent for SET_SRC, if any. */ struct table_elt *src_const_elt; + /* Table entry for the destination address. */ + struct table_elt *dest_addr_elt; }; static void @@ -5970,6 +5972,40 @@ cse_insn (rtx insn, rtx libcall_insn) so that the destination goes into that class. */ sets[i].src_elt = src_eqv_elt; + /* Record destination addresses in the hash table. This allows us to + check if they are invalidated by other sets. */ + for (i = 0; i < n_sets; i++) + { + if (sets[i].rtl) + { + rtx x = sets[i].inner_dest; + struct table_elt *elt; + enum machine_mode mode; + unsigned hash; + + if (MEM_P (x)) + { + x = XEXP (x, 0); + mode = GET_MODE (x); + hash = HASH (x, mode); + elt = lookup (x, hash, mode); + if (!elt) + { + if (insert_regs (x, NULL, 0)) + { + rehash_using_reg (x); + hash = HASH (x, mode); + } + elt = insert (x, NULL, hash, mode); + } + + sets[i].dest_addr_elt = elt; + } + else + sets[i].dest_addr_elt = NULL; + } + } + invalidate_from_clobbers (x); /* Some registers are invalidated by subroutine calls. Memory is @@ -6062,12 +6098,20 @@ cse_insn (rtx insn, rtx libcall_insn) } /* We may have just removed some of the src_elt's from the hash table. - So replace each one with the current head of the same class. */ + So replace each one with the current head of the same class. + Also check if destination addresses have been removed. */ for (i = 0; i < n_sets; i++) if (sets[i].rtl) { - if (sets[i].src_elt && sets[i].src_elt->first_same_value == 0) + if (sets[i].dest_addr_elt + && sets[i].dest_addr_elt->first_same_value == 0) + { + /* The elt was removed, which means this destination s not + valid after this instruction. */ + sets[i].rtl = NULL_RTX; + } + else if (sets[i].src_elt && sets[i].src_elt->first_same_value == 0) /* If elt was removed, find current head of same class, or 0 if nothing remains of that class. */ { |