Message ID | ri6ftx0crye.fsf@suse.cz |
---|---|
State | New |
Headers | show |
Series | Add a fun parameter to three stmt_could_throw... functions | expand |
On Sat, 20 Oct 2018, Martin Jambor wrote: > Hi, > > 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. I think that's the best and reasonable thing to do. > In any event, that > is a topic for another patch. Fine with me - handling NULL fn conservatively is OK. > I believe that currently we incorrectly implicitly 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? OK. Thanks, Richard. > Thanks, > > Martin > > 2018-10-20 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. > --- > gcc/cgraph.c | 10 +++--- > gcc/gimple-fold.c | 2 +- > gcc/gimple-ssa-evrp.c | 2 +- > gcc/gimple-ssa-store-merging.c | 4 +-- > gcc/gimple-ssa-strength-reduction.c | 2 +- > gcc/gimplify-me.c | 2 +- > gcc/ipa-pure-const.c | 10 +++--- > gcc/trans-mem.c | 2 +- > gcc/tree-cfg.c | 8 ++--- > gcc/tree-complex.c | 6 ++-- > gcc/tree-eh.c | 52 ++++++++++++++++------------- > gcc/tree-eh.h | 6 ++-- > gcc/tree-inline.c | 4 +-- > gcc/tree-outof-ssa.c | 2 +- > gcc/tree-parloops.c | 2 +- > gcc/tree-sra.c | 2 +- > gcc/tree-ssa-alias.c | 2 +- > gcc/tree-ssa-ccp.c | 2 +- > gcc/tree-ssa-dce.c | 4 +-- > gcc/tree-ssa-forwprop.c | 2 +- > gcc/tree-ssa-loop-im.c | 2 +- > gcc/tree-ssa-loop-ivopts.c | 4 +-- > gcc/tree-ssa-math-opts.c | 11 +++--- > gcc/tree-ssa-phiprop.c | 2 +- > gcc/tree-ssa-pre.c | 2 +- > gcc/tree-ssa-propagate.c | 2 +- > gcc/tree-ssa-reassoc.c | 10 +++--- > gcc/tree-ssa-sccvn.c | 2 +- > gcc/tree-ssa-scopedtables.c | 2 +- > gcc/tree-ssa-strlen.c | 4 +-- > gcc/tree-vect-data-refs.c | 2 +- > gcc/tree-vect-patterns.c | 2 +- > gcc/tree-vect-stmts.c | 6 ++-- > gcc/value-prof.c | 8 ++--- > 34 files changed, 94 insertions(+), 91 deletions(-) > > diff --git a/gcc/cgraph.c b/gcc/cgraph.c > index 8a03f3d6828..48bab9f2749 100644 > --- a/gcc/cgraph.c > +++ b/gcc/cgraph.c > @@ -815,9 +815,8 @@ cgraph_edge::set_call_stmt (gcall *new_stmt, bool update_speculative) > e = make_direct (new_callee); > } > > - push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl)); > - e->can_throw_external = stmt_can_throw_external (new_stmt); > - pop_cfun (); > + function *fun = DECL_STRUCT_FUNCTION (e->caller->decl); > + e->can_throw_external = stmt_can_throw_external (fun, new_stmt); > if (e->caller->call_site_hash) > cgraph_add_edge_to_call_site_hash (e); > } > @@ -870,10 +869,9 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee, > edge->count = count; > > edge->call_stmt = call_stmt; > - push_cfun (DECL_STRUCT_FUNCTION (caller->decl)); > edge->can_throw_external > - = call_stmt ? stmt_can_throw_external (call_stmt) : false; > - pop_cfun (); > + = call_stmt ? stmt_can_throw_external (DECL_STRUCT_FUNCTION (caller->decl), > + call_stmt) : false; > if (call_stmt > && callee && callee->decl > && !gimple_check_call_matching_types (call_stmt, callee->decl, > diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c > index fe6bc08bdd9..e862b1a1d4c 100644 > --- a/gcc/gimple-fold.c > +++ b/gcc/gimple-fold.c > @@ -4023,7 +4023,7 @@ fold_builtin_atomic_compare_exchange (gimple_stmt_iterator *gsi) > gimple_set_vuse (g, gimple_vuse (stmt)); > SSA_NAME_DEF_STMT (gimple_vdef (g)) = g; > tree oldlhs = gimple_call_lhs (stmt); > - if (stmt_can_throw_internal (stmt)) > + if (stmt_can_throw_internal (cfun, stmt)) > { > throws = true; > e = find_fallthru_edge (gsi_bb (*gsi)->succs); > diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c > index 50e8adc1aad..7d952765c5a 100644 > --- a/gcc/gimple-ssa-evrp.c > +++ b/gcc/gimple-ssa-evrp.c > @@ -164,7 +164,7 @@ evrp_dom_walker::before_dom_children (basic_block bb) > if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE) > && (val = value_range_constant_singleton (vr)) > && may_propagate_copy (output, val) > - && !stmt_could_throw_p (stmt) > + && !stmt_could_throw_p (cfun, stmt) > && !gimple_has_side_effects (stmt)) > { > stmts_to_remove.safe_push (stmt); > diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c > index 85dd5bccead..e1ddcb5e558 100644 > --- a/gcc/gimple-ssa-store-merging.c > +++ b/gcc/gimple-ssa-store-merging.c > @@ -4256,7 +4256,7 @@ handled_load (gimple *stmt, store_operand_info *op, > } > if (gimple_vuse (stmt) > && gimple_assign_load_p (stmt) > - && !stmt_can_throw_internal (stmt) > + && !stmt_can_throw_internal (cfun, stmt) > && !gimple_has_volatile_ops (stmt)) > { > tree mem = gimple_assign_rhs1 (stmt); > @@ -4551,7 +4551,7 @@ pass_store_merging::execute (function *fun) > } > > if (gimple_assign_single_p (stmt) && gimple_vdef (stmt) > - && !stmt_can_throw_internal (stmt) > + && !stmt_can_throw_internal (cfun, stmt) > && lhs_valid_for_store_merging_p (gimple_assign_lhs (stmt))) > process_store (stmt); > else > diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c > index ea81adca7ea..7ed6ae7f88a 100644 > --- a/gcc/gimple-ssa-strength-reduction.c > +++ b/gcc/gimple-ssa-strength-reduction.c > @@ -1775,7 +1775,7 @@ find_candidates_dom_walker::before_dom_children (basic_block bb) > { > gimple *gs = gsi_stmt (gsi); > > - if (stmt_could_throw_p (gs)) > + if (stmt_could_throw_p (cfun, gs)) > continue; > > if (gimple_vuse (gs) && gimple_assign_single_p (gs)) > diff --git a/gcc/gimplify-me.c b/gcc/gimplify-me.c > index 137a5662ccf..269fe6b3bae 100644 > --- a/gcc/gimplify-me.c > +++ b/gcc/gimplify-me.c > @@ -273,7 +273,7 @@ gimple_regimplify_operands (gimple *stmt, gimple_stmt_iterator *gsi_p) > || !(i & (ECF_CONST | ECF_PURE))) > need_temp = true; > } > - if (stmt_can_throw_internal (stmt)) > + if (stmt_can_throw_internal (cfun, stmt)) > need_temp = true; > } > } > diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c > index 66c81be23ec..1ca1d60517e 100644 > --- a/gcc/ipa-pure-const.c > +++ b/gcc/ipa-pure-const.c > @@ -555,9 +555,9 @@ check_call (funct_state local, gcall *call, bool ipa) > { > int flags = gimple_call_flags (call); > tree callee_t = gimple_call_fndecl (call); > - bool possibly_throws = stmt_could_throw_p (call); > + bool possibly_throws = stmt_could_throw_p (cfun, call); > bool possibly_throws_externally = (possibly_throws > - && stmt_can_throw_external (call)); > + && stmt_can_throw_external (cfun, call)); > > if (possibly_throws) > { > @@ -770,7 +770,7 @@ check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa) > ipa ? check_ipa_store : check_store); > > if (gimple_code (stmt) != GIMPLE_CALL > - && stmt_could_throw_p (stmt)) > + && stmt_could_throw_p (cfun, stmt)) > { > if (cfun->can_throw_non_call_exceptions) > { > @@ -778,7 +778,7 @@ check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa) > fprintf (dump_file, " can throw; looping\n"); > local->looping = true; > } > - if (stmt_can_throw_external (stmt)) > + if (stmt_can_throw_external (cfun, stmt)) > { > if (dump_file) > fprintf (dump_file, " can throw externally\n"); > @@ -2307,7 +2307,7 @@ pass_nothrow::execute (function *) > for (gimple_stmt_iterator gsi = gsi_start_bb (this_block); > !gsi_end_p (gsi); > gsi_next (&gsi)) > - if (stmt_can_throw_external (gsi_stmt (gsi))) > + if (stmt_can_throw_external (cfun, gsi_stmt (gsi))) > { > if (is_gimple_call (gsi_stmt (gsi))) > { > diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c > index 1d4eb806202..7e4bcec4030 100644 > --- a/gcc/trans-mem.c > +++ b/gcc/trans-mem.c > @@ -2582,7 +2582,7 @@ expand_call_tm (struct tm_region *region, > gassign *assign_stmt; > > /* Remember if the call was going to throw. */ > - if (stmt_can_throw_internal (stmt)) > + if (stmt_can_throw_internal (cfun, stmt)) > { > edge_iterator ei; > edge e; > diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c > index 87979bc4d75..d30e4aca773 100644 > --- a/gcc/tree-cfg.c > +++ b/gcc/tree-cfg.c > @@ -2720,7 +2720,7 @@ is_ctrl_altering_stmt (gimple *t) > } > > /* If a statement can throw, it alters control flow. */ > - return stmt_can_throw_internal (t); > + return stmt_can_throw_internal (cfun, t); > } > > > @@ -5387,7 +5387,7 @@ verify_gimple_in_cfg (struct function *fn, bool verify_nothrow) > visited_throwing_stmts.add (stmt); > if (lp_nr > 0) > { > - if (!stmt_could_throw_p (stmt)) > + if (!stmt_could_throw_p (cfun, stmt)) > { > if (verify_nothrow) > { > @@ -8283,7 +8283,7 @@ stmt_can_terminate_bb_p (gimple *t) > > /* Eh exception not handled internally terminates execution of the whole > function. */ > - if (stmt_can_throw_external (t)) > + if (stmt_can_throw_external (cfun, t)) > return true; > > /* NORETURN and LONGJMP calls already have an edge to exit. > @@ -8599,7 +8599,7 @@ gimple_purge_dead_eh_edges (basic_block bb) > edge_iterator ei; > gimple *stmt = last_stmt (bb); > > - if (stmt && stmt_can_throw_internal (stmt)) > + if (stmt && stmt_can_throw_internal (cfun, stmt)) > return false; > > for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) > diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c > index 93f274cd213..49088081bb0 100644 > --- a/gcc/tree-complex.c > +++ b/gcc/tree-complex.c > @@ -1010,13 +1010,13 @@ expand_complex_libcall (gimple_stmt_iterator *gsi, tree type, tree ar, tree ai, > if (inplace_p) > { > gimple *old_stmt = gsi_stmt (*gsi); > - gimple_call_set_nothrow (stmt, !stmt_could_throw_p (old_stmt)); > + gimple_call_set_nothrow (stmt, !stmt_could_throw_p (cfun, old_stmt)); > lhs = gimple_assign_lhs (old_stmt); > gimple_call_set_lhs (stmt, lhs); > gsi_replace (gsi, stmt, true); > > type = TREE_TYPE (type); > - if (stmt_can_throw_internal (stmt)) > + if (stmt_can_throw_internal (cfun, stmt)) > { > edge_iterator ei; > edge e; > @@ -1134,7 +1134,7 @@ expand_complex_multiplication (gimple_stmt_iterator *gsi, tree type, > /* If optimizing for size or not at all just do a libcall. > Same if there are exception-handling edges or signaling NaNs. */ > if (optimize == 0 || optimize_bb_for_size_p (gsi_bb (*gsi)) > - || stmt_can_throw_internal (gsi_stmt (*gsi)) > + || stmt_can_throw_internal (cfun, gsi_stmt (*gsi)) > || flag_signaling_nans) > { > expand_complex_libcall (gsi, type, ar, ai, br, bi, > diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c > index fb931aa4389..1c7d9dc1d59 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; > diff --git a/gcc/tree-eh.h b/gcc/tree-eh.h > index 11e096c9e5f..2bd6a856bd9 100644 > --- a/gcc/tree-eh.h > +++ b/gcc/tree-eh.h > @@ -38,10 +38,10 @@ extern bool operation_could_trap_helper_p (enum tree_code, bool, bool, bool, > extern bool operation_could_trap_p (enum tree_code, bool, bool, tree); > extern bool tree_could_trap_p (tree); > extern tree rewrite_to_non_trapping_overflow (tree); > -extern bool stmt_could_throw_p (gimple *); > +extern bool stmt_could_throw_p (function *, gimple *); > extern bool tree_could_throw_p (tree); > -extern bool stmt_can_throw_external (gimple *); > -extern bool stmt_can_throw_internal (gimple *); > +extern bool stmt_can_throw_external (function *, gimple *); > +extern bool stmt_can_throw_internal (function *, gimple *); > extern bool maybe_clean_eh_stmt_fn (struct function *, gimple *); > extern bool maybe_clean_eh_stmt (gimple *); > extern bool maybe_clean_or_replace_eh_stmt (gimple *, gimple *); > diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c > index 913425394e0..297fcd70c82 100644 > --- a/gcc/tree-inline.c > +++ b/gcc/tree-inline.c > @@ -2246,7 +2246,7 @@ copy_edges_for_bb (basic_block bb, profile_count num, profile_count den, > propagation can change an INDIRECT_REF which throws > 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); > + can_throw = stmt_can_throw_internal (cfun, copy_stmt); > nonlocal_goto > = (stmt_can_make_abnormal_goto (copy_stmt) > && !computed_goto_p (copy_stmt)); > @@ -2514,7 +2514,7 @@ maybe_move_debug_stmts_to_successors (copy_body_data *id, basic_block new_bb) > > if (gsi_end_p (si) > || gsi_one_before_end_p (si) > - || !(stmt_can_throw_internal (gsi_stmt (si)) > + || !(stmt_can_throw_internal (cfun, gsi_stmt (si)) > || stmt_can_make_abnormal_goto (gsi_stmt (si)))) > return; > > diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c > index 3f880ef7382..fca15e5f898 100644 > --- a/gcc/tree-outof-ssa.c > +++ b/gcc/tree-outof-ssa.c > @@ -65,7 +65,7 @@ ssa_is_replaceable_p (gimple *stmt) > return false; > > /* If the statement may throw an exception, it cannot be replaced. */ > - if (stmt_could_throw_p (stmt)) > + if (stmt_could_throw_p (cfun, stmt)) > return false; > > /* Punt if there is more than 1 def. */ > diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c > index e89c8875147..5935cf40927 100644 > --- a/gcc/tree-parloops.c > +++ b/gcc/tree-parloops.c > @@ -3076,7 +3076,7 @@ oacc_entry_exit_ok_1 (bitmap in_loop_bbs, vec<basic_block> region_bbs, > continue; > else if (!gimple_has_side_effects (stmt) > && !gimple_could_trap_p (stmt) > - && !stmt_could_throw_p (stmt) > + && !stmt_could_throw_p (cfun, stmt) > && !gimple_vdef (stmt) > && !gimple_vuse (stmt)) > continue; > diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c > index a9681ece0ae..e3e37466283 100644 > --- a/gcc/tree-sra.c > +++ b/gcc/tree-sra.c > @@ -1470,7 +1470,7 @@ scan_function (void) > tree t; > unsigned i; > > - if (final_bbs && stmt_can_throw_external (stmt)) > + if (final_bbs && stmt_can_throw_external (cfun, stmt)) > bitmap_set_bit (final_bbs, bb->index); > switch (gimple_code (stmt)) > { > diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c > index 032e79b8ba0..85a5de7ce05 100644 > --- a/gcc/tree-ssa-alias.c > +++ b/gcc/tree-ssa-alias.c > @@ -2396,7 +2396,7 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref) > ??? We only need to care about the RHS throwing. For aggregate > assignments or similar calls and non-call exceptions the LHS > might throw as well. */ > - && !stmt_can_throw_internal (stmt)) > + && !stmt_can_throw_internal (cfun, stmt)) > { > tree lhs = gimple_get_lhs (stmt); > /* If LHS is literally a base of the access we are done. */ > diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c > index d8a069be529..55ee30e7d13 100644 > --- a/gcc/tree-ssa-ccp.c > +++ b/gcc/tree-ssa-ccp.c > @@ -2931,7 +2931,7 @@ optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip, > gimple_set_location (g, gimple_location (call)); > gimple_set_vuse (g, gimple_vuse (call)); > gimple_set_vdef (g, gimple_vdef (call)); > - bool throws = stmt_can_throw_internal (call); > + bool throws = stmt_can_throw_internal (cfun, call); > gimple_call_set_nothrow (as_a <gcall *> (g), > gimple_call_nothrow_p (as_a <gcall *> (call))); > SSA_NAME_DEF_STMT (gimple_vdef (call)) = g; > diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c > index 91ce2aa4fc5..a8261b9a476 100644 > --- a/gcc/tree-ssa-dce.c > +++ b/gcc/tree-ssa-dce.c > @@ -195,7 +195,7 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive) > throw. If a statement could throw, it can be deemed necessary. */ > if (cfun->can_throw_non_call_exceptions > && !cfun->can_delete_dead_exceptions > - && stmt_could_throw_p (stmt)) > + && stmt_could_throw_p (cfun, stmt)) > { > mark_stmt_necessary (stmt, true); > return; > @@ -473,7 +473,7 @@ mark_aliased_reaching_defs_necessary_1 (ao_ref *ref, tree vdef, void *data) > ??? We only need to care about the RHS throwing. For aggregate > assignments or similar calls and non-call exceptions the LHS > might throw as well. */ > - && !stmt_can_throw_internal (def_stmt)) > + && !stmt_can_throw_internal (cfun, def_stmt)) > { > tree base, lhs = gimple_get_lhs (def_stmt); > poly_int64 size, offset, max_size; > diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c > index b1ee598fe5f..7449eaf86ae 100644 > --- a/gcc/tree-ssa-forwprop.c > +++ b/gcc/tree-ssa-forwprop.c > @@ -2343,7 +2343,7 @@ pass_forwprop::execute (function *fun) > && !gimple_has_volatile_ops (stmt) > && (TREE_CODE (gimple_assign_rhs1 (stmt)) > != TARGET_MEM_REF) > - && !stmt_can_throw_internal (stmt)) > + && !stmt_can_throw_internal (cfun, stmt)) > { > /* Rewrite loads used only in real/imagpart extractions to > component-wise loads. */ > diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c > index 9c62f20866c..3c59134d840 100644 > --- a/gcc/tree-ssa-loop-im.c > +++ b/gcc/tree-ssa-loop-im.c > @@ -302,7 +302,7 @@ movement_possibility (gimple *stmt) > if (stmt_ends_bb_p (stmt) > || gimple_has_volatile_ops (stmt) > || gimple_has_side_effects (stmt) > - || stmt_could_throw_p (stmt)) > + || stmt_could_throw_p (cfun, stmt)) > return MOVE_IMPOSSIBLE; > > if (is_gimple_call (stmt)) > diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c > index 6b445bd2214..b42f32da2b3 100644 > --- a/gcc/tree-ssa-loop-ivopts.c > +++ b/gcc/tree-ssa-loop-ivopts.c > @@ -1440,7 +1440,7 @@ find_givs_in_stmt_scev (struct ivopts_data *data, gimple *stmt, affine_iv *iv) > /* If STMT could throw, then do not consider STMT as defining a GIV. > While this will suppress optimizations, we can not safely delete this > GIV and associated statements, even if it appears it is not used. */ > - if (stmt_could_throw_p (stmt)) > + if (stmt_could_throw_p (cfun, stmt)) > return false; > > return true; > @@ -3222,7 +3222,7 @@ add_autoinc_candidates (struct ivopts_data *data, tree base, tree step, > statement. */ > if (use_bb->loop_father != data->current_loop > || !dominated_by_p (CDI_DOMINATORS, data->current_loop->latch, use_bb) > - || stmt_can_throw_internal (use->stmt) > + || stmt_can_throw_internal (cfun, use->stmt) > || !cst_and_fits_in_hwi (step)) > return; > > diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c > index e5aa5310e58..ccff56f4297 100644 > --- a/gcc/tree-ssa-math-opts.c > +++ b/gcc/tree-ssa-math-opts.c > @@ -951,7 +951,7 @@ pass_cse_reciprocals::execute (function *fun) > stmt = gsi_stmt (gsi); > if (flag_unsafe_math_optimizations > && is_gimple_assign (stmt) > - && !stmt_can_throw_internal (stmt) > + && !stmt_can_throw_internal (cfun, stmt) > && gimple_assign_rhs_code (stmt) == RDIV_EXPR) > optimize_recip_sqrt (&gsi, def); > } > @@ -2904,7 +2904,8 @@ convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2) > else > fma_stmt = gimple_build_call_internal (IFN_FMA, 3, mulop1, op2, addop); > gimple_set_lhs (fma_stmt, gimple_get_lhs (use_stmt)); > - gimple_call_set_nothrow (fma_stmt, !stmt_can_throw_internal (use_stmt)); > + gimple_call_set_nothrow (fma_stmt, !stmt_can_throw_internal (cfun, > + use_stmt)); > gsi_replace (&gsi, fma_stmt, true); > /* Follow all SSA edges so that we generate FMS, FNMA and FNMS > regardless of where the negation occurs. */ > @@ -3534,7 +3535,7 @@ divmod_candidate_p (gassign *stmt) > static bool > convert_to_divmod (gassign *stmt) > { > - if (stmt_can_throw_internal (stmt) > + if (stmt_can_throw_internal (cfun, stmt) > || !divmod_candidate_p (stmt)) > return false; > > @@ -3560,7 +3561,7 @@ convert_to_divmod (gassign *stmt) > && operand_equal_p (op1, gimple_assign_rhs1 (use_stmt), 0) > && operand_equal_p (op2, gimple_assign_rhs2 (use_stmt), 0)) > { > - if (stmt_can_throw_internal (use_stmt)) > + if (stmt_can_throw_internal (cfun, use_stmt)) > continue; > > basic_block bb = gimple_bb (use_stmt); > @@ -3598,7 +3599,7 @@ convert_to_divmod (gassign *stmt) > && operand_equal_p (top_op2, gimple_assign_rhs2 (use_stmt), 0)) > { > if (use_stmt == top_stmt > - || stmt_can_throw_internal (use_stmt) > + || stmt_can_throw_internal (cfun, use_stmt) > || !dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt), top_bb)) > continue; > > diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c > index 03dbb390bf8..bb18f3e9b49 100644 > --- a/gcc/tree-ssa-phiprop.c > +++ b/gcc/tree-ssa-phiprop.c > @@ -339,7 +339,7 @@ propagate_with_phi (basic_block bb, gphi *phi, struct phiprop_d *phivn, > || types_compatible_p > (TREE_TYPE (gimple_assign_lhs (use_stmt)), type)) > /* We cannot replace a load that may throw or is volatile. */ > - && !stmt_can_throw_internal (use_stmt))) > + && !stmt_can_throw_internal (cfun, use_stmt))) > continue; > > /* Check if we can move the loads. The def stmt of the virtual use > diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c > index d1b0cc0c26f..20d3c7807a1 100644 > --- a/gcc/tree-ssa-pre.c > +++ b/gcc/tree-ssa-pre.c > @@ -3827,7 +3827,7 @@ compute_avail (void) > BB_LIVE_VOP_ON_EXIT (block) = gimple_vdef (stmt); > > if (gimple_has_side_effects (stmt) > - || stmt_could_throw_p (stmt) > + || stmt_could_throw_p (cfun, stmt) > || is_gimple_debug (stmt)) > continue; > > diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c > index b1bfdd5c016..c635e3069f4 100644 > --- a/gcc/tree-ssa-propagate.c > +++ b/gcc/tree-ssa-propagate.c > @@ -1038,7 +1038,7 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb) > if (sprime > && sprime != lhs > && may_propagate_copy (lhs, sprime) > - && !stmt_could_throw_p (stmt) > + && !stmt_could_throw_p (cfun, stmt) > && !gimple_has_side_effects (stmt) > /* We have to leave ASSERT_EXPRs around for jump-threading. */ > && (!is_gimple_assign (stmt) > diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c > index 6b0bf5c0354..971d926e789 100644 > --- a/gcc/tree-ssa-reassoc.c > +++ b/gcc/tree-ssa-reassoc.c > @@ -3702,7 +3702,7 @@ suitable_cond_bb (basic_block bb, basic_block test_bb, basic_block *other_bb, > || (gimple_code (stmt) != GIMPLE_COND > && (backward || !final_range_test_p (stmt))) > || gimple_visited_p (stmt) > - || stmt_could_throw_p (stmt) > + || stmt_could_throw_p (cfun, stmt) > || *other_bb == bb) > return false; > is_cond = gimple_code (stmt) == GIMPLE_COND; > @@ -3958,7 +3958,7 @@ maybe_optimize_range_tests (gimple *stmt) > else > return cfg_cleanup_needed; > > - if (stmt_could_throw_p (stmt)) > + if (stmt_could_throw_p (cfun, stmt)) > return cfg_cleanup_needed; > > /* As relative ordering of post-dominator sons isn't fixed, > @@ -5109,14 +5109,14 @@ linearize_expr_tree (vec<operand_entry *> *ops, gimple *stmt, > { > binlhsdef = SSA_NAME_DEF_STMT (binlhs); > binlhsisreassoc = (is_reassociable_op (binlhsdef, rhscode, loop) > - && !stmt_could_throw_p (binlhsdef)); > + && !stmt_could_throw_p (cfun, binlhsdef)); > } > > if (TREE_CODE (binrhs) == SSA_NAME) > { > binrhsdef = SSA_NAME_DEF_STMT (binrhs); > binrhsisreassoc = (is_reassociable_op (binrhsdef, rhscode, loop) > - && !stmt_could_throw_p (binrhsdef)); > + && !stmt_could_throw_p (cfun, binrhsdef)); > } > > /* If the LHS is not reassociable, but the RHS is, we need to swap > @@ -5851,7 +5851,7 @@ reassociate_bb (basic_block bb) > stmt = gsi_stmt (gsi); > > if (is_gimple_assign (stmt) > - && !stmt_could_throw_p (stmt)) > + && !stmt_could_throw_p (cfun, stmt)) > { > tree lhs, rhs1, rhs2; > enum tree_code rhs_code = gimple_assign_rhs_code (stmt); > diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c > index 5a05dfb5640..e61f0ba7b8c 100644 > --- a/gcc/tree-ssa-sccvn.c > +++ b/gcc/tree-ssa-sccvn.c > @@ -1210,7 +1210,7 @@ copy_reference_ops_from_call (gcall *call, > temp.opcode = CALL_EXPR; > temp.op0 = gimple_call_fn (call); > temp.op1 = gimple_call_chain (call); > - if (stmt_could_throw_p (call) && (lr = lookup_stmt_eh_lp (call)) > 0) > + if (stmt_could_throw_p (cfun, call) && (lr = lookup_stmt_eh_lp (call)) > 0) > temp.op2 = size_int (lr); > temp.off = -1; > result->safe_push (temp); > diff --git a/gcc/tree-ssa-scopedtables.c b/gcc/tree-ssa-scopedtables.c > index 9e751a27152..d1a73a5d64c 100644 > --- a/gcc/tree-ssa-scopedtables.c > +++ b/gcc/tree-ssa-scopedtables.c > @@ -666,7 +666,7 @@ hashable_expr_equal_p (const struct hashable_expr *expr0, > expr1->ops.call.args[i], 0)) > return false; > > - if (stmt_could_throw_p (expr0->ops.call.fn_from)) > + if (stmt_could_throw_p (cfun, expr0->ops.call.fn_from)) > { > int lp0 = lookup_stmt_eh_lp (expr0->ops.call.fn_from); > int lp1 = lookup_stmt_eh_lp (expr1->ops.call.fn_from); > diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c > index 3fa5ef56f38..fd8c2750116 100644 > --- a/gcc/tree-ssa-strlen.c > +++ b/gcc/tree-ssa-strlen.c > @@ -1064,7 +1064,7 @@ adjust_last_stmt (strinfo *si, gimple *stmt, bool is_strcat) > > if (!integer_zerop (gimple_assign_rhs1 (last.stmt))) > return; > - if (stmt_could_throw_p (last.stmt)) > + if (stmt_could_throw_p (cfun, last.stmt)) > return; > gsi = gsi_for_stmt (last.stmt); > unlink_stmt_vdef (last.stmt); > @@ -3253,7 +3253,7 @@ handle_char_store (gimple_stmt_iterator *gsi) > { > /* When overwriting a '\0' with a '\0', the store can be removed > if we know it has been stored in the current function. */ > - if (!stmt_could_throw_p (stmt) && si->writable) > + if (!stmt_could_throw_p (cfun, stmt) && si->writable) > { > unlink_stmt_vdef (stmt); > release_defs (stmt); > diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c > index c4805e72447..4b3711442e6 100644 > --- a/gcc/tree-vect-data-refs.c > +++ b/gcc/tree-vect-data-refs.c > @@ -3844,7 +3844,7 @@ vect_find_stmt_data_reference (loop_p loop, gimple *stmt, > return opt_result::failure_at (stmt, "not vectorized: volatile type: %G", > stmt); > > - if (stmt_can_throw_internal (stmt)) > + if (stmt_can_throw_internal (cfun, stmt)) > return opt_result::failure_at (stmt, > "not vectorized:" > " statement can throw an exception: %G", > diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c > index 7956c1326d3..5548d47b87f 100644 > --- a/gcc/tree-vect-patterns.c > +++ b/gcc/tree-vect-patterns.c > @@ -3235,7 +3235,7 @@ check_bool_pattern (tree var, vec_info *vinfo, hash_set<gimple *> &stmts) > > /* If the comparison can throw, then is_gimple_condexpr will be > false and we can't make a COND_EXPR/VEC_COND_EXPR out of it. */ > - if (stmt_could_throw_p (def_stmt)) > + if (stmt_could_throw_p (cfun, def_stmt)) > return false; > > comp_vectype = get_vectype_for_scalar_type (TREE_TYPE (rhs1)); > diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c > index 8108d52a3cb..8995da80b1e 100644 > --- a/gcc/tree-vect-stmts.c > +++ b/gcc/tree-vect-stmts.c > @@ -1711,7 +1711,7 @@ vect_finish_stmt_generation_1 (stmt_vec_info stmt_info, gimple *vec_stmt) > e.g. be in a must-not-throw region. Ensure newly created stmts > that could throw are part of the same region. */ > int lp_nr = lookup_stmt_eh_lp (stmt_info->stmt); > - if (lp_nr != 0 && stmt_could_throw_p (vec_stmt)) > + if (lp_nr != 0 && stmt_could_throw_p (cfun, vec_stmt)) > add_stmt_to_eh_lp (vec_stmt, lp_nr); > > return vec_stmt_info; > @@ -3116,7 +3116,7 @@ vectorizable_call (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, > || TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME) > return false; > > - gcc_checking_assert (!stmt_can_throw_internal (stmt)); > + gcc_checking_assert (!stmt_can_throw_internal (cfun, stmt)); > > vectype_out = STMT_VINFO_VECTYPE (stmt_info); > > @@ -3751,7 +3751,7 @@ vectorizable_simd_clone_call (stmt_vec_info stmt_info, > && TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME) > return false; > > - gcc_checking_assert (!stmt_can_throw_internal (stmt)); > + gcc_checking_assert (!stmt_can_throw_internal (cfun, stmt)); > > vectype = STMT_VINFO_VECTYPE (stmt_info); > > diff --git a/gcc/value-prof.c b/gcc/value-prof.c > index 60b982793d1..f3be9ff8747 100644 > --- a/gcc/value-prof.c > +++ b/gcc/value-prof.c > @@ -1392,7 +1392,7 @@ gimple_ic (gcall *icall_stmt, struct cgraph_node *direct_call, > > /* Build an EH edge for the direct call if necessary. */ > lp_nr = lookup_stmt_eh_lp (icall_stmt); > - if (lp_nr > 0 && stmt_could_throw_p (dcall_stmt)) > + if (lp_nr > 0 && stmt_could_throw_p (cfun, dcall_stmt)) > { > add_stmt_to_eh_lp (dcall_stmt, lp_nr); > } > @@ -1410,7 +1410,7 @@ gimple_ic (gcall *icall_stmt, struct cgraph_node *direct_call, > PHI_ARG_DEF_FROM_EDGE (phi, e_eh)); > } > } > - if (!stmt_could_throw_p (dcall_stmt)) > + if (!stmt_could_throw_p (cfun, dcall_stmt)) > gimple_purge_dead_eh_edges (dcall_bb); > return dcall_stmt; > } > @@ -1634,8 +1634,8 @@ gimple_stringop_fixed_value (gcall *vcall_stmt, tree icall_size, profile_probabi > } > > /* Because these are all string op builtins, they're all nothrow. */ > - gcc_assert (!stmt_could_throw_p (vcall_stmt)); > - gcc_assert (!stmt_could_throw_p (icall_stmt)); > + gcc_assert (!stmt_could_throw_p (cfun, vcall_stmt)); > + gcc_assert (!stmt_could_throw_p (cfun, icall_stmt)); > } > > /* Find values inside STMT for that we want to measure histograms for >
diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 8a03f3d6828..48bab9f2749 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -815,9 +815,8 @@ cgraph_edge::set_call_stmt (gcall *new_stmt, bool update_speculative) e = make_direct (new_callee); } - push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl)); - e->can_throw_external = stmt_can_throw_external (new_stmt); - pop_cfun (); + function *fun = DECL_STRUCT_FUNCTION (e->caller->decl); + e->can_throw_external = stmt_can_throw_external (fun, new_stmt); if (e->caller->call_site_hash) cgraph_add_edge_to_call_site_hash (e); } @@ -870,10 +869,9 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee, edge->count = count; edge->call_stmt = call_stmt; - push_cfun (DECL_STRUCT_FUNCTION (caller->decl)); edge->can_throw_external - = call_stmt ? stmt_can_throw_external (call_stmt) : false; - pop_cfun (); + = call_stmt ? stmt_can_throw_external (DECL_STRUCT_FUNCTION (caller->decl), + call_stmt) : false; if (call_stmt && callee && callee->decl && !gimple_check_call_matching_types (call_stmt, callee->decl, diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index fe6bc08bdd9..e862b1a1d4c 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -4023,7 +4023,7 @@ fold_builtin_atomic_compare_exchange (gimple_stmt_iterator *gsi) gimple_set_vuse (g, gimple_vuse (stmt)); SSA_NAME_DEF_STMT (gimple_vdef (g)) = g; tree oldlhs = gimple_call_lhs (stmt); - if (stmt_can_throw_internal (stmt)) + if (stmt_can_throw_internal (cfun, stmt)) { throws = true; e = find_fallthru_edge (gsi_bb (*gsi)->succs); diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c index 50e8adc1aad..7d952765c5a 100644 --- a/gcc/gimple-ssa-evrp.c +++ b/gcc/gimple-ssa-evrp.c @@ -164,7 +164,7 @@ evrp_dom_walker::before_dom_children (basic_block bb) if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE) && (val = value_range_constant_singleton (vr)) && may_propagate_copy (output, val) - && !stmt_could_throw_p (stmt) + && !stmt_could_throw_p (cfun, stmt) && !gimple_has_side_effects (stmt)) { stmts_to_remove.safe_push (stmt); diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c index 85dd5bccead..e1ddcb5e558 100644 --- a/gcc/gimple-ssa-store-merging.c +++ b/gcc/gimple-ssa-store-merging.c @@ -4256,7 +4256,7 @@ handled_load (gimple *stmt, store_operand_info *op, } if (gimple_vuse (stmt) && gimple_assign_load_p (stmt) - && !stmt_can_throw_internal (stmt) + && !stmt_can_throw_internal (cfun, stmt) && !gimple_has_volatile_ops (stmt)) { tree mem = gimple_assign_rhs1 (stmt); @@ -4551,7 +4551,7 @@ pass_store_merging::execute (function *fun) } if (gimple_assign_single_p (stmt) && gimple_vdef (stmt) - && !stmt_can_throw_internal (stmt) + && !stmt_can_throw_internal (cfun, stmt) && lhs_valid_for_store_merging_p (gimple_assign_lhs (stmt))) process_store (stmt); else diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c index ea81adca7ea..7ed6ae7f88a 100644 --- a/gcc/gimple-ssa-strength-reduction.c +++ b/gcc/gimple-ssa-strength-reduction.c @@ -1775,7 +1775,7 @@ find_candidates_dom_walker::before_dom_children (basic_block bb) { gimple *gs = gsi_stmt (gsi); - if (stmt_could_throw_p (gs)) + if (stmt_could_throw_p (cfun, gs)) continue; if (gimple_vuse (gs) && gimple_assign_single_p (gs)) diff --git a/gcc/gimplify-me.c b/gcc/gimplify-me.c index 137a5662ccf..269fe6b3bae 100644 --- a/gcc/gimplify-me.c +++ b/gcc/gimplify-me.c @@ -273,7 +273,7 @@ gimple_regimplify_operands (gimple *stmt, gimple_stmt_iterator *gsi_p) || !(i & (ECF_CONST | ECF_PURE))) need_temp = true; } - if (stmt_can_throw_internal (stmt)) + if (stmt_can_throw_internal (cfun, stmt)) need_temp = true; } } diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index 66c81be23ec..1ca1d60517e 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -555,9 +555,9 @@ check_call (funct_state local, gcall *call, bool ipa) { int flags = gimple_call_flags (call); tree callee_t = gimple_call_fndecl (call); - bool possibly_throws = stmt_could_throw_p (call); + bool possibly_throws = stmt_could_throw_p (cfun, call); bool possibly_throws_externally = (possibly_throws - && stmt_can_throw_external (call)); + && stmt_can_throw_external (cfun, call)); if (possibly_throws) { @@ -770,7 +770,7 @@ check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa) ipa ? check_ipa_store : check_store); if (gimple_code (stmt) != GIMPLE_CALL - && stmt_could_throw_p (stmt)) + && stmt_could_throw_p (cfun, stmt)) { if (cfun->can_throw_non_call_exceptions) { @@ -778,7 +778,7 @@ check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa) fprintf (dump_file, " can throw; looping\n"); local->looping = true; } - if (stmt_can_throw_external (stmt)) + if (stmt_can_throw_external (cfun, stmt)) { if (dump_file) fprintf (dump_file, " can throw externally\n"); @@ -2307,7 +2307,7 @@ pass_nothrow::execute (function *) for (gimple_stmt_iterator gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi)) - if (stmt_can_throw_external (gsi_stmt (gsi))) + if (stmt_can_throw_external (cfun, gsi_stmt (gsi))) { if (is_gimple_call (gsi_stmt (gsi))) { diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index 1d4eb806202..7e4bcec4030 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -2582,7 +2582,7 @@ expand_call_tm (struct tm_region *region, gassign *assign_stmt; /* Remember if the call was going to throw. */ - if (stmt_can_throw_internal (stmt)) + if (stmt_can_throw_internal (cfun, stmt)) { edge_iterator ei; edge e; diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 87979bc4d75..d30e4aca773 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -2720,7 +2720,7 @@ is_ctrl_altering_stmt (gimple *t) } /* If a statement can throw, it alters control flow. */ - return stmt_can_throw_internal (t); + return stmt_can_throw_internal (cfun, t); } @@ -5387,7 +5387,7 @@ verify_gimple_in_cfg (struct function *fn, bool verify_nothrow) visited_throwing_stmts.add (stmt); if (lp_nr > 0) { - if (!stmt_could_throw_p (stmt)) + if (!stmt_could_throw_p (cfun, stmt)) { if (verify_nothrow) { @@ -8283,7 +8283,7 @@ stmt_can_terminate_bb_p (gimple *t) /* Eh exception not handled internally terminates execution of the whole function. */ - if (stmt_can_throw_external (t)) + if (stmt_can_throw_external (cfun, t)) return true; /* NORETURN and LONGJMP calls already have an edge to exit. @@ -8599,7 +8599,7 @@ gimple_purge_dead_eh_edges (basic_block bb) edge_iterator ei; gimple *stmt = last_stmt (bb); - if (stmt && stmt_can_throw_internal (stmt)) + if (stmt && stmt_can_throw_internal (cfun, stmt)) return false; for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c index 93f274cd213..49088081bb0 100644 --- a/gcc/tree-complex.c +++ b/gcc/tree-complex.c @@ -1010,13 +1010,13 @@ expand_complex_libcall (gimple_stmt_iterator *gsi, tree type, tree ar, tree ai, if (inplace_p) { gimple *old_stmt = gsi_stmt (*gsi); - gimple_call_set_nothrow (stmt, !stmt_could_throw_p (old_stmt)); + gimple_call_set_nothrow (stmt, !stmt_could_throw_p (cfun, old_stmt)); lhs = gimple_assign_lhs (old_stmt); gimple_call_set_lhs (stmt, lhs); gsi_replace (gsi, stmt, true); type = TREE_TYPE (type); - if (stmt_can_throw_internal (stmt)) + if (stmt_can_throw_internal (cfun, stmt)) { edge_iterator ei; edge e; @@ -1134,7 +1134,7 @@ expand_complex_multiplication (gimple_stmt_iterator *gsi, tree type, /* If optimizing for size or not at all just do a libcall. Same if there are exception-handling edges or signaling NaNs. */ if (optimize == 0 || optimize_bb_for_size_p (gsi_bb (*gsi)) - || stmt_can_throw_internal (gsi_stmt (*gsi)) + || stmt_can_throw_internal (cfun, gsi_stmt (*gsi)) || flag_signaling_nans) { expand_complex_libcall (gsi, type, ar, ai, br, bi, diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index fb931aa4389..1c7d9dc1d59 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; diff --git a/gcc/tree-eh.h b/gcc/tree-eh.h index 11e096c9e5f..2bd6a856bd9 100644 --- a/gcc/tree-eh.h +++ b/gcc/tree-eh.h @@ -38,10 +38,10 @@ extern bool operation_could_trap_helper_p (enum tree_code, bool, bool, bool, extern bool operation_could_trap_p (enum tree_code, bool, bool, tree); extern bool tree_could_trap_p (tree); extern tree rewrite_to_non_trapping_overflow (tree); -extern bool stmt_could_throw_p (gimple *); +extern bool stmt_could_throw_p (function *, gimple *); extern bool tree_could_throw_p (tree); -extern bool stmt_can_throw_external (gimple *); -extern bool stmt_can_throw_internal (gimple *); +extern bool stmt_can_throw_external (function *, gimple *); +extern bool stmt_can_throw_internal (function *, gimple *); extern bool maybe_clean_eh_stmt_fn (struct function *, gimple *); extern bool maybe_clean_eh_stmt (gimple *); extern bool maybe_clean_or_replace_eh_stmt (gimple *, gimple *); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 913425394e0..297fcd70c82 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -2246,7 +2246,7 @@ copy_edges_for_bb (basic_block bb, profile_count num, profile_count den, propagation can change an INDIRECT_REF which throws 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); + can_throw = stmt_can_throw_internal (cfun, copy_stmt); nonlocal_goto = (stmt_can_make_abnormal_goto (copy_stmt) && !computed_goto_p (copy_stmt)); @@ -2514,7 +2514,7 @@ maybe_move_debug_stmts_to_successors (copy_body_data *id, basic_block new_bb) if (gsi_end_p (si) || gsi_one_before_end_p (si) - || !(stmt_can_throw_internal (gsi_stmt (si)) + || !(stmt_can_throw_internal (cfun, gsi_stmt (si)) || stmt_can_make_abnormal_goto (gsi_stmt (si)))) return; diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index 3f880ef7382..fca15e5f898 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -65,7 +65,7 @@ ssa_is_replaceable_p (gimple *stmt) return false; /* If the statement may throw an exception, it cannot be replaced. */ - if (stmt_could_throw_p (stmt)) + if (stmt_could_throw_p (cfun, stmt)) return false; /* Punt if there is more than 1 def. */ diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c index e89c8875147..5935cf40927 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -3076,7 +3076,7 @@ oacc_entry_exit_ok_1 (bitmap in_loop_bbs, vec<basic_block> region_bbs, continue; else if (!gimple_has_side_effects (stmt) && !gimple_could_trap_p (stmt) - && !stmt_could_throw_p (stmt) + && !stmt_could_throw_p (cfun, stmt) && !gimple_vdef (stmt) && !gimple_vuse (stmt)) continue; diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index a9681ece0ae..e3e37466283 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1470,7 +1470,7 @@ scan_function (void) tree t; unsigned i; - if (final_bbs && stmt_can_throw_external (stmt)) + if (final_bbs && stmt_can_throw_external (cfun, stmt)) bitmap_set_bit (final_bbs, bb->index); switch (gimple_code (stmt)) { diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 032e79b8ba0..85a5de7ce05 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -2396,7 +2396,7 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref) ??? We only need to care about the RHS throwing. For aggregate assignments or similar calls and non-call exceptions the LHS might throw as well. */ - && !stmt_can_throw_internal (stmt)) + && !stmt_can_throw_internal (cfun, stmt)) { tree lhs = gimple_get_lhs (stmt); /* If LHS is literally a base of the access we are done. */ diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index d8a069be529..55ee30e7d13 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -2931,7 +2931,7 @@ optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip, gimple_set_location (g, gimple_location (call)); gimple_set_vuse (g, gimple_vuse (call)); gimple_set_vdef (g, gimple_vdef (call)); - bool throws = stmt_can_throw_internal (call); + bool throws = stmt_can_throw_internal (cfun, call); gimple_call_set_nothrow (as_a <gcall *> (g), gimple_call_nothrow_p (as_a <gcall *> (call))); SSA_NAME_DEF_STMT (gimple_vdef (call)) = g; diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index 91ce2aa4fc5..a8261b9a476 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -195,7 +195,7 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive) throw. If a statement could throw, it can be deemed necessary. */ if (cfun->can_throw_non_call_exceptions && !cfun->can_delete_dead_exceptions - && stmt_could_throw_p (stmt)) + && stmt_could_throw_p (cfun, stmt)) { mark_stmt_necessary (stmt, true); return; @@ -473,7 +473,7 @@ mark_aliased_reaching_defs_necessary_1 (ao_ref *ref, tree vdef, void *data) ??? We only need to care about the RHS throwing. For aggregate assignments or similar calls and non-call exceptions the LHS might throw as well. */ - && !stmt_can_throw_internal (def_stmt)) + && !stmt_can_throw_internal (cfun, def_stmt)) { tree base, lhs = gimple_get_lhs (def_stmt); poly_int64 size, offset, max_size; diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index b1ee598fe5f..7449eaf86ae 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -2343,7 +2343,7 @@ pass_forwprop::execute (function *fun) && !gimple_has_volatile_ops (stmt) && (TREE_CODE (gimple_assign_rhs1 (stmt)) != TARGET_MEM_REF) - && !stmt_can_throw_internal (stmt)) + && !stmt_can_throw_internal (cfun, stmt)) { /* Rewrite loads used only in real/imagpart extractions to component-wise loads. */ diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index 9c62f20866c..3c59134d840 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -302,7 +302,7 @@ movement_possibility (gimple *stmt) if (stmt_ends_bb_p (stmt) || gimple_has_volatile_ops (stmt) || gimple_has_side_effects (stmt) - || stmt_could_throw_p (stmt)) + || stmt_could_throw_p (cfun, stmt)) return MOVE_IMPOSSIBLE; if (is_gimple_call (stmt)) diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 6b445bd2214..b42f32da2b3 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -1440,7 +1440,7 @@ find_givs_in_stmt_scev (struct ivopts_data *data, gimple *stmt, affine_iv *iv) /* If STMT could throw, then do not consider STMT as defining a GIV. While this will suppress optimizations, we can not safely delete this GIV and associated statements, even if it appears it is not used. */ - if (stmt_could_throw_p (stmt)) + if (stmt_could_throw_p (cfun, stmt)) return false; return true; @@ -3222,7 +3222,7 @@ add_autoinc_candidates (struct ivopts_data *data, tree base, tree step, statement. */ if (use_bb->loop_father != data->current_loop || !dominated_by_p (CDI_DOMINATORS, data->current_loop->latch, use_bb) - || stmt_can_throw_internal (use->stmt) + || stmt_can_throw_internal (cfun, use->stmt) || !cst_and_fits_in_hwi (step)) return; diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index e5aa5310e58..ccff56f4297 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -951,7 +951,7 @@ pass_cse_reciprocals::execute (function *fun) stmt = gsi_stmt (gsi); if (flag_unsafe_math_optimizations && is_gimple_assign (stmt) - && !stmt_can_throw_internal (stmt) + && !stmt_can_throw_internal (cfun, stmt) && gimple_assign_rhs_code (stmt) == RDIV_EXPR) optimize_recip_sqrt (&gsi, def); } @@ -2904,7 +2904,8 @@ convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2) else fma_stmt = gimple_build_call_internal (IFN_FMA, 3, mulop1, op2, addop); gimple_set_lhs (fma_stmt, gimple_get_lhs (use_stmt)); - gimple_call_set_nothrow (fma_stmt, !stmt_can_throw_internal (use_stmt)); + gimple_call_set_nothrow (fma_stmt, !stmt_can_throw_internal (cfun, + use_stmt)); gsi_replace (&gsi, fma_stmt, true); /* Follow all SSA edges so that we generate FMS, FNMA and FNMS regardless of where the negation occurs. */ @@ -3534,7 +3535,7 @@ divmod_candidate_p (gassign *stmt) static bool convert_to_divmod (gassign *stmt) { - if (stmt_can_throw_internal (stmt) + if (stmt_can_throw_internal (cfun, stmt) || !divmod_candidate_p (stmt)) return false; @@ -3560,7 +3561,7 @@ convert_to_divmod (gassign *stmt) && operand_equal_p (op1, gimple_assign_rhs1 (use_stmt), 0) && operand_equal_p (op2, gimple_assign_rhs2 (use_stmt), 0)) { - if (stmt_can_throw_internal (use_stmt)) + if (stmt_can_throw_internal (cfun, use_stmt)) continue; basic_block bb = gimple_bb (use_stmt); @@ -3598,7 +3599,7 @@ convert_to_divmod (gassign *stmt) && operand_equal_p (top_op2, gimple_assign_rhs2 (use_stmt), 0)) { if (use_stmt == top_stmt - || stmt_can_throw_internal (use_stmt) + || stmt_can_throw_internal (cfun, use_stmt) || !dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt), top_bb)) continue; diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c index 03dbb390bf8..bb18f3e9b49 100644 --- a/gcc/tree-ssa-phiprop.c +++ b/gcc/tree-ssa-phiprop.c @@ -339,7 +339,7 @@ propagate_with_phi (basic_block bb, gphi *phi, struct phiprop_d *phivn, || types_compatible_p (TREE_TYPE (gimple_assign_lhs (use_stmt)), type)) /* We cannot replace a load that may throw or is volatile. */ - && !stmt_can_throw_internal (use_stmt))) + && !stmt_can_throw_internal (cfun, use_stmt))) continue; /* Check if we can move the loads. The def stmt of the virtual use diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index d1b0cc0c26f..20d3c7807a1 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -3827,7 +3827,7 @@ compute_avail (void) BB_LIVE_VOP_ON_EXIT (block) = gimple_vdef (stmt); if (gimple_has_side_effects (stmt) - || stmt_could_throw_p (stmt) + || stmt_could_throw_p (cfun, stmt) || is_gimple_debug (stmt)) continue; diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index b1bfdd5c016..c635e3069f4 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -1038,7 +1038,7 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb) if (sprime && sprime != lhs && may_propagate_copy (lhs, sprime) - && !stmt_could_throw_p (stmt) + && !stmt_could_throw_p (cfun, stmt) && !gimple_has_side_effects (stmt) /* We have to leave ASSERT_EXPRs around for jump-threading. */ && (!is_gimple_assign (stmt) diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 6b0bf5c0354..971d926e789 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -3702,7 +3702,7 @@ suitable_cond_bb (basic_block bb, basic_block test_bb, basic_block *other_bb, || (gimple_code (stmt) != GIMPLE_COND && (backward || !final_range_test_p (stmt))) || gimple_visited_p (stmt) - || stmt_could_throw_p (stmt) + || stmt_could_throw_p (cfun, stmt) || *other_bb == bb) return false; is_cond = gimple_code (stmt) == GIMPLE_COND; @@ -3958,7 +3958,7 @@ maybe_optimize_range_tests (gimple *stmt) else return cfg_cleanup_needed; - if (stmt_could_throw_p (stmt)) + if (stmt_could_throw_p (cfun, stmt)) return cfg_cleanup_needed; /* As relative ordering of post-dominator sons isn't fixed, @@ -5109,14 +5109,14 @@ linearize_expr_tree (vec<operand_entry *> *ops, gimple *stmt, { binlhsdef = SSA_NAME_DEF_STMT (binlhs); binlhsisreassoc = (is_reassociable_op (binlhsdef, rhscode, loop) - && !stmt_could_throw_p (binlhsdef)); + && !stmt_could_throw_p (cfun, binlhsdef)); } if (TREE_CODE (binrhs) == SSA_NAME) { binrhsdef = SSA_NAME_DEF_STMT (binrhs); binrhsisreassoc = (is_reassociable_op (binrhsdef, rhscode, loop) - && !stmt_could_throw_p (binrhsdef)); + && !stmt_could_throw_p (cfun, binrhsdef)); } /* If the LHS is not reassociable, but the RHS is, we need to swap @@ -5851,7 +5851,7 @@ reassociate_bb (basic_block bb) stmt = gsi_stmt (gsi); if (is_gimple_assign (stmt) - && !stmt_could_throw_p (stmt)) + && !stmt_could_throw_p (cfun, stmt)) { tree lhs, rhs1, rhs2; enum tree_code rhs_code = gimple_assign_rhs_code (stmt); diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 5a05dfb5640..e61f0ba7b8c 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -1210,7 +1210,7 @@ copy_reference_ops_from_call (gcall *call, temp.opcode = CALL_EXPR; temp.op0 = gimple_call_fn (call); temp.op1 = gimple_call_chain (call); - if (stmt_could_throw_p (call) && (lr = lookup_stmt_eh_lp (call)) > 0) + if (stmt_could_throw_p (cfun, call) && (lr = lookup_stmt_eh_lp (call)) > 0) temp.op2 = size_int (lr); temp.off = -1; result->safe_push (temp); diff --git a/gcc/tree-ssa-scopedtables.c b/gcc/tree-ssa-scopedtables.c index 9e751a27152..d1a73a5d64c 100644 --- a/gcc/tree-ssa-scopedtables.c +++ b/gcc/tree-ssa-scopedtables.c @@ -666,7 +666,7 @@ hashable_expr_equal_p (const struct hashable_expr *expr0, expr1->ops.call.args[i], 0)) return false; - if (stmt_could_throw_p (expr0->ops.call.fn_from)) + if (stmt_could_throw_p (cfun, expr0->ops.call.fn_from)) { int lp0 = lookup_stmt_eh_lp (expr0->ops.call.fn_from); int lp1 = lookup_stmt_eh_lp (expr1->ops.call.fn_from); diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 3fa5ef56f38..fd8c2750116 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -1064,7 +1064,7 @@ adjust_last_stmt (strinfo *si, gimple *stmt, bool is_strcat) if (!integer_zerop (gimple_assign_rhs1 (last.stmt))) return; - if (stmt_could_throw_p (last.stmt)) + if (stmt_could_throw_p (cfun, last.stmt)) return; gsi = gsi_for_stmt (last.stmt); unlink_stmt_vdef (last.stmt); @@ -3253,7 +3253,7 @@ handle_char_store (gimple_stmt_iterator *gsi) { /* When overwriting a '\0' with a '\0', the store can be removed if we know it has been stored in the current function. */ - if (!stmt_could_throw_p (stmt) && si->writable) + if (!stmt_could_throw_p (cfun, stmt) && si->writable) { unlink_stmt_vdef (stmt); release_defs (stmt); diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index c4805e72447..4b3711442e6 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -3844,7 +3844,7 @@ vect_find_stmt_data_reference (loop_p loop, gimple *stmt, return opt_result::failure_at (stmt, "not vectorized: volatile type: %G", stmt); - if (stmt_can_throw_internal (stmt)) + if (stmt_can_throw_internal (cfun, stmt)) return opt_result::failure_at (stmt, "not vectorized:" " statement can throw an exception: %G", diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 7956c1326d3..5548d47b87f 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -3235,7 +3235,7 @@ check_bool_pattern (tree var, vec_info *vinfo, hash_set<gimple *> &stmts) /* If the comparison can throw, then is_gimple_condexpr will be false and we can't make a COND_EXPR/VEC_COND_EXPR out of it. */ - if (stmt_could_throw_p (def_stmt)) + if (stmt_could_throw_p (cfun, def_stmt)) return false; comp_vectype = get_vectype_for_scalar_type (TREE_TYPE (rhs1)); diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 8108d52a3cb..8995da80b1e 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -1711,7 +1711,7 @@ vect_finish_stmt_generation_1 (stmt_vec_info stmt_info, gimple *vec_stmt) e.g. be in a must-not-throw region. Ensure newly created stmts that could throw are part of the same region. */ int lp_nr = lookup_stmt_eh_lp (stmt_info->stmt); - if (lp_nr != 0 && stmt_could_throw_p (vec_stmt)) + if (lp_nr != 0 && stmt_could_throw_p (cfun, vec_stmt)) add_stmt_to_eh_lp (vec_stmt, lp_nr); return vec_stmt_info; @@ -3116,7 +3116,7 @@ vectorizable_call (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, || TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME) return false; - gcc_checking_assert (!stmt_can_throw_internal (stmt)); + gcc_checking_assert (!stmt_can_throw_internal (cfun, stmt)); vectype_out = STMT_VINFO_VECTYPE (stmt_info); @@ -3751,7 +3751,7 @@ vectorizable_simd_clone_call (stmt_vec_info stmt_info, && TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME) return false; - gcc_checking_assert (!stmt_can_throw_internal (stmt)); + gcc_checking_assert (!stmt_can_throw_internal (cfun, stmt)); vectype = STMT_VINFO_VECTYPE (stmt_info); diff --git a/gcc/value-prof.c b/gcc/value-prof.c index 60b982793d1..f3be9ff8747 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -1392,7 +1392,7 @@ gimple_ic (gcall *icall_stmt, struct cgraph_node *direct_call, /* Build an EH edge for the direct call if necessary. */ lp_nr = lookup_stmt_eh_lp (icall_stmt); - if (lp_nr > 0 && stmt_could_throw_p (dcall_stmt)) + if (lp_nr > 0 && stmt_could_throw_p (cfun, dcall_stmt)) { add_stmt_to_eh_lp (dcall_stmt, lp_nr); } @@ -1410,7 +1410,7 @@ gimple_ic (gcall *icall_stmt, struct cgraph_node *direct_call, PHI_ARG_DEF_FROM_EDGE (phi, e_eh)); } } - if (!stmt_could_throw_p (dcall_stmt)) + if (!stmt_could_throw_p (cfun, dcall_stmt)) gimple_purge_dead_eh_edges (dcall_bb); return dcall_stmt; } @@ -1634,8 +1634,8 @@ gimple_stringop_fixed_value (gcall *vcall_stmt, tree icall_size, profile_probabi } /* Because these are all string op builtins, they're all nothrow. */ - gcc_assert (!stmt_could_throw_p (vcall_stmt)); - gcc_assert (!stmt_could_throw_p (icall_stmt)); + gcc_assert (!stmt_could_throw_p (cfun, vcall_stmt)); + gcc_assert (!stmt_could_throw_p (cfun, icall_stmt)); } /* Find values inside STMT for that we want to measure histograms for