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


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

[PATCH] Optimize __builtin_va_{start,copy,end} on typedef {char,void} *va_list; targets (PR middle-end/20983)


Hi!

Since ADDRESSOF was killed, GCC creates inefficient code for
va_{start,copy,end} on "va_list is simple pointer" targets.
The problem is that the __builtin_va_{start,copy,end} builtins
survive until expand, and all of them take address of the va_list
variable (set it by reference).  This means it is TREE_ADDRESSABLE
and as there is no ADDRESSOF, it is thrown into memory (i.e. it
is a code quality regression since 3.4.x).

The following patch fixes it, by always optimizing out in
pass_fold_all_builtins __builtin_va_end, which is a nop everywhere:
static rtx
expand_builtin_va_end (tree exp)
{
  tree valist = CALL_EXPR_ARG (exp, 0);
                          
  /* Evaluate for side effects, if needed.  I hate macros that don't
     do that.  */
  if (TREE_SIDE_EFFECTS (valist))
    expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
      
  return const0_rtx;
}
and in GIMPLE the argument can't have side-effects and on the simple
pointer va_list targets also __builtin_va_start (&ap, 0); into
ap = __builtin_next_arg (0); if that's the standard expander that is used:
void
std_expand_builtin_va_start (tree valist, rtx nextarg)
{
  rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
  convert_move (va_r, nextarg, 0);
}
where
  nextarg = expand_builtin_next_arg ();
  valist = stabilize_va_list (CALL_EXPR_ARG (exp, 0), 1);
and for va_list simple pointer also __builtin_va_copy into a pointer
assignment.

The patch is big, but the real changes are just in tree-ssa-ccp.c,
the rest is only mechanical changes to convert EXPAND_BUILTIN_VA_START
target macro into targetm.expand_bultin_va_start target hook
(which allows tree-ssa-ccp.c to find out if the default
std_expand_builtin_va_start is used or some other).
The optimization is done directly from execute_fold_all_builtins
rather than from builtins.c folders, because the pass_stdarg optimization
relies on the builtins still being in the code (and tree inlininer does as
well), so we don't want them to be folded too early.  And it makes no sense
to try to fold them several times anyway.

Some code improvement examples, e.g. on:

typedef __builtin_va_list __gnuc_va_list;
typedef __gnuc_va_list va_list;

int bar (int, va_list, va_list);

int foo (int x, ...)
{
  va_list ap1, ap2;
  __builtin_va_start(ap1,x);
  __builtin_va_copy(ap2,ap1);
  bar (x, ap1, ap2);
  __builtin_va_end(ap1);
  __builtin_va_end(ap2);
}

on x86_64-linux with -O2 -fomit-frame-pointer -m32 the difference
is:

--- m.s.vanilla	2007-11-16 09:37:27.000000000 +0100
+++ m.s.patched	2007-11-16 09:37:32.000000000 +0100
@@ -4,16 +4,14 @@
 .globl foo
 	.type	foo, @function
 foo:
-	subl	$28, %esp
-	leal	36(%esp), %eax
-	movl	%eax, 24(%esp)
-	movl	%eax, 20(%esp)
+	subl	$12, %esp
+	leal	20(%esp), %eax
 	movl	%eax, 8(%esp)
 	movl	%eax, 4(%esp)
-	movl	32(%esp), %eax
+	movl	16(%esp), %eax
 	movl	%eax, (%esp)
 	call	bar
-	addl	$28, %esp
+	addl	$12, %esp
 	ret
 	.size	foo, .-foo
 	.ident	"GCC: (GNU) 4.3.0 20071115 (experimental)"

and on ppc64-linux -O2 -fomit-frame-pointer -m64:

--- m.s.vanilla	2007-11-16 09:44:41.000000000 +0100
+++ m.s.patched	2007-11-16 09:44:18.000000000 +0100
@@ -13,22 +13,19 @@ foo:
 .L.foo:
        mflr 0
        std 0,16(1)
-       stdu 1,-128(1)
-       std 4,184(1)
-       std 5,192(1)
-       std 6,200(1)
-       std 7,208(1)
-       std 8,216(1)
-       std 9,224(1)
-       std 10,232(1)
-       addi 0,1,184
-       mr 4,0
-       mr 5,0
-       std 0,112(1)
-       std 0,120(1)
+       stdu 1,-112(1)
+       std 4,168(1)
+       std 5,176(1)
+       std 6,184(1)
+       std 7,192(1)
+       std 8,200(1)
+       std 9,208(1)
+       std 10,216(1)
+       addi 4,1,168
+       mr 5,4
        bl bar
        nop
-       addi 1,1,128
+       addi 1,1,112
        ld 0,16(1)
        mtlr 0
        blr

Another testcase:

int
foo (int a, ...)
{
  __builtin_va_list va;
  int c, i;

  __builtin_va_start (va, a);
  c = 0;
  while ((i = __builtin_va_arg (va, int)) != 0)
    c += i;
  __builtin_va_end (va);
  return c;
}

on x86_64-linux with -O2 -fomit-frame-pointer -m32 the difference
is:

--- pr20983.s.vanilla	2007-11-16 09:40:48.000000000 +0100
+++ pr20983.s.patched	2007-11-16 09:40:55.000000000 +0100
@@ -4,25 +4,21 @@
 .globl foo
 	.type	foo, @function
 foo:
-	subl	$16, %esp
-	xorl	%ecx, %ecx
-	movl	24(%esp), %edx
-	leal	28(%esp), %eax
-	movl	%eax, 12(%esp)
+	movl	8(%esp), %edx
+	xorl	%eax, %eax
+	leal	12(%esp), %ecx
 	testl	%edx, %edx
 	je	.L3
 	.p2align 4,,7
 	.p2align 3
 .L6:
-	addl	$4, %eax
-	addl	%edx, %ecx
-	movl	-4(%eax), %edx
+	addl	$4, %ecx
+	addl	%edx, %eax
+	movl	-4(%ecx), %edx
 	testl	%edx, %edx
 	jne	.L6
-	movl	%eax, 12(%esp)
 .L3:
-	movl	%ecx, %eax
-	addl	$16, %esp
+	rep
 	ret
 	.size	foo, .-foo
 	.ident	"GCC: (GNU) 4.3.0 20071115 (experimental)"

and on ppc64-linux -O2 -fomit-frame-pointer -m64:

--- pr20983.s.vanilla	2007-11-16 09:46:38.000000000 +0100
+++ pr20983.s.patched	2007-11-16 09:46:31.000000000 +0100
@@ -12,26 +12,24 @@ foo:
        .type   foo, @function
 .L.foo:
        extsw. 0,4
-       addi 11,1,64
+       std 9,96(1)
+       std 8,88(1)
+       addi 9,1,64
        std 5,64(1)
        std 6,72(1)
-       std 7,80(1)
-       std 8,88(1)
        li 3,0
-       std 9,96(1)
+       std 7,80(1)
        std 10,104(1)
        std 4,56(1)
-       std 11,-16(1)
        beqlr 0
        .p2align 4,,15
 .L6:
