aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-ccp.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-06-27 18:52:23 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-06-27 18:52:23 +0200
commit45d439ac1a9e2df33ac7ef573009749dbebf581b (patch)
treeefa39246412ef14d5214fe10b53a962abeab3d20 /gcc/tree-ssa-ccp.c
parentdc2a58daabf95cfac0dd346ff717902bdc6e3d93 (diff)
downloadgcc-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.c67
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)