[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