]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR rtl-optimization/60866 (ICE: in get_seqno_for_a_jump, at sel-sched...
authorAndrey Belevantsev <abel@ispras.ru>
Tue, 3 Jun 2014 09:25:39 +0000 (13:25 +0400)
committerAndrey Belevantsev <abel@gcc.gnu.org>
Tue, 3 Jun 2014 09:25:39 +0000 (13:25 +0400)
        Backport from mainline
        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.

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

From-SVN: r211165

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

index 278e13316cd96faa72d074625ff4d7331873d84d..343050c0d0a1febf010aaf1773659ce59913e715 100644 (file)
@@ -1,3 +1,19 @@
+2014-06-03  Andrey Belevantsev  <abel@ispras.ru>
+
+       Backport from mainline
+       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-06-03  Andrey Belevantsev  <abel@ispras.ru>
 
        Backport from mainline
index 91e91ec37fd6d574b648fca4d6a472cc06a4a04c..6aa1904f4280fba92de346520f1186e9c31236bb 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.  */
@@ -4011,9 +4011,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;
 
@@ -4069,8 +4070,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;
 }
 
@@ -4250,22 +4259,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)
@@ -4292,7 +4303,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))
@@ -5578,14 +5589,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
@@ -5594,8 +5605,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);
 
@@ -5607,7 +5623,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,
@@ -5626,6 +5643,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
@@ -5634,6 +5652,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 ());
@@ -5654,7 +5678,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 a165e84e458a3123857a46c10056535985facf3d..0bba1d5680191bba2f8c1b80747921f0b353442c 100644 (file)
@@ -1,3 +1,11 @@
+2014-06-03  Andrey Belevantsev  <abel@ispras.ru>
+
+       Backport from mainline
+       2014-05-14  Andrey Belevantsev  <abel@ispras.ru>
+
+       PR rtl-optimization/60866
+       * gcc.dg/pr60866.c: New test.
+
 2014-06-03  Andrey Belevantsev  <abel@ispras.ru>
 
        Backport from mainline
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)
+         ;
+      }
+}