------- Comment #7 from abel at gcc dot gnu dot org 2009-12-24 08:18 ------- The problem here is in the incorrect handling of the transformation history. When an insn is transformed (i.e. substituted/speculated), this is recorded so that the insn could be found during upward code motion. Part of the data recorded is the uid of insn on which the transformation happened. As this second insn could get removed while filling a parallel group, and its bookkeeping copy could be created, we need to undo the transformation while moving through this copy instead of original insn. To do this, we also maintain a bitmap of insn uids that could generate the copy (INSN_ORIGINATORS), and we also check it on the copies. The actual bug was that the bitmap should contain all "ancestor insns" of a copy, not only "parents", as the copy found could originated from another copy (yes, I was stupid of not thinking about this earlier). The alternate solution would be to make the search function recurse on INSN_ORIGINATORS bitmap, but this one seemed clearer.
Patch by Alexander below, we would need to ask someone with access to ppc64 to test it (as a part of combined patch fixing other sel-sched bugs) in addition to our testing. * sel-sched-ir.h (struct _sel_insn_data): Update comment. * sel-sched.c (move_exprs_to_boundary): Transitively add all originators' originators. --- gcc/sel-sched-ir.h | 3 ++- gcc/sel-sched.c | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletions(-) diff --git a/gcc/sel-sched-ir.h b/gcc/sel-sched-ir.h index 1950a65..67b5b62 100644 --- a/gcc/sel-sched-ir.h +++ b/gcc/sel-sched-ir.h @@ -715,7 +715,8 @@ struct _sel_insn_data bitmap found_deps; /* An INSN_UID bit is set when this is a bookkeeping insn generated from - a parent with this uid. */ + a parent with this uid. If a parent is a bookkeeping copy, all its + originators are transitively included in this set. */ bitmap originators; /* A hashtable caching the result of insn transformations through this one. */ diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index e5ebc57..9fcc633 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -5211,12 +5211,21 @@ move_exprs_to_boundary (bnd_t bnd, expr_t expr_vliw, EXECUTE_IF_SET_IN_BITMAP (current_copies, 0, book_uid, bi) { + unsigned uid; + bitmap_iterator bi; + /* We allocate these bitmaps lazily. */ if (! INSN_ORIGINATORS_BY_UID (book_uid)) INSN_ORIGINATORS_BY_UID (book_uid) = BITMAP_ALLOC (NULL); bitmap_copy (INSN_ORIGINATORS_BY_UID (book_uid), current_originators); + + /* Transitively add all originators' originators. */ + EXECUTE_IF_SET_IN_BITMAP (current_originators, 0, uid, bi) + if (INSN_ORIGINATORS_BY_UID (uid)) + bitmap_ior_into (INSN_ORIGINATORS_BY_UID (book_uid), + INSN_ORIGINATORS_BY_UID (uid)); } return should_move; -- abel at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |abel at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42294