From 202bbc063702f3adafb54ddc86142c04a77a1315 Mon Sep 17 00:00:00 2001 From: ebotcazou Date: Thu, 7 Apr 2011 21:11:51 +0000 Subject: * basic-block.h (force_nonfallthru): Move to... * cfghooks.h (struct cfg_hooks): Add force_nonfallthru hook. (force_nonfallthru): ...here. * cfghooks.c (force_nonfallthru): New function. * cfgrtl.c (force_nonfallthru): Rename into... (rtl_force_nonfallthru): ...this. (commit_one_edge_insertion): Do not set AUX field. (commit_edge_insertions): Do not discover new basic blocks. (rtl_cfg_hooks): Add rtl_force_nonfallthru. (cfg_layout_rtl_cfg_hooks): Likewise. * function.c (thread_prologue_and_epilogue_insns): Remove bogus ATTRIBUTE_UNUSED. Discover new basic blocks in the prologue insns. * tree-cfg.c (gimple_cfg_hooks): Add NULL for force_nonfallthru. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@172128 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cfghooks.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'gcc/cfghooks.c') diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c index fb991a76171..34685f4444a 100644 --- a/gcc/cfghooks.c +++ b/gcc/cfghooks.c @@ -398,8 +398,7 @@ 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) @@ -820,6 +819,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) { @@ -874,6 +875,42 @@ 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, dest = e->dest; + struct loop *loop; + + if (!cfg_hooks->force_nonfallthru) + internal_error ("%s does not support force_nonfallthru", + cfg_hooks->name); + + if (current_loops != NULL) + rescan_loop_exit (e, false, true); + + ret = cfg_hooks->force_nonfallthru (e); + 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); + add_bb_to_loop (ret, loop); + } + else if (find_edge (src, dest) == e) + rescan_loop_exit (e, true, false); + } + + return ret; +} + /* Returns true if we can duplicate basic block BB. */ bool -- cgit v1.2.1