Commit 37d486ab by Richard Biener Committed by Richard Biener

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
parent 74b7ec8c
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> 2015-07-24 Naveen H.S <Naveen.Hurugalawadi@caviumnetworks.com>
PR middle-end/25530 PR middle-end/25530
......
...@@ -3398,6 +3398,19 @@ replace_stmt_with_simplification (gimple_stmt_iterator *gsi, ...@@ -3398,6 +3398,19 @@ replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
return true; 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) else if (!inplace)
{ {
if (gimple_has_lhs (stmt)) if (gimple_has_lhs (stmt))
......
...@@ -338,19 +338,18 @@ maybe_push_res_to_seq (code_helper rcode, tree type, tree *ops, ...@@ -338,19 +338,18 @@ maybe_push_res_to_seq (code_helper rcode, tree type, tree *ops,
tree decl = builtin_decl_implicit (rcode); tree decl = builtin_decl_implicit (rcode);
if (!decl) if (!decl)
return NULL_TREE; 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 /* Play safe and do not allow abnormals to be mentioned in
newly created statements. */ newly created statements. */
if ((TREE_CODE (ops[0]) == SSA_NAME unsigned nargs;
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0])) for (nargs = 0; nargs < 3; ++nargs)
|| (nargs >= 2 {
&& TREE_CODE (ops[1]) == SSA_NAME if (!ops[nargs])
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1])) break;
|| (nargs == 3 if (TREE_CODE (ops[nargs]) == SSA_NAME
&& TREE_CODE (ops[2]) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[nargs]))
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2]))) return NULL_TREE;
return NULL_TREE; }
gcc_assert (nargs != 0);
if (!res) if (!res)
res = make_ssa_name (type); res = make_ssa_name (type);
gimple new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1], ops[2]); 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, ...@@ -563,6 +562,23 @@ gimple_simplify (enum built_in_function fn, tree type,
return maybe_push_res_to_seq (rcode, type, ops, seq); 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 /* The main STMT based simplification entry. It is used by the fold_stmt
and the fold_stmt_to_constant APIs. */ and the fold_stmt_to_constant APIs. */
...@@ -587,31 +603,25 @@ gimple_simplify (gimple stmt, ...@@ -587,31 +603,25 @@ gimple_simplify (gimple stmt,
|| code == VIEW_CONVERT_EXPR) || code == VIEW_CONVERT_EXPR)
{ {
tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0); tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
if (top_valueize && TREE_CODE (op0) == SSA_NAME) bool valueized = false;
{ op0 = do_valueize (op0, top_valueize, valueized);
tree tem = top_valueize (op0);
if (tem)
op0 = tem;
}
*rcode = code; *rcode = code;
ops[0] = op0; 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) else if (code == BIT_FIELD_REF)
{ {
tree rhs1 = gimple_assign_rhs1 (stmt); tree rhs1 = gimple_assign_rhs1 (stmt);
tree op0 = TREE_OPERAND (rhs1, 0); tree op0 = TREE_OPERAND (rhs1, 0);
if (top_valueize && TREE_CODE (op0) == SSA_NAME) bool valueized = false;
{ op0 = do_valueize (op0, top_valueize, valueized);
tree tem = top_valueize (op0);
if (tem)
op0 = tem;
}
*rcode = code; *rcode = code;
ops[0] = op0; ops[0] = op0;
ops[1] = TREE_OPERAND (rhs1, 1); ops[1] = TREE_OPERAND (rhs1, 1);
ops[2] = TREE_OPERAND (rhs1, 2); 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 else if (code == SSA_NAME
&& top_valueize) && top_valueize)
...@@ -628,65 +638,41 @@ gimple_simplify (gimple stmt, ...@@ -628,65 +638,41 @@ gimple_simplify (gimple stmt,
case GIMPLE_UNARY_RHS: case GIMPLE_UNARY_RHS:
{ {
tree rhs1 = gimple_assign_rhs1 (stmt); tree rhs1 = gimple_assign_rhs1 (stmt);
if (top_valueize && TREE_CODE (rhs1) == SSA_NAME) bool valueized = false;
{ rhs1 = do_valueize (rhs1, top_valueize, valueized);
tree tem = top_valueize (rhs1);
if (tem)
rhs1 = tem;
}
*rcode = code; *rcode = code;
ops[0] = rhs1; ops[0] = rhs1;
return gimple_resimplify1 (seq, rcode, type, ops, valueize); return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
|| valueized);
} }
case GIMPLE_BINARY_RHS: case GIMPLE_BINARY_RHS:
{ {
tree rhs1 = gimple_assign_rhs1 (stmt); 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); tree rhs2 = gimple_assign_rhs2 (stmt);
if (top_valueize && TREE_CODE (rhs2) == SSA_NAME) bool valueized = false;
{ rhs1 = do_valueize (rhs1, top_valueize, valueized);
tree tem = top_valueize (rhs2); rhs2 = do_valueize (rhs2, top_valueize, valueized);
if (tem)
rhs2 = tem;
}
*rcode = code; *rcode = code;
ops[0] = rhs1; ops[0] = rhs1;
ops[1] = rhs2; ops[1] = rhs2;
return gimple_resimplify2 (seq, rcode, type, ops, valueize); return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
|| valueized);
} }
case GIMPLE_TERNARY_RHS: case GIMPLE_TERNARY_RHS:
{ {
tree rhs1 = gimple_assign_rhs1 (stmt); 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); 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); tree rhs3 = gimple_assign_rhs3 (stmt);
if (top_valueize && TREE_CODE (rhs3) == SSA_NAME) bool valueized = false;
{ rhs1 = do_valueize (rhs1, top_valueize, valueized);
tree tem = top_valueize (rhs3); rhs2 = do_valueize (rhs2, top_valueize, valueized);
if (tem) rhs3 = do_valueize (rhs3, top_valueize, valueized);
rhs3 = tem;
}
*rcode = code; *rcode = code;
ops[0] = rhs1; ops[0] = rhs1;
ops[1] = rhs2; ops[1] = rhs2;
ops[2] = rhs3; ops[2] = rhs3;
return gimple_resimplify3 (seq, rcode, type, ops, valueize); return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
|| valueized);
} }
default: default:
gcc_unreachable (); gcc_unreachable ();
...@@ -696,96 +682,46 @@ gimple_simplify (gimple stmt, ...@@ -696,96 +682,46 @@ gimple_simplify (gimple stmt,
case GIMPLE_CALL: case GIMPLE_CALL:
/* ??? This way we can't simplify calls with side-effects. */ /* ??? 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); tree fn = gimple_call_fn (stmt);
/* ??? Internal function support missing. */ /* ??? Internal function support missing. */
if (!fn) if (!fn)
return false; return false;
if (top_valueize && TREE_CODE (fn) == SSA_NAME) bool valueized = false;
{ fn = do_valueize (fn, top_valueize, valueized);
tree tem = top_valueize (fn); if (TREE_CODE (fn) != ADDR_EXPR
if (tem) || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
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)))
return false; return false;
tree decl = TREE_OPERAND (fn, 0); 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)); 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)) switch (gimple_call_num_args (stmt))
{ {
case 1: case 1:
{ return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
tree arg1 = gimple_call_arg (stmt, 0); || valueized);
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);
}
case 2: case 2:
{ return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
tree arg1 = gimple_call_arg (stmt, 0); || valueized);
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);
}
case 3: case 3:
{ return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
tree arg1 = gimple_call_arg (stmt, 0); || valueized);
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);
}
default: default:
return false; gcc_unreachable ();
} }
} }
break; break;
...@@ -793,23 +729,16 @@ gimple_simplify (gimple stmt, ...@@ -793,23 +729,16 @@ gimple_simplify (gimple stmt,
case GIMPLE_COND: case GIMPLE_COND:
{ {
tree lhs = gimple_cond_lhs (stmt); 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); tree rhs = gimple_cond_rhs (stmt);
if (top_valueize && TREE_CODE (rhs) == SSA_NAME) bool valueized = false;
{ lhs = do_valueize (lhs, top_valueize, valueized);
tree tem = top_valueize (rhs); rhs = do_valueize (rhs, top_valueize, valueized);
if (tem)
rhs = tem;
}
*rcode = gimple_cond_code (stmt); *rcode = gimple_cond_code (stmt);
ops[0] = lhs; ops[0] = lhs;
ops[1] = rhs; 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: default:
......
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