[llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c llvm-representation.h llvm-types.c

Chris Lattner lattner at cs.uiuc.edu
Thu Jul 28 11:50:42 PDT 2005



Changes in directory llvm-gcc/gcc:

llvm-expand.c updated: 1.109 -> 1.110
llvm-representation.h updated: 1.18 -> 1.19
llvm-types.c updated: 1.25 -> 1.26
---
Log message:

Add a new set of LLVM_TARGET_ARG_* macros, which can be used by targets to
customize the calling convention used by the CFE for specific targets.  This
is useful on targets that like to do wacky things like pass FP values in 
integer registers.



---
Diffs of the changes:  (+161 -55)

 llvm-expand.c         |   95 ++++++++++++++++++++++++++++++++++----------------
 llvm-representation.h |   60 +++++++++++++++++++++++++++++++
 llvm-types.c          |   61 +++++++++++++++++++-------------
 3 files changed, 161 insertions(+), 55 deletions(-)


Index: llvm-gcc/gcc/llvm-expand.c
diff -u llvm-gcc/gcc/llvm-expand.c:1.109 llvm-gcc/gcc/llvm-expand.c:1.110
--- llvm-gcc/gcc/llvm-expand.c:1.109	Tue Jul 26 19:24:41 2005
+++ llvm-gcc/gcc/llvm-expand.c	Thu Jul 28 13:50:28 2005
@@ -159,7 +159,7 @@
 
 static inline llvm_value *
 cast_if_type_not_equal(llvm_function *Fn,
-                       llvm_value *V, const llvm_type *Ty) {
+                       llvm_value *V, llvm_type *Ty) {
   llvm_instruction *Cast;
   if (V->Ty == Ty) return V;  /* No cast required? */
 
@@ -3023,24 +3023,38 @@
 static unsigned PassStructureByValue(llvm_function *Fn, llvm_value *ArgAddr,
                                      llvm_instruction *Call,
                                      llvm_type *CalledFuncType,
-                                     unsigned ArgOffset, unsigned NumArgs) {
+                                     unsigned ArgOffset, unsigned NumArgs,
+                                     LLVM_TARGET_ARG_ACCUM_TYPE *ArgAccum) {
   llvm_type *ValTy = GET_POINTER_TYPE_ELEMENT(ArgAddr->Ty);
+  
   if (!llvm_type_is_composite(ValTy)) {
     /* Finally got down to a simple scalar value.  Load it out. */
-    llvm_value *Val = append_inst(Fn, create_load_inst("tmp", ArgAddr, 0));
+    llvm_value *Val;
+
+    LLVM_TARGET_ARG_MODIFY_ARG_TYPE_IF_NEEDED(*ArgAccum, ValTy);
+
+    if (ValTy != GET_POINTER_TYPE_ELEMENT(ArgAddr->Ty))
+      ArgAddr = cast_if_type_not_equal(Fn, ArgAddr,
+                                       llvm_type_get_pointer(ValTy));
+    
+    Val = append_inst(Fn, create_load_inst("tmp", ArgAddr, 0));
     Call->Operands[NumArgs+ArgOffset] = Val;
     CalledFuncType->Elements[1+NumArgs] = Val->Ty;
     return NumArgs+1;
   } else {
     unsigned i, e;
+    LLVM_TARGET_ARG_DEFINE_COMPOSITE_ACCUM(COMPACCUM);
+    LLVM_TARGET_ARG_ENTER_COMPOSITE(*ArgAccum, COMPACCUM, ValTy);
+
     for (i = 0, e = llvm_type_get_composite_num_elements(ValTy); i != e; ++i) {
       llvm_value *Element = llvm_constant_new_integral(ValTy->ID == StructTyID ?
                                                        UIntTy : IntPtrTy, i);
       llvm_value *Addr = append_inst(Fn, create_gep3(ArgAddr,
                                              llvm_constant_intptr_0, Element));
       NumArgs = PassStructureByValue(Fn, Addr, Call, CalledFuncType,
-                                     ArgOffset, NumArgs);
+                                     ArgOffset, NumArgs, ArgAccum);
     }
+    LLVM_TARGET_ARG_EXIT_COMPOSITE(*ArgAccum, COMPACCUM, ValTy);
     return NumArgs;
   }
 }
@@ -3059,6 +3073,7 @@
   unsigned ArgOffset;
   int FunctionMatches = 1;
   llvm_type *CalledFuncType;
+  LLVM_TARGET_ARG_ACCUM_TYPE ArgAccumulator = LLVM_TARGET_ARG_ACCUM_INIT;
 
   /* Check to see if this is an intrinsic.  If so, do not turn it into an
    * invoke!
@@ -3123,6 +3138,7 @@
       ArgTy = GET_FUNCTION_TYPE_ARGUMENT(FnType, 0);
     else if (!FnType->x.Function.isVarArg)
       FunctionMatches = 0;
+    LLVM_TARGET_ARG_MODIFY_ARG_TYPE_IF_NEEDED(ArgAccumulator, ArgTy);
     DestLoc = cast_if_type_not_equal(Fn, DestLoc, ArgTy);
     Call->Operands[ArgOffset] = DestLoc;
     CalledFuncType->Elements[1] = DestLoc->Ty;
@@ -3146,7 +3162,8 @@
     if (isPassedByInvisibleReference(TREE_TYPE(TREE_VALUE(arg)))) {
       /* Get the address of the parameters passed in. */
       ArgVal = llvm_expand_lvalue_expr(Fn, TREE_VALUE(arg), 0, 0);
-      if (ArgTy) ArgVal = cast_if_type_not_equal(Fn, ArgVal, ArgTy);
+      LLVM_TARGET_ARG_MODIFY_ARG_TYPE_IF_NEEDED(ArgAccumulator, ArgTy);
+      ArgVal = cast_if_type_not_equal(Fn, ArgVal, ArgTy);
       Call->Operands[NumArgs+ArgOffset] = ArgVal;
       CalledFuncType->Elements[1+NumArgs] = ArgVal->Ty;
       ++NumArgs;
@@ -3157,11 +3174,11 @@
       llvm_value *ArgAddr = llvm_expand_lvalue_expr(Fn, TREE_VALUE(arg), 0, 0);
       assert(ActualArgTy == GET_POINTER_TYPE_ELEMENT(ArgAddr->Ty));
       NumArgs = PassStructureByValue(Fn, ArgAddr, Call, CalledFuncType,
-                                     ArgOffset, NumArgs);
+                                     ArgOffset, NumArgs, &ArgAccumulator);
     } else {                /* Otherwise it is a simple scalar argument. */
       ArgVal = llvm_expand_expr(Fn, TREE_VALUE(arg), 0);
-      if (ArgTy)
-        ArgVal = cast_if_type_not_equal(Fn, ArgVal, ArgTy);
+      LLVM_TARGET_ARG_MODIFY_ARG_TYPE_IF_NEEDED(ArgAccumulator, ArgTy);
+      ArgVal = cast_if_type_not_equal(Fn, ArgVal, ArgTy);
       Call->Operands[NumArgs+ArgOffset] = ArgVal;
       CalledFuncType->Elements[1+NumArgs] = ArgVal->Ty;
       ++NumArgs;
@@ -4468,7 +4485,6 @@
   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
 
   static llvm_function *llvm_va_copy_fn = 0;
-  llvm_type *VAListType;
   tree SrcArg;
   llvm_value *DestAddr;
   llvm_instruction *I;
@@ -4581,7 +4597,7 @@
 }
 
 static llvm_value *
