GCC Middle and Back End API Reference
|
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "ssa.h"
#include "cgraph.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "calls.h"
#include "except.h"
#include "cfganal.h"
#include "cfgcleanup.h"
#include "tree-eh.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "tree-into-ssa.h"
#include "tree-ssa.h"
#include "tree-inline.h"
#include "langhooks.h"
#include "cfgloop.h"
#include "gimple-low.h"
#include "stringpool.h"
#include "attribs.h"
#include "asan.h"
#include "gimplify.h"
Data Structures | |
union | treemple |
struct | finally_tree_node |
struct | finally_tree_hasher |
struct | goto_queue_node |
struct | leh_state |
struct | leh_tf_state |
Macros | |
#define | LARGE_GOTO_QUEUE 20 |
#define | verify_norecord_switch_expr(state, switch_expr) |
Variables | |
static hash_table< finally_tree_hasher > * | finally_tree |
static gimple_seq | eh_seq |
static bitmap | eh_region_may_contain_throw_map |
#define LARGE_GOTO_QUEUE 20 |
Search for STMT in the goto queue. Return the replacement, or null if the statement isn't in the queue.
Referenced by find_goto_replacement().
#define verify_norecord_switch_expr | ( | state, | |
switch_expr ) |
Referenced by lower_eh_constructs_2().
void add_stmt_to_eh_lp | ( | gimple * | t, |
int | num ) |
Add statement T in the current function (cfun) to EH landing pad NUM.
References add_stmt_to_eh_lp_fn(), and cfun.
Referenced by cleanup_empty_eh(), gimple_ic(), gsi_insert_finally_seq_after_call(), input_bb(), maybe_clean_or_replace_eh_stmt(), maybe_duplicate_eh_stmt(), cgraph_edge::redirect_call_stmt_to_callee(), redirect_eh_edge_1(), and vect_finish_stmt_generation_1().
Misc functions used in this file.
Remember and lookup EH landing pad data for arbitrary statements. Really this means any statement that could_throw_p. We could stuff this information into the stmt_ann data structure, but: (1) We absolutely rely on this information being kept until we get to rtl. Once we're done with lowering here, if we lose the information there's no way to recover it! (2) There are many more statements that *cannot* throw as compared to those that can. We should be saving some amount of space by only allocating memory for those that can throw.
Add statement T in function IFUN to landing pad NUM.
References gcc_assert, get_eh_throw_stmt_table(), and set_eh_throw_stmt_table().
Referenced by add_stmt_to_eh_lp(), maybe_duplicate_eh_stmt_fn(), and record_stmt_eh_region().
|
static |
Do a post-order traversal of the EH region tree. Examine each post_landing_pad block and see if we can eliminate it as empty.
References cfun, changed, cleanup_empty_eh(), i, vec_safe_iterate(), and vec_safe_length().
Referenced by execute_cleanup_eh_1().
|
static |
Examine the block associated with LP to determine if it's an empty handler for its EH region. If so, attempt to redirect EH edges to an outer region. Return true the CFG was updated in any way. This is similar to jump forwarding, just across EH edges.
References add_stmt_to_eh_lp(), cfun, cleanup_empty_eh_merge_phis(), cleanup_empty_eh_move_lp(), cleanup_empty_eh_unsplit(), dump_file, dump_flags, EDGE_COUNT, ei_next(), ei_safe_edge(), ei_start, ERT_MUST_NOT_THROW, FOR_EACH_EDGE, gcc_assert, get_eh_region_from_lp_number(), gimple_call_builtin_p(), gsi_after_labels(), gsi_end_p(), gsi_last_bb(), gsi_last_nondebug_bb(), gsi_next_nondebug(), gsi_one_nondebug_before_end_p(), gsi_stmt(), eh_landing_pad_d::index, eh_region_d::index, infinite_empty_loop_p(), is_gimple_debug(), is_gimple_resx(), label_to_block(), lookup_stmt_eh_lp(), NULL, optimize_clobbers(), eh_landing_pad_d::post_landing_pad, basic_block_def::preds, remove_edge(), remove_eh_landing_pad(), remove_stmt_from_eh_lp(), single_succ_edge(), sink_clobbers(), stmt_can_throw_external(), basic_block_def::succs, TDF_DETAILS, and eh_region_d::type.
Referenced by cleanup_all_empty_eh().
|
static |
A subroutine of cleanup_empty_eh. Redirect all EH edges incoming to OLD_BB to NEW_BB; return true on success, false on failure. OLD_BB_OUT is the edge into NEW_BB from OLD_BB, so if we miss any PHI variables from OLD_BB we can pick them up from OLD_BB_OUT. Virtual PHIs may be deleted and marked for renaming.
References BITMAP_ALLOC, bitmap_bit_p, BITMAP_FREE, bitmap_set_bit, ei_next(), ei_safe_edge(), ei_start, find_edge(), flush_pending_stmts(), FOR_EACH_EDGE, FOR_EACH_IMM_USE_FAST, gimple_bb(), gimple_debug_bind_p(), gimple_phi_arg_def(), gimple_phi_arg_location(), gimple_phi_result(), gsi_end_p(), gsi_next(), gsi_start_phis(), has_single_use(), loop::latch, basic_block_def::loop_father, LOOPS_MAY_HAVE_MULTIPLE_LATCHES, loops_state_set(), mark_loop_for_removal(), NULL, gphi_iterator::phi(), basic_block_def::preds, redirect_edge_succ(), redirect_edge_var_map_add(), redirect_edge_var_map_clear(), redirect_eh_edge_1(), single_pred_p(), SSA_NAME_VERSION, and USE_STMT.
Referenced by cleanup_empty_eh(), and cleanup_empty_eh_unsplit().
|
static |
A subroutine of cleanup_empty_eh. Move a landing pad LP from its old region to NEW_REGION at BB.
References profile_probability::always(), gsi_last_bb(), gsi_remove(), gsi_stmt(), eh_region_d::landing_pads, eh_landing_pad_d::next_lp, eh_landing_pad_d::region, and unlink_stmt_vdef().
Referenced by cleanup_empty_eh().
|
static |
A subroutine of cleanup_empty_eh. Handle more complex cases of unsplitting than unsplit_eh was prepared to handle, e.g. when multiple incoming edges and phis are involved.
References cleanup_empty_eh_merge_phis(), dump_file, dump_flags, dyn_cast(), EH_LANDING_PAD_NR, gcc_assert, get_eh_region_from_lp_number(), gimple_label_label(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), eh_landing_pad_d::index, NULL, eh_landing_pad_d::region, and TDF_DETAILS.
Referenced by cleanup_empty_eh().
REG is current region of a LEH state. is the enclosing region for a possible cleanup region, or the region itself. Returns TRUE if such a region would be unreachable. Cleanup regions within a must-not-throw region aren't actually reachable even if there are throwing stmts within them, because the personality routine will call terminate before unwinding.
References ERT_CLEANUP, ERT_MUST_NOT_THROW, gcc_assert, eh_region_d::outer, and eh_region_d::type.
Referenced by lower_cleanup(), and lower_try_finally().
References as_a(), collect_finally_tree_1(), treemple::g, gimple_catch_handler(), gimple_eh_else_e_body(), gimple_eh_else_n_body(), gimple_eh_filter_failure(), gimple_label_label(), GIMPLE_TRY_CATCH, gimple_try_cleanup(), gimple_try_eval(), GIMPLE_TRY_FINALLY, gimple_try_kind(), record_in_finally_tree(), and treemple::t.
Referenced by collect_finally_tree_1().
|
static |
Go through the gimple sequence. Works with collect_finally_tree to record all GIMPLE_LABEL and GIMPLE_TRY statements.
References collect_finally_tree(), gsi_end_p(), gsi_next(), gsi_start(), and gsi_stmt().
Referenced by collect_finally_tree(), and lower_try_finally_dup_block().
|
static |
Decide whether or not we are going to duplicate the finally block. There are several considerations. Second, we'd like to prevent egregious code growth. One way to do this is to estimate the size of the finally block, multiply that by the number of copies we'd need to make, and compare against the estimate of the size of the switch machinery we'd have to add.
References cfun, eni_size_weights, estimate_num_insns_seq(), get_eh_else(), gimple_call_builtin_p(), gimple_clobber_p(), gimple_eh_else_n_body(), gsi_end_p(), gsi_next(), gsi_start(), gsi_stmt(), is_gimple_debug(), optimize_function_for_size_p(), and goto_queue_node::stmt.
Referenced by lower_try_finally().
|
static |
Similar, but easier, for GIMPLE_GOTO.
References goto_queue_node::cont_stmt, leh_tf_state::dest_array, gcc_assert, gimple_build_goto(), gimple_seq_add_seq(), gimple_seq_add_stmt(), gimple_set_location(), goto_queue_node::index, goto_queue_node::is_label, goto_queue_node::location, and goto_queue_node::repl_stmt.
Referenced by lower_try_finally_copy(), lower_try_finally_nofallthru(), lower_try_finally_onedest(), and lower_try_finally_switch().
|
static |
Redirect a RETURN_EXPR pointed to by Q to FINLAB. If MOD is non-null, insert it before the new branch.
References goto_queue_node::cont_stmt, treemple::g, gcc_assert, gimple_build_goto(), gimple_seq_add_seq(), gimple_seq_add_stmt(), gimple_set_location(), goto_queue_node::is_label, goto_queue_node::location, goto_queue_node::repl_stmt, and goto_queue_node::stmt.
Referenced by lower_try_finally_copy(), lower_try_finally_nofallthru(), lower_try_finally_onedest(), and lower_try_finally_switch().
Check if REGION has been marked as containing a throw. If REGION is NULL, this predicate is false.
References bitmap_bit_p, eh_region_may_contain_throw_map, and r.
Referenced by lower_catch(), lower_cleanup(), lower_eh_filter(), and lower_try_finally().
|
static |
Emit a standard landing pad sequence into SEQ for REGION.
References create_artificial_label(), EH_LANDING_PAD_NR, gen_eh_landing_pad(), gimple_build_label(), gimple_seq_add_stmt(), eh_landing_pad_d::index, eh_region_d::landing_pads, NULL, eh_landing_pad_d::post_landing_pad, leh_tf_state::region, and UNKNOWN_LOCATION.
Referenced by frob_into_branch_around(), honor_protect_cleanup_actions(), lower_try_finally_copy(), lower_try_finally_nofallthru(), lower_try_finally_onedest(), and lower_try_finally_switch().
|
static |
Emit a RESX statement into SEQ for REGION.
References gimple_build_resx(), gimple_seq_add_stmt(), eh_region_d::index, eh_region_d::outer, record_stmt_eh_region(), and leh_tf_state::region.
Referenced by honor_protect_cleanup_actions(), lower_catch(), lower_eh_filter(), lower_try_finally_copy(), lower_try_finally_onedest(), and lower_try_finally_switch().
|
static |
Perform cleanups and lowering of exception handling 1) cleanups regions with handlers doing nothing are optimized out 2) MUST_NOT_THROW regions that became dead because of 1) are optimized out 3) Info about regions that are containing instructions, and regions reachable via local EH edges is collected 4) Eh tree is pruned for regions no longer necessary. TODO: Push MUST_NOT_THROW regions to the root of the EH tree. Unify those that have the same failure decl and locus.
References CDI_DOMINATORS, CDI_POST_DOMINATORS, cfun, changed, cleanup_all_empty_eh(), delete_unreachable_blocks(), free_dominance_info(), remove_unreachable_handlers(), remove_unreachable_handlers_no_lp(), TODO_cleanup_cfg, TODO_update_ssa_only_virtuals, and unsplit_all_eh().
|
static |
References treemple::g, gcc_assert, hash_map< KeyId, Value, Traits >::get(), leh_tf_state::goto_queue, leh_tf_state::goto_queue_active, leh_tf_state::goto_queue_map, i, LARGE_GOTO_QUEUE, NULL, hash_map< KeyId, Value, Traits >::put(), goto_queue_node::repl_stmt, and goto_queue_node::stmt.
Referenced by replace_goto_queue_1(), and replace_goto_queue_cond_clause().
Return non-NULL if there is an integer operation with trapping overflow we can rewrite into non-trapping. Called via walk_tree from rewrite_to_non_trapping_overflow.
References ANY_INTEGRAL_TYPE_P, EXPR_P, IS_TYPE_OR_DECL_P, NULL, NULL_TREE, operation_no_trapping_overflow(), TREE_CODE, and TREE_TYPE.
Referenced by replace_trapping_overflow(), and rewrite_to_non_trapping_overflow().
|
static |
We want to transform try { body; } catch { stuff; } to normal_sequence: body; over: eh_sequence: landing_pad: stuff; goto over; TP is a GIMPLE_TRY node. REGION is the region whose post_landing_pad should be placed before the second operand, or NULL. OVER is an existing label that should be put at the exit, or NULL.
References create_artificial_label(), eh_seq, emit_post_landing_pad(), gimple_build_goto(), gimple_build_label(), gimple_location(), gimple_seq_add_seq(), gimple_seq_add_stmt(), gimple_seq_may_fallthru(), gimple_set_location(), gimple_try_cleanup(), gimple_try_eval(), and leh_tf_state::region.
Referenced by lower_catch(), lower_cleanup(), and lower_eh_filter().
|
inlinestatic |
A subroutine of lower_try_finally. If FINALLY consits of a GIMPLE_EH_ELSE node, return it.
References as_a(), gcc_assert, gimple_seq_first_stmt(), gimple_seq_singleton_p(), and NULL.
Referenced by decide_copy_try_finally(), honor_protect_cleanup_actions(), lower_try_finally_copy(), lower_try_finally_nofallthru(), lower_try_finally_onedest(), and lower_try_finally_switch().
|
static |
A subroutine of lower_try_finally. If the eh_protect_cleanup_actions langhook returns non-null, then the language requires that the exception path out of a try_finally be treated specially. To wit: the code within the finally block may not itself throw an exception. We have two choices here. First we can duplicate the finally block and wrap it in a must_not_throw region. Second, we can generate code like try { finally_block; } catch { if (fintmp == eh_edge) protect_cleanup_actions; } where "fintmp" is the temporary used in the switch statement generation alternative considered below. For the nonce, we always choose the first option. THIS_STATE may be null if this is a try-cleanup, not a try-finally.
References leh_state::cur_region, lang_hooks::eh_protect_cleanup_actions, eh_seq, leh_state::ehp_region, emit_post_landing_pad(), emit_resx(), get_eh_else(), gimple_build_eh_must_not_throw(), gimple_build_try(), gimple_eh_else_e_body(), gimple_eh_else_n_body(), gimple_location(), gimple_seq_add_seq(), gimple_seq_alloc_with_stmt(), gimple_seq_may_fallthru(), GIMPLE_TRY_CATCH, gimple_try_catch_is_cleanup(), gimple_try_cleanup(), gimple_try_eval(), gimple_try_kind(), gimple_try_set_cleanup(), gsi_insert_seq_before(), gsi_remove(), GSI_SAME_STMT, gsi_start(), gsi_stmt(), lower_eh_constructs_1(), lower_eh_must_not_throw(), lower_try_finally_dup_block(), leh_tf_state::may_throw, NULL, leh_tf_state::region, leh_tf_state::top_p, and leh_tf_state::try_finally_expr.
Referenced by lower_cleanup(), and lower_try_finally().
Returns true if it is possible to prove that the index of an array access REF (an ARRAY_REF expression) falls into the array bounds.
References array_ref_low_bound(), array_ref_up_bound(), TREE_CODE, tree_int_cst_lt(), and TREE_OPERAND.
Referenced by tree_could_trap_p().
Return true if edge E_FIRST is part of an empty infinite loop or leads to such a loop through a series of single successor empty bbs.
References gsi_after_labels(), gsi_end_p(), gsi_next_nondebug(), gsi_stmt(), is_gimple_debug(), NULL, single_succ_edge(), and single_succ_p().
Referenced by cleanup_empty_eh().
int lookup_stmt_eh_lp | ( | const gimple * | t | ) |
Likewise, but always use the current function.
References cfun, and lookup_stmt_eh_lp_fn().
Referenced by check_call(), cleanup_empty_eh(), copy_reference_ops_from_call(), expand_call_inline(), expand_gimple_stmt(), gimple_ic(), gsi_insert_finally_seq_after_call(), hashable_expr_equal_p(), lower_resx(), make_eh_edge(), mark_reachable_handlers(), maybe_clean_or_replace_eh_stmt(), maybe_duplicate_eh_stmt(), pp_gimple_stmt_1(), cgraph_edge::redirect_call_stmt_to_callee(), redirect_eh_edge_1(), vect_finish_stmt_generation_1(), verify_eh_edges(), and verify_gimple_in_cfg().
Determine if statement T is inside an EH region in function IFUN. Positive numbers indicate a landing pad index; negative numbers indicate a MUST_NOT_THROW region index; zero indicates that the statement is not recorded in the region table.
References function::eh, hash_map< KeyId, Value, Traits >::get(), NULL, and eh_status::throw_stmt_table.
Referenced by ipa_icf_gimple::func_checker::compare_bb(), find_outermost_region_in_block(), lookup_stmt_eh_lp(), maybe_duplicate_eh_stmt_fn(), merge_stmts_p(), output_bb(), stmt_can_throw_external(), and stmt_can_throw_internal().
|
static |
A subroutine of lower_eh_constructs_1. Lower a GIMPLE_TRY_CATCH with a list of GIMPLE_CATCH to a sequence of labels and blocks, plus the exception region trees that records all the magic.
References as_a(), create_artificial_label(), leh_state::cur_region, eh_region_may_contain_throw(), eh_seq, leh_state::ehp_region, emit_resx(), frob_into_branch_around(), gen_eh_region_catch(), gen_eh_region_try(), gimple_build_eh_dispatch(), gimple_build_goto(), gimple_build_label(), gimple_catch_handler(), gimple_catch_types(), gimple_location(), gimple_seq_add_seq(), gimple_seq_add_stmt(), gimple_seq_may_fallthru(), gimple_set_location(), gimple_try_cleanup(), gimple_try_eval(), gimple_try_eval_ptr(), gimple_try_set_cleanup(), gsi_end_p(), gsi_next(), gsi_start(), gsi_stmt(), eh_region_d::index, eh_catch_d::label, lower_eh_constructs_1(), NULL, leh_state::outer_non_cleanup, eh_catch_d::type_list, and UNKNOWN_LOCATION.
Referenced by lower_eh_constructs_2().
|
static |
Implement a cleanup expression. This is similar to try-finally, except that we only execute the cleanup block for exception edges.
References cleanup_is_dead_in(), leh_state::cur_region, eh_region_may_contain_throw(), leh_tf_state::fallthru_label, frob_into_branch_around(), gen_eh_region_cleanup(), gimple_build_label(), gimple_seq_add_stmt(), gimple_seq_may_fallthru(), gimple_try_cleanup_ptr(), gimple_try_eval(), gimple_try_eval_ptr(), honor_protect_cleanup_actions(), lower_eh_constructs_1(), leh_tf_state::may_fallthru, leh_tf_state::may_throw, NULL, leh_tf_state::outer, leh_state::outer_non_cleanup, leh_tf_state::region, leh_tf_state::top_p, and leh_tf_state::try_finally_expr.
Referenced by lower_eh_constructs_2().
|
static |
A helper to unwrap a gimple_seq and feed stmts to lower_eh_constructs_2.
References gsi_end_p(), gsi_start(), and lower_eh_constructs_2().
Referenced by honor_protect_cleanup_actions(), lower_catch(), lower_cleanup(), lower_eh_constructs_2(), lower_eh_filter(), lower_eh_must_not_throw(), lower_try_finally(), lower_try_finally_copy(), lower_try_finally_nofallthru(), lower_try_finally_onedest(), and lower_try_finally_switch().
|
static |
Main loop for lowering eh constructs. Also moves gsi to the next statement.
References as_a(), build_int_cst(), BUILT_IN_NORMAL, cfun, create_tmp_var, DECL_FUNCTION_CODE(), fndecl_built_in_p(), gcc_unreachable, gimple_block(), gimple_build_assign(), gimple_call_fndecl(), gimple_call_lhs(), gimple_call_set_arg(), gimple_get_lhs(), gimple_has_lhs(), gimple_location(), gimple_seq_first_stmt(), gimple_set_block(), gimple_set_lhs(), gimple_set_location(), gimple_stmt_may_fallthru(), gimple_try_cleanup(), gimple_try_eval(), GIMPLE_TRY_FINALLY, gimple_try_kind(), gsi_insert_after(), gsi_insert_before(), gsi_insert_seq_before(), gsi_next(), gsi_remove(), GSI_SAME_STMT, gsi_stmt(), integer_type_node, is_gimple_reg_type(), lower_catch(), lower_cleanup(), lower_eh_constructs_1(), lower_eh_filter(), lower_eh_must_not_throw(), lower_try_finally(), maybe_record_in_goto_queue(), note_eh_region_may_contain_throw(), nr, null_pointer_node, record_stmt_eh_region(), stmt_could_throw_p(), tree_could_throw_p(), TREE_TYPE, and verify_norecord_switch_expr.
Referenced by lower_eh_constructs_1().
|
static |
At the end of inlining, we can lower EH_DISPATCH. Return true when we have found some duplicate labels and removed some edges.
References hash_set< KeyId, Lazy, Traits >::add(), BRANCH_EDGE, build_case_label(), build_int_cst(), builtin_decl_implicit(), cfun, hash_set< KeyId, Lazy, Traits >::contains(), create_tmp_var, ERT_ALLOWED_EXCEPTIONS, ERT_TRY, FALLTHRU_EDGE, eh_catch_d::filter_list, find_edge(), FOR_EACH_EDGE, gcc_assert, gcc_unreachable, get_eh_region_from_number(), gimple_block_label(), gimple_build_call(), gimple_build_cond(), gimple_build_switch(), gimple_call_set_lhs(), gimple_eh_dispatch_region(), gimple_location(), gimple_set_location(), gsi_insert_before(), gsi_last_bb(), gsi_remove(), GSI_SAME_STMT, integer_type_node, eh_catch_d::label, label_to_block(), make_ssa_name(), eh_catch_d::next_catch, NULL, NULL_TREE, r, remove_edge(), single_succ_edge(), sort_case_labels(), basic_block_def::succs, TREE_CHAIN, TREE_TYPE, TREE_VALUE, and eh_catch_d::type_list.
|
static |
A subroutine of lower_eh_constructs_1. Lower a GIMPLE_TRY with a GIMPLE_EH_FILTER to a sequence of labels and blocks, plus the exception region trees that record all the magic.
References eh_region_d::eh_region_u::allowed, create_artificial_label(), leh_state::cur_region, eh_region_may_contain_throw(), leh_state::ehp_region, emit_resx(), frob_into_branch_around(), gen_eh_region_allowed(), gimple_build_eh_dispatch(), gimple_build_label(), gimple_eh_filter_failure(), gimple_eh_filter_failure_ptr(), gimple_eh_filter_types(), gimple_location(), gimple_seq_add_seq(), gimple_seq_add_stmt(), gimple_seq_first_stmt(), gimple_set_location(), gimple_try_cleanup(), gimple_try_eval(), gimple_try_eval_ptr(), gimple_try_set_cleanup(), eh_region_d::index, eh_region_d::eh_region_u::eh_region_u_allowed::label, lower_eh_constructs_1(), NULL, leh_state::outer_non_cleanup, eh_region_d::u, and UNKNOWN_LOCATION.
Referenced by lower_eh_constructs_2().
|
static |
A subroutine of lower_eh_constructs_1. Lower a GIMPLE_TRY with an GIMPLE_EH_MUST_NOT_THROW to a sequence of labels and blocks, plus the exception region trees that record all the magic.
References as_a(), leh_state::cur_region, eh_region_d::eh_region_u::eh_region_u_must_not_throw::failure_decl, eh_region_d::eh_region_u::eh_region_u_must_not_throw::failure_loc, gen_eh_region_must_not_throw(), gimple_eh_must_not_throw_fndecl(), gimple_location(), gimple_seq_first_stmt(), gimple_try_cleanup(), gimple_try_eval(), gimple_try_eval_ptr(), LOCATION_LOCUS, lower_eh_constructs_1(), eh_region_d::eh_region_u::must_not_throw, leh_state::outer_non_cleanup, TREE_USED, and eh_region_d::u.
Referenced by honor_protect_cleanup_actions(), and lower_eh_constructs_2().
|
static |
At the end of gimple optimization, we can lower RESX.
References add_bb_to_loop(), profile_probability::always(), build_int_cst(), builtin_decl_implicit(), cfun, basic_block_def::count, create_empty_bb(), create_tmp_var, EDGE_COUNT, EDGE_SUCC, ERT_MUST_NOT_THROW, eh_region_d::eh_region_u::eh_region_u_must_not_throw::failure_decl, eh_region_d::eh_region_u::eh_region_u_must_not_throw::failure_loc, FOR_EACH_EDGE, g, gcc_assert, hash_map< KeyId, Value, Traits >::get(), get_eh_landing_pad_from_number(), get_eh_region_from_lp_number(), get_eh_region_from_number(), gimple_block_label(), gimple_build_call(), gimple_call_set_ctrl_altering(), gimple_call_set_lhs(), gimple_location(), gimple_resx_region(), gimple_set_location(), GSI_CONTINUE_LINKING, gsi_insert_after(), gsi_insert_before(), gsi_last_bb(), gsi_remove(), GSI_SAME_STMT, gsi_start_bb(), eh_region_d::index, integer_type_node, label_to_block(), lookup_stmt_eh_lp(), basic_block_def::loop_father, make_single_succ_edge(), make_ssa_name(), eh_region_d::eh_region_u::must_not_throw, NULL, ptr_type_node, hash_map< KeyId, Value, Traits >::put(), remove_edge(), remove_eh_landing_pad(), SANITIZE_ADDRESS, sanitize_flags_p(), single_succ_edge(), basic_block_def::succs, TREE_TYPE, eh_region_d::type, TYPE_ARG_TYPES, eh_region_d::u, eh_region_d::use_cxa_end_cleanup, and void_list_node.
|
static |
A subroutine of lower_eh_constructs_1. Lower a GIMPLE_TRY_FINALLY nodes to a sequence of labels and blocks, plus the exception region trees that record all the magic. This is complicated by the need to arrange for the FINALLY block to be executed on all exits.
References cleanup_is_dead_in(), leh_state::cur_region, decide_copy_try_finally(), leh_tf_state::dest_array, eh_region_may_contain_throw(), eh_seq, leh_state::ehp_region, leh_tf_state::fallthru_label, free(), gen_eh_region_cleanup(), gimple_build_label(), gimple_seq_add_seq(), gimple_seq_add_stmt(), gimple_seq_may_fallthru(), gimple_try_cleanup(), gimple_try_eval(), gimple_try_eval_ptr(), gimple_try_set_cleanup(), leh_tf_state::goto_queue, leh_tf_state::goto_queue_map, honor_protect_cleanup_actions(), lower_eh_constructs_1(), lower_try_finally_copy(), lower_try_finally_nofallthru(), lower_try_finally_onedest(), lower_try_finally_switch(), leh_tf_state::may_fallthru, leh_tf_state::may_return, leh_tf_state::may_throw, NULL, leh_tf_state::outer, leh_state::outer_non_cleanup, leh_tf_state::region, leh_state::tf, leh_tf_state::top_p, leh_tf_state::top_p_seq, leh_tf_state::try_finally_expr, and using_eh_for_cleanups_p().
Referenced by lower_eh_constructs_2().
|
static |
A subroutine of lower_try_finally. There are multiple edges incoming and outgoing from the finally block. Implement this by duplicating the finally block for every destination.
References goto_queue_node::cont_stmt, create_artificial_label(), leh_tf_state::dest_array, do_goto_redirection(), do_return_redirection(), eh_seq, emit_post_landing_pad(), emit_resx(), free(), get_eh_else(), gimple_build_goto(), gimple_build_label(), gimple_eh_else_e_body(), gimple_eh_else_n_body(), gimple_location(), gimple_seq_add_seq(), gimple_seq_add_stmt(), gimple_set_location(), gimple_try_cleanup(), gimple_try_eval(), leh_tf_state::goto_queue, leh_tf_state::goto_queue_active, goto_queue_node::index, goto_queue_node::location, lower_eh_constructs_1(), lower_try_finally_dup_block(), lower_try_finally_fallthru_label(), leh_tf_state::may_fallthru, leh_tf_state::may_throw, maybe_record_in_goto_queue(), NULL, leh_tf_state::region, replace_goto_queue(), leh_tf_state::top_p, leh_tf_state::top_p_seq, and leh_tf_state::try_finally_expr.
Referenced by lower_try_finally().
|
static |
A subroutine of lower_try_finally. Duplicate the tree rooted at T. Make sure to record all new labels found.
References collect_finally_tree_1(), copy_gimple_seq_and_replace_locals(), gimple_block(), gimple_location(), gimple_set_block(), gimple_set_location(), gsi_end_p(), gsi_next(), gsi_start(), gsi_stmt(), LOCATION_LOCUS, NULL, leh_tf_state::region, leh_state::tf, leh_tf_state::try_finally_expr, and UNKNOWN_LOCATION.
Referenced by honor_protect_cleanup_actions(), and lower_try_finally_copy().
|
static |
A subroutine of lower_try_finally. Create a fallthru label for the given try_finally state. The only tricky bit here is that we have to make sure to record the label in our outer context.
References create_artificial_label(), leh_tf_state::fallthru_label, gimple_location(), leh_tf_state::outer, record_in_finally_tree(), treemple::t, leh_state::tf, and leh_tf_state::try_finally_expr.
Referenced by lower_try_finally_copy(), and lower_try_finally_switch().
|
static |
A subroutine of lower_try_finally. We have determined that there is no fallthru edge out of the finally block. This means that there is no outgoing edge corresponding to any incoming edge. Restructure the try_finally node for this special case.
References create_artificial_label(), do_goto_redirection(), do_return_redirection(), eh_seq, emit_post_landing_pad(), get_eh_else(), gimple_build_goto(), gimple_build_label(), gimple_eh_else_e_body(), gimple_eh_else_n_body(), gimple_location(), gimple_seq_add_seq(), gimple_seq_add_stmt(), gimple_set_location(), gimple_try_cleanup(), gimple_try_eval(), leh_tf_state::goto_queue, leh_tf_state::goto_queue_active, goto_queue_node::index, lower_eh_constructs_1(), leh_tf_state::may_throw, NULL, leh_tf_state::region, replace_goto_queue(), leh_tf_state::top_p, leh_tf_state::top_p_seq, and leh_tf_state::try_finally_expr.
Referenced by lower_try_finally().
|
static |
A subroutine of lower_try_finally. We have determined that there is exactly one destination of the finally block. Restructure the try_finally node for this special case.
References goto_queue_node::cont_stmt, create_artificial_label(), leh_tf_state::dest_array, do_goto_redirection(), do_return_redirection(), eh_seq, emit_post_landing_pad(), emit_resx(), leh_tf_state::fallthru_label, get_eh_else(), gimple_block(), gimple_build_label(), gimple_eh_else_e_body(), gimple_eh_else_n_body(), gimple_location(), gimple_seq_add_seq(), gimple_seq_add_stmt(), gimple_set_block(), gimple_set_location(), gimple_try_cleanup(), gimple_try_eval(), leh_tf_state::goto_queue, leh_tf_state::goto_queue_active, gsi_end_p(), gsi_next(), gsi_start(), gsi_stmt(), LOCATION_LOCUS, lower_eh_constructs_1(), leh_tf_state::may_fallthru, leh_tf_state::may_return, leh_tf_state::may_throw, maybe_record_in_goto_queue(), NULL, leh_tf_state::region, replace_goto_queue(), goto_queue_node::stmt, leh_tf_state::top_p, leh_tf_state::top_p_seq, leh_tf_state::try_finally_expr, and UNKNOWN_LOCATION.
Referenced by lower_try_finally().
|
static |
A subroutine of lower_try_finally. There are multiple edges incoming and outgoing from the finally block. Implement this by instrumenting each incoming edge and creating a switch statement at the end of the finally block that branches to the appropriate destination.
References build_case_label(), build_int_cst(), CASE_LABEL, CASE_LOW, goto_queue_node::cont_stmt, create_artificial_label(), create_tmp_var, leh_tf_state::dest_array, do_goto_redirection(), do_return_redirection(), eh_seq, emit_post_landing_pad(), emit_resx(), gcc_assert, hash_map< KeyId, Value, Traits >::get(), get_eh_else(), gimple_build_assign(), gimple_build_goto(), gimple_build_label(), gimple_build_switch(), gimple_eh_else_e_body(), gimple_eh_else_n_body(), gimple_location(), gimple_seq_add_seq(), gimple_seq_add_stmt(), gimple_seq_last_stmt(), gimple_set_location(), gimple_try_cleanup(), gimple_try_eval(), leh_tf_state::goto_queue, leh_tf_state::goto_queue_active, goto_queue_node::index, integer_type_node, lower_eh_constructs_1(), lower_try_finally_fallthru_label(), leh_tf_state::may_fallthru, leh_tf_state::may_return, leh_tf_state::may_throw, maybe_record_in_goto_queue(), NULL, hash_map< KeyId, Value, Traits >::put(), leh_tf_state::region, replace_goto_queue(), sort_case_labels(), leh_tf_state::top_p, leh_tf_state::top_p_seq, and leh_tf_state::try_finally_expr.
Referenced by lower_try_finally().
bool make_eh_dispatch_edges | ( | geh_dispatch * | stmt | ) |
Create the multiple edges from an EH_DISPATCH statement to all of the possible handlers for its EH region. Return true if there's no fallthru edge; false if there is.
References cfun, ERT_ALLOWED_EXCEPTIONS, ERT_TRY, gcc_unreachable, get_eh_region_from_number(), gimple_bb(), gimple_eh_dispatch_region(), eh_catch_d::label, label_to_block(), make_edge(), eh_catch_d::next_catch, NULL, r, and eh_catch_d::type_list.
Referenced by copy_edges_for_bb(), and make_edges_bb().
Create the single EH edge from STMT to its nearest landing pad, if there is such a landing pad within the current function.
References cfun, gcc_assert, get_eh_landing_pad_from_number(), gimple_bb(), label_to_block(), lookup_stmt_eh_lp(), make_edge(), NULL, and eh_landing_pad_d::post_landing_pad.
Referenced by copy_edges_for_bb(), gsi_insert_finally_seq_after_call(), and make_edges_bb().
gimple_opt_pass * make_pass_cleanup_eh | ( | gcc::context * | ctxt | ) |
gimple_opt_pass * make_pass_lower_eh | ( | gcc::context * | ctxt | ) |
gimple_opt_pass * make_pass_lower_eh_dispatch | ( | gcc::context * | ctxt | ) |
gimple_opt_pass * make_pass_lower_resx | ( | gcc::context * | ctxt | ) |
gimple_opt_pass * make_pass_refactor_eh | ( | gcc::context * | ctxt | ) |
Walk statements, see what regions and, optionally, landing pads are really referenced. Returns in R_REACHABLEP an sbitmap with bits set for reachable regions, and in LP_REACHABLE an sbitmap with bits set for reachable landing pads. Passing NULL for LP_REACHABLE is valid, in this case only reachable regions are marked. The caller is responsible for freeing the returned sbitmaps.
References as_a(), bitmap_clear(), bitmap_set_bit, cfun, FOR_EACH_BB_FN, gcc_assert, gcc_checking_assert, get_eh_region_from_lp_number(), gimple_call_arg(), gimple_call_builtin_p(), gimple_eh_dispatch_region(), gimple_resx_region(), gsi_end_p(), gsi_next(), gsi_one_before_end_p(), gsi_start_bb(), gsi_stmt(), i, eh_region_d::index, lookup_stmt_eh_lp(), NULL, sbitmap_alloc(), and tree_to_shwi().
Referenced by remove_unreachable_handlers(), and remove_unreachable_handlers_no_lp().
Likewise, but always use the current function.
References cfun, and maybe_clean_eh_stmt_fn().
Referenced by ipcp_modif_dom_walker::before_dom_children(), execute_fixup_cfg(), expand_complex_comparison(), expand_vector_operations(), instrument_builtin_call(), ipa_simd_modify_function_body(), ipa_param_body_adjustments::modify_cfun_body(), redirect_all_calls(), and sra_modify_function_body().
Given a statement STMT in IFUN, if STMT can no longer throw, then remove any entry it might have from the EH table. Return true if any change was made.
References remove_stmt_from_eh_lp_fn(), and stmt_could_throw_p().
Referenced by maybe_clean_eh_stmt(), and update_call_expr().
Given a statement OLD_STMT and a new statement NEW_STMT that has replaced OLD_STMT in the function, remove OLD_STMT from the EH table and put NEW_STMT in the table if it should be in there. Return TRUE if a replacement was done that my require an EH edge purge.
References add_stmt_to_eh_lp(), cfun, lookup_stmt_eh_lp(), remove_stmt_from_eh_lp(), and stmt_could_throw_p().
Referenced by substitute_and_fold_dom_walker::before_dom_children(), convert_mult_to_fma_1(), eliminate_dom_walker::eliminate_cleanup(), eliminate_dom_walker::eliminate_stmt(), eliminate_unnecessary_stmts(), expand_call_inline(), fold_marked_statements(), gsi_replace(), strlen_pass::handle_integral_assign(), instrument_builtin_call(), optimize_atomic_bit_test_and(), optimize_atomic_op_fetch_cmp_0(), dom_opt_dom_walker::optimize_stmt(), replace_uses_by(), tidy_after_forward_propagate_addr(), and update_complex_assignment().
Similar, but both OLD_STMT and NEW_STMT are within the current function, and thus no remapping is required.
References add_stmt_to_eh_lp(), cfun, lookup_stmt_eh_lp(), and stmt_could_throw_p().
Referenced by gimple_duplicate_bb().
bool maybe_duplicate_eh_stmt_fn | ( | struct function * | new_fun, |
gimple * | new_stmt, | ||
struct function * | old_fun, | ||
gimple * | old_stmt, | ||
hash_map< void *, void * > * | map, | ||
int | default_lp_nr ) |
Given a statement OLD_STMT in OLD_FUN and a duplicate statement NEW_STMT in NEW_FUN, copy the EH table data from OLD_STMT to NEW_STMT. The MAP operand is the return value of duplicate_eh_regions.
References add_stmt_to_eh_lp_fn(), function::eh, eh_landing_pad_d::index, eh_region_d::index, lookup_stmt_eh_lp_fn(), eh_status::lp_array, map, eh_status::region_array, and stmt_could_throw_p().
Referenced by copy_bb(), and move_block_to_fn().
For any GIMPLE_GOTO or GIMPLE_RETURN, decide whether it leaves a try_finally node, and if so record that fact in the goto queue associated with that try_finally node.
References as_a(), EXPR_LOCATION, treemple::g, gcc_unreachable, gimple_cond_false_label(), gimple_cond_true_label(), gimple_goto_dest(), gimple_location(), gimple_op_ptr(), leh_tf_state::may_return, record_in_goto_queue(), record_in_goto_queue_label(), and treemple::tp.
Referenced by lower_eh_constructs_2(), lower_try_finally_copy(), lower_try_finally_onedest(), and lower_try_finally_switch().
void maybe_remove_unreachable_handlers | ( | void | ) |
Remove unreachable handlers if any landing pads have been removed after last ehcleanup pass (due to gimple_purge_dead_eh_edges).
References cfun, FOR_EACH_VEC_SAFE_ELT, i, label_to_block(), NULL, NULL_TREE, eh_landing_pad_d::post_landing_pad, and remove_unreachable_handlers().
Referenced by execute_cleanup_cfg_post_optimizing(), and unsplit_eh_edges().
|
static |
Note that the current EH region may contain a throw, or a call to a function which itself may contain a throw.
References bitmap_set_bit, eh_region_may_contain_throw_map, ERT_MUST_NOT_THROW, eh_region_d::index, NULL, eh_region_d::outer, leh_tf_state::region, and eh_region_d::type.
Referenced by lower_eh_constructs_2().
bool operation_could_trap_helper_p | ( | enum tree_code | op, |
bool | fp_operation, | ||
bool | honor_trapv, | ||
bool | honor_nans, | ||
bool | honor_snans, | ||
tree | divisor, | ||
bool * | handled ) |
Helper function for operation_could_trap_p and stmt_could_throw_p.
References fixed_zerop(), i, integer_zerop(), TREE_CODE, TREE_CONSTANT, TREE_TYPE, TYPE_VECTOR_SUBPARTS(), vector_cst_elt(), vector_cst_encoded_nelts(), and VECTOR_CST_STEPPED_P.
Referenced by operation_could_trap_p(), stmt_could_throw_1_p(), and vn_nary_may_trap().
bool operation_could_trap_p | ( | enum tree_code | op, |
bool | fp_operation, | ||
bool | honor_trapv, | ||
tree | divisor ) |
Return true if operation OP may trap. FP_OPERATION is true if OP is applied on floating-point values. HONOR_TRAPV is true if OP is applied on integer type operands that may trap. If OP is a division operator, DIVISOR contains the value of the divisor.
References gcc_assert, operation_could_trap_helper_p(), tcc_binary, tcc_comparison, tcc_unary, and TREE_CODE_CLASS.
Referenced by expand_omp_for_init_vars(), fold_binary_op_with_conditional_arg(), gimple_could_trap_p_1(), maybe_resimplify_conditional_op(), replace_stmt_with_simplification(), stmt_could_throw_p(), and tree_could_trap_p().
|
static |
Try to optimize var = {v} {CLOBBER} stmts followed just by external throw.
References FOR_EACH_EDGE, gimple_call_builtin_p(), gimple_clobber_p(), gsi_end_p(), gsi_last_bb(), gsi_prev(), gsi_remove(), gsi_stmt(), is_gimple_debug(), NULL, basic_block_def::preds, release_defs(), and unlink_stmt_vdef().
Referenced by cleanup_empty_eh().
Optimize try { A() } finally { try { ~B() } catch { ~A() } } try { ... } finally { ~A() } into try { A() } catch { ~B() } try { ~B() ... } finally { ~A() } This occurs frequently in C++, where A is a local variable and B is a temporary used in the initializer for A.
References copy_gimple_seq_and_replace_locals(), gimple_seq_add_seq(), GIMPLE_TRY_CATCH, gimple_try_cleanup(), gimple_try_eval(), gimple_try_kind(), gimple_try_set_cleanup(), gimple_try_set_eval(), gimple_try_set_kind(), gsi_one_before_end_p(), gsi_start(), gsi_stmt(), and same_handler_p().
Referenced by refactor_eh_r().
Use the finally tree to determine if a jump from START to TARGET would leave the try_finally node that START lives in.
References finally_tree_node::child, finally_tree, and finally_tree_node::parent.
Referenced by record_in_goto_queue_label().
Returns true if it is possible to prove that the range of an array access REF (an ARRAY_RANGE_REF expression) falls into the array bounds.
References array_ref_low_bound(), array_ref_up_bound(), TREE_CODE, tree_int_cst_lt(), TREE_TYPE, TYPE_DOMAIN, TYPE_MAX_VALUE, and TYPE_MIN_VALUE.
Referenced by tree_could_trap_p().
References finally_tree_node::child, finally_tree, gcc_assert, and finally_tree_node::parent.
Referenced by collect_finally_tree(), and lower_try_finally_fallthru_label().
|
static |
Add a new record to the goto queue contained in TF. NEW_STMT is the data to be added, IS_LABEL indicates whether NEW_STMT is a label or a gimple return.
References gcc_assert, leh_tf_state::goto_queue, leh_tf_state::goto_queue_active, leh_tf_state::goto_queue_map, leh_tf_state::goto_queue_size, goto_queue_node::index, goto_queue_node::is_label, goto_queue_node::location, and goto_queue_node::stmt.
Referenced by maybe_record_in_goto_queue(), and record_in_goto_queue_label().
|
static |
Record the LABEL label in the goto queue contained in TF. TF is not null.
References leh_tf_state::dest_array, goto_queue_node::index, goto_queue_node::location, outside_finally_tree(), record_in_goto_queue(), goto_queue_node::stmt, treemple::t, TREE_CODE, and leh_tf_state::try_finally_expr.
Referenced by maybe_record_in_goto_queue().
Add statement T to the single EH landing pad in REGION.
References add_stmt_to_eh_lp_fn(), cfun, ERT_MUST_NOT_THROW, gcc_assert, gen_eh_landing_pad(), eh_landing_pad_d::index, eh_region_d::index, eh_region_d::landing_pads, eh_landing_pad_d::next_lp, NULL, and eh_region_d::type.
Referenced by emit_resx(), and lower_eh_constructs_2().
void redirect_eh_dispatch_edge | ( | geh_dispatch * | stmt, |
edge | e, | ||
basic_block | new_bb ) |
This is a subroutine of gimple_redirect_edge_and_branch. Update the labels for redirecting a non-fallthru EH_DISPATCH edge E to NEW_BB. The actual edge update will happen in the caller.
References cfun, ERT_ALLOWED_EXCEPTIONS, ERT_TRY, gcc_assert, gcc_unreachable, get_eh_region_from_number(), gimple_block_label(), gimple_eh_dispatch_region(), eh_catch_d::label, label_to_block(), eh_catch_d::next_catch, and r.
Referenced by gimple_redirect_edge_and_branch().
edge redirect_eh_edge | ( | edge | edge_in, |
basic_block | new_bb ) |
Redirect EH edge E to NEW_BB.
References redirect_eh_edge_1(), and ssa_redirect_edge().
Referenced by gimple_redirect_edge_and_branch().
|
static |
Do the work in redirecting EDGE_IN to NEW_BB within the EH region tree; do not actually perform the final edge redirection. CHANGE_REGION is true when we're being called from cleanup_empty_eh and we intend to change the destination EH region as well; this means EH_LANDING_PAD_NR must already be set on the destination block label. If false, we're being called from generic cfg manipulation code and we should preserve our place within the region tree.
References add_stmt_to_eh_lp(), EH_LANDING_PAD_NR, FOR_EACH_EDGE, gcc_assert, gcc_checking_assert, gen_eh_landing_pad(), get_eh_landing_pad_from_number(), gimple_block_label(), gsi_last_bb(), eh_landing_pad_d::index, lookup_stmt_eh_lp(), NULL, eh_landing_pad_d::post_landing_pad, basic_block_def::preds, eh_landing_pad_d::region, remove_eh_landing_pad(), and remove_stmt_from_eh_lp().
Referenced by cleanup_empty_eh_merge_phis(), redirect_eh_edge(), and unsplit_eh().
|
static |
Perform EH refactoring optimizations that are simpler to do when code flow has been lowered but EH structures haven't.
References as_a(), dyn_cast(), gimple_catch_handler(), gimple_eh_else_e_body(), gimple_eh_else_n_body(), gimple_eh_filter_failure(), gimple_try_cleanup(), gimple_try_eval(), GIMPLE_TRY_FINALLY, gimple_try_kind(), gsi_end_p(), gsi_next(), gsi_start(), gsi_stmt(), NULL, optimize_double_finally(), and refactor_eh_r().
Referenced by refactor_eh_r().
Remove statement T in the current function (cfun) from its EH landing pad.
References cfun, and remove_stmt_from_eh_lp_fn().
Referenced by cleanup_empty_eh(), gsi_remove(), maybe_clean_or_replace_eh_stmt(), cgraph_edge::redirect_call_stmt_to_callee(), and redirect_eh_edge_1().
Remove statement T in function IFUN from its EH landing pad.
References get_eh_throw_stmt_table(), and hash_map< KeyId, Value, Traits >::remove().
Referenced by maybe_clean_eh_stmt_fn(), move_block_to_fn(), and remove_stmt_from_eh_lp().
|
static |
Remove unreachable handlers and unreachable landing pads.
References bitmap_bit_p, cfun, dump_bitmap_file(), dump_eh_tree(), dump_file, FOR_EACH_VEC_SAFE_ELT, i, eh_landing_pad_d::index, eh_region_d::index, mark_reachable_handlers(), remove_eh_landing_pad(), remove_unreachable_eh_regions(), sbitmap_free(), and verify_eh_tree().
Referenced by execute_cleanup_eh_1(), and maybe_remove_unreachable_handlers().
|
static |
Remove regions that do not have landing pads. This assumes that remove_unreachable_handlers has already been run, and that we've just manipulated the landing pads since then. Preserve regions with landing pads and regions that prevent exceptions from propagating further, even if these regions are not reachable.
References bitmap_bit_p, bitmap_set_bit, cfun, dump_file, ERT_MUST_NOT_THROW, FOR_EACH_VEC_SAFE_ELT, i, eh_region_d::index, eh_region_d::landing_pads, mark_reachable_handlers(), NULL, remove_unreachable_eh_regions(), sbitmap_free(), and eh_region_d::type.
Referenced by execute_cleanup_eh_1().
|
static |
Replace all goto queue members.
References eh_seq, leh_tf_state::goto_queue_active, replace_goto_queue_stmt_list(), and leh_tf_state::top_p_seq.
Referenced by lower_try_finally_copy(), lower_try_finally_nofallthru(), lower_try_finally_onedest(), and lower_try_finally_switch().
|
static |
References as_a(), find_goto_replacement(), treemple::g, gimple_catch_handler_ptr(), gimple_eh_else_e_body_ptr(), gimple_eh_else_n_body_ptr(), gimple_eh_filter_failure_ptr(), gimple_location(), gimple_op_ptr(), gimple_seq_copy(), gimple_set_location(), gimple_try_cleanup_ptr(), gimple_try_eval_ptr(), gsi_end_p(), gsi_insert_seq_before(), gsi_next(), gsi_remove(), GSI_SAME_STMT, gsi_start(), gsi_stmt(), i, NULL, replace_goto_queue_cond_clause(), replace_goto_queue_stmt_list(), and goto_queue_node::stmt.
Referenced by replace_goto_queue_stmt_list().
|
static |
A subroutine of replace_goto_queue_1. Handles the sub-clauses of a lowered GIMPLE_COND. If, by chance, the replacement is a simple goto, then we can just splat it in, otherwise we add the new stmts immediately after the GIMPLE_COND and redirect.
References create_artificial_label(), find_goto_replacement(), gimple_build_label(), gimple_goto_dest(), gimple_location(), gimple_seq_copy(), gimple_seq_first_stmt(), gimple_seq_singleton_p(), GSI_CONTINUE_LINKING, gsi_insert_after(), gsi_insert_seq_after(), gsi_stmt(), and treemple::tp.
Referenced by replace_goto_queue_1().
|
static |
The real work of replace_goto_queue. Returns with TSI updated to point to the next statement.
A subroutine of replace_goto_queue. Handles GIMPLE_SEQ.
References gsi_end_p(), gsi_start(), gsi_stmt(), and replace_goto_queue_1().
Referenced by replace_goto_queue(), and replace_goto_queue_1().
Rewrite selected operations into unsigned arithmetics, so that they don't trap on overflow.
References find_trapping_overflow(), fold_convert, i, NULL_TREE, replace_trapping_overflow(), TREE_CODE, TREE_OPERAND, TREE_OPERAND_LENGTH, TREE_SET_CODE, TREE_TYPE, unsigned_type_for(), and walk_tree.
Referenced by replace_trapping_overflow(), and rewrite_to_non_trapping_overflow().
If any subexpression of EXPR can trap due to -ftrapv, rewrite it using unsigned arithmetics to avoid traps in it.
References hash_set< KeyId, Lazy, Traits >::empty(), expr, find_trapping_overflow(), replace_trapping_overflow(), unshare_expr(), and walk_tree.
Referenced by add_iv_candidate_for_doloop(), create_waw_or_war_checks(), generate_memcpy_builtin(), generate_memset_builtin(), get_segment_min_max(), and vect_get_loop_niters().
|
static |
Returns TRUE if oneh and twoh are exception handlers (gimple_try_cleanup of GIMPLE_TRY) that are similar enough to be considered the same. Currently this only handles handlers consisting of a single call, as that's the important case for C++: a destructor call for a particular object showing up in multiple handlers.
References gimple_call_arg(), gimple_call_chain(), gimple_call_lhs(), gimple_call_num_args(), gimple_call_same_target_p(), gsi_one_before_end_p(), gsi_start(), gsi_stmt(), is_gimple_call(), and operand_equal_p().
Referenced by optimize_double_finally().
|
static |
Try to sink var = {v} {CLOBBER} stmts followed just by internal throw to successor BB. SUNK, if not NULL, is an array of sequences indexed by basic-block index to sink to and to pick up sinking opportunities from. If FOUND_OPPORTUNITY is not NULL then do not perform the optimization but set *FOUND_OPPORTUNITY to true.
References BB_VISITED, basic_block_def::flags, FOR_EACH_EDGE, FOR_EACH_IMM_USE_ON_STMT, FOR_EACH_IMM_USE_STMT, gimple_assign_lhs(), gimple_clobber_p(), gimple_phi_result(), gimple_seq_empty_p(), gimple_vdef(), gimple_vuse(), gimple_vuse_op(), gsi_after_labels(), gsi_end_p(), gsi_insert_before(), gsi_insert_seq_before_without_update(), gsi_last(), gsi_last_bb(), GSI_NEW_STMT, gsi_next(), gsi_prev(), gsi_remove(), gsi_start(), gsi_start_phis(), gsi_stmt(), basic_block_def::index, is_gimple_debug(), mark_virtual_operand_for_renaming(), NULL, PHI_ARG_DEF_PTR_FROM_EDGE, basic_block_def::preds, release_defs(), SET_USE, single_pred_p(), single_succ_edge(), single_succ_p(), SSA_NAME_IS_DEFAULT_DEF, SSA_NAME_OCCURS_IN_ABNORMAL_PHI, sunk, todo, TODO_update_ssa_only_virtuals, TREE_CODE, TREE_OPERAND, unlink_stmt_vdef(), and virtual_operand_p().
Referenced by cleanup_empty_eh().
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.
References lookup_stmt_eh_lp_fn(), and stmt_could_throw_p().
Referenced by analyze_function(), check_call(), check_stmt(), cleanup_empty_eh(), compute_avail(), symbol_table::create_edge(), find_tail_calls(), cgraph_edge::set_call_stmt(), stmt_can_terminate_bb_p(), stmt_kills_ref_p(), and stmt_may_terminate_function_p().
Return true if STMT can throw an exception that is caught within its function FUN.
References gcc_checking_assert, lookup_stmt_eh_lp_fn(), and stmt_could_throw_p().
Referenced by add_autoinc_candidates(), convert_mult_to_fma_1(), convert_to_divmod(), copy_edges_for_bb(), expand_call_tm(), expand_complex_libcall(), expand_complex_multiplication(), fold_builtin_atomic_compare_exchange(), gimple_expand_vec_cond_expr(), gimple_purge_dead_eh_edges(), gimple_regimplify_operands(), handle_builtin_alloca(), predicate::init_from_control_deps(), is_ctrl_altering_stmt(), is_division_by(), is_division_by_square(), mark_aliased_reaching_defs_necessary_1(), maybe_move_debug_stmts_to_successors(), optimize_atomic_bit_test_and(), optimize_atomic_op_fetch_cmp_0(), propagate_with_phi(), sink_common_stores_to_bb(), stmt_kills_ref_p(), vect_build_slp_tree_1(), vect_find_stmt_data_reference(), vectorizable_call(), and vectorizable_simd_clone_call().
Helper for stmt_could_throw_p. Return true if STMT (assumed to be a an assignment or a conditional) may throw.
References FLOAT_TYPE_P, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_num_ops(), gimple_op(), i, INTEGRAL_TYPE_P, operation_could_trap_helper_p(), tcc_binary, tcc_comparison, tcc_unary, TREE_CODE_CLASS, tree_could_trap_p(), TREE_TYPE, and TYPE_OVERFLOW_TRAPS.
Referenced by stmt_could_throw_p().
Return true if statement STMT within FUN could throw an exception.
References as_a(), function::can_throw_non_call_exceptions, FLOAT_TYPE_P, gimple_asm_volatile_p(), gimple_call_nothrow_p(), gimple_clobber_p(), gimple_cond_code(), gimple_cond_lhs(), NULL_TREE, operation_could_trap_p(), stmt_could_throw_1_p(), and TREE_TYPE.
Referenced by strlen_pass::adjust_last_stmt(), find_candidates_dom_walker::before_dom_children(), substitute_and_fold_dom_walker::before_dom_children(), check_bool_pattern(), check_call(), check_stmt(), compute_avail(), convert_mult_to_fma_1(), copy_reference_ops_from_call(), dse_optimize_call(), dse_optimize_stmt(), expand_call_stmt(), expand_complex_libcall(), find_givs_in_stmt_scev(), find_tail_calls(), gimple_ic(), gimple_stringop_fixed_value(), strlen_pass::handle_store(), hashable_expr_equal_p(), ifcvt_can_hoist(), initialize_ao_ref_for_dse(), linearize_expr_tree(), lower_eh_constructs_2(), mark_stmt_if_obviously_necessary(), maybe_clean_eh_stmt_fn(), maybe_clean_or_replace_eh_stmt(), maybe_duplicate_eh_stmt(), maybe_duplicate_eh_stmt_fn(), maybe_optimize_range_tests(), movement_possibility_1(), oacc_entry_exit_ok_1(), reassociate_bb(), simple_dce_from_worklist(), sink_code_in_bb(), ssa_is_replaceable_p(), stmt_can_throw_external(), stmt_can_throw_internal(), stmt_unremovable_because_of_non_call_eh_p(), suitable_cond_bb(), vect_finish_stmt_generation_1(), verify_eh_edges(), and verify_gimple_in_cfg().
Return true if STMT in function FUN must be assumed necessary because of non-call exceptions.
References function::can_delete_dead_exceptions, function::can_throw_non_call_exceptions, and stmt_could_throw_p().
Referenced by simple_dce_from_worklist().
Return true if expression T could throw an exception.
References call_expr_flags(), cfun, ECF_NOTHROW, TREE_CODE, tree_could_trap_p(), and TREE_OPERAND.
Referenced by can_sm_ref_p(), check_call(), expand_call(), gimple_cond_get_ops_from_tree(), is_gimple_condexpr_1(), lower_eh_constructs_2(), and suitable_reference_p().
Return true if EXPR can trap, as in dereferencing an invalid pointer location or floating point arithmetic. C.f. the rtl version, may_trap_p. This routine expects only GIMPLE lhs or rhs input.
References CALL_EXPR_FN, COMPARISON_CLASS_P, DECL_COMDAT, DECL_EXTERNAL, DECL_P, DECL_SIZE_UNIT, DECL_WEAK, FLOAT_TYPE_P, cgraph_node::function_symbol(), cgraph_node::get(), varpool_node::get(), get_callee_fndecl(), in_array_bounds_p(), symtab_node::in_other_partition, INTEGRAL_TYPE_P, mem_ref_offset(), NULL_TREE, operation_could_trap_p(), poly_int_tree_p(), range_in_array_bounds_p(), tcc_binary, TMR_INDEX, TMR_INDEX2, wi::to_poly_offset(), TREE_CODE, TREE_CODE_CLASS, tree_could_trap_p(), TREE_OPERAND, TREE_STRING_LENGTH, TREE_THIS_NOTRAP, TREE_THIS_VOLATILE, TREE_TYPE, TYPE_OVERFLOW_TRAPS, and varpool_node::ultimate_alias_target().
Referenced by can_sm_ref_p(), cond_store_replacement(), generic_expr_could_trap_p(), gimple_could_trap_p_1(), pcom_worker::prepare_initializers_chain(), set_mem_attributes_minus_bitpos(), stmt_could_throw_1_p(), tree_could_throw_p(), tree_could_trap_p(), vn_nary_may_trap(), and vn_reference_may_trap().
|
static |
Examine each landing pad block and see if it matches unsplit_eh.
References cfun, changed, i, unsplit_eh(), and vec_safe_iterate().
Referenced by execute_cleanup_eh_1(), and unsplit_eh_edges().
|
static |
Undo critical edge splitting on an EH landing pad. Earlier, we optimisticaly split all sorts of edges, including EH edges. The optimization passes in between may not have needed them; if not, we should undo the split. Recognize this case by having one EH edge incoming to the BB and one normal edge outgoing; BB should be empty apart from the post_landing_pad label. Note that this is slightly different from the empty handler case handled by cleanup_empty_eh, in that the actual handler may yet have actual code but the landing pad has been separated from the handler. As such, cleanup_empty_eh relies on this transformation having been done first.
References cfun, dump_file, dump_flags, dyn_cast(), EH_LANDING_PAD_NR, find_edge(), FOR_EACH_IMM_USE_ON_STMT, FOR_EACH_IMM_USE_STMT, get_eh_region_from_lp_number(), gimple_label_label(), gimple_phi_arg_def(), gimple_phi_result(), gimple_seq_empty_p(), gsi_after_labels(), gsi_end_p(), gsi_next(), gsi_next_nondebug(), gsi_start_bb(), gsi_start_phis(), gsi_stmt(), eh_landing_pad_d::index, is_gimple_debug(), label_to_block(), phi_nodes(), eh_landing_pad_d::post_landing_pad, redirect_edge_pred(), redirect_eh_edge_1(), eh_landing_pad_d::region, remove_edge(), remove_phi_node(), SET_USE, single_pred_edge(), single_pred_p(), single_succ_edge(), single_succ_p(), SSA_NAME_OCCURS_IN_ABNORMAL_PHI, and TDF_DETAILS.
Referenced by unsplit_all_eh().
void unsplit_eh_edges | ( | void | ) |
Wrapper around unsplit_all_eh that makes it usable everywhere.
References CDI_DOMINATORS, CDI_POST_DOMINATORS, changed, delete_unreachable_blocks(), free_dominance_info(), maybe_remove_unreachable_handlers(), and unsplit_all_eh().
DEBUG_FUNCTION bool verify_eh_dispatch_edge | ( | geh_dispatch * | stmt | ) |
Similarly, but handle GIMPLE_EH_DISPATCH specifically.
References cfun, error(), ERT_ALLOWED_EXCEPTIONS, ERT_TRY, find_edge(), FOR_EACH_EDGE, gcc_assert, gcc_unreachable, get_eh_region_from_number(), gimple_bb(), gimple_eh_dispatch_region(), basic_block_def::index, eh_catch_d::label, label_to_block(), eh_catch_d::next_catch, NULL, r, basic_block_def::succs, and eh_catch_d::type_list.
Referenced by gimple_verify_flow_info().
DEBUG_FUNCTION bool verify_eh_edges | ( | gimple * | stmt | ) |
Disable warnings about missing quoting in GCC diagnostics for the verification errors. Their format strings don't follow GCC diagnostic conventions but are only used for debugging.
Verify that BB containing STMT as the last statement, has precisely the edge that make_eh_edge would create.
References cfun, error(), FOR_EACH_EDGE, get_eh_landing_pad_from_number(), gimple_bb(), basic_block_def::index, label_to_block(), lookup_stmt_eh_lp(), NULL, eh_landing_pad_d::post_landing_pad, stmt_could_throw_p(), and basic_block_def::succs.
Referenced by gimple_verify_flow_info().
|
static |
Record whether an EH region contains something that can throw, indexed by EH region number.
Referenced by eh_region_may_contain_throw(), and note_eh_region_may_contain_throw().
|
static |
Second pass of EH node decomposition. Actually transform the GIMPLE_TRY nodes into a set of gotos, magic labels, and eh regions. The eh region creation is straight-forward, but frobbing all the gotos and such into shape isn't.
The sequence into which we record all EH stuff. This will be placed at the end of the function when we're all done.
Referenced by frob_into_branch_around(), honor_protect_cleanup_actions(), lower_catch(), lower_try_finally(), lower_try_finally_copy(), lower_try_finally_nofallthru(), lower_try_finally_onedest(), lower_try_finally_switch(), and replace_goto_queue().
|
static |
Note that this table is *not* marked GTY. It is short-lived.
Referenced by outside_finally_tree(), and record_in_finally_tree().