This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch to provide infrastructure for parameter lists


In the future, it would be desirable to change the encoding of the parameter
arguments from using a linked list using TREE_CHAIN nodes to a vector of
pointers to the arguments to save space in the compiler.  This has been
discussed in the GCC mailing list:
http://gcc.gnu.org/ml/gcc/2007-06/msg00226.html

The enclosed patch is the first step at providing a new infrastructure to
access the parameter lists.  When all of the front ends and backends have been
modified to use this infrastructure exclusively, we can change the
representation underneath it.

This patch provides the infrastructure for iterating over the parameters, and
functions to determine if the function has been prototyped or is a variable
argument function.  I have included the patches for the standard x86 backend.
I have tested this with a full bootstrap and make check on both a
x86_64-unknown-linux-gnu and a i686-pc-linux-gnu sytem with no regressions in
the test.  At the moment there are 2 functions which aren't used yet
(alloc_parm_types, num_parm_types), but which will likely be needed when the
front ends are tackled.

I will be submitting the patches for the other backends in a bit after I test
them.  If I could get the maintianers or other interested parties to test the
subsequent patches on the appropriate hardware it would be helpful.

The backends that are affected are:

arm: Has a simple loop to go through the arguments.

avr: Wants to know if a function is a variable argument function.

c4x: Wants to know if a function is prototyped, and has a simple loop that goes
through the arguments.

crx: Wants to know if a function is a variable argument function.

i386: Wants to know if a function is a variable argument function.  Also, the
netware, winnt subports have loops over the argument lists.

ia64: Wants to know if the function is prototyped.

iq2000: Wants to know if a function is a variable argument function.

m68k: Wants to know if a function is a variable argument function.

mips: Wants to know if the function is prototyped and wants to know if a
function is a variable argument function.

mn10300: Wants to know if a function is a variable argument function.

pa: Wants to know if the function is prototyped and wants to know if a function
is a variable argument function.  It could also use num_parm_type.

som: Wants to know if a function is a variable argument function.

rs6000: Wants to know if the function is prototyped and wants to know if a
function is a variable argument function.  It also has support for overloaded
builtin functions that we may want to also change to use a vector instead of a
linked list in the future.

sh: Wants to know if the function is prototyped.

sparc: Wants to know if the function is prototyped.

spu: It has support for overloaded builtin functions that we may want to also
change to use a vector instead of a linked list in the future.

Any comments about the patch?  Changes to the iterator functions or other
functions?

2007-06-20  Michael Meissner  <michael.meissner@amd.com>

	* tree.h (function_args_iterator): New type to iterate over
	function arguments.
	(FOREACH_FUNCTION_ARGS{,_PTR}): Iterator macros for iterating over
	function arguments.
	(function_args_iter_{init,cond_ptr,cond,next}): New inline
	functions for iterating over arguments that are called from the
	FOREACH_FUNCTION_ARGS macros.
	(num_parm_types): New function, return # of arguments.
	(alloc_parm_types): New function to allocate the TREE_CHAIN linked
	list for building function arguments.
	(stdarg_p): New function, return true if variable argument
	function.
	(prototype_p): New function, return true if function is
	prototyped.

	* tree.c (num_parm_types): New function, return # of arguments.
	(alloc_parm_types): New function to allocate the TREE_CHAIN linked
	list for building function arguments.
	(stdarg_p): New function, return true if variable argument
	function.
	(prototype_p): New function, return true if function is
	prototyped.

	* config/i386/i386.c (type_has_variadic_args_p): Delete in favor
	of stdarg_p.
	(ix86_return_pops_args): Use stdarg_p to determine if the function
	has variable arguments.
	(ix86_setup_incoming_varargs): Ditto.
	(x86_this_parameter): Ditto.

*** gcc/tree.h.~1~	2007-06-20 16:01:48.193106000 -0400
--- gcc/tree.h	2007-06-20 15:43:26.968724000 -0400
*************** extern GTY(()) tree current_function_dec
*** 4375,4380 ****
--- 4375,4439 ----
  /* Nonzero means a FUNC_BEGIN label was emitted.  */
  extern GTY(()) const char * current_function_func_begin_label;
  