-llvm_expand_builtin_unaryop(llvm_function *Fn, const llvm_type *DestTy,
+llvm_expand_builtin_unaryop(llvm_function *Fn, llvm_type *DestTy,
                             tree arglist, const char *FnName) {
   llvm_value *arg;
   llvm_instruction *TheCall;
@@ -7041,27 +7057,34 @@
  * specified memory location.
  */
 static void AddArguments(llvm_function *Fn, llvm_type *Ty, const char *Name,
-                         llvm_value *Address, unsigned *ArgNo) {
+                         llvm_value *Address, unsigned *ArgNo,
+                         LLVM_TARGET_ARG_ACCUM_TYPE *ArgAccumulator) {
   if (!llvm_type_is_composite(Ty)) {
     llvm_type *FuncTy = GET_POINTER_TYPE_ELEMENT(G2V(Fn)->Ty);
     llvm_type *ArgTy = Ty;
     llvm_argument *Arg;
 
-    if (*ArgNo < GET_FUNCTION_TYPE_NUMARGS(FuncTy) && 
-        ArgTy != GET_FUNCTION_TYPE_ARGUMENT(FuncTy, *ArgNo)) {
-      fprintf(stderr, "WARNING: Function declared to have type '");
-      llvm_type_print(GET_FUNCTION_TYPE_ARGUMENT(FuncTy, *ArgNo), stderr);
-      fprintf(stderr, "' but it actually has type '");
-      llvm_type_print(ArgTy, stderr);
-      ArgTy = GET_FUNCTION_TYPE_ARGUMENT(FuncTy, *ArgNo);
-      fprintf(stderr, "'!\n");
-    }
+    LLVM_TARGET_ARG_MODIFY_ARG_TYPE_IF_NEEDED(*ArgAccumulator, ArgTy);
 
+    assert((*ArgNo >= GET_FUNCTION_TYPE_NUMARGS(FuncTy) ||
+            ArgTy == GET_FUNCTION_TYPE_ARGUMENT(FuncTy, *ArgNo)) &&
+           "ERROR: Function type mismatch!");
+    
     Arg = llvm_argument_new(ArgTy, Name);
     llvm_ilist_push_back(llvm_argument, Fn->Arguments, Arg);
     if (Address) {
-      llvm_value *ArgV = cast_if_type_not_equal(Fn, D2V(Arg),
-                                        GET_POINTER_TYPE_ELEMENT(Address->Ty));
+      llvm_value *ArgV = D2V(Arg);
+      
+      /* If LLVM_TARGET_* modified type type, cast the destination pointer,
+       * otherwise cast the input value.
+       */
+      if (ArgTy == Ty) {
+        ArgV = cast_if_type_not_equal(Fn, ArgV,
+                                      GET_POINTER_TYPE_ELEMENT(Address->Ty));
+      } else {
+        Address = cast_if_type_not_equal(Fn, Address,
+                                         llvm_type_get_pointer(ArgTy));
+      }
       append_inst(Fn, create_store_inst(ArgV, Address, 0));
     }
     ++*ArgNo;
@@ -7072,6 +7095,9 @@
     unsigned i, NameLen = strlen(Name);
     char *SubName = (char*)xmalloc(NameLen+6); /* Should use alloca, oh well */
     llvm_type *ElIdxTy = Ty->ID == StructTyID ? UIntTy : IntPtrTy;
+    LLVM_TARGET_ARG_DEFINE_COMPOSITE_ACCUM(COMPACCUM);
+    
+    LLVM_TARGET_ARG_ENTER_COMPOSITE(*ArgAccumulator, COMPACCUM, Ty);
     strcpy(SubName, Name);
     for (i = 0; i != llvm_type_get_composite_num_elements(Ty); ++i) {
       llvm_type *ElTy = llvm_type_get_composite_element(Ty, i);
@@ -7086,9 +7112,10 @@
                           llvm_constant_new(ElIdxTy, SubName+NameLen+1));
         Offset = append_inst(Fn, GEP);  /* Add the inst to the stream */
       }
-      AddArguments(Fn, ElTy, SubName, Offset, ArgNo);
+      AddArguments(Fn, ElTy, SubName, Offset, ArgNo, ArgAccumulator);
     }
     free(SubName);
+    LLVM_TARGET_ARG_EXIT_COMPOSITE(*ArgAccumulator, COMPACCUM, Ty);
   }
 }
 
