GCC Middle and Back End API Reference
tree-eh.c File Reference

Data Structures

union  treemple
struct  finally_tree_node
struct  finally_tree_hasher
struct  goto_queue_node
struct  leh_state
struct  leh_tf_state

Functions

void using_eh_for_cleanups ()
void add_stmt_to_eh_lp_fn ()
void add_stmt_to_eh_lp ()
static void record_stmt_eh_region ()
bool remove_stmt_from_eh_lp_fn ()
bool remove_stmt_from_eh_lp ()
int lookup_stmt_eh_lp_fn ()
int lookup_stmt_eh_lp ()
static void record_in_finally_tree ()
static void collect_finally_tree (gimple stmt, gimple region)
static void collect_finally_tree_1 ()
static void collect_finally_tree ()
static bool outside_finally_tree ()
static gimple_seq lower_eh_must_not_throw (struct leh_state *, gimple)
static void lower_eh_constructs_1 (struct leh_state *state, gimple_seq *seq)
static gimple_seq find_goto_replacement ()
static void replace_goto_queue_cond_clause (tree *tp, struct leh_tf_state *tf, gimple_stmt_iterator *gsi)
static void replace_goto_queue_stmt_list (gimple_seq *, struct leh_tf_state *)
static void replace_goto_queue_1 (gimple stmt, struct leh_tf_state *tf, gimple_stmt_iterator *gsi)
static void replace_goto_queue_stmt_list ()
static void replace_goto_queue ()
static void record_in_goto_queue (struct leh_tf_state *tf, treemple new_stmt, int index, bool is_label, location_t location)
static void record_in_goto_queue_label (struct leh_tf_state *tf, treemple stmt, tree label, location_t location)
static void maybe_record_in_goto_queue ()
static void verify_norecord_switch_expr ()
static void do_return_redirection ()
static void do_goto_redirection (struct goto_queue_node *q, tree finlab, gimple_seq mod, struct leh_tf_state *tf)
static void emit_post_landing_pad ()
static void emit_resx ()
static void emit_eh_dispatch ()
static void note_eh_region_may_contain_throw ()
static bool eh_region_may_contain_throw ()
static gimple_seq frob_into_branch_around ()
static gimple_seq lower_try_finally_dup_block (gimple_seq seq, struct leh_state *outer_state, location_t loc)
static tree lower_try_finally_fallthru_label ()
static gimple get_eh_else ()
static void honor_protect_cleanup_actions (struct leh_state *outer_state, struct leh_state *this_state, struct leh_tf_state *tf)
static void lower_try_finally_nofallthru (struct leh_state *state, struct leh_tf_state *tf)
static void lower_try_finally_onedest ()
static void lower_try_finally_copy ()
static void lower_try_finally_switch ()
static bool decide_copy_try_finally ()
static bool cleanup_is_dead_in ()
static gimple_seq lower_try_finally ()
static gimple_seq lower_catch ()
static gimple_seq lower_eh_filter ()
static gimple_seq lower_eh_must_not_throw ()
static gimple_seq lower_cleanup ()
static void lower_eh_constructs_2 ()
static void lower_eh_constructs_1 ()
static unsigned int lower_eh_constructs ()
gimple_opt_passmake_pass_lower_eh ()
bool make_eh_dispatch_edges ()
void make_eh_edges ()
static void redirect_eh_edge_1 ()
edge redirect_eh_edge ()
void redirect_eh_dispatch_edge ()
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)
bool operation_could_trap_p (enum tree_code op, bool fp_operation, bool honor_trapv, tree divisor)
bool tree_could_trap_p ()
static bool stmt_could_throw_1_p ()
bool stmt_could_throw_p ()
bool tree_could_throw_p ()
bool stmt_can_throw_external ()
bool stmt_can_throw_internal ()
bool maybe_clean_eh_stmt_fn ()
bool maybe_clean_eh_stmt ()
bool maybe_clean_or_replace_eh_stmt ()
bool maybe_duplicate_eh_stmt_fn (struct function *new_fun, gimple new_stmt, struct function *old_fun, gimple old_stmt, struct pointer_map_t *map, int default_lp_nr)
bool maybe_duplicate_eh_stmt ()
static bool same_handler_p ()
static void optimize_double_finally ()
static void refactor_eh_r ()
static unsigned refactor_eh ()
static bool gate_refactor_eh ()
gimple_opt_passmake_pass_refactor_eh ()
static bool lower_resx ()
static unsigned execute_lower_resx ()
static bool gate_lower_resx ()
gimple_opt_passmake_pass_lower_resx ()
static void optimize_clobbers ()
static int sink_clobbers ()
static bool lower_eh_dispatch ()
static unsigned execute_lower_eh_dispatch ()
static bool gate_lower_eh_dispatch ()
gimple_opt_passmake_pass_lower_eh_dispatch ()
static void mark_reachable_handlers ()
static void remove_unreachable_handlers ()
void maybe_remove_unreachable_handlers ()
static void remove_unreachable_handlers_no_lp ()
static bool unsplit_eh ()
static bool unsplit_all_eh ()
static bool cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb, edge old_bb_out, bool change_region)
static void cleanup_empty_eh_move_lp (basic_block bb, edge e_out, eh_landing_pad lp, eh_region new_region)
static bool cleanup_empty_eh_unsplit ()
static bool infinite_empty_loop_p ()
static bool cleanup_empty_eh ()
static bool cleanup_all_empty_eh ()
static unsigned int execute_cleanup_eh_1 ()
static unsigned int execute_cleanup_eh ()
static bool gate_cleanup_eh ()
gimple_opt_passmake_pass_cleanup_eh ()
DEBUG_FUNCTION bool verify_eh_edges ()
DEBUG_FUNCTION bool verify_eh_dispatch_edge ()

