mirror of git://gcc.gnu.org/git/gcc.git
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
|
|
@ -7,6 +7,15 @@
|
||||||
* tree-cfg.c (make_cond_expr_edges, make_goto_expr_edges): Only set
|
* tree-cfg.c (make_cond_expr_edges, make_goto_expr_edges): Only set
|
||||||
goto_block on edges if goto_locus is known.
|
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>
|
2008-10-08 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* graphite.c (gloog): Don't call find_unreachable_blocks
|
* 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 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.
|
/* Return the alignment in bits of EXP, a pointer valued expression.
|
||||||
But don't return more than MAX_ALIGN no matter what.
|
But don't return more than MAX_ALIGN no matter what.
|
||||||
The alignment returned is, by default, the alignment of the thing that
|
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:
|
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. */
|
||||||
exp = TREE_OPERAND (exp, 0);
|
return get_object_alignment (TREE_OPERAND (exp, 0), align, max_align);
|
||||||
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);
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return align;
|
return align;
|
||||||
|
|
|
||||||
|
|
@ -1564,6 +1564,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
|
||||||
if (! TYPE_P (t))
|
if (! TYPE_P (t))
|
||||||
{
|
{
|
||||||
tree base;
|
tree base;
|
||||||
|
bool align_computed = false;
|
||||||
|
|
||||||
if (TREE_THIS_VOLATILE (t))
|
if (TREE_THIS_VOLATILE (t))
|
||||||
MEM_VOLATILE_P (ref) = 1;
|
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)
|
&& host_integerp (DECL_SIZE_UNIT (t), 1)
|
||||||
? GEN_INT (tree_low_cst (DECL_SIZE_UNIT (t), 1)) : 0);
|
? GEN_INT (tree_low_cst (DECL_SIZE_UNIT (t), 1)) : 0);
|
||||||
align = DECL_ALIGN (t);
|
align = DECL_ALIGN (t);
|
||||||
|
align_computed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is a constant, we know the alignment. */
|
/* 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
|
#ifdef CONSTANT_ALIGNMENT
|
||||||
align = CONSTANT_ALIGNMENT (t, align);
|
align = CONSTANT_ALIGNMENT (t, align);
|
||||||
#endif
|
#endif
|
||||||
|
align_computed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is a field reference and not a bit-field, record it. */
|
/* 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);
|
align = DECL_ALIGN (t2);
|
||||||
if (aoff && (unsigned HOST_WIDE_INT) aoff < align)
|
if (aoff && (unsigned HOST_WIDE_INT) aoff < align)
|
||||||
align = aoff;
|
align = aoff;
|
||||||
|
align_computed = true;
|
||||||
offset = GEN_INT (ioff);
|
offset = GEN_INT (ioff);
|
||||||
apply_bitpos = bitpos;
|
apply_bitpos = bitpos;
|
||||||
}
|
}
|
||||||
|
|
@ -1721,6 +1725,13 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
|
||||||
expr = t;
|
expr = t;
|
||||||
offset = NULL;
|
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
|
/* 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 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 int get_pointer_alignment (tree, unsigned int);
|
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 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);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue