http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49349

Alexander Monakov <amonakov at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |ASSIGNED
   Last reconfirmed|                            |2011.06.10 12:13:45
         AssignedTo|unassigned at gcc dot       |amonakov at gcc dot gnu.org
                   |gnu.org                     |
     Ever Confirmed|0                           |1

--- Comment #1 from Alexander Monakov <amonakov at gcc dot gnu.org> 2011-06-10 
12:13:45 UTC ---
It's a rare bug in sel-sched: we fail to schedule some code in non-pipelining
mode.  The root cause is that we put bookkeeping instructions above a fence
that is placed on the last insn (uncond. jump) of the bookkeeping block.  We
could either make such blocks ineligible for bookkeeping or rewind such fences
from the jump back to the bookkeeping code (there's also a more involved
approach of re-introducing the idea of using local nops as placeholders for
fences).  I'm testing the following patch that implements the second approach
(as it should result in a bit cleaner code in such situations).

diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index 3f22a3c..f40ab90 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -4665,7 +4666,7 @@ create_block_for_bookkeeping (edge e1, edge e2)
 /* Return insn after which we must insert bookkeeping code for path(s)
incoming
    into E2->dest, except from E1->src.  */
 static insn_t
-find_place_for_bookkeeping (edge e1, edge e2)
+find_place_for_bookkeeping (edge e1, edge e2, fence_t *fence_to_rewind)
 {
   insn_t place_to_insert;
   /* Find a basic block that can hold bookkeeping.  If it can be found, do not
@@ -4707,9 +4708,13 @@ find_place_for_bookkeeping (edge e1, edge e2)
     sel_print ("Pre-existing bookkeeping block is %i\n", book_block->index);
     }

+  *fence_to_rewind = NULL;
   /* If basic block ends with a jump, insert bookkeeping code right before it.
 */
   if (INSN_P (place_to_insert) && control_flow_insn_p (place_to_insert))
-    place_to_insert = PREV_INSN (place_to_insert);
+    {
+      *fence_to_rewind = flist_lookup (fences, place_to_insert);
+      place_to_insert = PREV_INSN (place_to_insert);
+    }

   return place_to_insert;
 }
@@ -4784,21 +4789,23 @@ generate_bookkeeping_insn (expr_t c_expr, edge e1, edge
e2)
   insn_t join_point, place_to_insert, new_insn;
   int new_seqno;
   bool need_to_exchange_data_sets;
+  fence_t fence_to_rewind;

   if (sched_verbose >= 4)
     sel_print ("Generating bookkeeping insn (%d->%d)\n", e1->src->index,
            e2->dest->index);

   join_point = sel_bb_head (e2->dest);
-  place_to_insert = find_place_for_bookkeeping (e1, e2);
-  if (!place_to_insert)
-    return NULL;
+  place_to_insert = find_place_for_bookkeeping (e1, e2, &fence_to_rewind);
   new_seqno = find_seqno_for_bookkeeping (place_to_insert, join_point);
   need_to_exchange_data_sets
     = sel_bb_empty_p (BLOCK_FOR_INSN (place_to_insert));

   new_insn = emit_bookkeeping_insn (place_to_insert, c_expr, new_seqno);

+  if (fence_to_rewind)
+    FENCE_INSN (fence_to_rewind) = new_insn;
+
   /* When inserting bookkeeping insn in new block, av sets should be
      following: old basic block (that now holds bookkeeping) data sets are
      the same as was before generation of bookkeeping, and new basic block

Reply via email to