re PR middle-end/37774 (Alignment information is lost for ARRAY_REFs)
PR middle-end/37774 * tree.h (get_object_alignment): Declare. * emit-rtl.c (set_mem_attributes_minus_bitpos): Call get_object_alignment if needed. * builtins.c (get_pointer_alignment): Move ADDR_EXPR operand handling to ... (get_object_alignment): ... here. New function. Try harder to determine alignment from get_inner_reference returned offset. From-SVN: r141003
This commit is contained in:
parent
cc2a64dd80
commit
df96b05947
4 changed files with 98 additions and 53 deletions
|
@ -7,6 +7,15 @@
|
|||
* tree-cfg.c (make_cond_expr_edges, make_goto_expr_edges): Only set
|
||||
goto_block on edges if goto_locus is known.
|
||||
|
||||
PR middle-end/37774
|
||||
* tree.h (get_object_alignment): Declare.
|
||||
* emit-rtl.c (set_mem_attributes_minus_bitpos): Call
|
||||
get_object_alignment if needed.
|
||||
* builtins.c (get_pointer_alignment): Move ADDR_EXPR operand handling
|
||||
to ...
|
||||
(get_object_alignment): ... here. New function. Try harder to
|
||||
determine alignment from get_inner_reference returned offset.
|
||||
|
||||
2008-10-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* graphite.c (gloog): Don't call find_unreachable_blocks
|
||||
|
|
130
gcc/builtins.c
130
gcc/builtins.c
|
@ -253,6 +253,82 @@ static bool called_as_built_in (tree node)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Return the alignment in bits of EXP, an object.
|
||||
Don't return more than MAX_ALIGN no matter what, ALIGN is the inital
|
||||
guessed alignment e.g. from type alignment. */
|
||||
|
||||
int
|
||||
get_object_alignment (tree exp, unsigned int align, unsigned int max_align)
|
||||
{
|
||||
unsigned int inner;
|
||||
|
||||
inner = max_align;
|
||||
if (handled_component_p (exp))
|
||||
{
|
||||
HOST_WIDE_INT bitsize, bitpos;
|
||||
tree offset;
|
||||
enum machine_mode mode;
|
||||
int unsignedp, volatilep;
|
||||
|
||||
exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
|
||||
&mode, &unsignedp, &volatilep, true);
|
||||
if (bitpos)
|
||||
inner = MIN (inner, (unsigned) (bitpos & -bitpos));
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (DECL_P (exp))
|
||||
align = MIN (inner, DECL_ALIGN (exp));
|
||||
#ifdef CONSTANT_ALIGNMENT
|
||||
else if (CONSTANT_CLASS_P (exp))
|
||||
align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
|
||||
#endif
|
||||
else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
|
||||
|| TREE_CODE (exp) == INDIRECT_REF)
|
||||
align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
|
||||
else
|
||||
align = MIN (align, inner);
|
||||
return MIN (align, max_align);
|
||||
}
|
||||
|
||||
/* Return the alignment in bits of EXP, a pointer valued expression.
|
||||
But don't return more than MAX_ALIGN no matter what.
|
||||
The alignment returned is, by default, the alignment of the thing that
|
||||
|
@ -306,59 +382,7 @@ get_pointer_alignment (tree exp, unsigned int max_align)
|
|||
|
||||
case ADDR_EXPR:
|
||||
/* See what we are pointing at and look at its alignment. */
|
||||
exp = TREE_OPERAND (exp, 0);
|
||||
inner = max_align;
|
||||
if (handled_component_p (exp))
|
||||
{
|
||||
HOST_WIDE_INT bitsize, bitpos;
|
||||
tree offset;
|
||||
enum machine_mode mode;
|
||||
int unsignedp, volatilep;
|
||||
|
||||
exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
|
||||
&mode, &unsignedp, &volatilep, true);
|
||||
if (bitpos)
|
||||
inner = MIN (inner, (unsigned) (bitpos & -bitpos));
|
||||
if (offset && TREE_CODE (offset) == PLUS_EXPR
|
||||
&& host_integerp (TREE_OPERAND (offset, 1), 1))
|
||||
{
|
||||
/* Any overflow in calculating offset_bits won't change
|
||||
the alignment. */
|
||||
unsigned offset_bits
|
||||
= ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
|
||||
* BITS_PER_UNIT);
|
||||
|
||||
if (offset_bits)
|
||||
inner = MIN (inner, (offset_bits & -offset_bits));
|
||||
offset = TREE_OPERAND (offset, 0);
|
||||
}
|
||||
if (offset && 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 if (offset)
|
||||
inner = MIN (inner, BITS_PER_UNIT);
|
||||
}
|
||||
if (DECL_P (exp))
|
||||
align = MIN (inner, DECL_ALIGN (exp));
|
||||
#ifdef CONSTANT_ALIGNMENT
|
||||
else if (CONSTANT_CLASS_P (exp))
|
||||
align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
|
||||
#endif
|
||||
else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
|
||||
|| TREE_CODE (exp) == INDIRECT_REF)
|
||||
align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
|
||||
else
|
||||
align = MIN (align, inner);
|
||||
return MIN (align, max_align);
|
||||
return get_object_alignment (TREE_OPERAND (exp, 0), align, max_align);
|
||||
|
||||
default:
|
||||
return align;
|
||||
|
|
|
@ -1564,6 +1564,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
|
|||
if (! TYPE_P (t))
|
||||
{
|
||||
tree base;
|
||||
bool align_computed = false;
|
||||
|
||||
if (TREE_THIS_VOLATILE (t))
|
||||
MEM_VOLATILE_P (ref) = 1;
|
||||
|
@ -1620,6 +1621,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
|
|||
&& host_integerp (DECL_SIZE_UNIT (t), 1)
|
||||
? GEN_INT (tree_low_cst (DECL_SIZE_UNIT (t), 1)) : 0);
|
||||
align = DECL_ALIGN (t);
|
||||
align_computed = true;
|
||||
}
|
||||
|
||||
/* If this is a constant, we know the alignment. */
|
||||
|
@ -1629,6 +1631,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
|
|||
#ifdef CONSTANT_ALIGNMENT
|
||||
align = CONSTANT_ALIGNMENT (t, align);
|
||||
#endif
|
||||
align_computed = true;
|
||||
}
|
||||
|
||||
/* If this is a field reference and not a bit-field, record it. */
|
||||
|
@ -1688,6 +1691,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
|
|||
align = DECL_ALIGN (t2);
|
||||
if (aoff && (unsigned HOST_WIDE_INT) aoff < align)
|
||||
align = aoff;
|
||||
align_computed = true;
|
||||
offset = GEN_INT (ioff);
|
||||
apply_bitpos = bitpos;
|
||||
}
|
||||
|
@ -1721,6 +1725,13 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
|
|||
expr = t;
|
||||
offset = NULL;
|
||||
}
|
||||
|
||||
if (!align_computed && !INDIRECT_REF_P (t))
|
||||
{
|
||||
unsigned int obj_align
|
||||
= get_object_alignment (t, align, BIGGEST_ALIGNMENT);
|
||||
align = MAX (align, obj_align);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we modified OFFSET based on T, then subtract the outstanding
|
||||
|
|
|
@ -4864,6 +4864,7 @@ extern tree build_string_literal (int, const char *);
|
|||
extern bool validate_arglist (const_tree, ...);
|
||||
extern rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
|
||||
extern int get_pointer_alignment (tree, unsigned int);
|
||||
extern int get_object_alignment (tree, unsigned int, unsigned int);
|
||||
extern tree fold_call_stmt (gimple, bool);
|
||||
extern tree gimple_fold_builtin_snprintf_chk (gimple, tree, enum built_in_function);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue