diff options
author | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-04 23:47:09 +0000 |
---|---|---|
committer | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-04 23:47:09 +0000 |
commit | 611d2ac17cbd3df0489cffe3fda88ec503a3e059 (patch) | |
tree | f496fa9bd8e7472a0092f253d2c670a09063973a /gcc/cfghooks.c | |
parent | 9606b4af46c2fe61092079ffd9bb3db991b9f615 (diff) | |
download | gcc-611d2ac17cbd3df0489cffe3fda88ec503a3e059.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121583 138bc75d-0d04-0410-961f-82ee72b054a4
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 d6a981d1db8..d65cce98fa9 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. */ |