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 _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits