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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120766
138bc75d-0d04-0410-961f-
82ee72b054a4
+2007-01-14 Jan Hubicka <jh@suse.cz>
+
+ * 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 <dvorakz@suse.cz>
* ipa-reference.c (analyze_function): Consider also addresses taken
2007-01-13 Zdenek Dvorak <dvorakz@suse.cz>
* ipa-reference.c (analyze_function): Consider also addresses taken
else
{
tree call = get_call_expr_in (stmt);
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;
if (call && CALL_EXPR_TAILCALL (call))
{
bool can_fallthru;
current_function_decl = node->decl;
delete_tree_ssa ();
delete_tree_cfg_annotations ();
current_function_decl = node->decl;
delete_tree_ssa ();
delete_tree_cfg_annotations ();
current_function_decl = old_decl;
pop_cfun();
}
current_function_decl = old_decl;
pop_cfun();
}
extern struct htab *get_eh_throw_stmt_table (struct function *);
extern void set_eh_throw_stmt_table (struct function *, struct htab *);
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
#include "hashtab.h"
#include "tree-ssa-propagate.h"
#include "value-prof.h"
#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. */
/* This file contains functions for building the Control Flow Graph (CFG)
for a function tree. */
static tree
verify_node_sharing (tree * tp, int *walk_subtrees, void *data)
{
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))
{
if (tree_node_can_be_shared (*tp))
{
- slot = htab_find_slot (htab, *tp, INSERT);
- if (*slot)
- return (tree) *slot;
- *slot = *tp;
+ if (pointer_set_insert (visited, *tp))
+ return *tp;
return walk_tree (&t, verify_gimple_tuples_1, NULL, NULL) != NULL;
}
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
/* Verify the GIMPLE statement chain. */
void
basic_block bb;
block_stmt_iterator bsi;
bool err = false;
basic_block bb;
block_stmt_iterator bsi;
bool err = false;
+ struct pointer_set_t *visited, *visited_stmts;
tree addr;
timevar_push (TV_TREE_STMT_VERIFY);
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 ();
{
int phi_num_args = PHI_NUM_ARGS (phi);
{
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");
if (bb_for_stmt (phi) != bb)
{
error ("bb_for_stmt (phi) is set to a wrong basic block");
- 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");
if (addr)
{
error ("incorrect sharing of tree nodes");
{
tree stmt = bsi_stmt (bsi);
{
tree stmt = bsi_stmt (bsi);
+ pointer_set_insert (visited_stmts, stmt);
err |= verify_gimple_tuples (stmt);
if (bb_for_stmt (stmt) != bb)
err |= verify_gimple_tuples (stmt);
if (bb_for_stmt (stmt) != bb)
bsi_next (&bsi);
err |= verify_stmt (stmt, bsi_end_p (bsi));
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");
if (addr)
{
error ("incorrect sharing of tree nodes");
+ 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 | eh_error_found)
internal_error ("verify_stmts failed");
internal_error ("verify_stmts failed");
+ pointer_set_destroy (visited);
+ pointer_set_destroy (visited_stmts);
verify_histograms ();
timevar_pop (TV_TREE_STMT_VERIFY);
}
verify_histograms ();
timevar_pop (TV_TREE_STMT_VERIFY);
}
slot = htab_find_slot (get_eh_throw_stmt_table (ifun), n, INSERT);
gcc_assert (!*slot);
*slot = n;
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);
if (slot)
{
htab_clear_slot (get_eh_throw_stmt_table (ifun), slot);
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);
-
-#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
/* And get rid of annotations we no longer need. */
delete_tree_cfg_annotations ();
/* 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