diff mbox

P.P.S.: Updated: RFA: Fix middle-end/46500 (void * encapsulated)

Message ID 20101122155140.zjou1fzgu8kogk4k-nzlynne@webmail.spamcop.net
State New
Headers show

Commit Message

Joern Rennecke Nov. 22, 2010, 8:51 p.m. UTC
Quoting Joern Rennecke <amylaar@spamcop.net>:

> Quoting Joern Rennecke <amylaar@spamcop.net>:
> If it helps the review process, I could decouple the middle-end end the
> target part, by checking config/${cpu_type}/${cpu_type}.c if it mentions
> cumulative_args_t, and set a macro if that is the case.
>
> Then for unconverted ports, target.h can continue to include "tm.h" and do:
> typedef CUMULATIVE_ARGS *cumulative_args_t;
>
> to provide backward compatibility.

This patch set shows how this can be implemented.  I originally though about
putting the test for cumulative_args_t being used by the target into
configure, but we can't put the result into tm_defines - we want to get
away from including tm.h, messing with the compiler flags is ... messy ...
because that would interfere with flag overrides, and there are way to many
Makefile rules affected to change them all for a temporary phasing-in hack.
Therefore, I use a generated file, insn-cumulative_args_t, to convey the
result of the test.  As this file needs new Makefile rules, I put the check
straight in the Makefile rule that generates this file.

Unconverted ports will miss a dependency on $(TM_H) in $(TARGET_H), but that
should only matter if CUMULATIVE_ARGS is changed in
config/${cpu_type}/${cpu_type}.h - and when a port maintainer does that, (s)he
might as well update the argument types for the CUMULATIVE_ARGS taking hook
functions; the patches for all the official ports are in the second  
attachment,
and any new / unoffical ports should also be easy to adjust.

N.B. this patch makes PR target/46608 more likely to be visible.

Bootstrapped without target specific patches on i686-pc-linux-gnu

Bootstrapped & regression tested with target specific patches on
i686-pc-linux-gnu .

build-gcc cross-test succeeded with target-specific patches
on i686-pc-linux-gnu for the following targets:

alpha-linux-gnu hppa-linux-gnu mips-elf sh-elf arc-elf ia64-elf
mmix-knuth-mmixware sparc-elf arm-eabi iq2000-elf mn10300-elf spu-elf
avr-elf lm32-elf moxie-elf v850-elf bfin-elf pdp11-aout vax-linux-gnu
cris-elf m32r-elf xstormy16-elf m68hc11-elf ppc-elf xtensa-elf fr30-elf
m68k-elf rx-elf frv-elf mcore-elf s390-linux-gnu h8300-elf mep-elf
score-elf

picochip-elf is affected by PR46608 - build succeeds with manual make of
generated files or with the proposed patch for PR46608 applied.

m32c-elf does not build since r167020.

crx-elf is still affected by PR46434 .
2010-11-19  Joern Rennecke  <amylaar@spamcop.net>

	PR middle-end/46500
gcc:
	* doc/tm.texi: Regenerate.
	* targhooks.c (default_setup_incoming_varargs): Replace
	CUMULATIVE_ARGS* argument type with cumulative_args_t.
	(default_pretend_outgoing_varargs_named): Likewise.
	(hook_pass_by_reference_must_pass_in_stack): Likewise.
	(hook_callee_copies_named): Likewise.
	(default_function_arg_advance): Likewise.
	(default_function_arg): Likewise.
	(default_function_incoming_arg): Likewise.
	(hook_bool_CUMULATIVE_ARGS_false): Likewise.
	(hook_bool_CUMULATIVE_ARGS_true): Likewise.
	(hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false): Likewise.
	(hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true): Likewise.
	(hook_int_CUMULATIVE_ARGS_mode_tree_bool_0): Likewise.
	* targhooks.h (default_setup_incoming_varargs): Likewise.
	(default_pretend_outgoing_varargs_named): Likewise.
	(hook_pass_by_reference_must_pass_in_stack): Likewise.
	(hook_callee_copies_named): Likewise.
	(default_function_arg_advance): Likewise.
	(default_function_arg): Likewise.
	(default_function_incoming_arg): Likewise.
	(hook_bool_CUMULATIVE_ARGS_false): Likewise.
	(hook_bool_CUMULATIVE_ARGS_true): Likewise.
	(hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false): Likewise.
	(hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true): Likewise.
	(hook_int_CUMULATIVE_ARGS_mode_tree_bool_0): Likewise.
	* target.def (pass_by_reference): Likewise.
	(setup_incoming_varargs, strict_argument_naming): Likewise.
	(pretend_outgoing_varargs_named, callee_copies): Likewise.
	(arg_partial_bytes, function_arg_advance, function_arg): Likewise.
	(function_incoming_arg): Likewise.
	* target.h: Don't include "tm.h" .
	Include "insn-cumulative_args_t.h" .
	(cumulative_args_t): New typedef.
	[GCC_TM_H] (get_cumulative_args): New static inline function.
	[GCC_TM_H] (pack_cumulative_args): Likewise.
	* calls.c (initialize_argument_information): Use pack_cumulative_args.
	(expand_call, emit_library_call_value_1): Likewise.
	* dse.c (get_call_args): Likewise.
	* expr.c (block_move_libcall_safe_for_call_parm): Likewise.
	* function.c (pass_by_reference, reference_callee_copied): Likewise.
	(assign_parm_find_data_types, assign_parms_setup_varargs): Likewise.
	(assign_parm_find_entry_rtl, assign_parms): Likewise.
	(gimplify_parameters): Likewise.
	* Makefile.in (TARGET_H): Replace $(TM_H) with insn-cumulative_args_t.h.
	(insn-cumulative_args_t.h, s-cumulative_args_t): New rules.
