]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR target/43603 (gcc-4.4.3 ICE on ia64 with -O3)
authorAndrey Belevantsev <abel@ispras.ru>
Mon, 20 Jun 2011 11:56:08 +0000 (15:56 +0400)
committerAndrey Belevantsev <abel@gcc.gnu.org>
Mon, 20 Jun 2011 11:56:08 +0000 (15:56 +0400)
        Backport from mainline
        2010-12-07  Andrey Belevantsev  <abel@ispras.ru>
        PR target/43603
        * haifa-sched.c (sched_create_recovery_edges): Update
        dominator info.
        * sel-sched-ir.c (maybe_tidy_empty_bb): Update dominator info
        after deleting an empty block, verify dominators.
        (sel_remove_bb): Update dominator info after removing a block.
        (sel_redirect_edge_and_branch_force): Assert that no unreachable
        blocks will be created. Update dominator info.
        (sel_redirect_edge_and_branch): Update dominator info when
        basic blocks do not become unreachable.
        (sel_remove_loop_preheader): Update dominator info.

        2010-10-14  Andrey Belevantsev  <abel@ispras.ru>

        * sel-sched-ir.c (maybe_tidy_empty_bb): Simplify comment.
        (tidy_control_flow): Tidy vertical space.
        (sel_remove_bb): New variable idx.  Use it to remember the basic
        block index before deleting the block.
        (sel_remove_empty_bb): Remove dead code, simplify and insert to ...
        (sel_merge_blocks): ... here.  Add forward declaration.
        * sel-sched-ir.h (sel_remove_empty_bb): Remove prototype.
        (sel_merge_blocks): Likewise.

2011-06-20  Andrey Belevantsev  <abel@ispras.ru>

        Backport from mainline
        2010-12-07  Andrey Belevantsev  <abel@ispras.ru>

        PR target/43603
        * gcc.target/ia64/pr43603.c: New.
        * gcc/testsuite/g++.dg/opt/pr46640.C: New.

From-SVN: r175207

gcc/ChangeLog
gcc/haifa-sched.c
gcc/sel-sched-ir.c
gcc/sel-sched-ir.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr46640.C [new file with mode: 0644]
gcc/testsuite/gcc.target/ia64/pr43603.c [new file with mode: 0644]

index 09164bed7a370542866d3fd65f2da6e58f19d6bd..8dafef711f74fbbf6e07f2eafd29082f2c9ef82a 100644 (file)
@@ -1,3 +1,30 @@
+2011-06-20  Andrey Belevantsev  <abel@ispras.ru>
+
+       Backport from mainline
+       2010-12-07  Andrey Belevantsev  <abel@ispras.ru>
+       PR target/43603
+       * haifa-sched.c (sched_create_recovery_edges): Update
+       dominator info.
+       * sel-sched-ir.c (maybe_tidy_empty_bb): Update dominator info
+       after deleting an empty block, verify dominators.
+       (sel_remove_bb): Update dominator info after removing a block.
+       (sel_redirect_edge_and_branch_force): Assert that no unreachable
+       blocks will be created. Update dominator info.
+       (sel_redirect_edge_and_branch): Update dominator info when
+       basic blocks do not become unreachable.
+       (sel_remove_loop_preheader): Update dominator info.
+
+       2010-10-14  Andrey Belevantsev  <abel@ispras.ru>
+
+       * sel-sched-ir.c (maybe_tidy_empty_bb): Simplify comment.
+       (tidy_control_flow): Tidy vertical space.
+       (sel_remove_bb): New variable idx.  Use it to remember the basic
+       block index before deleting the block.
+       (sel_remove_empty_bb): Remove dead code, simplify and insert to ...
+       (sel_merge_blocks): ... here.  Add forward declaration.
+       * sel-sched-ir.h (sel_remove_empty_bb): Remove prototype.
+       (sel_merge_blocks): Likewise.
+
 2011-06-17  Hans-Peter Nilsson  <hp@axis.com>
 
        Backport from mainline
