OSDN Git Service

Update my e-mail address for new employer.
[pf3gnuchains/gcc-fork.git] / gcc / cfgrtl.c
index 4aaedbe..4abb8a1 100644 (file)
@@ -85,8 +85,8 @@ static void rtl_make_forwarder_block (edge);
 static int
 can_delete_note_p (rtx note)
 {
-  return (NOTE_LINE_NUMBER (note) == NOTE_INSN_DELETED
-         || NOTE_LINE_NUMBER (note) == NOTE_INSN_BASIC_BLOCK);
+  return (NOTE_KIND (note) == NOTE_INSN_DELETED
+         || NOTE_KIND (note) == NOTE_INSN_BASIC_BLOCK);
 }
 
 /* True if a given label can be deleted.  */
@@ -120,7 +120,7 @@ delete_insn (rtx insn)
 
          really_delete = false;
          PUT_CODE (insn, NOTE);
-         NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED_LABEL;
+         NOTE_KIND (insn) = NOTE_INSN_DELETED_LABEL;
          NOTE_DELETED_LABEL_NAME (insn) = name;
        }
 
@@ -580,7 +580,7 @@ rtl_merge_blocks (basic_block a, basic_block b)
 
       for (prev = PREV_INSN (a_end); ; prev = PREV_INSN (prev))
        if (!NOTE_P (prev)
-           || NOTE_LINE_NUMBER (prev) == NOTE_INSN_BASIC_BLOCK
+           || NOTE_INSN_BASIC_BLOCK_P (prev)
            || prev == BB_HEAD (a))
          break;
 
@@ -728,7 +728,8 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout)
      the cc0 setter too.  */
   kill_from = insn;
 #ifdef HAVE_cc0
-  if (reg_mentioned_p (cc0_rtx, PATTERN (insn)))
+  if (reg_mentioned_p (cc0_rtx, PATTERN (insn))
+      && only_sets_cc0_p (PREV_INSN (insn)))
     kill_from = PREV_INSN (insn);
 #endif
 
@@ -1407,8 +1408,7 @@ commit_one_edge_insertion (edge e)
              bb_note = NULL_RTX;
              for (cur_insn = BB_HEAD (bb); cur_insn != NEXT_INSN (BB_END (bb));
                   cur_insn = NEXT_INSN (cur_insn))
-               if (NOTE_P (cur_insn)
-                   && NOTE_LINE_NUMBER (cur_insn) == NOTE_INSN_BASIC_BLOCK)
+               if (NOTE_INSN_BASIC_BLOCK_P (cur_insn))
                  {
                    bb_note = cur_insn;
                    break;
@@ -1715,12 +1715,6 @@ rtl_verify_flow_info_1 (void)
                   bb->index);
            err = 1;
          }
-
-      if (bb->predictions)
-       {
-         error ("bb prediction set for block %d, but it is not used in RTL land", bb->index);
-         err = 1;
-       }
     }
 
   /* Now check the basic blocks (boundaries etc.) */
@@ -1974,8 +1968,7 @@ rtl_verify_flow_info (void)
          for (insn = BB_END (bb); !insn || !BARRIER_P (insn);
               insn = NEXT_INSN (insn))
            if (!insn
-               || (NOTE_P (insn)
-                   && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK))
+               || NOTE_INSN_BASIC_BLOCK_P (insn))
                {
                  error ("missing barrier after block %i", bb->index);
                  err = 1;
@@ -2518,10 +2511,11 @@ cfg_layout_can_merge_blocks_p (basic_block a, basic_block b)
          /* Must be simple edge.  */
          && !(single_succ_edge (a)->flags & EDGE_COMPLEX)
          && a != ENTRY_BLOCK_PTR && b != EXIT_BLOCK_PTR
-         /* If the jump insn has side effects,
-            we can't kill the edge.  */
+         /* If the jump insn has side effects, we can't kill the edge.
+            When not optimizing, try_redirect_by_replacing_jump will
+            not allow us to redirect an edge by replacing a table jump.  */
          && (!JUMP_P (BB_END (a))
-             || (reload_completed
+             || ((!optimize || reload_completed)
                  ? simplejump_p (BB_END (a)) : onlyjump_p (BB_END (a)))));
 }
 
@@ -2976,6 +2970,38 @@ insert_insn_end_bb_new (rtx pat, basic_block bb)
   return new_insn;
 }
 
+/* Returns true if it is possible to remove edge E by redirecting
+   it to the destination of the other edge from E->src.  */
+
+static bool
+rtl_can_remove_branch_p (edge e)
+{
+  basic_block src = e->src;
+  basic_block target = EDGE_SUCC (src, EDGE_SUCC (src, 0) == e)->dest;
+  rtx insn = BB_END (src), set;
+
+  /* The conditions are taken from try_redirect_by_replacing_jump.  */
+  if (target == EXIT_BLOCK_PTR)
+    return false;
+
+  if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
+    return false;
+
+  if (find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)
+      || BB_PARTITION (src) != BB_PARTITION (target))
+    return false;
+
+  if (!onlyjump_p (insn)
+      || tablejump_p (insn, NULL, NULL))
+    return false;
+
+  set = single_set (insn);
+  if (!set || side_effects_p (set))
+    return false;
+
+  return true;
+}
+
 /* Implementation of CFG manipulation for linearized RTL.  */
 struct cfg_hooks rtl_cfg_hooks = {
   "rtl",
@@ -2984,6 +3010,7 @@ struct cfg_hooks rtl_cfg_hooks = {
   rtl_create_basic_block,
   rtl_redirect_edge_and_branch,
   rtl_redirect_edge_and_branch_force,
+  rtl_can_remove_branch_p,
   rtl_delete_block,
   rtl_split_block,
   rtl_move_block_after,
@@ -3027,6 +3054,7 @@ struct cfg_hooks cfg_layout_rtl_cfg_hooks = {
   cfg_layout_create_basic_block,
   cfg_layout_redirect_edge_and_branch,
   cfg_layout_redirect_edge_and_branch_force,
+  rtl_can_remove_branch_p,
   cfg_layout_delete_block,
   cfg_layout_split_block,
   rtl_move_block_after,