+ /* Iterator for going through the function arguments.  */
+ typedef struct {
+   tree fntype;			/* function type declaration */
+   tree next;			/* TREE_LIST pointing to the next argument */
+ } function_args_iterator;
+ 
+ /* Initialize the iterator I with arguments from function FNDECL  */
+ 
+ static inline void
+ function_args_iter_init (function_args_iterator *i, tree fntype)
+ {
+   i->fntype = fntype;
+   i->next = TYPE_ARG_TYPES (fntype);
+ }
+ 
+ /* Return a pointer that holds the next argument if there are more arguments to
+    handle, otherwise return NULL.  */
+ 
+ static inline tree *
+ function_args_iter_cond_ptr (function_args_iterator *i)
+ {
+   return (i->next) ? &TREE_VALUE (i->next) : NULL;
+ }
+ 
+ /* Return the next argument if there are more arguments to handle, otherwise
+    return NULL.  */
+ 
+ static inline tree
+ function_args_iter_cond (function_args_iterator *i)
+ {
+   return (i->next) ? TREE_VALUE (i->next) : NULL_TREE;
+ }
+ 
+ /* Advance to the next argument.  */
+ static inline void
+ function_args_iter_next (function_args_iterator *i)
+ {
+   gcc_assert (i->next != NULL_TREE);
+   i->next = TREE_CHAIN (i->next);
+ }
+ 
+ /* Loop over all function arguments of FNTYPE.  In each iteration, PTR is set
+    to point to the next tree element.  ITER is an instance of
+    function_args_iterator used to iterate the arguments.  */
+ #define FOREACH_FUNCTION_ARGS_PTR(FNTYPE, PTR, ITER)			\
+   for (function_args_iter_init (&(ITER), (FNTYPE));			\
+        (PTR = function_args_iter_cond_ptr (&(ITER))) != NULL;		\
+        function_args_iter_next (&(ITER)))
+ 
+ /* Loop over all function arguments of FNTYPE.  In each iteration, TREE is set
+    to the next tree element.  ITER is an instance of function_args_iterator
+    used to iterate the arguments.  */
+ #define FOREACH_FUNCTION_ARGS(FNTYPE, TREE, ITER)			\
+   for (function_args_iter_init (&(ITER), (FNTYPE));			\
+        (TREE = function_args_iter_cond (&(ITER))) != NULL_TREE;		\
+        function_args_iter_next (&(ITER)))
+ 
+ 
+ 
  /* In tree.c */
  extern unsigned crc32_string (unsigned, const char *);
  extern void clean_symbol_name (char *);
*************** extern bool empty_body_p (tree);
*** 4391,4396 ****
--- 4450,4460 ----
  extern tree call_expr_arg (tree, int);
  extern tree *call_expr_argp (tree, int);
  extern tree call_expr_arglist (tree);
+ extern int num_parm_types (tree);
+ extern bool stdarg_p (tree);
+ extern bool prototype_p (tree);
+ extern tree alloc_parm_types (int);
+ 
  
  /* In stmt.c */
  
*** gcc/tree.c.~1~	2007-06-20 16:01:48.164146000 -0400
--- gcc/tree.c	2007-06-20 14:34:43.220108000 -0400
*************** call_expr_arglist (tree exp)
*** 8394,8397 ****
--- 8394,8452 ----
    return arglist;
  }
  
+ /* Return the number of elements in PARMTYPES, a list of parameter
+    types.  */
+ 
+ int
+ num_parm_types (tree parmtypes)
+ {
+   gcc_assert (parmtypes == NULL_TREE
+ 	      || TREE_CODE (parmtypes) == TREE_LIST);
+   return parmtypes ? list_length (parmtypes) : 0;
+ }
+ 
+ /* Allocate enough space to hold N arguments and return the value to store into
+    TYPE_ARG_TYPES field.  */
+ tree
+ alloc_parm_types (int n)
+ {
+   tree chain = NULL_TREE;
+ 
+   while (n-- > 0)
+     chain = tree_cons (NULL_TREE, NULL_TREE, chain);
+ 
+   return chain;
+ }
+ 
+ /* Return true if TYPE has a variable argument list.  */
+ 
+ bool
+ stdarg_p (tree fntype)
+ {
+   function_args_iterator args_iter;
+   tree n = NULL_TREE, t;
+ 
+   gcc_assert (fntype != NULL_TREE);
+ 
+   FOREACH_FUNCTION_ARGS(fntype, t, args_iter)
+     {
+       n = t;
+     }
+ 
+   return n != NULL_TREE && n != void_type_node;
+ }
+ 
+ /* Return true if TYPE has a prototype.  */
+ 
+ bool
+ prototype_p (tree fntype)
+ {
+   tree t;
+ 
+   gcc_assert (fntype != NULL_TREE);
+ 
+   t = TYPE_ARG_TYPES (fntype);
+   return (t != NULL_TREE);
+ }
+ 
  #include "gt-tree.h"