index 09dc233c2537536cee00d0da41e442ac2c20e02b..a3931a591b59f72a329f862e6b372663a982a51f 100644 (file)
@@ -3918,7 +3918,9 @@ sched_create_recovery_edges (basic_block first_bb, basic_block rec,
   else
     edge_flags = 0;  
 
-  make_single_succ_edge (rec, second_bb, edge_flags);  
+  make_single_succ_edge (rec, second_bb, edge_flags);
+  if (dom_info_available_p (CDI_DOMINATORS))
+    set_immediate_dominator (CDI_DOMINATORS, rec, first_bb);
 }
 
 /* This function creates recovery code for INSN.  If MUTATE_P is nonzero,
index a6b73b997d00416f961b557353917fff875913d2..ab2742fd871bad8130a4074df2fc664be59e9c1e 100644 (file)
@@ -152,6 +152,7 @@ static void free_history_vect (VEC (expr_history_def, heap) **);
 
 static void move_bb_info (basic_block, basic_block);
 static void remove_empty_bb (basic_block, bool);
+static void sel_merge_blocks (basic_block, basic_block);
 static void sel_remove_loop_preheader (void);
 
 static bool insn_is_the_only_one_in_bb_p (insn_t);
@@ -3539,6 +3540,7 @@ static bool
 maybe_tidy_empty_bb (basic_block bb, bool recompute_toporder_p)
 {
   basic_block succ_bb, pred_bb;
+  VEC (basic_block, heap) *dom_bbs;
   edge e;
   edge_iterator ei;
   bool rescan_p;
@@ -3574,6 +3576,7 @@ maybe_tidy_empty_bb (basic_block bb, bool recompute_toporder_p)
   succ_bb = single_succ (bb);
   rescan_p = true;
   pred_bb = NULL;
+  dom_bbs = NULL;
 
   /* Redirect all non-fallthru edges to the next bb.  */
   while (rescan_p)
@@ -3586,6 +3589,12 @@ maybe_tidy_empty_bb (basic_block bb, bool recompute_toporder_p)
 
           if (!(e->flags & EDGE_FALLTHRU))
             {
+             /* We will update dominators here only when we'll get
+                an unreachable block when redirecting, otherwise
+                sel_redirect_edge_and_branch will take care of it.  */
+             if (e->dest != bb
+                 && single_pred_p (e->dest))
+               VEC_safe_push (basic_block, heap, dom_bbs, e->dest);
               recompute_toporder_p |= sel_redirect_edge_and_branch (e, succ_bb);
               rescan_p = true;
               break;
@@ -3593,13 +3602,11 @@ maybe_tidy_empty_bb (basic_block bb, bool recompute_toporder_p)
         }
     }
 
-  /* If it is possible - merge BB with its predecessor.  */
   if (can_merge_blocks_p (bb->prev_bb, bb))
     sel_merge_blocks (bb->prev_bb, bb);
   else
-    /* Otherwise this is a block without fallthru predecessor.
-       Just delete it.  */
     {
+      /* This is a block without fallthru predecessor.  Just delete it.  */
       gcc_assert (pred_bb != NULL);
 
       if (in_current_region_p (pred_bb))
@@ -3607,11 +3614,19 @@ maybe_tidy_empty_bb (basic_block bb, bool recompute_toporder_p)
       remove_empty_bb (bb, true);
     }
 
+  if (!VEC_empty (basic_block, dom_bbs))
+    {
+       VEC_safe_push (basic_block, heap, dom_bbs, succ_bb);
+       iterate_fix_dominators (CDI_DOMINATORS, dom_bbs, false);
+       VEC_free (basic_block, heap, dom_bbs);
+    }
+
   if (recompute_toporder_p)
     sel_recompute_toporder ();
 
 #ifdef ENABLE_CHECKING
   verify_backedges ();
+  verify_dominators (CDI_DOMINATORS);
 #endif
 
   return true;
@@ -4985,16 +5000,23 @@ sel_add_bb (basic_block bb)
 static void
 sel_remove_bb (basic_block bb, bool remove_from_cfg_p)
 {
+  unsigned idx = bb->index;
+
   gcc_assert (bb != NULL && BB_NOTE_LIST (bb) == NULL_RTX);
   
   remove_bb_from_region (bb);
   return_bb_to_pool (bb);
-  bitmap_clear_bit (blocks_to_reschedule, bb->index);
+  bitmap_clear_bit (blocks_to_reschedule, idx);
   
   if (remove_from_cfg_p)
-    delete_and_free_basic_block (bb);
+    {
+      basic_block succ = single_succ (bb);
+      delete_and_free_basic_block (bb);
+      set_immediate_dominator (CDI_DOMINATORS, succ,
+                               recompute_dominator (CDI_DOMINATORS, succ));
+    }
 
-  rgn_setup_region (CONTAINING_RGN (bb->index));
+  rgn_setup_region (CONTAINING_RGN (idx));
 }
 
 /* Concatenate info of EMPTY_BB to info of MERGE_BB.  */
@@ -5009,50 +5031,6 @@ move_bb_info (basic_block merge_bb, basic_block empty_bb)
 
 }
 
