mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
Remove recursion in simplify_control_stmt_condition_1 [PR114855].
Remove some ad-hoc simplification code in the forward threader, as the call into the ranger in m_simplifier->simplify() will handle anything we can do manually in simplify_control_stmt_condition_1. In PR114855, DOM time is reduced from 120s to 92s (-23%) and overall compilation time from 235s to 205s (-12%). The total thread count at -O1 is unchanged for the testcase. In our bootstrap .ii benchmark suite, I see we thread 3 threads less over all files at -O1. At -O2, the backward threader picks up one more, for no difference over all. PR tree-optimization/114855 gcc/ChangeLog: * tree-ssa-threadedge.cc: Remove unneeded recursion.
This commit is contained in:
parent
63a598deb0
commit
9b76263838
@ -496,124 +496,6 @@ jump_threader::simplify_control_stmt_condition_1
|
||||
std::swap (op0, op1);
|
||||
}
|
||||
|
||||
/* If the condition has the form (A & B) CMP 0 or (A | B) CMP 0 then
|
||||
recurse into the LHS to see if there is a simplification that
|
||||
makes this condition always true or always false along the edge
|
||||
E. */
|
||||
if ((cond_code == EQ_EXPR || cond_code == NE_EXPR)
|
||||
&& TREE_CODE (op0) == SSA_NAME
|
||||
&& integer_zerop (op1))
|
||||
{
|
||||
gimple *def_stmt = SSA_NAME_DEF_STMT (op0);
|
||||
if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
|
||||
;
|
||||
else if (gimple_assign_rhs_code (def_stmt) == BIT_AND_EXPR
|
||||
|| gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR)
|
||||
{
|
||||
enum tree_code rhs_code = gimple_assign_rhs_code (def_stmt);
|
||||
const tree rhs1 = gimple_assign_rhs1 (def_stmt);
|
||||
const tree rhs2 = gimple_assign_rhs2 (def_stmt);
|
||||
|
||||
/* Is A != 0 ? */
|
||||
const tree res1
|
||||
= simplify_control_stmt_condition_1 (e, def_stmt,
|
||||
rhs1, NE_EXPR, op1,
|
||||
limit - 1);
|
||||
if (res1 == NULL_TREE)
|
||||
;
|
||||
else if (rhs_code == BIT_AND_EXPR && integer_zerop (res1))
|
||||
{
|
||||
/* If A == 0 then (A & B) != 0 is always false. */
|
||||
if (cond_code == NE_EXPR)
|
||||
return boolean_false_node;
|
||||
/* If A == 0 then (A & B) == 0 is always true. */
|
||||
if (cond_code == EQ_EXPR)
|
||||
return boolean_true_node;
|
||||
}
|
||||
else if (rhs_code == BIT_IOR_EXPR && integer_nonzerop (res1))
|
||||
{
|
||||
/* If A != 0 then (A | B) != 0 is always true. */
|
||||
if (cond_code == NE_EXPR)
|
||||
return boolean_true_node;
|
||||
/* If A != 0 then (A | B) == 0 is always false. */
|
||||
if (cond_code == EQ_EXPR)
|
||||
return boolean_false_node;
|
||||
}
|
||||
|
||||
/* Is B != 0 ? */
|
||||
const tree res2
|
||||
= simplify_control_stmt_condition_1 (e, def_stmt,
|
||||
rhs2, NE_EXPR, op1,
|
||||
limit - 1);
|
||||
if (res2 == NULL_TREE)
|
||||
;
|
||||
else if (rhs_code == BIT_AND_EXPR && integer_zerop (res2))
|
||||
{
|
||||
/* If B == 0 then (A & B) != 0 is always false. */
|
||||
if (cond_code == NE_EXPR)
|
||||
return boolean_false_node;
|
||||
/* If B == 0 then (A & B) == 0 is always true. */
|
||||
if (cond_code == EQ_EXPR)
|
||||
return boolean_true_node;
|
||||
}
|
||||
else if (rhs_code == BIT_IOR_EXPR && integer_nonzerop (res2))
|
||||
{
|
||||
/* If B != 0 then (A | B) != 0 is always true. */
|
||||
if (cond_code == NE_EXPR)
|
||||
return boolean_true_node;
|
||||
/* If B != 0 then (A | B) == 0 is always false. */
|
||||
if (cond_code == EQ_EXPR)
|
||||
return boolean_false_node;
|
||||
}
|
||||
|
||||
if (res1 != NULL_TREE && res2 != NULL_TREE)
|
||||
{
|
||||
if (rhs_code == BIT_AND_EXPR
|
||||
&& TYPE_PRECISION (TREE_TYPE (op0)) == 1
|
||||
&& integer_nonzerop (res1)
|
||||
&& integer_nonzerop (res2))
|
||||
{
|
||||
/* If A != 0 and B != 0 then (bool)(A & B) != 0 is true. */
|
||||
if (cond_code == NE_EXPR)
|
||||
return boolean_true_node;
|
||||
/* If A != 0 and B != 0 then (bool)(A & B) == 0 is false. */
|
||||
if (cond_code == EQ_EXPR)
|
||||
return boolean_false_node;
|
||||
}
|
||||
|
||||
if (rhs_code == BIT_IOR_EXPR
|
||||
&& integer_zerop (res1)
|
||||
&& integer_zerop (res2))
|
||||
{
|
||||
/* If A == 0 and B == 0 then (A | B) != 0 is false. */
|
||||
if (cond_code == NE_EXPR)
|
||||
return boolean_false_node;
|
||||
/* If A == 0 and B == 0 then (A | B) == 0 is true. */
|
||||
if (cond_code == EQ_EXPR)
|
||||
return boolean_true_node;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Handle (A CMP B) CMP 0. */
|
||||
else if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))
|
||||
== tcc_comparison)
|
||||
{
|
||||
tree rhs1 = gimple_assign_rhs1 (def_stmt);
|
||||
tree rhs2 = gimple_assign_rhs2 (def_stmt);
|
||||
|
||||
tree_code new_cond = gimple_assign_rhs_code (def_stmt);
|
||||
if (cond_code == EQ_EXPR)
|
||||
new_cond = invert_tree_comparison (new_cond, false);
|
||||
|
||||
tree res
|
||||
= simplify_control_stmt_condition_1 (e, def_stmt,
|
||||
rhs1, new_cond, rhs2,
|
||||
limit - 1);
|
||||
if (res != NULL_TREE && is_gimple_min_invariant (res))
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
gimple_cond_set_code (dummy_cond, cond_code);
|
||||
gimple_cond_set_lhs (dummy_cond, op0);
|
||||
gimple_cond_set_rhs (dummy_cond, op1);
|
||||
|
Loading…
Reference in New Issue
Block a user