diff options
author | Zdenek Dvorak <dvorakz@suse.cz> | 2007-02-05 00:47:09 +0100 |
---|---|---|
committer | Zdenek Dvorak <rakdver@gcc.gnu.org> | 2007-02-04 23:47:09 +0000 |
commit | 14fa2cc05762323f22f92cdb1dee039277bc6292 (patch) | |
tree | f496fa9bd8e7472a0092f253d2c670a09063973a /gcc/cfghooks.c | |
parent | 284893341f2086559700fe966ea86e8e1196f775 (diff) | |
download | gcc-14fa2cc05762323f22f92cdb1dee039277bc6292.zip gcc-14fa2cc05762323f22f92cdb1dee039277bc6292.tar.gz gcc-14fa2cc05762323f22f92cdb1dee039277bc6292.tar.bz2 |
cfgloopmanip.c (loop_delete_branch_edge): Removed.
* cfgloopmanip.c (loop_delete_branch_edge): Removed.
(remove_path): Use can_remove_branch_p and remove_branch instead
of loop_delete_branch_edge.
* tree-ssa-loop-manip.c (scale_dominated_blocks_in_loop): New function.
(tree_transform_and_unroll_loop): Remove dead branches immediately.
Update profile using scale_dominated_blocks_in_loop.
* cfghooks.c (can_remove_branch_p, remove_branch): New functions.
* cfghooks.h (struct cfg_hooks): Add can_remove_branch_p.
(can_remove_branch_p, remove_branch): Declare.
* tree-cfg.c (tree_can_remove_branch_p): New function.
(tree_cfg_hooks): Add tree_can_remove_branch_p.
* cfgrtl.c (rtl_can_remove_branch_p): New function.
(rtl_cfg_hooks, cfg_layout_rtl_cfg_hook): Add rtl_can_remove_branch_p.
From-SVN: r121583
Diffstat (limited to 'gcc/cfghooks.c')
-rw-r--r-- | gcc/cfghooks.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c index d6a981d..d65cce9 100644 --- a/gcc/cfghooks.c +++ b/gcc/cfghooks.c @@ -318,6 +318,48 @@ redirect_edge_and_branch (edge e, basic_block dest) return ret; } +/* Returns true if it is possible to remove the edge E by redirecting it + to the destination of the other edge going from its source. */ + +bool +can_remove_branch_p (edge e) +{ + if (!cfg_hooks->can_remove_branch_p) + internal_error ("%s does not support can_remove_branch_p", + cfg_hooks->name); + + if (EDGE_COUNT (e->src->succs) != 2) + return false; + + return cfg_hooks->can_remove_branch_p (e); +} + +/* Removes E, by redirecting it to the destination of the other edge going + from its source. Can_remove_branch_p must be true for E, hence this + operation cannot fail. */ + +void +remove_branch (edge e) +{ + edge other; + basic_block src = e->src; + int irr; + + gcc_assert (EDGE_COUNT (e->src->succs) == 2); + + other = EDGE_SUCC (src, EDGE_SUCC (src, 0) == e); + irr = other->flags & EDGE_IRREDUCIBLE_LOOP; + + if (current_loops != NULL) + rescan_loop_exit (e, false, true); + + e = redirect_edge_and_branch (e, other->dest); + gcc_assert (e != NULL); + + e->flags &= ~EDGE_IRREDUCIBLE_LOOP; + e->flags |= irr; +} + /* Redirect the edge E to basic block DEST even if it requires creating of a new basic block; then it returns the newly created basic block. Aborts when redirection is impossible. */ |