-/* Remove an empty basic block EMPTY_BB.  When MERGE_UP_P is true, we put 
-   EMPTY_BB's note lists into its predecessor instead of putting them 
-   into the successor.  When REMOVE_FROM_CFG_P is true, also remove 
-   the empty block.  */
-void
-sel_remove_empty_bb (basic_block empty_bb, bool merge_up_p,
-                    bool remove_from_cfg_p)
-{
-  basic_block merge_bb;
-
-  gcc_assert (sel_bb_empty_p (empty_bb));
-
-  if (merge_up_p)
-    {
-      merge_bb = empty_bb->prev_bb;
-      gcc_assert (EDGE_COUNT (empty_bb->preds) == 1
-                 && EDGE_PRED (empty_bb, 0)->src == merge_bb);
-    }
-  else
-    {
-      edge e;
-      edge_iterator ei;
-
-      merge_bb = bb_next_bb (empty_bb);
-
-      /* Redirect incoming edges (except fallthrough one) of EMPTY_BB to its 
-         successor block.  */
-      for (ei = ei_start (empty_bb->preds);
-           (e = ei_safe_edge (ei)); )
-        {
-          if (! (e->flags & EDGE_FALLTHRU))
-            sel_redirect_edge_and_branch (e, merge_bb);
-          else
-            ei_next (&ei);
-        }
-
-      gcc_assert (EDGE_COUNT (empty_bb->succs) == 1
-                 && EDGE_SUCC (empty_bb, 0)->dest == merge_bb);
-    }
-
-  move_bb_info (merge_bb, empty_bb);
-  remove_empty_bb (empty_bb, remove_from_cfg_p);
-}
-
 /* Remove EMPTY_BB.  If REMOVE_FROM_CFG_P is false, remove EMPTY_BB from
    region, but keep it in CFG.  */
 static void
@@ -5352,12 +5330,16 @@ sel_create_recovery_block (insn_t orig_insn)
 }
 
 /* Merge basic block B into basic block A.  */
-void
+static void
 sel_merge_blocks (basic_block a, basic_block b)
 {
-  sel_remove_empty_bb (b, true, false);
-  merge_blocks (a, b);
+  gcc_assert (sel_bb_empty_p (b)
+              && EDGE_COUNT (b->preds) == 1
+              && EDGE_PRED (b, 0)->src == b->prev_bb);
 
+  move_bb_info (b->prev_bb, b);
+  remove_empty_bb (b, false);
+  merge_blocks (a, b);
   change_loops_latches (b, a);
 }
 
@@ -5367,11 +5349,15 @@ sel_merge_blocks (basic_block a, basic_block b)
 void
 sel_redirect_edge_and_branch_force (edge e, basic_block to)
 {
-  basic_block jump_bb, src;
+  basic_block jump_bb, src, orig_dest = e->dest;
   int prev_max_uid;
   rtx jump;
     
-  gcc_assert (!sel_bb_empty_p (e->src));
+  /* 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
+     hit unreachable blocks when updating dominator info.  */
+  gcc_assert (!sel_bb_empty_p (e->src)
+              && !single_pred_p (orig_dest));
   
   src = e->src;
   prev_max_uid = get_max_uid ();
@@ -5389,6 +5375,10 @@ 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);
+  set_immediate_dominator (CDI_DOMINATORS, to,
+                          recompute_dominator (CDI_DOMINATORS, to));
+  set_immediate_dominator (CDI_DOMINATORS, orig_dest,
+                          recompute_dominator (CDI_DOMINATORS, orig_dest));
 }
 
 /* A wrapper for redirect_edge_and_branch.  Return TRUE if blocks connected by
@@ -5397,11 +5387,12 @@ bool
 sel_redirect_edge_and_branch (edge e, basic_block to)
 {
   bool latch_edge_p;
-  basic_block src;
+  basic_block src, orig_dest = e->dest;
   int prev_max_uid;
   rtx jump;
   edge redirected;
   bool recompute_toporder_p = false;
+  bool maybe_unreachable = single_pred_p (orig_dest);
 
   latch_edge_p = (pipelining_p
                   && current_loop_nest
@@ -5432,6 +5423,15 @@ sel_redirect_edge_and_branch (edge e, basic_block to)
   if (jump)
     sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP);
 
+  /* Only update dominator info when we don't have unreachable blocks.
+     Otherwise we'll update in maybe_tidy_empty_bb.  */
+  if (!maybe_unreachable)
+    {
+      set_immediate_dominator (CDI_DOMINATORS, to,
+                               recompute_dominator (CDI_DOMINATORS, to));
+      set_immediate_dominator (CDI_DOMINATORS, orig_dest,
+                               recompute_dominator (CDI_DOMINATORS, orig_dest));
+    }
   return recompute_toporder_p;
 }
 
