diff options
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r-- | gcc/tree-ssa-ccp.c | 96 |
1 files changed, 58 insertions, 38 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 459894b24f0..673415c1ca0 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -939,15 +939,13 @@ ccp_fold (tree stmt) /* We may be able to fold away calls to builtin functions if their arguments are constants. */ else if (code == CALL_EXPR - && TREE_CODE (TREE_OPERAND (rhs, 0)) == ADDR_EXPR - && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0)) - == FUNCTION_DECL) - && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0))) + && TREE_CODE (CALL_EXPR_FN (rhs)) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (CALL_EXPR_FN (rhs), 0)) == FUNCTION_DECL + && DECL_BUILT_IN (TREE_OPERAND (CALL_EXPR_FN (rhs), 0))) { if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_USE)) { tree *orig, var; - tree fndecl, arglist; size_t i = 0; ssa_op_iter iter; use_operand_p var_p; @@ -959,9 +957,7 @@ ccp_fold (tree stmt) /* Substitute operands with their values and try to fold. */ replace_uses_in (stmt, NULL, const_val); - fndecl = get_callee_fndecl (rhs); - arglist = TREE_OPERAND (rhs, 1); - retval = fold_builtin (fndecl, arglist, false); + retval = fold_call_expr (rhs, false); /* Restore operands to their original form. */ i = 0; @@ -2219,18 +2215,18 @@ static tree ccp_fold_builtin (tree stmt, tree fn) { tree result, val[3]; - tree callee, arglist, a; + tree callee, a; int arg_mask, i, type; bitmap visited; bool ignore; + call_expr_arg_iterator iter; + int nargs; ignore = TREE_CODE (stmt) != GIMPLE_MODIFY_STMT; /* First try the generic builtin folder. If that succeeds, return the result directly. */ - callee = get_callee_fndecl (fn); - arglist = TREE_OPERAND (fn, 1); - result = fold_builtin (callee, arglist, ignore); + result = fold_call_expr (fn, ignore); if (result) { if (ignore) @@ -2239,12 +2235,14 @@ ccp_fold_builtin (tree stmt, tree fn) } /* Ignore MD builtins. */ + callee = get_callee_fndecl (fn); if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_MD) return NULL_TREE; /* If the builtin could not be folded, and it has no argument list, we're done. */ - if (!arglist) + nargs = call_expr_nargs (fn); + if (nargs == 0) return NULL_TREE; /* Limit the work only for builtins we know how to simplify. */ @@ -2287,15 +2285,17 @@ ccp_fold_builtin (tree stmt, tree fn) visited = BITMAP_ALLOC (NULL); memset (val, 0, sizeof (val)); - for (i = 0, a = arglist; - arg_mask; - i++, arg_mask >>= 1, a = TREE_CHAIN (a)) - if (arg_mask & 1) - { - bitmap_clear (visited); - if (!get_maxval_strlen (TREE_VALUE (a), &val[i], visited, type)) - val[i] = NULL_TREE; - } + init_call_expr_arg_iterator (fn, &iter); + for (i = 0; arg_mask; i++, arg_mask >>= 1) + { + a = next_call_expr_arg (&iter); + if (arg_mask & 1) + { + bitmap_clear (visited); + if (!get_maxval_strlen (a, &val[i], visited, type)) + val[i] = NULL_TREE; + } + } BITMAP_FREE (visited); @@ -2317,23 +2317,32 @@ ccp_fold_builtin (tree stmt, tree fn) break; case BUILT_IN_STRCPY: - if (val[1] && is_gimple_val (val[1])) - result = fold_builtin_strcpy (callee, arglist, val[1]); + if (val[1] && is_gimple_val (val[1]) && nargs == 2) + result = fold_builtin_strcpy (callee, + CALL_EXPR_ARG (fn, 0), + CALL_EXPR_ARG (fn, 1), + val[1]); break; case BUILT_IN_STRNCPY: - if (val[1] && is_gimple_val (val[1])) - result = fold_builtin_strncpy (callee, arglist, val[1]); + if (val[1] && is_gimple_val (val[1]) && nargs == 3) + result = fold_builtin_strncpy (callee, + CALL_EXPR_ARG (fn, 0), + CALL_EXPR_ARG (fn, 1), + CALL_EXPR_ARG (fn, 2), + val[1]); break; case BUILT_IN_FPUTS: - result = fold_builtin_fputs (arglist, + result = fold_builtin_fputs (CALL_EXPR_ARG (fn, 0), + CALL_EXPR_ARG (fn, 1), TREE_CODE (stmt) != GIMPLE_MODIFY_STMT, 0, val[0]); break; case BUILT_IN_FPUTS_UNLOCKED: - result = fold_builtin_fputs (arglist, + result = fold_builtin_fputs (CALL_EXPR_ARG (fn, 0), + CALL_EXPR_ARG (fn, 1), TREE_CODE (stmt) != GIMPLE_MODIFY_STMT, 1, val[0]); break; @@ -2343,26 +2352,39 @@ ccp_fold_builtin (tree stmt, tree fn) case BUILT_IN_MEMMOVE_CHK: case BUILT_IN_MEMSET_CHK: if (val[2] && is_gimple_val (val[2])) - result = fold_builtin_memory_chk (callee, arglist, val[2], ignore, + result = fold_builtin_memory_chk (callee, + CALL_EXPR_ARG (fn, 0), + CALL_EXPR_ARG (fn, 1), + CALL_EXPR_ARG (fn, 2), + CALL_EXPR_ARG (fn, 3), + val[2], ignore, DECL_FUNCTION_CODE (callee)); break; case BUILT_IN_STRCPY_CHK: case BUILT_IN_STPCPY_CHK: if (val[1] && is_gimple_val (val[1])) - result = fold_builtin_stxcpy_chk (callee, arglist, val[1], ignore, + result = fold_builtin_stxcpy_chk (callee, + CALL_EXPR_ARG (fn, 0), + CALL_EXPR_ARG (fn, 1), + CALL_EXPR_ARG (fn, 2), + val[1], ignore, DECL_FUNCTION_CODE (callee)); break; case BUILT_IN_STRNCPY_CHK: if (val[2] && is_gimple_val (val[2])) - result = fold_builtin_strncpy_chk (arglist, val[2]); + result = fold_builtin_strncpy_chk (CALL_EXPR_ARG (fn, 0), + CALL_EXPR_ARG (fn, 1), + CALL_EXPR_ARG (fn, 2), + CALL_EXPR_ARG (fn, 3), + val[2]); break; case BUILT_IN_SNPRINTF_CHK: case BUILT_IN_VSNPRINTF_CHK: if (val[1] && is_gimple_val (val[1])) - result = fold_builtin_snprintf_chk (arglist, val[1], + result = fold_builtin_snprintf_chk (fn, val[1], DECL_FUNCTION_CODE (callee)); break; @@ -2398,9 +2420,7 @@ fold_stmt (tree *stmt_p) then we may need to fold instances of *&VAR into VAR, etc. */ if (walk_tree (stmt_p, fold_stmt_r, &fold_stmt_r_data, NULL)) { - *stmt_p - = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP], - NULL); + *stmt_p = build_call_expr (implicit_built_in_decls[BUILT_IN_TRAP], 0); return true; } @@ -2428,8 +2448,8 @@ fold_stmt (tree *stmt_p) copying EH region info to the new node. Easier to just do it here where we can just smash the call operand. Also CALL_EXPR_RETURN_SLOT_OPT needs to be handled correctly and - copied, fold_ternary does not have not information. */ - callee = TREE_OPERAND (rhs, 0); + copied, fold_call_expr does not have not information. */ + callee = CALL_EXPR_FN (rhs); if (TREE_CODE (callee) == OBJ_TYPE_REF && lang_hooks.fold_obj_type_ref && TREE_CODE (OBJ_TYPE_REF_OBJECT (callee)) == ADDR_EXPR @@ -2447,7 +2467,7 @@ fold_stmt (tree *stmt_p) t = lang_hooks.fold_obj_type_ref (callee, t); if (t) { - TREE_OPERAND (rhs, 0) = t; + CALL_EXPR_FN (rhs) = t; changed = true; } } |