]> gcc.gnu.org Git - gcc.git/commitdiff
re PR rtl-optimization/60866 (ICE: in get_seqno_for_a_jump, at sel-sched-ir.c:4068...
authorAndrey Belevantsev <abel@ispras.ru>
Wed, 14 May 2014 12:09:02 +0000 (16:09 +0400)
committerAndrey Belevantsev <abel@gcc.gnu.org>
Wed, 14 May 2014 12:09:02 +0000 (16:09 +0400)
        PR rtl-optimization/60866
        * sel-sched-ir (sel_init_new_insn): New parameter old_seqno.
        Default it to -1.  Pass it down to init_simplejump_data.
        (init_simplejump_data): New parameter old_seqno.  Pass it down
        to get_seqno_for_a_jump.
        (get_seqno_for_a_jump): New parameter old_seqno.  Use it for
        initializing new jump seqno as a last resort.  Add comment.
        (sel_redirect_edge_and_branch): Save old seqno of the conditional
        jump and pass it down to sel_init_new_insn.
        (sel_redirect_edge_and_branch_force): Likewise.

* gcc.dg/pr60866.c: New test.

From-SVN: r210420

gcc/ChangeLog
gcc/sel-sched-ir.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr60866.c [new file with mode: 0644]

index 8308c260bcafb4752961a3c30f79d1de762b168c..86f92f0fcf27ff5d6223a8e8a3f7f2ab08650d22 100644 (file)
@@ -1,3 +1,16 @@
+2014-05-14  Andrey Belevantsev  <abel@ispras.ru>
+
+       PR rtl-optimization/60866
+       * sel-sched-ir (sel_init_new_insn): New parameter old_seqno.
+       Default it to -1.  Pass it down to init_simplejump_data.
+       (init_simplejump_data): New parameter old_seqno.  Pass it down
+       to get_seqno_for_a_jump.
+       (get_seqno_for_a_jump): New parameter old_seqno.  Use it for
+       initializing new jump seqno as a last resort.  Add comment.
+       (sel_redirect_edge_and_branch): Save old seqno of the conditional
+       jump and pass it down to sel_init_new_insn.
+       (sel_redirect_edge_and_branch_force): Likewise.
+
 2014-05-14  Georg-Johann Lay  <avr@gjlay.de>
 
        * config/avr/avr.h (REG_CLASS_CONTENTS): Use unsigned suffix for
index 868083b1a02d84249b5296f643cf413b6c0d4a9a..3cba326e89741f28a7ee2643bd9f40022a3f2e09 100644 (file)
@@ -162,7 +162,7 @@ static void create_initial_data_sets (basic_block);
 static void free_av_set (basic_block);
 static void invalidate_av_set (basic_block);
 static void extend_insn_data (void);
-static void sel_init_new_insn (insn_t, int);
+static void sel_init_new_insn (insn_t, int, int = -1);
 static void finish_insns (void);
 \f
 /* Various list functions.  */
@@ -4007,9 +4007,10 @@ get_seqno_by_succs (rtx insn)
   return seqno;
 }
 
-/* Compute seqno for INSN by its preds or succs.  */
+/* Compute seqno for INSN by its preds or succs.  Use OLD_SEQNO to compute
+   seqno in corner cases.  */
 static int
-get_seqno_for_a_jump (insn_t insn)
+get_seqno_for_a_jump (insn_t insn, int old_seqno)
 {
   int seqno;
 
@@ -4065,8 +4066,16 @@ get_seqno_for_a_jump (insn_t insn)
   if (seqno < 0)
     seqno = get_seqno_by_succs (insn);
 
-  gcc_assert (seqno >= 0);
+  if (seqno < 0)
+    {
+      /* The only case where this could be here legally is that the only
+        unscheduled insn was a conditional jump that got removed and turned
+        into this unconditional one.  Initialize from the old seqno
+        of that jump passed down to here.  */
+      seqno = old_seqno;
+    }
 
+  gcc_assert (seqno >= 0);
   return seqno;
 }
 
@@ -4246,22 +4255,24 @@ init_insn_data (insn_t insn)
 }
 
 /* This is used to initialize spurious jumps generated by
-   sel_redirect_edge ().  */
+   sel_redirect_edge ().  OLD_SEQNO is used for initializing seqnos
+   in corner cases within get_seqno_for_a_jump.  */
 static void
