[llvm-commits] [llvm-gcc-4.2] r65770 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h llvm-types.cpp

Duncan Sands baldrick at free.fr
Sun Mar 1 07:01:22 PST 2009


Author: baldrick
Date: Sun Mar  1 09:01:21 2009
New Revision: 65770

URL: http://llvm.org/viewvc/llvm-project?rev=65770&view=rev
Log:
Now that gcc array types are always converted to
an LLVM array, there is no longer any need for
isArrayCompatible.  The new equivalent is that the
TREE_CODE is ARRAY_TYPE and that the type passes
isSequentialCompatible.  Simplify some code using
this.  Also, handle the case when an array type
has an element type with variable size, but the
array itself has constant size.  This is in theory
possible, but I couldn't construct an Ada example.

Modified:
    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-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=65770&r1=65769&r2=65770&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Sun Mar  1 09:01:21 2009
@@ -5834,24 +5834,15 @@
     // SExt it to retain its value in the larger type
     IndexVal = CastToSIntType(IndexVal, IntPtrTy);
 
-  // If this is an index into an LLVM array, codegen as a GEP.
-  if (isArrayCompatible(ArrayTreeType)) {
-    Value *Idxs[2] = { ConstantInt::get(Type::Int32Ty, 0), IndexVal };
-    Value *Ptr = Builder.CreateGEP(ArrayAddr, Idxs, Idxs + 2);
-    const Type *ATy = cast<PointerType>(ArrayAddr->getType())->getElementType();
-    const Type *ElementTy = cast<ArrayType>(ATy)->getElementType();
-    unsigned Alignment = MinAlign(ArrayAlign, TD.getTypePaddedSize(ElementTy));
-    return LValue(BitCastToType(Ptr,
-                           PointerType::getUnqual(ConvertType(TREE_TYPE(exp)))),
-                  Alignment);
-  }
-
   // If we are indexing over a fixed-size type, just use a GEP.
   if (isSequentialCompatible(ArrayTreeType)) {
+    SmallVector<Value*, 2> Idx;
+    if (TREE_CODE(ArrayTreeType) == ARRAY_TYPE)
+      Idx.push_back(ConstantInt::get(IntPtrTy, 0));
+    Idx.push_back(IndexVal);
+    Value *Ptr = Builder.CreateGEP(ArrayAddr, Idx.begin(), Idx.end());
+
     const Type *ElementTy = ConvertType(ElementType);
-    const Type *PtrElementTy = PointerType::getUnqual(ElementTy);
-    ArrayAddr = BitCastToType(ArrayAddr, PtrElementTy);
-    Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal);
     unsigned Alignment = MinAlign(ArrayAlign, TD.getABITypeAlignment(ElementTy));
     return LValue(BitCastToType(Ptr,
                            PointerType::getUnqual(ConvertType(TREE_TYPE(exp)))),
@@ -7202,8 +7193,7 @@
 
   // Check for variable sized reference.
   // FIXME: add support for array types where the size doesn't fit into 64 bits
-  assert((isArrayCompatible(ArrayType) || isSequentialCompatible(ArrayType))
-         && "Cannot have globals with variable size!");
+  assert(isSequentialCompatible(ArrayType) && "Global with variable size?");
 
   // As an LLVM extension, we allow ARRAY_REF with a pointer as the first
   // operand.  This construct maps directly to a getelementptr instruction.
@@ -7226,8 +7216,8 @@
                                         !TYPE_UNSIGNED(IndexType));
 
   std::vector<Value*> Idx;
-  if (isArrayCompatible(ArrayType))
-    Idx.push_back(ConstantInt::get(Type::Int32Ty, 0));
+  if (TREE_CODE (ArrayType) == ARRAY_TYPE)
+    Idx.push_back(ConstantInt::get(IntPtrTy, 0));
   Idx.push_back(IndexVal);
 
   return TheFolder->CreateGetElementPtr(ArrayAddr, &Idx[0], Idx.size());

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=65770&r1=65769&r2=65770&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Sun Mar  1 09:01:21 2009
@@ -213,13 +213,10 @@
 
 /// isSequentialCompatible - Return true if the specified gcc array or pointer
 /// type and the corresponding LLVM SequentialType lay out their components
-/// identically in memory.
+/// identically in memory, so doing a GEP accesses the right memory location.
+/// We assume that objects without a known size do not.
 bool isSequentialCompatible(tree_node *type);
 
