[llvm-commits] [124921] Support arrays with non-zero lower bound

dpatel at apple.com dpatel at apple.com
Mon Mar 12 16:07:59 PDT 2007


Revision: 124921
Author:   dpatel
Date:     2007-03-12 16:07:59 -0700 (Mon, 12 Mar 2007)

Log Message:
-----------
Support arrays with non-zero lower bound
Patch by Duncan Sands.

Modified Paths:
--------------
    apple-local/branches/llvm/gcc/llvm-abi.h
    apple-local/branches/llvm/gcc/llvm-convert.cpp
    apple-local/branches/llvm/gcc/llvm-internal.h
    apple-local/branches/llvm/gcc/llvm-types.cpp

Modified: apple-local/branches/llvm/gcc/llvm-abi.h
===================================================================
--- apple-local/branches/llvm/gcc/llvm-abi.h	2007-03-12 22:37:51 UTC (rev 124920)
+++ apple-local/branches/llvm/gcc/llvm-abi.h	2007-03-12 23:07:59 UTC (rev 124921)
@@ -110,16 +110,11 @@
       }
     return FoundField ? isSingleElementStructOrArray(FoundField) : 0;
   case ARRAY_TYPE:
-    tree Domain = TYPE_DOMAIN(type);
-    if (!Domain || !TYPE_MIN_VALUE(Domain) || !TYPE_MAX_VALUE(Domain))
+    if (TREE_CODE(TYPE_SIZE(type)) != INTEGER_CST)
       return 0;
-    if (TREE_CODE(TYPE_SIZE(type)) != INTEGER_CST ||
-        TREE_CODE(TYPE_MIN_VALUE(Domain)) != INTEGER_CST ||
-        TREE_CODE(TYPE_MAX_VALUE(Domain)) != INTEGER_CST)
+    tree length = arrayLength(type);
+    if (!length || !integer_onep(length))
       return 0;
-    if (TREE_INT_CST_LOW(TYPE_MAX_VALUE(Domain)) !=
-        TREE_INT_CST_LOW(TYPE_MIN_VALUE(Domain)))
-      return 0;
     return isSingleElementStructOrArray(TREE_TYPE(type));
   }
 }

