Commit a31895d7 by Tom de Vries Committed by Tom de Vries

re PR tree-optimization/50908 (building emacs-23.3; gives msg: indent.c:1140:1:…

re PR tree-optimization/50908 (building emacs-23.3; gives msg: indent.c:1140:1: internal compiler error: in verify_dominators, at dominance.c:1041)

2011-11-01  Tom de Vries  <tom@codesourcery.com>

	PR tree-optimization/50908
	* tree-ssa-tail-merge.c (update_vuses): Now that edges are removed
	before update_vuses, test for 1 predecessor rather than two.
	(delete_block_update_dominator_info): New function, part of it factored
	out of ...
	(replace_block_by): Use delete_block_update_dominator_info.  Call
	update_vuses after deleting bb1 and updating dominator info, instead of
	before.

From-SVN: r180737
parent eb6a1e56
2011-11-01 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/50908
* tree-ssa-tail-merge.c (update_vuses): Now that edges are removed
before update_vuses, test for 1 predecessor rather than two.
(delete_block_update_dominator_info): New function, part of it factored
out of ...
(replace_block_by): Use delete_block_update_dominator_info. Call
update_vuses after deleting bb1 and updating dominator info, instead of
before.
2011-11-01 David S. Miller <davem@davemloft.net> 2011-11-01 David S. Miller <davem@davemloft.net>
* config/sparc/sparc.c (sparc_expand_vcond): New function. * config/sparc/sparc.c (sparc_expand_vcond): New function.
...@@ -1458,7 +1458,7 @@ update_vuses (bool vuse1_phi_args, tree vuse1, tree vuse2, basic_block bb2, ...@@ -1458,7 +1458,7 @@ update_vuses (bool vuse1_phi_args, tree vuse1, tree vuse2, basic_block bb2,
if (!dominated_by_p (CDI_DOMINATORS, pred, bb2)) if (!dominated_by_p (CDI_DOMINATORS, pred, bb2))
continue; continue;
if (pred == bb2 && EDGE_COUNT (gimple_bb (stmt)->preds) == 2) if (pred == bb2 && EDGE_COUNT (gimple_bb (stmt)->preds) == 1)
{ {
gimple_stmt_iterator gsi = gsi_for_stmt (stmt); gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
unlink_virtual_phi (stmt, lhs); unlink_virtual_phi (stmt, lhs);
...@@ -1526,6 +1526,88 @@ vop_at_entry (basic_block bb) ...@@ -1526,6 +1526,88 @@ vop_at_entry (basic_block bb)
: NULL_TREE); : NULL_TREE);
} }
/* Given that all incoming edges of BB1 have been redirected to BB2, delete BB1
and recompute dominator info. */
static void
delete_block_update_dominator_info (basic_block bb1, basic_block bb2)
{
VEC (basic_block,heap) *fix_dom_bb;
unsigned int i;
basic_block bb, dom;
edge e;
edge_iterator ei;
/* Consider the following cfg, where A is the direct dominator of I:
A
/ \
B \
/ \ \
C D
/| |\
E F
|\ /|
| x |
|/ \|
G H
\ /
I
Say E and F are duplicates, and F is removed. The cfg then looks like
this:
A
/ \
B \
/ \ \
C D
/ \ / \
E
/ \
G H
\ /
I
E is now the new direct dominator of I.
In order to calculate the new dominator info, we take the nearest common
dominator (A) of bb1 (F) and bb2 (E), and get the set of bbs immediately
dominated by it. Some of this set may now be directly dominated by bb2.
Ideally we would have a means to determine which bbs in the set are now
dominated by bb2, and call set_immediate_dominator for those bbs, but we
don't, so instead we let iterate_fix_dominators figure it out. */
/* Add bbs immediately dominated by the most common dominator. */
dom = nearest_common_dominator (CDI_DOMINATORS, bb1, bb2);
fix_dom_bb = get_dominated_by (CDI_DOMINATORS, dom);
if (get_immediate_dominator (CDI_DOMINATORS, bb1) == dom)
for (i = 0; VEC_iterate (basic_block, fix_dom_bb, i, bb); ++i)
{
if (bb != bb1)
continue;
VEC_unordered_remove (basic_block, fix_dom_bb, i);
break;
}
/* Add bb2, but not twice. */
if (get_immediate_dominator (CDI_DOMINATORS, bb2) != dom)
VEC_safe_push (basic_block, heap, fix_dom_bb, bb2);
/* Add succs of bb2, but not twice. */
FOR_EACH_EDGE (e, ei, bb2->succs)
if (get_immediate_dominator (CDI_DOMINATORS, e->dest) != dom)
VEC_safe_push (basic_block, heap, fix_dom_bb, e->dest);
delete_basic_block (bb1);
iterate_fix_dominators (CDI_DOMINATORS, fix_dom_bb, false);
#if defined (ENABLE_CHECKING)
verify_dominators (CDI_DOMINATORS);
#endif
VEC_free (basic_block, heap, fix_dom_bb);
}
/* Redirect all edges from BB1 to BB2, marks BB1 for removal, and if /* Redirect all edges from BB1 to BB2, marks BB1 for removal, and if
UPDATE_VOPS, inserts vop phis. */ UPDATE_VOPS, inserts vop phis. */
...@@ -1539,7 +1621,6 @@ replace_block_by (basic_block bb1, basic_block bb2, bool update_vops) ...@@ -1539,7 +1621,6 @@ replace_block_by (basic_block bb1, basic_block bb2, bool update_vops)
edge e; edge e;
edge_iterator ei; edge_iterator ei;
bool vuse1_phi_args = false; bool vuse1_phi_args = false;
VEC (basic_block,heap) *fix_dom_bb;
phi_vuse2 = vop_at_entry (bb2); phi_vuse2 = vop_at_entry (bb2);
if (phi_vuse2 != NULL_TREE && TREE_CODE (phi_vuse2) != SSA_NAME) if (phi_vuse2 != NULL_TREE && TREE_CODE (phi_vuse2) != SSA_NAME)
...@@ -1550,7 +1631,8 @@ replace_block_by (basic_block bb1, basic_block bb2, bool update_vops) ...@@ -1550,7 +1631,8 @@ replace_block_by (basic_block bb1, basic_block bb2, bool update_vops)
/* Find the vops at entry of bb1 and bb2. */ /* Find the vops at entry of bb1 and bb2. */
phi_vuse1 = vop_at_entry (bb1); phi_vuse1 = vop_at_entry (bb1);
/* If both are not found, it means there's no need to update. */ /* If both are not found, it means there's no need to update. Uses old
dominator info. */
if (phi_vuse1 == NULL_TREE && phi_vuse2 == NULL_TREE) if (phi_vuse1 == NULL_TREE && phi_vuse2 == NULL_TREE)
update_vops = false; update_vops = false;
else if (phi_vuse1 == NULL_TREE) else if (phi_vuse1 == NULL_TREE)
...@@ -1591,25 +1673,20 @@ replace_block_by (basic_block bb1, basic_block bb2, bool update_vops) ...@@ -1591,25 +1673,20 @@ replace_block_by (basic_block bb1, basic_block bb2, bool update_vops)
pred_edge, UNKNOWN_LOCATION); pred_edge, UNKNOWN_LOCATION);
} }
/* Update the vops. */ /* Do updates that use bb1, before deleting bb1. */
if (!update_vops)
release_last_vdef (bb1);
same_succ_flush_bb (bb1);
delete_block_update_dominator_info (bb1, bb2);
/* Update the vops. Uses new dominator info. */
if (update_vops) if (update_vops)
{ {
update_vuses (vuse1_phi_args, phi_vuse1, phi_vuse2, bb2, update_vuses (vuse1_phi_args, phi_vuse1, phi_vuse2, bb2,
redirected_edges); redirected_edges);
VEC_free (edge, heap, redirected_edges); VEC_free (edge, heap, redirected_edges);
} }
else
release_last_vdef (bb1);
same_succ_flush_bb (bb1);
delete_basic_block (bb1);
fix_dom_bb = VEC_alloc (basic_block, heap, 2);
VEC_safe_push (basic_block, heap, fix_dom_bb, bb2);
FOR_EACH_EDGE (e, ei, bb2->succs)
VEC_safe_push (basic_block, heap, fix_dom_bb, e->dest);
iterate_fix_dominators (CDI_DOMINATORS, fix_dom_bb, false);
VEC_free (basic_block, heap, fix_dom_bb);
} }
/* Bbs for which update_debug_stmt need to be called. */ /* Bbs for which update_debug_stmt need to be called. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment