From 36bbc05db8ef71811a7b925bbb862d0b1c3b5b89 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Mon, 22 Oct 2018 10:27:50 +0200 Subject: Add a fun parameter to three stmt_could_throw... functions This long patch only does one simple thing, adds an explicit function parameter to predicates stmt_could_throw_p, stmt_can_throw_external and stmt_can_throw_internal. My motivation was ability to use stmt_can_throw_external in IPA analysis phase without the need to push cfun. As I have discovered, we were already doing that in cgraph.c, which this patch avoids as well. In the process, I had to add a struct function parameter to stmt_could_throw_p and decided to also change the interface of stmt_can_throw_internal just for the sake of some minimal consistency. In the process I have discovered that calling method cgraph_node::create_version_clone_with_body (used by ipa-split, ipa-sra, OMP simd and multiple_target) leads to calls of stmt_can_throw_external with NULL cfun. I have worked around this by making stmt_can_throw_external and stmt_could_throw_p gracefully accept NULL and just be pessimistic in that case. The problem with fixing this in a better way is that struct function for the clone is created after cloning edges where we attempt to push the yet not existing cfun, and moving it before would require a bit of surgery in tree-inline.c. A slightly hackish but simpler fix might be to explicitely pass the "old" function to symbol_table::create_edge because it should be just as good at that moment. In any event, that is a topic for another patch. I believe that currently we incorrectly use cfun in maybe_clean_eh_stmt_fn and maybe_duplicate_eh_stmt_fn, both in tree-eh.c, and so I have fixed these cases too. The bulk of other changes is just mechanical adding of cfun to all users. Bootstrapped and tested on x86_64-linux (also with extra NULLing and restoring cfun to double check it is not used in a place I missed), OK for trunk? Thanks, Martin 2018-10-22 Martin Jambor * tree-eh.h (stmt_could_throw_p): Add function parameter. (stmt_can_throw_external): Likewise. (stmt_can_throw_internal): Likewise. * tree-eh.c (lower_eh_constructs_2): Pass cfun to stmt_could_throw_p. (lower_eh_constructs_2): Likewise. (stmt_could_throw_p): Add fun parameter, use it instead of cfun. (stmt_can_throw_external): Likewise. (stmt_can_throw_internal): Likewise. (maybe_clean_eh_stmt_fn): Pass cfun to stmt_could_throw_p. (maybe_clean_or_replace_eh_stmt): Pass cfun to stmt_could_throw_p. (maybe_duplicate_eh_stmt_fn): Pass new_fun to stmt_could_throw_p. (maybe_duplicate_eh_stmt): Pass cfun to stmt_could_throw_p. (pass_lower_eh_dispatch::execute): Pass cfun to stmt_can_throw_external. (cleanup_empty_eh): Likewise. (verify_eh_edges): Pass cfun to stmt_could_throw_p. * cgraph.c (cgraph_edge::set_call_stmt): Pass a function to stmt_can_throw_external instead of pushing it to cfun. (symbol_table::create_edge): Likewise. * gimple-fold.c (fold_builtin_atomic_compare_exchange): Pass cfun to stmt_can_throw_internal. * gimple-ssa-evrp.c (evrp_dom_walker::before_dom_children): Pass cfun to stmt_could_throw_p. * gimple-ssa-store-merging.c (handled_load): Pass cfun to stmt_can_throw_internal. (pass_store_merging::execute): Likewise. * gimple-ssa-strength-reduction.c (find_candidates_dom_walker::before_dom_children): Pass cfun to stmt_could_throw_p. * gimplify-me.c (gimple_regimplify_operands): Pass cfun to stmt_can_throw_internal. * ipa-pure-const.c (check_call): Pass cfun to stmt_could_throw_p and to stmt_can_throw_external. (check_stmt): Pass cfun to stmt_could_throw_p. (check_stmt): Pass cfun to stmt_can_throw_external. (pass_nothrow::execute): Likewise. * trans-mem.c (expand_call_tm): Pass cfun to stmt_can_throw_internal. * tree-cfg.c (is_ctrl_altering_stmt): Pass cfun to stmt_can_throw_internal. (verify_gimple_in_cfg): Pass cfun to stmt_could_throw_p. (stmt_can_terminate_bb_p): Pass cfun to stmt_can_throw_external. (gimple_purge_dead_eh_edges): Pass cfun to stmt_can_throw_internal. * tree-complex.c (expand_complex_libcall): Pass cfun to stmt_could_throw_p and to stmt_can_throw_internal. (expand_complex_multiplication): Pass cfun to stmt_can_throw_internal. * tree-inline.c (copy_edges_for_bb): Likewise. (maybe_move_debug_stmts_to_successors): Likewise. * tree-outof-ssa.c (ssa_is_replaceable_p): Pass cfun to stmt_could_throw_p. * tree-parloops.c (oacc_entry_exit_ok_1): Likewise. * tree-sra.c (scan_function): Pass cfun to stmt_can_throw_external. * tree-ssa-alias.c (stmt_kills_ref_p): Pass cfun to stmt_can_throw_internal. * tree-ssa-ccp.c (optimize_atomic_bit_test_and): Likewise. * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Pass cfun to stmt_could_throw_p. (mark_aliased_reaching_defs_necessary_1): Pass cfun to stmt_can_throw_internal. * tree-ssa-forwprop.c (pass_forwprop::execute): Likewise. * tree-ssa-loop-im.c (movement_possibility): Pass cfun to stmt_could_throw_p. * tree-ssa-loop-ivopts.c (find_givs_in_stmt_scev): Likewise. (add_autoinc_candidates): Pass cfun to stmt_can_throw_internal. * tree-ssa-math-opts.c (pass_cse_reciprocals::execute): Likewise. (convert_mult_to_fma_1): Likewise. (convert_to_divmod): Likewise. * tree-ssa-phiprop.c (propagate_with_phi): Likewise. * tree-ssa-pre.c (compute_avail): Pass cfun to stmt_could_throw_p. * tree-ssa-propagate.c (substitute_and_fold_dom_walker::before_dom_children): Likewise. * tree-ssa-reassoc.c (suitable_cond_bb): Likewise. (maybe_optimize_range_tests): Likewise. (linearize_expr_tree): Likewise. (reassociate_bb): Likewise. * tree-ssa-sccvn.c (copy_reference_ops_from_call): Likewise. * tree-ssa-scopedtables.c (hashable_expr_equal_p): Likewise. * tree-ssa-strlen.c (adjust_last_stmt): Likewise. (handle_char_store): Likewise. * tree-vect-data-refs.c (vect_find_stmt_data_reference): Pass cfun to stmt_can_throw_internal. * tree-vect-patterns.c (check_bool_pattern): Pass cfun to stmt_could_throw_p. * tree-vect-stmts.c (vect_finish_stmt_generation_1): Likewise. (vectorizable_call): Pass cfun to stmt_can_throw_internal. (vectorizable_simd_clone_call): Likewise. * value-prof.c (gimple_ic): Pass cfun to stmt_could_throw_p. (gimple_stringop_fixed_value): Likewise. From-SVN: r265372 --- gcc/tree-eh.c | 52 ++++++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 24 deletions(-) (limited to 'gcc/tree-eh.c') diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index fb931aa..1c7d9dc 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -2033,7 +2033,7 @@ lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi) available on the EH edge. Only do so for statements that potentially fall through (no noreturn calls e.g.), otherwise this new assignment might create fake fallthru regions. */ - if (stmt_could_throw_p (stmt) + if (stmt_could_throw_p (cfun, stmt) && gimple_has_lhs (stmt) && gimple_stmt_may_fallthru (stmt) && !tree_could_throw_p (gimple_get_lhs (stmt)) @@ -2051,7 +2051,7 @@ lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi) gsi_insert_after (gsi, s, GSI_SAME_STMT); } /* Look for things that can throw exceptions, and record them. */ - if (state->cur_region && stmt_could_throw_p (stmt)) + if (state->cur_region && stmt_could_throw_p (cfun, stmt)) { record_stmt_eh_region (state->cur_region, stmt); note_eh_region_may_contain_throw (state->cur_region); @@ -2866,10 +2866,10 @@ stmt_could_throw_1_p (gassign *stmt) } -/* Return true if statement STMT could throw an exception. */ +/* Return true if statement STMT within FUN could throw an exception. */ bool -stmt_could_throw_p (gimple *stmt) +stmt_could_throw_p (function *fun, gimple *stmt) { if (!flag_exceptions) return false; @@ -2886,7 +2886,7 @@ stmt_could_throw_p (gimple *stmt) case GIMPLE_COND: { - if (!cfun->can_throw_non_call_exceptions) + if (fun && !fun->can_throw_non_call_exceptions) return false; gcond *cond = as_a (stmt); tree lhs = gimple_cond_lhs (cond); @@ -2896,13 +2896,13 @@ stmt_could_throw_p (gimple *stmt) } case GIMPLE_ASSIGN: - if (!cfun->can_throw_non_call_exceptions + if ((fun && !fun->can_throw_non_call_exceptions) || gimple_clobber_p (stmt)) return false; return stmt_could_throw_1_p (as_a (stmt)); case GIMPLE_ASM: - if (!cfun->can_throw_non_call_exceptions) + if (fun && !fun->can_throw_non_call_exceptions) return false; return gimple_asm_volatile_p (as_a (stmt)); @@ -2936,33 +2936,37 @@ tree_could_throw_p (tree t) return false; } -/* Return true if STMT can throw an exception that is not caught within - the current function (CFUN). */ +/* Return true if STMT can throw an exception that is not caught within its + function FUN. FUN can be NULL but the function is extra conservative + then. */ bool -stmt_can_throw_external (gimple *stmt) +stmt_can_throw_external (function *fun, gimple *stmt) { int lp_nr; - if (!stmt_could_throw_p (stmt)) + if (!stmt_could_throw_p (fun, stmt)) return false; + if (!fun) + return true; - lp_nr = lookup_stmt_eh_lp (stmt); + lp_nr = lookup_stmt_eh_lp_fn (fun, stmt); return lp_nr == 0; } -/* Return true if STMT can throw an exception that is caught within - the current function (CFUN). */ +/* Return true if STMT can throw an exception that is caught within its + function FUN. */ bool -stmt_can_throw_internal (gimple *stmt) +stmt_can_throw_internal (function *fun, gimple *stmt) { int lp_nr; - if (!stmt_could_throw_p (stmt)) + gcc_checking_assert (fun); + if (!stmt_could_throw_p (fun, stmt)) return false; - lp_nr = lookup_stmt_eh_lp (stmt); + lp_nr = lookup_stmt_eh_lp_fn (fun, stmt); return lp_nr > 0; } @@ -2973,7 +2977,7 @@ stmt_can_throw_internal (gimple *stmt) bool maybe_clean_eh_stmt_fn (struct function *ifun, gimple *stmt) { - if (stmt_could_throw_p (stmt)) + if (stmt_could_throw_p (ifun, stmt)) return false; return remove_stmt_from_eh_lp_fn (ifun, stmt); } @@ -2998,7 +3002,7 @@ maybe_clean_or_replace_eh_stmt (gimple *old_stmt, gimple *new_stmt) if (lp_nr != 0) { - bool new_stmt_could_throw = stmt_could_throw_p (new_stmt); + bool new_stmt_could_throw = stmt_could_throw_p (cfun, new_stmt); if (new_stmt == old_stmt && new_stmt_could_throw) return false; @@ -3028,7 +3032,7 @@ maybe_duplicate_eh_stmt_fn (struct function *new_fun, gimple *new_stmt, { int old_lp_nr, new_lp_nr; - if (!stmt_could_throw_p (new_stmt)) + if (!stmt_could_throw_p (new_fun, new_stmt)) return false; old_lp_nr = lookup_stmt_eh_lp_fn (old_fun, old_stmt); @@ -3067,7 +3071,7 @@ maybe_duplicate_eh_stmt (gimple *new_stmt, gimple *old_stmt) { int lp_nr; - if (!stmt_could_throw_p (new_stmt)) + if (!stmt_could_throw_p (cfun, new_stmt)) return false; lp_nr = lookup_stmt_eh_lp (old_stmt); @@ -3862,7 +3866,7 @@ pass_lower_eh_dispatch::execute (function *fun) } else if (gimple_code (last) == GIMPLE_RESX) { - if (stmt_can_throw_external (last)) + if (stmt_can_throw_external (cfun, last)) optimize_clobbers (bb); else flags |= sink_clobbers (bb); @@ -4502,7 +4506,7 @@ cleanup_empty_eh (eh_landing_pad lp) resx = gsi_stmt (gsi); if (resx && is_gimple_resx (resx)) { - if (stmt_can_throw_external (resx)) + if (stmt_can_throw_external (cfun, resx)) optimize_clobbers (bb); else if (sink_clobbers (bb)) ret = true; @@ -4783,7 +4787,7 @@ verify_eh_edges (gimple *stmt) return false; } - if (!stmt_could_throw_p (stmt)) + if (!stmt_could_throw_p (cfun, stmt)) { error ("BB %i last statement has incorrectly set lp", bb->index); return true; -- cgit v1.1