aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfghooks.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2011-04-07 21:11:51 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2011-04-07 21:11:51 +0000
commitcf103ca449e8f5e38f42b107b3271b18c73c59a5 (patch)
tree145e2606d4e9bb3d9ec4665487247f62c68485dd /gcc/cfghooks.c
parentdf9292840d1a59a7eee79d70fb38bafabd6049fa (diff)
downloadgcc-cf103ca449e8f5e38f42b107b3271b18c73c59a5.zip
gcc-cf103ca449e8f5e38f42b107b3271b18c73c59a5.tar.gz
gcc-cf103ca449e8f5e38f42b107b3271b18c73c59a5.tar.bz2
basic-block.h (force_nonfallthru): Move to...
* 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. From-SVN: r172128
Diffstat (limited to 'gcc/cfghooks.c')
-rw-r--r--gcc/cfghooks.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index fb991a7..34685f4 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