Hi! On the attached testcase we spend > 7 minutes in RTL DSE, as we end up with active_local_stores chain with up to 100000 entries and we walk it through on each store.
The following patch fixes it by throwing away from active_local_stores list stores that don't have any positions needed, but can't be deleted (I believe such stores aren't helpful at all in the list, we aren't going to remove them anyway, and they can't be used by replace_read either). Alternatively (or in addition to this) we might remember the length of the active_local_stores list and just drop it on the floor when it becomes too long (say over 5000 stores or something similar, perhaps a param). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk (and after a while for 4.6)? 2011-03-15 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/48141 * dse.c (record_store): If no positions are needed in an insn that cannot be deleted, at least unchain it from active_local_stores. * gcc.dg/pr48141.c: New test. --- gcc/dse.c.jj 2011-02-15 15:42:26.000000000 +0100 +++ gcc/dse.c 2011-03-15 21:25:59.000000000 +0100 @@ -1530,8 +1530,7 @@ record_store (rtx body, bb_info_t bb_inf /* An insn can be deleted if every position of every one of its s_infos is zero. */ - if (any_positions_needed_p (s_info) - || ptr->cannot_delete) + if (any_positions_needed_p (s_info)) del = false; if (del) @@ -1543,7 +1542,8 @@ record_store (rtx body, bb_info_t bb_inf else active_local_stores = ptr->next_local_store; - delete_dead_store_insn (insn_to_delete); + if (!insn_to_delete->cannot_delete) + delete_dead_store_insn (insn_to_delete); } else last = ptr; --- gcc/testsuite/gcc.dg/pr48141.c.jj 2011-03-15 21:48:46.000000000 +0100 +++ gcc/testsuite/gcc.dg/pr48141.c 2011-03-15 21:48:27.000000000 +0100 @@ -0,0 +1,17 @@ +/* PR rtl-optimization/48141 */ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +#define A i = 0; +#define B A A A A A A A A A A +#define C B B B B B B B B B B +#define D C C C C C C C C C C +#define E D D D D D D D D D D + +int +foo (void) +{ + volatile int i = 0; + E E E E E E E E E E E + return 0; +} Jakub