@@ -6156,6 +6156,10 @@ sel_remove_loop_preheader (void)
                   if (BB_END (prev_bb) == bb_note (prev_bb))
                     free_data_sets (prev_bb);
                 }
+
+              set_immediate_dominator (CDI_DOMINATORS, next_bb,
+                                       recompute_dominator (CDI_DOMINATORS,
+                                                            next_bb));
             }
         }
       VEC_free (basic_block, heap, preheader_blocks);
index 8a67003df455d90de389b3f739f2f766f6630587..e5e905b8201bf56d4676225bcbee853983181473 100644 (file)
@@ -1579,11 +1579,9 @@ extern bool in_same_ebb_p (insn_t, insn_t);
 extern bool tidy_control_flow (basic_block, bool);
 extern void free_bb_note_pool (void);
 
-extern void sel_remove_empty_bb (basic_block, bool, bool);
 extern void purge_empty_blocks (void);
 extern basic_block sel_split_edge (edge);
 extern basic_block sel_create_recovery_block (insn_t);
-extern void sel_merge_blocks (basic_block, basic_block);
 extern bool sel_redirect_edge_and_branch (edge, basic_block);
 extern void sel_redirect_edge_and_branch_force (edge, basic_block);
 extern void sel_init_pipelining (void);
index e8fe3a5110fea565ec6f85ab5d505fd8e6738e9f..f0c4342233f8429a8380bb89946b590d85e09ffa 100644 (file)
@@ -1,3 +1,12 @@
+2011-06-20  Andrey Belevantsev  <abel@ispras.ru>
+
+       Backport from mainline
+       2010-12-07  Andrey Belevantsev  <abel@ispras.ru>
+
+       PR target/43603
+       * gcc.target/ia64/pr43603.c: New.
+       * gcc/testsuite/g++.dg/opt/pr46640.C: New.
+
 2011-06-17  Hans-Peter Nilsson  <hp@axis.com>
 
        Backport from mainline
diff --git a/gcc/testsuite/g++.dg/opt/pr46640.C b/gcc/testsuite/g++.dg/opt/pr46640.C
new file mode 100644 (file)
index 0000000..0892c9a
--- /dev/null
@@ -0,0 +1,44 @@
+// { dg-do compile { target x86_64-*-* } }
+// { dg-options "-fschedule-insns2 -fsel-sched-pipelining -fselective-scheduling2 -fno-exceptions -O" }
+
+struct QBasicAtomicInt
+{
+  int i, j;
+  bool deref ()
+  {
+    asm volatile ("":"=m" (i), "=qm" (j));
+  }
+};
+
+struct Data
+{
+  QBasicAtomicInt ref;
+  void *data;
+};
+
+struct QByteArray
+{
+  Data * d;
+  ~QByteArray ()
+  {
+    d->ref.deref ();
+  }
+};
+
+int indexOf (unsigned);
+int stat (void *, int *);
+QByteArray encodeName ();
+
+bool makeDir (unsigned len)
+{
+  unsigned i = 0;
+  while (len)
+    {
+      int st;
+      int pos = indexOf (i);
+      QByteArray baseEncoded = encodeName ();
+      if (stat (baseEncoded.d->data, &st) && stat (baseEncoded.d, &st))
+        return false;
+      i = pos;
+    }
+}
diff --git a/gcc/testsuite/gcc.target/ia64/pr43603.c b/gcc/testsuite/gcc.target/ia64/pr43603.c
new file mode 100644 (file)
index 0000000..ad3a5b1
--- /dev/null
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int 
+foo( long * np, int * dp, int qn)
+{
+  int i;
+  int n0;
+  int d0;
+  int a;
+  int b;
+  int c;
+  int d;
+
+  a = 1;
+  b = 0;
+  c = 1;
+  d = 1;
+
+  d0 = dp[0];
+
+  for (i = qn; i >= 0; i--) {
+    if (bar((c == 0)) && (np[1] == d0)) {
+      car(np - 3, dp, 3);
+    } else { 
+      __asm__ ("xma.hu %0 = %2, %3, f0\n\txma.l %1 = %2, %3, f0" : "=&f" ((a)), 
+"=f" (b) : "f" ((c)), "f" ((d))); 
+      n0 = np[0]; 
+      if (n0 < d0) 
+        c = 1; 
+      else 
+        c = 0; 
+
+    }
+    *--np = a;
+  }
+
+  return 0;
+}