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:
parent
74b7ec8c45
commit
37d486ab11
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue