From: Richard Henderson Date: Mon, 10 Dec 2001 01:09:42 +0000 (-0800) Subject: cfgcleanup.c (label_is_jump_target_p): New function. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ec10f7c7036edcb58649048bef39ade57fc12594;p=gcc.git cfgcleanup.c (label_is_jump_target_p): New function. * 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. From-SVN: r47825 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 73f05efcd22..9c3dcdab4c0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2001-12-09 Richard Henderson + + * 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 * vmsdbgout.c (lookup_filename): Assign null string instead diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index 28f3a1fb0c8..526202a3f32 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -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; } +/* 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);