From: Richard Biener Date: Fri, 24 Jul 2015 08:25:41 +0000 (+0000) Subject: gimple-fold.c (replace_stmt_with_simplification): Special-case valueizing call operands. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=37d486ab11c0d4f1e860b6dbc46e2e94bb8f0647;p=gcc.git gimple-fold.c (replace_stmt_with_simplification): Special-case valueizing call operands. 2015-07-24 Richard Biener * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 075c0fd4d96..47f7237d224 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-07-24 Richard Biener + + * 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 PR middle-end/25530 diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 2909c42ef19..64f27917e61 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 2c66dccb260..ca7acdfb4a4 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: