------- 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

Reply via email to