Commit 44b6ab2b by Jeff Law Committed by Jeff Law

re PR tree-optimization/69347 (excessive compile time with -O2)

	PR middle-end/69347
	* tree-ssa-dom.c (back_propagate_equivalences): Factored out of
	record_temporary_equivalences.  Rewritten to avoid unnecessary calls
	into dominated_by_p.
	(cprop_into_successor_phis): Avoid unnecessary tests.

From-SVN: r232745
parent f7d2ad6f
2016-01-21 Jeff Law <law@redhat.com>
PR middle-end/69347
* tree-ssa-dom.c (back_propagate_equivalences): Factored out of
record_temporary_equivalences. Rewritten to avoid unnecessary calls
into dominated_by_p.
(cprop_into_successor_phis): Avoid unnecessary tests.
2016-01-22 Richard Henderson <rth@redhat.com>
PR target/69416
......
......@@ -819,6 +819,74 @@ dom_valueize (tree t)
return t;
}
/* We have just found an equivalence for LHS on an edge E.
Look backwards to other uses of LHS and see if we can derive
additional equivalences that are valid on edge E. */
static void
back_propagate_equivalences (tree lhs, edge e,
class const_and_copies *const_and_copies)
{
use_operand_p use_p;
imm_use_iterator iter;
bitmap domby = NULL;
basic_block dest = e->dest;
/* Iterate over the uses of LHS to see if any dominate E->dest.
If so, they may create useful equivalences too.
??? If the code gets re-organized to a worklist to catch more
indirect opportunities and it is made to handle PHIs then this
should only consider use_stmts in basic-blocks we have already visited. */
FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
{
gimple *use_stmt = USE_STMT (use_p);
/* Often the use is in DEST, which we trivially know we can't use.
This is cheaper than the dominator set tests below. */
if (dest == gimple_bb (use_stmt))
continue;
/* Filter out statements that can never produce a useful
equivalence. */
tree lhs2 = gimple_get_lhs (use_stmt);
if (!lhs2 || TREE_CODE (lhs2) != SSA_NAME)
continue;
/* Profiling has shown the domination tests here can be fairly
expensive. We get significant improvements by building the
set of blocks that dominate BB. We can then just test
for set membership below.
We also initialize the set lazily since often the only uses
are going to be in the same block as DEST. */
if (!domby)
{
domby = BITMAP_ALLOC (NULL);
basic_block bb = get_immediate_dominator (CDI_DOMINATORS, dest);
while (bb)
{
bitmap_set_bit (domby, bb->index);
bb = get_immediate_dominator (CDI_DOMINATORS, bb);
}
}
/* This tests if USE_STMT does not dominate DEST. */
if (!bitmap_bit_p (domby, gimple_bb (use_stmt)->index))
continue;
/* At this point USE_STMT dominates DEST and may result in a
useful equivalence. Try to simplify its RHS to a constant
or SSA_NAME. */
tree res = gimple_fold_stmt_to_constant_1 (use_stmt, dom_valueize,
no_follow_ssa_edges);
if (res && (TREE_CODE (res) == SSA_NAME || is_gimple_min_invariant (res)))
record_equality (lhs2, res, const_and_copies);
}
if (domby)
BITMAP_FREE (domby);
}
/* Record into CONST_AND_COPIES and AVAIL_EXPRS_STACK any equivalences implied
by traversing edge E (which are cached in E->aux).
......@@ -836,19 +904,23 @@ record_temporary_equivalences (edge e,
if (edge_info)
{
cond_equivalence *eq;
/* If we have 0 = COND or 1 = COND equivalences, record them
into our expression hash tables. */
for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i)
record_cond (eq, avail_exprs_stack);
tree lhs = edge_info->lhs;
tree rhs = edge_info->rhs;
if (!lhs || TREE_CODE (lhs) != SSA_NAME)
return;
/* If we have a simple NAME = VALUE equivalence, record it. */
if (lhs)
record_equality (lhs, rhs, const_and_copies);
/* Record the simple NAME = VALUE equivalence. */
tree rhs = edge_info->rhs;
record_equality (lhs, rhs, const_and_copies);
/* If LHS is an SSA_NAME and RHS is a constant integer and LHS was
set via a widening type conversion, then we may be able to record
additional equivalences. */
if (lhs
&& TREE_CODE (lhs) == SSA_NAME
&& TREE_CODE (rhs) == INTEGER_CST)
if (TREE_CODE (rhs) == INTEGER_CST)
{
gimple *defstmt = SSA_NAME_DEF_STMT (lhs);
......@@ -875,45 +947,10 @@ record_temporary_equivalences (edge e,
}
}
/* If LHS is an SSA_NAME with a new equivalency then try if
stmts with uses of that LHS that dominate the edge destination
simplify and allow further equivalences to be recorded. */
if (lhs && TREE_CODE (lhs) == SSA_NAME)
{
use_operand_p use_p;
imm_use_iterator iter;
FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
{
gimple *use_stmt = USE_STMT (use_p);
/* Only bother to record more equivalences for lhs that
can be directly used by e->dest.
??? If the code gets re-organized to a worklist to
catch more indirect opportunities and it is made to
handle PHIs then this should only consider use_stmts
in basic-blocks we have already visited. */
if (e->dest == gimple_bb (use_stmt)
|| !dominated_by_p (CDI_DOMINATORS,
e->dest, gimple_bb (use_stmt)))
continue;
tree lhs2 = gimple_get_lhs (use_stmt);
if (lhs2 && TREE_CODE (lhs2) == SSA_NAME)
{
tree res
= gimple_fold_stmt_to_constant_1 (use_stmt, dom_valueize,
no_follow_ssa_edges);
if (res
&& (TREE_CODE (res) == SSA_NAME
|| is_gimple_min_invariant (res)))
record_equality (lhs2, res, const_and_copies);
}
}
}
/* If we have 0 = COND or 1 = COND equivalences, record them
into our expression hash tables. */
for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i)
record_cond (eq, avail_exprs_stack);
/* Any equivalence found for LHS may result in additional
equivalences for other uses of LHS that we have already
processed. */
back_propagate_equivalences (lhs, e, const_and_copies);
}
}
......@@ -1321,8 +1358,6 @@ cprop_into_successor_phis (basic_block bb,
new_val = SSA_NAME_VALUE (orig_val);
if (new_val
&& new_val != orig_val
&& (TREE_CODE (new_val) == SSA_NAME
|| is_gimple_min_invariant (new_val))
&& may_propagate_copy (orig_val, new_val))
propagate_value (orig_p, new_val);
}
......
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