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

Evan Cheng evan.cheng at apple.com
Mon Oct 13 11:03:01 PDT 2008


Author: evancheng
Date: Mon Oct 13 13:03:01 2008
New Revision: 57454

URL: http://llvm.org/viewvc/llvm-project?rev=57454&view=rev
Log:
On x86, pass _Complex * as a first class aggregate instead of ByVal. The exceptions are _Complex char, _Complex short, and _Complex int which codegen are not yet generating ABI compatible code.

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
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-types.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=57454&r1=57453&r2=57454&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 Mon Oct 13 13:03:01 2008
@@ -181,6 +181,16 @@
 #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_as_fca(tree type, const Type *);
+
+/* LLVM_SHOULD_PASS_AGGREGATE_AS_FCA - Return true if an aggregate of the
+   specified type should be passed as a first-class aggregate. */
+#ifndef LLVM_SHOULD_PASS_AGGREGATE_AS_FCA
+#define LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(X, TY) \
+  llvm_x86_should_pass_aggregate_as_fca(X, TY)
+#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/config/i386/llvm-i386.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp?rev=57454&r1=57453&r2=57454&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 Mon Oct 13 13:03:01 2008
@@ -619,9 +619,28 @@
   return true;
 }  
 
+/* It returns true if an aggregate of the specified type should be passed as a
+   first class aggregate. */
+bool llvm_x86_should_pass_aggregate_as_fca(tree type, const Type *Ty) {
+  if (TREE_CODE(type) != COMPLEX_TYPE)
+    return false;
+  const StructType *STy = dyn_cast<StructType>(Ty);
+  if (!STy || STy->isPacked()) return false;
+
+  // FIXME: Currently codegen isn't lowering _Complex char / short and _Complex
+  // int in x86-64 in a way that makes it ABI compatible.
+  const Type *EltTy = STy->getElementType(0);
+  return !((TARGET_64BIT && EltTy == Type::Int32Ty) ||
+           EltTy == Type::Int16Ty ||
+           EltTy == Type::Int8Ty);
+}
+
 /* Target hook for llvm-abi.h. It returns true if an aggregate of the
    specified type should be passed in memory. */
 bool llvm_x86_should_pass_aggregate_in_memory(tree TreeType, const Type *Ty) {
+  if (llvm_x86_should_pass_aggregate_as_fca(TreeType, Ty))
+    return false;
+
   enum machine_mode Mode = ix86_getNaturalModeForType(TreeType);
   HOST_WIDE_INT Bytes =
     (Mode == BLKmode) ? int_size_in_bytes(TreeType) : (int) GET_MODE_SIZE(Mode);
@@ -723,6 +742,9 @@
 bool
 llvm_x86_64_should_pass_aggregate_in_mixed_regs(tree TreeType, const Type *Ty,
                                                 std::vector<const Type*> &Elts){
+  if (llvm_x86_should_pass_aggregate_as_fca(TreeType, Ty))
+    return false;
+
   enum x86_64_reg_class Class[MAX_CLASSES];
   enum machine_mode Mode = ix86_getNaturalModeForType(TreeType);
   bool totallyEmpty = true;
@@ -1362,9 +1384,9 @@
 /// llvm_store_scalar_argument - Store scalar argument ARGVAL of type
 /// LLVMTY at location LOC.
 void llvm_x86_store_scalar_argument(Value *Loc, Value *ArgVal,
-                                const llvm::Type *LLVMTy,
-                                unsigned RealSize,
-                                LLVMBuilder &Builder) {
+                                    const llvm::Type *LLVMTy,
+                                    unsigned RealSize,
+                                    LLVMBuilder &Builder) {
   if (RealSize) {
     // Do byte wise store because actaul argument type does not match LLVMTy.
     Loc = Builder.CreateBitCast(Loc, 
@@ -1413,8 +1435,7 @@
 /// register.  This means we'll be loading bytes off the end of the object
 /// in some cases.  That's what gcc does, so it must be OK, right?  Right?
 bool llvm_x86_should_pass_aggregate_in_integer_regs(tree type, unsigned *size,
-                                                    bool *DontCheckAlignment)
-{
+                                                    bool *DontCheckAlignment) {
   *size = 0;
   if (TARGET_64BIT) {
     enum x86_64_reg_class Class[MAX_CLASSES];

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=57454&r1=57453&r2=57454&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Mon Oct 13 13:03:01 2008
@@ -94,6 +94,10 @@
   /// argument is passed by value.
   void HandleByValArgument(const llvm::Type *LLVMTy, tree type) {}
 
+  /// HandleFCAArgument - This callback is invoked if the aggregate function
+  /// argument is passed by value as a first class aggregate.
+  void HandleFCAArgument(const llvm::Type *LLVMTy, tree type) {}
+
   /// EnterField - Called when we're about the enter the field of a struct
   /// or union.  FieldNo is the number of the element we are entering in the
   /// LLVM Struct, StructTy is the LLVM type of the struct we are entering.
@@ -251,6 +255,14 @@
     false
 #endif
 
+// LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR - Return true if this aggregate
+// value should be passed by value as a first class aggregate. The default is
+// false.
+#ifndef LLVM_SHOULD_PASS_AGGREGATE_AS_FCA
+#define LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(X, TY) \
+    false
+#endif
+
 // LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS - Return true if this aggregate
 // value should be passed in a mixture of integer, floating point, and vector
 // registers. The routine should also return by reference a vector of the
@@ -441,6 +453,8 @@
     } else if (Ty->isSingleValueType()) {
       C.HandleScalarArgument(Ty, type);
       ScalarElts.push_back(Ty);
+    } else if (LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(type, Ty)) {
+      C.HandleFCAArgument(Ty, type);
     } else if (LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(type, Ty, Elts)) {
       if (!LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS(Elts, ScalarElts))
         PassInMixedRegisters(type, Ty, Elts, ScalarElts);

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=57454&r1=57453&r2=57454&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Oct 13 13:03:01 2008
@@ -513,6 +513,15 @@
       abort();
     }
 
+    void HandleFCAArgument(const llvm::Type *LLVMTy, tree type) {
+      // Store the FCA argument into alloca.
+      assert(!LocStack.empty());
+      Value *Loc = LocStack.back();
+      Builder.CreateStore(AI, Loc);
+      AI->setName(NameStack.back());
+      ++AI;
+    }
+
     void HandleAggregateResultAsScalar(const Type *ScalarTy, unsigned Offset=0){
       this->Offset = Offset;
     }
@@ -2270,7 +2279,7 @@
     // value out of the specified register.
     return EmitReadOfRegisterVariable(exp, DestLoc);
   }
-  
+
   LValue LV = EmitLV(exp);
   bool isVolatile = TREE_THIS_VOLATILE(exp);
   const Type *Ty = ConvertType(TREE_TYPE(exp));
@@ -2649,6 +2658,14 @@
       CallOperands.push_back(Loc);
     }
 
+    /// HandleFCAArgument - This callback is invoked if the aggregate function
+    /// argument is passed as a first class aggregate.
+    void HandleFCAArgument(const llvm::Type *LLVMTy, tree type) {
+      Value *Loc = getAddress();
+      assert(PointerType::getUnqual(LLVMTy) == Loc->getType());
+      CallOperands.push_back(Builder.CreateLoad(Loc));
+    }
+
     /// EnterField - Called when we're about the enter the field of a struct
     /// or union.  FieldNo is the number of the element we are entering in the
     /// LLVM Struct, StructTy is the LLVM type of the struct we are entering.
@@ -2735,12 +2752,17 @@
   // Loop over the arguments, expanding them and adding them to the op list.
   std::vector<const Type*> ScalarArgs;
   for (tree arg = TREE_OPERAND(exp, 1); arg; arg = TREE_CHAIN(arg)) {
-    const Type *ArgTy = ConvertType(TREE_TYPE(TREE_VALUE(arg)));
+    tree type = TREE_TYPE(TREE_VALUE(arg));
+    const Type *ArgTy = ConvertType(type);
 
     // Push the argument.
     if (ArgTy->isSingleValueType()) {
       // A scalar - push the value.
       Client.pushValue(Emit(TREE_VALUE(arg), 0));
+    } else if (LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(type, ArgTy)) {
+      // A first class aggregate - push the value.
+      LValue ArgVal = EmitLV(TREE_VALUE(arg));
+      Client.pushValue(Builder.CreateLoad(ArgVal.Ptr));
     } else {
       // An aggregate - push the address.
       LValue ArgVal = EmitLV(TREE_VALUE(arg));
@@ -2749,8 +2771,7 @@
     }
 
     Attributes Attrs = Attribute::None;
-    ABIConverter.HandleArgument(TREE_TYPE(TREE_VALUE(arg)), ScalarArgs,
-                                &Attrs);
+    ABIConverter.HandleArgument(type, ScalarArgs, &Attrs);
     if (Attrs != Attribute::None)
       PAL = PAL.addAttr(CallOperands.size(), Attrs);
 
@@ -5848,7 +5869,7 @@
         mark_referenced(ID);
     }
   }
-  
+
   const Type *Ty = ConvertType(TREE_TYPE(exp));
   // If we have "extern void foo", make the global have type {} instead of
   // type void.

Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=57454&r1=57453&r2=57454&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Mon Oct 13 13:03:01 2008
@@ -1021,6 +1021,12 @@
     void HandleByValArgument(const llvm::Type *LLVMTy, tree type) {
       HandleScalarArgument(PointerType::getUnqual(LLVMTy), type);
     }
+
+    /// HandleFCAArgument - This callback is invoked if the aggregate function
+    /// argument is a first class aggregate passed by value.
+    void HandleFCAArgument(const llvm::Type *LLVMTy, tree type) {
+      ArgTypes.push_back(LLVMTy);
+    }
   };
 }
 





More information about the llvm-commits mailing list