[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