[llvm-commits] [llvm-gcc-4.2] r45907 - in /llvm-gcc-4.2/trunk/gcc: llvm-abi.h llvm-convert.cpp llvm-types.cpp

Evan Cheng evan.cheng at apple.com
Sat Jan 12 01:22:44 PST 2008


Author: evancheng
Date: Sat Jan 12 03:22:43 2008
New Revision: 45907

URL: http://llvm.org/viewvc/llvm-project?rev=45907&view=rev
Log:
Add support for aggregate parameter passing by reference. At the llvm level
they look like passing by address but with the ByVal parameter attribute.
Code generator will lower them to confirm target ABI's. e.g. X86-32 passes
aggregates on stack.

Modified:
    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/llvm-abi.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-abi.h?rev=45907&r1=45906&r2=45907&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Sat Jan 12 03:22:43 2008
@@ -32,6 +32,7 @@
 #include "llvm-internal.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/ParameterAttributes.h"
 #include "llvm/Target/TargetData.h"
 
 namespace llvm {
@@ -126,7 +127,15 @@
 // would often be 64-bits).
 #ifndef LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS
 #define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X) \
-   !isSingleElementStructOrArray(type)
+   !isSingleElementStructOrArray(X)
+#endif
+
+// LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR - Return true if this aggregate
+// value should be passed by reference by passing its address with the byval
+// attribute bit set. The default is false.
+#ifndef LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X)
+#define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X) \
+    false
 #endif
 
 /// DefaultABI - This class implements the default LLVM ABI where structures are
@@ -192,13 +201,17 @@
   /// argument and invokes methods on the client that indicate how its pieces
   /// should be handled.  This handles things like decimating structures into
   /// their fields.
-  void HandleArgument(tree type) {
+  void HandleArgument(tree type, uint16_t *Attributes = NULL) {
     const Type *Ty = ConvertType(type);
 
     if (isPassedByInvisibleReference(type)) { // variable size -> by-ref.
       C.HandleScalarArgument(PointerType::getUnqual(Ty), type);
     } else if (Ty->isFirstClassType()) {
       C.HandleScalarArgument(Ty, type);
+    } else if (LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(type)) {
+      C.HandleByValArgument(Ty, type);
+      if (Attributes)
+        *Attributes |= ParamAttr::ByVal;
     } else if (LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(type)) {
       PassInIntegerRegisters(type, Ty);
     } else if (TREE_CODE(type) == RECORD_TYPE) {

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=45907&r1=45906&r2=45907&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Sat Jan 12 03:22:43 2008
@@ -493,6 +493,11 @@
       ++AI;
     }
         
+    void HandleByValArgument(const llvm::Type *LLVMTy, tree type) {
+      // Should not get here.
+      abort();
+    }
+
     void EnterField(unsigned FieldNo, const llvm::Type *StructTy) {
       NameStack.push_back(NameStack.back()+"."+utostr(FieldNo));
       
@@ -663,9 +668,12 @@
     const char *Name = "unnamed_arg";
     if (DECL_NAME(Args)) Name = IDENTIFIER_POINTER(DECL_NAME(Args));
 
-    if (isPassedByInvisibleReference(TREE_TYPE(Args))) {
-      // If the value is passed by 'invisible reference', the l-value for the
-      // argument IS the argument itself.
+    const Type *ArgTy = ConvertType(TREE_TYPE(Args));
+    if (isPassedByInvisibleReference(TREE_TYPE(Args)) ||
+        (!ArgTy->isFirstClassType() &&
+         LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(TREE_TYPE(Args)))) {
+      // If the value is passed by 'invisible reference' or 'byval reference',
+      // the l-value for the argument IS the argument itself.
       SET_DECL_LLVM(Args, AI);
       AI->setName(Name);
       ++AI;
@@ -673,7 +681,6 @@
       // Otherwise, we create an alloca to hold the argument value and provide
       // an l-value.  On entry to the function, we copy formal argument values
       // into the alloca.
-      const Type *ArgTy = ConvertType(TREE_TYPE(Args));
       Value *Tmp = CreateTemporary(ArgTy);
       Tmp->setName(std::string(Name)+"_addr");
       SET_DECL_LLVM(Args, Tmp);
@@ -2372,6 +2379,16 @@
       CallOperands.push_back(Builder.CreateLoad(Loc, "tmp"));
     }
     
+    /// HandleByValArgument - This callback is invoked if the aggregate function
+    /// argument is passed by value. It is lowered to a parameter passed by
+    /// reference with an additional parameter attribute "ByVal".
+    void HandleByValArgument(const llvm::Type *LLVMTy, tree type) {
+      assert(!LocStack.empty());
+      Value *Loc = LocStack.back();
+      assert(PointerType::getUnqual(LLVMTy) == Loc->getType());
+      CallOperands.push_back(Loc);
+    }
+
     void EnterField(unsigned FieldNo, const llvm::Type *StructTy) {
       Constant *Zero = Constant::getNullValue(Type::Int32Ty);
       Constant *FIdx = ConstantInt::get(Type::Int32Ty, FieldNo);
@@ -2477,7 +2494,10 @@
       LValue LV = EmitLV(TREE_VALUE(arg));
       assert(!LV.isBitfield() && "Bitfields are first-class types!");
       Client.setLocation(LV.Ptr);
-      ABIConverter.HandleArgument(TREE_TYPE(TREE_VALUE(arg)));
+      uint16_t Attributes = ParamAttr::None;
+      ABIConverter.HandleArgument(TREE_TYPE(TREE_VALUE(arg)), &Attributes);
+      if (Attributes != ParamAttr::None)
+        PAL= ParamAttrsList::includeAttrs(PAL, CallOperands.size(), Attributes);
     }
   }
 

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=45907&r1=45906&r2=45907&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Sat Jan 12 03:22:43 2008
@@ -999,6 +999,13 @@
       }
       ArgTypes.push_back(LLVMTy);
     }
+
+    /// HandleByValArgument - This callback is invoked if the aggregate function
+    /// argument is passed by value. It is lowered to a parameter passed by
+    /// reference with an additional parameter attribute "ByVal".
+    void HandleByValArgument(const llvm::Type *LLVMTy, tree type) {
+      HandleScalarArgument(PointerType::getUnqual(LLVMTy), type);
+    }
   };
 }
 
@@ -1057,11 +1064,12 @@
 
   for (; Args && TREE_TYPE(Args) != void_type_node; Args = TREE_CHAIN(Args)) {
     tree ArgTy = TREE_TYPE(Args);
-    ABIConverter.HandleArgument(ArgTy);
 
     // Determine if there are any attributes for this param.
     uint16_t Attributes = ParamAttr::None;
 
+    ABIConverter.HandleArgument(ArgTy, &Attributes);
+
     // Compute zext/sext attributes.
     Attributes |= HandleArgumentExtension(ArgTy);
 
@@ -1174,11 +1182,11 @@
       break;        
     }
     
-    ABIConverter.HandleArgument(ArgTy);
-
     // Determine if there are any attributes for this param.
     uint16_t Attributes = ParamAttr::None;
     
+    ABIConverter.HandleArgument(ArgTy, &Attributes);
+
     // Compute zext/sext attributes.
     Attributes |= HandleArgumentExtension(ArgTy);
 





More information about the llvm-commits mailing list