Right now we only bother forward propagating into COND_EXPRs since those
are relatively common cases where forward propagation creates valid
- gimple code without the expression needing to fold. ie
+ gimple code without the expression needing to fold. i.e.
bb0:
x = a COND b;
if (cond_code == SSA_NAME
|| ((cond_code == EQ_EXPR || cond_code == NE_EXPR)
&& TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
- && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (cond, 1))) == 'c'
+ && CONSTANT_CLASS_P (TREE_OPERAND (cond, 1))
&& INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))))
{
tree def;
/* The first operand must be an SSA_NAME and the second
operand must be a constant. */
if (TREE_CODE (op0) != SSA_NAME
- || TREE_CODE_CLASS (TREE_CODE (op1)) != 'c'
+ || !CONSTANT_CLASS_P (op1)
|| !INTEGRAL_TYPE_P (TREE_TYPE (op1)))
continue;
+
+ /* Don't propagate if the first operand occurs in
+ an abnormal PHI. */
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0))
+ continue;
}
/* These cases require comparisons of a naked SSA_NAME or
/* If TEST_VAR is set from a relational operation
between two SSA_NAMEs or a combination of an SSA_NAME
and a constant, then it is interesting. */
- if (TREE_CODE_CLASS (TREE_CODE (def_rhs)) == '<')
+ if (COMPARISON_CLASS_P (def_rhs))
{
tree op0 = TREE_OPERAND (def_rhs, 0);
tree op1 = TREE_OPERAND (def_rhs, 1);
|| (TREE_CODE (op1) != SSA_NAME
&& !is_gimple_min_invariant (op1)))
continue;
+
+ /* Don't propagate if the first operand occurs in
+ an abnormal PHI. */
+ if (TREE_CODE (op0) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0))
+ continue;
+
+ /* Don't propagate if the second operand occurs in
+ an abnormal PHI. */
+ if (TREE_CODE (op1) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op1))
+ continue;
}
/* If TEST_VAR is set from a TRUTH_NOT_EXPR, then it
if (TREE_CODE (def_rhs) != SSA_NAME
&& !is_gimple_min_invariant (def_rhs))
continue;
+
+ /* Don't propagate if the operand occurs in
+ an abnormal PHI. */
+ if (TREE_CODE (def_rhs) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def_rhs))
+ continue;
}
/* If TEST_VAR was set from a cast of an integer type
;
else
continue;
+
+ /* Don't propagate if the operand occurs in
+ an abnormal PHI. */
+ if (TREE_CODE (TREE_OPERAND (def_rhs, 0)) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND
+ (def_rhs, 0)))
+ continue;
}
else
continue;
new_cond = build (cond_code, boolean_type_node, op0, t);
}
/* If the variable is defined by a conditional expression... */
- else if (TREE_CODE_CLASS (def_rhs_code) == '<')
+ else if (TREE_CODE_CLASS (def_rhs_code) == tcc_comparison)
{
/* TEST_VAR was set from a relational operator. */
tree op0 = TREE_OPERAND (def_rhs, 0);
/* If we did not get a simple relational expression or
bare SSA_NAME, then we can not optimize this case. */
- if (TREE_CODE_CLASS (TREE_CODE (new_cond)) != '<'
+ if (!COMPARISON_CLASS_P (new_cond)
&& TREE_CODE (new_cond) != SSA_NAME)
continue;
}
{
bool invert = false;
enum tree_code new_code;
+ tree new_arg;
/* TEST_VAR was set from a TRUTH_NOT_EXPR or a NOP_EXPR. */
if (def_rhs_code == TRUTH_NOT_EXPR)
if (invert)
new_code = (new_code == EQ_EXPR ? NE_EXPR : EQ_EXPR);
- new_cond = build (new_code,
- boolean_type_node,
- TREE_OPERAND (def_rhs, 0),
- convert (TREE_TYPE (def_rhs),
- integer_zero_node));
+ new_arg = TREE_OPERAND (def_rhs, 0);
+ new_cond = build2 (new_code, boolean_type_node, new_arg,
+ fold_convert (TREE_TYPE (new_arg),
+ integer_zero_node));
}
/* Dump details. */
NULL, /* next */
0, /* static_pass_number */
TV_TREE_FORWPROP, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
+ PROP_cfg | PROP_ssa
+ | PROP_alias, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */
- | TODO_verify_ssa
+ | TODO_verify_ssa,
+ 0 /* letter */
};