gcc/c-family:
	* c-opts.c: Include "tm.h" .
gcc/java:
	* expr.c: Include "tm.h" .
gcc/fortran:
	* trans-types.c: Include "tm.h" .
diff mbox

Patch

Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 167032)
+++ gcc/doc/tm.texi	(working copy)
@@ -4051,7 +4051,7 @@  @defmac FUNCTION_INCOMING_ARG (@var{cum}
 serves both purposes.
 @end defmac
 
-@deftypefn {Target Hook} int TARGET_ARG_PARTIAL_BYTES (CUMULATIVE_ARGS *@var{cum}, enum machine_mode @var{mode}, tree @var{type}, bool @var{named})
+@deftypefn {Target Hook} int TARGET_ARG_PARTIAL_BYTES (cumulative_args_t @var{cum}, enum machine_mode @var{mode}, tree @var{type}, bool @var{named})
 This target hook returns the number of bytes at the beginning of an
 argument that must be put in registers.  The value must be zero for
 arguments that are passed entirely in registers or that are entirely
@@ -4070,7 +4070,7 @@  structure) crosses that boundary, its fi
 @code{FUNCTION_INCOMING_ARG}, for the called function.
 @end deftypefn
 
-@deftypefn {Target Hook} bool TARGET_PASS_BY_REFERENCE (CUMULATIVE_ARGS *@var{cum}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named})
+@deftypefn {Target Hook} bool TARGET_PASS_BY_REFERENCE (cumulative_args_t @var{cum}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named})
 This target hook should return @code{true} if an argument at the
 position indicated by @var{cum} should be passed by reference.  This
 predicate is queried after target independent reasons for being
@@ -4082,7 +4082,7 @@  passed by reference, such as @code{TREE_
 to that type.
 @end deftypefn
 
-@deftypefn {Target Hook} bool TARGET_CALLEE_COPIES (CUMULATIVE_ARGS *@var{cum}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named})
+@deftypefn {Target Hook} bool TARGET_CALLEE_COPIES (cumulative_args_t @var{cum}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named})
 The function argument described by the parameters to this hook is
 known to be passed by reference.  The hook should return true if the
 function argument should be copied by the callee instead of copied
@@ -5016,7 +5016,7 @@  @deftypefn {Target Hook} rtx TARGET_EXPA
 to use as the return of @code{__builtin_saveregs}.
 @end deftypefn
 
-@deftypefn {Target Hook} void TARGET_SETUP_INCOMING_VARARGS (CUMULATIVE_ARGS *@var{args_so_far}, enum machine_mode @var{mode}, tree @var{type}, int *@var{pretend_args_size}, int @var{second_time})
+@deftypefn {Target Hook} void TARGET_SETUP_INCOMING_VARARGS (cumulative_args_t @var{args_so_far}, enum machine_mode @var{mode}, tree @var{type}, int *@var{pretend_args_size}, int @var{second_time})
 This target hook offers an alternative to using
 @code{__builtin_saveregs} and defining the hook
 @code{TARGET_EXPAND_BUILTIN_SAVEREGS}.  Use it to store the anonymous
@@ -5050,7 +5050,7 @@  structure, containing the values that ar
 not generate any instructions in this case.
 @end deftypefn
 
-@deftypefn {Target Hook} bool TARGET_STRICT_ARGUMENT_NAMING (CUMULATIVE_ARGS *@var{ca})
+@deftypefn {Target Hook} bool TARGET_STRICT_ARGUMENT_NAMING (cumulative_args_t @var{ca})
 Define this hook to return @code{true} if the location where a function
 argument is passed depends on whether or not it is a named argument.
 
@@ -5065,7 +5065,7 @@  @deftypefn {Target Hook} bool TARGET_STR
 You need not define this hook if it always returns @code{false}.
 @end deftypefn
 
