Commit e80c2726 by Richard Guenther Committed by Richard Biener

tree.h (get_object_alignment): Adjust prototype.

2010-08-10  Richard Guenther  <rguenther@suse.de>

	* tree.h (get_object_alignment): Adjust prototype.
	* builtins.c (get_object_alignment): Return unsigned int,
	drop the align parameter.  Handle MEM_REF, MISALIGNED_INDIRECT_REF
	and TARGET_MEM_REF properly.
	(get_pointer_alignment): Adjust.
	* emit-rtl.c (get_mem_align_offset): Adjust comment.
	(set_mem_attributes_minus_bitpos): Adjust.
	* tree-ssa-ccp.c (get_value_from_alignment): Adjust.

From-SVN: r163051
parent a024390f
2010-08-10 Richard Guenther <rguenther@suse.de> 2010-08-10 Richard Guenther <rguenther@suse.de>
* tree.h (get_object_alignment): Adjust prototype.
* builtins.c (get_object_alignment): Return unsigned int,
drop the align parameter. Handle MEM_REF, MISALIGNED_INDIRECT_REF
and TARGET_MEM_REF properly.
(get_pointer_alignment): Adjust.
* emit-rtl.c (get_mem_align_offset): Adjust comment.
(set_mem_attributes_minus_bitpos): Adjust.
* tree-ssa-ccp.c (get_value_from_alignment): Adjust.
2010-08-10 Richard Guenther <rguenther@suse.de>
* tree-ssa-copy.c (set_copy_of_val): Use operand_equal_p. * tree-ssa-copy.c (set_copy_of_val): Use operand_equal_p.
(copy_prop_visit_assignment): Simplify. (copy_prop_visit_assignment): Simplify.
(copy_prop_visit_stmt): Also visit assignments from (copy_prop_visit_stmt): Also visit assignments from
......
...@@ -267,81 +267,135 @@ called_as_built_in (tree node) ...@@ -267,81 +267,135 @@ called_as_built_in (tree node)
} }
/* Return the alignment in bits of EXP, an object. /* Return the alignment in bits of EXP, an object.
Don't return more than MAX_ALIGN no matter what, ALIGN is the inital Don't return more than MAX_ALIGN no matter what. */
guessed alignment e.g. from type alignment. */
int unsigned int
get_object_alignment (tree exp, unsigned int align, unsigned int max_align) get_object_alignment (tree exp, unsigned int max_align)
{ {
unsigned int inner; HOST_WIDE_INT bitsize, bitpos;
tree offset;
inner = max_align; enum machine_mode mode;
if (handled_component_p (exp)) int unsignedp, volatilep;
{ unsigned int align, inner;
HOST_WIDE_INT bitsize, bitpos;
tree offset;
enum machine_mode mode;
int unsignedp, volatilep;
exp = get_inner_reference (exp, &bitsize, &bitpos, &offset, /* Get the innermost object and the constant (bitpos) and possibly
&mode, &unsignedp, &volatilep, true); variable (offset) offset of the access. */
if (bitpos) exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
inner = MIN (inner, (unsigned) (bitpos & -bitpos)); &mode, &unsignedp, &volatilep, true);
while (offset)
{
tree next_offset;
if (TREE_CODE (offset) == PLUS_EXPR) /* Extract alignment information from the innermost object and
{ possibly adjust bitpos and offset. */
next_offset = TREE_OPERAND (offset, 0);
offset = TREE_OPERAND (offset, 1);
}
else
next_offset = NULL;
if (host_integerp (offset, 1))
{
/* Any overflow in calculating offset_bits won't change
the alignment. */
unsigned offset_bits
= ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
if (offset_bits)
inner = MIN (inner, (offset_bits & -offset_bits));
}
else if (TREE_CODE (offset) == MULT_EXPR
&& host_integerp (TREE_OPERAND (offset, 1), 1))
{
/* Any overflow in calculating offset_factor won't change
the alignment. */
unsigned offset_factor
= ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
* BITS_PER_UNIT);
if (offset_factor)
inner = MIN (inner, (offset_factor & -offset_factor));
}
else
{
inner = MIN (inner, BITS_PER_UNIT);
break;
}
offset = next_offset;
}
}
if (TREE_CODE (exp) == CONST_DECL) if (TREE_CODE (exp) == CONST_DECL)
exp = DECL_INITIAL (exp); exp = DECL_INITIAL (exp);
if (DECL_P (exp) if (DECL_P (exp)
&& TREE_CODE (exp) != LABEL_DECL) && TREE_CODE (exp) != LABEL_DECL)
align = MIN (inner, DECL_ALIGN (exp)); align = DECL_ALIGN (exp);
#ifdef CONSTANT_ALIGNMENT
else if (CONSTANT_CLASS_P (exp)) else if (CONSTANT_CLASS_P (exp))
align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align)); {
align = TYPE_ALIGN (TREE_TYPE (exp));
#ifdef CONSTANT_ALIGNMENT
align = (unsigned)CONSTANT_ALIGNMENT (exp, align);
#endif #endif
else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR }
|| TREE_CODE (exp) == INDIRECT_REF) else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR)
align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner); align = TYPE_ALIGN (TREE_TYPE (exp));
else if (TREE_CODE (exp) == INDIRECT_REF)
align = TYPE_ALIGN (TREE_TYPE (exp));
else if (TREE_CODE (exp) == MISALIGNED_INDIRECT_REF)
{
tree op1 = TREE_OPERAND (exp, 1);
align = integer_zerop (op1) ? BITS_PER_UNIT : TREE_INT_CST_LOW (op1);
}
else if (TREE_CODE (exp) == MEM_REF)
{
tree addr = TREE_OPERAND (exp, 0);
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) == ADDR_EXPR)
align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0),
max_align));
bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
}
else if (TREE_CODE (exp) == TARGET_MEM_REF
&& TMR_SYMBOL (exp))
{
align = get_object_alignment (TMR_SYMBOL (exp), 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 else
align = MIN (align, inner); align = BITS_PER_UNIT;
/* If there is a non-constant offset part extract the maximum
alignment that can prevail. */
inner = max_align;
while (offset)
{
tree next_offset;
if (TREE_CODE (offset) == PLUS_EXPR)
{
next_offset = TREE_OPERAND (offset, 0);
offset = TREE_OPERAND (offset, 1);
}
else
next_offset = NULL;
if (host_integerp (offset, 1))
{
/* Any overflow in calculating offset_bits won't change
the alignment. */
unsigned offset_bits
= ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
if (offset_bits)
inner = MIN (inner, (offset_bits & -offset_bits));
}
else if (TREE_CODE (offset) == MULT_EXPR
&& host_integerp (TREE_OPERAND (offset, 1), 1))
{
/* Any overflow in calculating offset_factor won't change
the alignment. */
unsigned offset_factor
= ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
* BITS_PER_UNIT);
if (offset_factor)
inner = MIN (inner, (offset_factor & -offset_factor));
}
else
{
inner = MIN (inner, BITS_PER_UNIT);
break;
}
offset = next_offset;
}
/* Alignment is innermost object alignment adjusted by the constant
and non-constant offset parts. */
align = MIN (align, inner);
bitpos = bitpos & (align - 1);
/* align and bitpos now specify known low bits of the pointer.
ptr & (align - 1) == bitpos. */
if (bitpos != 0)
align = (bitpos & -bitpos);
return MIN (align, max_align); return MIN (align, max_align);
} }
...@@ -407,7 +461,7 @@ get_pointer_alignment (tree exp, unsigned int max_align) ...@@ -407,7 +461,7 @@ get_pointer_alignment (tree exp, unsigned int max_align)
case ADDR_EXPR: case ADDR_EXPR:
/* See what we are pointing at and look at its alignment. */ /* See what we are pointing at and look at its alignment. */
return get_object_alignment (TREE_OPERAND (exp, 0), align, max_align); return get_object_alignment (TREE_OPERAND (exp, 0), max_align);
default: default:
return align; return align;
......
...@@ -1459,7 +1459,8 @@ get_mem_align_offset (rtx mem, unsigned int align) ...@@ -1459,7 +1459,8 @@ get_mem_align_offset (rtx mem, unsigned int align)
/* This function can't use /* This function can't use
if (!MEM_EXPR (mem) || !MEM_OFFSET (mem) if (!MEM_EXPR (mem) || !MEM_OFFSET (mem)
|| !CONST_INT_P (MEM_OFFSET (mem)) || !CONST_INT_P (MEM_OFFSET (mem))
|| (get_object_alignment (MEM_EXPR (mem), MEM_ALIGN (mem), align) || (MAX (MEM_ALIGN (mem),
get_object_alignment (MEM_EXPR (mem), align))
< align)) < align))
return -1; return -1;
else else
...@@ -1796,8 +1797,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, ...@@ -1796,8 +1797,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
if (!align_computed && !INDIRECT_REF_P (t)) if (!align_computed && !INDIRECT_REF_P (t))
{ {
unsigned int obj_align unsigned int obj_align = get_object_alignment (t, BIGGEST_ALIGNMENT);
= get_object_alignment (t, align, BIGGEST_ALIGNMENT);
align = MAX (align, obj_align); align = MAX (align, obj_align);
} }
} }
......
...@@ -515,8 +515,7 @@ get_value_from_alignment (tree expr) ...@@ -515,8 +515,7 @@ get_value_from_alignment (tree expr)
val = bit_value_binop (PLUS_EXPR, TREE_TYPE (expr), val = bit_value_binop (PLUS_EXPR, TREE_TYPE (expr),
TREE_OPERAND (base, 0), TREE_OPERAND (base, 1)); TREE_OPERAND (base, 0), TREE_OPERAND (base, 1));
else if (base else if (base
&& ((align = get_object_alignment (base, BITS_PER_UNIT, && ((align = get_object_alignment (base, BIGGEST_ALIGNMENT))
BIGGEST_ALIGNMENT))
> BITS_PER_UNIT)) > BITS_PER_UNIT))
{ {
val.lattice_val = CONSTANT; val.lattice_val = CONSTANT;
......
...@@ -5036,7 +5036,7 @@ extern bool can_trust_pointer_alignment (void); ...@@ -5036,7 +5036,7 @@ extern bool can_trust_pointer_alignment (void);
extern int get_pointer_alignment (tree, unsigned int); extern 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 int get_object_alignment (tree, unsigned int, unsigned int); extern unsigned int get_object_alignment (tree, unsigned int);
extern tree fold_call_stmt (gimple, bool); extern tree fold_call_stmt (gimple, bool);
extern tree gimple_fold_builtin_snprintf_chk (gimple, tree, enum built_in_function); extern tree gimple_fold_builtin_snprintf_chk (gimple, tree, enum built_in_function);
extern tree make_range (tree, int *, tree *, tree *, bool *); extern tree make_range (tree, int *, tree *, tree *, bool *);
......
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