@@ -7108,6 +7135,7 @@
   int isExternal = !DECL_SAVED_TREE(fd);  /* no body? */
   tree Args;
   unsigned NumArgs = 0;
+  LLVM_TARGET_ARG_ACCUM_TYPE ArgAccumulator = LLVM_TARGET_ARG_ACCUM_INIT;
   assert(TREE_CODE(fd) == FUNCTION_DECL);
   
   if (isExternal) return BaseType;  /* Still external, used declared type. */
@@ -7135,13 +7163,17 @@
 
   if (DECL_RESULT(fd)) {
     RetType = llvm_type_get_from_tree(TREE_TYPE(DECL_RESULT(fd)));
-    if (llvm_type_is_composite(RetType))
-      BaseType->Elements[NumArgs++] = llvm_type_get_pointer(RetType);
+    if (llvm_type_is_composite(RetType)) {
+      llvm_type *ArgTy = llvm_type_get_pointer(RetType);
+      LLVM_TARGET_ARG_MODIFY_ARG_TYPE_IF_NEEDED(ArgAccumulator, ArgTy);
+      BaseType->Elements[NumArgs++] = ArgTy;
+    }
   }
 
   for (Args = DECL_ARGUMENTS(fd); Args; Args = TREE_CHAIN(Args)) {
-    llvm_type *Ty = llvm_type_get_from_tree(TREE_TYPE(Args));
-    NumArgs += SetFunctionArgs(BaseType, NumArgs, Ty);
+    NumArgs += SetFunctionArgs(BaseType, NumArgs,
+                               llvm_type_get_from_tree(TREE_TYPE(Args)),
+                               &ArgAccumulator);
   }
   
   return llvm_type_get_cannonical_function(BaseType);
