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

Dale Johannesen dalej at apple.com
Thu Mar 20 11:42:57 PDT 2008


Author: johannes
Date: Thu Mar 20 13:42:57 2008
New Revision: 48608

URL: http://llvm.org/viewvc/llvm-project?rev=48608&view=rev
Log:
Add vector handling for ppc32.  Move x86 vector
logic from header file macros into functions.  Rewrite
llvm-convert changes for sret-returning vectors (and
add one more) per patch feedback.


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/config/rs6000/llvm-rs6000.cpp
    llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.h
    llvm-gcc-4.2/trunk/gcc/llvm-abi.h
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp

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=48608&r1=48607&r2=48608&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 Mar 20 13:42:57 2008
@@ -98,40 +98,26 @@
   isSingleElementStructOrArray(X, true, false)
 #endif
 
+extern bool llvm_x86_should_pass_vector_in_integer_regs(tree);
+
+/* Vectors which are not MMX nor SSE should be passed as integers. */
+#define LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(X)      \
+  llvm_x86_should_pass_vector_in_integer_regs((X))
+
+extern tree llvm_x86_should_return_vector_as_scalar(tree, bool);
+
 /* The MMX vector v1i64 is returned in EAX and EDX on Darwin.  Communicate
     this by returning i64 here.  Likewise, (generic) vectors such as v2i16
     are returned in EAX.  */
 #define LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR(X,isBuiltin)\
-  ((TARGET_MACHO &&                                     \
-    !isBuiltin &&                                       \
-    !TARGET_64BIT &&                                    \
-    TREE_CODE(X) == VECTOR_TYPE &&                      \
-    TYPE_SIZE(X) &&                                     \
-    TREE_CODE(TYPE_SIZE(X))==INTEGER_CST)               \
-   ? (TREE_INT_CST_LOW(TYPE_SIZE(X))==64 &&             \
-      TYPE_VECTOR_SUBPARTS(X)==1)                       \
-     ? uint64_type_node                                 \
-     : (TREE_INT_CST_LOW(TYPE_SIZE(X))==32)             \
-        ? uint32_type_node                              \
-        : 0                                             \
-   : 0)
+  llvm_x86_should_return_vector_as_scalar((X), (isBuiltin))
+
+extern bool llvm_x86_should_return_vector_as_shadow(tree, bool);
 
 /* MMX vectors v2i32, v4i16, v8i8, v2f32 are returned using sret on Darwin
    32-bit.  Vectors bigger than 128 are returned using sret.  */
 #define LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(X,isBuiltin)\
-  ((TARGET_MACHO &&                                     \
-    !isBuiltin &&                                       \
-    !TARGET_64BIT &&                                    \
-    TREE_CODE(X) == VECTOR_TYPE &&                      \
-    TYPE_SIZE(X) &&                                     \
-    TREE_CODE(TYPE_SIZE(X))==INTEGER_CST)               \
-    ? (TREE_INT_CST_LOW(TYPE_SIZE(X))==64 &&            \
-       TYPE_VECTOR_SUBPARTS(X)>1)                       \
-       ? true                                           \
-       : (TREE_INT_CST_LOW(TYPE_SIZE(X))>128)           \
-         ? true                                         \
-         : false                                        \
-    : false)
+  llvm_x86_should_return_vector_as_shadow((X),(isBuiltin))
 
 extern bool llvm_x86_should_pass_aggregate_in_memory(tree, const Type *);
 

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=48608&r1=48607&r2=48608&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 Thu Mar 20 13:42:57 2008
@@ -759,4 +759,57 @@
   }
   return true;
 }
