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

Devang Patel dpatel at apple.com
Wed Apr 16 17:33:04 PDT 2008


Author: dpatel
Date: Wed Apr 16 19:33:04 2008
New Revision: 49834

URL: http://llvm.org/viewvc/llvm-project?rev=49834&view=rev
Log:
_Complex deserves special treatement.

Modified:
    llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h
    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-target.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h?rev=49834&r1=49833&r2=49834&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 Wed Apr 16 19:33:04 2008
@@ -151,6 +151,15 @@
 #define LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(X,isBuiltin)\
   llvm_x86_should_return_vector_as_shadow((X),(isBuiltin))
 
+extern bool
+llvm_x86_should_not_return_complex_in_memory(tree type);
+
+/* LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY - A hook to allow
+   special _Complex handling. Return true if X should be returned using
+   multiple value return instruction.  */
+#define LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(X) \
+  llvm_x86_should_not_return_complex_in_memory((X))
+
 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/config/i386/llvm-i386.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp?rev=49834&r1=49833&r2=49834&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 Wed Apr 16 19:33:04 2008
@@ -900,12 +900,27 @@
   return false;
 }
 
+// llvm_x86_should_not_return_complex_in_memory -  Return true if TYPE 
+// should be returned using multiple value return instruction.
+bool llvm_x86_should_not_return_complex_in_memory(tree type) {
+  if (!TARGET_64BIT)
+    return false;
+
+  if (AGGREGATE_TYPE_P(type)) {
+    tree field = TYPE_FIELDS(type);
+    if (field && TREE_CHAIN(field) == NULL 
+        && TREE_CODE(TREE_TYPE(field)) == COMPLEX_TYPE)
+      return true;
+  }
+  return false;
+}
+
 // llvm_suitable_multiple_ret_value_type - Return TRUE if return value 
 // of type TY should be returned using multiple value return instruction.
 static bool llvm_suitable_multiple_ret_value_type(const Type *Ty,
                                                   tree TreeType) {
   //NOTE: Work in progress. Do not open the flood gate yet.
-  return false; 
+  //  return false; 
 
   if (!TARGET_64BIT)
     return false;
@@ -914,6 +929,9 @@
   if (!STy)
     return false;
 
+  if (llvm_x86_should_not_return_complex_in_memory(TreeType))
+    return true;
+
   // llvm only accepts first class types for multiple values in ret instruction.
   bool foundNonInt = false;
   bool foundInt = false;
@@ -922,7 +940,7 @@
     const Type *ETy = STy->getElementType(i);
     if (const ArrayType *ATy = dyn_cast<ArrayType>(ETy))
       ETy = ATy->getElementType();
-    if (!ETy->isFirstClassType())
+    if (!ETy->isFirstClassType() && ETy->getTypeID() != Type::X86_FP80TyID)
       return false;
     if (!ETy->isInteger())
       foundNonInt = true;
@@ -987,8 +1005,15 @@
 
   const StructType *STy = cast<StructType>(Ty);
   unsigned NumElements = STy->getNumElements();
-
   std::vector<const Type *> ElementTypes;
+
+  // Special handling for _Complex.
+  if (llvm_x86_should_not_return_complex_in_memory(type)) {
+    ElementTypes.push_back(Type::X86_FP80Ty);
+    ElementTypes.push_back(Type::X86_FP80Ty);
+    return StructType::get(ElementTypes, STy->isPacked());
+  } 
+    
   for (unsigned i = 0; i < NumElements; ++i) {
     const Type *T = STy->getElementType(i);
     
@@ -1086,8 +1111,22 @@
       ++RNO;
       ++SNO;
       continue;
+    } 
+    // Special treatement for _Complex.
+    if (const StructType *ComplexType = dyn_cast<StructType>(ElemType)) {
+      llvm::Value *Idxs[3];
+      Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+      Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, RNO);
+      Idxs[2] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+      Value *GEP = Builder.CreateGEP(RetVal, Idxs, Idxs+3, "mrv_gep");
+      RetVals.push_back(Builder.CreateLoad(GEP, "mrv"));
+      Idxs[2] = ConstantInt::get(llvm::Type::Int32Ty, 1);
+      GEP = Builder.CreateGEP(RetVal, Idxs, Idxs+3, "mrv_gep");
+      RetVals.push_back(Builder.CreateLoad(GEP, "mrv"));
+      ++RNO;
+      ++SNO;
+      continue;
     }
-
     const ArrayType *ATy = cast<ArrayType>(ElemType);
     unsigned ArraySize = ATy->getNumElements();
     unsigned AElemNo = 0;
@@ -1172,6 +1211,26 @@
       ++DNO; ++SNO;
       continue;
     } 
+
+    // Special treatement for _Complex.
+    if (const StructType *ComplexType = dyn_cast<StructType>(DestElemType)) {
+      llvm::Value *Idxs[3];
+      Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+      Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, DNO);
+
+      Idxs[2] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+      Value *GEP = Builder.CreateGEP(Dest, Idxs, Idxs+3, "mrv_gep");
+      GetResultInst *GR = Builder.CreateGetResult(Src, 0, "mrv_gr");
+      Builder.CreateStore(GR, GEP, isVolatile);
+      ++SNO;
+
+      Idxs[2] = ConstantInt::get(llvm::Type::Int32Ty, 1);
+      GEP = Builder.CreateGEP(Dest, Idxs, Idxs+3, "mrv_gep");
+      GR = Builder.CreateGetResult(Src, 1, "mrv_gr");
+      Builder.CreateStore(GR, GEP, isVolatile);
+      ++DNO; ++SNO;
+      continue;
+    }
     
     // Access array elements individually. Note, Src and Dest type may
     // not match. For example { <2 x float>, float } and { float[3]; }

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=49834&r1=49833&r2=49834&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Wed Apr 16 19:33:04 2008
@@ -104,6 +104,14 @@
          TREE_CODE(type) == COMPLEX_TYPE;
 }
 
+// LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY - A hook to allow
+// special _Complex handling. Return true if X should be returned using
+// multiple value return instruction.
+#ifndef LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY
+#define LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(X) \
+ false
+#endif
+
 // doNotUseShadowReturn - Return true if the specified GCC type 
 // should not be returned using a pointer to struct parameter. 
 static bool doNotUseShadowReturn(tree type, tree fndecl) {
@@ -111,6 +119,9 @@
     return false;
   if (TREE_CODE(TYPE_SIZE(type)) != INTEGER_CST)
     return false;
+  // LLVM says do no use shadow argument.
+  if (LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(type))
+    return true;
   // GCC says use shadow argument.
   if (aggregate_value_p(type, fndecl))
     return false;





More information about the llvm-commits mailing list