Variables

static int using_eh_for_cleanups_p = 0
static hash_table
< finally_tree_hasher
finally_tree
static gimple_seq eh_seq
static bitmap eh_region_may_contain_throw_map

Function Documentation

void add_stmt_to_eh_lp ( )
void add_stmt_to_eh_lp_fn ( )
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 get_eh_throw_stmt_table(), ggc_free(), throw_stmt_node::lp_nr, set_eh_throw_stmt_table(), throw_stmt_node::stmt, struct_ptr_eq(), and struct_ptr_hash().

Referenced by add_stmt_to_eh_lp(), maybe_duplicate_eh_stmt_fn(), and record_stmt_eh_region().

static bool cleanup_all_empty_eh ( )
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(), function::eh, eh_status::lp_array, and vec_safe_iterate().

Referenced by execute_cleanup_eh_1().

static bool cleanup_empty_eh_merge_phis ( basic_block  new_bb,
basic_block  old_bb,
edge  old_bb_out,
bool  change_region 
)
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_bit_p(), bitmap_set_bit(), edge_def::dest, edge_def::dest_idx, ei_next(), ei_safe_edge(), find_edge(), edge_def::flags, flush_pending_stmts(), gimple_debug_bind_p(), gimple_phi_arg_def(), gimple_phi_arg_location(), gimple_phi_result(), gsi_end_p(), gsi_next(), gsi_start_phis(), gsi_stmt(), has_single_use(), loop::header, loop::latch, basic_block_def::loop_father, LOOPS_MAY_HAVE_MULTIPLE_LATCHES, LOOPS_NEED_FIXUP, loops_state_set(), basic_block_def::preds, redirect_edge_succ(), redirect_edge_var_map_add(), redirect_edge_var_map_clear(), redirect_eh_edge_1(), and edge_def::src.

Referenced by cleanup_empty_eh(), and cleanup_empty_eh_unsplit().

static void cleanup_empty_eh_move_lp ( basic_block  bb,
edge  e_out,
eh_landing_pad  lp,
eh_region  new_region 
)
static
A subroutine of cleanup_empty_eh.  Move a landing pad LP from its
   old region to NEW_REGION at BB.   

