http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60101
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |manu at gcc dot gnu.org --- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So, I've started to add hash tables into the picture if tlist go over certain number of elements, but while doing that I've noticed two issues in the original code. The first one is that merge_tlist either has misnamed argument (copy), or does the wrong thing, because it copies when copy is false and doesn't copy if it is true. Most of the merge_tlist calls are with 0 and I think can reuse the tlist structures, because the original list is not used anymore for anything afterwards. I don't understand: merge_tlist (pbefore_sp, tmp_list2, 1); in COND_EXPR handling, tmp_tlist isn't used afterwards either, and merge_tlist (pbefore_sp, t->cache_before_sp, 1); in SAVE_EXPR handling looks to be the only place where we need to make copies during merge_tlist. The second issue is the SAVE_EXPR handling, where I don't understand at all what is meant by the while (tmp_nosp) loop, because every merge_tlist iteration already merges in all the tmp_nosp list elements into tmp_list3 (and because of the broken merge_tlist copy handling creates copies of all those elements), then it attempts to merge again all but the first one (but, that shouldn't add anything, all the entries should be already merged in by the previous merge_tlist call). --- c-common.c.jj 2014-02-08 10:07:12.000000000 +0100 +++ c-common.c 2014-02-11 13:18:53.270521683 +0100 @@ -2976,7 +2976,7 @@ merge_tlist (struct tlist **to, struct t } if (!found) { - *end = copy ? add : new_tlist (NULL, add->expr, add->writer); + *end = copy ? new_tlist (NULL, add->expr, add->writer) : add; end = &(*end)->next; *end = 0; } @@ -3134,7 +3134,7 @@ verify_tree (tree x, struct tlist **pbef verify_tree (TREE_OPERAND (x, 0), &tmp_before, &tmp_list2, NULL_TREE); warn_for_collisions (tmp_list2); merge_tlist (pbefore_sp, tmp_before, 0); - merge_tlist (pbefore_sp, tmp_list2, 1); + merge_tlist (pbefore_sp, tmp_list2, 0); tmp_list3 = tmp_nosp = 0; verify_tree (TREE_OPERAND (x, 1), &tmp_list3, &tmp_nosp, NULL_TREE); @@ -3238,12 +3238,7 @@ verify_tree (tree x, struct tlist **pbef warn_for_collisions (tmp_nosp); tmp_list3 = 0; - while (tmp_nosp) - { - struct tlist *t = tmp_nosp; - tmp_nosp = t->next; - merge_tlist (&tmp_list3, t, 0); - } + merge_tlist (&tmp_list3, tmp_nosp, 0); t->cache_before_sp = tmp_before; t->cache_after_sp = tmp_list3; } make check RUNTESTFLAGS=dg.exp=*seq* passes with this change and the testcase from this PR finishes in under a second. Manuel, can you please try to explain what you were trying to achieve in the SAVE_EXPR case and whether the reversal of copy behavior in merge_tlist was on purpose?