-/// isArrayCompatible - Return true if the specified gcc array or pointer type
-/// corresponds to an LLVM array type.
-bool isArrayCompatible(tree_node *type);
-
 /// isBitfield - Returns whether to treat the specified field as a bitfield.
 bool isBitfield(tree_node *field_decl);
 

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=65770&r1=65769&r2=65770&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Sun Mar  1 09:01:21 2009
@@ -298,7 +298,8 @@
 
 /// isSequentialCompatible - Return true if the specified gcc array or pointer
 /// type and the corresponding LLVM SequentialType lay out their components
-/// identically in memory.  We assume that objects without a known size do not.
+/// identically in memory, so doing a GEP accesses the right memory location.
+/// We assume that objects without a known size do not.
 bool isSequentialCompatible(tree_node *type) {
   assert((TREE_CODE(type) == ARRAY_TYPE ||
           TREE_CODE(type) == POINTER_TYPE ||
@@ -311,28 +312,6 @@
          isInt64(TYPE_SIZE(TREE_TYPE(type)), true);
 }
 
-/// 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 ||
-          TREE_CODE(type) == BLOCK_POINTER_TYPE) && "not a sequential type!");
-  return
-    (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 i32]'.
-      (!TYPE_SIZE(type) && isSequentialCompatible(type)) ||
-
-      // Arrays with constant size map to LLVM arrays.  If the array has zero
-      // size then there can be two exotic cases: (1) the array might have zero
-      // length and a component type of variable size; or (2) the array could
-      // have variable length and a component type with zero size.  In both
-      // cases we convert to a zero length LLVM array.
-      (TYPE_SIZE(type) && isInt64(TYPE_SIZE(type), true))
-    );
-}
-
 /// isBitfield - Returns whether to treat the specified field as a bitfield.
 bool isBitfield(tree_node *field_decl) {
   tree type = DECL_BIT_FIELD_TYPE(field_decl);
@@ -872,44 +851,51 @@
     if (const Type *Ty = GET_TYPE_LLVM(type))
       return Ty;
 
-    if (isArrayCompatible(type)) {
-      uint64_t NumElements;
-
-      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
-        // to an unsized array of elements.
-        NumElements = 0;
-      } 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 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)),
-                                                 NumElements));
+    uint64_t ElementSize;
+    const Type *ElementTy;
+    if (isSequentialCompatible(type)) {
+      // The gcc element type maps to an LLVM type of the same size.
+      // Convert to an LLVM array of the converted element type.
+      ElementSize = getInt64(TYPE_SIZE(TREE_TYPE(type)), true);
+      ElementTy = ConvertType(TREE_TYPE(type));
+    } else {
+      // The gcc element type has no size, or has variable size.  Convert to an
+      // LLVM array of bytes.  In the unlikely but theoretically possible case
+      // that the gcc array type has constant size, using an i8 for the element
+      // type ensures we can produce an LLVM array of the right size.
+      ElementSize = 8;
+      ElementTy = Type::Int8Ty;
+    }
+
+    uint64_t NumElements;
+    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
+      // to an unsized array of elements.
+      NumElements = 0;
+    } else if (!isInt64(TYPE_SIZE(type), true)) {
+      // This handles cases like "int A[n]" which have a runtime constant
+      // number of elements, but is a compile-time variable.  Since these
+      // are variable sized, we represent them as [0 x type].
+      NumElements = 0;
+    } 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 constant-size array.
+      assert(ElementSize
+             && "Array of positive size with elements of zero size!");
+      NumElements = getInt64(TYPE_SIZE(type), true);
+      assert(!(NumElements % ElementSize)
+             && "Array size is not a multiple of the element size!");
+      NumElements /= ElementSize;
     }
 
-    // This handles cases like "int A[n]" which have a runtime constant
-    // number of elements, but is a compile-time variable.  Since these
-    // are variable sized, we represent them as A[0].
-    return TypeDB.setType(type, ArrayType::get(ConvertType(TREE_TYPE(type)),0));
+    return TypeDB.setType(type, ArrayType::get(ElementTy, NumElements));
   }
   case OFFSET_TYPE:
     // Handle OFFSET_TYPE specially.  This is used for pointers to members,





More information about the llvm-commits mailing list