diff options
author | Martin Jambor <mjambor@suse.cz> | 2018-10-22 10:27:50 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2018-10-22 10:27:50 +0200 |
commit | 36bbc05db8ef71811a7b925bbb862d0b1c3b5b89 (patch) | |
tree | c7ed4a03002467a31c3a0cf10bca6c5d06b40338 /gcc/tree-eh.c | |
parent | 3703b60c903e1cb7629c1a51cda68e53ebd8fbe8 (diff) | |
download | gcc-36bbc05db8ef71811a7b925bbb862d0b1c3b5b89.zip gcc-36bbc05db8ef71811a7b925bbb862d0b1c3b5b89.tar.gz gcc-36bbc05db8ef71811a7b925bbb862d0b1c3b5b89.tar.bz2 |
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 <mjambor@suse.cz>
* 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
Diffstat (limited to 'gcc/tree-eh.c')
-rw-r--r-- | gcc/tree-eh.c | 52 |
1 files changed, 28 insertions, 24 deletions
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 <gcond *> (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 <gassign *> (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 <gasm *> (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; |