aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2014-01-29 12:02:46 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2014-01-29 12:02:46 +0100
commit09b22f48d435d158761a02117facec4daa7395fb (patch)
tree4b721b57c74c1349afc462b869e17ae0bdb8fa90 /gcc/tree-inline.c
parent42eb8bd17982621ad29ec491053851fd2d0d740e (diff)
downloadgcc-09b22f48d435d158761a02117facec4daa7395fb.zip
gcc-09b22f48d435d158761a02117facec4daa7395fb.tar.gz
gcc-09b22f48d435d158761a02117facec4daa7395fb.tar.bz2
re PR middle-end/59917 (ICE in calc_dfs_tree, at dominance.c:401)
PR middle-end/59917 PR tree-optimization/59920 * tree.c (build_common_builtin_nodes): Remove __builtin_setjmp_dispatcher initialization. * omp-low.h (make_gimple_omp_edges): Add a new int * argument. * profile.c (branch_prob): Use gsi_start_nondebug_after_labels_bb instead of gsi_after_labels + manually skipping debug stmts. Don't ignore bbs with BUILT_IN_SETJMP_DISPATCHER, instead ignore bbs with IFN_ABNORMAL_DISPATCHER. * tree-inline.c (copy_edges_for_bb): Remove can_make_abnormal_goto argument, instead add abnormal_goto_dest argument. Ignore computed_goto_p stmts. Don't call make_abnormal_goto_edges. If a call might need abnormal edges for non-local gotos, see if it already has an edge to IFN_ABNORMAL_DISPATCHER or if it is IFN_ABNORMAL_DISPATCHER with true argument, don't do anything then, otherwise add EDGE_ABNORMAL from the call's bb to abnormal_goto_dest. (copy_cfg_body): Compute abnormal_goto_dest, adjust copy_edges_for_bb caller. * gimple-low.c (struct lower_data): Remove calls_builtin_setjmp. (lower_function_body): Don't emit __builtin_setjmp_dispatcher. (lower_stmt): Don't set data->calls_builtin_setjmp. (lower_builtin_setjmp): Adjust comment. * builtins.def (BUILT_IN_SETJMP_DISPATCHER): Remove. * tree-cfg.c (found_computed_goto): Remove. (factor_computed_gotos): Remove. (make_goto_expr_edges): Return bool, true for computed gotos. Don't call make_abnormal_goto_edges. (build_gimple_cfg): Don't set found_computed_goto, don't call factor_computed_gotos. (computed_goto_p): No longer static. (make_blocks): Don't set found_computed_goto. (get_abnormal_succ_dispatcher, handle_abnormal_edges): New functions. (make_edges): If make_goto_expr_edges returns true, push bb into ab_edge_goto vector, for stmt_can_make_abnormal_goto calls instead of calling make_abnormal_goto_edges push bb into ab_edge_call vector. Record mapping between bbs and OpenMP regions if there are any, adjust make_gimple_omp_edges caller. Call handle_abnormal_edges. (make_abnormal_goto_edges): Remove. * tree-cfg.h (make_abnormal_goto_edges): Remove. (computed_goto_p, get_abnormal_succ_dispatcher): New prototypes. * internal-fn.c (expand_ABNORMAL_DISPATCHER): New function. * builtins.c (expand_builtin): Don't handle BUILT_IN_SETJMP_DISPATCHER. * internal-fn.def (ABNORMAL_DISPATCHER): New. * omp-low.c (make_gimple_omp_edges): Add region_idx argument, when filling *region also set *region_idx to (*region)->entry->index. * gcc.dg/pr59920-1.c: New test. * gcc.dg/pr59920-2.c: New test. * gcc.dg/pr59920-3.c: New test. * c-c++-common/gomp/pr59917-1.c: New test. * c-c++-common/gomp/pr59917-2.c: New test. From-SVN: r207231
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r--gcc/tree-inline.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index a3175b3..79a39bc 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1967,7 +1967,7 @@ update_ssa_across_abnormal_edges (basic_block bb, basic_block ret_bb,
static bool
copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb,
- bool can_make_abnormal_goto)
+ basic_block abnormal_goto_dest)
{
basic_block new_bb = (basic_block) bb->aux;
edge_iterator ei;
@@ -2021,7 +2021,9 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb,
into a COMPONENT_REF which doesn't. If the copy
can throw, the original could also throw. */
can_throw = stmt_can_throw_internal (copy_stmt);
- nonlocal_goto = stmt_can_make_abnormal_goto (copy_stmt);
+ nonlocal_goto
+ = (stmt_can_make_abnormal_goto (copy_stmt)
+ && !computed_goto_p (copy_stmt));
if (can_throw || nonlocal_goto)
{
@@ -2052,9 +2054,26 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb,
/* If the call we inline cannot make abnormal goto do not add
additional abnormal edges but only retain those already present
in the original function body. */
- nonlocal_goto &= can_make_abnormal_goto;
+ if (abnormal_goto_dest == NULL)
+ nonlocal_goto = false;
if (nonlocal_goto)
- make_abnormal_goto_edges (gimple_bb (copy_stmt), true);
+ {
+ basic_block copy_stmt_bb = gimple_bb (copy_stmt);
+
+ if (get_abnormal_succ_dispatcher (copy_stmt_bb))
+ nonlocal_goto = false;
+ /* ABNORMAL_DISPATCHER (1) is for longjmp/setjmp or nonlocal gotos
+ in OpenMP regions which aren't allowed to be left abnormally.
+ So, no need to add abnormal edge in that case. */
+ else if (is_gimple_call (copy_stmt)
+ && gimple_call_internal_p (copy_stmt)
+ && (gimple_call_internal_fn (copy_stmt)
+ == IFN_ABNORMAL_DISPATCHER)
+ && gimple_call_arg (copy_stmt, 0) == boolean_true_node)
+ nonlocal_goto = false;
+ else
+ make_edge (copy_stmt_bb, abnormal_goto_dest, EDGE_ABNORMAL);
+ }
if ((can_throw || nonlocal_goto)
&& gimple_in_ssa_p (cfun))
@@ -2493,13 +2512,22 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
last = last_basic_block_for_fn (cfun);
/* Now that we've duplicated the blocks, duplicate their edges. */
- bool can_make_abormal_goto
- = id->gimple_call && stmt_can_make_abnormal_goto (id->gimple_call);
+ basic_block abnormal_goto_dest = NULL;
+ if (id->gimple_call
+ && stmt_can_make_abnormal_goto (id->gimple_call))
+ {
+ gimple_stmt_iterator gsi = gsi_for_stmt (id->gimple_call);
+
+ bb = gimple_bb (id->gimple_call);
+ gsi_next (&gsi);
+ if (gsi_end_p (gsi))
+ abnormal_goto_dest = get_abnormal_succ_dispatcher (bb);
+ }
FOR_ALL_BB_FN (bb, cfun_to_copy)
if (!id->blocks_to_copy
|| (bb->index > 0 && bitmap_bit_p (id->blocks_to_copy, bb->index)))
need_debug_cleanup |= copy_edges_for_bb (bb, count_scale, exit_block_map,
- can_make_abormal_goto);
+ abnormal_goto_dest);
if (new_entry)
{