@@ -7159,6 +7191,7 @@
   int isExternal = !DECL_SAVED_TREE(subr);  /* no body, YET */
   llvm_type *DeclResultTy;
   int ReturnsComposite = 0;
+  LLVM_TARGET_ARG_ACCUM_TYPE ArgAccumulator = LLVM_TARGET_ARG_ACCUM_INIT;
 
   if (!isExternal && FnTy->x.Function.isVarArg && Args == 0) {
     /* Check to see if this is a false varargs function.  In C, declaring a
@@ -7268,8 +7301,10 @@
   if (DECL_RESULT(subr)) {
     DeclResultTy = llvm_type_get_from_tree(TREE_TYPE(DECL_RESULT(subr)));
     if (llvm_type_is_composite(DeclResultTy)) {
-      llvm_argument *Arg =llvm_argument_new(llvm_type_get_pointer(DeclResultTy),
-                                            "agg.result");
+      llvm_type *ArgTy = llvm_type_get_pointer(DeclResultTy);
+      llvm_argument *Arg;
+      LLVM_TARGET_ARG_MODIFY_ARG_TYPE_IF_NEEDED(ArgAccumulator, ArgTy);
+      Arg = llvm_argument_new(ArgTy, "agg.result");
       llvm_ilist_push_back(llvm_argument, Fn->Arguments, Arg);
       SET_DECL_LLVM(DECL_RESULT(subr), D2V(Arg));
       ReturnsComposite = 1;
@@ -7319,7 +7354,7 @@
        * this could cause multiple LLVM arguments to be added for this one C
        * argument.
        */
-      AddArguments(Fn, Ty, Name, D2V(A), &ArgNo);
+      AddArguments(Fn, Ty, Name, D2V(A), &ArgNo, &ArgAccumulator);
 
       /* If the value is passed by "invisible reference", the l-value for the
        * argument IS the argument itself.


Index: llvm-gcc/gcc/llvm-representation.h
diff -u llvm-gcc/gcc/llvm-representation.h:1.18 llvm-gcc/gcc/llvm-representation.h:1.19
--- llvm-gcc/gcc/llvm-representation.h:1.18	Fri Jul 22 13:53:38 2005
+++ llvm-gcc/gcc/llvm-representation.h	Thu Jul 28 13:50:28 2005
@@ -506,7 +506,65 @@
 
 void llvm_type_print_all_named(FILE *F);
 
-unsigned SetFunctionArgs(llvm_type *FuncTy, unsigned ArgNo, llvm_type *ArgTy);
+/*===---------------------------------------------------------------------===
+ * Argument passing ABI hooks.
+ *
+ * These hooks are used by targets that do not pass arguments in the standard
+ * way or need to change specific portions of the calling convention for
+ * certain arguments.
+ *
+ * If the target doesn't define these, we provide defaults below.  We also
+ * describe what these are supposed to do below.
+ */
+
+/* LLVM_TARGET_ARG_ACCUM_TYPE - This is the name of a C type that is used to
+ * implement the state machine for the target.
+ */
+#ifndef LLVM_TARGET_ARG_ACCUM_TYPE
+#define LLVM_TARGET_ARG_ACCUM_TYPE int
+#endif
+
+/* LLVM_TARGET_ARG_ACCUM_INIT - This is the value to initialize the state
+ * machine with.
+ */
+#ifndef LLVM_TARGET_ARG_ACCUM_INIT
+#define LLVM_TARGET_ARG_ACCUM_INIT 0
+#endif
+
+/* LLVM_TARGET_ARG_DEFINE_COMPOSITE_ACCUM - This is the type of a value used
+ * when recursing into a composite type like a structure or array.
+ */
+#ifndef LLVM_TARGET_ARG_DEFINE_COMPOSITE_ACCUM
+#define LLVM_TARGET_ARG_DEFINE_COMPOSITE_ACCUM(NAME)
+#endif
+
+/* LLVM_TARGET_ARG_ENTER_COMPOSITE - This is invoked when entering a composite
+ * type.  The first argument is the ARG_ACCUM for the entire call, the second
+ * argument is the composite accumulator for the composite type we are entering,
+ * and the third is the composite llvm_type itself.
+ */
+#ifndef LLVM_TARGET_ARG_ENTER_COMPOSITE
+#define LLVM_TARGET_ARG_ENTER_COMPOSITE(ACCUM, COMPACCUM, TY)
+#endif
+
+/* LLVM_TARGET_ARG_EXIT_COMPOSITE - When recursing out of a composite type
+ * this callback is invoked with the same arguments as .._ENTER_COMPOSITE.
+ */
+#ifndef LLVM_TARGET_ARG_EXIT_COMPOSITE
+#define LLVM_TARGET_ARG_EXIT_COMPOSITE(ACCUM, COMPACCUM, TY)
+#endif
+
+/* LLVM_TARGET_ARG_MODIFY_ARG_TYPE_IF_NEEDED - This is the callback that is
+ * actually used to modify types passed to functions.  Given the specified
+ * accumulator, this may modify TY, an lvalue for the current scalar llvm_type
+ * which is trying to be passed to a function.
+ */
+#ifndef LLVM_TARGET_ARG_MODIFY_ARG_TYPE_IF_NEEDED
+#define LLVM_TARGET_ARG_MODIFY_ARG_TYPE_IF_NEEDED(ACCUM, TY)
+#endif
+
+unsigned SetFunctionArgs(llvm_type *FuncTy, unsigned ArgNo, llvm_type *ArgTy,
+                         LLVM_TARGET_ARG_ACCUM_TYPE *ACCUM);
 
 /*===---------------------------------------------------------------------===*/
 


Index: llvm-gcc/gcc/llvm-types.c
diff -u llvm-gcc/gcc/llvm-types.c:1.25 llvm-gcc/gcc/llvm-types.c:1.26
--- llvm-gcc/gcc/llvm-types.c:1.25	Mon Jul 25 20:17:22 2005
+++ llvm-gcc/gcc/llvm-types.c	Thu Jul 28 13:50:28 2005
@@ -607,27 +607,6 @@
   return 1;
 }
 
