diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e18dfd6f4b6..e79b7de7a85 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2007-01-14 Jan Hubicka + + * tree-eh.c (add_stmt_to_eh_region_fn): Do not add call_exprs + separately. + (remove_stmt_from_eh_region_fn): Do not remove call_exprs. + (verify_eh_throw_stmt_node, verify_eh_throw_table_statements): Kill. + * except.h (verify_eh_throw_table_statements): Kill prototype. + * cfgexpand.c (expand_gimple_basic_block): Propagate Eh regions + into call exrepssions. + * tree-optimize.c (execute_free_cfg_annotatiosn): Do not call + eh trhow verifier. + * tree-cfg.c: Include pointer-set.h. + (verify_node_sharing): Work on pointer set. + (verify_eh_throw_stmt_node): New. + (verify_stmts): Use pointers sets, verify throw_stmt. + 2007-01-13 Zdenek Dvorak * ipa-reference.c (analyze_function): Consider also addresses taken diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index b8d44a65e0c..b91af8ef799 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -1512,6 +1512,13 @@ expand_gimple_basic_block (basic_block bb) else { tree call = get_call_expr_in (stmt); + int region; + /* For the benefit of calls.c, converting all this to rtl, + we need to record the call expression, not just the outer + modify statement. */ + if (call && call != stmt + && (region = lookup_stmt_eh_region (stmt)) > 0) + add_stmt_to_eh_region (call, region); if (call && CALL_EXPR_TAILCALL (call)) { bool can_fallthru; diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 8914569b395..1f7f0ad6742 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -481,6 +481,7 @@ cgraph_release_function_body (struct cgraph_node *node) current_function_decl = node->decl; delete_tree_ssa (); delete_tree_cfg_annotations (); + cfun->eh = NULL; current_function_decl = old_decl; pop_cfun(); } diff --git a/gcc/except.h b/gcc/except.h index 5efad71647f..5b50d2aa8c8 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -176,7 +176,3 @@ struct throw_stmt_node GTY(()) extern struct htab *get_eh_throw_stmt_table (struct function *); extern void set_eh_throw_stmt_table (struct function *, struct htab *); - -#ifdef ENABLE_CHECKING -extern void verify_eh_throw_table_statements (void); -#endif diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 69b4b4bb0a5..e4971384438 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -47,6 +47,7 @@ Boston, MA 02110-1301, USA. */ #include "hashtab.h" #include "tree-ssa-propagate.h" #include "value-prof.h" +#include "pointer-set.h" /* This file contains functions for building the Control Flow Graph (CFG) for a function tree. */ @@ -3525,8 +3526,7 @@ tree_node_can_be_shared (tree t) static tree verify_node_sharing (tree * tp, int *walk_subtrees, void *data) { - htab_t htab = (htab_t) data; - void **slot; + struct pointer_set_t *visited = (struct pointer_set_t *) data; if (tree_node_can_be_shared (*tp)) { @@ -3534,10 +3534,8 @@ verify_node_sharing (tree * tp, int *walk_subtrees, void *data) return NULL; } - slot = htab_find_slot (htab, *tp, INSERT); - if (*slot) - return (tree) *slot; - *slot = *tp; + if (pointer_set_insert (visited, *tp)) + return *tp; return NULL; } @@ -3572,6 +3570,22 @@ verify_gimple_tuples (tree t) return walk_tree (&t, verify_gimple_tuples_1, NULL, NULL) != NULL; } +static bool eh_error_found; +static int +verify_eh_throw_stmt_node (void **slot, void *data) +{ + struct throw_stmt_node *node = (struct throw_stmt_node *)*slot; + struct pointer_set_t *visited = (struct pointer_set_t *) data; + + if (!pointer_set_contains (visited, node->stmt)) + { + error ("Dead STMT in EH table"); + debug_generic_stmt (node->stmt); + eh_error_found = true; + } + return 0; +} + /* Verify the GIMPLE statement chain. */ void @@ -3580,11 +3594,12 @@ verify_stmts (void) basic_block bb; block_stmt_iterator bsi; bool err = false; - htab_t htab; + struct pointer_set_t *visited, *visited_stmts; tree addr; timevar_push (TV_TREE_STMT_VERIFY); - htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL); + visited = pointer_set_create (); + visited_stmts = pointer_set_create (); FOR_EACH_BB (bb) { @@ -3595,6 +3610,7 @@ verify_stmts (void) { int phi_num_args = PHI_NUM_ARGS (phi); + pointer_set_insert (visited_stmts, phi); if (bb_for_stmt (phi) != bb) { error ("bb_for_stmt (phi) is set to a wrong basic block"); @@ -3625,7 +3641,7 @@ verify_stmts (void) err |= true; } - addr = walk_tree (&t, verify_node_sharing, htab, NULL); + addr = walk_tree (&t, verify_node_sharing, visited, NULL); if (addr) { error ("incorrect sharing of tree nodes"); @@ -3640,6 +3656,7 @@ verify_stmts (void) { tree stmt = bsi_stmt (bsi); + pointer_set_insert (visited_stmts, stmt); err |= verify_gimple_tuples (stmt); if (bb_for_stmt (stmt) != bb) @@ -3650,7 +3667,7 @@ verify_stmts (void) bsi_next (&bsi); err |= verify_stmt (stmt, bsi_end_p (bsi)); - addr = walk_tree (&stmt, verify_node_sharing, htab, NULL); + addr = walk_tree (&stmt, verify_node_sharing, visited, NULL); if (addr) { error ("incorrect sharing of tree nodes"); @@ -3660,11 +3677,17 @@ verify_stmts (void) } } } + eh_error_found = false; + if (get_eh_throw_stmt_table (cfun)) + htab_traverse (get_eh_throw_stmt_table (cfun), + verify_eh_throw_stmt_node, + visited_stmts); - if (err) + if (err | eh_error_found) internal_error ("verify_stmts failed"); - htab_delete (htab); + pointer_set_destroy (visited); + pointer_set_destroy (visited_stmts); verify_histograms (); timevar_pop (TV_TREE_STMT_VERIFY); } diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 760cdc3da10..2965357f9b5 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -112,12 +112,6 @@ add_stmt_to_eh_region_fn (struct function *ifun, tree t, int num) slot = htab_find_slot (get_eh_throw_stmt_table (ifun), n, INSERT); gcc_assert (!*slot); *slot = n; - /* ??? For the benefit of calls.c, converting all this to rtl, - we need to record the call expression, not just the outer - modify statement. */ - if (TREE_CODE (t) == GIMPLE_MODIFY_STMT - && (t = get_call_expr_in (t))) - add_stmt_to_eh_region_fn (ifun, t, num); } void @@ -141,12 +135,6 @@ remove_stmt_from_eh_region_fn (struct function *ifun, tree t) if (slot) { htab_clear_slot (get_eh_throw_stmt_table (ifun), slot); - /* ??? For the benefit of calls.c, converting all this to rtl, - we need to record the call expression, not just the outer - modify statement. */ - if (TREE_CODE (t) == GIMPLE_MODIFY_STMT - && (t = get_call_expr_in (t))) - remove_stmt_from_eh_region_fn (ifun, t); return true; } else @@ -2074,25 +2062,3 @@ maybe_clean_or_replace_eh_stmt (tree old_stmt, tree new_stmt) return false; } - -#ifdef ENABLE_CHECKING -static int -verify_eh_throw_stmt_node (void **slot, void *data ATTRIBUTE_UNUSED) -{ - struct throw_stmt_node *node = (struct throw_stmt_node *)*slot; - - gcc_assert (node->stmt->base.ann == NULL); - return 1; -} - -void -verify_eh_throw_table_statements (void) -{ - if (!get_eh_throw_stmt_table (cfun)) - return; - htab_traverse (get_eh_throw_stmt_table (cfun), - verify_eh_throw_stmt_node, - NULL); -} - -#endif diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index 6c5fb550ff5..a2439be7574 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -247,11 +247,6 @@ execute_free_cfg_annotations (void) /* And get rid of annotations we no longer need. */ delete_tree_cfg_annotations (); -#ifdef ENABLE_CHECKING - /* Once the statement annotations have been removed, we can verify - the integrity of statements in the EH throw table. */ - verify_eh_throw_table_statements (); -#endif return 0; }