-       addi 11,11,8
+       addi 9,9,8
        add 0,0,3
        extsw 3,0
-       lwa 0,-4(11)
+       lwa 0,-4(9)
        cmpdi 7,0,0
        bne 7,.L6
-       std 11,-16(1)
        blr
        .long 0
        .byte 0,0,0,0,0,0,0,0

On ia64-linux I saw similar improvement on these testcases.

For 4.4 there are further improvements possible, one is to optimize
the rest of the simple pointer architectures (there is a couple of
targets which use std_expand_builtin_va_start, but do something
on top of that, e.g. also add a __builtin_saveregs () call or add
some constant to the nextarg before calling it).  So perhaps a
fold_builtin_va_start target hook could be eventually useful.
On targets which use one entry array of structures instead of a pointer
the changes would be too involved for 4.3 and would be only useful if
it could be scalarized.

Bootstrapped/regtested on x86_64-linux, i686-linux, ppc64-linux (-m64 by
default).  Ok for trunk?

2007-11-16  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/20983
	* tree-ssa-ccp.c (optimize_stdarg_builtin): New function.
	(execute_fold_all_builtins): Call it for BUILT_IN_VA_START,
	BUILT_IN_VA_COPY and BUILT_IN_VA_END.

	* target.h (struct ggc_target): Add expand_builtin_va_start
	hook.
	* target-def.h (TARGET_EXPAND_BUILTIN_VA_START): Define.
	(TARGET_INITIALIZER): Add it.
	* builtins.c (expand_builtin_va_start): Use
	targetm.expand_builtin_va_start hook instead of
	EXPAND_BUILTIN_VA_START macro.
	* alpha/alpha.c (alpha_va_start): Made static.
	(override_options): Clear targetm.expand_builtin_va_start if
	TARGET_UNICOSMK.
	(TARGET_EXPAND_BUILTIN_VA_START): Define.
	* alpha/unicosmk.h (EXPAND_BUILTIN_VA_START): Remove.
	* alpha/alpha.h (EXPAND_BUILTIN_VA_START): Remove.
	* alpha/alpha-protos.h (alpha_va_start): Remove prototype.
	* xtensa/xtensa.h (EXPAND_BUILTIN_VA_START): Remove.
	* xtensa/xtensa.c (TARGET_EXPAND_BUILTIN_VA_START): Define.
	(xtensa_va_start): Made static.
	* xtensa/xtensa-protos.h (xtensa_va_start): Remove prototype.
	* pa/pa-protos.h (hppa_va_start): Remove prototype.
	* pa/pa.h (EXPAND_BUILTIN_VA_START): Remove.
	* pa/pa.c (hppa_va_start): Made static, add prototype.
	(TARGET_EXPAND_BUILTIN_VA_START): Define.
	* frv/frv.c (frv_expand_builtin_va_start): Made static, add prototype.
	(TARGET_EXPAND_BUILTIN_VA_START): Define.
	* frv/frv-protos.h (frv_expand_builtin_va_start): Remove prototype.
	* frv/frv.h (EXPAND_BUILTIN_VA_START): Remove.
	* i386/i386.c (override_options): Clear
	targetm.expand_builtin_va_start if -m32 or 64-bit MS ABI.
	(ix86_va_start): Made static.
	(TARGET_EXPAND_BUILTIN_VA_START): Define.
	* i386/i386.h (EXPAND_BUILTIN_VA_START): Remove.
	* i386/i386-protos.h (ix86_va_start, ix86_va_arg): Remove prototypes.
	* iq2000/iq2000-protos.h (iq2000_va_start): Remove prototype.
	* iq2000/iq2000.h (EXPAND_BUILTIN_VA_START): Remove.
	* iq2000/iq2000.c (iq2000_va_start): Made static, add prototype.
	(TARGET_EXPAND_BUILTIN_VA_START): Define.
	* rs6000/rs6000-protos.h (rs6000_va_start): Remove prototype.
	* rs6000/rs6000.c (rs6000_va_start): Made static, add prototype.
	(TARGET_EXPAND_BUILTIN_VA_START): Define.
	(rs6000_override_options): Clear targetm.expand_builtin_va_start if
	DEFAULT_ABI != ABI_V4.
	* rs6000/rs6000.h (EXPAND_BUILTIN_VA_START): Remove.
	* spu/spu.c (spu_va_start): Made static, add prototype.
	(TARGET_EXPAND_BUILTIN_VA_START): Define.
	* spu/spu.h (EXPAND_BUILTIN_VA_START): Remove.
	* spu/spu-protos.h spu_va_start): Remove prototype.
	* stormy16/stormy16.h (EXPAND_BUILTIN_VA_START): Remove.
	* stormy16/stormy16-protos.h (xstormy16_expand_builtin_va_start):
	Remove prototype.
	* stormy16/stormy16.c (xstormy16_expand_builtin_va_start): Made
	static.
	(TARGET_EXPAND_BUILTIN_VA_START): Define.
	* s390/s390-protos.h (s390_va_start): Remove prototype.
	* s390/s390.c (s390_va_start): Made static.
	(TARGET_EXPAND_BUILTIN_VA_START): Define.
	* s390/s390.h (EXPAND_BUILTIN_VA_START): Remove.
	* mn10300/mn10300.h (EXPAND_BUILTIN_VA_START): Remove.
	* mn10300/mn10300-protos.h (mn10300_va_start): Remove prototype.
	* mn10300/mn10300.c (mn10300_va_start): Made static, add prototype.
	(TARGET_EXPAND_BUILTIN_VA_START): Define.
	* arc/arc.c (arc_va_start): Made static, add prototype.
	(TARGET_EXPAND_BUILTIN_VA_START): Define.
	* arc/arc.h (EXPAND_BUILTIN_VA_START): Remove.
	* arc/arc-protos.h (arc_va_start): Remove prototype.
	* mt/mt-protos.h (mt_va_start): Remove prototype.
	* sparc/sparc.c (sparc_va_start): Made static, add prototype.
	(TARGET_EXPAND_BUILTIN_VA_START): Define.
	* sparc/sparc-protos.h (sparc_va_start): Remove prototype.
	* sparc/sparc.h (EXPAND_BUILTIN_VA_START): Remove.
	* sh/sh.c (sh_va_start): Made static, add prototype.
	(TARGET_EXPAND_BUILTIN_VA_START): Define.
	* sh/sh-protos.h (sh_va_start): Remove prototype.
	* sh/sh.h (EXPAND_BUILTIN_VA_START): Remove.
	* mips/mips-protos.h (mips_va_start): Remove prototype.
	* mips/mips.h (EXPAND_BUILTIN_VA_START): Remove.
	* mips/mips.c (mips_va_start): Made static.
	(TARGET_EXPAND_BUILTIN_VA_START): Define.

--- gcc/target.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/target.h	2007-11-15 22:47:40.000000000 +0100
@@ -694,6 +694,9 @@ struct gcc_target
   /* Create the __builtin_va_list type.  */
   tree (* build_builtin_va_list) (void);
 