+
+/* Vectors which are not MMX nor SSE should be passed as integers. */
+bool llvm_x86_should_pass_vector_in_integer_regs(tree type) {
+  if (TARGET_MACHO &&
+    !TARGET_64BIT &&
+    TREE_CODE(type) == VECTOR_TYPE &&
+    TYPE_SIZE(type) &&
+    TREE_CODE(TYPE_SIZE(type))==INTEGER_CST) {
+    if (TREE_INT_CST_LOW(TYPE_SIZE(type))==64 && TARGET_MMX)
+      return false;
+    if (TREE_INT_CST_LOW(TYPE_SIZE(type))==128 && TARGET_SSE)
+      return false;
+  }
+  return true;
+}
+
+/* The MMX vector v1i64 is returned in EAX and EDX on Darwin.  Communicate
+    this by returning i64 here.  Likewise, (generic) vectors such as v2i16
+    are returned in EAX.  */
+tree llvm_x86_should_return_vector_as_scalar(tree type, bool isBuiltin) {
+  if (TARGET_MACHO &&
+      !isBuiltin &&
+      !TARGET_64BIT &&
+      TREE_CODE(type) == VECTOR_TYPE &&
+      TYPE_SIZE(type) &&
+      TREE_CODE(TYPE_SIZE(type))==INTEGER_CST) {
+    if (TREE_INT_CST_LOW(TYPE_SIZE(type))==64 &&
+        TYPE_VECTOR_SUBPARTS(type)==1)
+      return uint64_type_node;
+    if (TREE_INT_CST_LOW(TYPE_SIZE(type))==32)
+      return uint32_type_node;
+  }
+  return 0;
+}
+
+/* MMX vectors v2i32, v4i16, v8i8, v2f32 are returned using sret on Darwin
+   32-bit.  Vectors bigger than 128 are returned using sret.  */
+bool llvm_x86_should_return_vector_as_shadow(tree type, bool isBuiltin) {
+  if (TARGET_MACHO &&
+    !isBuiltin &&
+    !TARGET_64BIT &&
+    TREE_CODE(type) == VECTOR_TYPE &&
+    TYPE_SIZE(type) &&
+    TREE_CODE(TYPE_SIZE(type))==INTEGER_CST) {
+    if (TREE_INT_CST_LOW(TYPE_SIZE(type))==64 &&
+       TYPE_VECTOR_SUBPARTS(type)>1)
+      return true;
+    if (TREE_INT_CST_LOW(TYPE_SIZE(type))>128)
+      return true;
+  }
+  return false;
+}
+
 /* LLVM LOCAL end (ENTIRE FILE!)  */

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

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp Thu Mar 20 13:42:57 2008
@@ -448,5 +448,44 @@
   return false;
 }
 
+/* Non-Altivec vectors are passed in integer regs. */
+bool llvm_rs6000_should_pass_vector_in_integer_regs(tree type) {
+  if (!TARGET_64BIT &&
+    TREE_CODE(type) == VECTOR_TYPE &&
+    TYPE_SIZE(type) && TREE_CODE(TYPE_SIZE(type))==INTEGER_CST &&
+    TREE_INT_CST_LOW(TYPE_SIZE(type)) != 128)
+    return true;
+  return false;
+}
+
+/* (Generic) vectors 4 bytes long are returned as an int.
+   Vectors 8 bytes long are returned as 2 ints. */
+tree llvm_rs6000_should_return_vector_as_scalar(tree type, 
+                                    bool isBuiltin ATTRIBUTE_UNUSED) {
+  if (!TARGET_64BIT &&
+      TREE_CODE(type) == VECTOR_TYPE &&
+      TYPE_SIZE(type) &&
+      TREE_CODE(TYPE_SIZE(type))==INTEGER_CST) {
+    if (TREE_INT_CST_LOW(TYPE_SIZE(type))==32)
+      return uint32_type_node;
+    else if (TREE_INT_CST_LOW(TYPE_SIZE(type))==64)
+      return uint64_type_node;
+  }
+  return 0;
+}
+
+/* Non-altivec vectors bigger than 8 bytes are returned by sret. */
+bool llvm_rs6000_should_return_vector_as_shadow(tree type, 
+                                      bool isBuiltin ATTRIBUTE_UNUSED) {
+  if (!TARGET_64BIT &&
+      TREE_CODE(type) == VECTOR_TYPE &&
+      TYPE_SIZE(type) &&
+      TREE_CODE(TYPE_SIZE(type))==INTEGER_CST &&
+      TREE_INT_CST_LOW(TYPE_SIZE(type))>64 &&
+      TREE_INT_CST_LOW(TYPE_SIZE(type))!=128)
+    return true;
+  return false;
+}
+
 /* LLVM LOCAL end (ENTIRE FILE!)  */
 

Modified: llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.h?rev=48608&r1=48607&r2=48608&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.h (original)
+++ llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.h Thu Mar 20 13:42:57 2008
@@ -638,7 +638,7 @@
    We must map them here to avoid huge unwinder tables mostly consisting
    of unused space.  */
 /* APPLE LOCAL begin 3399553 */
