aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-eh.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2018-10-22 10:27:50 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2018-10-22 10:27:50 +0200
commit36bbc05db8ef71811a7b925bbb862d0b1c3b5b89 (patch)
treec7ed4a03002467a31c3a0cf10bca6c5d06b40338 /gcc/tree-eh.c
parent3703b60c903e1cb7629c1a51cda68e53ebd8fbe8 (diff)
downloadgcc-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.c52
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;