+  /* Expand the __builtin_va_start builtin.  */
+  void (* expand_builtin_va_start) (tree valist, rtx nextarg);
+
   /* Gimplifies a VA_ARG_EXPR.  */
   tree (* gimplify_va_arg_expr) (tree valist, tree type, tree *pre_p,
 				 tree *post_p);
--- gcc/target-def.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/target-def.h	2007-11-15 22:47:40.000000000 +0100
@@ -517,6 +517,7 @@
 #define TARGET_MACHINE_DEPENDENT_REORG 0
 
 #define TARGET_BUILD_BUILTIN_VA_LIST std_build_builtin_va_list
+#define TARGET_EXPAND_BUILTIN_VA_START 0
 
 #define TARGET_GET_PCH_VALIDITY default_get_pch_validity
 #define TARGET_PCH_VALID_P default_pch_valid_p
@@ -750,6 +751,7 @@
   TARGET_CC_MODES_COMPATIBLE,			\
   TARGET_MACHINE_DEPENDENT_REORG,		\
   TARGET_BUILD_BUILTIN_VA_LIST,			\
+  TARGET_EXPAND_BUILTIN_VA_START,		\
   TARGET_GIMPLIFY_VA_ARG_EXPR,			\
   TARGET_GET_PCH_VALIDITY,			\
   TARGET_PCH_VALID_P,				\
--- gcc/builtins.c.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/builtins.c	2007-11-15 22:47:40.000000000 +0100
@@ -4700,11 +4700,10 @@ expand_builtin_va_start (tree exp)
   nextarg = expand_builtin_next_arg ();
   valist = stabilize_va_list (CALL_EXPR_ARG (exp, 0), 1);
 
-#ifdef EXPAND_BUILTIN_VA_START
-  EXPAND_BUILTIN_VA_START (valist, nextarg);
-#else
-  std_expand_builtin_va_start (valist, nextarg);
-#endif
+  if (targetm.expand_builtin_va_start)
+    targetm.expand_builtin_va_start (valist, nextarg);
+  else
+    std_expand_builtin_va_start (valist, nextarg);
 
   return const0_rtx;
 }
--- gcc/tree-ssa-ccp.c.jj	2007-11-15 20:02:05.000000000 +0100
+++ gcc/tree-ssa-ccp.c	2007-11-16 10:41:33.000000000 +0100
@@ -2671,6 +2671,78 @@ optimize_stack_restore (basic_block bb, 
   return integer_zero_node;
 }
 
+/* If va_list type is a simple pointer and nothing special is needed,
+   optimize __builtin_va_start (&ap, 0) into ap = __builtin_next_arg (0),
+   __builtin_va_end (&ap) out as NOP and __builtin_va_copy into a simple
+   pointer assignment.  */
+
+static tree
+optimize_stdarg_builtin (tree call)
+{
+  tree callee, lhs, rhs;
+  bool va_list_simple_ptr;
+
+  if (TREE_CODE (call) != CALL_EXPR)
+    return NULL_TREE;
+
+  va_list_simple_ptr = POINTER_TYPE_P (va_list_type_node)
+		       && (TREE_TYPE (va_list_type_node) == void_type_node
+			   || TREE_TYPE (va_list_type_node) == char_type_node);
+
+  callee = get_callee_fndecl (call);
+  switch (DECL_FUNCTION_CODE (callee))
+    {
+    case BUILT_IN_VA_START:
+      if (!va_list_simple_ptr
+	  || targetm.expand_builtin_va_start != NULL
+	  || built_in_decls[BUILT_IN_NEXT_ARG] == NULL)
+	return NULL_TREE;
+
+      if (call_expr_nargs (call) != 2)
+	return NULL_TREE;
+
+      lhs = CALL_EXPR_ARG (call, 0);
+      if (!POINTER_TYPE_P (TREE_TYPE (lhs))
+	  || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs)))
+	     != TYPE_MAIN_VARIANT (va_list_type_node))
+	return NULL_TREE;
+
+      lhs = build_fold_indirect_ref (lhs);
+      rhs = build_call_expr (built_in_decls[BUILT_IN_NEXT_ARG],
+			     1, integer_zero_node);
+      rhs = fold_convert (TREE_TYPE (lhs), rhs);
+      return build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, rhs);
+
+    case BUILT_IN_VA_COPY:
+      if (!va_list_simple_ptr)
+	return NULL_TREE;
+
+      if (call_expr_nargs (call) != 2)
+	return NULL_TREE;
+
+      lhs = CALL_EXPR_ARG (call, 0);
+      if (!POINTER_TYPE_P (TREE_TYPE (lhs))
+	  || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs)))
+	     != TYPE_MAIN_VARIANT (va_list_type_node))
+	return NULL_TREE;
+
+      lhs = build_fold_indirect_ref (lhs);
+      rhs = CALL_EXPR_ARG (call, 1);
+      if (TYPE_MAIN_VARIANT (TREE_TYPE (rhs))
+	  != TYPE_MAIN_VARIANT (va_list_type_node))
+	return NULL_TREE;
+
+      rhs = fold_convert (TREE_TYPE (lhs), rhs);
+      return build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, rhs);
+
+    case BUILT_IN_VA_END:
+      return integer_zero_node;
+
+    default:
+      gcc_unreachable ();
+    }
+}
+
 /* Convert EXPR into a GIMPLE value suitable for substitution on the
    RHS of an assignment.  Insert the necessary statements before
    iterator *SI_P. 
@@ -2759,6 +2831,16 @@ execute_fold_all_builtins (void)
 		result = optimize_stack_restore (bb, *stmtp, i);
 		if (result)
 		  break;
+                bsi_next (&i);
+                continue;
+
+	      case BUILT_IN_VA_START:
+	      case BUILT_IN_VA_END:
+	      case BUILT_IN_VA_COPY:
+		/* These shouldn't be folded before pass_stdarg.  */
+		result = optimize_stdarg_builtin (*stmtp);
+		if (result)
+		  break;
 		/* FALLTHRU */
 
 	      default:
--- gcc/config/alpha/alpha.c.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/alpha/alpha.c	2007-11-15 22:47:40.000000000 +0100
@@ -522,6 +522,11 @@ override_options (void)
   if (!(target_flags_explicit & MASK_LONG_DOUBLE_128))
     target_flags |= MASK_LONG_DOUBLE_128;
 #endif
+
+  /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
+     can be optimized to ap = __builtin_next_arg (0).  */
+  if (TARGET_ABI_UNICOSMK)
+    targetm.expand_builtin_va_start = NULL;
 }
 
 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones.  */
@@ -6069,7 +6074,7 @@ alpha_setup_incoming_varargs (CUMULATIVE
 #endif
 }
 
