summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-ccp.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-08-12 10:36:08 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-08-12 10:36:08 +0000
commit153c3b5050025f879d92be6cd675dbb0686255e3 (patch)
tree9a3a2a1cd2ab3e673bfae829eadbac8146e824a5 /gcc/tree-ssa-ccp.c
parentaadb75a702993e265e9f0dbda27187420f0a9b1f (diff)
downloadgcc-153c3b5050025f879d92be6cd675dbb0686255e3.tar.gz
2010-08-12 Richard Guenther <rguenther@suse.de>
* tree-flow.h (struct ptr_info_def): Add align and misalign fields. * tree-ssa-alias.c (get_ptr_info): Move ... * tree-ssanames.c (get_ptr_info): ... here. Initialize align and misalign fields conservatively. * tree-ssa-ccp.c (ccp_finalize): From partially constant pointers derive alignment information. (evaluate_stmt): Derive alignment information from memory allocation functions. * tree.h (get_pointer_alignment): Make unsigned. * builtins.c (get_object_alignment): Use alignment information we have computed for pointers. (get_pointer_alignment): Likewise. Make conservative, return and unsigned value. (expand_builtin_strlen): Adjust. (expand_builtin_memcmp): Likewise. (expand_builtin_strcmp): Likewise. (expand_builtin_strncmp): Likewise. (get_builtin_sync_mem): Use at least mode alignment. (fold_builtin_memset): Adjust. (fold_builtin_memory_op): Likewise. * gimple-pretty-print.c (dump_gimple_phi): Alongside alias information also dump pointer alignment knowledge. (dump_gimple_stmt): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@163189 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r--gcc/tree-ssa-ccp.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 622fe146315..5551df2d5a3 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -839,8 +839,40 @@ static bool
ccp_finalize (void)
{
bool something_changed;
+ unsigned i;
do_dbg_cnt ();
+
+ /* Derive alignment and misalignment information from partially
+ constant pointers in the lattice. */
+ for (i = 1; i < num_ssa_names; ++i)
+ {
+ tree name = ssa_name (i);
+ prop_value_t *val;
+ struct ptr_info_def *pi;
+ unsigned int tem, align;
+
+ if (!name
+ || !POINTER_TYPE_P (TREE_TYPE (name)))
+ continue;
+
+ val = get_value (name);
+ if (val->lattice_val != CONSTANT
+ || TREE_CODE (val->value) != INTEGER_CST)
+ continue;
+
+ /* Trailing constant bits specify the alignment, trailing value
+ bits the misalignment. */
+ tem = val->mask.low;
+ align = (tem & -tem);
+ if (align == 1)
+ continue;
+
+ pi = get_ptr_info (name);
+ pi->align = align;
+ pi->misalign = TREE_INT_CST_LOW (val->value) & (align - 1);
+ }
+
/* Perform substitutions based on the known constant values. */
something_changed = substitute_and_fold (get_constant_value,
ccp_fold_stmt, true);
@@ -1981,6 +2013,7 @@ evaluate_stmt (gimple stmt)
&& !is_constant)
{
enum gimple_code code = gimple_code (stmt);
+ tree fndecl;
val.lattice_val = VARYING;
val.value = NULL_TREE;
val.mask = double_int_minus_one;
@@ -2026,6 +2059,33 @@ evaluate_stmt (gimple stmt)
|| POINTER_TYPE_P (TREE_TYPE (rhs1)))
val = bit_value_binop (code, TREE_TYPE (rhs1), rhs1, rhs2);
}
+ else if (code == GIMPLE_CALL
+ && (fndecl = gimple_call_fndecl (stmt))
+ && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+ {
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_MALLOC:
+ case BUILT_IN_REALLOC:
+ case BUILT_IN_CALLOC:
+ val.lattice_val = CONSTANT;
+ val.value = build_int_cst (TREE_TYPE (gimple_get_lhs (stmt)), 0);
+ val.mask = shwi_to_double_int
+ (~(((HOST_WIDE_INT) MALLOC_ABI_ALIGNMENT)
+ / BITS_PER_UNIT - 1));
+ break;
+
+ case BUILT_IN_ALLOCA:
+ val.lattice_val = CONSTANT;
+ val.value = build_int_cst (TREE_TYPE (gimple_get_lhs (stmt)), 0);
+ val.mask = shwi_to_double_int
+ (~(((HOST_WIDE_INT) BIGGEST_ALIGNMENT)
+ / BITS_PER_UNIT - 1));
+ break;
+
+ default:;
+ }
+ }
is_constant = (val.lattice_val == CONSTANT);
}