Patchwork [pr46489-20101217-branch] : hookize INIT_CUMULATIVE_*ARGS, CALL_POPS_ARGS

login
register
mail settings
Submitter Joern Rennecke
Date Dec. 19, 2010, 2:06 p.m.
Message ID <20101219090643.kfbltu2u40s4skwk-nzlynne@webmail.spamcop.net>
Download mbox | patch
Permalink /patch/76130/
State New
Headers show

Comments

Joern Rennecke - Dec. 19, 2010, 2:06 p.m.
2010-12-18  Joern Rennecke  <amylaar@spamcop.net>

gcc:
	* doc/tm.texi: Regenerate.
	* doc/tm.texi.in (CALL_POPS_ARGS): Change into ...
	(TARGET_CALL_POPS_ARGS): New hook.
	(TARGET_CUMULATIVE_ARGS_SIZE): New hook marker.
	(TARGET_INIT_CUMULATIVE_ARGS): Likewise.
	* targhooks.c (legacy_init_cumulative_args): New function.
	(init_simple_cumulative_args, hook_int_cumulative_args_0): Likewise.
	* targhooks.h (legacy_init_cumulative_args): Declare.
	(init_simple_cumulative_args, hook_int_cumulative_args_0): Likewise.
	* genrecog.c (write_header): Also include target.h.
	* genemit.c (main): Likewise.
	* genconditions.c (write_header): Likewise.
	* gengtype (do_typedef): Also special-case cumulative_args_t.
	(main): Likewise.
	* target.def (cumulative_args_size): New const pod "hook".
	(init_cumulative_args, call_pops_args): New hooks.
	* target.h (cumulative_args_t) Move from here ...
	* coretypes.h (cumulative_args_t): ... to here.
	* builtin.c (std_gimplify_va_arg_expr): Use pack_cumulative_args.
	* expr.c (block_move_libcall_safe_for_call_parm): Use new hooks.
	* dse.c (get_call_args): Likewise.
	* calls.c (emit_call_1, emit_library_call_value_1): Likewise.
	* function.c (pass_by_reference): Take a cumulative_args_t parameter.
	Changed all callers.
	(reference_callee_copied): Likewise.
	(struct assign_parm_data_all): Change type of args_so_far to
	cumulative_args_t.  Changed all users.
	(assign_parms_initialize_all): Take an extra void * parameter.
	Changed all callers.  Use new hooks.
	* function.h (struct incoming_arg) <info>: Change type to
	cumulative_args_t.  Changed all users.
	(pass_by_reference, reference_callee_copied): Update prototype.
	* calls.c (emit_call_1): Changed args_so_far to cumulative_args_t.
	Changed all callers.
	(initialize_argument_information): Likewise.
	* Makefile.in (insn-emit.o): Depend on $(TARGET_H).
	(insn-recog.o): Likewise.
	(build/gencondmd.o): Depend on target.h.
	* config/m32c/m32c.h (CALL_POPS_ARGS): Don't define.
	* config/sh/sh.c (TARGET_CALL_POPS_ARGS): Override.
	(sh_call_pops_args): New function.
	* config/sh/sh.h (CALL_POPS_ARGS): Don't define.
gcc/ada:
	* gcc-interface/misc.c (default_pass_by_ref): Update for new
	pass_by_reference signature.
Ralf Wildenhues - Dec. 19, 2010, 2:10 p.m.
Hi Joern,

a couple of nits:

* Joern Rennecke wrote on Sun, Dec 19, 2010 at 03:06:43PM CET:
> --- target.def	(revision 167989)
> +++ target.def	(working copy)
> @@ -1922,6 +1922,31 @@ HOOK_VECTOR (TARGET_CALLS, calls)
>   bool, (const_tree type),
>   hook_bool_const_tree_false)
>  
> +DEFHOOKPOD
> +(cumulative_args_size,
> + "The amount of memory, in bytes, that the caller should allocate when\
> + passing a non-@code{NULL} @var{mem} argument to the\
> + @code{init_cumulative_args} target hook.",
> +/* Once we  got all the  struct-user ports fully hookized, we can use
> +   sizeof(int) as  default.  */
> + const size_t, sizeof (CUMULATIVE_ARGS))
> +
> +DEFHOOK
> +(init_cumulative_args,
> + /* Still waiting on the FSF to allow us to put the full documentation here.  */
> + "Broadly like @code{INIT_CUMULATIVE_ARGS}, but it's a hook.\
> +  @var{mem} is a memory area to accomodate the target-specific data referred\

accommodate

> +  to by a cumulative_args_t.  It should be (at least) of the size that\

@code{cumulative_args_t} ?

> +  @code{TARGET_CUMULATIVE_ARGS_SIZE} indicates.\
> +  If @var{mem} is NULL, a statically allocated memory area is used.\
> +  When @var{libname} is set, @var{fntype} contains a type which is not\
> +  necessarily the actual return type, but which has the same machine mode.\
> +  The return value is a @code{cumulative_args_t} that refers to the\
> +  initialized argument information.",
> + cumulative_args_t,

Cheers,
Ralf

Patch

Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 167989)
+++ doc/tm.texi	(working copy)
@@ -3957,12 +3957,12 @@  nothing (the caller pops all).  When thi
 number of arguments.
 @end deftypefn
 
-@defmac CALL_POPS_ARGS (@var{cum})
+@deftypefn {Target Hook} int TARGET_CALL_POPS_ARGS (cumulative_args_t @var{ca})
 A C expression that should indicate the number of bytes a call sequence
 pops off the stack.  It is added to the value of @code{RETURN_POPS_ARGS}
 when compiling a function call.
 
-@var{cum} is the variable in which all arguments to the called function
+@var{ca} is the variable in which all arguments to the called function
 have been accumulated.
 
 On certain architectures, such as the SH5, a call trampoline is used
@@ -3970,7 +3970,7 @@  @defmac CALL_POPS_ARGS (@var{cum})
 that have been passed to the function.  Since this is a property of the
 call site, not of the called function, @code{RETURN_POPS_ARGS} is not
 appropriate.
-@end defmac
+@end deftypefn
 
 @node Register Arguments
 @subsection Passing Arguments in Registers
