aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-07-24 08:25:41 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-07-24 08:25:41 +0000
commit37d486ab11c0d4f1e860b6dbc46e2e94bb8f0647 (patch)
tree762fcfff7fe872d4458ad5bab5afaf8c962e9a5b
parent74b7ec8c45c8db5df69e7a9894e6306e1d631a58 (diff)
downloadgcc-37d486ab11c0d4f1e860b6dbc46e2e94bb8f0647.zip
gcc-37d486ab11c0d4f1e860b6dbc46e2e94bb8f0647.tar.gz
gcc-37d486ab11c0d4f1e860b6dbc46e2e94bb8f0647.tar.bz2
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
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/gimple-fold.c13
-rw-r--r--gcc/gimple-match-head.c233
3 files changed, 104 insertions, 152 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 075c0fd..47f7237 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 2909c42..64f2791 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -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))
diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c
index 2c66dcc..ca7acdf 100644
--- a/gcc/gimple-match-head.c
+++ b/gcc/gimple-match-head.c
@@ -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: