tree-switch-conversion.c (gen_inbound_check): Free post-dominance information as...
authorSteven Bosscher <steven@gcc.gnu.org>
Thu, 3 May 2012 11:14:15 +0000 (11:14 +0000)
committerSteven Bosscher <steven@gcc.gnu.org>
Thu, 3 May 2012 11:14:15 +0000 (11:14 +0000)
* 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

gcc/ChangeLog
gcc/tree-switch-conversion.c

index 788574b5290b1fe037a5257873ae5d9f73bb6306..60ffb7d9cf4d2a8d8d3896a37f72193f16c118cb 100644 (file)
@@ -1,3 +1,9 @@
+2012-05-03  Steven Bosscher  <steven@gcc.gnu.org>
+
+       * tree-switch-conversion.c (gen_inbound_check): Free post-dominance
+       information as early as possible.  Update dominance info instead of
+       discarding it.
+
 2012-05-03  Richard Guenther  <rguenther@suse.de>
 
        * tree-ssa-pre.c (debug_bitmap_sets_for): New function.
index 3d10750e4dc480996f0bc2322fbd7d2be7a83d2d..4f3d1d30f206579bde4d2e3ec34b32a8383276fc 100644 (file)
@@ -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