-init_simplejump_data (insn_t insn)
+init_simplejump_data (insn_t insn, int old_seqno)
 {
   init_expr (INSN_EXPR (insn), vinsn_create (insn, false), 0,
             REG_BR_PROB_BASE, 0, 0, 0, 0, 0, 0,
             vNULL, true, false, false,
             false, true);
-  INSN_SEQNO (insn) = get_seqno_for_a_jump (insn);
+  INSN_SEQNO (insn) = get_seqno_for_a_jump (insn, old_seqno);
   init_first_time_insn_data (insn);
 }
 
 /* Perform deferred initialization of insns.  This is used to process
-   a new jump that may be created by redirect_edge.  */
-void
-sel_init_new_insn (insn_t insn, int flags)
+   a new jump that may be created by redirect_edge.  OLD_SEQNO is used
+   for initializing simplejumps in init_simplejump_data.  */
+static void
+sel_init_new_insn (insn_t insn, int flags, int old_seqno)
 {
   /* We create data structures for bb when the first insn is emitted in it.  */
   if (INSN_P (insn)
@@ -4288,7 +4299,7 @@ sel_init_new_insn (insn_t insn, int flags)
   if (flags & INSN_INIT_TODO_SIMPLEJUMP)
     {
       extend_insn_data ();
-      init_simplejump_data (insn);
+      init_simplejump_data (insn, old_seqno);
     }
 
   gcc_assert (CONTAINING_RGN (BLOCK_NUM (insn))
@@ -5575,14 +5586,14 @@ sel_merge_blocks (basic_block a, basic_block b)
 }
 
 /* A wrapper for redirect_edge_and_branch_force, which also initializes
-   data structures for possibly created bb and insns.  Returns the newly
-   added bb or NULL, when a bb was not needed.  */
+   data structures for possibly created bb and insns.  */
 void
 sel_redirect_edge_and_branch_force (edge e, basic_block to)
 {
   basic_block jump_bb, src, orig_dest = e->dest;
   int prev_max_uid;
   rtx jump;
+  int old_seqno = -1;
 
   /* This function is now used only for bookkeeping code creation, where
      we'll never get the single pred of orig_dest block and thus will not
@@ -5591,8 +5602,13 @@ sel_redirect_edge_and_branch_force (edge e, basic_block to)
               && !single_pred_p (orig_dest));
   src = e->src;
   prev_max_uid = get_max_uid ();
-  jump_bb = redirect_edge_and_branch_force (e, to);
+  /* Compute and pass old_seqno down to sel_init_new_insn only for the case
+     when the conditional jump being redirected may become unconditional.  */
+  if (any_condjump_p (BB_END (src))
+      && INSN_SEQNO (BB_END (src)) >= 0)
+    old_seqno = INSN_SEQNO (BB_END (src));
 
+  jump_bb = redirect_edge_and_branch_force (e, to);
   if (jump_bb != NULL)
     sel_add_bb (jump_bb);
 
@@ -5604,7 +5620,8 @@ sel_redirect_edge_and_branch_force (edge e, basic_block to)
 
   jump = find_new_jump (src, jump_bb, prev_max_uid);
   if (jump)
-    sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP);
+    sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP,
+                      old_seqno);
   set_immediate_dominator (CDI_DOMINATORS, to,
                           recompute_dominator (CDI_DOMINATORS, to));
   set_immediate_dominator (CDI_DOMINATORS, orig_dest,
@@ -5623,6 +5640,7 @@ sel_redirect_edge_and_branch (edge e, basic_block to)
   edge redirected;
   bool recompute_toporder_p = false;
   bool maybe_unreachable = single_pred_p (orig_dest);
+  int old_seqno = -1;
 
   latch_edge_p = (pipelining_p
                   && current_loop_nest
@@ -5631,6 +5649,12 @@ sel_redirect_edge_and_branch (edge e, basic_block to)
   src = e->src;
   prev_max_uid = get_max_uid ();
 
+  /* Compute and pass old_seqno down to sel_init_new_insn only for the case
+     when the conditional jump being redirected may become unconditional.  */
+  if (any_condjump_p (BB_END (src))
+      && INSN_SEQNO (BB_END (src)) >= 0)
+    old_seqno = INSN_SEQNO (BB_END (src));
+
   redirected = redirect_edge_and_branch (e, to);
 
   gcc_assert (redirected && !last_added_blocks.exists ());
@@ -5651,7 +5675,7 @@ sel_redirect_edge_and_branch (edge e, basic_block to)
 
   jump = find_new_jump (src, NULL, prev_max_uid);
   if (jump)
-    sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP);
+    sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP, old_seqno);
 
   /* Only update dominator info when we don't have unreachable blocks.
      Otherwise we'll update in maybe_tidy_empty_bb.  */
index b9847d38829e3eeb8ed354b794b76ed180cb5279..faa38583ef779634a35c2c0464d11fcb21ea1415 100644 (file)
@@ -1,3 +1,8 @@
+2014-05-14  Andrey Belevantsev  <abel@ispras.ru>
+
+       PR rtl-optimization/60866
+       * gcc.dg/pr60866.c: New test. 
+
 2014-05-14  Andrey Belevantsev  <abel@ispras.ru>
 
        PR rtl-optimization/60901
diff --git a/gcc/testsuite/gcc.dg/pr60866.c b/gcc/testsuite/gcc.dg/pr60866.c
new file mode 100644 (file)
index 0000000..020878d
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile { target powerpc*-*-* ia64-*-* x86_64-*-* } } */
+/* { dg-options "-O -fselective-scheduling -fno-if-conversion -fschedule-insns"  } */
+
+int n;
+
+void
+foo (int w, int **dnroot, int **dn)
+{
+  int *child;
+  int *xchild = xchild;
+  for (; w < n; w++)
+    if (!dnroot)
+      {
+       dnroot = dn;
+       for (child = *dn; child; child = xchild)
+         ;
+      }
+}
This page took 0.088117 seconds and 5 git commands to generate.