gimple-fold.c (replace_stmt_with_simplification): Special-case valueizing call operands.

2015-07-24  Richard Biener  <rguenther@suse.de>

	* gimple-fold.c (replace_stmt_with_simplification): Special-case
	valueizing call operands.
	* gimple-match-head.c (maybe_push_res_to_seq): Take
	number of call arguments from ops array.
	(do_valueize): New function.
	(gimple_simplify): Return true if valueization changed
	any operand even if the result didn't simplify further.

From-SVN: r226139
This commit is contained in:
Richard Biener 2015-07-24 08:25:41 +00:00 committed by Richard Biener
parent 74b7ec8c45
commit 37d486ab11
3 changed files with 104 additions and 152 deletions

View File

@ -1,3 +1,13 @@
2015-07-24 Richard Biener <rguenther@suse.de>
* gimple-fold.c (replace_stmt_with_simplification): Special-case
valueizing call operands.
* gimple-match-head.c (maybe_push_res_to_seq): Take
number of call arguments from ops array.
(do_valueize): New function.
(gimple_simplify): Return true if valueization changed
any operand even if the result didn't simplify further.
2015-07-24 Naveen H.S <Naveen.Hurugalawadi@caviumnetworks.com>
PR middle-end/25530

View File

@ -3398,6 +3398,19 @@ replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
return true;
}
}
else if (rcode.is_fn_code ()
&& gimple_call_builtin_p (stmt, rcode))
{
unsigned i;
for (i = 0; i < gimple_call_num_args (stmt); ++i)
{
gcc_assert (ops[i] != NULL_TREE);
gimple_call_set_arg (stmt, i, ops[i]);
}
if (i < 3)
gcc_assert (ops[i] == NULL_TREE);
return true;
}
else if (!inplace)
{
if (gimple_has_lhs (stmt))

View File

@ -338,19 +338,18 @@ maybe_push_res_to_seq (code_helper rcode, tree type, tree *ops,
tree decl = builtin_decl_implicit (rcode);
if (!decl)
return NULL_TREE;
unsigned nargs = type_num_arguments (TREE_TYPE (decl));
gcc_assert (nargs <= 3);
/* Play safe and do not allow abnormals to be mentioned in
newly created statements. */
if ((TREE_CODE (ops[0]) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
|| (nargs >= 2
&& TREE_CODE (ops[1]) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
|| (nargs == 3
&& TREE_CODE (ops[2]) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
return NULL_TREE;
unsigned nargs;
for (nargs = 0; nargs < 3; ++nargs)
{
if (!ops[nargs])
break;
if (TREE_CODE (ops[nargs]) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[nargs]))
return NULL_TREE;
}
gcc_assert (nargs != 0);
if (!res)
res = make_ssa_name (type);
gimple new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1], ops[2]);
@ -563,6 +562,23 @@ gimple_simplify (enum built_in_function fn, tree type,
return maybe_push_res_to_seq (rcode, type, ops, seq);
}
/* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
VALUEIZED to true if valueization changed OP. */
static inline tree
do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
{
if (valueize && TREE_CODE (op) == SSA_NAME)
{
tree tem = valueize (op);
if (tem && tem != op)
{
op = tem;
valueized = true;
}
}
return op;
}
/* The main STMT based simplification entry. It is used by the fold_stmt
and the fold_stmt_to_constant APIs. */
@ -587,31 +603,25 @@ gimple_simplify (gimple stmt,
|| code == VIEW_CONVERT_EXPR)
{
tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
if (top_valueize && TREE_CODE (op0) == SSA_NAME)
{
tree tem = top_valueize (op0);
if (tem)
op0 = tem;
}
bool valueized = false;
op0 = do_valueize (op0, top_valueize, valueized);
*rcode = code;
ops[0] = op0;
return gimple_resimplify1 (seq, rcode, type, ops, valueize);
return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
|| valueized);
}
else if (code == BIT_FIELD_REF)
{
tree rhs1 = gimple_assign_rhs1 (stmt);
tree op0 = TREE_OPERAND (rhs1, 0);
if (top_valueize && TREE_CODE (op0) == SSA_NAME)
{
tree tem = top_valueize (op0);
if (tem)
op0 = tem;
}
bool valueized = false;
op0 = do_valueize (op0, top_valueize, valueized);
*rcode = code;
ops[0] = op0;
ops[1] = TREE_OPERAND (rhs1, 1);
ops[2] = TREE_OPERAND (rhs1, 2);
return gimple_resimplify3 (seq, rcode, type, ops, valueize);
return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
|| valueized);
}
else if (code == SSA_NAME
&& top_valueize)
@ -628,65 +638,41 @@ gimple_simplify (gimple stmt,
case GIMPLE_UNARY_RHS:
{
tree rhs1 = gimple_assign_rhs1 (stmt);
if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
{
tree tem = top_valueize (rhs1);
if (tem)
rhs1 = tem;
}
bool valueized = false;
rhs1 = do_valueize (rhs1, top_valueize, valueized);
*rcode = code;
ops[0] = rhs1;
return gimple_resimplify1 (seq, rcode, type, ops, valueize);
return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
|| valueized);
}
case GIMPLE_BINARY_RHS:
{
tree rhs1 = gimple_assign_rhs1 (stmt);
if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
{
tree tem = top_valueize (rhs1);
if (tem)
rhs1 = tem;
}
tree rhs2 = gimple_assign_rhs2 (stmt);
if (top_valueize && TREE_CODE (rhs2) == SSA_NAME)
{
tree tem = top_valueize (rhs2);
if (tem)
rhs2 = tem;
}
bool valueized = false;
rhs1 = do_valueize (rhs1, top_valueize, valueized);
rhs2 = do_valueize (rhs2, top_valueize, valueized);
*rcode = code;
ops[0] = rhs1;
ops[1] = rhs2;
return gimple_resimplify2 (seq, rcode, type, ops, valueize);
return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
|| valueized);
}
case GIMPLE_TERNARY_RHS:
{
tree rhs1 = gimple_assign_rhs1 (stmt);
if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
{
tree tem = top_valueize (rhs1);
if (tem)
rhs1 = tem;
}
tree rhs2 = gimple_assign_rhs2 (stmt);
if (top_valueize && TREE_CODE (rhs2) == SSA_NAME)
{
tree tem = top_valueize (rhs2);
if (tem)
rhs2 = tem;
}
tree rhs3 = gimple_assign_rhs3 (stmt);
if (top_valueize && TREE_CODE (rhs3) == SSA_NAME)
{
tree tem = top_valueize (rhs3);
if (tem)
rhs3 = tem;
}
bool valueized = false;
rhs1 = do_valueize (rhs1, top_valueize, valueized);
rhs2 = do_valueize (rhs2, top_valueize, valueized);
rhs3 = do_valueize (rhs3, top_valueize, valueized);
*rcode = code;
ops[0] = rhs1;
ops[1] = rhs2;
ops[2] = rhs3;
return gimple_resimplify3 (seq, rcode, type, ops, valueize);
return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
|| valueized);
}
default:
gcc_unreachable ();
@ -696,96 +682,46 @@ gimple_simplify (gimple stmt,
case GIMPLE_CALL:
/* ??? This way we can't simplify calls with side-effects. */
if (gimple_call_lhs (stmt) != NULL_TREE)
if (gimple_call_lhs (stmt) != NULL_TREE
&& gimple_call_num_args (stmt) >= 1
&& gimple_call_num_args (stmt) <= 3)
{
tree fn = gimple_call_fn (stmt);
/* ??? Internal function support missing. */
if (!fn)
return false;
if (top_valueize && TREE_CODE (fn) == SSA_NAME)
{
tree tem = top_valueize (fn);
if (tem)
fn = tem;
}
if (!fn
|| TREE_CODE (fn) != ADDR_EXPR
|| TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL
|| DECL_BUILT_IN_CLASS (TREE_OPERAND (fn, 0)) != BUILT_IN_NORMAL
|| !builtin_decl_implicit (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0)))
|| !gimple_builtin_call_types_compatible_p (stmt,
TREE_OPERAND (fn, 0)))
bool valueized = false;
fn = do_valueize (fn, top_valueize, valueized);
if (TREE_CODE (fn) != ADDR_EXPR
|| TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
return false;
tree decl = TREE_OPERAND (fn, 0);
if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL
|| !builtin_decl_implicit (DECL_FUNCTION_CODE (decl))
|| !gimple_builtin_call_types_compatible_p (stmt, decl))
return false;
tree type = TREE_TYPE (gimple_call_lhs (stmt));
*rcode = DECL_FUNCTION_CODE (decl);
for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
{
tree arg = gimple_call_arg (stmt, i);
ops[i] = do_valueize (arg, top_valueize, valueized);
}
switch (gimple_call_num_args (stmt))
{
case 1:
{
tree arg1 = gimple_call_arg (stmt, 0);
if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
{
tree tem = top_valueize (arg1);
if (tem)
arg1 = tem;
}
*rcode = DECL_FUNCTION_CODE (decl);
ops[0] = arg1;
return gimple_resimplify1 (seq, rcode, type, ops, valueize);
}
return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
|| valueized);
case 2:
{
tree arg1 = gimple_call_arg (stmt, 0);
if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
{
tree tem = top_valueize (arg1);
if (tem)
arg1 = tem;
}
tree arg2 = gimple_call_arg (stmt, 1);
if (top_valueize && TREE_CODE (arg2) == SSA_NAME)
{
tree tem = top_valueize (arg2);
if (tem)
arg2 = tem;
}
*rcode = DECL_FUNCTION_CODE (decl);
ops[0] = arg1;
ops[1] = arg2;
return gimple_resimplify2 (seq, rcode, type, ops, valueize);
}
return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
|| valueized);
case 3:
{
tree arg1 = gimple_call_arg (stmt, 0);
if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
{
tree tem = top_valueize (arg1);
if (tem)
arg1 = tem;
}
tree arg2 = gimple_call_arg (stmt, 1);
if (top_valueize && TREE_CODE (arg2) == SSA_NAME)
{
tree tem = top_valueize (arg2);
if (tem)
arg2 = tem;
}
tree arg3 = gimple_call_arg (stmt, 2);
if (top_valueize && TREE_CODE (arg3) == SSA_NAME)
{
tree tem = top_valueize (arg3);
if (tem)
arg3 = tem;
}
*rcode = DECL_FUNCTION_CODE (decl);
ops[0] = arg1;
ops[1] = arg2;
ops[2] = arg3;
return gimple_resimplify3 (seq, rcode, type, ops, valueize);
}
return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
|| valueized);
default:
return false;
gcc_unreachable ();
}
}
break;
@ -793,23 +729,16 @@ gimple_simplify (gimple stmt,
case GIMPLE_COND:
{
tree lhs = gimple_cond_lhs (stmt);
if (top_valueize && TREE_CODE (lhs) == SSA_NAME)
{
tree tem = top_valueize (lhs);
if (tem)
lhs = tem;
}
tree rhs = gimple_cond_rhs (stmt);
if (top_valueize && TREE_CODE (rhs) == SSA_NAME)
{
tree tem = top_valueize (rhs);
if (tem)
rhs = tem;
}
bool valueized = false;
lhs = do_valueize (lhs, top_valueize, valueized);
rhs = do_valueize (rhs, top_valueize, valueized);
*rcode = gimple_cond_code (stmt);
ops[0] = lhs;
ops[1] = rhs;
return gimple_resimplify2 (seq, rcode, boolean_type_node, ops, valueize);
return (gimple_resimplify2 (seq, rcode,
boolean_type_node, ops, valueize)
|| valueized);
}
default: