OSDN Git Service

* cfgcleanup.c (label_is_jump_target_p): New function.
authordanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 10 Dec 2001 01:09:42 +0000 (01:09 +0000)
committerdanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 10 Dec 2001 01:09:42 +0000 (01:09 +0000)
(try_optimize_cfg): Use label_is_jump_target_p to check if label is
target of a JUMP_INSN from the preceding block.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@47825 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cfgcleanup.c

index 73f05ef..9c3dcda 100644 (file)
@@ -1,3 +1,9 @@
+2001-12-09  Richard Henderson  <rth@redhat.com>
+
+       * cfgcleanup.c (label_is_jump_target_p): New function.
+       (try_optimize_cfg): Use label_is_jump_target_p to check if label is
+       target of a JUMP_INSN from the preceding block.
+
 Sun Dec  9 18:40:07 2001  Douglas B. Rupp  <rupp@gnat.com>
 
        * vmsdbgout.c (lookup_filename): Assign null string instead
index 28f3a1f..526202a 100644 (file)
@@ -69,6 +69,7 @@ static int flow_find_cross_jump               PARAMS ((int, basic_block, basic_block,
                                                 rtx *, rtx *));
 
 static bool delete_unreachable_blocks  PARAMS ((void));
+static bool label_is_jump_target_p     PARAMS ((rtx, rtx));
 static bool tail_recursion_label_p     PARAMS ((rtx));
 static void merge_blocks_move_predecessor_nojumps PARAMS ((basic_block,
                                                          basic_block));
@@ -291,6 +292,38 @@ try_forward_edges (mode, b)
   return changed;
 }
 \f
+/* Return true if LABEL is a target of JUMP_INSN.  This applies only
+   to non-complex jumps.  That is, direct unconditional, conditional,
+   and tablejumps, but not computed jumps or returns.  It also does
+   not apply to the fallthru case of a conditional jump.  */
+
+static bool
+label_is_jump_target_p (label, jump_insn)
+     rtx label, jump_insn;
+{
+  rtx tmp = JUMP_LABEL (jump_insn);
+
+  if (label == tmp)
+    return true;
+
+  if (tmp != NULL_RTX
+      && (tmp = NEXT_INSN (tmp)) != NULL_RTX
+      && GET_CODE (tmp) == JUMP_INSN
+      && (tmp = PATTERN (tmp),
+         GET_CODE (tmp) == ADDR_VEC
+         || GET_CODE (tmp) == ADDR_DIFF_VEC))
+    {
+      rtvec vec = XVEC (tmp, GET_CODE (tmp) == ADDR_DIFF_VEC);
+      int i, veclen = GET_NUM_ELEM (vec);
+
+      for (i = 0; i < veclen; ++i)
+       if (XEXP (RTVEC_ELT (vec, i), 0) == label)
+         return true;
+    }
+
+  return false;
+}
+
 /* Return true if LABEL is used for tail recursion.  */
 
 static bool
@@ -1162,10 +1195,14 @@ try_optimize_cfg (mode)
              && GET_CODE (b->head) == CODE_LABEL
              && (!(mode & CLEANUP_PRE_SIBCALL)
                  || !tail_recursion_label_p (b->head))
-             /* If previous block ends with condjump jumping to next BB,
-                we can't delete the label.  */
+             /* If the previous block ends with a branch to this block,
+                we can't delete the label.  Normally this is a condjump
+                that is yet to be simplified, but if CASE_DROPS_THRU,
+                this can be a tablejump with some element going to the
+                same place as the default (fallthru).  */
              && (b->pred->src == ENTRY_BLOCK_PTR
-                 || !reg_mentioned_p (b->head, b->pred->src->end)))
+                 || GET_CODE (b->pred->src->end) != JUMP_INSN
+                 || ! label_is_jump_target_p (b->head, b->pred->src->end)))
            {
              rtx label = b->head;
              b->head = NEXT_INSN (b->head);