References edge_def::flags, gsi_last_bb(), gsi_remove(), gsi_stmt(), eh_region_d::landing_pads, eh_landing_pad_d::next_lp, edge_def::probability, eh_landing_pad_d::region, and unlink_stmt_vdef().

Referenced by cleanup_empty_eh().

static bool cleanup_empty_eh_unsplit ( )
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(), edge_def::dest, dump_file, dump_flags, get_eh_region_from_lp_number(), gimple_label_label(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), eh_landing_pad_d::index, basic_block_def::index, and eh_landing_pad_d::region.

Referenced by cleanup_empty_eh().

static bool cleanup_is_dead_in ( )
static
REG 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, eh_region_d::outer, and eh_region_d::type.

Referenced by lower_cleanup(), and lower_try_finally().

static void collect_finally_tree ( gimple  stmt,
gimple  region 
)
static

Referenced by collect_finally_tree_1().

static void 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(), and gsi_stmt().

Referenced by collect_finally_tree(), lower_eh_constructs(), and lower_try_finally_dup_block().

static bool decide_copy_try_finally ( )
static
Decide whether or not we are going to duplicate the finally block.
   There are several considerations.

   First, if this is Java, then the finally block contains code
   written by the user.  It has line numbers associated with it,
   so duplicating the block means it's difficult to set a breakpoint.
   Since controlling code generation via -g is verboten, we simply
   never duplicate code without optimization.

   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, count_insns_seq(), eni_size_weights, get_eh_else(), gimple_clobber_p(), gimple_eh_else_n_body(), gsi_end_p(), gsi_next(), gsi_stmt(), is_gimple_debug(), and optimize_function_for_size_p().

Referenced by lower_try_finally().

static bool eh_region_may_contain_throw ( )
inlinestatic
Check if REGION has been marked as containing a throw.  If REGION is
   NULL, this predicate is false.   

References bitmap_bit_p(), and eh_region_d::index.

Referenced by lower_catch(), lower_cleanup(), lower_eh_filter(), and lower_try_finally().

static void emit_eh_dispatch ( )
static
Emit an EH_DISPATCH statement into SEQ for REGION.   

References gimple_build_eh_dispatch(), gimple_seq_add_stmt(), and eh_region_d::index.

Referenced by lower_catch(), and lower_eh_filter().

static unsigned int execute_cleanup_eh ( )
static
static unsigned int execute_cleanup_eh_1 ( )
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(), function::eh, free_dominance_info(), eh_status::region_tree, remove_unreachable_handlers(), remove_unreachable_handlers_no_lp(), and unsplit_all_eh().

Referenced by execute_cleanup_eh().

static gimple_seq frob_into_branch_around ( )
static
We want to transform
        try { body; } catch { stuff; }
   to
        normal_seqence:
          body;
          over:
        eh_seqence:
          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(), 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(), and gimple_try_eval().

Referenced by lower_catch(), lower_cleanup(), and lower_eh_filter().

static bool gate_cleanup_eh ( )
static
static bool gate_lower_eh_dispatch ( )
static
static bool gate_lower_resx ( )
static
static bool gate_refactor_eh ( )
static
static gimple get_eh_else ( )
inlinestatic
A subroutine of lower_try_finally.  If FINALLY consits of a
   GIMPLE_EH_ELSE node, return it.   

References gimple_seq_first_stmt(), and gimple_seq_singleton_p().

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 void honor_protect_cleanup_actions ( struct leh_state outer_state,
struct leh_state this_state,
struct leh_tf_state tf 
)
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 lang_hooks::eh_protect_cleanup_actions, 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_stmt(), lower_eh_must_not_throw(), lower_try_finally_dup_block(), leh_tf_state::may_throw, leh_tf_state::region, leh_tf_state::top_p, and leh_tf_state::try_finally_expr.

Referenced by lower_cleanup(), and lower_try_finally().

