aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-switch-conversion.c
diff options
context:
space:
mode:
authorSteven Bosscher <steven@gcc.gnu.org>2012-05-03 11:14:15 +0000
committerSteven Bosscher <steven@gcc.gnu.org>2012-05-03 11:14:15 +0000
commit6ab1ab1480bf6090f1da481e6cb3da59e46f31bf (patch)
tree767acae9ce911d995b67441e042cc3ddac67a02f /gcc/tree-switch-conversion.c
parent1937283892c2fb55b9c22f4d91b3185a99ed335a (diff)
downloadgcc-6ab1ab1480bf6090f1da481e6cb3da59e46f31bf.zip
gcc-6ab1ab1480bf6090f1da481e6cb3da59e46f31bf.tar.gz
gcc-6ab1ab1480bf6090f1da481e6cb3da59e46f31bf.tar.bz2
tree-switch-conversion.c (gen_inbound_check): Free post-dominance information as early as possible.
* tree-switch-conversion.c (gen_inbound_check): Free post-dominance information as early as possible. Update dominance info instead of discarding it. From-SVN: r187093
Diffstat (limited to 'gcc/tree-switch-conversion.c')
-rw-r--r--gcc/tree-switch-conversion.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 3d10750..4f3d1d3 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -800,6 +800,14 @@ gen_inbound_check (gimple swtch, struct switch_conv_info *info)
location_t loc = gimple_location (swtch);
gcc_assert (info->default_values);
+
+ /* Make no effort to update the post-dominator tree. It is actually not
+ that hard for the transformations we have performed, but it is not
+ supported by iterate_fix_dominators.
+ Freeing post-dominance info is dome early to avoid pointless work in
+ create_basic_block, which is called when we split SWITCH_BB. */
+ free_dominance_info (CDI_POST_DOMINATORS);
+
bb0 = gimple_bb (swtch);
tidx = gimple_assign_lhs (info->arr_ref_first);
@@ -866,13 +874,32 @@ gen_inbound_check (gimple swtch, struct switch_conv_info *info)
bb2->frequency = EDGE_FREQUENCY (e02);
bbf->frequency = EDGE_FREQUENCY (e1f) + EDGE_FREQUENCY (e2f);
- prune_bbs (bbd, info->final_bb); /* To keep calc_dfs_tree() in dominance.c
- happy. */
+ /* Tidy blocks that have become unreachable. */
+ prune_bbs (bbd, info->final_bb);
+ /* Fixup the PHI nodes in bbF. */
fix_phi_nodes (e1f, e2f, bbf, info);
- free_dominance_info (CDI_DOMINATORS);
- free_dominance_info (CDI_POST_DOMINATORS);
+ /* Fix the dominator tree, if it is available. */
+ if (dom_info_available_p (CDI_DOMINATORS))
+ {
+ VEC (basic_block, heap) *bbs_to_fix_dom;
+
+ set_immediate_dominator (CDI_DOMINATORS, bb1, bb0);
+ set_immediate_dominator (CDI_DOMINATORS, bb2, bb0);
+ if (! get_immediate_dominator(CDI_DOMINATORS, bbf))
+ /* If bbD was the immediate dominator ... */
+ set_immediate_dominator (CDI_DOMINATORS, bbf, bb0);
+
+ bbs_to_fix_dom = VEC_alloc (basic_block, heap, 4);
+ VEC_quick_push (basic_block, bbs_to_fix_dom, bb0);
+ VEC_quick_push (basic_block, bbs_to_fix_dom, bb1);
+ VEC_quick_push (basic_block, bbs_to_fix_dom, bb2);
+ VEC_quick_push (basic_block, bbs_to_fix_dom, bbf);
+
+ iterate_fix_dominators (CDI_DOMINATORS, bbs_to_fix_dom, true);
+ VEC_free (basic_block, heap, bbs_to_fix_dom);
+ }
}
/* The following function is invoked on every switch statement (the current one