-#define DWARF_REG_TO_UNWIND_COLUMN(r)	\
+#define DWARF_REG_TO_UNWIND_COLUMN(r)  \
   ((r) > 1200 ? ((r) - 1200 + LAST_PHYSICAL_REGISTER) : (r))
 /* APPLE LOCAL end 3399553 */
 
@@ -3479,7 +3479,13 @@
 extern bool llvm_rs6000_should_pass_aggregate_byval(tree, const Type *);
 
 #define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X, TY)      \
-  llvm_rs6000_should_pass_aggregate_byval(X, TY)
+  llvm_rs6000_should_pass_aggregate_byval((X), (TY))
+
+extern bool llvm_rs6000_should_pass_vector_in_integer_regs(tree);
+
+/* All non-Altivec vectors are passed in integer regs. */
+#define LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(X)            \
+  llvm_rs6000_should_pass_vector_in_integer_regs((X))
 
 extern bool llvm_rs6000_should_pass_aggregate_in_mixed_regs(tree, const Type*, 
                                               std::vector<const Type*>&);
@@ -3488,15 +3494,18 @@
 #define LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(T, TY, E) \
    llvm_rs6000_should_pass_aggregate_in_mixed_regs((T), (TY), (E))
 
-/* Non-altivec vectors bigger than 4 bytes are returned by sret. */
+extern tree llvm_rs6000_should_return_vector_as_scalar(tree, bool);
+
+/* (Generic) vectors 4 bytes long are returned as an int.
+   Vectors 8 bytes long are returned as 2 ints. */
+#define LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR(X,isBuiltin)  \
+  llvm_rs6000_should_return_vector_as_scalar((X), (isBuiltin))
+
+extern bool llvm_rs6000_should_return_vector_as_shadow(tree, bool);
+
+/* Non-altivec vectors bigger than 8 bytes are returned by sret. */
 #define LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(X,isBuiltin)\
