diff options
author | Jakub Jelinek <jakub@redhat.com> | 2011-06-27 18:52:23 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-06-27 18:52:23 +0200 |
commit | 45d439ac1a9e2df33ac7ef573009749dbebf581b (patch) | |
tree | efa39246412ef14d5214fe10b53a962abeab3d20 /gcc/tree-ssa-ccp.c | |
parent | dc2a58daabf95cfac0dd346ff717902bdc6e3d93 (diff) | |
download | gcc-45d439ac1a9e2df33ac7ef573009749dbebf581b.zip gcc-45d439ac1a9e2df33ac7ef573009749dbebf581b.tar.gz gcc-45d439ac1a9e2df33ac7ef573009749dbebf581b.tar.bz2 |
builtin-types.def (BT_FN_PTR_CONST_PTR_SIZE_VAR): New.
* builtin-types.def (BT_FN_PTR_CONST_PTR_SIZE_VAR): New.
* builtins.def (BUILT_IN_ASSUME_ALIGNED): New builtin.
* tree-ssa-structalias.c (find_func_aliases_for_builtin_call,
find_func_clobbers): Handle BUILT_IN_ASSUME_ALIGNED.
* tree-ssa-ccp.c (bit_value_assume_aligned): New function.
(evaluate_stmt, execute_fold_all_builtins): Handle
BUILT_IN_ASSUME_ALIGNED.
* tree-ssa-dce.c (propagate_necessity): Likewise.
* tree-ssa-alias.c (ref_maybe_used_by_call_p_1,
call_may_clobber_ref_p_1): Likewise.
* builtins.c (is_simple_builtin, expand_builtin): Likewise.
(expand_builtin_assume_aligned): New function.
* doc/extend.texi (__builtin_assume_aligned): Document.
* c-common.c (check_builtin_function_arguments): Handle
BUILT_IN_ASSUME_ALIGNED.
* gcc.dg/builtin-assume-aligned-1.c: New test.
* gcc.dg/builtin-assume-aligned-2.c: New test.
* gcc.target/i386/builtin-assume-aligned-1.c: New test.
From-SVN: r175541
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r-- | gcc/tree-ssa-ccp.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index fd95abb..78724de 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1476,6 +1476,64 @@ bit_value_binop (enum tree_code code, tree type, tree rhs1, tree rhs2) return val; } +/* Return the propagation value when applying __builtin_assume_aligned to + its arguments. */ + +static prop_value_t +bit_value_assume_aligned (gimple stmt) +{ + tree ptr = gimple_call_arg (stmt, 0), align, misalign = NULL_TREE; + tree type = TREE_TYPE (ptr); + unsigned HOST_WIDE_INT aligni, misaligni = 0; + prop_value_t ptrval = get_value_for_expr (ptr, true); + prop_value_t alignval; + double_int value, mask; + prop_value_t val; + if (ptrval.lattice_val == UNDEFINED) + return ptrval; + gcc_assert ((ptrval.lattice_val == CONSTANT + && TREE_CODE (ptrval.value) == INTEGER_CST) + || double_int_minus_one_p (ptrval.mask)); + align = gimple_call_arg (stmt, 1); + if (!host_integerp (align, 1)) + return ptrval; + aligni = tree_low_cst (align, 1); + if (aligni <= 1 + || (aligni & (aligni - 1)) != 0) + return ptrval; + if (gimple_call_num_args (stmt) > 2) + { + misalign = gimple_call_arg (stmt, 2); + if (!host_integerp (misalign, 1)) + return ptrval; + misaligni = tree_low_cst (misalign, 1); + if (misaligni >= aligni) + return ptrval; + } + align = build_int_cst_type (type, -aligni); + alignval = get_value_for_expr (align, true); + bit_value_binop_1 (BIT_AND_EXPR, type, &value, &mask, + type, value_to_double_int (ptrval), ptrval.mask, + type, value_to_double_int (alignval), alignval.mask); + if (!double_int_minus_one_p (mask)) + { + val.lattice_val = CONSTANT; + val.mask = mask; + gcc_assert ((mask.low & (aligni - 1)) == 0); + gcc_assert ((value.low & (aligni - 1)) == 0); + value.low |= misaligni; + /* ??? Delay building trees here. */ + val.value = double_int_to_tree (type, value); + } + else + { + val.lattice_val = VARYING; + val.value = NULL_TREE; + val.mask = double_int_minus_one; + } + return val; +} + /* Evaluate statement STMT. Valid only for assignments, calls, conditionals, and switches. */ @@ -1647,6 +1705,10 @@ evaluate_stmt (gimple stmt) val = get_value_for_expr (gimple_call_arg (stmt, 0), true); break; + case BUILT_IN_ASSUME_ALIGNED: + val = bit_value_assume_aligned (stmt); + break; + default:; } } @@ -2186,6 +2248,11 @@ execute_fold_all_builtins (void) result = integer_zero_node; break; + case BUILT_IN_ASSUME_ALIGNED: + /* Remove __builtin_assume_aligned. */ + result = gimple_call_arg (stmt, 0); + break; + case BUILT_IN_STACK_RESTORE: result = optimize_stack_restore (i); if (result) |