diff options
author | Richard Henderson <rth@redhat.com> | 2004-06-28 23:59:35 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2004-06-28 23:59:35 -0700 |
commit | 1eaba2f2086b04bb92b153214d970146452b2fb4 (patch) | |
tree | 017eaae88bfa95da2ee42be01673c3b4ea54a1c2 /gcc/tree-cfg.c | |
parent | afc066ef359fbce1d44025e59c67eeb08aa87a44 (diff) | |
download | gcc-1eaba2f2086b04bb92b153214d970146452b2fb4.zip gcc-1eaba2f2086b04bb92b153214d970146452b2fb4.tar.gz gcc-1eaba2f2086b04bb92b153214d970146452b2fb4.tar.bz2 |
tree-cfg.c (verify_stmt): Add last_in_block parameter.
* tree-cfg.c (verify_stmt): Add last_in_block parameter. Verify
that eh stmts can throw.
(verify_stmts): Update verify_stmt call.
(tree_purge_dead_eh_edges, tree_purge_all_dead_eh_edges): New.
* tree-eh.c (remove_stmt_from_eh_region): New.
(lower_eh_constructs): Fix throw_stmt_table delete routine.
(tree_could_trap_p): Match may_trap_p.
(maybe_clean_eh_stmt): New.
* tree-flow.h: Update decls.
* tree-ssa-ccp.c (pass_ccp): Add TODO_verify_stmts.
(substitute_and_fold): Clean eh edges.
* tree-ssa-dce.c (mark_control_dependent_edges_necessary): Handle
empty basic blocks.
* tree-ssa-dom.c (need_eh_cleanup): New.
(tree_ssa_dominator_optimize): Allocate it. Cleanup eh edges.
(optimize_stmt): Cleanup eh stmts; set need_eh_cleanup.
From-SVN: r83843
Diffstat (limited to 'gcc/tree-cfg.c')
-rw-r--r-- | gcc/tree-cfg.c | 67 |
1 files changed, 62 insertions, 5 deletions
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 6855d71..88e66f7 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -3316,15 +3316,14 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) TODO: Implement type checking. */ static bool -verify_stmt (tree stmt) +verify_stmt (tree stmt, bool last_in_block) { tree addr; if (!is_gimple_stmt (stmt)) { error ("Is not a valid GIMPLE statement."); - debug_generic_stmt (stmt); - return true; + goto fail; } addr = walk_tree (&stmt, verify_expr, NULL, NULL); @@ -3334,7 +3333,30 @@ verify_stmt (tree stmt) return true; } + /* If the statement is marked as part of an EH region, then it is + expected that the statement could throw. Verify that when we + have optimizations that simplify statements such that we prove + that they cannot throw, that we update other data structures + to match. */ + if (lookup_stmt_eh_region (stmt) >= 0) + { + if (!tree_could_throw_p (stmt)) + { + error ("Statement marked for throw, but doesn't."); + goto fail; + } + if (!last_in_block && tree_can_throw_internal (stmt)) + { + error ("Statement marked for throw in middle of block."); + goto fail; + } + } + return false; + + fail: + debug_generic_stmt (stmt); + return true; } @@ -3449,10 +3471,11 @@ verify_stmts (void) } } - for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) + for (bsi = bsi_start (bb); !bsi_end_p (bsi); ) { tree stmt = bsi_stmt (bsi); - err |= verify_stmt (stmt); + bsi_next (&bsi); + err |= verify_stmt (stmt, bsi_end_p (bsi)); addr = walk_tree (&stmt, verify_node_sharing, htab, NULL); if (addr) { @@ -4637,6 +4660,40 @@ tree_flow_call_edges_add (sbitmap blocks) return blocks_split; } +bool +tree_purge_dead_eh_edges (basic_block bb) +{ + bool changed = false; + edge e, next; + tree stmt = last_stmt (bb); + + if (stmt && tree_can_throw_internal (stmt)) + return false; + + for (e = bb->succ; e ; e = next) + { + next = e->succ_next; + if (e->flags & EDGE_EH) + { + ssa_remove_edge (e); + changed = true; + } + } + + return changed; +} + +bool +tree_purge_all_dead_eh_edges (bitmap blocks) +{ + bool changed = false; + size_t i; + + EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i, + { changed |= tree_purge_dead_eh_edges (BASIC_BLOCK (i)); }); + + return changed; +} struct cfg_hooks tree_cfg_hooks = { "tree", |