aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/utils2.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2008-06-24 18:15:36 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2008-06-24 18:15:36 +0000
commit324ed5a676f020e3bd4b37f40028025d1e915bbf (patch)
tree1f4c859fa21f77b99e36f9bd2885a7fe48b8f631 /gcc/ada/utils2.c
parenta057a4f13b2599c7fa19bf08b9617b6b3f67d2d7 (diff)
downloadgcc-324ed5a676f020e3bd4b37f40028025d1e915bbf.zip
gcc-324ed5a676f020e3bd4b37f40028025d1e915bbf.tar.gz
gcc-324ed5a676f020e3bd4b37f40028025d1e915bbf.tar.bz2
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
Diffstat (limited to 'gcc/ada/utils2.c')
-rw-r--r--gcc/ada/utils2.c61
1 files changed, 32 insertions, 29 deletions
diff --git a/gcc/ada/utils2.c b/gcc/ada/utils2.c
index 891463c..300fbd3 100644
--- a/gcc/ada/utils2.c
+++ b/gcc/ada/utils2.c
@@ -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:
- /* 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);
+ {
+ unsigned HOST_WIDE_INT c = TREE_INT_CST_LOW (exp);
+ /* The first part of this represents the lowest bit in the constant,
+ 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:
- this_alignment = 0;
+ /* 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