utils2.c (known_alignment): Derive the alignment from pointed-to types only if it is otherwise unknown.

* utils2.c (known_alignment): Derive the alignment from pointed-to
	types only if it is otherwise unknown.
	<INTEGER_CST>: Tidy.
	<MULT_EXPR>: Likewise.
	<POINTER_PLUS_EXPR>: If the alignment of the offset is unknown, use
	that of the base.

From-SVN: r137081
This commit is contained in:
Eric Botcazou 2008-06-24 18:15:36 +00:00 committed by Eric Botcazou
parent a057a4f13b
commit 324ed5a676
4 changed files with 79 additions and 29 deletions

View File

@ -1,3 +1,12 @@
2008-06-24 Eric Botcazou <ebotcazou@adacore.com>
* utils2.c (known_alignment): Derive the alignment from pointed-to
types only if it is otherwise unknown.
<INTEGER_CST>: Tidy.
<MULT_EXPR>: Likewise.
<POINTER_PLUS_EXPR>: If the alignment of the offset is unknown, use
that of the base.
2008-06-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR ada/36573

View File

@ -136,23 +136,6 @@ known_alignment (tree exp)
{
unsigned int this_alignment;
unsigned int lhs, rhs;
unsigned int type_alignment;
/* For pointer expressions, we know that the designated object is always at
least as strictly aligned as the designated subtype, so we account for
both type and expression information in this case.
Beware that we can still get a dummy designated subtype here (e.g. Taft
Amendment types), in which the alignment information is meaningless and
should be ignored.
We always compute a type_alignment value and return the MAX of it
compared with what we get from the expression tree. Just set the
type_alignment value to 0 when the type information is to be ignored. */
type_alignment
= ((POINTER_TYPE_P (TREE_TYPE (exp))
&& !TYPE_IS_DUMMY_P (TREE_TYPE (TREE_TYPE (exp))))
? TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp))) : 0);
switch (TREE_CODE (exp))
{
@ -170,7 +153,6 @@ known_alignment (tree exp)
break;
case PLUS_EXPR:
case POINTER_PLUS_EXPR:
case MINUS_EXPR:
/* If two address are added, the alignment of the result is the
minimum of the two alignments. */
@ -179,6 +161,17 @@ known_alignment (tree exp)
this_alignment = MIN (lhs, rhs);
break;
case POINTER_PLUS_EXPR:
lhs = known_alignment (TREE_OPERAND (exp, 0));
rhs = known_alignment (TREE_OPERAND (exp, 1));
/* If we don't know the alignment of the offset, we assume that
of the base. */
if (rhs == 0)
this_alignment = lhs;
else
this_alignment = MIN (lhs, rhs);
break;
case COND_EXPR:
/* If there is a choice between two values, use the smallest one. */
lhs = known_alignment (TREE_OPERAND (exp, 1));
@ -187,12 +180,12 @@ known_alignment (tree exp)
break;
case INTEGER_CST:
{
unsigned HOST_WIDE_INT c = TREE_INT_CST_LOW (exp);
/* The first part of this represents the lowest bit in the constant,
but is it in bytes, not bits. */
this_alignment
= MIN (BITS_PER_UNIT
* (TREE_INT_CST_LOW (exp) & - TREE_INT_CST_LOW (exp)),
BIGGEST_ALIGNMENT);
but it is originally in bytes, not bits. */
this_alignment = MIN (BITS_PER_UNIT * (c & -c), BIGGEST_ALIGNMENT);
}
break;
case MULT_EXPR:
@ -201,10 +194,12 @@ known_alignment (tree exp)
lhs = known_alignment (TREE_OPERAND (exp, 0));
rhs = known_alignment (TREE_OPERAND (exp, 1));
if (lhs == 0 || rhs == 0)
this_alignment = MIN (BIGGEST_ALIGNMENT, MAX (lhs, rhs));
if (lhs == 0)
this_alignment = rhs;
else if (rhs == 0)
this_alignment = lhs;
else
this_alignment = MIN (BIGGEST_ALIGNMENT, lhs * rhs);
this_alignment = MIN (lhs * rhs, BIGGEST_ALIGNMENT);
break;
case BIT_AND_EXPR:
@ -220,11 +215,19 @@ known_alignment (tree exp)
break;
default:
/* For other pointer expressions, we assume that the pointed-to object
is at least as aligned as the pointed-to type. Beware that we can
have a dummy type here (e.g. a Taft Amendment type), for which the
alignment is meaningless and should be ignored. */
if (POINTER_TYPE_P (TREE_TYPE (exp))
&& !TYPE_IS_DUMMY_P (TREE_TYPE (TREE_TYPE (exp))))
this_alignment = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
else
this_alignment = 0;
break;
}
return MAX (type_alignment, this_alignment);
return this_alignment;
}
/* We have a comparison or assignment operation on two types, T1 and T2, which

View File

@ -1,3 +1,7 @@
2008-06-24 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/warn5.adb: New test.
2008-06-24 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/36504

View File

@ -0,0 +1,34 @@
-- { dg-do compile }
with System;
with Unchecked_Conversion;
procedure Warn5 is
type Digit_Type is range 0..15;
type Frequency_Type is array( 1..12) of Digit_Type;
pragma Pack(Frequency_Type);
type Element_Type is record
F : Frequency_Type;
end record;
type Array_Type is array (Natural range <>) of Element_Type;
type List_Type is record
A : Array_Type (0..1);
end record;
for List_Type'Alignment use 4;
type Pointer_Type is access Element_Type;
function To_Ptr is new Unchecked_Conversion(System.Address, Pointer_Type);
function Pointer (Pos : Natural; List : List_Type) return Pointer_Type is
begin
return To_Ptr(List.A(Pos)'Address); -- { dg-warning "source alignment" "" { target alpha*-*-* hppa*-*-* ia64-*-* mips*-*-* sparc*-*-* } }
end;
begin
null;
end;