From 09b22f48d435d158761a02117facec4daa7395fb Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 29 Jan 2014 12:02:46 +0100 Subject: 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 --- gcc/tree-inline.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) (limited to 'gcc/tree-inline.c') 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) { -- cgit v1.1