/* Exception handling semantics and decomposition for trees.
- Copyright (C) 2003-2015 Free Software Foundation, Inc.
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
This file is part of GCC.
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "hash-table.h"
-#include "tm.h"
-#include "hash-set.h"
-#include "vec.h"
-#include "input.h"
-#include "alias.h"
-#include "symtab.h"
-#include "inchash.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 "hashtab.h"
-#include "hard-reg-set.h"
-#include "function.h"
-#include "rtl.h"
-#include "flags.h"
-#include "statistics.h"
-#include "insn-config.h"
-#include "expmed.h"
-#include "dojump.h"
-#include "explow.h"
#include "calls.h"
-#include "emit-rtl.h"
-#include "varasm.h"
-#include "stmt.h"
-#include "expr.h"
#include "except.h"
-#include "predict.h"
-#include "dominance.h"
-#include "cfg.h"
#include "cfganal.h"
#include "cfgcleanup.h"
-#include "basic-block.h"
-#include "tree-ssa-alias.h"
-#include "internal-fn.h"
#include "tree-eh.h"
-#include "gimple-expr.h"
-#include "is-a.h"
-#include "gimple.h"
#include "gimple-iterator.h"
-#include "gimple-ssa.h"
-#include "hash-map.h"
-#include "plugin-api.h"
-#include "ipa-ref.h"
-#include "cgraph.h"
#include "tree-cfg.h"
-#include "tree-phinodes.h"
-#include "ssa-iterators.h"
-#include "stringpool.h"
-#include "tree-ssanames.h"
#include "tree-into-ssa.h"
#include "tree-ssa.h"
#include "tree-inline.h"
-#include "tree-pass.h"
#include "langhooks.h"
-#include "diagnostic-core.h"
-#include "target.h"
#include "cfgloop.h"
#include "gimple-low.h"
/* In some instances a tree and a gimple need to be stored in a same table,
i.e. in hash tables. This is a structure to do this. */
-typedef union {tree *tp; tree t; gimple g;} treemple;
+typedef union {tree *tp; tree t; gimple *g;} treemple;
/* Misc functions used in this file. */
/* Add statement T in function IFUN to landing pad NUM. */
static void
-add_stmt_to_eh_lp_fn (struct function *ifun, gimple t, int num)
+add_stmt_to_eh_lp_fn (struct function *ifun, gimple *t, int num)
{
gcc_assert (num != 0);
if (!get_eh_throw_stmt_table (ifun))
- set_eh_throw_stmt_table (ifun, hash_map<gimple, int>::create_ggc (31));
+ set_eh_throw_stmt_table (ifun, hash_map<gimple *, int>::create_ggc (31));
gcc_assert (!get_eh_throw_stmt_table (ifun)->put (t, num));
}
/* Add statement T in the current function (cfun) to EH landing pad NUM. */
void
-add_stmt_to_eh_lp (gimple t, int num)
+add_stmt_to_eh_lp (gimple *t, int num)
{
add_stmt_to_eh_lp_fn (cfun, t, num);
}
/* Add statement T to the single EH landing pad in REGION. */
static void
-record_stmt_eh_region (eh_region region, gimple t)
+record_stmt_eh_region (eh_region region, gimple *t)
{
if (region == NULL)
return;
/* Remove statement T in function IFUN from its EH landing pad. */
bool
-remove_stmt_from_eh_lp_fn (struct function *ifun, gimple t)
+remove_stmt_from_eh_lp_fn (struct function *ifun, gimple *t)
{
if (!get_eh_throw_stmt_table (ifun))
return false;
EH landing pad. */
bool
-remove_stmt_from_eh_lp (gimple t)
+remove_stmt_from_eh_lp (gimple *t)
{
return remove_stmt_from_eh_lp_fn (cfun, t);
}
statement is not recorded in the region table. */
int
-lookup_stmt_eh_lp_fn (struct function *ifun, gimple t)
+lookup_stmt_eh_lp_fn (struct function *ifun, gimple *t)
{
if (ifun->eh->throw_stmt_table == NULL)
return 0;
/* Likewise, but always use the current function. */
int
-lookup_stmt_eh_lp (gimple t)
+lookup_stmt_eh_lp (gimple *t)
{
/* We can get called from initialized data when -fnon-call-exceptions
is on; prevent crash. */
/* Hashtable helpers. */
-struct finally_tree_hasher : typed_free_remove <finally_tree_node>
+struct finally_tree_hasher : free_ptr_hash <finally_tree_node>
{
- typedef finally_tree_node *value_type;
- typedef finally_tree_node *compare_type;
static inline hashval_t hash (const finally_tree_node *);
static inline bool equal (const finally_tree_node *,
const finally_tree_node *);
}
static void
-collect_finally_tree (gimple stmt, gtry *region);
+collect_finally_tree (gimple *stmt, gtry *region);
/* Go through the gimple sequence. Works with collect_finally_tree to
record all GIMPLE_LABEL and GIMPLE_TRY statements. */
}
static void
-collect_finally_tree (gimple stmt, gtry *region)
+collect_finally_tree (gimple *stmt, gtry *region)
{
treemple temp;
would leave the try_finally node that START lives in. */
static bool
-outside_finally_tree (treemple start, gimple target)
+outside_finally_tree (treemple start, gimple *target)
{
struct finally_tree_node n, *p;
indexed by EH region number. */
static bitmap eh_region_may_contain_throw_map;
-/* The GOTO_QUEUE is is an array of GIMPLE_GOTO and GIMPLE_RETURN
+/* The GOTO_QUEUE is an array of GIMPLE_GOTO and GIMPLE_RETURN
statements that are seen to escape this GIMPLE_TRY_FINALLY node.
The idea is to record a gimple statement for everything except for
the conditionals, which get their labels recorded. Since labels are
treemple stmt;
location_t location;
gimple_seq repl_stmt;
- gimple cont_stmt;
+ gimple *cont_stmt;
int index;
/* This is used when index >= 0 to indicate that stmt is a label (as
opposed to a goto stmt). */
size_t goto_queue_active;
/* Pointer map to help in searching goto_queue when it is large. */
- hash_map<gimple, goto_queue_node *> *goto_queue_map;
+ hash_map<gimple *, goto_queue_node *> *goto_queue_map;
/* The set of unique labels seen as entries in the goto queue. */
vec<tree> dest_array;
if (!tf->goto_queue_map)
{
- tf->goto_queue_map = new hash_map<gimple, goto_queue_node *>;
+ tf->goto_queue_map = new hash_map<gimple *, goto_queue_node *>;
for (i = 0; i < tf->goto_queue_active; i++)
{
bool existed = tf->goto_queue_map->put (tf->goto_queue[i].stmt.g,
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,
+replace_goto_queue_1 (gimple *stmt, struct leh_tf_state *tf,
gimple_stmt_iterator *gsi)
{
gimple_seq seq;
try_finally node. */
static void
-maybe_record_in_goto_queue (struct leh_state *state, gimple stmt)
+maybe_record_in_goto_queue (struct leh_state *state, gimple *stmt)
{
struct leh_tf_state *tf = state->tf;
treemple new_stmt;
}
-#ifdef ENABLE_CHECKING
+#if CHECKING_P
/* 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. */
static void
do_return_redirection (struct goto_queue_node *q, tree finlab, gimple_seq mod)
{
- gimple x;
+ gimple *x;
/* In the case of a return, the queue node must be a gimple statement. */
gcc_assert (!q->is_label);
static gimple_seq
frob_into_branch_around (gtry *tp, eh_region region, tree over)
{
- gimple x;
+ gimple *x;
gimple_seq cleanup, result;
location_t loc = gimple_location (tp);
for (gsi = gsi_start (new_seq); !gsi_end_p (gsi); gsi_next (&gsi))
{
- gimple stmt = gsi_stmt (gsi);
- if (LOCATION_LOCUS (gimple_location (stmt)) == UNKNOWN_LOCATION)
+ gimple *stmt = gsi_stmt (gsi);
+ /* We duplicate __builtin_stack_restore at -O0 in the hope of eliminating
+ it on the EH paths. When it is not eliminated, make it transparent in
+ the debug info. */
+ if (gimple_call_builtin_p (stmt, BUILT_IN_STACK_RESTORE))
+ gimple_set_location (stmt, UNKNOWN_LOCATION);
+ else if (LOCATION_LOCUS (gimple_location (stmt)) == UNKNOWN_LOCATION)
{
tree block = gimple_block (stmt);
gimple_set_location (stmt, loc);
static inline geh_else *
get_eh_else (gimple_seq finally)
{
- gimple x = gimple_seq_first_stmt (finally);
+ gimple *x = gimple_seq_first_stmt (finally);
if (gimple_code (x) == GIMPLE_EH_ELSE)
{
gcc_assert (gimple_seq_singleton_p (finally));
struct leh_state *this_state,
struct leh_tf_state *tf)
{
- tree protect_cleanup_actions;
- gimple_stmt_iterator gsi;
- bool finally_may_fallthru;
- gimple_seq finally;
- gimple x;
- geh_mnt *eh_mnt;
- gtry *try_stmt;
- geh_else *eh_else;
+ gimple_seq finally = gimple_try_cleanup (tf->top_p);
- /* First check for nothing to do. */
- if (lang_hooks.eh_protect_cleanup_actions == NULL)
- return;
- protect_cleanup_actions = lang_hooks.eh_protect_cleanup_actions ();
- if (protect_cleanup_actions == NULL)
- return;
-
- finally = gimple_try_cleanup (tf->top_p);
- eh_else = get_eh_else (finally);
-
- /* Duplicate the FINALLY block. Only need to do this for try-finally,
- and not for cleanups. If we've got an EH_ELSE, extract it now. */
- if (eh_else)
+ /* EH_ELSE doesn't come from user code; only compiler generated stuff.
+ It does need to be handled here, so as to separate the (different)
+ EH path from the normal path. But we should not attempt to wrap
+ it with a must-not-throw node (which indeed gets in the way). */
+ if (geh_else *eh_else = get_eh_else (finally))
{
- finally = gimple_eh_else_e_body (eh_else);
gimple_try_set_cleanup (tf->top_p, gimple_eh_else_n_body (eh_else));
+ finally = gimple_eh_else_e_body (eh_else);
+
+ /* Let the ELSE see the exception that's being processed. */
+ eh_region save_ehp = this_state->ehp_region;
+ this_state->ehp_region = this_state->cur_region;
+ lower_eh_constructs_1 (this_state, &finally);
+ this_state->ehp_region = save_ehp;
}
- else if (this_state)
- finally = lower_try_finally_dup_block (finally, outer_state,
- gimple_location (tf->try_finally_expr));
- finally_may_fallthru = gimple_seq_may_fallthru (finally);
-
- /* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP
- set, the handler of the TRY_CATCH_EXPR is another cleanup which ought
- to be in an enclosing scope, but needs to be implemented at this level
- to avoid a nesting violation (see wrap_temporary_cleanups in
- cp/decl.c). Since it's logically at an outer level, we should call
- terminate before we get to it, so strip it away before adding the
- MUST_NOT_THROW filter. */
- gsi = gsi_start (finally);
- x = gsi_stmt (gsi);
- if (gimple_code (x) == GIMPLE_TRY
- && gimple_try_kind (x) == GIMPLE_TRY_CATCH
- && gimple_try_catch_is_cleanup (x))
+ else
{
- gsi_insert_seq_before (&gsi, gimple_try_eval (x), GSI_SAME_STMT);
- gsi_remove (&gsi, false);
- }
+ /* First check for nothing to do. */
+ if (lang_hooks.eh_protect_cleanup_actions == NULL)
+ return;
+ tree actions = lang_hooks.eh_protect_cleanup_actions ();
+ if (actions == NULL)
+ return;
+
+ if (this_state)
+ finally = lower_try_finally_dup_block (finally, outer_state,
+ gimple_location (tf->try_finally_expr));
+
+ /* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP
+ set, the handler of the TRY_CATCH_EXPR is another cleanup which ought
+ to be in an enclosing scope, but needs to be implemented at this level
+ to avoid a nesting violation (see wrap_temporary_cleanups in
+ cp/decl.c). Since it's logically at an outer level, we should call
+ terminate before we get to it, so strip it away before adding the
+ MUST_NOT_THROW filter. */
+ gimple_stmt_iterator gsi = gsi_start (finally);
+ gimple *x = gsi_stmt (gsi);
+ if (gimple_code (x) == GIMPLE_TRY
+ && gimple_try_kind (x) == GIMPLE_TRY_CATCH
+ && gimple_try_catch_is_cleanup (x))
+ {
+ gsi_insert_seq_before (&gsi, gimple_try_eval (x), GSI_SAME_STMT);
+ gsi_remove (&gsi, false);
+ }
- /* Wrap the block with protect_cleanup_actions as the action. */
- eh_mnt = gimple_build_eh_must_not_throw (protect_cleanup_actions);
- try_stmt = gimple_build_try (finally, gimple_seq_alloc_with_stmt (eh_mnt),
- GIMPLE_TRY_CATCH);
- finally = lower_eh_must_not_throw (outer_state, try_stmt);
+ /* Wrap the block with protect_cleanup_actions as the action. */
+ geh_mnt *eh_mnt = gimple_build_eh_must_not_throw (actions);
+ gtry *try_stmt = gimple_build_try (finally,
+ gimple_seq_alloc_with_stmt (eh_mnt),
+ GIMPLE_TRY_CATCH);
+ finally = lower_eh_must_not_throw (outer_state, try_stmt);
+ }
/* Drop all of this into the exception sequence. */
emit_post_landing_pad (&eh_seq, tf->region);
gimple_seq_add_seq (&eh_seq, finally);
- if (finally_may_fallthru)
+ if (gimple_seq_may_fallthru (finally))
emit_resx (&eh_seq, tf->region);
/* Having now been handled, EH isn't to be considered with
struct leh_tf_state *tf)
{
tree lab;
- gimple x;
+ gimple *x;
geh_else *eh_else;
gimple_seq finally;
struct goto_queue_node *q, *qe;
struct goto_queue_node *q, *qe;
geh_else *eh_else;
glabel *label_stmt;
- gimple x;
+ gimple *x;
gimple_seq finally;
gimple_stmt_iterator gsi;
tree finally_label;
for (gsi = gsi_start (finally); !gsi_end_p (gsi); gsi_next (&gsi))
{
- gimple stmt = gsi_stmt (gsi);
+ gimple *stmt = gsi_stmt (gsi);
if (LOCATION_LOCUS (gimple_location (stmt)) == UNKNOWN_LOCATION)
{
tree block = gimple_block (stmt);
gimple_seq finally;
gimple_seq new_stmt;
gimple_seq seq;
- gimple x;
+ gimple *x;
geh_else *eh_else;
tree tmp;
location_t tf_loc = gimple_location (tf->try_finally_expr);
int return_index, eh_index, fallthru_index;
int nlabels, ndests, j, last_case_index;
tree last_case;
- vec<tree> case_label_vec;
+ auto_vec<tree> case_label_vec;
gimple_seq switch_body = NULL;
- gimple x;
+ gimple *x;
geh_else *eh_else;
tree tmp;
- gimple switch_stmt;
+ gimple *switch_stmt;
gimple_seq finally;
- hash_map<tree, gimple> *cont_map = NULL;
+ hash_map<tree, gimple *> *cont_map = NULL;
/* The location of the TRY_FINALLY stmt. */
location_t tf_loc = gimple_location (tf->try_finally_expr);
/* The location of the finally block. */
/* We store the cont_stmt in the pointer map, so that we can recover
it in the loop below. */
if (!cont_map)
- cont_map = new hash_map<tree, gimple>;
+ cont_map = new hash_map<tree, gimple *>;
cont_map->put (case_lab, q->cont_stmt);
case_label_vec.quick_push (case_lab);
}
}
for (j = last_case_index; j < last_case_index + nlabels; j++)
{
- gimple cont_stmt;
+ gimple *cont_stmt;
last_case = case_label_vec[j];
for (gsi = gsi_start (finally); !gsi_end_p (gsi); gsi_next (&gsi))
{
- gimple stmt = gsi_stmt (gsi);
- if (!is_gimple_debug (stmt) && !gimple_clobber_p (stmt))
+ /* Duplicate __builtin_stack_restore in the hope of eliminating it
+ on the EH paths and, consequently, useless cleanups. */
+ gimple *stmt = gsi_stmt (gsi);
+ if (!is_gimple_debug (stmt)
+ && !gimple_clobber_p (stmt)
+ && !gimple_call_builtin_p (stmt, BUILT_IN_STACK_RESTORE))
return false;
}
return true;
}
/* Finally estimate N times, plus N gotos. */
- f_estimate = count_insns_seq (finally, &eni_size_weights);
+ f_estimate = estimate_num_insns_seq (finally, &eni_size_weights);
f_estimate = (f_estimate + 1) * ndests;
/* Switch statement (cost 10), N variable assignments, N gotos. */
if (this_tf.fallthru_label)
{
/* This must be reached only if ndests == 0. */
- gimple x = gimple_build_label (this_tf.fallthru_label);
+ gimple *x = gimple_build_label (this_tf.fallthru_label);
gimple_seq_add_stmt (&this_tf.top_p_seq, x);
}
gimple_stmt_iterator gsi;
tree out_label;
gimple_seq new_seq, cleanup;
- gimple x;
+ gimple *x;
location_t try_catch_loc = gimple_location (tp);
if (flag_exceptions)
{
struct leh_state this_state = *state;
eh_region this_region = NULL;
- gimple inner, x;
+ gimple *inner, *x;
gimple_seq new_seq;
inner = gimple_seq_first_stmt (gimple_try_cleanup (tp));
if (flag_exceptions)
{
- gimple inner = gimple_seq_first_stmt (gimple_try_cleanup (tp));
+ gimple *inner = gimple_seq_first_stmt (gimple_try_cleanup (tp));
eh_region this_region;
this_region = gen_eh_region_must_not_throw (state->cur_region);
result = gimple_try_eval (tp);
if (fake_tf.fallthru_label)
{
- gimple x = gimple_build_label (fake_tf.fallthru_label);
+ gimple *x = gimple_build_label (fake_tf.fallthru_label);
gimple_seq_add_stmt (&result, x);
}
}
lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi)
{
gimple_seq replace;
- gimple x;
- gimple stmt = gsi_stmt (*gsi);
+ gimple *x;
+ gimple *stmt = gsi_stmt (*gsi);
switch (gimple_code (stmt))
{
{
tree lhs = gimple_get_lhs (stmt);
tree tmp = create_tmp_var (TREE_TYPE (lhs));
- gimple s = gimple_build_assign (lhs, tmp);
+ gimple *s = gimple_build_assign (lhs, tmp);
gimple_set_location (s, gimple_location (stmt));
gimple_set_block (s, gimple_block (stmt));
gimple_set_lhs (stmt, tmp);
if there is such a landing pad within the current function. */
void
-make_eh_edges (gimple stmt)
+make_eh_edges (gimple *stmt)
{
basic_block src, dst;
eh_landing_pad lp;
{
eh_landing_pad old_lp, new_lp;
basic_block old_bb;
- gimple throw_stmt;
+ gimple *throw_stmt;
int old_lp_nr, new_lp_nr;
tree old_label, new_label;
edge_iterator ei;
an assignment or a conditional) may throw. */
static bool
-stmt_could_throw_1_p (gimple stmt)
+stmt_could_throw_1_p (gimple *stmt)
{
enum tree_code code = gimple_expr_code (stmt);
bool honor_nans = false;
/* Return true if statement STMT could throw an exception. */
bool
-stmt_could_throw_p (gimple stmt)
+stmt_could_throw_p (gimple *stmt)
{
if (!flag_exceptions)
return false;
the current function (CFUN). */
bool
-stmt_can_throw_external (gimple stmt)
+stmt_can_throw_external (gimple *stmt)
{
int lp_nr;
the current function (CFUN). */
bool
-stmt_can_throw_internal (gimple stmt)
+stmt_can_throw_internal (gimple *stmt)
{
int lp_nr;
any change was made. */
bool
-maybe_clean_eh_stmt_fn (struct function *ifun, gimple stmt)
+maybe_clean_eh_stmt_fn (struct function *ifun, gimple *stmt)
{
if (stmt_could_throw_p (stmt))
return false;
/* Likewise, but always use the current function. */
bool
-maybe_clean_eh_stmt (gimple stmt)
+maybe_clean_eh_stmt (gimple *stmt)
{
return maybe_clean_eh_stmt_fn (cfun, stmt);
}
done that my require an EH edge purge. */
bool
-maybe_clean_or_replace_eh_stmt (gimple old_stmt, gimple new_stmt)
+maybe_clean_or_replace_eh_stmt (gimple *old_stmt, gimple *new_stmt)
{
int lp_nr = lookup_stmt_eh_lp (old_stmt);
operand is the return value of duplicate_eh_regions. */
bool
-maybe_duplicate_eh_stmt_fn (struct function *new_fun, gimple new_stmt,
- struct function *old_fun, gimple old_stmt,
+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)
{
and thus no remapping is required. */
bool
-maybe_duplicate_eh_stmt (gimple new_stmt, gimple old_stmt)
+maybe_duplicate_eh_stmt (gimple *new_stmt, gimple *old_stmt)
{
int lp_nr;
same_handler_p (gimple_seq oneh, gimple_seq twoh)
{
gimple_stmt_iterator gsi;
- gimple ones, twos;
+ gimple *ones, *twos;
unsigned int ai;
gsi = gsi_start (oneh);
static void
optimize_double_finally (gtry *one, gtry *two)
{
- gimple oneh;
+ gimple *oneh;
gimple_stmt_iterator gsi;
gimple_seq cleanup;
refactor_eh_r (gimple_seq seq)
{
gimple_stmt_iterator gsi;
- gimple one, two;
+ gimple *one, *two;
one = NULL;
two = NULL;
int lp_nr;
eh_region src_r, dst_r;
gimple_stmt_iterator gsi;
- gimple x;
+ gimple *x;
tree fn, src_nr;
bool ret = false;
FOR_EACH_BB_FN (bb, fun)
{
- gimple last = last_stmt (bb);
+ gimple *last = last_stmt (bb);
if (last && is_gimple_resx (last))
{
dominance_invalidated |=
call, and has an incoming EH edge. */
for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
{
- gimple stmt = gsi_stmt (gsi);
+ gimple *stmt = gsi_stmt (gsi);
if (is_gimple_debug (stmt))
continue;
if (gimple_clobber_p (stmt))
gsi = gsi_last_bb (bb);
for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
{
- gimple stmt = gsi_stmt (gsi);
+ gimple *stmt = gsi_stmt (gsi);
if (!gimple_clobber_p (stmt))
continue;
unlink_stmt_vdef (stmt);
gsi = gsi_last_bb (bb);
for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
{
- gimple stmt = gsi_stmt (gsi);
+ gimple *stmt = gsi_stmt (gsi);
if (is_gimple_debug (stmt))
continue;
if (gimple_code (stmt) == GIMPLE_LABEL)
gsi = gsi_last_bb (bb);
for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
{
- gimple stmt = gsi_stmt (gsi);
+ gimple *stmt = gsi_stmt (gsi);
tree lhs;
if (is_gimple_debug (stmt))
continue;
/* But adjust virtual operands if we sunk across a PHI node. */
if (vuse)
{
- gimple use_stmt;
+ gimple *use_stmt;
imm_use_iterator iter;
use_operand_p use_p;
FOR_EACH_IMM_USE_STMT (use_stmt, iter, vuse)
int region_nr;
eh_region r;
tree filter, fn;
- gimple x;
+ gimple *x;
bool redirected = false;
region_nr = gimple_eh_dispatch_region (stmt);
FOR_EACH_BB_FN (bb, fun)
{
- gimple last = last_stmt (bb);
+ gimple *last = last_stmt (bb);
if (last == NULL)
continue;
if (gimple_code (last) == GIMPLE_EH_DISPATCH)
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- gimple stmt = gsi_stmt (gsi);
+ gimple *stmt = gsi_stmt (gsi);
if (mark_landing_pads)
{
tree rt = gimple_call_arg (stmt, i);
HOST_WIDE_INT ri = tree_to_shwi (rt);
- gcc_assert (ri = (int)ri);
+ gcc_assert (ri == (int)ri);
bitmap_set_bit (r_reachable, ri);
}
break;
sbitmap_free (r_reachable);
sbitmap_free (lp_reachable);
-#ifdef ENABLE_CHECKING
- verify_eh_tree (cfun);
-#endif
+ if (flag_checking)
+ verify_eh_tree (cfun);
}
/* Remove unreachable handlers if any landing pads have been removed after
{
for (gphi_iterator gpi = gsi_start_phis (bb); !gsi_end_p (gpi); )
{
- gimple use_stmt;
+ gimple *use_stmt;
gphi *phi = gpi.phi ();
tree lhs = gimple_phi_result (phi);
tree rhs = gimple_phi_arg_def (phi, 0);
{
basic_block bb = label_to_block (lp->post_landing_pad);
gimple_stmt_iterator gsi;
- gimple resx;
+ gimple *resx;
eh_region new_region;
edge_iterator ei;
edge e, e_out;
for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
if (e->flags & EDGE_EH)
{
- gimple stmt = last_stmt (e->src);
+ gimple *stmt = last_stmt (e->src);
remove_stmt_from_eh_lp (stmt);
remove_edge (e);
}
for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
if (e->flags & EDGE_EH)
{
- gimple stmt = last_stmt (e->src);
+ gimple *stmt = last_stmt (e->src);
remove_stmt_from_eh_lp (stmt);
add_stmt_to_eh_lp (stmt, new_lp_nr);
remove_edge (e);
edge that make_eh_edges would create. */
DEBUG_FUNCTION bool
-verify_eh_edges (gimple stmt)
+verify_eh_edges (gimple *stmt)
{
basic_block bb = gimple_bb (stmt);
eh_landing_pad lp = NULL;