static bool infinite_empty_loop_p ( )
static
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 basic_block_def::aux, edge_def::dest, gsi_after_labels(), gsi_end_p(), gsi_next_nondebug(), gsi_stmt(), is_gimple_debug(), single_succ_edge(), single_succ_p(), and edge_def::src.

Referenced by cleanup_empty_eh().

int lookup_stmt_eh_lp_fn ( )
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 throw_stmt_node::lp_nr, and throw_stmt_node::stmt.

Referenced by find_outermost_region_in_block(), lookup_stmt_eh_lp(), maybe_duplicate_eh_stmt_fn(), and output_bb().

static void lower_eh_constructs_1 ( )
static
A helper to unwrap a gimple_seq and feed stmts to lower_eh_constructs_2.  

References gsi_end_p(), and lower_eh_constructs_2().

static gimple_seq lower_eh_must_not_throw ( struct leh_state ,
gimple   
)
static
static gimple_seq lower_eh_must_not_throw ( )
static
static gimple_seq lower_try_finally_dup_block ( gimple_seq  seq,
struct leh_state outer_state,
location_t  loc 
)
static
static tree lower_try_finally_fallthru_label ( )
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 void lower_try_finally_nofallthru ( struct leh_state state,
struct leh_tf_state tf 
)
static
bool make_eh_dispatch_edges ( )
void make_eh_edges ( )
Create the single EH edge from STMT to its nearest landing pad,
   if there is such a landing pad within the current function.   

References get_eh_landing_pad_from_number(), gimple_bb(), lookup_stmt_eh_lp(), make_edge(), and eh_landing_pad_d::post_landing_pad.

Referenced by copy_edges_for_bb(), and make_edges().

gimple_opt_pass* make_pass_cleanup_eh ( )
gimple_opt_pass* make_pass_lower_eh ( )
gimple_opt_pass* make_pass_lower_eh_dispatch ( )
gimple_opt_pass* make_pass_lower_resx ( )
gimple_opt_pass* make_pass_refactor_eh ( )
static void mark_reachable_handlers ( )
static
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 bitmap_clear(), bitmap_set_bit(), cfun, function::eh, get_eh_region_from_lp_number(), gimple_eh_dispatch_region(), gimple_resx_region(), gsi_end_p(), gsi_next(), gsi_one_before_end_p(), gsi_start_bb(), gsi_stmt(), eh_region_d::index, lookup_stmt_eh_lp(), eh_status::lp_array, eh_status::region_array, and sbitmap_alloc().

Referenced by remove_unreachable_handlers(), and remove_unreachable_handlers_no_lp().

bool maybe_clean_eh_stmt_fn ( )
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().

bool maybe_clean_or_replace_eh_stmt ( )
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(), lookup_stmt_eh_lp(), remove_stmt_from_eh_lp(), and stmt_could_throw_p().

Referenced by associate_plusminus(), eliminate_bb(), eliminate_unnecessary_stmts(), execute_fold_all_builtins(), expand_call_inline(), expand_complex_libcall(), fold_marked_statements(), gsi_replace(), optimize_stmt(), propagate_into_all_uses(), propagate_rhs_into_lhs(), replace_uses_by(), substitute_and_fold(), tidy_after_forward_propagate_addr(), and vectorizable_call().

bool maybe_duplicate_eh_stmt ( )
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(), lookup_stmt_eh_lp(), and stmt_could_throw_p().

Referenced by gimple_duplicate_bb(), and graphite_copy_stmts_from_block().