-  ((!TARGET_64BIT &&                                    \
-    TREE_CODE(X) == VECTOR_TYPE &&                      \
-    TYPE_SIZE(X) &&                                     \
-    TREE_CODE(TYPE_SIZE(X))==INTEGER_CST &&             \
-    TREE_INT_CST_LOW(TYPE_SIZE(X))>32 &&                \
-    TREE_INT_CST_LOW(TYPE_SIZE(X))!=128)                \
-    ? true : false)    
+  llvm_rs6000_should_return_vector_as_shadow((X), (isBuiltin))
 
 #endif /* LLVM_ABI_H */
 

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=48608&r1=48607&r2=48608&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Thu Mar 20 13:42:57 2008
@@ -321,10 +321,11 @@
     if (isPassedByInvisibleReference(type)) { // variable size -> by-ref.
       C.HandleScalarArgument(PointerType::getUnqual(Ty), type);
     } else if (Ty->getTypeID()==Type::VectorTyID) {
-      if (LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(type))
+      if (LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(type)) {
         PassInIntegerRegisters(type, Ty);
-      else
+      } else {
         C.HandleScalarArgument(Ty, type);
+      }
     } else if (Ty->isFirstClassType()) {
       C.HandleScalarArgument(Ty, type);
     } else if (LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(type, Ty, Elts)) {

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=48608&r1=48607&r2=48608&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu Mar 20 13:42:57 2008
@@ -825,14 +825,7 @@
 }
 
 Value *TreeToLLVM::Emit(tree exp, const MemRef *DestLoc) {
-  tree fndecl;
-  // Some vectors are returned using sret; these should have DestLoc provided.
-  assert(((isAggregateTreeType(TREE_TYPE(exp)) == (DestLoc != 0)) ||
-          (TREE_CODE(exp)==CALL_EXPR && 
-           TREE_CODE(TREE_TYPE(exp))==VECTOR_TYPE &&
-           LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(TREE_TYPE(exp),
-             ((fndecl = get_callee_fndecl(exp)) ? DECL_BUILT_IN(fndecl) : 
-                                                false))) ||
+  assert((isAggregateTreeType(TREE_TYPE(exp)) == (DestLoc != 0) ||
           TREE_CODE(exp) == MODIFY_EXPR) &&
          "Didn't pass DestLoc to an aggregate expr, or passed it to scalar!");
   
@@ -2279,8 +2272,24 @@
   // parameter for the chain.
   Callee = BitCastToType(Callee, PointerType::getUnqual(Ty));
 
-  //EmitCall(exp, DestLoc);
-  Value *Result = EmitCallOf(Callee, exp, DestLoc, PAL);
+  Value *Result;
+  if (TREE_CODE(TREE_TYPE(exp))==VECTOR_TYPE &&
+      LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(TREE_TYPE(exp),
+                                fndecl ? DECL_BUILT_IN(fndecl) : false)) {
+    // Vectors are first class types, so we need to return a value,
+    // but this one is to be passed using sret.  Pass in a DestLoc, if
+    // there isn't one already, and return a Load from it as the value.
+    if (!DestLoc) {
+      MemRef NewLoc = CreateTempLoc(ConvertType(TREE_TYPE(exp)));
+      DestLoc = &NewLoc;
+    }
+    EmitCallOf(Callee, exp, DestLoc, PAL);
+    LoadInst *LI = Builder.CreateLoad(DestLoc->Ptr, false, "tmp");
+    Result = LI;
+  } else {
+    //EmitCall(exp, DestLoc);
+    Result = EmitCallOf(Callee, exp, DestLoc, PAL);
+  }
 
   // If the function has the volatile bit set, then it is a "noreturn" function.
   // Output an unreachable instruction right after the function to prevent LLVM
@@ -2505,8 +2514,20 @@
       CallOperands.push_back(BitCastToType(Ptr, ArgTy));
     } else if (ActualArgTy->isFirstClassType()) {
       Value *V = Emit(TREE_VALUE(arg), 0);
-      bool isSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_VALUE(arg)));
-      CallOperands.push_back(CastToAnyType(V, isSigned, ArgTy, false));
+      if (TREE_CODE(TREE_TYPE(TREE_VALUE(arg)))==VECTOR_TYPE &&
+          LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(TREE_TYPE(TREE_VALUE(arg)))) {
+        // Passed as integer registers.  We need a stack object, not a value.
+        MemRef NewLoc = CreateTempLoc(ConvertType(TREE_TYPE(TREE_VALUE(arg))));
+        StoreInst *St = Builder.CreateStore(V, NewLoc.Ptr, false);
+        Client.setLocation(NewLoc.Ptr);
+        ParameterAttributes Attributes = ParamAttr::None;
+        ABIConverter.HandleArgument(TREE_TYPE(TREE_VALUE(arg)), &Attributes);
+        if (Attributes != ParamAttr::None)
+          PAL = PAL.addAttr(CallOperands.size(), Attributes);
+      } else {
+        bool isSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_VALUE(arg)));
+        CallOperands.push_back(CastToAnyType(V, isSigned, ArgTy, false));
+      }
     } else {
       // If this is an aggregate value passed by-value, use the current ABI to
       // determine how the parameters are passed.
@@ -2654,26 +2675,7 @@
       HandleMultiplyDefinedGCCTemp(lhs);
       return EmitMODIFY_EXPR(exp, DestLoc);
     }
-    // Some types (so far, generic vectors on x86-32 and ppc32) can have
-    // GCC SSA temporaries for them, but are passed using sret, which means
-    // Emit will return 0.  Handle this.
-    Value *RHS;
-    tree fndecl;
-    if (TREE_CODE(rhs)==CALL_EXPR && 
-        TREE_CODE(TREE_TYPE(rhs))==VECTOR_TYPE &&
-        LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(TREE_TYPE(rhs), 
-          ((fndecl = get_callee_fndecl(rhs)) ? DECL_BUILT_IN(fndecl) : 
-                                               false))) {
-      bool isVolatile = TREE_THIS_VOLATILE(lhs);
-      unsigned Alignment = expr_align(lhs) / 8;
-      MemRef NewLoc = CreateTempLoc(ConvertType(TREE_TYPE(rhs)));
-      Emit(rhs, &NewLoc);
-      LoadInst *LI = Builder.CreateLoad(NewLoc.Ptr, isVolatile, "tmp");
-      LI->setAlignment(Alignment);
-      RHS = LI;
-    } else {
-      RHS = Emit(rhs, 0);
-    }
+    Value *RHS = Emit(rhs, 0);
     RHS = CastToAnyType(RHS, RHSSigned, ConvertType(TREE_TYPE(lhs)), LHSSigned);
     SET_DECL_LLVM(lhs, RHS);
     return RHS;





More information about the llvm-commits mailing list