[llvm-commits] [llvm-gcc-4.2] r47743 - in /llvm-gcc-4.2/trunk/gcc: config/i386/llvm-i386-target.h llvm-abi.h
Dale Johannesen
dalej at apple.com
Thu Feb 28 17:42:19 PST 2008
Author: johannes
Date: Thu Feb 28 19:42:19 2008
New Revision: 47743
URL: http://llvm.org/viewvc/llvm-project?rev=47743&view=rev
Log:
Compensate for an Undocumented Feature of darwin
x86-32: a struct with a single data field and an
arbitrary number of zero-length fields is returned
as if it were the type of the single data field.
This is not correct for ppc32, so I've added a
target hook. I don't know if it's correct for Linux
x86-32, but this is not an area where we've made
darwin-specific modifications, so I'm guessing it is.
Modified:
llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h
llvm-gcc-4.2/trunk/gcc/llvm-abi.h
Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h?rev=47743&r1=47742&r2=47743&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h Thu Feb 28 19:42:19 2008
@@ -91,6 +91,13 @@
(TARGET_64BIT ? 0 : \
TARGET_SSE && contains_128bit_aligned_vector_p(T) ? 16 : 4)
+/* Structs containing a single data field plus zero-length fields are
+ considered as if they were the type of the data field. */
+#ifndef LLVM_SHOULD_RETURN_STRUCT_AS_SCALAR
+#define LLVM_SHOULD_RETURN_STRUCT_AS_SCALAR(X) \
+ isSingleElementStructOrArray(X, true, false)
+#endif
+
extern bool llvm_x86_should_pass_aggregate_in_memory(tree, const Type *);
#define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X, TY) \
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=47743&r1=47742&r2=47743&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Thu Feb 28 19:42:19 2008
@@ -87,9 +87,12 @@
/// isSingleElementStructOrArray - If this is (recursively) a structure with one
/// field or an array with one element, return the field type, otherwise return
-/// null. If rejectFatBitField, and the single element is a bitfield of a type
-/// that's bigger than the struct, return null anyway.
-static tree isSingleElementStructOrArray(tree type, bool rejectFatBitfield) {
+/// null. If ignoreZeroLength, the struct (recursively) may include zero-length
+/// fields in addition to the single element that has data. If
+/// rejectFatBitField, and the single element is a bitfield of a type that's
+/// bigger than the struct, return null anyway.
+static tree isSingleElementStructOrArray(tree type, bool ignoreZeroLength,
+ bool rejectFatBitfield) {
// Scalars are good.
if (!isAggregateTreeType(type)) return type;
@@ -107,6 +110,11 @@
for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field))
if (TREE_CODE(Field) == FIELD_DECL) {
+ if (ignoreZeroLength) {
+ if (TREE_CODE(DECL_SIZE(Field)) == INTEGER_CST &&
+ TREE_INT_CST_LOW(DECL_SIZE(Field)) == 0)
+ continue;
+ }
if (!FoundField) {
if (rejectFatBitfield &&
TREE_CODE(TYPE_SIZE(type)) == INTEGER_CST &&
@@ -114,15 +122,18 @@
TREE_INT_CST_LOW(TYPE_SIZE(type)))
return 0;
FoundField = getDeclaredType(Field);
- } else
+ } else {
return 0; // More than one field.
+ }
}
- return FoundField ? isSingleElementStructOrArray(FoundField, false) : 0;
+ return FoundField ? isSingleElementStructOrArray(FoundField,
+ ignoreZeroLength, false)
+ : 0;
case ARRAY_TYPE:
const ArrayType *Ty = dyn_cast<ArrayType>(ConvertType(type));
if (!Ty || Ty->getNumElements() != 1)
return 0;
- return isSingleElementStructOrArray(TREE_TYPE(type), false);
+ return isSingleElementStructOrArray(TREE_TYPE(type), false, false);
}
}
@@ -171,7 +182,14 @@
// for field-by-field struct passing does not handle this one right.
#ifndef LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS
#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X) \
- !isSingleElementStructOrArray(X, true)
+ !isSingleElementStructOrArray(X, false, true)
+#endif
+
+// LLVM_SHOULD_RETURN_STRUCT_AS_SCALAR - Return a TYPE tree if this struct
+// should be returned using the convention for that scalar TYPE, 0 otherwise.
+#ifndef LLVM_SHOULD_RETURN_STRUCT_AS_SCALAR
+#define LLVM_SHOULD_RETURN_STRUCT_AS_SCALAR(X) \
+ isSingleElementStructOrArray(X, false, false)
#endif
/// DefaultABI - This class implements the default LLVM ABI where structures are
@@ -201,7 +219,7 @@
// FIXME: this is a hack around returning 'complex double' by-val
// which returns in r3/r4/r5/r6 on PowerPC.
TREE_INT_CST_LOW(TYPE_SIZE_UNIT(type)) <= 8) {
- if (tree SingleElt = isSingleElementStructOrArray(type, false)) {
+ if (tree SingleElt = LLVM_SHOULD_RETURN_STRUCT_AS_SCALAR(type)) {
C.HandleAggregateResultAsScalar(ConvertType(SingleElt));
} else {
// Otherwise return as an integer value large enough to hold the entire
More information about the llvm-commits
mailing list