-void
+static void
 alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
 {
   HOST_WIDE_INT offset;
@@ -10704,6 +10709,9 @@ alpha_init_libfuncs (void)
 #undef TARGET_BUILD_BUILTIN_VA_LIST
 #define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list
 
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START alpha_va_start
+
 /* The Alpha architecture does not require sequential consistency.  See
    http://www.cs.umd.edu/~pugh/java/memoryModel/AlphaReordering.html
    for an example of how it can be violated in practice.  */
--- gcc/config/alpha/unicosmk.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/alpha/unicosmk.h	2007-11-15 22:47:40.000000000 +0100
@@ -435,6 +435,4 @@ do { fprintf (FILE, "\tbr $1,0\n");			\
 #undef LIB_SPEC
 #define LIB_SPEC "-L/opt/ctl/craylibs/craylibs -lu -lm -lc -lsma"
 
-#undef EXPAND_BUILTIN_VA_START
-
 #define EH_FRAME_IN_DATA_SECTION 1
--- gcc/config/alpha/alpha.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/alpha/alpha.h	2007-11-15 22:47:40.000000000 +0100
@@ -1335,10 +1335,6 @@ do {						\
 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
   print_operand_address((FILE), (ADDR))
 
-/* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  alpha_va_start (valist, nextarg)
-
 /* Tell collect that the object format is ECOFF.  */
 #define OBJECT_FORMAT_COFF
 #define EXTENDED_COFF
--- gcc/config/alpha/alpha-protos.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/alpha/alpha-protos.h	2007-11-15 22:47:40.000000000 +0100
@@ -75,7 +75,6 @@ extern void print_operand (FILE *, rtx, 
 extern void print_operand_address (FILE *, rtx);
 extern void alpha_initialize_trampoline (rtx, rtx, rtx, int, int, int);
 
-extern void alpha_va_start (tree, rtx);
 extern rtx alpha_va_arg (tree, tree);
 extern rtx function_arg (CUMULATIVE_ARGS, enum machine_mode, tree, int);
 extern rtx function_value (const_tree, const_tree, enum machine_mode);
--- gcc/config/xtensa/xtensa.h.jj	2007-11-15 20:00:40.000000000 +0100
+++ gcc/config/xtensa/xtensa.h	2007-11-15 22:47:40.000000000 +0100
@@ -782,10 +782,6 @@ typedef struct xtensa_args
 		       0, VOIDmode, 1, addr, Pmode);			\
   } while (0)
 
-/* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  xtensa_va_start (valist, nextarg)
-
 /* If defined, a C expression that produces the machine-specific code
    to setup the stack so that arbitrary frames can be accessed.
 
--- gcc/config/xtensa/xtensa.c.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/xtensa/xtensa.c	2007-11-15 22:47:40.000000000 +0100
@@ -179,6 +179,9 @@ static const int reg_nonleaf_alloc_order
 #undef TARGET_BUILD_BUILTIN_VA_LIST
 #define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
 
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start
+
 #undef TARGET_PROMOTE_FUNCTION_ARGS
 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
 #undef TARGET_PROMOTE_FUNCTION_RETURN
@@ -2478,7 +2481,7 @@ xtensa_builtin_saveregs (void)
 /* Implement `va_start' for varargs and stdarg.  We look at the
    current function to fill in an initial va_list.  */
 
-void
+static void
 xtensa_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
 {
   tree f_stk, stk;
--- gcc/config/xtensa/xtensa-protos.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/xtensa/xtensa-protos.h	2007-11-15 22:47:40.000000000 +0100
@@ -58,7 +58,6 @@ extern rtx xtensa_legitimize_address (rt
 
 #ifdef TREE_CODE
 extern void init_cumulative_args (CUMULATIVE_ARGS *, int);
-extern void xtensa_va_start (tree, rtx);
 #endif /* TREE_CODE */
 
 extern void print_operand (FILE *, rtx, int);
--- gcc/config/pa/pa-protos.h.jj	2007-11-15 20:00:37.000000000 +0100
+++ gcc/config/pa/pa-protos.h	2007-11-15 22:47:40.000000000 +0100
@@ -29,9 +29,6 @@ extern int following_call (rtx);
 extern int function_label_operand (rtx, enum machine_mode);
 extern int lhs_lshift_cint_operand (rtx, enum machine_mode);
 
-#ifdef TREE_CODE
-extern void hppa_va_start (tree, rtx);
-#endif /* TREE_CODE */
 extern rtx hppa_legitimize_address (rtx, rtx, enum machine_mode);
 
 /* Define functions in pa.c and used in insn-output.c.  */
--- gcc/config/pa/pa.h.jj	2007-11-15 20:00:37.000000000 +0100
+++ gcc/config/pa/pa.h	2007-11-15 22:47:40.000000000 +0100
@@ -976,11 +976,6 @@ extern int may_call_alloca;
    
 #define TRAMPOLINE_ADJUST_ADDRESS(ADDR) \
   if (!TARGET_64BIT) (ADDR) = memory_address (Pmode, plus_constant ((ADDR), 46))
-
-/* Implement `va_start' for varargs and stdarg.  */
-
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  hppa_va_start (valist, nextarg)
 
 /* Addressing modes, and classification of registers for them. 
 
--- gcc/config/pa/pa.c.jj	2007-11-15 20:00:37.000000000 +0100
+++ gcc/config/pa/pa.c	2007-11-15 22:47:40.000000000 +0100
@@ -124,6 +124,7 @@ static void pa_asm_out_destructor (rtx, 
 #endif
 static void pa_init_builtins (void);
 static rtx hppa_builtin_saveregs (void);
+static void hppa_va_start (tree, rtx);
 static tree hppa_gimplify_va_arg_expr (tree, tree, tree *, tree *);
 static bool pa_scalar_mode_supported_p (enum machine_mode);
 static bool pa_commutative_p (const_rtx x, int outer_code);
@@ -304,6 +305,8 @@ static size_t n_deferred_plabels = 0;
 
 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
 #define TARGET_EXPAND_BUILTIN_SAVEREGS hppa_builtin_saveregs
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START hppa_va_start
 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR hppa_gimplify_va_arg_expr
 
@@ -5913,7 +5916,7 @@ hppa_builtin_saveregs (void)
 				    offset, 0, 0, OPTAB_LIB_WIDEN));
 }
 
-void
+static void
 hppa_va_start (tree valist, rtx nextarg)
 {
   nextarg = expand_builtin_saveregs ();
--- gcc/config/frv/frv.c.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/frv/frv.c	2007-11-15 22:47:40.000000000 +0100
@@ -365,6 +365,7 @@ static void frv_setup_incoming_varargs		
 						 enum machine_mode,
 						 tree, int *, int);
 static rtx frv_expand_builtin_saveregs		(void);
+static void frv_expand_builtin_va_start		(tree, rtx);
 static bool frv_rtx_costs			(rtx, int, int, int*);
 static void frv_asm_out_constructor		(rtx, int);
 static void frv_asm_out_destructor		(rtx, int);
@@ -453,6 +454,9 @@ static void frv_output_dwarf_dtprel		(FI
 #undef TARGET_MACHINE_DEPENDENT_REORG
 #define TARGET_MACHINE_DEPENDENT_REORG frv_reorg
 
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START frv_expand_builtin_va_start
+
 #if HAVE_AS_TLS
 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
 #define TARGET_ASM_OUTPUT_DWARF_DTPREL frv_output_dwarf_dtprel
@@ -2186,7 +2190,7 @@ frv_expand_builtin_saveregs (void)
 
 /* Expand __builtin_va_start to do the va_start macro.  */
 
-void
+static void
 frv_expand_builtin_va_start (tree valist, rtx nextarg)
 {
   tree t;
--- gcc/config/frv/frv-protos.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/frv/frv-protos.h	2007-11-15 22:47:40.000000000 +0100
@@ -64,8 +64,6 @@ extern rtx frv_function_arg			(CUMULATIV
 extern void frv_function_arg_advance		(CUMULATIVE_ARGS *,
 						 enum machine_mode,
 						 tree, int);
-
-extern void frv_expand_builtin_va_start		(tree, rtx);
 #endif /* TREE_CODE */
 
 extern int frv_expand_block_move		(rtx *);
--- gcc/config/frv/frv.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/frv/frv.h	2007-11-15 22:47:40.000000000 +0100
@@ -1847,19 +1847,6 @@ typedef struct frv_stack {
 
 #define FUNCTION_PROFILER(FILE, LABELNO)
 
-
-/* Implementing the Varargs Macros.  */
-
-/* Implement the stdarg/varargs va_start macro.  STDARG_P is nonzero if this
-   is stdarg.h instead of varargs.h.  VALIST is the tree of the va_list
-   variable to initialize.  NEXTARG is the machine independent notion of the
-   'next' argument after the variable arguments.  If not defined, a standard
-   implementation will be defined that works for arguments passed on the stack.  */
-
-#define EXPAND_BUILTIN_VA_START(VALIST, NEXTARG)		\
-  (frv_expand_builtin_va_start(VALIST, NEXTARG))
-
-
 /* Trampolines for Nested Functions.  */
 
 /* A C expression for the size in bytes of the trampoline, as an integer.  */
--- gcc/config/i386/i386.c.jj	2007-11-15 20:00:40.000000000 +0100
+++ gcc/config/i386/i386.c	2007-11-15 22:47:41.000000000 +0100
@@ -2689,6 +2689,11 @@ override_options (void)
     set_param_value ("l1-cache-size", ix86_cost->l1_cache_size);
   if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
     set_param_value ("l2-cache-size", ix86_cost->l2_cache_size);
+
+  /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
+     can be optimized to ap = __builtin_next_arg (0).  */
+  if (!TARGET_64BIT || TARGET_64BIT_MS_ABI)
+    targetm.expand_builtin_va_start = NULL;
 }
 
 /* Return true if this goes in large data/bss.  */
@@ -5037,7 +5042,7 @@ ix86_setup_incoming_varargs (CUMULATIVE_
 
 /* Implement va_start.  */
 
-void
+static void
 ix86_va_start (tree valist, rtx nextarg)
 {
   HOST_WIDE_INT words, n_gpr, n_fpr;
@@ -25232,6 +25237,9 @@ x86_builtin_vectorization_cost (bool run
 #undef TARGET_BUILD_BUILTIN_VA_LIST
 #define TARGET_BUILD_BUILTIN_VA_LIST ix86_build_builtin_va_list
 
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START ix86_va_start
+
 #undef TARGET_MD_ASM_CLOBBERS
 #define TARGET_MD_ASM_CLOBBERS ix86_md_asm_clobbers
 
--- gcc/config/i386/i386.h.jj	2007-11-15 20:00:40.000000000 +0100
+++ gcc/config/i386/i386.h	2007-11-15 22:47:41.000000000 +0100
@@ -1704,10 +1704,6 @@ typedef struct ix86_args {
 #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
   function_arg (&(CUM), (MODE), (TYPE), (NAMED))
 
-/* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(VALIST, NEXTARG) \
-  ix86_va_start (VALIST, NEXTARG)
-
 #define TARGET_ASM_FILE_END ix86_file_end
 #define NEED_INDICATE_EXEC_STACK 0
 
--- gcc/config/i386/i386-protos.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/i386/i386-protos.h	2007-11-15 22:47:41.000000000 +0100
@@ -137,8 +137,6 @@ extern bool ix86_function_arg_regno_p (i
 extern int ix86_function_arg_boundary (enum machine_mode, tree);
 extern int ix86_return_in_memory (const_tree);
 extern int ix86_sol10_return_in_memory (const_tree);
-extern void ix86_va_start (tree, rtx);
-extern rtx ix86_va_arg (tree, tree);
 
 extern rtx ix86_force_to_memory (enum machine_mode, rtx);
 extern void ix86_free_from_memory (enum machine_mode);
--- gcc/config/iq2000/iq2000-protos.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/iq2000/iq2000-protos.h	2007-11-15 22:47:41.000000000 +0100
@@ -48,7 +48,6 @@ extern void             gen_conditional_
 extern void             init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx);
 extern void             function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
 extern struct rtx_def * function_arg (CUMULATIVE_ARGS *, enum machine_mode, const_tree, int);
-extern void             iq2000_va_start (tree, rtx);
 extern rtx              iq2000_function_value (const_tree, const_tree);
 #endif
 
--- gcc/config/iq2000/iq2000.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/iq2000/iq2000.h	2007-11-15 22:47:41.000000000 +0100
@@ -476,12 +476,6 @@ typedef struct iq2000_args
 }
 
 
-/* Implementing the Varargs Macros.  */
-
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  iq2000_va_start (valist, nextarg)
-
-
 /* Trampolines for Nested Functions.  */
 
 /* A C statement to output, on the stream FILE, assembler code for a
--- gcc/config/iq2000/iq2000.c.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/iq2000/iq2000.c	2007-11-15 22:47:41.000000000 +0100
@@ -168,6 +168,7 @@ static bool iq2000_pass_by_reference  (C
 				       const_tree, bool);
 static int  iq2000_arg_partial_bytes  (CUMULATIVE_ARGS *, enum machine_mode,
 				       tree, bool);
+static void iq2000_va_start	      (tree, rtx);
 
 #undef  TARGET_INIT_BUILTINS
 #define TARGET_INIT_BUILTINS 		iq2000_init_builtins
@@ -210,6 +211,9 @@ static int  iq2000_arg_partial_bytes  (C
 #undef  TARGET_STRICT_ARGUMENT_NAMING
 #define TARGET_STRICT_ARGUMENT_NAMING	hook_bool_CUMULATIVE_ARGS_true
 
+#undef	TARGET_EXPAND_BUILTIN_VA_START
+#define	TARGET_EXPAND_BUILTIN_VA_START	iq2000_va_start
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Return nonzero if we split the address into high and low parts.  */
@@ -1357,7 +1361,7 @@ iq2000_arg_partial_bytes (CUMULATIVE_ARG
 
 /* Implement va_start.  */
 
-void
+static void
 iq2000_va_start (tree valist, rtx nextarg)
 {
   int int_arg_words;
--- gcc/config/rs6000/rs6000-protos.h.jj	2007-11-15 20:00:37.000000000 +0100
+++ gcc/config/rs6000/rs6000-protos.h	2007-11-15 22:47:41.000000000 +0100
@@ -28,7 +28,6 @@
 
 #ifdef TREE_CODE
 extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, int, int, int);
-extern void rs6000_va_start (tree, rtx);
 #endif /* TREE_CODE */
 
 extern bool easy_altivec_constant (rtx, enum machine_mode);
--- gcc/config/rs6000/rs6000.c.jj	2007-11-15 20:00:37.000000000 +0100
+++ gcc/config/rs6000/rs6000.c	2007-11-15 22:47:41.000000000 +0100
@@ -899,6 +899,7 @@ static void rs6000_darwin_file_start (vo
 #endif
 
 static tree rs6000_build_builtin_va_list (void);
+static void rs6000_va_start (tree, rtx);
 static tree rs6000_gimplify_va_arg (tree, tree, tree *, tree *);
 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
@@ -1159,6 +1160,9 @@ static const char alt_reg_names[][8] =
 #undef TARGET_BUILD_BUILTIN_VA_LIST
 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
 
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
+
 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
 
@@ -1842,6 +1846,11 @@ rs6000_override_options (const char *def
     set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
   if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
     set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
+
+  /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
+     can be optimized to ap = __builtin_next_arg (0).  */
+  if (DEFAULT_ABI != ABI_V4)
+    targetm.expand_builtin_va_start = NULL;
 }
 
 /* Implement targetm.vectorize.builtin_mask_for_load.  */
@@ -6482,7 +6491,7 @@ rs6000_build_builtin_va_list (void)
 
 /* Implement va_start.  */
 
-void
+static void
 rs6000_va_start (tree valist, rtx nextarg)
 {
   HOST_WIDE_INT words, n_gpr, n_fpr;
--- gcc/config/rs6000/rs6000.h.jj	2007-11-15 20:00:37.000000000 +0100
+++ gcc/config/rs6000/rs6000.h	2007-11-15 22:47:41.000000000 +0100
@@ -1493,10 +1493,6 @@ typedef struct rs6000_args
 #define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
   function_arg_boundary (MODE, TYPE)
 
-/* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  rs6000_va_start (valist, nextarg)
-
 #define PAD_VARARGS_DOWN \
    (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
 
--- gcc/config/spu/spu.c.jj	2007-11-15 20:00:40.000000000 +0100
+++ gcc/config/spu/spu.c	2007-11-15 22:47:41.000000000 +0100
@@ -117,6 +117,7 @@ static int spu_naked_function_p (tree fu
 static unsigned char spu_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode,
 					    const_tree type, unsigned char named);
 static tree spu_build_builtin_va_list (void);
+static void spu_va_start (tree, rtx);
 static tree spu_gimplify_va_arg_expr (tree valist, tree type, tree * pre_p,
 				      tree * post_p);
 static int regno_aligned_for_load (int regno);
@@ -247,6 +248,9 @@ const struct attribute_spec spu_attribut
 #undef TARGET_BUILD_BUILTIN_VA_LIST
 #define TARGET_BUILD_BUILTIN_VA_LIST spu_build_builtin_va_list
 
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START spu_va_start
+
 #undef TARGET_SETUP_INCOMING_VARARGS
 #define TARGET_SETUP_INCOMING_VARARGS spu_setup_incoming_varargs
 
@@ -3214,7 +3218,7 @@ spu_build_builtin_va_list (void)
        holds the offset of the first anonymous stack argument
        (relative to the virtual arg pointer).  */
 
-void
+static void
 spu_va_start (tree valist, rtx nextarg)
 {
   tree f_args, f_skip;
--- gcc/config/spu/spu.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/spu/spu.h	2007-11-15 22:47:41.000000000 +0100
@@ -380,11 +380,6 @@ targetm.resolve_overloaded_builtin = spu
 #define PAD_VARARGS_DOWN 0
 
 #define FUNCTION_ARG_REGNO_P(N) ((N) >= (FIRST_ARG_REGNUM) && (N) <= (LAST_ARG_REGNUM))
-
-/* Undocumented */
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  spu_va_start (valist, nextarg)
-
 
 /* Scalar Return */
 
--- gcc/config/spu/spu-protos.h.jj	2007-11-15 20:00:40.000000000 +0100
+++ gcc/config/spu/spu-protos.h	2007-11-15 22:47:41.000000000 +0100
@@ -61,7 +61,6 @@ extern int spu_initial_elimination_offse
 extern rtx spu_function_value (const_tree type, const_tree func);
 extern rtx spu_function_arg (int cum, enum machine_mode mode, tree type,
 			     int named);
-extern void spu_va_start (tree valist, rtx nextarg);
 extern void spu_setup_incoming_varargs (int *cum, enum machine_mode mode,
 					tree type, int *pretend_size,
 					int no_rtl);
--- gcc/config/stormy16/stormy16.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/stormy16/stormy16.h	2007-11-15 22:47:41.000000000 +0100
@@ -461,16 +461,6 @@ enum reg_class
    contains a '%s' sequence, this will be replaced by the name of the function.  */
 /* #define TARGET_CANNOT_INLINE_P(FN_DECL) xstormy16_cannot_inline_p (FN_DECL) */
 
-/* Implementing the Varargs Macros.  */
-
-/* Implement the stdarg/varargs va_start macro.  STDARG_P is nonzero if this
-   is stdarg.h instead of varargs.h.  VALIST is the tree of the va_list
-   variable to initialize.  NEXTARG is the machine independent notion of the
-   'next' argument after the variable arguments.  If not defined, a standard
-   implementation will be defined that works for arguments passed on the stack.  */
-#define EXPAND_BUILTIN_VA_START(VALIST, NEXTARG) \
-  xstormy16_expand_builtin_va_start (VALIST, NEXTARG)
-
 /* Trampolines for Nested Functions.  */
 
 #define TRAMPOLINE_SIZE 8
--- gcc/config/stormy16/stormy16-protos.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/stormy16/stormy16-protos.h	2007-11-15 22:47:41.000000000 +0100
@@ -42,7 +42,6 @@ extern rtx xstormy16_function_arg
 #endif
 
 #if defined (TREE_CODE) && defined (RTX_CODE)
-extern void xstormy16_expand_builtin_va_start (tree, rtx);
 extern void xstormy16_initialize_trampoline (rtx, rtx, rtx);
 extern rtx xstormy16_function_value (const_tree, const_tree);
 #endif
--- gcc/config/stormy16/stormy16.c.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/stormy16/stormy16.c	2007-11-15 22:47:41.000000000 +0100
@@ -1352,7 +1352,7 @@ xstormy16_build_builtin_va_list (void)
    is stdarg.h instead of varargs.h.  VALIST is the tree of the va_list
    variable to initialize.  NEXTARG is the machine independent notion of the
    'next' argument after the variable arguments.  */
-void
+static void
 xstormy16_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
 {
   tree f_base, f_count;
@@ -2666,6 +2666,8 @@ xstormy16_return_in_memory (const_tree t
 
 #undef TARGET_BUILD_BUILTIN_VA_LIST
 #define TARGET_BUILD_BUILTIN_VA_LIST xstormy16_build_builtin_va_list
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START xstormy16_expand_builtin_va_start
 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR xstormy16_expand_builtin_va_arg
 
--- gcc/config/s390/s390-protos.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/s390/s390-protos.h	2007-11-15 22:47:41.000000000 +0100
@@ -122,6 +122,5 @@ extern void s390_function_arg_advance (C
 #ifdef RTX_CODE
 extern rtx s390_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
 extern rtx s390_function_value (const_tree, enum machine_mode);
-extern void s390_va_start (tree, rtx);
 #endif /* RTX_CODE */
 #endif /* TREE_CODE */
--- gcc/config/s390/s390.c.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/s390/s390.c	2007-11-15 22:47:41.000000000 +0100
@@ -7961,7 +7961,7 @@ s390_build_builtin_va_list (void)
        holds the offset of the first anonymous stack argument
        (relative to the virtual arg pointer).  */
 
-void
+static void
 s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
 {
   HOST_WIDE_INT n_gpr, n_fpr;
@@ -9314,6 +9314,8 @@ s390_reorg (void)
 
 #undef TARGET_BUILD_BUILTIN_VA_LIST
 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START s390_va_start
 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
 
--- gcc/config/s390/s390.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/s390/s390.h	2007-11-15 22:47:41.000000000 +0100
@@ -661,11 +661,6 @@ CUMULATIVE_ARGS;
 #define PROFILE_BEFORE_PROLOGUE 1
 
 
-/* Implementing the varargs macros.  */
-
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  s390_va_start (valist, nextarg)
-
 /* Trampolines for nested functions.  */
 
 #define TRAMPOLINE_SIZE (TARGET_64BIT ? 32 : 16)
--- gcc/config/mn10300/mn10300.h.jj	2007-11-15 20:00:37.000000000 +0100
+++ gcc/config/mn10300/mn10300.h	2007-11-15 22:47:41.000000000 +0100
@@ -624,10 +624,6 @@ struct cum_arg {int nbytes; };
   ((COUNT == 0)                         \
    ? gen_rtx_MEM (Pmode, arg_pointer_rtx) \
    : (rtx) 0)
-
-/* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  mn10300_va_start (valist, nextarg)
 
 /* 1 if X is an rtx for a constant that is a valid address.  */
 
--- gcc/config/mn10300/mn10300-protos.h.jj	2007-11-15 20:00:37.000000000 +0100
+++ gcc/config/mn10300/mn10300-protos.h	2007-11-15 22:47:41.000000000 +0100
@@ -20,10 +20,6 @@ along with GCC; see the file COPYING3.  
 
 #ifdef RTX_CODE
 
-#ifdef TREE_CODE
-extern void mn10300_va_start (tree, rtx);
-#endif /* TREE_CODE */
-
 extern void mn10300_override_options (void);
 extern struct rtx_def *legitimize_address (rtx, rtx, enum machine_mode);
 extern rtx legitimize_pic_address (rtx, rtx);
--- gcc/config/mn10300/mn10300.c.jj	2007-11-15 20:00:37.000000000 +0100
+++ gcc/config/mn10300/mn10300.c	2007-11-15 22:47:41.000000000 +0100
@@ -74,6 +74,7 @@ static bool mn10300_rtx_costs (rtx, int,
 static void mn10300_file_start (void);
 static bool mn10300_return_in_memory (const_tree, const_tree);
 static rtx mn10300_builtin_saveregs (void);
+static void mn10300_va_start (tree, rtx);
 static bool mn10300_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
 				       const_tree, bool);
 static int mn10300_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
@@ -114,6 +115,8 @@ static int mn10300_arg_partial_bytes (CU
 
 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
 #define TARGET_EXPAND_BUILTIN_SAVEREGS mn10300_builtin_saveregs
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START mn10300_va_start
 
 static void mn10300_encode_section_info (tree, rtx, int);
 struct gcc_target targetm = TARGET_INITIALIZER;
@@ -1471,7 +1474,7 @@ mn10300_builtin_saveregs (void)
 				    offset, 0, 0, OPTAB_LIB_WIDEN));
 }
 
-void
+static void
 mn10300_va_start (tree valist, rtx nextarg)
 {
   nextarg = expand_builtin_saveregs ();
--- gcc/config/arc/arc.c.jj	2007-11-15 20:00:37.000000000 +0100
+++ gcc/config/arc/arc.c	2007-11-15 22:47:41.000000000 +0100
@@ -89,6 +89,7 @@ static void arc_output_function_prologue
 static void arc_output_function_epilogue (FILE *, HOST_WIDE_INT);
 static void arc_file_start (void);
 static void arc_internal_label (FILE *, const char *, unsigned long);
+static void arc_va_start (tree, rtx);
 static void arc_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
 					tree, int *, int);
 static bool arc_rtx_costs (rtx, int, int, int *);
@@ -144,6 +145,9 @@ static bool arc_pass_by_reference (CUMUL
 #undef TARGET_SETUP_INCOMING_VARARGS
 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
 
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START arc_va_start
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Implement TARGET_HANDLE_OPTION.  */
@@ -2274,7 +2278,7 @@ arc_ccfsm_record_branch_deleted (void)
   current_insn_set_cc_p = last_insn_set_cc_p;
 }
 
-void
+static void
 arc_va_start (tree valist, rtx nextarg)
 {
   /* See arc_setup_incoming_varargs for reasons for this oddity.  */
--- gcc/config/arc/arc.h.jj	2007-11-15 20:00:37.000000000 +0100
+++ gcc/config/arc/arc.h	2007-11-15 22:47:41.000000000 +0100
@@ -1086,8 +1086,3 @@ enum arc_function_type {
 #define ARC_INTERRUPT_P(TYPE) \
 ((TYPE) == ARC_FUNCTION_ILINK1 || (TYPE) == ARC_FUNCTION_ILINK2)
 /* Compute the type of a function from its DECL.  */
-
-
-/* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  arc_va_start (valist, nextarg)
--- gcc/config/arc/arc-protos.h.jj	2007-11-15 20:00:37.000000000 +0100
+++ gcc/config/arc/arc-protos.h	2007-11-15 22:47:41.000000000 +0100
@@ -17,8 +17,6 @@ You should have received a copy of the G
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-extern void arc_va_start (tree, rtx);
-
 #ifdef RTX_CODE
 extern enum machine_mode arc_select_cc_mode (enum rtx_code, rtx, rtx);
 
--- gcc/config/mt/mt-protos.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/mt/mt-protos.h	2007-11-15 22:47:41.000000000 +0100
@@ -58,7 +58,6 @@ extern void	    mt_final_prescan_insn (r
 #ifdef RTX_CODE
 extern void         mt_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
 extern rtx          mt_function_arg	 (const CUMULATIVE_ARGS *, enum machine_mode, tree, int, int);
-extern void	    mt_va_start	 (tree, rtx);
 extern enum reg_class mt_secondary_reload_class (enum reg_class, enum machine_mode, rtx);
 extern rtx	    mt_function_value	 (const_tree, enum machine_mode, const_tree);
 #endif
--- gcc/config/sparc/sparc.c.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/sparc/sparc.c	2007-11-15 22:47:42.000000000 +0100
@@ -409,6 +409,7 @@ static bool sparc_promote_prototypes (co
 static rtx sparc_struct_value_rtx (tree, int);
 static bool sparc_return_in_memory (const_tree, const_tree);
 static bool sparc_strict_argument_naming (CUMULATIVE_ARGS *);
+static void sparc_va_start (tree, rtx);
 static tree sparc_gimplify_va_arg (tree, tree, tree *, tree *);
 static bool sparc_vector_mode_supported_p (enum machine_mode);
 static bool sparc_pass_by_reference (CUMULATIVE_ARGS *,
@@ -545,6 +546,8 @@ static bool fpu_option_set = false;
 #undef TARGET_STRICT_ARGUMENT_NAMING
 #define TARGET_STRICT_ARGUMENT_NAMING sparc_strict_argument_naming
 
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START sparc_va_start
 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR sparc_gimplify_va_arg
 
@@ -5696,7 +5699,7 @@ sparc_builtin_saveregs (void)
 
 /* Implement `va_start' for stdarg.  */
 
-void
+static void
 sparc_va_start (tree valist, rtx nextarg)
 {
   nextarg = expand_builtin_saveregs ();
--- gcc/config/sparc/sparc-protos.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/sparc/sparc-protos.h	2007-11-15 22:47:42.000000000 +0100
@@ -31,7 +31,6 @@ extern struct rtx_def *function_arg (con
 				     enum machine_mode, tree, int, int);
 #ifdef RTX_CODE
 extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
-extern void sparc_va_start (tree, rtx);
 #endif
 extern unsigned long sparc_type_code (tree);
 #ifdef ARGS_SIZE_RTX
--- gcc/config/sparc/sparc.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/sparc/sparc.h	2007-11-15 22:47:42.000000000 +0100
@@ -1700,10 +1700,6 @@ do {									\
     else							\
       sparc_initialize_trampoline (TRAMP, FNADDR, CXT)
 
-/* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  sparc_va_start (valist, nextarg)
-
 /* Generate RTL to flush the register windows so as to make arbitrary frames
    available.  */
 #define SETUP_FRAME_ADDRESSES()		\
--- gcc/config/sh/sh.c.jj	2007-11-15 20:00:40.000000000 +0100
+++ gcc/config/sh/sh.c	2007-11-15 22:47:42.000000000 +0100
@@ -248,6 +248,7 @@ static void sh_setup_incoming_varargs (C
 static bool sh_strict_argument_naming (CUMULATIVE_ARGS *);
 static bool sh_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *);
 static tree sh_build_builtin_va_list (void);
+static void sh_va_start (tree, rtx);
 static tree sh_gimplify_va_arg_expr (tree, tree, tree *, tree *);
 static bool sh_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
 				  const_tree, bool);
@@ -425,6 +426,8 @@ static int sh_dwarf_calling_convention (
 
 #undef TARGET_BUILD_BUILTIN_VA_LIST
 #define TARGET_BUILD_BUILTIN_VA_LIST sh_build_builtin_va_list
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START sh_va_start
 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR sh_gimplify_va_arg_expr
 
@@ -7035,7 +7038,7 @@ sh_build_builtin_va_list (void)
 
 /* Implement `va_start' for varargs and stdarg.  */
 
-void
+static void
 sh_va_start (tree valist, rtx nextarg)
 {
   tree f_next_o, f_next_o_limit, f_next_fp, f_next_fp_limit, f_next_stack;
--- gcc/config/sh/sh-protos.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/sh/sh-protos.h	2007-11-15 22:47:42.000000000 +0100
@@ -120,9 +120,6 @@ extern void sh_expand_binop_v2sf (enum r
 extern int sh_expand_t_scc (enum rtx_code code, rtx target);
 extern rtx sh_gen_truncate (enum machine_mode, rtx, int);
 extern bool sh_vector_mode_supported_p (enum machine_mode);
-#ifdef TREE_CODE
-extern void sh_va_start (tree, rtx);
-#endif /* TREE_CODE */
 #endif /* RTX_CODE */
 
 extern const char *output_jump_label_table (void);
--- gcc/config/sh/sh.h.jj	2007-11-15 20:00:36.000000000 +0100
+++ gcc/config/sh/sh.h	2007-11-15 22:47:42.000000000 +0100
@@ -2076,10 +2076,6 @@ struct sh_args {
 /* Perform any needed actions needed for a function that is receiving a
    variable number of arguments.  */
 
-/* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  sh_va_start (valist, nextarg)
-
 /* Call the function profiler with a given profile label.
    We use two .aligns, so as to make sure that both the .long is aligned
    on a 4 byte boundary, and that the .long is a fixed distance (2 bytes)
--- gcc/config/mips/mips-protos.h.jj	2007-11-15 20:00:37.000000000 +0100
+++ gcc/config/mips/mips-protos.h	2007-11-15 22:47:42.000000000 +0100
@@ -223,7 +223,6 @@ extern rtx mips_function_arg (const CUMU
 extern int mips_function_arg_boundary (enum machine_mode, tree);
 extern bool mips_pad_arg_upward (enum machine_mode, const_tree);
 extern bool mips_pad_reg_upward (enum machine_mode, tree);
-extern void mips_va_start (tree, rtx);
 
 extern bool mips_expand_ext_as_unaligned_load (rtx, rtx, HOST_WIDE_INT,
 					       HOST_WIDE_INT);
--- gcc/config/mips/mips.h.jj	2007-11-15 20:00:37.000000000 +0100
+++ gcc/config/mips/mips.h	2007-11-15 22:47:42.000000000 +0100
@@ -2098,9 +2098,6 @@ typedef struct mips_args {
   (TARGET_NEWABI ? ((LOC) + 15) & -16 : ((LOC) + 7) & -8)
 
 
-/* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START mips_va_start
-
 /* Output assembler code to FILE to increment profiler label # LABELNO
    for profiling a function entry.  */
 
--- gcc/config/mips/mips.c.jj	2007-11-15 20:00:37.000000000 +0100
+++ gcc/config/mips/mips.c	2007-11-15 22:47:42.000000000 +0100
@@ -4735,9 +4735,9 @@ mips_build_builtin_va_list (void)
     return ptr_type_node;
 }
 
-/* Implement EXPAND_BUILTIN_VA_START.  */
+/* Implement TARGET_EXPAND_BUILTIN_VA_START.  */
 
-void
+static void
 mips_va_start (tree valist, rtx nextarg)
 {
   if (EABI_FLOAT_VARARGS_P)
@@ -12443,6 +12443,8 @@ mips_order_regs_for_local_alloc (void)
 
 #undef TARGET_BUILD_BUILTIN_VA_LIST
 #define TARGET_BUILD_BUILTIN_VA_LIST mips_build_builtin_va_list
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START mips_va_start
 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR mips_gimplify_va_arg_expr
 

	Jakub


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