[llvm-commits] [llvm-gcc-4.2] r42243 - in /llvm-gcc-4.2/trunk/gcc: llvm-abi.h llvm-convert.cpp llvm-internal.h llvm-types.cpp
Duncan Sands
baldrick at free.fr
Sun Sep 23 01:02:12 PDT 2007
Author: baldrick
Date: Sun Sep 23 03:02:11 2007
New Revision: 42243
URL: http://llvm.org/viewvc/llvm-project?rev=42243&view=rev
Log:
Remove arrayLength, which calculated the length of
a possibly variable-sized array type as a gcc tree.
The problem is that we determine whether an array
type corresponds to an LLVM array (essentially
whether it is of constant length) using TYPE_SIZE,
but calculate the length from the difference between
the upper and lower bounds using arrayLength. The
implicit assumption in this is that arrayLength will
return a constant if TYPE_SIZE is constant. This
worked fine in llvm-gcc-4.0, but 4.2 does TYPE_SIZE
optimizations and sometimes reduces it to a constant
in cases where fold cannot deduce that the upper and
lower array bounds differ by a constant, leading to
a bunch of compile failures in the Ada testsuite.
Instead, deduce the array length from TYPE_SIZE. The
only downside to this is that a fixed-length array of
zero-sized elements now always maps to a zero-length
LLVM array, but I think this is acceptable. Also,
fix a bug in which DECL_SIZE was being ignored for
variable length arrays allocated on the stack.
Modified:
llvm-gcc-4.2/trunk/gcc/llvm-abi.h
llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
llvm-gcc-4.2/trunk/gcc/llvm-internal.h
llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
Modified: llvm-gcc-4.2/trunk/gcc/llvm-abi.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-abi.h?rev=42243&r1=42242&r2=42243&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Sun Sep 23 03:02:11 2007
@@ -110,10 +110,8 @@
}
return FoundField ? isSingleElementStructOrArray(FoundField) : 0;
case ARRAY_TYPE:
- if (!isArrayCompatible(type))
- return 0;
- tree length = arrayLength(type);
- if (!length || !integer_onep(length))
+ const ArrayType *Ty = dyn_cast<ArrayType>(ConvertType(type));
+ if (!Ty || Ty->getNumElements() != 1)
return 0;
return isSingleElementStructOrArray(TREE_TYPE(type));
}
Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=42243&r1=42242&r2=42243&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Sun Sep 23 03:02:11 2007
@@ -1510,15 +1510,17 @@
DECL_USER_ALIGN(decl) = 0;
Alignment = DECL_ALIGN(decl)/8;
} else {
- tree length;
-
// Dynamic-size object: must push space on the stack.
- if (TREE_CODE(type) == ARRAY_TYPE &&
- isSequentialCompatible(type) &&
- (length = arrayLength(type))) {
+ if (TREE_CODE(type) == ARRAY_TYPE
+ && isSequentialCompatible(type)
+ && TYPE_SIZE(type) == DECL_SIZE(decl)) {
Ty = ConvertType(TREE_TYPE(type)); // Get array element type.
// Compute the number of elements in the array.
- Size = Emit(length, 0);
+ Size = Emit(DECL_SIZE(decl), 0);
+ assert(!integer_zerop(TYPE_SIZE(TREE_TYPE(type)))
+ && "Array of positive size with elements of zero size!");
+ Value *EltSize = Emit(TYPE_SIZE(TREE_TYPE(type)), 0);
+ Size = Builder.CreateUDiv(Size, EltSize, "len");
} else {
// Compute the variable's size in bytes.
Size = Emit(DECL_SIZE_UNIT(decl), 0);
Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=42243&r1=42242&r2=42243&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Sun Sep 23 03:02:11 2007
@@ -213,10 +213,6 @@
/// corresponds to an LLVM array type.
bool isArrayCompatible(tree_node *type);
-/// arrayLength - Return a tree expressing the number of elements in an array
-/// of the specified type, or NULL if the type does not specify the length.
-tree_node *arrayLength(tree_node *type);
-
/// ValidateRegisterVariable - Check that a static "asm" variable is
/// well-formed. If not, emit error messages and return true. If so, return
/// false.
Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=42243&r1=42242&r2=42243&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Sun Sep 23 03:02:11 2007
@@ -299,9 +299,9 @@
/// type and the corresponding LLVM SequentialType lay out their components
/// identically in memory.
bool isSequentialCompatible(tree_node *type) {
- assert((TREE_CODE (type) == ARRAY_TYPE ||
- TREE_CODE (type) == POINTER_TYPE ||
- TREE_CODE (type) == REFERENCE_TYPE) && "not a sequential type!");
+ assert((TREE_CODE(type) == ARRAY_TYPE ||
+ TREE_CODE(type) == POINTER_TYPE ||
+ TREE_CODE(type) == REFERENCE_TYPE) && "not a sequential type!");
// This relies on gcc types with constant size mapping to LLVM types with the
// same size.
return isInt64(TYPE_SIZE(TREE_TYPE(type)), true);
@@ -310,13 +310,13 @@
/// isArrayCompatible - Return true if the specified gcc array or pointer type
/// corresponds to an LLVM array type.
bool isArrayCompatible(tree_node *type) {
- assert((TREE_CODE (type) == ARRAY_TYPE ||
- TREE_CODE (type) == POINTER_TYPE ||
- TREE_CODE (type) == REFERENCE_TYPE) && "not a sequential type!");
+ assert((TREE_CODE(type) == ARRAY_TYPE ||
+ TREE_CODE(type) == POINTER_TYPE ||
+ TREE_CODE(type) == REFERENCE_TYPE) && "not a sequential type!");
return
- (TREE_CODE (type) == ARRAY_TYPE) && (
+ (TREE_CODE(type) == ARRAY_TYPE) && (
// Arrays with no size are fine as long as their components are layed out
- // the same way in memory by LLVM. For example "int X[]" -> "[0 x int]".
+ // the same way in memory by LLVM. For example 'int X[]' -> '[0 x i32]'.
(!TYPE_SIZE(type) && isSequentialCompatible(type)) ||
// Arrays with constant size map to LLVM arrays. If the array has zero
@@ -328,21 +328,6 @@
);
}
-/// arrayLength - Return a tree expressing the number of elements in an array
-/// of the specified type, or NULL if the type does not specify the length.
-tree_node *arrayLength(tree_node *type) {
- tree Domain = TYPE_DOMAIN(type);
-
- if (!Domain || !TYPE_MAX_VALUE(Domain))
- return NULL;
-
- tree length = fold_convert(sizetype, TYPE_MAX_VALUE(Domain));
- if (TYPE_MIN_VALUE(Domain))
- length = size_binop (MINUS_EXPR, length,
- fold_convert(sizetype, TYPE_MIN_VALUE(Domain)));
- return size_binop (PLUS_EXPR, length, size_one_node);
-}
-
/// refine_type_to - Cause all users of the opaque type old_type to switch
/// to the more concrete type new_type.
void refine_type_to(tree old_type, tree new_type)
@@ -579,7 +564,7 @@
case ARRAY_TYPE: {
unsigned EltSizeBits = TREE_INT_CST_LOW(TYPE_SIZE(TREE_TYPE(type)));
- unsigned NumElts = getInt64(arrayLength(type), true);
+ unsigned NumElts = cast<ArrayType>(ConvertType(type))->getNumElements();
unsigned OverlapElt = (unsigned)PadStartBits/EltSizeBits;
// Check each element for overlap. This is inelegant, but effective.
@@ -849,25 +834,32 @@
if (isArrayCompatible(type)) {
uint64_t NumElements;
- tree length = arrayLength(type);
- if (!length) {
- // We get here if we have something that is globally declared as an
- // array with no dimension, this becomes just a zero size array of the
- // element type so that: int X[] becomes '%X = external global [0x i32]'
+ if (!TYPE_SIZE(type)) {
+ // We get here if we have something that is declared to be an array with
+ // no dimension. This just becomes a zero length array of the element
+ // type, so 'int X[]' becomes '%X = external global [0 x i32]'.
//
- // Note that this also affects new expressions, which return a pointer
+ // Note that this also affects new expressions, which return a pointer
// to an unsized array of elements.
NumElements = 0;
- } else if (!isInt64(length, true)) {
- // A variable length array where the element type has size zero. Turn
- // it into a zero length array of the element type.
- assert(integer_zerop(TYPE_SIZE(TREE_TYPE(type)))
- && "variable length array has constant size!");
+ } else if (integer_zerop(TYPE_SIZE(type))) {
+ // An array of zero length, or with an element type of zero size.
+ // Turn it into a zero length array of the element type.
NumElements = 0;
} else {
- // Normal array.
- NumElements = getInt64(length, true);
+ // Normal constant-size array.
+ NumElements = getInt64(TYPE_SIZE(type), true);
+
+ assert(isInt64(TYPE_SIZE(TREE_TYPE(type)), true)
+ && "Array of constant size with elements of variable size!");
+ uint64_t ElementSize = getInt64(TYPE_SIZE(TREE_TYPE(type)), true);
+ assert(ElementSize
+ && "Array of positive size with elements of zero size!");
+ assert(!(NumElements % ElementSize)
+ && "Array size is not a multiple of the element size!");
+
+ NumElements /= ElementSize;
}
return TypeDB.setType(type, ArrayType::get(ConvertType(TREE_TYPE(type)),
More information about the llvm-commits
mailing list