[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