Modified: apple-local/branches/llvm/gcc/llvm-convert.cpp
===================================================================
--- apple-local/branches/llvm/gcc/llvm-convert.cpp	2007-03-12 22:37:51 UTC (rev 124920)
+++ apple-local/branches/llvm/gcc/llvm-convert.cpp	2007-03-12 23:07:59 UTC (rev 124921)
@@ -1353,18 +1353,14 @@
     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 && TYPE_DOMAIN(type)) {
+    if (TREE_CODE(type) == ARRAY_TYPE && (length = arrayLength(type))) {
       Ty = ConvertType(TREE_TYPE(type));  // Get array element type.
-      // Compute the size of the number of elements of the array.
-      Size = Emit(TYPE_MAX_VALUE(TYPE_DOMAIN(type)), 0);
-      Size = CastToUIntType(Size, Type::Int32Ty);
-      
-      // Annoyingly, TYPE_MAX_VALUE returns the maximum valid index, NOT the
-      // number of elements in the array.  Thus, we must add one to the returned
-      // value.  This addition should be optimized out later.
-      Size = BinaryOperator::createAdd(Size, ConstantInt::get(Type::Int32Ty, 1),
-                                       "tmp", CurBB);
+      // Compute the number of elements in the array.
+      Size = Emit(length, 0);
+      Size = CastToUIntType(Size, Size->getType());
     } else {
       // Compute the variable's size in bytes.
       Size = CastToUIntType(Emit(DECL_SIZE_UNIT(decl), 0), Type::Int32Ty);
@@ -4538,9 +4534,8 @@
   // If this is an index into an array, codegen as a GEP.
   if (TREE_CODE(TREE_TYPE(Array)) == ARRAY_TYPE) {
     // Check for variable sized array reference.
-    tree Domain = TYPE_DOMAIN(TREE_TYPE(Array));
-    if (Domain && TYPE_MAX_VALUE(Domain) &&
-        TREE_CODE(TYPE_MAX_VALUE(Domain)) != INTEGER_CST) {
+    tree length = arrayLength(TREE_TYPE(Array));
+    if (length && !host_integerp(length, 1)) {
       // Make sure that ArrayAddr is of type ElementTy*, then do a 2-index gep.
       tree ElTy = TREE_TYPE(TREE_TYPE(Array));
       ArrayAddr = BitCastToType(ArrayAddr, PointerType::get(Type::Int8Ty));
@@ -5003,7 +4998,7 @@
     // If this is a variable sized array type, set the length to Len.
     if (ConstantSize == 0) {
       tree Domain = TYPE_DOMAIN(TREE_TYPE(exp));
-      if (Domain == 0 || TYPE_MAX_VALUE(Domain) == 0) {
+      if (!Domain || !TYPE_MAX_VALUE(Domain)) {
         ConstantSize = Len;
         StrTy = ArrayType::get(ElTy, Len);
       }
@@ -5102,21 +5097,23 @@
   // type indirectly.
   assert(TREE_CODE(TREE_TYPE(exp)) != VECTOR_TYPE &&
          "VECTOR_TYPE's haven't been tested!");
-  
-  // If we have constant lower bound for the range of the type, get it.  */
+
+  // If we have a lower bound for the range of the type, get it.  */
   tree Domain = TYPE_DOMAIN(TREE_TYPE(exp));
-  unsigned MinElement = 0;
-  if (Domain && TYPE_MIN_VALUE(Domain) && 
-      host_integerp(TYPE_MIN_VALUE(Domain), 0))
-    MinElement = tree_low_cst(TYPE_MIN_VALUE(Domain), 0);
-  
+  tree min_element = size_zero_node;
+  if (Domain && TYPE_MIN_VALUE(Domain))
+    min_element = fold_convert(sizetype, TYPE_MIN_VALUE(Domain));
+
   std::vector<Constant*> ResultElts;
   Constant *SomeVal = 0;
   
-  if (Domain && TYPE_MAX_VALUE(Domain) && 
-      host_integerp(TYPE_MAX_VALUE(Domain), 0)) {
-    unsigned MaxElement = tree_low_cst(TYPE_MAX_VALUE(Domain), 0);
-    ResultElts.resize(MaxElement-MinElement+1);
+  if (Domain && TYPE_MAX_VALUE(Domain)) {
+    tree max_element = fold_convert(sizetype, TYPE_MAX_VALUE(Domain));
+    tree size = size_binop (MINUS_EXPR, max_element, min_element);
+    size = size_binop (PLUS_EXPR, size, size_one_node);
+
+    if (host_integerp(size, 1))
+      ResultElts.resize(tree_low_cst(size, 1));
   }
 
   unsigned NextFieldToFill = 0;
@@ -5132,14 +5129,21 @@
     // The first and last field to fill in, inclusive.
     unsigned FieldOffset, FieldLastOffset;
     if (index && TREE_CODE(index) == RANGE_EXPR) {
-      assert(TREE_CODE(TREE_OPERAND(index, 0)) == INTEGER_CST &&
-             TREE_CODE(TREE_OPERAND(index, 1)) == INTEGER_CST &&
+      tree first = fold_convert (sizetype, TREE_OPERAND(index, 0));
+      tree last  = fold_convert (sizetype, TREE_OPERAND(index, 1));
+
+      first = size_binop (MINUS_EXPR, first, min_element);
+      last  = size_binop (MINUS_EXPR, last, min_element);
+
+      assert(host_integerp(first, 1) && host_integerp(last, 1) &&
              "Unknown range_expr!");
-      FieldOffset     = TREE_INT_CST_LOW(TREE_OPERAND(index, 0))-MinElement;
-      FieldLastOffset = TREE_INT_CST_LOW(TREE_OPERAND(index, 1))-MinElement;
+      FieldOffset     = tree_low_cst(first, 1);
+      FieldLastOffset = tree_low_cst(last, 1);
     } else if (index) {
-      assert(TREE_CODE(index) == INTEGER_CST && TREE_INT_CST_HIGH(index) == 0);
-      FieldOffset = TREE_INT_CST_LOW(index)-MinElement;
+      index = size_binop (MINUS_EXPR, fold_convert (sizetype, index),
+                          min_element);
+      assert(host_integerp(index, 1));
+      FieldOffset = tree_low_cst(index, 1);
       FieldLastOffset = FieldOffset;
     } else {
       FieldOffset = NextFieldToFill;
@@ -5649,11 +5653,9 @@
   
   // Check for variable sized array reference.
   if (TREE_CODE(TREE_TYPE(Array)) == ARRAY_TYPE) {
-    tree Domain = TYPE_DOMAIN(TREE_TYPE(Array));
-    if (Domain && TYPE_MAX_VALUE(Domain)) {
-      assert(TREE_CODE(TYPE_MAX_VALUE(Domain)) == INTEGER_CST &&
-             "Cannot have globals with variable size!");
-    }
+    tree length = arrayLength(TREE_TYPE(Array));
+    assert(!length || host_integerp(length, 1) &&
+           "Cannot have globals with variable size!");
   }
 
   std::vector<Value*> Idx;

Modified: apple-local/branches/llvm/gcc/llvm-internal.h
===================================================================
--- apple-local/branches/llvm/gcc/llvm-internal.h	2007-03-12 22:37:51 UTC (rev 124920)
+++ apple-local/branches/llvm/gcc/llvm-internal.h	2007-03-12 23:07:59 UTC (rev 124921)
@@ -148,6 +148,10 @@
 /// thing by value, pass the address of a temporary.
 bool isPassedByInvisibleReference(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: apple-local/branches/llvm/gcc/llvm-types.cpp
===================================================================
--- apple-local/branches/llvm/gcc/llvm-types.cpp	2007-03-12 22:37:51 UTC (rev 124920)
+++ apple-local/branches/llvm/gcc/llvm-types.cpp	2007-03-12 23:07:59 UTC (rev 124921)
@@ -269,7 +269,22 @@
   return Prefix + ContextStr + Name;
 }
 
+/// 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);
+}
+
+
 //===----------------------------------------------------------------------===//
 //                     Abstract Type Refinement Helpers
 //===----------------------------------------------------------------------===//
@@ -566,11 +581,11 @@
       return Ty;
 
     unsigned NumElements;
-    tree Domain = TYPE_DOMAIN(type);
-    if (Domain && TYPE_MAX_VALUE(Domain)) {
-      if (TREE_CODE(TYPE_MAX_VALUE(Domain)) == INTEGER_CST) {
+    tree length = arrayLength(type);
+    if (length) {
+      if (host_integerp(length, 1)) {
         // Normal array.
-        NumElements = TREE_INT_CST_LOW(TYPE_MAX_VALUE(Domain))+1;
+        NumElements = tree_low_cst(length, 1);
       } else {
         // This handles cases like "int A[n]" which have a runtime constant
         // number of elements, but is a compile-time variable.  Since these are





More information about the llvm-commits mailing list