OSDN Git Service

Tweak ABI & add moxie-uclinux target.
[pf3gnuchains/gcc-fork.git] / gcc / cfgcleanup.c
index 8b9756d..c631907 100644 (file)
@@ -483,7 +483,7 @@ try_forward_edges (int mode, basic_block b)
                     blocks with different locus are not optimized out.  */
                  int locus = single_succ_edge (target)->goto_locus;
 
-                 if (locus && goto_locus && locus != goto_locus)
+                 if (locus && goto_locus && !locator_eq (locus, goto_locus))
                    counter = n_basic_blocks;
                  else if (locus)
                    goto_locus = locus;
@@ -492,7 +492,8 @@ try_forward_edges (int mode, basic_block b)
                    {
                      locus = INSN_LOCATOR (BB_END (target));
 
-                     if (locus && goto_locus && locus != goto_locus)
+                     if (locus && goto_locus
+                         && !locator_eq (locus, goto_locus))
                        counter = n_basic_blocks;
                      else if (locus)
                        goto_locus = locus;
@@ -952,7 +953,12 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
   if (GET_CODE (i1) != GET_CODE (i2))
     return false;
 
-  p1 = PATTERN (i1);
+  /* __builtin_unreachable() may lead to empty blocks (ending with
+     NOTE_INSN_BASIC_BLOCK).  They may be crossjumped. */
+  if (NOTE_INSN_BASIC_BLOCK_P (i1) && NOTE_INSN_BASIC_BLOCK_P (i2))
+    return true;
+
+   p1 = PATTERN (i1);
   p2 = PATTERN (i2);
 
   if (GET_CODE (p1) != GET_CODE (p2))
@@ -1008,40 +1014,6 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
       ? rtx_renumbered_equal_p (p1, p2) : rtx_equal_p (p1, p2))
     return true;
 
-  /* Do not do EQUIV substitution after reload.  First, we're undoing the
-     work of reload_cse.  Second, we may be undoing the work of the post-
-     reload splitting pass.  */
-  /* ??? Possibly add a new phase switch variable that can be used by
-     targets to disallow the troublesome insns after splitting.  */
-  if (!reload_completed)
-    {
-      /* The following code helps take care of G++ cleanups.  */
-      rtx equiv1 = find_reg_equal_equiv_note (i1);
-      rtx equiv2 = find_reg_equal_equiv_note (i2);
-
-      if (equiv1 && equiv2
-         /* If the equivalences are not to a constant, they may
-            reference pseudos that no longer exist, so we can't
-            use them.  */
-         && (! reload_completed
-             || (CONSTANT_P (XEXP (equiv1, 0))
-                 && rtx_equal_p (XEXP (equiv1, 0), XEXP (equiv2, 0)))))
-       {
-         rtx s1 = single_set (i1);
-         rtx s2 = single_set (i2);
-         if (s1 != 0 && s2 != 0
-             && rtx_renumbered_equal_p (SET_DEST (s1), SET_DEST (s2)))
-           {
-             validate_change (i1, &SET_SRC (s1), XEXP (equiv1, 0), 1);
-             validate_change (i2, &SET_SRC (s2), XEXP (equiv2, 0), 1);
-             if (! rtx_renumbered_equal_p (p1, p2))
-               cancel_changes (0);
-             else if (apply_change_group ())
-               return true;
-           }
-       }
-    }
-
   return false;
 }
 \f
@@ -1671,8 +1643,7 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
   /* Skip possible basic block header.  */
   if (LABEL_P (newpos1))
     newpos1 = NEXT_INSN (newpos1);
-
-  if (NOTE_P (newpos1))
+  if (NOTE_INSN_BASIC_BLOCK_P (newpos1))
     newpos1 = NEXT_INSN (newpos1);
 
   redirect_from = split_block (src1, PREV_INSN (newpos1))->src;
@@ -1873,8 +1844,18 @@ try_optimize_cfg (int mode)
              edge s;
              bool changed_here = false;
 
-             /* Delete trivially dead basic blocks.  */
-             if (EDGE_COUNT (b->preds) == 0)
+             /* Delete trivially dead basic blocks.  This is either
+                blocks with no predecessors, or empty blocks with no
+                successors.  However if the empty block with no
+                successors is the successor of the ENTRY_BLOCK, it is
+                kept.  This ensures that the ENTRY_BLOCK will have a
+                successor which is a precondition for many RTL
+                passes.  Empty blocks may result from expanding
+                __builtin_unreachable ().  */
+             if (EDGE_COUNT (b->preds) == 0
+                 || (EDGE_COUNT (b->succs) == 0
+                     && BB_HEAD (b) == BB_END (b)
+                     && single_succ_edge (ENTRY_BLOCK_PTR)->dest != b))
                {
                  c = b->prev_bb;
                  if (dump_file)
@@ -1946,6 +1927,7 @@ try_optimize_cfg (int mode)
                  delete_basic_block (b);
                  changed = true;
                  b = c;
+                 continue;
                }
 
              if (single_succ_p (b)
@@ -2094,9 +2076,7 @@ delete_dead_jumptables (void)
          next = NEXT_INSN (insn);
          if (LABEL_P (insn)
              && LABEL_NUSES (insn) == LABEL_PRESERVE_P (insn)
-             && JUMP_P (next)
-             && (GET_CODE (PATTERN (next)) == ADDR_VEC
-                 || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
+             && JUMP_TABLE_DATA_P (next))
            {
              rtx label = insn, jump = next;
 
@@ -2197,8 +2177,6 @@ cleanup_cfg (int mode)
 static unsigned int
 rest_of_handle_jump (void)
 {
-  delete_unreachable_blocks ();
-
   if (crtl->tail_call_emit)
     fixup_tail_calls ();
   return 0;