X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-cfgcleanup.c;h=8cf66cb4a270c5bddef8b7ffcee0e9d11dcf5144;hb=bca4d139fd7eb1b554c6701071c27048a0e458a6;hp=d13a53668d42ac49569b906531d4c6eecf12884a;hpb=7194de72e1651831d842524a0d0a01f64f8f98ed;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index d13a53668d4..8cf66cb4a27 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -1,5 +1,6 @@ /* CFG cleanup for trees. - Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. This file is part of GCC. @@ -28,7 +29,7 @@ Boston, MA 02110-1301, USA. */ #include "hard-reg-set.h" #include "basic-block.h" #include "output.h" -#include "errors.h" +#include "toplev.h" #include "flags.h" #include "function.h" #include "expr.h" @@ -78,6 +79,9 @@ cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi) { edge e; edge_iterator ei; + bool warned; + + fold_defer_overflow_warnings (); switch (TREE_CODE (expr)) { @@ -88,7 +92,10 @@ cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi) case SWITCH_EXPR: val = fold (SWITCH_COND (expr)); if (TREE_CODE (val) != INTEGER_CST) - return false; + { + fold_undefer_and_ignore_overflow_warnings (); + return false; + } break; default: @@ -97,13 +104,24 @@ cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi) taken_edge = find_taken_edge (bb, val); if (!taken_edge) - return false; + { + fold_undefer_and_ignore_overflow_warnings (); + return false; + } /* Remove all the edges except the one that is always executed. */ + warned = false; for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) { if (e != taken_edge) { + if (!warned) + { + fold_undefer_overflow_warnings + (true, expr, WARN_STRICT_OVERFLOW_CONDITIONAL); + warned = true; + } + taken_edge->probability += e->probability; taken_edge->count += e->count; remove_edge (e); @@ -112,6 +130,8 @@ cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi) else ei_next (&ei); } + if (!warned) + fold_undefer_and_ignore_overflow_warnings (); if (taken_edge->probability > REG_BR_PROB_BASE) taken_edge->probability = REG_BR_PROB_BASE; } @@ -127,14 +147,6 @@ cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi) return retval; } -/* A list of all the noreturn calls passed to modify_stmt. - cleanup_control_flow uses it to detect cases where a mid-block - indirect call has been turned into a noreturn call. When this - happens, all the instructions after the call are no longer - reachable and must be deleted as dead. */ - -VEC(tree,gc) *modified_noreturn_calls; - /* Try to remove superfluous control structures. */ static bool @@ -146,13 +158,14 @@ cleanup_control_flow (void) tree stmt; /* Detect cases where a mid-block call is now known not to return. */ - while (VEC_length (tree, modified_noreturn_calls)) - { - stmt = VEC_pop (tree, modified_noreturn_calls); - bb = bb_for_stmt (stmt); - if (bb != NULL && last_stmt (bb) != stmt && noreturn_call_p (stmt)) - split_block (bb, stmt); - } + if (cfun->gimple_df) + while (VEC_length (tree, MODIFIED_NORETURN_CALLS (cfun))) + { + stmt = VEC_pop (tree, MODIFIED_NORETURN_CALLS (cfun)); + bb = bb_for_stmt (stmt); + if (bb != NULL && last_stmt (bb) != stmt && noreturn_call_p (stmt)) + split_block (bb, stmt); + } FOR_EACH_BB (bb) { @@ -581,7 +594,7 @@ cleanup_tree_cfg (void) /* Cleanup cfg and repair loop structures. */ -void +bool cleanup_tree_cfg_loop (void) { bool changed = cleanup_tree_cfg (); @@ -589,8 +602,8 @@ cleanup_tree_cfg_loop (void) if (changed) { bitmap changed_bbs = BITMAP_ALLOC (NULL); - fix_loop_structure (changed_bbs); calculate_dominance_info (CDI_DOMINATORS); + fix_loop_structure (changed_bbs); /* This usually does nothing. But sometimes parts of cfg that originally were inside a loop get out of it due to edge removal (since they @@ -604,6 +617,7 @@ cleanup_tree_cfg_loop (void) #endif scev_reset (); } + return changed; } /* Merge the PHI nodes at BB into those at BB's sole successor. */