bool maybe_duplicate_eh_stmt_fn ( struct function new_fun,
gimple  new_stmt,
struct function old_fun,
gimple  old_stmt,
struct pointer_map_t 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(), eh_landing_pad_d::index, eh_region_d::index, lookup_stmt_eh_lp_fn(), pointer_map_contains(), and stmt_could_throw_p().

Referenced by copy_bb(), and move_block_to_fn().

static void maybe_record_in_goto_queue ( )
static
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 treemple::g, 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(), leh_state::tf, 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, function::eh, eh_status::lp_array, eh_landing_pad_d::post_landing_pad, and remove_unreachable_handlers().

Referenced by execute_cleanup_cfg_post_optimizing().

static void note_eh_region_may_contain_throw ( )
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(), ERT_MUST_NOT_THROW, eh_region_d::index, eh_region_d::outer, 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 integer_zerop().

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 operation_could_trap_helper_p(), tcc_binary, tcc_comparison, and tcc_unary.

Referenced by gimple_could_trap_p_1(), and tree_could_trap_p().

static void optimize_clobbers ( )
static
static void optimize_double_finally ( )
static
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_stmt(), and same_handler_p().

Referenced by refactor_eh_r().

static bool outside_finally_tree ( )
static
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, hash_table< Descriptor, Allocator >::find(), treemple::g, and finally_tree_node::parent.

Referenced by record_in_goto_queue_label(), and verify_norecord_switch_expr().

static void record_in_goto_queue ( struct leh_tf_state tf,
treemple  new_stmt,
int  index,
bool  is_label,
location_t  location 
)
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 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, memset(), and goto_queue_node::stmt.

Referenced by maybe_record_in_goto_queue(), and record_in_goto_queue_label().

static void record_in_goto_queue_label ( struct leh_tf_state tf,
treemple  stmt,
tree  label,
location_t  location 
)
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, outside_finally_tree(), record_in_goto_queue(), goto_queue_node::stmt, treemple::t, and leh_tf_state::try_finally_expr.

Referenced by maybe_record_in_goto_queue().

static void record_stmt_eh_region ( )
static
void redirect_eh_dispatch_edge ( )
edge redirect_eh_edge ( )
Redirect EH edge E to NEW_BB.   

References redirect_eh_edge_1(), and ssa_redirect_edge().

Referenced by gimple_redirect_edge_and_branch().

static void redirect_eh_edge_1 ( )
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(), edge_def::dest, edge_def::flags, gen_eh_landing_pad(), get_eh_landing_pad_from_number(), gimple_block_label(), eh_landing_pad_d::index, last_stmt(), lookup_stmt_eh_lp(), eh_landing_pad_d::post_landing_pad, basic_block_def::preds, eh_landing_pad_d::region, remove_eh_landing_pad(), remove_stmt_from_eh_lp(), and edge_def::src.

Referenced by cleanup_empty_eh_merge_phis(), redirect_eh_edge(), and unsplit_eh().

static unsigned refactor_eh ( )
static
static void refactor_eh_r ( )
static
Perform EH refactoring optimizations that are simpler to do when code
   flow has been lowered but EH structures haven't.   

References 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_stmt(), and optimize_double_finally().

Referenced by refactor_eh().

bool remove_stmt_from_eh_lp ( )
Remove statement T in the current function (cfun) from its
   EH landing pad.   

References cfun, and remove_stmt_from_eh_lp_fn().

Referenced by cgraph_redirect_edge_call_stmt_to_callee(), cleanup_empty_eh(), gsi_remove(), maybe_clean_or_replace_eh_stmt(), and redirect_eh_edge_1().

bool remove_stmt_from_eh_lp_fn ( )
Remove statement T in function IFUN from its EH landing pad.   

References get_eh_throw_stmt_table(), and throw_stmt_node::stmt.

Referenced by maybe_clean_eh_stmt_fn(), move_block_to_fn(), and remove_stmt_from_eh_lp().

static void remove_unreachable_handlers_no_lp ( )
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, function::eh, ERT_MUST_NOT_THROW, eh_region_d::index, eh_region_d::landing_pads, mark_reachable_handlers(), eh_status::region_array, remove_unreachable_eh_regions(), sbitmap_free(), and eh_region_d::type.

Referenced by execute_cleanup_eh_1().

static void replace_goto_queue_cond_clause ( tree tp,
struct leh_tf_state tf,
gimple_stmt_iterator gsi 
)
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 void replace_goto_queue_stmt_list ( gimple_seq ,
struct leh_tf_state  
)
static
The real work of replace_goto_queue.  Returns with TSI updated to
   point to the next statement.   

Referenced by replace_goto_queue(), and replace_goto_queue_1().

static void replace_goto_queue_stmt_list ( )
static
A subroutine of replace_goto_queue.  Handles GIMPLE_SEQ.   

References gsi_end_p(), gsi_stmt(), and replace_goto_queue_1().

static bool same_handler_p ( )
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_stmt(), is_gimple_call(), and operand_equal_p().

Referenced by optimize_double_finally().

bool stmt_can_throw_external ( )
Return true if STMT can throw an exception that is not caught within
   the current function (CFUN).   

References lookup_stmt_eh_lp(), and stmt_could_throw_p().

Referenced by cgraph_create_edge_1(), cgraph_set_call_stmt(), check_call(), check_stmt(), cleanup_empty_eh(), execute_lower_eh_dispatch(), and scan_function().

static bool stmt_could_throw_1_p ( )
static
Helper for stmt_could_throw_p.  Return true if STMT (assumed to be a
   an assignment or a conditional) may throw.   

References gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_cond_lhs(), gimple_expr_code(), gimple_expr_type(), gimple_num_ops(), gimple_op(), is_gimple_assign(), operation_could_trap_helper_p(), tcc_binary, tcc_comparison, tcc_unary, and tree_could_trap_p().

Referenced by stmt_could_throw_p().

bool tree_could_throw_p ( )
static bool unsplit_all_eh ( )
static
Examine each landing pad block and see if it matches unsplit_eh.   

References cfun, changed, function::eh, eh_status::lp_array, unsplit_eh(), and vec_safe_iterate().

Referenced by execute_cleanup_eh_1().

static bool unsplit_eh ( )
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 edge_def::count, edge_def::dest, dump_file, dump_flags, find_edge(), edge_def::flags, 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, basic_block_def::index, is_gimple_debug(), phi_nodes(), eh_landing_pad_d::post_landing_pad, edge_def::probability, redirect_edge_pred(), redirect_eh_edge_1(), eh_landing_pad_d::region, remove_edge(), remove_phi_node(), single_pred_edge(), single_pred_p(), single_succ_edge(), single_succ_p(), and edge_def::src.

Referenced by unsplit_all_eh().

void using_eh_for_cleanups ( void  )
In tree-eh.c  

References using_eh_for_cleanups_p.

DEBUG_FUNCTION bool verify_eh_edges ( )
Verify that BB containing STMT as the last statement, has precisely the
   edge that make_eh_edges would create.   

References edge_def::dest, error(), edge_def::flags, get_eh_landing_pad_from_number(), gimple_bb(), basic_block_def::index, lookup_stmt_eh_lp(), eh_landing_pad_d::post_landing_pad, stmt_could_throw_p(), and basic_block_def::succs.

Referenced by gimple_verify_flow_info().

static void verify_norecord_switch_expr ( )
static
We do not process GIMPLE_SWITCHes for now.  As long as the original source
   was in fact structured, and we've not yet done jump threading, then none
   of the labels will leave outer GIMPLE_TRY_FINALLY nodes. Verify this.   

References gimple_switch_label(), gimple_switch_num_labels(), outside_finally_tree(), treemple::t, leh_state::tf, and leh_tf_state::try_finally_expr.

Referenced by lower_eh_constructs_2().


Variable Documentation

bitmap eh_region_may_contain_throw_map
static
Record whether an EH region contains something that can throw,
   indexed by EH region number.   
gimple_seq eh_seq
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 lower_try_finally().

hash_table<finally_tree_hasher> finally_tree
static
Note that this table is *not* marked GTY.  It is short-lived.   
int using_eh_for_cleanups_p = 0
static
Nonzero if we are using EH to handle cleanups.   

Referenced by lower_try_finally(), and using_eh_for_cleanups().