*** gcc/config/i386/i386.c.~1~	2007-06-20 16:01:48.906392000 -0400
--- gcc/config/i386/i386.c	2007-06-20 15:43:24.422273000 -0400
*************** ix86_eax_live_at_start_p (void)
*** 3024,3045 ****
    return REGNO_REG_SET_P (df_get_live_out (ENTRY_BLOCK_PTR), 0);
  }
  
- /* Return true if TYPE has a variable argument list.  */
- 
- static bool
- type_has_variadic_args_p (tree type)
- {
-   tree n, t = TYPE_ARG_TYPES (type);
- 
-   if (t == NULL)
-     return false;
- 
-   while ((n = TREE_CHAIN (t)) != NULL)
-     t = n;
- 
-   return TREE_VALUE (t) != void_type_node;
- }
- 
  /* Value is the number of bytes of arguments automatically
     popped when returning from a subroutine call.
     FUNDECL is the declaration node of the function (as a tree),
--- 3024,3029 ----
*************** ix86_return_pops_args (tree fundecl, tre
*** 3077,3083 ****
            || lookup_attribute ("fastcall", TYPE_ATTRIBUTES (funtype)))
  	rtd = 1;
  
!       if (rtd && ! type_has_variadic_args_p (funtype))
  	return size;
      }
  
--- 3061,3067 ----
            || lookup_attribute ("fastcall", TYPE_ATTRIBUTES (funtype)))
  	rtd = 1;
  
!       if (rtd && ! stdarg_p (funtype))
  	return size;
      }
  
*************** init_cumulative_args (CUMULATIVE_ARGS *c
*** 3177,3184 ****
    cum->warn_sse = true;
    cum->warn_mmx = true;
    cum->maybe_vaarg = (fntype
! 		      ? (!TYPE_ARG_TYPES (fntype)
! 			 || type_has_variadic_args_p (fntype))
  		      : !libname);
  
    if (!TARGET_64BIT)
--- 3161,3167 ----
    cum->warn_sse = true;
    cum->warn_mmx = true;
    cum->maybe_vaarg = (fntype
! 		      ? (!prototype_p (fntype) || stdarg_p (fntype))
  		      : !libname);
  
    if (!TARGET_64BIT)
*************** ix86_setup_incoming_varargs (CUMULATIVE_
*** 4749,4755 ****
  {
    CUMULATIVE_ARGS next_cum;
    tree fntype;
-   int stdarg_p;
  
    /* This argument doesn't appear to be used anymore.  Which is good,
       because the old code here didn't suppress rtl generation.  */
--- 4732,4737 ----
*************** ix86_setup_incoming_varargs (CUMULATIVE_
*** 4759,4772 ****
      return;
  
    fntype = TREE_TYPE (current_function_decl);
-   stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
- 	      && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
- 		  != void_type_node));
  
    /* For varargs, we do not want to skip the dummy va_dcl argument.
       For stdargs, we do want to skip the last named argument.  */
    next_cum = *cum;
!   if (stdarg_p)
      function_arg_advance (&next_cum, mode, type, 1);
  
    if (TARGET_64BIT_MS_ABI)
--- 4741,4751 ----
      return;
  
    fntype = TREE_TYPE (current_function_decl);
  
    /* For varargs, we do not want to skip the dummy va_dcl argument.
       For stdargs, we do want to skip the last named argument.  */
    next_cum = *cum;
!   if (stdarg_p (fntype))
      function_arg_advance (&next_cum, mode, type, 1);
  
    if (TARGET_64BIT_MS_ABI)
*************** x86_this_parameter (tree function)
*** 21037,21044 ****
        return gen_rtx_REG (DImode, parm_regs[aggr]);
      }
  
!   if (ix86_function_regparm (type, function) > 0
!       && !type_has_variadic_args_p (type))
      {
        int regno = 0;
        if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
--- 21016,21022 ----
        return gen_rtx_REG (DImode, parm_regs[aggr]);
      }
  
!   if (ix86_function_regparm (type, function) > 0 && !stdarg_p (type))
      {
        int regno = 0;
        if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))

-- 
Michael Meissner, AMD
90 Central Street, MS 83-29, Boxborough, MA, 01719, USA
michael.meissner@amd.com



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]