X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcfghooks.c;h=c4c51cc44042cf4258d9fbbe23c1aa8218578164;hb=126588a30d610641389529d156dda71e68e7e829;hp=ad5fb6b6c4cb2f37744c91b73a6a28f2e1b4d797;hpb=48e1416a24d50cacbb2a5e06a9ee61dd8cbee313;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c index ad5fb6b6c4c..c4c51cc4404 100644 --- a/gcc/cfghooks.c +++ b/gcc/cfghooks.c @@ -1,6 +1,6 @@ /* Hooks for cfg representation specific functions. - Copyright (C) 2003, 2004, 2005, 2007, 2008 Free Software Foundation, - Inc. + Copyright (C) 2003, 2004, 2005, 2007, 2008, 2010 + Free Software Foundation, Inc. Contributed by Sebastian Pop This file is part of GCC. @@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "basic-block.h" #include "tree-flow.h" #include "timevar.h" -#include "toplev.h" +#include "diagnostic-core.h" #include "cfgloop.h" /* A pointer to one of the hooks containers. */ @@ -88,7 +88,7 @@ current_ir_type (void) Currently it does following: checks edge and basic block list correctness and calls into IL dependent checking then. */ -void +DEBUG_FUNCTION void verify_flow_info (void) { size_t *edge_checksum; @@ -388,7 +388,6 @@ basic_block redirect_edge_and_branch_force (edge e, basic_block dest) { basic_block ret, src = e->src; - struct loop *loop; if (!cfg_hooks->redirect_edge_and_branch_force) internal_error ("%s does not support redirect_edge_and_branch_force", @@ -398,16 +397,17 @@ redirect_edge_and_branch_force (edge e, basic_block dest) rescan_loop_exit (e, false, true); ret = cfg_hooks->redirect_edge_and_branch_force (e, dest); - if (ret != NULL - && dom_info_available_p (CDI_DOMINATORS)) + + if (ret != NULL && dom_info_available_p (CDI_DOMINATORS)) set_immediate_dominator (CDI_DOMINATORS, ret, src); if (current_loops != NULL) { if (ret != NULL) { - loop = find_common_loop (single_pred (ret)->loop_father, - single_succ (ret)->loop_father); + struct loop *loop + = find_common_loop (single_pred (ret)->loop_father, + single_succ (ret)->loop_father); add_bb_to_loop (ret, loop); } else if (find_edge (src, dest) == e) @@ -820,6 +820,8 @@ make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge), return fallthru; } +/* Try to make the edge fallthru. */ + void tidy_fallthru_edge (edge e) { @@ -830,7 +832,9 @@ tidy_fallthru_edge (edge e) /* Fix up edges that now fall through, or rather should now fall through but previously required a jump around now deleted blocks. Simplify the search by only examining blocks numerically adjacent, since this - is how they were created. */ + is how they were created. + + ??? This routine is currently RTL specific. */ void tidy_fallthru_edges (void) @@ -872,6 +876,38 @@ tidy_fallthru_edges (void) } } +/* Edge E is assumed to be fallthru edge. Emit needed jump instruction + (and possibly create new basic block) to make edge non-fallthru. + Return newly created BB or NULL if none. */ + +basic_block +force_nonfallthru (edge e) +{ + basic_block ret, src = e->src; + + if (!cfg_hooks->force_nonfallthru) + internal_error ("%s does not support force_nonfallthru", + cfg_hooks->name); + + ret = cfg_hooks->force_nonfallthru (e); + if (ret != NULL) + { + if (dom_info_available_p (CDI_DOMINATORS)) + set_immediate_dominator (CDI_DOMINATORS, ret, src); + + if (current_loops != NULL) + { + struct loop *loop + = find_common_loop (single_pred (ret)->loop_father, + single_succ (ret)->loop_father); + rescan_loop_exit (e, false, true); + add_bb_to_loop (ret, loop); + } + } + + return ret; +} + /* Returns true if we can duplicate basic block BB. */ bool @@ -906,9 +942,7 @@ duplicate_block (basic_block bb, edge e, basic_block after) if (bb->count < new_count) new_count = bb->count; -#ifdef ENABLE_CHECKING - gcc_assert (can_duplicate_block_p (bb)); -#endif + gcc_checking_assert (can_duplicate_block_p (bb)); new_bb = cfg_hooks->duplicate_block (bb); if (after)