-/* SetFunctionArgs - Add ArgTy to the list of arguments in MethTy.  This could
- * be a composite type, expanding into many actual LLVM arguments.  Insert them
- * into the method type at location ArgNo, and return the actual number of
- * arguments inserted.
- */
-unsigned SetFunctionArgs(llvm_type *FuncTy, unsigned ArgNo, llvm_type *ArgTy) {
-  if (llvm_type_is_composite(ArgTy)) {
-    unsigned NumInserted = 0, i;
-    for (i = 0; i < llvm_type_get_composite_num_elements(ArgTy); ++i) {
-      unsigned NI = SetFunctionArgs(FuncTy, ArgNo,
-                                    llvm_type_get_composite_element(ArgTy, i));
-      ArgNo += NI;
-      NumInserted += NI;
-    }
-    return NumInserted;
-  } else {
-    FuncTy->Elements[ArgNo] = ArgTy;
-    return 1;
-  }
-}
-
 llvm_type *llvm_type_get_integer(unsigned NumBits, int isUnsigned) {
   switch (NumBits*2+!isUnsigned) {
   case 8*2+0 : return UByteTy;
@@ -1033,6 +1012,33 @@
   return memcpy(Buffer, Prefix, strlen(Prefix));
 }
 
+/* SetFunctionArgs - Add ArgTy to the list of arguments in FuncTy.  This could
+* be a composite type, expanding into many actual LLVM arguments.  Insert them
+* into the function type at location ArgNo, and return the actual number of
+* arguments inserted.
+*/
+unsigned SetFunctionArgs(llvm_type *FuncTy, unsigned ArgNo, llvm_type *ArgTy,
+                         LLVM_TARGET_ARG_ACCUM_TYPE *ACCUM) {
+  if (llvm_type_is_composite(ArgTy)) {
+    unsigned NumInserted = 0, i;
+    LLVM_TARGET_ARG_DEFINE_COMPOSITE_ACCUM(COMACCUM);
+    LLVM_TARGET_ARG_ENTER_COMPOSITE(*ACCUM, COMACCUM, ArgTy);
+    for (i = 0; i < llvm_type_get_composite_num_elements(ArgTy); ++i) {
+      unsigned NI = SetFunctionArgs(FuncTy, ArgNo,
+                                    llvm_type_get_composite_element(ArgTy, i),
+                                    ACCUM);
+      ArgNo += NI;
+      NumInserted += NI;
+    }
+    LLVM_TARGET_ARG_EXIT_COMPOSITE(*ACCUM, COMACCUM, ArgTy);
+    return NumInserted;
+  } else {
+    LLVM_TARGET_ARG_MODIFY_ARG_TYPE_IF_NEEDED(*ACCUM, ArgTy);
+    FuncTy->Elements[ArgNo] = ArgTy;
+    return 1;
+  }
+}
+
 /* isPassedByInvisibleReference - Return true if an argument of the specified
  * type should be passed in by invisible reference.
  */
@@ -1066,6 +1072,7 @@
   return 0;
 }
 
