From: Eric Botcazou Date: Mon, 18 Oct 2010 16:44:38 +0000 (+0000) Subject: tree-flow.h (gimple_purge_all_dead_abnormal_call_edges): Declare. X-Git-Tag: upstream/12.2.0~89259 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=30fd588162ce3286f388ae2f0e09a7a3637a9a23;p=platform%2Fupstream%2Fgcc.git tree-flow.h (gimple_purge_all_dead_abnormal_call_edges): Declare. * tree-flow.h (gimple_purge_all_dead_abnormal_call_edges): Declare. * tree-cfg.c (gimple_purge_dead_abnormal_call_edges): Move around and rewrite modelled on gimple_purge_dead_eh_edges. (gimple_purge_all_dead_abnormal_call_edges): New function. * tree-inline.c (expand_call_inline): Call gimple_purge_dead_eh_edges directly instead of through gimple_purge_dead_abnormal_call_edges. * tree-ssa-pre.c (need_ab_cleanup): New static variable. (eliminate): Set bit in need_ab_cleanup for the basic block if we have removed AB side-effects from one of its statements. (init_pre): Initialize need_ab_cleanup. (fini_pre): Purge dead abnormal call edges and clean up the CFG if bits are set in need_ab_cleanup. Free need_ab_cleanup afterward. From-SVN: r165646 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e409c9d..995c231 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2010-10-18 Eric Botcazou + + * tree-flow.h (gimple_purge_all_dead_abnormal_call_edges): Declare. + * tree-cfg.c (gimple_purge_dead_abnormal_call_edges): Move around and + rewrite modelled on gimple_purge_dead_eh_edges. + (gimple_purge_all_dead_abnormal_call_edges): New function. + * tree-inline.c (expand_call_inline): Call gimple_purge_dead_eh_edges + directly instead of through gimple_purge_dead_abnormal_call_edges. + * tree-ssa-pre.c (need_ab_cleanup): New static variable. + (eliminate): Set bit in need_ab_cleanup for the basic block if we have + removed AB side-effects from one of its statements. + (init_pre): Initialize need_ab_cleanup. + (fini_pre): Purge dead abnormal call edges and clean up the CFG if bits + are set in need_ab_cleanup. Free need_ab_cleanup afterward. + 2010-10-18 Jakub Jelinek PR c/46015 diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index d1ee63a..ff0c2ad 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -6824,39 +6824,6 @@ gimple_flow_call_edges_add (sbitmap blocks) return blocks_split; } -/* Purge dead abnormal call edges from basic block BB. */ - -bool -gimple_purge_dead_abnormal_call_edges (basic_block bb) -{ - bool changed = gimple_purge_dead_eh_edges (bb); - - if (cfun->has_nonlocal_label) - { - gimple stmt = last_stmt (bb); - edge_iterator ei; - edge e; - - if (!(stmt && stmt_can_make_abnormal_goto (stmt))) - for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) - { - if (e->flags & EDGE_ABNORMAL) - { - remove_edge (e); - changed = true; - } - else - ei_next (&ei); - } - - /* See gimple_purge_dead_eh_edges below. */ - if (changed) - free_dominance_info (CDI_DOMINATORS); - } - - return changed; -} - /* Removes edge E and all the blocks dominated by it, and updates dominance information. The IL in E->src needs to be updated separately. If dominance info is not available, only the edge E is removed.*/ @@ -7010,6 +6977,8 @@ gimple_purge_dead_eh_edges (basic_block bb) return changed; } +/* Purge dead EH edges from basic block listed in BLOCKS. */ + bool gimple_purge_all_dead_eh_edges (const_bitmap blocks) { @@ -7031,6 +7000,59 @@ gimple_purge_all_dead_eh_edges (const_bitmap blocks) return changed; } +/* Purge dead abnormal call edges from basic block BB. */ + +bool +gimple_purge_dead_abnormal_call_edges (basic_block bb) +{ + bool changed = false; + edge e; + edge_iterator ei; + gimple stmt = last_stmt (bb); + + if (!cfun->has_nonlocal_label) + return false; + + if (stmt && stmt_can_make_abnormal_goto (stmt)) + return false; + + for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) + { + if (e->flags & EDGE_ABNORMAL) + { + remove_edge_and_dominated_blocks (e); + changed = true; + } + else + ei_next (&ei); + } + + return changed; +} + +/* Purge dead abnormal call edges from basic block listed in BLOCKS. */ + +bool +gimple_purge_all_dead_abnormal_call_edges (const_bitmap blocks) +{ + bool changed = false; + unsigned i; + bitmap_iterator bi; + + EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i, bi) + { + basic_block bb = BASIC_BLOCK (i); + + /* Earlier gimple_purge_dead_abnormal_call_edges could have removed + this basic block already. */ + gcc_assert (bb || changed); + if (bb != NULL) + changed |= gimple_purge_dead_abnormal_call_edges (bb); + } + + return changed; +} + /* This function is called whenever a new edge is created or redirected. */ diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 85ad534..c2702dc 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -450,9 +450,10 @@ extern void gather_blocks_in_sese_region (basic_block entry, basic_block exit, VEC(basic_block,heap) **bbs_p); extern void add_phi_args_after_copy_bb (basic_block); extern void add_phi_args_after_copy (basic_block *, unsigned, edge); -extern bool gimple_purge_dead_abnormal_call_edges (basic_block); extern bool gimple_purge_dead_eh_edges (basic_block); extern bool gimple_purge_all_dead_eh_edges (const_bitmap); +extern bool gimple_purge_dead_abnormal_call_edges (basic_block); +extern bool gimple_purge_all_dead_abnormal_call_edges (const_bitmap); extern tree gimplify_build1 (gimple_stmt_iterator *, enum tree_code, tree, tree); extern tree gimplify_build2 (gimple_stmt_iterator *, enum tree_code, diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 5aa7bb0..133d916 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -4010,7 +4010,10 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id) } if (purge_dead_abnormal_edges) - gimple_purge_dead_abnormal_call_edges (return_block); + { + gimple_purge_dead_eh_edges (return_block); + gimple_purge_dead_abnormal_call_edges (return_block); + } /* If the value of the new expression is ignored, that's OK. We don't warn about this for CALL_EXPRs, so we shouldn't warn about diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 41d0542..d4d108d 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -484,10 +484,12 @@ static tree pretemp; static tree storetemp; static tree prephitemp; -/* Set of blocks with statements that have had its EH information - cleaned up. */ +/* Set of blocks with statements that have had their EH properties changed. */ static bitmap need_eh_cleanup; +/* Set of blocks with statements that have had their AB properties changed. */ +static bitmap need_ab_cleanup; + /* The phi_translate_table caches phi translations for a given expression and predecessor. */ @@ -4253,6 +4255,10 @@ eliminate (void) || TREE_CODE (rhs) != SSA_NAME || may_propagate_copy (rhs, sprime))) { + bool can_make_abnormal_goto + = is_gimple_call (stmt) + && stmt_can_make_abnormal_goto (stmt); + gcc_assert (sprime != rhs); if (dump_file && (dump_flags & TDF_DETAILS)) @@ -4281,14 +4287,24 @@ eliminate (void) stmt = gsi_stmt (gsi); update_stmt (stmt); - /* If we removed EH side effects from the statement, clean + /* If we removed EH side-effects from the statement, clean its EH information. */ if (maybe_clean_or_replace_eh_stmt (stmt, stmt)) { bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index); if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " Removed EH side effects.\n"); + fprintf (dump_file, " Removed EH side-effects.\n"); + } + + /* Likewise for AB side-effects. */ + if (can_make_abnormal_goto + && !stmt_can_make_abnormal_goto (stmt)) + { + bitmap_set_bit (need_ab_cleanup, + gimple_bb (stmt)->index); + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " Removed AB side-effects.\n"); } } } @@ -4345,13 +4361,16 @@ eliminate (void) } /* Visit indirect calls and turn them into direct calls if possible. */ - if (gimple_code (stmt) == GIMPLE_CALL + if (is_gimple_call (stmt) && TREE_CODE (gimple_call_fn (stmt)) == SSA_NAME) { tree fn = VN_INFO (gimple_call_fn (stmt))->valnum; if (TREE_CODE (fn) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL) { + bool can_make_abnormal_goto + = stmt_can_make_abnormal_goto (stmt); + if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Replacing call target with "); @@ -4362,12 +4381,25 @@ eliminate (void) gimple_call_set_fn (stmt, fn); update_stmt (stmt); + + /* If we removed EH side-effects from the statement, clean + its EH information. */ if (maybe_clean_or_replace_eh_stmt (stmt, stmt)) { bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index); if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " Removed EH side effects.\n"); + fprintf (dump_file, " Removed EH side-effects.\n"); + } + + /* Likewise for AB side-effects. */ + if (can_make_abnormal_goto + && !stmt_can_make_abnormal_goto (stmt)) + { + bitmap_set_bit (need_ab_cleanup, + gimple_bb (stmt)->index); + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " Removed AB side-effects.\n"); } /* Changing an indirect call to a direct call may @@ -4746,6 +4778,7 @@ init_pre (bool do_fre) } need_eh_cleanup = BITMAP_ALLOC (NULL); + need_ab_cleanup = BITMAP_ALLOC (NULL); } @@ -4777,6 +4810,14 @@ fini_pre (bool do_fre) BITMAP_FREE (need_eh_cleanup); + if (!bitmap_empty_p (need_ab_cleanup)) + { + gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup); + cleanup_tree_cfg (); + } + + BITMAP_FREE (need_ab_cleanup); + if (!do_fre) loop_optimizer_finalize (); }