[llvm-commits] [llvm-gcc-4.2] r52192 - in /llvm-gcc-4.2/trunk/gcc: config/i386/llvm-i386.cpp llvm-abi.h

Dale Johannesen dalej at apple.com
Tue Jun 10 18:13:03 PDT 2008


Author: johannes
Date: Tue Jun 10 20:13:02 2008
New Revision: 52192

URL: http://llvm.org/viewvc/llvm-project?rev=52192&view=rev
Log:
X86-64 ABI compatibility.  Words consisting only of
padding can occur in the middle of structs as well as
at the end; handle this with the MixedRegisters mechanism.
Some unions are passed in memory even though they are
converted to a struct consisting only of ints; the
special case looking for the latter is removed.
All compat and struct-layout-1 tests now pass, comparing
llvm-gcc against itself.


Modified:
    llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-abi.h

Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp?rev=52192&r1=52191&r2=52192&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp Tue Jun 10 20:13:02 2008
@@ -629,13 +629,6 @@
   if (Bytes == 0)
     return false;
 
-  if (TARGET_64BIT &&
-      (Bytes == GET_MODE_SIZE(SImode) || Bytes == GET_MODE_SIZE(DImode))) {
-    // 32-bit or 64-bit and all elements are integers, not passed in memory.
-    const Type *Ty = ConvertType(TreeType);
-    if (llvm_x86_is_all_integer_types(Ty))
-      return false;
-  }
   if (!TARGET_64BIT) {
     std::vector<const Type*> Elts;
     return !llvm_x86_32_should_pass_aggregate_in_mixed_regs(TreeType, Ty, Elts);
@@ -662,6 +655,9 @@
         ++NumXMMs;
     } else if (Ty->isInteger() || isa<PointerType>(Ty)) {
       ++NumGPRs;
+    } else if (Ty==Type::VoidTy) {
+      // Padding bytes that are not passed anywhere
+      ;
     } else {
       // Floating point scalar argument.
       assert(Ty->isFloatingPoint() && Ty->isPrimitiveType() &&
@@ -728,6 +724,7 @@
                                                 std::vector<const Type*> &Elts){
   enum x86_64_reg_class Class[MAX_CLASSES];
   enum machine_mode Mode = ix86_getNaturalModeForType(TreeType);
+  bool totallyEmpty = true;
   HOST_WIDE_INT Bytes =
     (Mode == BLKmode) ? int_size_in_bytes(TreeType) : (int) GET_MODE_SIZE(Mode);
   int NumClasses = ix86_ClassifyArgument(Mode, TreeType, Class, 0);
@@ -743,9 +740,11 @@
     case X86_64_INTEGER_CLASS:
     case X86_64_INTEGERSI_CLASS:
       Elts.push_back(Type::Int64Ty);
+      totallyEmpty = false;
       Bytes -= 8;
       break;
     case X86_64_SSE_CLASS:
+      totallyEmpty = false;
       // If it's a SSE class argument, then one of the followings are possible:
       // 1. 1 x SSE, size is 8: 1 x Double.
       // 2. 1 x SSE, size is 4: 1 x Float.
@@ -811,6 +810,7 @@
         } else if (Class[i+1] == X86_64_NO_CLASS) {
           // padding bytes, don't pass
           Elts.push_back(Type::DoubleTy);
+          Elts.push_back(Type::VoidTy);
           Bytes -= 16;
         } else
           assert(0 && "Not yet handled!");
@@ -819,10 +819,12 @@
         assert(0 && "Not yet handled!");
       break;
     case X86_64_SSESF_CLASS:
+      totallyEmpty = false;
       Elts.push_back(Type::FloatTy);
       Bytes -= 4;
       break;
     case X86_64_SSEDF_CLASS:
+      totallyEmpty = false;
       Elts.push_back(Type::DoubleTy);
       Bytes -= 8;
       break;
@@ -831,12 +833,16 @@
     case X86_64_COMPLEX_X87_CLASS:
       return false;
     case X86_64_NO_CLASS:
-      return false;
+      // Padding bytes that are not passed (unless the entire object consists
+      // of padding)
+      Elts.push_back(Type::VoidTy);
+      Bytes -= 8;
+      break;
     default: assert(0 && "Unexpected register class!");
     }
   }
 
-  return true;
+  return !totallyEmpty;
 }
 
 /* On Darwin, vectors which are not MMX nor SSE should be passed as integers. */

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=52192&r1=52191&r2=52192&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Tue Jun 10 20:13:02 2008
@@ -607,9 +607,20 @@
   /// mixed integer, floating point, and vector registers, convert it to a
   /// structure containing the specified struct elements in.
   void PassInMixedRegisters(tree type, const Type *Ty,
-                            std::vector<const Type*> &Elts,
+                            std::vector<const Type*> &OrigElts,
                             std::vector<const Type*> &ScalarElts) {
+    // We use VoidTy in OrigElts to mean "this is a word in the aggregate
+    // that occupies storage but has no useful information, and is not passed
+    // anywhere".  Happens on x86-64.
+    std::vector<const Type*> Elts(OrigElts);
+    const Type* wordType = getTargetData().getPointerSize() == 4 ? Type::Int32Ty :
+                                                                 Type::Int64Ty;
+    for (unsigned i=0, e=Elts.size(); i!=e; ++i)
+      if (OrigElts[i]==Type::VoidTy)
+        Elts[i] = wordType;
+
     const StructType *STy = StructType::get(Elts, false);
+
     unsigned Size = getTargetData().getABITypeSize(STy);
     const StructType *InSTy = dyn_cast<StructType>(Ty);
     unsigned InSize = 0;
@@ -627,13 +638,15 @@
       }
     }
     for (unsigned i = 0, e = Elts.size(); i != e; ++i) {
-      C.EnterField(i, STy);
-      unsigned RealSize = 0;
-      if (LastEltSizeDiff && i == (e - 1))
-        RealSize = LastEltSizeDiff;
-      C.HandleScalarArgument(Elts[i], 0, RealSize);
-      ScalarElts.push_back(Elts[i]);
-      C.ExitField();
+      if (OrigElts[i] != Type::VoidTy) {
+        C.EnterField(i, STy);
+        unsigned RealSize = 0;
+        if (LastEltSizeDiff && i == (e - 1))
+          RealSize = LastEltSizeDiff;
+        C.HandleScalarArgument(Elts[i], 0, RealSize);
+        ScalarElts.push_back(Elts[i]);
+        C.ExitField();
+      }
     }
   }
 };





More information about the llvm-commits mailing list