-@deftypefn {Target Hook} bool TARGET_PRETEND_OUTGOING_VARARGS_NAMED (CUMULATIVE_ARGS *@var{ca})
+@deftypefn {Target Hook} bool TARGET_PRETEND_OUTGOING_VARARGS_NAMED (cumulative_args_t @var{ca})
 If you need to conditionally change ABIs so that one works with
 @code{TARGET_SETUP_INCOMING_VARARGS}, but the other works like neither
 @code{TARGET_SETUP_INCOMING_VARARGS} nor @code{TARGET_STRICT_ARGUMENT_NAMING} was
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c	(revision 167032)
+++ gcc/targhooks.c	(working copy)
@@ -167,7 +167,7 @@  default_expand_builtin_saveregs (void)
 }
 
 void
-default_setup_incoming_varargs (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+default_setup_incoming_varargs (cumulative_args_t ca ATTRIBUTE_UNUSED,
 				enum machine_mode mode ATTRIBUTE_UNUSED,
 				tree type ATTRIBUTE_UNUSED,
 				int *pretend_arg_size ATTRIBUTE_UNUSED,
@@ -186,13 +186,13 @@  default_builtin_setjmp_frame_value (void
 /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns false.  */
 
 bool
-hook_bool_CUMULATIVE_ARGS_false (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
+hook_bool_CUMULATIVE_ARGS_false (cumulative_args_t ca ATTRIBUTE_UNUSED)
 {
   return false;
 }
 
 bool
-default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
+default_pretend_outgoing_varargs_named (cumulative_args_t ca ATTRIBUTE_UNUSED)
 {
   return (targetm.calls.setup_incoming_varargs
 	  != default_setup_incoming_varargs);
@@ -250,7 +250,7 @@  default_mode_rep_extended (enum machine_
 /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns true.  */
 
 bool
-hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS * a ATTRIBUTE_UNUSED)
+hook_bool_CUMULATIVE_ARGS_true (cumulative_args_t a ATTRIBUTE_UNUSED)
 {
   return true;
 }
@@ -299,7 +299,7 @@  default_cxx_get_cookie_size (tree type)
    of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK.  */
 
 bool
-hook_pass_by_reference_must_pass_in_stack (CUMULATIVE_ARGS *c ATTRIBUTE_UNUSED,
+hook_pass_by_reference_must_pass_in_stack (cumulative_args_t c ATTRIBUTE_UNUSED,
 	enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED,
 	bool named_arg ATTRIBUTE_UNUSED)
 {
@@ -310,7 +310,7 @@  hook_pass_by_reference_must_pass_in_stac
    version of the hook is true for all named arguments.  */
 
 bool
-hook_callee_copies_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+hook_callee_copies_named (cumulative_args_t ca ATTRIBUTE_UNUSED,
 			  enum machine_mode mode ATTRIBUTE_UNUSED,
 			  const_tree type ATTRIBUTE_UNUSED, bool named)
 {
@@ -541,7 +541,7 @@  default_builtin_reciprocal (unsigned int
 
 bool
 hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false (
-	CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+	cumulative_args_t ca ATTRIBUTE_UNUSED,
 	enum machine_mode mode ATTRIBUTE_UNUSED,
 	const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
 {
@@ -550,7 +550,7 @@  hook_bool_CUMULATIVE_ARGS_mode_tree_bool
 
 bool
 hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true (
-	CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+	cumulative_args_t ca ATTRIBUTE_UNUSED,
 	enum machine_mode mode ATTRIBUTE_UNUSED,
 	const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
 {
@@ -559,7 +559,7 @@  hook_bool_CUMULATIVE_ARGS_mode_tree_bool
 
 int
 hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 (
-	CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+	cumulative_args_t ca ATTRIBUTE_UNUSED,
 	enum machine_mode mode ATTRIBUTE_UNUSED,
 	tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
 {
@@ -567,41 +567,43 @@  hook_int_CUMULATIVE_ARGS_mode_tree_bool_
 }
 
 void
-default_function_arg_advance (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+default_function_arg_advance (cumulative_args_t ca ATTRIBUTE_UNUSED,
 			      enum machine_mode mode ATTRIBUTE_UNUSED,
 			      const_tree type ATTRIBUTE_UNUSED,
 			      bool named ATTRIBUTE_UNUSED)
 {
 #ifdef FUNCTION_ARG_ADVANCE
-  CUMULATIVE_ARGS args = *ca;
+  CUMULATIVE_ARGS args = *get_cumulative_args (ca);
   FUNCTION_ARG_ADVANCE (args, mode, CONST_CAST_TREE (type), named);
-  *ca = args;
+  *ca = pack_cumulative_args (args);
 #else
   gcc_unreachable ();
 #endif
 }
 
 rtx
-default_function_arg (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+default_function_arg (cumulative_args_t ca ATTRIBUTE_UNUSED,
 		      enum machine_mode mode ATTRIBUTE_UNUSED,
 		      const_tree type ATTRIBUTE_UNUSED,
 		      bool named ATTRIBUTE_UNUSED)
 {
 #ifdef FUNCTION_ARG
-  return FUNCTION_ARG (*ca, mode, CONST_CAST_TREE (type), named);
+  return FUNCTION_ARG (*get_cumulative_args (ca), mode, CONST_CAST_TREE (type),
+		       named);
 #else
   gcc_unreachable ();
 #endif
 }
 
 rtx
-default_function_incoming_arg (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+default_function_incoming_arg (cumulative_args_t ca ATTRIBUTE_UNUSED,
 			       enum machine_mode mode ATTRIBUTE_UNUSED,
 			       const_tree type ATTRIBUTE_UNUSED,
 			       bool named ATTRIBUTE_UNUSED)
 {
 #ifdef FUNCTION_INCOMING_ARG
-  return FUNCTION_INCOMING_ARG (*ca, mode, CONST_CAST_TREE (type), named);
+  return FUNCTION_INCOMING_ARG (*get_cumulative_args (ca), mode,
+				CONST_CAST_TREE (type), named);
 #else
   gcc_unreachable ();
 #endif
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h	(revision 167032)
+++ gcc/targhooks.h	(working copy)
@@ -35,9 +35,9 @@  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 void default_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int);
+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 *);
+extern bool default_pretend_outgoing_varargs_named (cumulative_args_t);
 
 extern enum machine_mode default_eh_return_filter_mode (void);
 extern enum machine_mode default_libgcc_cmp_return_mode (void);
@@ -58,9 +58,9 @@  extern tree default_cxx_guard_type (void
 extern tree default_cxx_get_cookie_size (tree);
 
 extern bool hook_pass_by_reference_must_pass_in_stack
-  (CUMULATIVE_ARGS *, enum machine_mode mode, const_tree, bool);
+  (cumulative_args_t, enum machine_mode mode, const_tree, bool);
 extern bool hook_callee_copies_named
-  (CUMULATIVE_ARGS *ca, enum machine_mode, const_tree, bool);
+  (cumulative_args_t ca, enum machine_mode, const_tree, bool);
 
 extern void default_print_operand (FILE *, rtx, int);
 extern void default_print_operand_address (FILE *, rtx);
@@ -94,23 +94,23 @@  extern unsigned int default_autovectoriz
 /* These are here, and not in hooks.[ch], because not all users of
    hooks.h include tm.h, and thus we don't have CUMULATIVE_ARGS.  */
 
-extern bool hook_bool_CUMULATIVE_ARGS_false (CUMULATIVE_ARGS *);
-extern bool hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS *);
+extern bool hook_bool_CUMULATIVE_ARGS_false (cumulative_args_t);
+extern bool hook_bool_CUMULATIVE_ARGS_true (cumulative_args_t);
 
 extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false
-  (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool);
+  (cumulative_args_t, enum machine_mode, const_tree, bool);
 extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
-  (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool);
+  (cumulative_args_t, enum machine_mode, const_tree, bool);
 extern int hook_int_CUMULATIVE_ARGS_mode_tree_bool_0
-  (CUMULATIVE_ARGS *, enum machine_mode, tree, bool);
+  (cumulative_args_t, enum machine_mode, tree, bool);
 extern const char *hook_invalid_arg_for_unprototyped_fn
   (const_tree, const_tree, const_tree);
 extern void default_function_arg_advance
-  (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool);
+  (cumulative_args_t, enum machine_mode, const_tree, bool);
 extern rtx default_function_arg
-  (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool);
+  (cumulative_args_t, enum machine_mode, const_tree, bool);
 extern rtx default_function_incoming_arg
-  (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool);
+  (cumulative_args_t, enum machine_mode, const_tree, bool);
 extern unsigned int default_function_arg_boundary (enum machine_mode,
 						   const_tree);
 extern bool hook_bool_const_rtx_commutative_p (const_rtx, int);
Index: gcc/c-family/c-opts.c
===================================================================
--- gcc/c-family/c-opts.c	(revision 167032)
+++ gcc/c-family/c-opts.c	(working copy)
@@ -22,6 +22,7 @@  Software Foundation; either version 3, o
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "c-common.h"
 #include "c-pragma.h"
Index: gcc/java/expr.c
===================================================================
--- gcc/java/expr.c	(revision 167032)
+++ gcc/java/expr.c	(working copy)
@@ -27,6 +27,7 @@  the Free Software Foundation; either ver
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "flags.h"
 #include "java-tree.h"
Index: gcc/target.def
===================================================================
--- gcc/target.def	(revision 167032)
+++ gcc/target.def	(working copy)
@@ -1890,7 +1890,7 @@  HOOK_VECTOR (TARGET_CALLS, calls)
 (pass_by_reference,
  "",
  bool,
- (CUMULATIVE_ARGS *cum, enum machine_mode mode, const_tree type, bool named),
+ (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named),
  hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false)
 
 DEFHOOK
@@ -1903,14 +1903,14 @@  HOOK_VECTOR (TARGET_CALLS, calls)
 DEFHOOK
 (setup_incoming_varargs,
  "",
- void, (CUMULATIVE_ARGS *args_so_far, enum machine_mode mode, tree type,
+ void, (cumulative_args_t args_so_far, enum machine_mode mode, tree type,
 	int *pretend_args_size, int second_time),
  default_setup_incoming_varargs)
 
 DEFHOOK
 (strict_argument_naming,
  "",
- bool, (CUMULATIVE_ARGS *ca),
+ bool, (cumulative_args_t ca),
  hook_bool_CUMULATIVE_ARGS_false)
 
 /* Returns true if we should use
@@ -1919,7 +1919,7 @@  HOOK_VECTOR (TARGET_CALLS, calls)
 DEFHOOK
 (pretend_outgoing_varargs_named,
  "",
- bool, (CUMULATIVE_ARGS *ca),
+ bool, (cumulative_args_t ca),
  default_pretend_outgoing_varargs_named)
 
 /* Given a complex type T, return true if a parameter of type T
@@ -1946,7 +1946,7 @@  HOOK_VECTOR (TARGET_CALLS, calls)
 (callee_copies,
  "",
  bool,
- (CUMULATIVE_ARGS *cum, enum machine_mode mode, const_tree type, bool named),
+ (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named),
  hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false)
 
 /* Return zero for arguments passed entirely on the stack or entirely
@@ -1955,7 +1955,7 @@  HOOK_VECTOR (TARGET_CALLS, calls)
 DEFHOOK
 (arg_partial_bytes,
  "",
- int, (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, bool named),
+ int, (cumulative_args_t cum, enum machine_mode mode, tree type, bool named),
  hook_int_CUMULATIVE_ARGS_mode_tree_bool_0)
 
 /* Update the state in CA to advance past an argument in the
@@ -1966,7 +1966,7 @@  HOOK_VECTOR (TARGET_CALLS, calls)
 (function_arg_advance,
  "",
  void,
- (CUMULATIVE_ARGS *ca, enum machine_mode mode, const_tree type, bool named),
+ (cumulative_args_t ca, enum machine_mode mode, const_tree type, bool named),
  default_function_arg_advance)
 
 /* Return zero if the argument described by the state of CA should
@@ -1977,7 +1977,7 @@  HOOK_VECTOR (TARGET_CALLS, calls)
 DEFHOOK_UNDOC
 (function_arg,
  "",
- rtx, (CUMULATIVE_ARGS *ca, enum machine_mode mode, const_tree type,
+ rtx, (cumulative_args_t ca, enum machine_mode mode, const_tree type,
        bool named),
  default_function_arg)
 
@@ -1987,7 +1987,7 @@  HOOK_VECTOR (TARGET_CALLS, calls)
 DEFHOOK_UNDOC
 (function_incoming_arg,
  "",
- rtx, (CUMULATIVE_ARGS *ca, enum machine_mode mode, const_tree type,
+ rtx, (cumulative_args_t ca, enum machine_mode mode, const_tree type,
        bool named),
  default_function_incoming_arg)
 
Index: gcc/target.h
===================================================================
--- gcc/target.h	(revision 167032)
+++ gcc/target.h	(working copy)
@@ -49,9 +49,31 @@ 
 #ifndef GCC_TARGET_H
 #define GCC_TARGET_H
 
-#include "tm.h"
 #include "insn-modes.h"
 
+#include "insn-cumulative_args_t.h"
+
+#ifndef TARGET_USES_CUMULATIVE_ARGS_T
+
+#include "tm.h"
+typedef CUMULATIVE_ARGS *cumulative_args_t;
+
+#elif defined (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
 {
@@ -176,4 +198,50 @@  struct default_options
 /* Each target can provide their own.  */
 extern struct gcc_targetcm targetcm;
 
+#ifdef GCC_TM_H
+
+#ifdef TARGET_USES_CUMULATIVE_ARGS_T
+
+#ifndef CUMULATIVE_ARGS_MAGIC
+#define CUMULATIVE_ARGS_MAGIC ((void *) &targetm.calls)
+#endif
+
+static inline CUMULATIVE_ARGS *
+get_cumulative_args (cumulative_args_t arg)
+{
+#ifdef ENABLE_CHECKING
+  gcc_assert (arg.magic == CUMULATIVE_ARGS_MAGIC);
+#endif /* ENABLE_CHECKING */
+  return (CUMULATIVE_ARGS *) arg.p;
+}
+
+static inline cumulative_args_t
+pack_cumulative_args (CUMULATIVE_ARGS *arg)
+{
+  cumulative_args_t ret;
+
+#ifdef ENABLE_CHECKING
+  ret.magic = CUMULATIVE_ARGS_MAGIC;
+#endif /* ENABLE_CHECKING */
+  ret.p = (void *) arg;
+  return ret;
+}
+
+#else /* !TARGET_USES_CUMULATIVE_ARGS_T */
+
+static inline CUMULATIVE_ARGS *
+get_cumulative_args (cumulative_args_t arg)
+{
+  return arg;
+}
+
+static inline cumulative_args_t
+pack_cumulative_args (CUMULATIVE_ARGS *arg)
+{
+  return arg;
+}
+
+#endif /* !TARGET_USES_CUMULATIVE_ARGS_T */
+#endif /* GCC_TM_H */
+
 #endif /* GCC_TARGET_H */
Index: gcc/expr.c
===================================================================
--- gcc/expr.c	(revision 167032)
+++ gcc/expr.c	(working copy)
@@ -1238,14 +1238,16 @@  block_move_libcall_safe_for_call_parm (v
     for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
       {
 	enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
-	rtx tmp = targetm.calls.function_arg (&args_so_far, mode,
-					      NULL_TREE, true);
+	rtx tmp
+	  = targetm.calls.function_arg (pack_cumulative_args (&args_so_far),
+					mode, NULL_TREE, true);
 	if (!tmp || !REG_P (tmp))
 	  return false;
-	if (targetm.calls.arg_partial_bytes (&args_so_far, mode, NULL, 1))
+	if (targetm.calls.arg_partial_bytes
+	     (pack_cumulative_args (&args_so_far), mode, NULL, 1))
 	  return false;
-	targetm.calls.function_arg_advance (&args_so_far, mode,
-					    NULL_TREE, true);
+	targetm.calls.function_arg_advance (pack_cumulative_args (&args_so_far),
+					    mode, NULL_TREE, true);
       }
   }
   return true;
Index: gcc/dse.c
===================================================================
--- gcc/dse.c	(revision 167032)
+++ gcc/dse.c	(working copy)
@@ -2322,7 +2322,8 @@  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 (&args_so_far, mode, NULL_TREE, true);
+      reg = targetm.calls.function_arg (pack_cumulative_args (&args_so_far),
+					mode, NULL_TREE, true);
       if (!reg || !REG_P (reg) || GET_MODE (reg) != mode
 	  || GET_MODE_CLASS (mode) != MODE_INT)
 	return false;
@@ -2356,7 +2357,8 @@  get_call_args (rtx call_insn, tree fn, r
       if (tmp)
 	args[idx] = tmp;
 
-      targetm.calls.function_arg_advance (&args_so_far, mode, NULL_TREE, true);
+      targetm.calls.function_arg_advance (pack_cumulative_args (&args_so_far),
+					  mode, NULL_TREE, true);
     }
   if (arg != void_list_node || idx != nargs)
     return false;
Index: gcc/fortran/trans-types.c
===================================================================
--- gcc/fortran/trans-types.c	(revision 167032)
+++ gcc/fortran/trans-types.c	(working copy)
@@ -26,6 +26,7 @@  Software Foundation; either version 3, o
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "langhooks.h"	/* For iso-c-bindings.def.  */
 #include "target.h"
Index: gcc/function.c
===================================================================
--- gcc/function.c	(revision 167032)
+++ gcc/function.c	(working copy)
@@ -2106,7 +2106,8 @@  pass_by_reference (CUMULATIVE_ARGS *ca, 
 	}
     }
 
-  return targetm.calls.pass_by_reference (ca, mode, type, named_arg);
+  return targetm.calls.pass_by_reference (pack_cumulative_args (ca), mode,
+					  type, named_arg);
 }
 
 /* Return true if TYPE, which is passed by reference, should be callee
@@ -2118,7 +2119,7 @@  reference_callee_copied (CUMULATIVE_ARGS
 {
   if (type && TREE_ADDRESSABLE (type))
     return false;
-  return targetm.calls.callee_copies (ca, mode, type, named_arg);
+  return targetm.calls.callee_copies (pack_cumulative_args (ca), mode, type, named_arg);
 }
 
 /* Structures to communicate between the subroutines of assign_parms.
@@ -2291,7 +2292,8 @@  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 (&all->args_so_far))
+  else if (targetm.calls.strict_argument_naming
+	    (pack_cumulative_args (&all->args_so_far)))
     data->named_arg = 1;  /* Only variadic ones are unnamed.  */
   else
     data->named_arg = 0;  /* Treat as variadic.  */
@@ -2356,10 +2358,9 @@  assign_parms_setup_varargs (struct assig
 {
   int varargs_pretend_bytes = 0;
 
-  targetm.calls.setup_incoming_varargs (&all->args_so_far,
-					data->promoted_mode,
-					data->passed_type,
-					&varargs_pretend_bytes, no_rtl);
+  (targetm.calls.setup_incoming_varargs
+    (pack_cumulative_args (&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
@@ -2385,10 +2386,9 @@  assign_parm_find_entry_rtl (struct assig
       return;
     }
 
-  entry_parm = targetm.calls.function_incoming_arg (&all->args_so_far,
-						    data->promoted_mode,
-						    data->passed_type,
-						    data->named_arg);
+  entry_parm = (targetm.calls.function_incoming_arg
+		 (pack_cumulative_args (&all->args_so_far),
+		  data->promoted_mode, data->passed_type, data->named_arg));
 
   if (entry_parm == 0)
     data->promoted_mode = data->passed_mode;
@@ -2409,12 +2409,13 @@  assign_parm_find_entry_rtl (struct assig
 #endif
   if (!in_regs && !data->named_arg)
     {
-      if (targetm.calls.pretend_outgoing_varargs_named (&all->args_so_far))
+      if (targetm.calls.pretend_outgoing_varargs_named
+	   (pack_cumulative_args (&all->args_so_far)))
 	{
 	  rtx tem;
-	  tem = targetm.calls.function_incoming_arg (&all->args_so_far,
-						     data->promoted_mode,
-						     data->passed_type, true);
+	  tem = (targetm.calls.function_incoming_arg
+		  (pack_cumulative_args (&all->args_so_far),
+		   data->promoted_mode, data->passed_type, true));
 	  in_regs = tem != NULL;
 	}
     }
@@ -2429,10 +2430,9 @@  assign_parm_find_entry_rtl (struct assig
     {
       int partial;
 
-      partial = targetm.calls.arg_partial_bytes (&all->args_so_far,
-						 data->promoted_mode,
-						 data->passed_type,
-						 data->named_arg);
+      partial = (targetm.calls.arg_partial_bytes
+		  (pack_cumulative_args (&all->args_so_far),
+		   data->promoted_mode, data->passed_type, data->named_arg));
       data->partial = partial;
 
       /* The caller might already have allocated stack space for the
@@ -3363,8 +3363,9 @@  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 (&all.args_so_far, data.promoted_mode,
-					  data.passed_type, data.named_arg);
+      (targetm.calls.function_arg_advance
+	(pack_cumulative_args (&all.args_so_far), data.promoted_mode,
+			       data.passed_type, data.named_arg));
 
       assign_parm_adjust_stack_rtl (&data);
 
@@ -3553,8 +3554,9 @@  gimplify_parameters (void)
 	continue;
 
       /* Update info on where next arg arrives in registers.  */
-      targetm.calls.function_arg_advance (&all.args_so_far, data.promoted_mode,
-					  data.passed_type, data.named_arg);
+      (targetm.calls.function_arg_advance
+	(pack_cumulative_args (&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
Index: gcc/calls.c
===================================================================
--- gcc/calls.c	(revision 167032)
+++ gcc/calls.c	(working copy)
@@ -1138,23 +1138,25 @@  initialize_argument_information (int num
       args[i].unsignedp = unsignedp;
       args[i].mode = mode;
 
-      args[i].reg = targetm.calls.function_arg (args_so_far, mode, type,
-						argpos < n_named_args);
+      args[i].reg
+	= targetm.calls.function_arg (pack_cumulative_args (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
 	 arguments have to go into the incoming registers.  */
       if (targetm.calls.function_incoming_arg != targetm.calls.function_arg)
 	args[i].tail_call_reg
-	  = targetm.calls.function_incoming_arg (args_so_far, mode, type,
-						 argpos < n_named_args);
+	  = (targetm.calls.function_incoming_arg
+	      (pack_cumulative_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 (args_so_far, mode, type,
-					     argpos < n_named_args);
+	  = targetm.calls.arg_partial_bytes (pack_cumulative_args (args_so_far),
+					     mode, type, argpos < n_named_args);
 
       args[i].pass_on_stack = targetm.calls.must_pass_in_stack (mode, type);
 
@@ -1204,7 +1206,8 @@  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 (args_so_far, TYPE_MODE (type),
+      targetm.calls.function_arg_advance (pack_cumulative_args (args_so_far),
+					  TYPE_MODE (type),
 					  type, argpos < n_named_args);
     }
 }
@@ -2247,10 +2250,12 @@  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 (&args_so_far))
+      && (targetm.calls.strict_argument_naming
+	   (pack_cumulative_args (&args_so_far))))
     ;
   else if (type_arg_types != 0
-	   && ! targetm.calls.pretend_outgoing_varargs_named (&args_so_far))
+	   && ! (targetm.calls.pretend_outgoing_varargs_named
+		  (pack_cumulative_args (&args_so_far))))
     /* Don't include the last named arg.  */
     --n_named_args;
   else
@@ -2861,14 +2866,13 @@  expand_call (tree exp, rtx target, int i
       /* Set up next argument register.  For sibling calls on machines
 	 with register windows this should be the incoming register.  */
       if (pass == 0)
-	next_arg_reg = targetm.calls.function_incoming_arg (&args_so_far,
-							    VOIDmode,
-							    void_type_node,
-							    true);
+	next_arg_reg = (targetm.calls.function_incoming_arg
+			 (pack_cumulative_args (&args_so_far), VOIDmode,
+			  void_type_node, true));
       else
-	next_arg_reg = targetm.calls.function_arg (&args_so_far,
-						   VOIDmode, void_type_node,
-						   true);
+	next_arg_reg
+	  = targetm.calls.function_arg (pack_cumulative_args (&args_so_far),
+					VOIDmode, void_type_node, true);
 
       /* All arguments and registers used for the call must be set up by
 	 now!  */
@@ -3455,10 +3459,12 @@  emit_library_call_value_1 (int retval, r
       argvec[count].mode = Pmode;
       argvec[count].partial = 0;
 
-      argvec[count].reg = targetm.calls.function_arg (&args_so_far,
-						      Pmode, NULL_TREE, true);
-      gcc_assert (targetm.calls.arg_partial_bytes (&args_so_far, Pmode,
-						   NULL_TREE, 1) == 0);
+      argvec[count].reg
+	= targetm.calls.function_arg (pack_cumulative_args (&args_so_far),
+				      Pmode, NULL_TREE, true);
+      gcc_assert ((targetm.calls.arg_partial_bytes
+		    (pack_cumulative_args (&args_so_far), Pmode, NULL_TREE, 1))
+		  == 0);
 
       locate_and_pad_parm (Pmode, NULL_TREE,
 #ifdef STACK_PARMS_IN_REG_PARM_AREA
@@ -3472,7 +3478,8 @@  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 (&args_so_far, Pmode, (tree) 0, true);
+      targetm.calls.function_arg_advance (pack_cumulative_args (&args_so_far),
+					  Pmode, (tree) 0, true);
 
       count++;
     }
@@ -3531,11 +3538,13 @@  emit_library_call_value_1 (int retval, r
       argvec[count].value = val;
       argvec[count].mode = mode;
 
-      argvec[count].reg = targetm.calls.function_arg (&args_so_far, mode,
-						      NULL_TREE, true);
+      argvec[count].reg
+	= targetm.calls.function_arg (pack_cumulative_args (&args_so_far),
+				      mode, NULL_TREE, true);
 
       argvec[count].partial
-	= targetm.calls.arg_partial_bytes (&args_so_far, mode, NULL_TREE, 1);
+	= targetm.calls.arg_partial_bytes (pack_cumulative_args (&args_so_far),
+					   mode, NULL_TREE, 1);
 
       locate_and_pad_parm (mode, NULL_TREE,
 #ifdef STACK_PARMS_IN_REG_PARM_AREA
@@ -3552,7 +3561,8 @@  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 (&args_so_far, mode, (tree) 0, true);
+      targetm.calls.function_arg_advance (pack_cumulative_args (&args_so_far),
+					  mode, (tree) 0, true);
     }
 
   /* If this machine requires an external definition for library
@@ -3868,7 +3878,7 @@  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 (&args_so_far,
+	       targetm.calls.function_arg (pack_cumulative_args (&args_so_far),
 					   VOIDmode, void_type_node, true),
 	       valreg,
 	       old_inhibit_defer_pop + 1, call_fusage, flags, & args_so_far);
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 167032)
+++ gcc/Makefile.in	(working copy)
@@ -874,7 +874,7 @@  REVISION_s  := "\"$(if $(DEVPHASE_c), $(
 VEC_H = vec.h statistics.h
 EXCEPT_H = except.h $(HASHTAB_H) vecprim.h vecir.h
 TOPLEV_H = toplev.h $(INPUT_H) bversion.h $(DIAGNOSTIC_CORE_H)
-TARGET_H = $(TM_H) target.h target.def insn-modes.h
+TARGET_H = insn-cumulative_args_t.h target.h target.def insn-modes.h
 MACHMODE_H = machmode.h mode-classes.def insn-modes.h
 HOOKS_H = hooks.h $(MACHMODE_H)
 HOSTHOOKS_DEF_H = hosthooks-def.h $(HOOKS_H)
@@ -3708,6 +3708,13 @@  s-constrs-h: $(MD_DEPS) build/genpreds$(
 	$(SHELL) $(srcdir)/../move-if-change tmp-constrs.h tm-constrs.h
 	$(STAMP) s-constrs-h
 
+insn-cumulative_args_t.h : s-cumulative_args_t; @true
+s-cumulative_args_t: $(out_file:.o=.c)
+	if test -n "`grep cumulative_args_t $^`"; then \
+	  echo '#define TARGET_USES_CUMULATIVE_ARGS_T 1'; \
+	fi > tmp-cumulative_args_t.h
+	$(SHELL) $(srcdir)/../move-if-change tmp-cumulative_args_t.h insn-cumulative_args_t.h
+
 target-hooks-def.h: s-target-hooks-def-h; @true
 # make sure that when we build info files, the used tm.texi is up to date.
 $(srcdir)/doc/tm.texi: s-tm-texi; @true