diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2008-06-24 18:15:36 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2008-06-24 18:15:36 +0000 |
commit | 324ed5a676f020e3bd4b37f40028025d1e915bbf (patch) | |
tree | 1f4c859fa21f77b99e36f9bd2885a7fe48b8f631 /gcc/ada/utils2.c | |
parent | a057a4f13b2599c7fa19bf08b9617b6b3f67d2d7 (diff) | |
download | gcc-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.c | 61 |
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 |