diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-29 06:59:35 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-29 06:59:35 +0000 |
commit | 35c15734e84896f65e212c1263ea47c19acd42a0 (patch) | |
tree | 017eaae88bfa95da2ee42be01673c3b4ea54a1c2 /gcc/tree-eh.c | |
parent | cbf596b8cad9e18f4ebfa83d65d8f7efc72e77ec (diff) | |
download | gcc-35c15734e84896f65e212c1263ea47c19acd42a0.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83843 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-eh.c')
-rw-r--r-- | gcc/tree-eh.c | 111 |
1 files changed, 101 insertions, 10 deletions
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index f15fe099142..c0ddf3e7c3c 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -119,7 +119,27 @@ add_stmt_to_eh_region (tree t, int num) abort (); *slot = n; } - + +bool +remove_stmt_from_eh_region (tree t) +{ + struct throw_stmt_node dummy; + void **slot; + + if (!throw_stmt_table) + return false; + + dummy.stmt = t; + slot = htab_find_slot (throw_stmt_table, &dummy, NO_INSERT); + if (slot) + { + htab_clear_slot (throw_stmt_table, slot); + return true; + } + else + return false; +} + int lookup_stmt_eh_region (tree t) { @@ -1600,7 +1620,8 @@ lower_eh_constructs (void) tree *tp = &DECL_SAVED_TREE (current_function_decl); finally_tree = htab_create (31, struct_ptr_hash, struct_ptr_eq, free); - throw_stmt_table = htab_create_ggc (31, struct_ptr_hash, struct_ptr_eq, free); + throw_stmt_table = htab_create_ggc (31, struct_ptr_hash, struct_ptr_eq, + ggc_free); collect_finally_tree (*tp, NULL); @@ -1670,15 +1691,32 @@ make_eh_edges (tree stmt) -/* Return true if the expr can trap, as in dereferencing an - invalid pointer location. */ +/* Return true if the expr can trap, as in dereferencing an invalid pointer + location or floating point arithmetic. C.f. the rtl version, may_trap_p. + This routine expects only GIMPLE lhs or rhs input. */ bool tree_could_trap_p (tree expr) { enum tree_code code = TREE_CODE (expr); + bool honor_nans = false; + bool honor_snans = false; + bool fp_operation = false; tree t; + if (TREE_CODE_CLASS (code) == '<' + || TREE_CODE_CLASS (code) == '1' + || TREE_CODE_CLASS (code) == '2') + { + t = TREE_TYPE (expr); + fp_operation = FLOAT_TYPE_P (t); + if (fp_operation) + { + honor_nans = flag_trapping_math && !flag_finite_math_only; + honor_snans = flag_signaling_nans != 0; + } + } + switch (code) { case ARRAY_REF: @@ -1691,7 +1729,10 @@ tree_could_trap_p (tree expr) return !t || tree_could_trap_p (t); case INDIRECT_REF: - return (TREE_THIS_NOTRAP (expr) == false); + return !TREE_THIS_NOTRAP (expr); + + case ASM_EXPR: + return TREE_THIS_VOLATILE (expr); case TRUNC_DIV_EXPR: case CEIL_DIV_EXPR: @@ -1702,16 +1743,57 @@ tree_could_trap_p (tree expr) case FLOOR_MOD_EXPR: case ROUND_MOD_EXPR: case TRUNC_MOD_EXPR: - return true; + case RDIV_EXPR: + if (honor_snans) + return true; + if (fp_operation && flag_trapping_math) + return true; + t = TREE_OPERAND (expr, 1); + if (!TREE_CONSTANT (t) || integer_zerop (t)) + return true; + return false; + + case LT_EXPR: + case LE_EXPR: + case GT_EXPR: + case GE_EXPR: + case LTGT_EXPR: + /* Some floating point comparisons may trap. */ + return honor_nans; + + case EQ_EXPR: + case NE_EXPR: + case UNORDERED_EXPR: + case ORDERED_EXPR: + case UNLT_EXPR: + case UNLE_EXPR: + case UNGT_EXPR: + case UNGE_EXPR: + case UNEQ_EXPR: + return honor_snans; + + case CONVERT_EXPR: + case FIX_TRUNC_EXPR: + case FIX_CEIL_EXPR: + case FIX_FLOOR_EXPR: + case FIX_ROUND_EXPR: + /* Conversion of floating point might trap. */ + return honor_nans; + + case NEGATE_EXPR: + case ABS_EXPR: + case CONJ_EXPR: + /* These operations don't trap even with floating point. */ + return false; default: - break; + /* Any floating arithmetic may trap. */ + if (fp_operation && flag_trapping_math) + return true; + return false; } - - return false; } - bool tree_could_throw_p (tree t) { @@ -1750,4 +1832,13 @@ tree_can_throw_external (tree stmt) return can_throw_external_1 (region_nr); } +bool +maybe_clean_eh_stmt (tree stmt) +{ + if (!tree_could_throw_p (stmt)) + if (remove_stmt_from_eh_region (stmt)) + return true; + return false; +} + #include "gt-tree-eh.h" |