@@ -4125,6 +4125,14 @@  @defmac OVERRIDE_ABI_FORMAT (@var{fndecl
 @var{fndecl} may be @code{NULL}.
 @end defmac
 
+@deftypevr {Target Hook} {const size_t} TARGET_CUMULATIVE_ARGS_SIZE
+The amount of memory, in bytes, that the caller should allocate when passing a non-@code{NULL} @var{mem} argument to the @code{init_cumulative_args} target hook.
+@end deftypevr
+
+@deftypefn {Target Hook} cumulative_args_t TARGET_INIT_CUMULATIVE_ARGS (void *@var{mem}, tree @var{fntype}, rtx @var{libname}, tree @var{fndecl}, int @var{n_named})
+Broadly like @code{INIT_CUMULATIVE_ARGS}, but it's a hook.  @var{mem} is a memory area to accomodate the target-specific data referred  to by a cumulative_args_t.  It should be (at least) of the size that  @code{TARGET_CUMULATIVE_ARGS_SIZE} indicates.  If @var{mem} is NULL, a statically allocated memory area is used.  When @var{libname} is set, @var{fntype} contains a type which is not  necessarily the actual return type, but which has the same machine mode.  The return value is a @code{cumulative_args_t} that refers to the  initialized argument information.
+@end deftypefn
+
 @defmac INIT_CUMULATIVE_ARGS (@var{cum}, @var{fntype}, @var{libname}, @var{fndecl}, @var{n_named_args})
 A C statement (sans semicolon) for initializing the variable
 @var{cum} for the state at the beginning of the argument list.  The
Index: doc/tm.texi.in
===================================================================
--- doc/tm.texi.in	(revision 167989)
+++ doc/tm.texi.in	(working copy)
@@ -3945,12 +3945,12 @@  nothing (the caller pops all).  When thi
 number of arguments.
 @end deftypefn
 
-@defmac CALL_POPS_ARGS (@var{cum})
+@hook TARGET_CALL_POPS_ARGS
 A C expression that should indicate the number of bytes a call sequence
 pops off the stack.  It is added to the value of @code{RETURN_POPS_ARGS}
 when compiling a function call.
 
-@var{cum} is the variable in which all arguments to the called function
+@var{ca} is the variable in which all arguments to the called function
 have been accumulated.
 
 On certain architectures, such as the SH5, a call trampoline is used
@@ -3958,7 +3958,7 @@  @defmac CALL_POPS_ARGS (@var{cum})
 that have been passed to the function.  Since this is a property of the
 call site, not of the called function, @code{RETURN_POPS_ARGS} is not
 appropriate.
-@end defmac
+@end deftypefn
 
 @node Register Arguments
 @subsection Passing Arguments in Registers
@@ -4113,6 +4113,10 @@  @defmac OVERRIDE_ABI_FORMAT (@var{fndecl
 @var{fndecl} may be @code{NULL}.
 @end defmac
 
+@hook TARGET_CUMULATIVE_ARGS_SIZE
+
+@hook TARGET_INIT_CUMULATIVE_ARGS
+
 @defmac INIT_CUMULATIVE_ARGS (@var{cum}, @var{fntype}, @var{libname}, @var{fndecl}, @var{n_named_args})
 A C statement (sans semicolon) for initializing the variable
 @var{cum} for the state at the beginning of the argument list.  The
Index: targhooks.c
===================================================================
--- targhooks.c	(revision 167989)
+++ targhooks.c	(working copy)
@@ -167,6 +167,54 @@  default_expand_builtin_saveregs (void)
   return const0_rtx;
 }
 
+cumulative_args_t
+legacy_init_cumulative_args (void *mem, tree fntype ATTRIBUTE_UNUSED,
+			     rtx libname, tree fndecl ATTRIBUTE_UNUSED,
+			     int n_named_args ATTRIBUTE_UNUSED)
+{
+  static CUMULATIVE_ARGS static_args;
+  CUMULATIVE_ARGS *args_so_far;
+
+  if (mem == NULL)
+    mem = &static_args;
+  args_so_far = (CUMULATIVE_ARGS *) mem;
+  if (libname)
+    {
+#ifdef INIT_CUMULATIVE_LIBCALL_ARGS
+      INIT_CUMULATIVE_LIBCALL_ARGS (*args_so_far,
+				    TYPE_MODE (TREE_TYPE (fntype)),
+				    libname);
+      return pack_cumulative_args (args_so_far);
+#else
+      fntype = NULL_TREE;
+#endif
+    }
+#ifdef INIT_CUMULATIVE_INCOMING_ARGS
+  if (n_named_args < 0)
+    {
+      INIT_CUMULATIVE_INCOMING_ARGS (*args_so_far, fntype, libname);
+    }
+  else
+#endif
+    INIT_CUMULATIVE_ARGS (*args_so_far, fntype, libname, fndecl, n_named_args);
+  return pack_cumulative_args (args_so_far);
+}
+
+cumulative_args_t
+init_simple_cumulative_args (void *mem, tree fntype ATTRIBUTE_UNUSED,
+			     rtx libname ATTRIBUTE_UNUSED,
+			     tree fndecl ATTRIBUTE_UNUSED,
+			     int n_named_args ATTRIBUTE_UNUSED)
+{
+  static char static_args[sizeof (int)];
+
+  gcc_assert (sizeof static_args == targetm.calls.cumulative_args_size);
+  if (mem == NULL)
+    mem = &static_args;
+  memset (mem, 0, targetm.calls.cumulative_args_size);
+  return pack_cumulative_args ((CUMULATIVE_ARGS *) mem);
+}
+
 void
 default_setup_incoming_varargs (cumulative_args_t ca ATTRIBUTE_UNUSED,
 				enum machine_mode mode ATTRIBUTE_UNUSED,
@@ -588,6 +636,12 @@  hook_int_CUMULATIVE_ARGS_mode_tree_bool_
   return 0;
 }
 
+int
+hook_int_cumulative_args_0 (cumulative_args_t ca ATTRIBUTE_UNUSED)
+{
+  return 0;
+}
+
 void
 default_function_arg_advance (cumulative_args_t ca ATTRIBUTE_UNUSED,
 			      enum machine_mode mode ATTRIBUTE_UNUSED,
Index: targhooks.h
===================================================================
--- targhooks.h	(revision 167989)
+++ targhooks.h	(working copy)
@@ -35,6 +35,10 @@  extern enum machine_mode default_cc_mode
 extern bool default_return_in_memory (const_tree, const_tree);
 
 extern rtx default_expand_builtin_saveregs (void);
+extern cumulative_args_t legacy_init_cumulative_args
+  (void *mem, tree fntype, rtx libname, tree fndecl, int n_named_args);
+extern cumulative_args_t init_simple_cumulative_args
+  (void *mem, tree fntype, rtx libname, tree fndecl, int n_named_args);
 extern void default_setup_incoming_varargs (cumulative_args_t, enum machine_mode, tree, int *, int);
 extern rtx default_builtin_setjmp_frame_value (void);
 extern bool default_pretend_outgoing_varargs_named (cumulative_args_t);
@@ -106,6 +110,7 @@  extern bool hook_bool_CUMULATIVE_ARGS_tr
   (cumulative_args_t, enum machine_mode, const_tree, bool);
 extern int hook_int_CUMULATIVE_ARGS_mode_tree_bool_0
   (cumulative_args_t, enum machine_mode, tree, bool);
+extern int hook_int_cumulative_args_0 (cumulative_args_t);
 extern const char *hook_invalid_arg_for_unprototyped_fn
   (const_tree, const_tree, const_tree);
 extern void default_function_arg_advance
Index: genrecog.c
===================================================================
--- genrecog.c	(revision 167989)
+++ genrecog.c	(working copy)
@@ -2439,6 +2439,7 @@  write_header (void)
 #include \"system.h\"\n\
 #include \"coretypes.h\"\n\
 #include \"tm.h\"\n\
+#include \"target.h\"\n\
 #include \"rtl.h\"\n\
 #include \"tm_p.h\"\n\
 #include \"function.h\"\n\
Index: gengtype.c
===================================================================
--- gengtype.c	(revision 167989)
+++ gengtype.c	(working copy)
@@ -497,6 +497,8 @@  do_typedef (const char *s, type_p t, str
      definitions).  */
   if (!strcmp (s, "CUMULATIVE_ARGS") && pos->file != this_file)
     return;
+  if (!strcmp (s, "cumulative_args_t") && pos->file != this_file)
+    return;
 
   for (p = typedefs; p != NULL; p = p->next)
     if (strcmp (p->name, s) == 0)
@@ -4871,6 +4873,7 @@  main (int argc, char **argv)
 #define POS_HERE(Call) do { pos.file = this_file; pos.line = __LINE__; \
 	Call;} while(0)
       POS_HERE (do_scalar_typedef ("CUMULATIVE_ARGS", &pos));
+      POS_HERE (do_scalar_typedef ("cumulative_args_t", &pos));
       POS_HERE (do_scalar_typedef ("REAL_VALUE_TYPE", &pos));
       POS_HERE (do_scalar_typedef ("FIXED_VALUE_TYPE", &pos));
       POS_HERE (do_scalar_typedef ("double_int", &pos));
Index: target.def
===================================================================
--- target.def	(revision 167989)
+++ target.def	(working copy)
@@ -1922,6 +1922,31 @@  HOOK_VECTOR (TARGET_CALLS, calls)
  bool, (const_tree type),
  hook_bool_const_tree_false)
 
+DEFHOOKPOD
+(cumulative_args_size,
+ "The amount of memory, in bytes, that the caller should allocate when\
+ passing a non-@code{NULL} @var{mem} argument to the\
+ @code{init_cumulative_args} target hook.",
+/* Once we  got all the  struct-user ports fully hookized, we can use
+   sizeof(int) as  default.  */
+ const size_t, sizeof (CUMULATIVE_ARGS))
+
+DEFHOOK
+(init_cumulative_args,
+ /* Still waiting on the FSF to allow us to put the full documentation here.  */
+ "Broadly like @code{INIT_CUMULATIVE_ARGS}, but it's a hook.\
+  @var{mem} is a memory area to accomodate the target-specific data referred\
+  to by a cumulative_args_t.  It should be (at least) of the size that\
+  @code{TARGET_CUMULATIVE_ARGS_SIZE} indicates.\
+  If @var{mem} is NULL, a statically allocated memory area is used.\
+  When @var{libname} is set, @var{fntype} contains a type which is not\
+  necessarily the actual return type, but which has the same machine mode.\
+  The return value is a @code{cumulative_args_t} that refers to the\
+  initialized argument information.",
+ cumulative_args_t,
+ (void *mem, tree fntype, rtx libname, tree fndecl, int n_named),
+ legacy_init_cumulative_args)
+
 /* Return true if a parameter must be passed by reference.  TYPE may
    be null if this is a libcall.  CA may be null if this query is
    from __builtin_va_arg.  */
@@ -2129,6 +2154,12 @@  HOOK_VECTOR (TARGET_CALLS, calls)
  int, (tree fundecl, tree funtype, int size),
  default_return_pops_args)
 
+DEFHOOK
+(call_pops_args,
+ "",
+ int, (cumulative_args_t ca),
+ hook_int_cumulative_args_0)
+
 /* Return a mode wide enough to copy any function value that might be
    returned.  */
 DEFHOOK
Index: target.h
===================================================================
--- target.h	(revision 167989)
+++ target.h	(working copy)
@@ -51,22 +51,6 @@ 
 
 #include "insn-modes.h"
 
-#ifdef ENABLE_CHECKING
-
-typedef struct { void *magic; void *p; } cumulative_args_t;
-
-#else /* !ENABLE_CHECKING */
-
-#ifdef __GNUC__
-#define ATTRIBUTE_TRANSPARENT_UNION __attribute__((transparent_union))
-#else
-#define ATTRIBUTE_TRANSPARENT_UNION
-#endif
-
-typedef union ATTRIBUTE_TRANSPARENT_UNION { void *p; } cumulative_args_t;
-
-#endif /* !ENABLE_CHECKING */
-
 /* Types used by the record_gcc_switches() target function.  */
 typedef enum
 {
Index: builtins.c
===================================================================
--- builtins.c	(revision 167989)
+++ builtins.c	(working copy)
@@ -4698,7 +4698,8 @@  std_gimplify_va_arg_expr (tree valist, t
   gcc_unreachable ();
 #endif
 
-  indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
+  indirect = pass_by_reference (pack_cumulative_args (NULL), TYPE_MODE (type),
+				type, false);
   if (indirect)
     type = build_pointer_type (type);
 
Index: genemit.c
===================================================================
--- genemit.c	(revision 167989)
+++ genemit.c	(working copy)
@@ -849,6 +849,7 @@  main (int argc, char **argv)
   printf ("#include \"system.h\"\n");
   printf ("#include \"coretypes.h\"\n");
   printf ("#include \"tm.h\"\n");
+  printf ("#include \"target.h\"\n");
   printf ("#include \"rtl.h\"\n");
   printf ("#include \"tm_p.h\"\n");
   printf ("#include \"function.h\"\n");
Index: expr.c
===================================================================
--- expr.c	(revision 167989)
+++ expr.c	(working copy)
@@ -1228,26 +1228,27 @@  block_move_libcall_safe_for_call_parm (v
   /* If any argument goes in memory, then it might clobber an outgoing
      argument.  */
   {
-    CUMULATIVE_ARGS args_so_far;
+    void *args_so_far_mem;
+    cumulative_args_t args_so_far;
     tree fn, arg;
 
     fn = emit_block_move_libcall_fn (false);
-    INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (fn), NULL_RTX, 0, 3);
+    args_so_far_mem = alloca (targetm.calls.cumulative_args_size);
+    args_so_far
+      = targetm.calls.init_cumulative_args (args_so_far_mem, TREE_TYPE (fn),
+					    NULL_RTX, 0, 3);
 
     arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
     for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
       {
 	enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
 	rtx tmp
-	  = targetm.calls.function_arg (pack_cumulative_args (&args_so_far),
-					mode, NULL_TREE, true);
+	  = targetm.calls.function_arg (args_so_far, mode, NULL_TREE, true);
 	if (!tmp || !REG_P (tmp))
 	  return false;
-	if (targetm.calls.arg_partial_bytes
-	     (pack_cumulative_args (&args_so_far), mode, NULL, 1))
+	if (targetm.calls.arg_partial_bytes (args_so_far, mode, NULL, 1))
 	  return false;
-	targetm.calls.function_arg_advance (pack_cumulative_args (&args_so_far),
-					    mode, NULL_TREE, true);
+	targetm.calls.function_arg_advance (args_so_far, mode, NULL_TREE, true);
       }
   }
   return true;
Index: genconditions.c
===================================================================
--- genconditions.c	(revision 167989)
+++ genconditions.c	(working copy)
@@ -70,6 +70,7 @@  write_header (void)
 \n\
 #include \"coretypes.h\"\n\
 #include \"tm.h\"\n\
+#include \"target.h\"\n\
 #include \"insn-constants.h\"\n\
 #include \"rtl.h\"\n\
 #include \"tm_p.h\"\n\
Index: ada/gcc-interface/misc.c
===================================================================
--- ada/gcc-interface/misc.c	(revision 167989)
+++ ada/gcc-interface/misc.c	(working copy)
@@ -623,7 +623,8 @@  default_pass_by_ref (tree gnu_type)
      is an In Out parameter, but it's probably best to err on the side of
      passing more things by reference.  */
 
-  if (pass_by_reference (NULL, TYPE_MODE (gnu_type), gnu_type, true))
+  if (pass_by_reference (pack_cumulative_args (NULL), TYPE_MODE (gnu_type),
+			 gnu_type, true))
     return true;
 
   if (targetm.calls.return_in_memory (gnu_type, NULL_TREE))
Index: dse.c
===================================================================
--- dse.c	(revision 167989)
+++ dse.c	(working copy)
@@ -2309,11 +2309,15 @@  check_mem_read_use (rtx *loc, void *data
 static bool
 get_call_args (rtx call_insn, tree fn, rtx *args, int nargs)
 {
-  CUMULATIVE_ARGS args_so_far;
+  void *args_so_far_mem;
+  cumulative_args_t args_so_far;
   tree arg;
   int idx;
 
-  INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (fn), NULL_RTX, 0, 3);
+  args_so_far_mem = alloca (targetm.calls.cumulative_args_size);
+  args_so_far
+    = targetm.calls.init_cumulative_args (args_so_far_mem, TREE_TYPE (fn),
+					  NULL_RTX, 0, 3);
 
   arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
   for (idx = 0;
@@ -2322,8 +2326,7 @@  get_call_args (rtx call_insn, tree fn, r
     {
       enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
       rtx reg, link, tmp;
-      reg = targetm.calls.function_arg (pack_cumulative_args (&args_so_far),
-					mode, NULL_TREE, true);
+      reg = targetm.calls.function_arg (args_so_far, mode, NULL_TREE, true);
       if (!reg || !REG_P (reg) || GET_MODE (reg) != mode
 	  || GET_MODE_CLASS (mode) != MODE_INT)
 	return false;
@@ -2357,8 +2360,7 @@  get_call_args (rtx call_insn, tree fn, r
       if (tmp)
 	args[idx] = tmp;
 
-      targetm.calls.function_arg_advance (pack_cumulative_args (&args_so_far),
-					  mode, NULL_TREE, true);
+      targetm.calls.function_arg_advance (args_so_far, mode, NULL_TREE, true);
     }
   if (arg != void_list_node || idx != nargs)
     return false;
Index: function.c
===================================================================
--- function.c	(revision 167989)
+++ function.c	(working copy)
@@ -2083,7 +2083,7 @@  use_register_for_decl (const_tree decl)
 /* Return true if TYPE should be passed by invisible reference.  */
 
 bool
-pass_by_reference (CUMULATIVE_ARGS *ca, enum machine_mode mode,
+pass_by_reference (cumulative_args_t ca, enum machine_mode mode,
 		   tree type, bool named_arg)
 {
   if (type)
@@ -2106,20 +2106,19 @@  pass_by_reference (CUMULATIVE_ARGS *ca, 
 	}
     }
 
-  return targetm.calls.pass_by_reference (pack_cumulative_args (ca), mode,
-					  type, named_arg);
+  return targetm.calls.pass_by_reference (ca, mode, type, named_arg);
 }
 
 /* Return true if TYPE, which is passed by reference, should be callee
    copied instead of caller copied.  */
 
 bool
-reference_callee_copied (CUMULATIVE_ARGS *ca, enum machine_mode mode,
+reference_callee_copied (cumulative_args_t ca, enum machine_mode mode,
 			 tree type, bool named_arg)
 {
   if (type && TREE_ADDRESSABLE (type))
     return false;
-  return targetm.calls.callee_copies (pack_cumulative_args (ca), mode, type, named_arg);
+  return targetm.calls.callee_copies (ca, mode, type, named_arg);
 }
 
 /* Structures to communicate between the subroutines of assign_parms.
@@ -2128,7 +2127,7 @@  reference_callee_copied (CUMULATIVE_ARGS
 
 struct assign_parm_data_all
 {
-  CUMULATIVE_ARGS args_so_far;
+  cumulative_args_t args_so_far;
   struct args_size stack_args_size;
   tree function_result_decl;
   tree orig_fnargs;
@@ -2159,7 +2158,7 @@  struct assign_parm_data_one
 /* A subroutine of assign_parms.  Initialize ALL.  */
 
 static void
-assign_parms_initialize_all (struct assign_parm_data_all *all)
+assign_parms_initialize_all (struct assign_parm_data_all *all, void *mem)
 {
   tree fntype ATTRIBUTE_UNUSED;
 
@@ -2167,12 +2166,9 @@  assign_parms_initialize_all (struct assi
 
   fntype = TREE_TYPE (current_function_decl);
 
-#ifdef INIT_CUMULATIVE_INCOMING_ARGS
-  INIT_CUMULATIVE_INCOMING_ARGS (all->args_so_far, fntype, NULL_RTX);
-#else
-  INIT_CUMULATIVE_ARGS (all->args_so_far, fntype, NULL_RTX,
-			current_function_decl, -1);
-#endif
+  all->args_so_far
+    = targetm.calls.init_cumulative_args (mem, fntype, NULL_RTX,
+					  current_function_decl, -1);
 
 #ifdef REG_PARM_STACK_SPACE
   all->reg_parm_stack_space = REG_PARM_STACK_SPACE (current_function_decl);
@@ -2292,8 +2288,7 @@  assign_parm_find_data_types (struct assi
     data->named_arg = 1;  /* No variadic parms.  */
   else if (DECL_CHAIN (parm))
     data->named_arg = 1;  /* Not the last non-variadic parm. */
-  else if (targetm.calls.strict_argument_naming
-	    (pack_cumulative_args (&all->args_so_far)))
+  else if (targetm.calls.strict_argument_naming (all->args_so_far))
     data->named_arg = 1;  /* Only variadic ones are unnamed.  */
   else
     data->named_arg = 0;  /* Treat as variadic.  */
@@ -2329,7 +2324,7 @@  assign_parm_find_data_types (struct assi
     passed_type = TREE_TYPE (first_field (passed_type));
 
   /* See if this arg was passed by invisible reference.  */
-  if (pass_by_reference (&all->args_so_far, passed_mode,
+  if (pass_by_reference (all->args_so_far, passed_mode,
 			 passed_type, data->named_arg))
     {
       passed_type = nominal_type = build_pointer_type (passed_type);
@@ -2358,9 +2353,9 @@  assign_parms_setup_varargs (struct assig
 {
   int varargs_pretend_bytes = 0;
 
-  (targetm.calls.setup_incoming_varargs
-    (pack_cumulative_args (&all->args_so_far), data->promoted_mode,
-			   data->passed_type, &varargs_pretend_bytes, no_rtl));
+  targetm.calls.setup_incoming_varargs (all->args_so_far, data->promoted_mode,
+					data->passed_type,
+					&varargs_pretend_bytes, no_rtl);
 
   /* If the back-end has requested extra stack space, record how much is
      needed.  Do not change pretend_args_size otherwise since it may be
@@ -2387,7 +2382,7 @@  assign_parm_find_entry_rtl (struct assig
     }
 
   entry_parm = (targetm.calls.function_incoming_arg
-		 (pack_cumulative_args (&all->args_so_far),
+		 (all->args_so_far,
 		  data->promoted_mode, data->passed_type, data->named_arg));
 
   if (entry_parm == 0)
@@ -2409,12 +2404,11 @@  assign_parm_find_entry_rtl (struct assig
 #endif
   if (!in_regs && !data->named_arg)
     {
-      if (targetm.calls.pretend_outgoing_varargs_named
-	   (pack_cumulative_args (&all->args_so_far)))
+      if (targetm.calls.pretend_outgoing_varargs_named (all->args_so_far))
 	{
 	  rtx tem;
 	  tem = (targetm.calls.function_incoming_arg
-		  (pack_cumulative_args (&all->args_so_far),
+		  (all->args_so_far,
 		   data->promoted_mode, data->passed_type, true));
 	  in_regs = tem != NULL;
 	}
@@ -2431,7 +2425,7 @@  assign_parm_find_entry_rtl (struct assig
       int partial;
 
       partial = (targetm.calls.arg_partial_bytes
-		  (pack_cumulative_args (&all->args_so_far),
+		  (all->args_so_far,
 		   data->promoted_mode, data->passed_type, data->named_arg));
       data->partial = partial;
 
@@ -3309,7 +3303,9 @@  assign_parms (tree fndecl)
   crtl->args.internal_arg_pointer
     = targetm.calls.internal_arg_pointer ();
 
-  assign_parms_initialize_all (&all);
+  /* We will be storing all.args_so_far in crtl, so use the statically
+     allocated CUMULATIVE_ARGS.  */
+  assign_parms_initialize_all (&all, NULL);
   fnargs = assign_parms_augmented_arg_list (&all);
 
   FOR_EACH_VEC_ELT (tree, fnargs, i, parm)
@@ -3363,9 +3359,8 @@  assign_parms (tree fndecl)
       set_decl_incoming_rtl (parm, data.entry_parm, data.passed_pointer);
 
       /* Update info on where next arg arrives in registers.  */
-      (targetm.calls.function_arg_advance
-	(pack_cumulative_args (&all.args_so_far), data.promoted_mode,
-			       data.passed_type, data.named_arg));
+      targetm.calls.function_arg_advance (all.args_so_far, data.promoted_mode,
+					  data.passed_type, data.named_arg);
 
       assign_parm_adjust_stack_rtl (&data);
 
@@ -3539,7 +3534,8 @@  gimplify_parameters (void)
   VEC(tree, heap) *fnargs;
   unsigned i;
 
-  assign_parms_initialize_all (&all);
+  assign_parms_initialize_all (&all,
+			       alloca (targetm.calls.cumulative_args_size));
   fnargs = assign_parms_augmented_arg_list (&all);
 
   FOR_EACH_VEC_ELT (tree, fnargs, i, parm)
@@ -3554,9 +3550,8 @@  gimplify_parameters (void)
 	continue;
 
       /* Update info on where next arg arrives in registers.  */
-      (targetm.calls.function_arg_advance
-	(pack_cumulative_args (&all.args_so_far), data.promoted_mode,
-			       data.passed_type, data.named_arg));
+      targetm.calls.function_arg_advance (all.args_so_far, data.promoted_mode,
+					  data.passed_type, data.named_arg);
 
       /* ??? Once upon a time variable_size stuffed parameter list
 	 SAVE_EXPRs (amongst others) onto a pending sizes list.  This
@@ -3574,7 +3569,7 @@  gimplify_parameters (void)
       if (data.passed_pointer)
 	{
           tree type = TREE_TYPE (data.passed_type);
-	  if (reference_callee_copied (&all.args_so_far, TYPE_MODE (type),
+	  if (reference_callee_copied (all.args_so_far, TYPE_MODE (type),
 				       type, data.named_arg))
 	    {
 	      tree local, t;
Index: function.h
===================================================================
--- function.h	(revision 167989)
+++ function.h	(working copy)
@@ -210,7 +210,7 @@  struct GTY(()) incoming_args {
 
   /* Quantities of various kinds of registers
      used for the current function's args.  */
-  CUMULATIVE_ARGS info;
+  cumulative_args_t info;
 
   /* The arg pointer hard register, or the pseudo into which it was copied.  */
   rtx internal_arg_pointer;
@@ -746,9 +746,9 @@  extern const char *current_function_name
 
 extern void do_warn_unused_parameter (tree);
 
-extern bool pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
+extern bool pass_by_reference (cumulative_args_t, enum machine_mode,
 			       tree, bool);
-extern bool reference_callee_copied (CUMULATIVE_ARGS *, enum machine_mode,
+extern bool reference_callee_copied (cumulative_args_t, enum machine_mode,
 				     tree, bool);
 
 extern void used_types_insert (tree);
Index: coretypes.h
===================================================================
--- coretypes.h	(revision 167989)
+++ coretypes.h	(working copy)
@@ -157,6 +157,24 @@  #define gcc_obstack_init(OBSTACK)			\
    in target.h.  */
 typedef int reg_class_t;
 
+/* cumulative_args_t is needed for target.h and function.h .  */
+
+#ifdef ENABLE_CHECKING
+
+typedef struct { void *magic; void *p; } cumulative_args_t;
+
+#else /* !ENABLE_CHECKING */
+
+#ifdef __GNUC__
+#define ATTRIBUTE_TRANSPARENT_UNION __attribute__((transparent_union))
+#else
+#define ATTRIBUTE_TRANSPARENT_UNION
+#endif
+
+typedef union ATTRIBUTE_TRANSPARENT_UNION { void *p; } cumulative_args_t;
+
+#endif /* !ENABLE_CHECKING */
+
 #else
 
 struct _dont_use_rtx_here_;
Index: calls.c
===================================================================
--- calls.c	(revision 167989)
+++ calls.c	(working copy)
@@ -126,7 +126,7 @@  struct arg_data
 
 static void emit_call_1 (rtx, tree, tree, tree, HOST_WIDE_INT, HOST_WIDE_INT,
 			 HOST_WIDE_INT, rtx, rtx, int, rtx, int,
-			 CUMULATIVE_ARGS *);
+			 cumulative_args_t);
 static void precompute_register_parameters (int, struct arg_data *, int *);
 static int store_one_arg (struct arg_data *, rtx, int, int, int);
 static void store_unaligned_arguments_into_pseudos (struct arg_data *, int);
@@ -137,7 +137,7 @@  static int compute_argument_block_size (
 static void initialize_argument_information (int, struct arg_data *,
 					     struct args_size *, int,
 					     tree, tree,
-					     tree, tree, CUMULATIVE_ARGS *, int,
+					     tree, tree, cumulative_args_t, int,
 					     rtx *, int *, int *, int *,
 					     bool *, bool);
 static void compute_argument_addresses (struct arg_data *, rtx, int);
@@ -253,7 +253,7 @@  emit_call_1 (rtx funexp, tree fntree ATT
 	     HOST_WIDE_INT struct_value_size ATTRIBUTE_UNUSED,
 	     rtx next_arg_reg ATTRIBUTE_UNUSED, rtx valreg,
 	     int old_inhibit_defer_pop, rtx call_fusage, int ecf_flags,
-	     CUMULATIVE_ARGS *args_so_far ATTRIBUTE_UNUSED)
+	     cumulative_args_t args_so_far ATTRIBUTE_UNUSED)
 {
   rtx rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
   rtx call_insn;
@@ -261,9 +261,7 @@  emit_call_1 (rtx funexp, tree fntree ATT
   HOST_WIDE_INT n_popped
     = targetm.calls.return_pops_args (fndecl, funtype, stack_size);
 
-#ifdef CALL_POPS_ARGS
-  n_popped += CALL_POPS_ARGS (* args_so_far);
-#endif
+  n_popped += targetm.calls.call_pops_args (args_so_far);
 
   /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
      and we don't want to load it into a register as an optimization,
@@ -946,7 +944,7 @@  initialize_argument_information (int num
 				 int n_named_args ATTRIBUTE_UNUSED,
 				 tree exp, tree struct_value_addr_value,
 				 tree fndecl, tree fntype,
-				 CUMULATIVE_ARGS *args_so_far,
+				 cumulative_args_t args_so_far,
 				 int reg_parm_stack_space,
 				 rtx *old_stack_level, int *old_pending_adj,
 				 int *must_preallocate, int *ecf_flags,
@@ -1138,9 +1136,8 @@  initialize_argument_information (int num
       args[i].unsignedp = unsignedp;
       args[i].mode = mode;
 
-      args[i].reg
-	= targetm.calls.function_arg (pack_cumulative_args (args_so_far), mode,
-				      type, argpos < n_named_args);
+      args[i].reg = targetm.calls.function_arg (args_so_far, mode,
+						type, argpos < n_named_args);
 
       /* If this is a sibling call and the machine has register windows, the
 	 register window has to be unwinded before calling the routine, so
@@ -1148,14 +1145,13 @@  initialize_argument_information (int num
       if (targetm.calls.function_incoming_arg != targetm.calls.function_arg)
 	args[i].tail_call_reg
 	  = (targetm.calls.function_incoming_arg
-	      (pack_cumulative_args (args_so_far), mode, type,
-	       argpos < n_named_args));
+	      (args_so_far, mode, type, argpos < n_named_args));
       else
 	args[i].tail_call_reg = args[i].reg;
 
       if (args[i].reg)
 	args[i].partial
-	  = targetm.calls.arg_partial_bytes (pack_cumulative_args (args_so_far),
+	  = targetm.calls.arg_partial_bytes (args_so_far,
 					     mode, type, argpos < n_named_args);
 
       args[i].pass_on_stack = targetm.calls.must_pass_in_stack (mode, type);
@@ -1206,8 +1202,7 @@  initialize_argument_information (int num
       /* Increment ARGS_SO_FAR, which has info about which arg-registers
 	 have been used, etc.  */
 
-      targetm.calls.function_arg_advance (pack_cumulative_args (args_so_far),
-					  TYPE_MODE (type),
+      targetm.calls.function_arg_advance (args_so_far, TYPE_MODE (type),
 					  type, argpos < n_named_args);
     }
 }
@@ -1991,7 +1986,8 @@  expand_call (tree exp, rtx target, int i
   /* Size of arguments before any adjustments (such as rounding).  */
   int unadjusted_args_size;
   /* Data on reg parms scanned so far.  */
-  CUMULATIVE_ARGS args_so_far;
+  void *args_so_far_mem;
+  cumulative_args_t args_so_far;
   /* Nonzero if a reg parm has been scanned.  */
   int reg_parm_seen;
   /* Nonzero if this is an indirect function call.  */
@@ -2212,7 +2208,7 @@  expand_call (tree exp, rtx target, int i
     call_expr_nargs (exp) + num_complex_actuals + structure_value_addr_parm;
 
   /* Compute number of named args.
-     First, do a raw count of the args for INIT_CUMULATIVE_ARGS.  */
+     First, do a raw count of the args for init_cumulative_args.  */
 
   if (type_arg_types != 0)
     n_named_args
@@ -2227,9 +2223,12 @@  expand_call (tree exp, rtx target, int i
 
      On some machines (such as the PA) indirect calls have a different
      calling convention than normal calls.  The fourth argument in
-     INIT_CUMULATIVE_ARGS tells the backend if this is an indirect call
+     init_cumulative_args tells the backend if this is an indirect call
      or not.  */
-  INIT_CUMULATIVE_ARGS (args_so_far, funtype, NULL_RTX, fndecl, n_named_args);
+  args_so_far_mem = alloca (targetm.calls.cumulative_args_size);
+  args_so_far
+    = targetm.calls.init_cumulative_args (args_so_far_mem, funtype, NULL_RTX,
+					  fndecl, n_named_args);
 
   /* Now possibly adjust the number of named args.
      Normally, don't include the last named arg if anonymous args follow.
@@ -2250,12 +2249,10 @@  expand_call (tree exp, rtx target, int i
      registers, so we must force them into memory.  */
 
   if (type_arg_types != 0
-      && (targetm.calls.strict_argument_naming
-	   (pack_cumulative_args (&args_so_far))))
+      && (targetm.calls.strict_argument_naming (args_so_far)))
     ;
   else if (type_arg_types != 0
-	   && ! (targetm.calls.pretend_outgoing_varargs_named
-		  (pack_cumulative_args (&args_so_far))))
+	   && ! (targetm.calls.pretend_outgoing_varargs_named (args_so_far)))
     /* Don't include the last named arg.  */
     --n_named_args;
   else
@@ -2271,7 +2268,7 @@  expand_call (tree exp, rtx target, int i
   initialize_argument_information (num_actuals, args, &args_size,
 				   n_named_args, exp,
 				   structure_value_addr_value, fndecl, fntype,
-				   &args_so_far, reg_parm_stack_space,
+				   args_so_far, reg_parm_stack_space,
 				   &old_stack_level, &old_pending_adj,
 				   &must_preallocate, &flags,
 				   &try_tail_call, CALL_FROM_THUNK_P (exp));
@@ -2867,11 +2864,10 @@  expand_call (tree exp, rtx target, int i
 	 with register windows this should be the incoming register.  */
       if (pass == 0)
 	next_arg_reg = (targetm.calls.function_incoming_arg
-			 (pack_cumulative_args (&args_so_far), VOIDmode,
-			  void_type_node, true));
+			 (args_so_far, VOIDmode, void_type_node, true));
       else
 	next_arg_reg
-	  = targetm.calls.function_arg (pack_cumulative_args (&args_so_far),
+	  = targetm.calls.function_arg (args_so_far,
 					VOIDmode, void_type_node, true);
 
       /* All arguments and registers used for the call must be set up by
@@ -2885,7 +2881,7 @@  expand_call (tree exp, rtx target, int i
       emit_call_1 (funexp, exp, fndecl, funtype, unadjusted_args_size,
 		   adjusted_args_size.constant, struct_value_size,
 		   next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
-		   flags, & args_so_far);
+		   flags, args_so_far);
 
       /* If the call setup or the call itself overlaps with anything
 	 of the argument setup we probably clobbered our call address.
@@ -3318,7 +3314,8 @@  emit_library_call_value_1 (int retval, r
   int inc;
   int count;
   rtx argblock = 0;
-  CUMULATIVE_ARGS args_so_far;
+  void *args_so_far_mem;
+  cumulative_args_t args_so_far;
   struct arg
   {
     rtx value;
@@ -3429,11 +3426,9 @@  emit_library_call_value_1 (int retval, r
   argvec = XALLOCAVEC (struct arg, nargs + 1);
   memset (argvec, 0, (nargs + 1) * sizeof (struct arg));
 
-#ifdef INIT_CUMULATIVE_LIBCALL_ARGS
-  INIT_CUMULATIVE_LIBCALL_ARGS (args_so_far, outmode, fun);
-#else
-  INIT_CUMULATIVE_ARGS (args_so_far, NULL_TREE, fun, 0, nargs);
-#endif
+  args_so_far_mem = alloca (targetm.calls.cumulative_args_size);
+  args_so_far
+    = targetm.calls.init_cumulative_args (args_so_far_mem, tfom, fun, 0, nargs);
 
   args_size.constant = 0;
   args_size.var = 0;
@@ -3460,10 +3455,9 @@  emit_library_call_value_1 (int retval, r
       argvec[count].partial = 0;
 
       argvec[count].reg
-	= targetm.calls.function_arg (pack_cumulative_args (&args_so_far),
-				      Pmode, NULL_TREE, true);
+	= targetm.calls.function_arg (args_so_far, Pmode, NULL_TREE, true);
       gcc_assert ((targetm.calls.arg_partial_bytes
-		    (pack_cumulative_args (&args_so_far), Pmode, NULL_TREE, 1))
+		    (args_so_far, Pmode, NULL_TREE, 1))
 		  == 0);
 
       locate_and_pad_parm (Pmode, NULL_TREE,
@@ -3478,8 +3472,7 @@  emit_library_call_value_1 (int retval, r
 	  || reg_parm_stack_space > 0)
 	args_size.constant += argvec[count].locate.size.constant;
 
-      targetm.calls.function_arg_advance (pack_cumulative_args (&args_so_far),
-					  Pmode, (tree) 0, true);
+      targetm.calls.function_arg_advance (args_so_far, Pmode, (tree) 0, true);
 
       count++;
     }
@@ -3499,11 +3492,11 @@  emit_library_call_value_1 (int retval, r
 	  && ! (CONSTANT_P (val) && LEGITIMATE_CONSTANT_P (val)))
 	val = force_operand (val, NULL_RTX);
 
-      if (pass_by_reference (&args_so_far, mode, NULL_TREE, 1))
+      if (pass_by_reference (args_so_far, mode, NULL_TREE, 1))
 	{
 	  rtx slot;
 	  int must_copy
-	    = !reference_callee_copied (&args_so_far, mode, NULL_TREE, 1);
+	    = !reference_callee_copied (args_so_far, mode, NULL_TREE, 1);
 
 	  /* If this was a CONST function, it is now PURE since it now
 	     reads memory.  */
@@ -3539,12 +3532,10 @@  emit_library_call_value_1 (int retval, r
       argvec[count].mode = mode;
 
       argvec[count].reg
-	= targetm.calls.function_arg (pack_cumulative_args (&args_so_far),
-				      mode, NULL_TREE, true);
+	= targetm.calls.function_arg (args_so_far, mode, NULL_TREE, true);
 
       argvec[count].partial
-	= targetm.calls.arg_partial_bytes (pack_cumulative_args (&args_so_far),
-					   mode, NULL_TREE, 1);
+	= targetm.calls.arg_partial_bytes (args_so_far, mode, NULL_TREE, 1);
 
       locate_and_pad_parm (mode, NULL_TREE,
 #ifdef STACK_PARMS_IN_REG_PARM_AREA
@@ -3561,8 +3552,7 @@  emit_library_call_value_1 (int retval, r
 	  || reg_parm_stack_space > 0)
 	args_size.constant += argvec[count].locate.size.constant;
 
-      targetm.calls.function_arg_advance (pack_cumulative_args (&args_so_far),
-					  mode, (tree) 0, true);
+      targetm.calls.function_arg_advance (args_so_far, mode, (tree) 0, true);
     }
 
   /* If this machine requires an external definition for library
@@ -3878,10 +3868,10 @@  emit_library_call_value_1 (int retval, r
 	       build_function_type (tfom, NULL_TREE),
 	       original_args_size.constant, args_size.constant,
 	       struct_value_size,
-	       targetm.calls.function_arg (pack_cumulative_args (&args_so_far),
+	       targetm.calls.function_arg (args_so_far,
 					   VOIDmode, void_type_node, true),
 	       valreg,
-	       old_inhibit_defer_pop + 1, call_fusage, flags, & args_so_far);
+	       old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far);
 
   /* For calls to `setjmp', etc., inform function.c:setjmp_warnings
      that it should complain if nonvolatile values are live.  For
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 167989)
+++ Makefile.in	(working copy)
@@ -3576,7 +3576,7 @@  insn-automata.o : insn-automata.c $(CONF
   $(TM_H) $(RTL_H) $(REGS_H) output.h $(INSN_ATTR_H)			\
   insn-config.h toplev.h $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(TM_P_H) $(FLAGS_H) $(EMIT_RTL_H)
 insn-emit.o : insn-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)	\
-  $(RTL_H) $(TM_P_H) $(FUNCTION_H) $(EXPR_H) $(OPTABS_H) 		\
+  $(RTL_H) $(TM_P_H) $(FUNCTION_H) $(EXPR_H) $(OPTABS_H) $(TARGET_H)	\
   dfp.h $(FLAGS_H) output.h insn-config.h hard-reg-set.h $(RECOG_H)	\
   $(RESOURCE_H) reload.h $(DIAGNOSTIC_CORE_H) $(REGS_H) tm-constrs.h $(GGC_H)	\
   $(BASIC_BLOCK_H) $(INTEGRATE_H)
@@ -3603,7 +3603,7 @@  insn-preds.o : insn-preds.c $(CONFIG_H) 
 insn-recog.o : insn-recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h		\
   $(TM_H) $(RTL_H) insn-config.h $(RECOG_H) output.h $(FLAGS_H)		\
   $(FUNCTION_H) hard-reg-set.h $(RESOURCE_H) $(TM_P_H) $(DIAGNOSTIC_CORE_H)	\
-  reload.h $(REGS_H) tm-constrs.h
+  reload.h $(REGS_H) tm-constrs.h $(TARGET_H)
 
 # For each of the files generated by running a generator program over
 # the machine description, the following static pattern rules run the
@@ -3893,7 +3893,7 @@  build/rtl.o: rtl.c $(BCONFIG_H) coretype
 build/vec.o : vec.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(VEC_H)	\
    $(GGC_H) toplev.h $(DIAGNOSTIC_CORE_H)
 build/gencondmd.o : build/gencondmd.c $(BCONFIG_H) $(SYSTEM_H)		\
-  coretypes.h $(GTM_H) insn-constants.h					\
+  coretypes.h $(GTM_H) target.h insn-constants.h					\
   $(filter-out insn-flags.h, $(RTL_H) $(TM_P_H) $(FUNCTION_H) $(REGS_H) \
   $(RECOG_H) output.h $(FLAGS_H) $(RESOURCE_H) toplev.h $(DIAGNOSTIC_CORE_H) reload.h 	\
   $(EXCEPT_H) tm-constrs.h)
Index: config/alpha/alpha.c
===================================================================
--- config/alpha/alpha.c	(revision 167989)
+++ config/alpha/alpha.c	(working copy)
@@ -185,9 +185,9 @@  struct alpha_rtx_cost_data
 
 /* Get the number of args of a function in one of two ways.  */
 #if TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK
-#define NUM_ARGS crtl->args.info.num_args
+#define NUM_ARGS (*get_cumulative_args (crtl->args.info)).num_args
 #else
-#define NUM_ARGS crtl->args.info
+#define NUM_ARGS (*get_cumulative_args (crtl->args.info))
 #endif
 
 #define REG_PV 27
@@ -6395,7 +6395,8 @@  alpha_gimplify_va_arg (tree valist, tree
   t = fold_convert (lang_hooks.types.type_for_size (64, 0), offset_field);
   offset = get_initialized_tmp_var (t, pre_p, NULL);
 
-  indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
+  indirect = pass_by_reference (pack_cumulative_args (NULL), TYPE_MODE (type),
+				type, false);
   if (indirect)
     type = build_pointer_type_for_mode (type, ptr_mode, true);
 
Index: config/frv/frv.c
===================================================================
--- config/frv/frv.c	(revision 167989)
+++ config/frv/frv.c	(working copy)
@@ -2253,7 +2253,8 @@  frv_expand_builtin_saveregs (void)
 frv_expand_builtin_va_start (tree valist, rtx nextarg)
 {
   tree t;
-  int num = crtl->args.info - FIRST_ARG_REGNUM - FRV_NUM_ARG_REGS;
+  int num = (*get_cumulative_args (crtl->args.info)
+	     - FIRST_ARG_REGNUM - FRV_NUM_ARG_REGS);
 
   nextarg = gen_rtx_PLUS (Pmode, virtual_incoming_args_rtx,
 			  GEN_INT (UNITS_PER_WORD * num));
@@ -2261,7 +2262,7 @@  frv_expand_builtin_va_start (tree valist
   if (TARGET_DEBUG_ARG)
     {
       fprintf (stderr, "va_start: args_info = %d, num = %d\n",
-	       crtl->args.info, num);
+	       *get_cumulative_args (crtl->args.info), num);
 
       debug_rtx (nextarg);
     }
Index: config/s390/s390.c
===================================================================
--- config/s390/s390.c	(revision 167989)
+++ config/s390/s390.c	(working copy)
@@ -7265,9 +7265,9 @@  s390_register_info (int clobbered_regs[]
     {
       /* Varargs functions need to save gprs 2 to 6.  */
       if (cfun->va_list_gpr_size
-	  && crtl->args.info.gprs < GP_ARG_NUM_REG)
+	  && get_cumulative_args (crtl->args.info)->gprs < GP_ARG_NUM_REG)
 	{
-	  int min_gpr = crtl->args.info.gprs;
+	  int min_gpr = get_cumulative_args (crtl->args.info)->gprs;
 	  int max_gpr = min_gpr + cfun->va_list_gpr_size;
 	  if (max_gpr > GP_ARG_NUM_REG)
 	    max_gpr = GP_ARG_NUM_REG;
@@ -7289,9 +7289,9 @@  s390_register_info (int clobbered_regs[]
 
       /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved.  */
       if (TARGET_HARD_FLOAT && cfun->va_list_fpr_size
-	  && crtl->args.info.fprs < FP_ARG_NUM_REG)
+	  && get_cumulative_args (crtl->args.info)->fprs < FP_ARG_NUM_REG)
 	{
-	  int min_fpr = crtl->args.info.fprs;
+	  int min_fpr = get_cumulative_args (crtl->args.info)->fprs;
 	  int max_fpr = min_fpr + cfun->va_list_fpr_size;
 	  if (max_fpr > FP_ARG_NUM_REG)
 	    max_fpr = FP_ARG_NUM_REG;
@@ -8791,8 +8791,8 @@  s390_va_start (tree valist, rtx nextarg 
 
   /* Count number of gp and fp argument registers used.  */
 
-  n_gpr = crtl->args.info.gprs;
-  n_fpr = crtl->args.info.fprs;
+  n_gpr = get_cumulative_args (crtl->args.info)->gprs;
+  n_fpr = get_cumulative_args (crtl->args.info)->fprs;
 
   if (cfun->va_list_gpr_size)
     {
@@ -8893,7 +8893,8 @@  s390_gimplify_va_arg (tree valist, tree 
 
   size = int_size_in_bytes (type);
 
-  if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
+  if (pass_by_reference (pack_cumulative_args (NULL), TYPE_MODE (type), type,
+      false))
     {
       if (TARGET_DEBUG_ARG)
 	{
@@ -9605,7 +9606,7 @@  s390_call_saved_register_used (tree call
       mode = TYPE_MODE (type);
       gcc_assert (mode);
 
-      if (pass_by_reference (&cum, mode, type, true))
+      if (pass_by_reference (pack_cumulative_args (&cum), mode, type, true))
  	{
  	  mode = Pmode;
  	  type = build_pointer_type (type);
Index: config/m32c/m32c.h
===================================================================
--- config/m32c/m32c.h	(revision 167989)
+++ config/m32c/m32c.h	(working copy)
@@ -518,7 +518,6 @@  #define INITIAL_ELIMINATION_OFFSET(FROM,
 
 #define PUSH_ARGS 1
 #define PUSH_ROUNDING(N) m32c_push_rounding (N)
-#define CALL_POPS_ARGS(C) 0
 
 /* Passing Arguments in Registers */
 
Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 167989)
+++ config/sparc/sparc.c	(working copy)
@@ -6250,7 +6250,7 @@  sparc_function_value_regno_p (const unsi
 static rtx
 sparc_builtin_saveregs (void)
 {
-  int first_reg = crtl->args.info.words;
+  int first_reg = get_cumulative_args (crtl->args.info)->words;
   rtx address;
   int regno;
 
@@ -6292,7 +6292,8 @@  sparc_gimplify_va_arg (tree valist, tree
   bool indirect;
   tree ptrtype = build_pointer_type (type);
 
-  if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
+  if (pass_by_reference (pack_cumulative_args (NULL), TYPE_MODE (type), type,
+			 false))
     {
       indirect = true;
       size = rsize = UNITS_PER_WORD;
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 167989)
+++ config/i386/i386.c	(working copy)
@@ -7832,6 +7832,7 @@  ix86_va_start (tree valist, rtx nextarg)
   tree gpr, fpr, ovf, sav, t;
   tree type;
   rtx ovf_rtx;
+  CUMULATIVE_ARGS *ca;
 
   if (flag_split_stack
       && cfun->machine->split_stack_varargs_pointer == NULL_RTX)
@@ -7902,9 +7903,10 @@  ix86_va_start (tree valist, rtx nextarg)
 		f_sav, NULL_TREE);
 
   /* Count number of gp and fp argument registers used.  */
-  words = crtl->args.info.words;
-  n_gpr = crtl->args.info.regno;
-  n_fpr = crtl->args.info.sse_regno;
+  ca = get_cumulative_args (crtl->args.info);
+  words = ca->words;
+  n_gpr = ca->regno;
+  n_fpr = ca->sse_regno;
 
   if (cfun->va_list_gpr_size)
     {
@@ -7987,7 +7989,8 @@  ix86_gimplify_va_arg (tree valist, tree 
   ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
   sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
 
-  indirect_p = pass_by_reference (NULL, TYPE_MODE (type), type, false);
+  indirect_p = pass_by_reference (pack_cumulative_args (NULL),
+				  TYPE_MODE (type), type, false);
   if (indirect_p)
     type = build_pointer_type (type);
   size = int_size_in_bytes (type);
Index: config/sh/sh.c
===================================================================
--- config/sh/sh.c	(revision 167989)
+++ config/sh/sh.c	(working copy)
@@ -292,6 +292,7 @@  static void sh_function_arg_advance (cum
 				     const_tree, bool);
 static rtx sh_function_arg (cumulative_args_t, enum machine_mode,
 			    const_tree, bool);
+static int sh_call_pops_args (cumulative_args_t ca);
 static bool sh_scalar_mode_supported_p (enum machine_mode);
 static int sh_dwarf_calling_convention (const_tree);
 static void sh_encode_section_info (tree, rtx, int);
@@ -546,6 +547,8 @@  #define TARGET_BRANCH_TARGET_REGISTER_CA
 #define TARGET_FUNCTION_ARG sh_function_arg
 #undef TARGET_FUNCTION_ARG_ADVANCE
 #define TARGET_FUNCTION_ARG_ADVANCE sh_function_arg_advance
+#undef TARGET_CALL_POPS_ARGS
+#define TARGET_CALL_POPS_ARGS sh_call_pops_args
 
 #undef TARGET_BUILD_BUILTIN_VA_LIST
 #define TARGET_BUILD_BUILTIN_VA_LIST sh_build_builtin_va_list
@@ -6710,7 +6713,7 @@  calc_live_regs (HARD_REG_SET *live_regs_
   /* Force PR to be live if the prologue has to call the SHmedia
      argument decoder or register saver.  */
   if (TARGET_SHCOMPACT
-      && ((crtl->args.info.call_cookie
+      && ((get_cumulative_args (crtl->args.info)->call_cookie
 	   & ~ CALL_COOKIE_RET_TRAMP (1))
 	  || crtl->saves_all_registers))
     pr_live = 1;
@@ -6737,7 +6740,7 @@  calc_live_regs (HARD_REG_SET *live_regs_
 	  : (/* Only push those regs which are used and need to be saved.  */
 	     (TARGET_SHCOMPACT
 	      && flag_pic
-	      && crtl->args.info.call_cookie
+	      && get_cumulative_args (crtl->args.info)->call_cookie
 	      && reg == PIC_OFFSET_TABLE_REGNUM)
 	     || (df_regs_ever_live_p (reg)
 		 && ((!call_really_used_regs[reg]
@@ -6986,6 +6989,7 @@  sh_expand_prologue (void)
   int stack_usage;
   tree sp_switch_attr
     = lookup_attribute ("sp_switch", DECL_ATTRIBUTES (current_function_decl));
+  CUMULATIVE_ARGS *ca = get_cumulative_args (crtl->args.info);
 
   current_function_interrupt = sh_cfun_interrupt_handler_p ();
 
@@ -6993,24 +6997,21 @@  sh_expand_prologue (void)
      and partially on the stack, e.g. a large structure.  */
   pretend_args = crtl->args.pretend_args_size;
   if (TARGET_VARARGS_PRETEND_ARGS (current_function_decl)
-      && (NPARM_REGS(SImode)
-	  > crtl->args.info.arg_count[(int) SH_ARG_INT]))
+      && (NPARM_REGS(SImode) > ca->arg_count[(int) SH_ARG_INT]))
     pretend_args = 0;
 
-  output_stack_adjust (-pretend_args
-		       - crtl->args.info.stack_regs * 8,
+  output_stack_adjust (-pretend_args - ca->stack_regs * 8,
 		       stack_pointer_rtx, 0, NULL, true);
-  stack_usage = pretend_args + crtl->args.info.stack_regs * 8;
+  stack_usage = pretend_args + ca->stack_regs * 8;
 
-  if (TARGET_SHCOMPACT && flag_pic && crtl->args.info.call_cookie)
+  if (TARGET_SHCOMPACT && flag_pic && ca->call_cookie)
     /* We're going to use the PIC register to load the address of the
        incoming-argument decoder and/or of the return trampoline from
        the GOT, so make sure the PIC register is preserved and
        initialized.  */
     df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
 
-  if (TARGET_SHCOMPACT
-      && (crtl->args.info.call_cookie & ~ CALL_COOKIE_RET_TRAMP(1)))
+  if (TARGET_SHCOMPACT && (ca->call_cookie & ~ CALL_COOKIE_RET_TRAMP(1)))
     {
       int reg;
 
@@ -7018,20 +7019,19 @@  sh_expand_prologue (void)
 	 be pushed onto the stack live, so that register renaming
 	 doesn't overwrite them.  */
       for (reg = 0; reg < NPARM_REGS (SImode); reg++)
-	if (CALL_COOKIE_STACKSEQ_GET (crtl->args.info.call_cookie)
+	if (CALL_COOKIE_STACKSEQ_GET (ca->call_cookie)
 	    >= NPARM_REGS (SImode) - reg)
 	  for (; reg < NPARM_REGS (SImode); reg++)
 	    emit_insn (gen_shcompact_preserve_incoming_args
 		       (gen_rtx_REG (SImode, FIRST_PARM_REG + reg)));
 	else if (CALL_COOKIE_INT_REG_GET
-		 (crtl->args.info.call_cookie, reg) == 1)
+		 (ca->call_cookie, reg) == 1)
 	  emit_insn (gen_shcompact_preserve_incoming_args
 		     (gen_rtx_REG (SImode, FIRST_PARM_REG + reg)));
 
       emit_move_insn (gen_rtx_REG (Pmode, MACL_REG),
 		      stack_pointer_rtx);
-      emit_move_insn (gen_rtx_REG (SImode, R0_REG),
-		      GEN_INT (crtl->args.info.call_cookie));
+      emit_move_insn (gen_rtx_REG (SImode, R0_REG), GEN_INT (ca->call_cookie));
       emit_move_insn (gen_rtx_REG (SImode, MACH_REG),
 		      gen_rtx_REG (SImode, R0_REG));
     }
@@ -7055,7 +7055,7 @@  sh_expand_prologue (void)
 	      int rn = NPARM_REGS(SImode) + FIRST_PARM_REG - i - 1;
 
 	      if (i >= (NPARM_REGS(SImode)
-			- crtl->args.info.arg_count[(int) SH_ARG_INT]
+			- ca->arg_count[(int) SH_ARG_INT]
 			))
 		break;
 	      push (rn);
@@ -7317,7 +7317,7 @@  sh_expand_prologue (void)
     frame_insn (GEN_MOV (hard_frame_pointer_rtx, stack_pointer_rtx));
 
   if (TARGET_SHCOMPACT
-      && (crtl->args.info.call_cookie & ~ CALL_COOKIE_RET_TRAMP(1)))
+      && (ca->call_cookie & ~ CALL_COOKIE_RET_TRAMP(1)))
     {
       /* This must NOT go through the PLT, otherwise mach and macl
 	 may be clobbered.  */
@@ -7610,7 +7610,7 @@  sh_expand_epilogue (bool sibcall_p)
 
   output_stack_adjust (crtl->args.pretend_args_size
 		       + save_size + d_rounding
-		       + crtl->args.info.stack_regs * 8,
+		       + get_cumulative_args (crtl->args.info)->stack_regs * 8,
 		       stack_pointer_rtx, e, NULL, false);
 
   if (crtl->calls_eh_return)
@@ -7732,12 +7732,13 @@  sh_output_function_epilogue (FILE *file 
 static rtx
 sh_builtin_saveregs (void)
 {
+  CUMULATIVE_ARGS *ca = get_cumulative_args (crtl->args.info);
   /* First unnamed integer register.  */
-  int first_intreg = crtl->args.info.arg_count[(int) SH_ARG_INT];
+  int first_intreg = ca->arg_count[(int) SH_ARG_INT];
   /* Number of integer registers we need to save.  */
   int n_intregs = MAX (0, NPARM_REGS (SImode) - first_intreg);
   /* First unnamed SFmode float reg */
-  int first_floatreg = crtl->args.info.arg_count[(int) SH_ARG_FLOAT];
+  int first_floatreg = ca->arg_count[(int) SH_ARG_FLOAT];
   /* Number of SFmode float regs to save.  */
   int n_floatregs = MAX (0, NPARM_REGS (SFmode) - first_floatreg);
   rtx regbuf, fpregs;
@@ -7752,22 +7753,22 @@  sh_builtin_saveregs (void)
 
 	  while (pushregs < NPARM_REGS (SImode) - 1
 		 && (CALL_COOKIE_INT_REG_GET
-			(crtl->args.info.call_cookie,
+			(ca->call_cookie,
 			 NPARM_REGS (SImode) - pushregs)
 		     == 1))
 	    {
-	      crtl->args.info.call_cookie
+	      ca->call_cookie
 		&= ~ CALL_COOKIE_INT_REG (NPARM_REGS (SImode)
 					  - pushregs, 1);
 	      pushregs++;
 	    }
 
 	  if (pushregs == NPARM_REGS (SImode))
-	    crtl->args.info.call_cookie
+	    ca->call_cookie
 	      |= (CALL_COOKIE_INT_REG (0, 1)
 		  | CALL_COOKIE_STACKSEQ (pushregs - 1));
 	  else
-	    crtl->args.info.call_cookie
+	    ca->call_cookie
 	      |= CALL_COOKIE_STACKSEQ (pushregs);
 
 	  crtl->args.pretend_args_size += 8 * n_intregs;
@@ -7977,7 +7978,7 @@  sh_va_start (tree valist, rtx nextarg)
   TREE_SIDE_EFFECTS (t) = 1;
   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
 
-  nfp = crtl->args.info.arg_count[SH_ARG_FLOAT];
+  nfp = get_cumulative_args (crtl->args.info)->arg_count[SH_ARG_FLOAT];
   if (nfp < 8)
     nfp = 8 - nfp;
   else
@@ -7992,7 +7993,7 @@  sh_va_start (tree valist, rtx nextarg)
   TREE_SIDE_EFFECTS (t) = 1;
   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
 
-  nint = crtl->args.info.arg_count[SH_ARG_INT];
+  nint = get_cumulative_args (crtl->args.info)->arg_count[SH_ARG_INT];
   if (nint < 4)
     nint = 4 - nint;
   else
@@ -8751,6 +8752,18 @@  sh_pretend_outgoing_varargs_named (cumul
   return ! (TARGET_HITACHI || ca->renesas_abi) && ! TARGET_SH5;
 }
 
+/* Value is the number of bytes of arguments automatically popped when
+   calling a subroutine.
+   CA is the accumulated argument list.
+
+   On SHcompact, the call trampoline pops arguments off the stack.  */
+static int
+sh_call_pops_args (cumulative_args_t ca)
+{
+  return TARGET_SHCOMPACT ? get_cumulative_args (ca)->stack_regs * 8 : 0;
+}
+
+
 
 /* Define the offset between two registers, one to be eliminated, and
    the other its replacement, at the start of a routine.  */
@@ -8788,11 +8801,11 @@  initial_elimination_offset (int from, in
 
   if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
     return total_saved_regs_space + total_auto_space
-      + crtl->args.info.byref_regs * 8;
+      + get_cumulative_args (crtl->args.info)->byref_regs * 8;
 
   if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
     return total_saved_regs_space + total_auto_space
-      + crtl->args.info.byref_regs * 8;
+      + get_cumulative_args (crtl->args.info)->byref_regs * 8;
 
   /* Initial gap between fp and sp is 0.  */
   if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
@@ -10403,7 +10416,7 @@  sh_allocate_initial_value (rtx hard_reg)
       if (current_function_is_leaf
 	  && ! sh_pr_n_sets ()
 	  && ! (TARGET_SHCOMPACT
-		&& ((crtl->args.info.call_cookie
+		&& ((get_cumulative_args (crtl->args.info)->call_cookie
 		     & ~ CALL_COOKIE_RET_TRAMP (1))
 		    || crtl->saves_all_registers)))
 	x = hard_reg;
@@ -11013,7 +11026,7 @@  sh_function_ok_for_sibcall (tree decl, t
 {
   return (1
 	  && (! TARGET_SHCOMPACT
-	      || crtl->args.info.stack_regs == 0)
+	      || get_cumulative_args (crtl->args.info)->stack_regs == 0)
 	  && ! sh_cfun_interrupt_handler_p ()
 	  && (! flag_pic
 	      || (decl && ! TREE_PUBLIC (decl))
@@ -11929,7 +11942,7 @@  sh_get_pr_initial_val (void)
      PR register on SHcompact, because it might be clobbered by the prologue.
      We check first if that is known to be the case.  */
   if (TARGET_SHCOMPACT
-      && ((crtl->args.info.call_cookie
+      && ((get_cumulative_args (crtl->args.info)->call_cookie
 	   & ~ CALL_COOKIE_RET_TRAMP (1))
 	  || crtl->saves_all_registers))
     return gen_frame_mem (SImode, return_address_pointer_rtx);
Index: config/sh/sh.h
===================================================================
--- config/sh/sh.h	(revision 167989)
+++ config/sh/sh.h	(working copy)
@@ -1362,13 +1362,6 @@  #define NPARM_REGS(MODE) \
 /* Offset of first parameter from the argument pointer register value.  */
 #define FIRST_PARM_OFFSET(FNDECL)  0
 
-/* Value is the number of bytes of arguments automatically popped when
-   calling a subroutine.
-   CUM is the accumulated argument list.
-
-   On SHcompact, the call trampoline pops arguments off the stack.  */
-#define CALL_POPS_ARGS(CUM) (TARGET_SHCOMPACT ? (CUM).stack_regs * 8 : 0)
-
 /* Some subroutine macros specific to this machine.  */
 
 #define BASE_RETURN_VALUE_REG(MODE) \
Index: config/sh/sh.md
===================================================================
--- config/sh/sh.md	(revision 167989)
+++ config/sh/sh.md	(working copy)
@@ -9017,7 +9017,8 @@  (define_expand "return"
     }
 
   if (TARGET_SHCOMPACT
-      && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
+      && (get_cumulative_args (crtl->args.info)->call_cookie
+	  & CALL_COOKIE_RET_TRAMP (1)))
     {
       emit_jump_insn (gen_shcompact_return_tramp ());
       DONE;
@@ -9027,7 +9028,7 @@  (define_expand "return"
 (define_insn "*return_i"
   [(return)]
   "TARGET_SH1 && ! (TARGET_SHCOMPACT
-		    && (crtl->args.info.call_cookie
+		    && (get_cumulative_args (crtl->args.info)->call_cookie
 			& CALL_COOKIE_RET_TRAMP (1)))
    && reload_completed
    && lookup_attribute (\"trap_exit\",
@@ -9054,7 +9055,8 @@  (define_insn "*return_trapa"
 (define_expand "shcompact_return_tramp"
   [(return)]
   "TARGET_SHCOMPACT
-   && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
+   && (get_cumulative_args (crtl->args.info)->call_cookie
+       & CALL_COOKIE_RET_TRAMP (1))"
   "
 {
   rtx reg = gen_rtx_REG (Pmode, R0_REG);
@@ -9067,7 +9069,8 @@  (define_expand "shcompact_return_tramp"
 (define_insn "shcompact_return_tramp_i"
   [(parallel [(return) (use (reg:SI R0_REG))])]
   "TARGET_SHCOMPACT
-   && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
+   && (get_cumulative_args (crtl->args.info)->call_cookie
+       & CALL_COOKIE_RET_TRAMP (1))"
   "jmp	@r0%#"
   [(set_attr "type" "jump_ind")
    (set_attr "needs_delay_slot" "yes")])
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c	(revision 167989)
+++ config/avr/avr.c	(working copy)
@@ -2773,7 +2773,7 @@  out_movhi_mr_r (rtx insn, rtx op[], int 
 avr_frame_pointer_required_p (void)
 {
   return (cfun->calls_alloca
-	  || crtl->args.info.nregs == 0
+	  || get_cumulative_args (crtl->args.info)->nregs == 0
   	  || get_frame_size () > 0);
 }
 
Index: config/xtensa/xtensa.c
===================================================================
--- config/xtensa/xtensa.c	(revision 167989)
+++ config/xtensa/xtensa.c	(working copy)
@@ -2752,7 +2752,7 @@  xtensa_build_builtin_va_list (void)
 xtensa_builtin_saveregs (void)
 {
   rtx gp_regs;
-  int arg_words = crtl->args.info.arg_words;
+  int arg_words = get_cumulative_args (crtl->args.info)->arg_words;
   int gp_left = MAX_ARGS_IN_REGISTERS - arg_words;
 
   if (gp_left <= 0)
@@ -2789,7 +2789,7 @@  xtensa_va_start (tree valist, rtx nextar
   tree t, u;
   int arg_words;
 
-  arg_words = crtl->args.info.arg_words;
+  arg_words = get_cumulative_args (crtl->args.info)->arg_words;
 
   f_stk = TYPE_FIELDS (va_list_type_node);
   f_reg = DECL_CHAIN (f_stk);
@@ -2840,7 +2840,8 @@  xtensa_gimplify_va_arg_expr (tree valist
   tree lab_false, lab_over, lab_false2;
   bool indirect;
 
-  indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
+  indirect = pass_by_reference (pack_cumulative_args (NULL), TYPE_MODE (type),
+				type, false);
   if (indirect)
     type = build_pointer_type (type);
 
@@ -3184,7 +3185,7 @@  order_regs_for_local_alloc (void)
 
       /* Use the AR registers in increasing order (skipping a0 and a1)
 	 but save the incoming argument registers for a last resort.  */
-      num_arg_regs = crtl->args.info.arg_words;
+      num_arg_regs = get_cumulative_args (crtl->args.info)->arg_words;
       if (num_arg_regs > MAX_ARGS_IN_REGISTERS)
 	num_arg_regs = MAX_ARGS_IN_REGISTERS;
       for (i = GP_ARG_FIRST; i < 16 - num_arg_regs; i++)
Index: config/stormy16/stormy16.c
===================================================================
--- config/stormy16/stormy16.c	(revision 167989)
+++ config/stormy16/stormy16.c	(working copy)
@@ -1353,7 +1353,8 @@  xstormy16_expand_builtin_va_start (tree 
 
   t = build2 (MODIFY_EXPR, TREE_TYPE (count), count,
 	      build_int_cst (NULL_TREE,
-			     crtl->args.info * UNITS_PER_WORD));
+			     (*get_cumulative_args (crtl->args.info)
+			      * UNITS_PER_WORD)));
   TREE_SIDE_EFFECTS (t) = 1;
   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
 }
Index: config/m68hc11/m68hc11.c
===================================================================
--- config/m68hc11/m68hc11.c	(revision 167989)
+++ config/m68hc11/m68hc11.c	(working copy)
@@ -1669,7 +1669,7 @@  expand_prologue (void)
      If the first argument is a 32-bit quantity, the D+X registers
      are used.  Use Y to compute the frame.  Otherwise, X is cheaper.
      For 68HC12, this scratch register is not used.  */
-  if (crtl->args.info.nregs == 2)
+  if (get_cumulative_args (crtl->args.info)->nregs == 2)
     scratch = iy_reg;
   else
     scratch = ix_reg;
Index: config/iq2000/iq2000.c
===================================================================
--- config/iq2000/iq2000.c	(revision 167989)
+++ config/iq2000/iq2000.c	(working copy)
@@ -1416,7 +1416,7 @@  iq2000_va_start (tree valist, rtx nextar
   /* Find out how many non-float named formals.  */
   int gpr_save_area_size;
   /* Note UNITS_PER_WORD is 4 bytes.  */
-  int_arg_words = crtl->args.info.arg_words;
+  int_arg_words = get_cumulative_args (crtl->args.info)->arg_words;
 
   if (int_arg_words < 8 )
     /* Adjust for the prologue's economy measure.  */
Index: config/ia64/ia64.c
===================================================================
--- config/ia64/ia64.c	(revision 167989)
+++ config/ia64/ia64.c	(working copy)
@@ -3299,7 +3299,8 @@  #define PRINTREG(a) if (current_frame_in
   /* We don't need an alloc instruction if we've used no outputs or locals.  */
   if (current_frame_info.n_local_regs == 0
       && current_frame_info.n_output_regs == 0
-      && current_frame_info.n_input_regs <= crtl->args.info.int_regs
+      && (current_frame_info.n_input_regs
+	  <= get_cumulative_args (crtl->args.info)->int_regs)
       && !TEST_HARD_REG_BIT (current_frame_info.mask, AR_PFS_REGNUM))
     {
       /* If there is no alloc, but there are input registers used, then we
@@ -4785,7 +4786,8 @@  ia64_gimplify_va_arg (tree valist, tree 
 		      gimple_seq *post_p)
 {
   /* Variable sized types are passed by reference.  */
-  if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
+  if (pass_by_reference (pack_cumulative_args (NULL), TYPE_MODE (type),
+			 type, false))
     {
       tree ptrtype = build_pointer_type (type);
       tree addr = std_gimplify_va_arg_expr (valist, ptrtype, pre_p, post_p);
Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c	(revision 167989)
+++ config/rs6000/rs6000.c	(working copy)
@@ -8421,7 +8421,8 @@  rs6000_function_arg_advance_1 (CUMULATIV
 rs6000_function_arg_advance (cumulative_args_t cum, enum machine_mode mode,
 			     const_tree type, bool named)
 {
-  rs6000_function_arg_advance_1 (get_cumulative_args (cum), mode, type, named, 0);
+  rs6000_function_arg_advance_1 (get_cumulative_args (cum), mode, type, named,
+				 0);
 }
 
 static rtx
@@ -9472,10 +9473,11 @@  rs6000_va_start (tree valist, rtx nextar
 		f_sav, NULL_TREE);
 
   /* Count number of gp and fp argument registers used.  */
-  words = crtl->args.info.words;
-  n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
+  words = get_cumulative_args (crtl->args.info)->words;
+  n_gpr = MIN (get_cumulative_args (crtl->args.info)->sysv_gregno
+	       - GP_ARG_MIN_REG,
 	       GP_ARG_NUM_REG);
-  n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
+  n_fpr = MIN (get_cumulative_args (crtl->args.info)->fregno - FP_ARG_MIN_REG,
 	       FP_ARG_NUM_REG);
 
   if (TARGET_DEBUG_ARG)
@@ -9541,7 +9543,8 @@  rs6000_gimplify_va_arg (tree valist, tre
   int regalign = 0;
   gimple stmt;
 
-  if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
+  if (pass_by_reference (pack_cumulative_args (NULL), TYPE_MODE (type), type,
+			 false))
     {
       t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
       return build_va_arg_indirect_ref (t);
@@ -18178,7 +18181,8 @@  compute_vrsave_mask (void)
      them in again.  More importantly, the mask we compute here is
      used to generate CLOBBERs in the set_vrsave insn, and we do not
      wish the argument registers to die.  */
-  for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
+  for (i = get_cumulative_args (crtl->args.info)->vregno - 1;
+       i >= ALTIVEC_ARG_MIN_REG; --i)
     mask &= ~ALTIVEC_REG_BIT (i);
 
   /* Similarly, remove the return value from the set.  */
Index: config/arc/arc.c
===================================================================
--- config/arc/arc.c	(revision 167989)
+++ config/arc/arc.c	(working copy)
@@ -2298,8 +2298,8 @@  arc_ccfsm_record_branch_deleted (void)
 arc_va_start (tree valist, rtx nextarg)
 {
   /* See arc_setup_incoming_varargs for reasons for this oddity.  */
-  if (crtl->args.info < 8
-      && (crtl->args.info & 1))
+  if (*get_cumulative_args (crtl->args.info) < 8
+      && (*get_cumulative_args (crtl->args.info) & 1))
     nextarg = plus_constant (nextarg, UNITS_PER_WORD);
 
   std_expand_builtin_va_start (valist, nextarg);
Index: config/arm/arm.c
===================================================================
--- config/arm/arm.c	(revision 167989)
+++ config/arm/arm.c	(working copy)
@@ -5304,7 +5304,7 @@  thumb_find_work_register (unsigned long 
   if (! cfun->machine->uses_anonymous_args
       && crtl->args.size >= 0
       && crtl->args.size <= (LAST_ARG_REGNUM * UNITS_PER_WORD)
-      && crtl->args.info.nregs < 4)
+      && get_cumulative_args (crtl->args.info)->nregs < 4)
     return LAST_ARG_REGNUM;
 
   /* Otherwise look for a call-saved register that is going to be pushed.  */
Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c	(revision 167989)
+++ config/pa/pa.c	(working copy)
@@ -6100,7 +6100,8 @@  hppa_gimplify_va_arg_expr (tree valist, 
       unsigned int size, ofs;
       bool indirect;
 
-      indirect = pass_by_reference (NULL, TYPE_MODE (type), type, 0);
+      indirect = pass_by_reference (pack_cumulative_args (NULL),
+				    TYPE_MODE (type), type, 0);
       if (indirect)
 	{
 	  type = ptr;
Index: config/mips/mips.c
===================================================================
--- config/mips/mips.c	(revision 167989)
+++ config/mips/mips.c	(working copy)
@@ -5496,7 +5496,7 @@  mips_va_start (tree valist, rtx nextarg)
       int fpr_save_area_size;
       int fpr_offset;
 
-      cum = &crtl->args.info;
+      cum = get_cumulative_args (crtl->args.info);
       gpr_save_area_size
 	= (MAX_ARGS_IN_REGISTERS - cum->num_gprs) * UNITS_PER_WORD;
       fpr_save_area_size
@@ -5574,7 +5574,8 @@  mips_gimplify_va_arg_expr (tree valist, 
   tree addr;
   bool indirect_p;
 
-  indirect_p = pass_by_reference (NULL, TYPE_MODE (type), type, 0);
+  indirect_p = pass_by_reference (pack_cumulative_args (NULL),
+				  TYPE_MODE (type), type, 0);
   if (indirect_p)
     type = build_pointer_type (type);
 
@@ -6039,7 +6040,8 @@  mips16_build_function_stub (void)
   fprintf (asm_out_file, "\t# Stub function for %s (",
 	   current_function_name ());
   separator = "";
-  for (f = (unsigned int) crtl->args.info.fp_code; f != 0; f >>= 2)
+  for (f = (unsigned int) get_cumulative_args (crtl->args.info)->fp_code;
+       f != 0; f >>= 2)
     {
       fprintf (asm_out_file, "%s%s", separator,
 	       (f & 3) == 1 ? "float" : "double");
@@ -6075,7 +6077,7 @@  mips16_build_function_stub (void)
   output_asm_insn ("la\t%^,%0", &symbol);
 
   /* Move the arguments from floating-point registers to general registers.  */
-  mips_output_args_xfer (crtl->args.info.fp_code, 'f');
+  mips_output_args_xfer (get_cumulative_args (crtl->args.info)->fp_code, 'f');
 
   /* Jump to the MIPS16 function.  */
   output_asm_insn ("jr\t%^", NULL);
@@ -9847,7 +9849,7 @@  mips_output_function_prologue (FILE *fil
      floating-point arguments.  */
   if (TARGET_MIPS16
       && TARGET_HARD_FLOAT_ABI
-      && crtl->args.info.fp_code != 0)
+      && get_cumulative_args (crtl->args.info)->fp_code != 0)
     mips16_build_function_stub ();
 
   /* Get the function name the same way that toplev.c does before calling
Index: config/mmix/mmix.c
===================================================================
--- config/mmix/mmix.c	(revision 167989)
+++ config/mmix/mmix.c	(working copy)
@@ -908,9 +908,10 @@  mmix_reorg (void)
      wasteful to optimize for unused parameter registers.  As of
      2002-04-30, df_regs_ever_live_p (n) seems to be set for only-reads too, but
      that might change.  */
-  if (!TARGET_ABI_GNU && regno < crtl->args.info.regs - 1)
+  if (!TARGET_ABI_GNU
+      && regno < get_cumulative_args (crtl->args.info)->regs - 1)
     {
-      regno = crtl->args.info.regs - 1;
+      regno = get_cumulative_args (crtl->args.info)->regs - 1;
 
       /* We don't want to let this cause us to go over the limit and make
 	 incoming parameter registers be misnumbered and treating the last