+
 /* llvm_type_get_tree_type - Return the LLVM type that corresponds to the
  * specified tree type.  If this is the first time we have seen a structure
  * type, we assign indexes to all of the FIELD_DECLs in it.
@@ -1086,7 +1093,9 @@
     llvm_type *RetType = llvm_type_get_from_tree(TREE_TYPE(type));
     llvm_type *FirstArgTy = 0;  /* Non-null if returning a struct */
     unsigned NumArgs = 0, i;
-
+    
+    LLVM_TARGET_ARG_ACCUM_TYPE ArgAccumulator = LLVM_TARGET_ARG_ACCUM_INIT;
+  
     /* Loop over all of the args, counting how many there are */
     tree Args = TYPE_ARG_TYPES(type);
     for (; Args && TREE_VALUE(Args) != void_type_node; Args = TREE_CHAIN(Args)){
@@ -1118,7 +1127,11 @@
 
     Result = llvm_type_create_function(NumArgs, RetType);
     if (!Args) Result->x.Function.isVarArg = 1;
-    if (FirstArgTy) Result->Elements[1] = FirstArgTy;
+    
+    if (FirstArgTy) {
+      LLVM_TARGET_ARG_MODIFY_ARG_TYPE_IF_NEEDED(ArgAccumulator, FirstArgTy);
+      Result->Elements[1] = FirstArgTy;
+    }
 
     Args = TYPE_ARG_TYPES(type);
     for (i = (FirstArgTy != 0)+1; i < NumArgs+1; Args = TREE_CHAIN(Args)) {
@@ -1128,7 +1141,7 @@
       if (isPassedByInvisibleReference(TREE_VALUE(Args)))
         Ty = llvm_type_get_pointer(Ty);
 
-      i += SetFunctionArgs(Result, i, Ty);
+      i += SetFunctionArgs(Result, i, Ty, &ArgAccumulator);
     }
     return llvm_type_get_cannonical_function(Result);
   }






More information about the llvm-commits mailing list