Commit 1be38ccb by Richard Guenther Committed by Richard Biener

tree-flow.h (struct ptr_info_def): Add align and misalign fields.

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.

From-SVN: r163189
parent a96ad348
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.
2010-08-12 Uros Bizjak <ubizjak@gmail.com> 2010-08-12 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.c (LONG_TYPE_SIZE): Remove. * config/i386/i386.c (LONG_TYPE_SIZE): Remove.
......
...@@ -309,6 +309,7 @@ get_object_alignment (tree exp, unsigned int max_align) ...@@ -309,6 +309,7 @@ get_object_alignment (tree exp, unsigned int max_align)
else if (TREE_CODE (exp) == MEM_REF) else if (TREE_CODE (exp) == MEM_REF)
{ {
tree addr = TREE_OPERAND (exp, 0); tree addr = TREE_OPERAND (exp, 0);
struct ptr_info_def *pi;
if (TREE_CODE (addr) == BIT_AND_EXPR if (TREE_CODE (addr) == BIT_AND_EXPR
&& TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST) && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
{ {
...@@ -319,12 +320,53 @@ get_object_alignment (tree exp, unsigned int max_align) ...@@ -319,12 +320,53 @@ get_object_alignment (tree exp, unsigned int max_align)
} }
else else
align = BITS_PER_UNIT; align = BITS_PER_UNIT;
if (TREE_CODE (addr) == ADDR_EXPR) if (TREE_CODE (addr) == SSA_NAME
&& (pi = SSA_NAME_PTR_INFO (addr)))
{
bitpos += (pi->misalign * BITS_PER_UNIT) & ~(align - 1);
align = MAX (pi->align * BITS_PER_UNIT, align);
}
else if (TREE_CODE (addr) == ADDR_EXPR)
align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0), align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0),
max_align)); max_align));
bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT; bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
} }
else if (TREE_CODE (exp) == TARGET_MEM_REF else if (TREE_CODE (exp) == TARGET_MEM_REF
&& TMR_BASE (exp)
&& POINTER_TYPE_P (TREE_TYPE (TMR_BASE (exp))))
{
struct ptr_info_def *pi;
tree addr = TMR_BASE (exp);
if (TREE_CODE (addr) == BIT_AND_EXPR
&& TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
{
align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))
& -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)));
align *= BITS_PER_UNIT;
addr = TREE_OPERAND (addr, 0);
}
else
align = BITS_PER_UNIT;
if (TREE_CODE (addr) == SSA_NAME
&& (pi = SSA_NAME_PTR_INFO (addr)))
{
bitpos += (pi->misalign * BITS_PER_UNIT) & ~(align - 1);
align = MAX (pi->align * BITS_PER_UNIT, align);
}
else if (TREE_CODE (addr) == ADDR_EXPR)
align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0),
max_align));
if (TMR_OFFSET (exp))
bitpos += TREE_INT_CST_LOW (TMR_OFFSET (exp)) * BITS_PER_UNIT;
if (TMR_INDEX (exp) && TMR_STEP (exp))
{
unsigned HOST_WIDE_INT step = TREE_INT_CST_LOW (TMR_STEP (exp));
align = MIN (align, (step & -step) * BITS_PER_UNIT);
}
else if (TMR_INDEX (exp))
align = BITS_PER_UNIT;
}
else if (TREE_CODE (exp) == TARGET_MEM_REF
&& TMR_SYMBOL (exp)) && TMR_SYMBOL (exp))
{ {
align = get_object_alignment (TMR_SYMBOL (exp), max_align); align = get_object_alignment (TMR_SYMBOL (exp), max_align);
...@@ -417,56 +459,28 @@ can_trust_pointer_alignment (void) ...@@ -417,56 +459,28 @@ can_trust_pointer_alignment (void)
Otherwise, look at the expression to see if we can do better, i.e., if the Otherwise, look at the expression to see if we can do better, i.e., if the
expression is actually pointing at an object whose alignment is tighter. */ expression is actually pointing at an object whose alignment is tighter. */
int unsigned int
get_pointer_alignment (tree exp, unsigned int max_align) get_pointer_alignment (tree exp, unsigned int max_align)
{ {
unsigned int align, inner; STRIP_NOPS (exp);
if (!can_trust_pointer_alignment ())
return 0;
if (!POINTER_TYPE_P (TREE_TYPE (exp)))
return 0;
align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
align = MIN (align, max_align);
while (1)
{
switch (TREE_CODE (exp))
{
CASE_CONVERT:
exp = TREE_OPERAND (exp, 0);
if (! POINTER_TYPE_P (TREE_TYPE (exp)))
return align;
inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
align = MIN (inner, max_align);
break;
case POINTER_PLUS_EXPR:
/* If sum of pointer + int, restrict our maximum alignment to that
imposed by the integer. If not, we can't do any better than
ALIGN. */
if (! host_integerp (TREE_OPERAND (exp, 1), 1))
return align;
while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
& (max_align / BITS_PER_UNIT - 1))
!= 0)
max_align >>= 1;
exp = TREE_OPERAND (exp, 0);
break;
case ADDR_EXPR:
/* See what we are pointing at and look at its alignment. */
return get_object_alignment (TREE_OPERAND (exp, 0), max_align);
default: if (TREE_CODE (exp) == ADDR_EXPR)
return align; return get_object_alignment (TREE_OPERAND (exp, 0), max_align);
} else if (TREE_CODE (exp) == SSA_NAME
&& POINTER_TYPE_P (TREE_TYPE (exp)))
{
struct ptr_info_def *pi = SSA_NAME_PTR_INFO (exp);
unsigned align;
if (!pi)
return BITS_PER_UNIT;
if (pi->misalign != 0)
align = (pi->misalign & -pi->misalign);
else
align = pi->align;
return MIN (max_align, align * BITS_PER_UNIT);
} }
return POINTER_TYPE_P (TREE_TYPE (exp)) ? BITS_PER_UNIT : 0;
} }
/* Compute the length of a C string. TREE_STRING_LENGTH is not the right /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
...@@ -3293,7 +3307,7 @@ expand_builtin_strlen (tree exp, rtx target, ...@@ -3293,7 +3307,7 @@ expand_builtin_strlen (tree exp, rtx target,
rtx result, src_reg, char_rtx, before_strlen; rtx result, src_reg, char_rtx, before_strlen;
enum machine_mode insn_mode = target_mode, char_mode; enum machine_mode insn_mode = target_mode, char_mode;
enum insn_code icode = CODE_FOR_nothing; enum insn_code icode = CODE_FOR_nothing;
int align; unsigned int align;
/* If the length can be computed at compile-time, return it. */ /* If the length can be computed at compile-time, return it. */
len = c_strlen (src, 0); len = c_strlen (src, 0);
...@@ -4066,9 +4080,9 @@ expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target, ...@@ -4066,9 +4080,9 @@ expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target,
tree arg2 = CALL_EXPR_ARG (exp, 1); tree arg2 = CALL_EXPR_ARG (exp, 1);
tree len = CALL_EXPR_ARG (exp, 2); tree len = CALL_EXPR_ARG (exp, 2);
int arg1_align unsigned int arg1_align
= get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
int arg2_align unsigned int arg2_align
= get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
enum machine_mode insn_mode; enum machine_mode insn_mode;
...@@ -4168,9 +4182,9 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target) ...@@ -4168,9 +4182,9 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
tree arg1 = CALL_EXPR_ARG (exp, 0); tree arg1 = CALL_EXPR_ARG (exp, 0);
tree arg2 = CALL_EXPR_ARG (exp, 1); tree arg2 = CALL_EXPR_ARG (exp, 1);
int arg1_align unsigned int arg1_align
= get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
int arg2_align unsigned int arg2_align
= get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
/* If we don't have POINTER_TYPE, call the function. */ /* If we don't have POINTER_TYPE, call the function. */
...@@ -4319,9 +4333,9 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target, ...@@ -4319,9 +4333,9 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
tree arg2 = CALL_EXPR_ARG (exp, 1); tree arg2 = CALL_EXPR_ARG (exp, 1);
tree arg3 = CALL_EXPR_ARG (exp, 2); tree arg3 = CALL_EXPR_ARG (exp, 2);
int arg1_align unsigned int arg1_align
= get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
int arg2_align unsigned int arg2_align
= get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
enum machine_mode insn_mode enum machine_mode insn_mode
= insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode; = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
...@@ -5505,7 +5519,9 @@ get_builtin_sync_mem (tree loc, enum machine_mode mode) ...@@ -5505,7 +5519,9 @@ get_builtin_sync_mem (tree loc, enum machine_mode mode)
satisfy the full barrier semantics of the intrinsic. */ satisfy the full barrier semantics of the intrinsic. */
mem = validize_mem (gen_rtx_MEM (mode, addr)); mem = validize_mem (gen_rtx_MEM (mode, addr));
set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT)); /* The alignment needs to be at least according to that of the mode. */
set_mem_align (mem, MAX (GET_MODE_ALIGNMENT (mode),
get_pointer_alignment (loc, BIGGEST_ALIGNMENT)));
set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER); set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
MEM_VOLATILE_P (mem) = 1; MEM_VOLATILE_P (mem) = 1;
...@@ -8280,7 +8296,7 @@ fold_builtin_memset (location_t loc, tree dest, tree c, tree len, ...@@ -8280,7 +8296,7 @@ fold_builtin_memset (location_t loc, tree dest, tree c, tree len,
length = tree_low_cst (len, 1); length = tree_low_cst (len, 1);
if (GET_MODE_SIZE (TYPE_MODE (etype)) != length if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
|| get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
< (int) length) < length)
return NULL_TREE; return NULL_TREE;
if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT) if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
...@@ -8365,7 +8381,7 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src, ...@@ -8365,7 +8381,7 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
else else
{ {
tree srctype, desttype; tree srctype, desttype;
int src_align, dest_align; unsigned int src_align, dest_align;
tree off0; tree off0;
if (endp == 3) if (endp == 3)
...@@ -8504,8 +8520,8 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src, ...@@ -8504,8 +8520,8 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT); src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
if (dest_align < (int) TYPE_ALIGN (desttype) if (dest_align < TYPE_ALIGN (desttype)
|| src_align < (int) TYPE_ALIGN (srctype)) || src_align < TYPE_ALIGN (srctype))
return NULL_TREE; return NULL_TREE;
if (!ignore) if (!ignore)
...@@ -8531,7 +8547,7 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src, ...@@ -8531,7 +8547,7 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
&& tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len) && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
&& (!STRICT_ALIGNMENT && (!STRICT_ALIGNMENT
|| !destvar || !destvar
|| src_align >= (int) TYPE_ALIGN (desttype))) || src_align >= TYPE_ALIGN (desttype)))
srcvar = fold_build2 (MEM_REF, destvar ? desttype : srctype, srcvar = fold_build2 (MEM_REF, destvar ? desttype : srctype,
srcvar, off0); srcvar, off0);
else else
...@@ -8543,7 +8559,7 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src, ...@@ -8543,7 +8559,7 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
if (srcvar == NULL_TREE) if (srcvar == NULL_TREE)
{ {
if (STRICT_ALIGNMENT if (STRICT_ALIGNMENT
&& src_align < (int) TYPE_ALIGN (desttype)) && src_align < TYPE_ALIGN (desttype))
return NULL_TREE; return NULL_TREE;
STRIP_NOPS (src); STRIP_NOPS (src);
srcvar = fold_build2 (MEM_REF, desttype, src, off0); srcvar = fold_build2 (MEM_REF, desttype, src, off0);
...@@ -8551,7 +8567,7 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src, ...@@ -8551,7 +8567,7 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
else if (destvar == NULL_TREE) else if (destvar == NULL_TREE)
{ {
if (STRICT_ALIGNMENT if (STRICT_ALIGNMENT
&& dest_align < (int) TYPE_ALIGN (srctype)) && dest_align < TYPE_ALIGN (srctype))
return NULL_TREE; return NULL_TREE;
STRIP_NOPS (dest); STRIP_NOPS (dest);
destvar = fold_build2 (MEM_REF, srctype, dest, off0); destvar = fold_build2 (MEM_REF, srctype, dest, off0);
......
...@@ -1363,8 +1363,13 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags) ...@@ -1363,8 +1363,13 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
&& POINTER_TYPE_P (TREE_TYPE (lhs)) && POINTER_TYPE_P (TREE_TYPE (lhs))
&& SSA_NAME_PTR_INFO (lhs)) && SSA_NAME_PTR_INFO (lhs))
{ {
struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs);
pp_string (buffer, "PT = "); pp_string (buffer, "PT = ");
pp_points_to_solution (buffer, &SSA_NAME_PTR_INFO (lhs)->pt); pp_points_to_solution (buffer, &pi->pt);
newline_and_indent (buffer, spc);
if (pi->align != 1)
pp_printf (buffer, "# ALIGN = %u, MISALIGN = %u",
pi->align, pi->misalign);
newline_and_indent (buffer, spc); newline_and_indent (buffer, spc);
pp_string (buffer, "# "); pp_string (buffer, "# ");
} }
...@@ -1650,9 +1655,16 @@ dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags) ...@@ -1650,9 +1655,16 @@ dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
&& POINTER_TYPE_P (TREE_TYPE (lhs)) && POINTER_TYPE_P (TREE_TYPE (lhs))
&& SSA_NAME_PTR_INFO (lhs)) && SSA_NAME_PTR_INFO (lhs))
{ {
struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs);
pp_string (buffer, "# PT = "); pp_string (buffer, "# PT = ");
pp_points_to_solution (buffer, &SSA_NAME_PTR_INFO (lhs)->pt); pp_points_to_solution (buffer, &pi->pt);
newline_and_indent (buffer, spc); newline_and_indent (buffer, spc);
if (pi->align != 1)
{
pp_printf (buffer, "# ALIGN = %u, MISALIGN = %u",
pi->align, pi->misalign);
newline_and_indent (buffer, spc);
}
} }
} }
......
...@@ -119,6 +119,18 @@ struct GTY(()) ptr_info_def ...@@ -119,6 +119,18 @@ struct GTY(()) ptr_info_def
{ {
/* The points-to solution. */ /* The points-to solution. */
struct pt_solution pt; struct pt_solution pt;
/* Alignment and misalignment of the pointer in bytes. Together
align and misalign specify low known bits of the pointer.
ptr & (align - 1) == misalign. */
/* The power-of-two byte alignment of the object this pointer
points into. This is usually DECL_ALIGN_UNIT for decls and
MALLOC_ABI_ALIGNMENT for allocated storage. */
unsigned int align;
/* The byte offset this pointer differs from the above alignment. */
unsigned int misalign;
}; };
......
...@@ -368,27 +368,6 @@ debug_alias_info (void) ...@@ -368,27 +368,6 @@ debug_alias_info (void)
} }
/* Return the alias information associated with pointer T. It creates a
new instance if none existed. */
struct ptr_info_def *
get_ptr_info (tree t)
{
struct ptr_info_def *pi;
gcc_assert (POINTER_TYPE_P (TREE_TYPE (t)));
pi = SSA_NAME_PTR_INFO (t);
if (pi == NULL)
{
pi = ggc_alloc_cleared_ptr_info_def ();
pt_solution_reset (&pi->pt);
SSA_NAME_PTR_INFO (t) = pi;
}
return pi;
}
/* Dump the points-to set *PT into FILE. */ /* Dump the points-to set *PT into FILE. */
void void
......
...@@ -839,8 +839,40 @@ static bool ...@@ -839,8 +839,40 @@ static bool
ccp_finalize (void) ccp_finalize (void)
{ {
bool something_changed; bool something_changed;
unsigned i;
do_dbg_cnt (); 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. */ /* Perform substitutions based on the known constant values. */
something_changed = substitute_and_fold (get_constant_value, something_changed = substitute_and_fold (get_constant_value,
ccp_fold_stmt, true); ccp_fold_stmt, true);
...@@ -1981,6 +2013,7 @@ evaluate_stmt (gimple stmt) ...@@ -1981,6 +2013,7 @@ evaluate_stmt (gimple stmt)
&& !is_constant) && !is_constant)
{ {
enum gimple_code code = gimple_code (stmt); enum gimple_code code = gimple_code (stmt);
tree fndecl;
val.lattice_val = VARYING; val.lattice_val = VARYING;
val.value = NULL_TREE; val.value = NULL_TREE;
val.mask = double_int_minus_one; val.mask = double_int_minus_one;
...@@ -2026,6 +2059,33 @@ evaluate_stmt (gimple stmt) ...@@ -2026,6 +2059,33 @@ evaluate_stmt (gimple stmt)
|| POINTER_TYPE_P (TREE_TYPE (rhs1))) || POINTER_TYPE_P (TREE_TYPE (rhs1)))
val = bit_value_binop (code, TREE_TYPE (rhs1), rhs1, rhs2); 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); is_constant = (val.lattice_val == CONSTANT);
} }
......
...@@ -240,20 +240,29 @@ release_ssa_name (tree var) ...@@ -240,20 +240,29 @@ release_ssa_name (tree var)
} }
} }
/* Creates a duplicate of a ssa name NAME defined in statement STMT. */
tree /* Return the alias information associated with pointer T. It creates a
duplicate_ssa_name (tree name, gimple stmt) new instance if none existed. */
struct ptr_info_def *
get_ptr_info (tree t)
{ {
tree new_name = make_ssa_name (SSA_NAME_VAR (name), stmt); struct ptr_info_def *pi;
struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
if (old_ptr_info) gcc_assert (POINTER_TYPE_P (TREE_TYPE (t)));
duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
return new_name; pi = SSA_NAME_PTR_INFO (t);
} if (pi == NULL)
{
pi = ggc_alloc_cleared_ptr_info_def ();
pt_solution_reset (&pi->pt);
pi->align = 1;
pi->misalign = 0;
SSA_NAME_PTR_INFO (t) = pi;
}
return pi;
}
/* Creates a duplicate of the ptr_info_def at PTR_INFO for use by /* Creates a duplicate of the ptr_info_def at PTR_INFO for use by
the SSA name NAME. */ the SSA name NAME. */
...@@ -276,6 +285,21 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info) ...@@ -276,6 +285,21 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
} }
/* Creates a duplicate of a ssa name NAME tobe defined by statement STMT. */
tree
duplicate_ssa_name (tree name, gimple stmt)
{
tree new_name = make_ssa_name (SSA_NAME_VAR (name), stmt);
struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
if (old_ptr_info)
duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
return new_name;
}
/* Release all the SSA_NAMEs created by STMT. */ /* Release all the SSA_NAMEs created by STMT. */
void void
......
...@@ -5033,7 +5033,7 @@ extern tree build_string_literal (int, const char *); ...@@ -5033,7 +5033,7 @@ extern tree build_string_literal (int, const char *);
extern bool validate_arglist (const_tree, ...); extern bool validate_arglist (const_tree, ...);
extern rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode); extern rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
extern bool can_trust_pointer_alignment (void); extern bool can_trust_pointer_alignment (void);
extern int get_pointer_alignment (tree, unsigned int); extern unsigned int get_pointer_alignment (tree, unsigned int);
extern bool is_builtin_name (const char *); extern bool is_builtin_name (const char *);
extern bool is_builtin_fn (tree); extern bool is_builtin_fn (tree);
extern unsigned int get_object_alignment (tree, unsigned int); extern unsigned int get_object_alignment (tree, unsigned int);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment