re PR middle-end/20983 (varargs functions force va_list variable to stack unnecessarily)
authorJakub Jelinek <jakub@redhat.com>
Thu, 6 Dec 2007 13:25:37 +0000 (14:25 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 6 Dec 2007 13:25:37 +0000 (14:25 +0100)
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.

From-SVN: r130650

52 files changed:
gcc/ChangeLog
gcc/builtins.c
gcc/config/alpha/alpha-protos.h
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/alpha/unicosmk.h
gcc/config/arc/arc-protos.h
gcc/config/arc/arc.c
gcc/config/arc/arc.h
gcc/config/frv/frv-protos.h
gcc/config/frv/frv.c
gcc/config/frv/frv.h
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/iq2000/iq2000-protos.h
gcc/config/iq2000/iq2000.c
gcc/config/iq2000/iq2000.h
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mn10300/mn10300-protos.h
gcc/config/mn10300/mn10300.c
gcc/config/mn10300/mn10300.h
gcc/config/mt/mt-protos.h
gcc/config/pa/pa-protos.h
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/config/sh/sh-protos.h
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/config/spu/spu-protos.h
gcc/config/spu/spu.c
gcc/config/spu/spu.h
gcc/config/stormy16/stormy16-protos.h
gcc/config/stormy16/stormy16.c
gcc/config/stormy16/stormy16.h
gcc/config/xtensa/xtensa-protos.h
gcc/config/xtensa/xtensa.c
gcc/config/xtensa/xtensa.h
gcc/target-def.h
gcc/target.h
gcc/tree-ssa-ccp.c

index f28d0190c35e498f840b360965c2dd01187a8305..a38894e44e01e8a33c78ada70987c8ab2b3333b8 100644 (file)
@@ -1,3 +1,88 @@
+2007-12-06  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.
+
 2007-12-05  Uros Bizjak  <ubizjak@gmail.com>
 
        * tree-ssa-loop.c (gate_tree_parallelize_loops): Return true when
index 630cd2506ecb6f6a3ad8e27ce0c030f7d1b6b29a..1c140508a5336ea5bb21d0e117af9d78636fb400 100644 (file)
@@ -4716,11 +4716,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;
 }
index df2ae6814d2b1c689db38e7639cc412684cdebdc..bbbcd8f4f1aa39141f83b40e46e66daffd966355 100644 (file)
@@ -75,7 +75,6 @@ extern void print_operand (FILE *, rtx, int);
 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);
index fee5cd11115f89cfc407b0dcaa4cdc3c4e3a9412..800b354a71d24dc2401dfed8a699e58800f599c5 100644 (file)
@@ -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;
 }
 \f
 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones.  */
@@ -6069,7 +6074,7 @@ alpha_setup_incoming_varargs (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
 #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.  */
index 2b048841063584ee193ca38f7340272bdfa584d8..b0019bf22cf904f6ee8b881df02127ad7082f307 100644 (file)
@@ -1335,10 +1335,6 @@ do {                                             \
 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
   print_operand_address((FILE), (ADDR))
 \f
-/* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  alpha_va_start (valist, nextarg)
-\f
 /* Tell collect that the object format is ECOFF.  */
 #define OBJECT_FORMAT_COFF
 #define EXTENDED_COFF
index 0721c19cdb624673c085267aba17c3c8200ab9b9..d08fa73bc281c800086367e85d78854eeacd2bdb 100644 (file)
@@ -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
index 9eadf354b21d1b07589e29c11173f0996117dfc6..c9fc51ad2ac5570b1c91c78a817bd41f58f8e5f6 100644 (file)
@@ -17,8 +17,6 @@ You should have received a copy of the GNU General Public License
 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);
 
index a1e04af8c8f89b909ec72836cca6b6146c643f2b..5b2e7b804f4c77697f3fa0da2504bbc135e6b3b2 100644 (file)
@@ -89,6 +89,7 @@ static void arc_output_function_prologue (FILE *, HOST_WIDE_INT);
 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 (CUMULATIVE_ARGS *, enum machine_mode,
 #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;
 \f
 /* Implement TARGET_HANDLE_OPTION.  */
@@ -2274,7 +2278,7 @@ arc_ccfsm_record_branch_deleted (void)
   current_insn_set_cc_p = last_insn_set_cc_p;
 }
 \f
-void
+static void
 arc_va_start (tree valist, rtx nextarg)
 {
   /* See arc_setup_incoming_varargs for reasons for this oddity.  */
index 05f4aad9dba9dcc5db92c8c6bdce6a1340eb8ea1..17412fc18d8c145043221042e164d0b4fc03c8f9 100644 (file)
@@ -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.  */
-
-\f
-/* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  arc_va_start (valist, nextarg)
index 89f2f1e33533e734cf9eb35ec0f191927915f1c8..dd41fc27767addd1c89c14cd1347e8f0b71db822 100644 (file)
@@ -64,8 +64,6 @@ extern rtx frv_function_arg                   (CUMULATIVE_ARGS *,
 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 *);
index 9c31b8bb5007774227cd8916815782953073d27b..150e25d568b6d727a1375003dabf271937249b8c 100644 (file)
@@ -365,6 +365,7 @@ static void frv_setup_incoming_varargs              (CUMULATIVE_ARGS *,
                                                 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         (FILE *, int, rtx)
 #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)
 \f
 /* Expand __builtin_va_start to do the va_start macro.  */
 
-void
+static void
 frv_expand_builtin_va_start (tree valist, rtx nextarg)
 {
   tree t;
index ba00ee44b23634f4098cb3a7a1b66cfc5238f49e..feb88d56946fd69640e5a4a47e735a7c482dd83d 100644 (file)
@@ -1847,19 +1847,6 @@ typedef struct frv_stack {
 
 #define FUNCTION_PROFILER(FILE, LABELNO)
 
-\f
-/* 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))
-
-\f
 /* Trampolines for Nested Functions.  */
 
 /* A C expression for the size in bytes of the trampoline, as an integer.  */
index bb40af936e4fe4aae724367d1ce4c79ec745eb2a..8dd203ebee60a4f366830f6ebfdc572f4448fc44 100644 (file)
@@ -137,8 +137,6 @@ extern bool ix86_function_arg_regno_p (int);
 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);
index cac5dbeb1b01188eedf6ccd9d0940ef7bf77f303..095ba1727d7b9befdab02195742479d1de8a36dd 100644 (file)
@@ -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;
 }
 \f
 /* Return true if this goes in large data/bss.  */
@@ -5041,7 +5046,7 @@ ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
 
 /* Implement va_start.  */
 
-void
+static void
 ix86_va_start (tree valist, rtx nextarg)
 {
   HOST_WIDE_INT words, n_gpr, n_fpr;
@@ -25253,6 +25258,9 @@ x86_builtin_vectorization_cost (bool runtime_test)
 #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
 
index 3a36149a471ad9db64ca016311e3887966276a09..6e0b96a0b65bab8febd4ad281e4696e4c5d4f42b 100644 (file)
@@ -1710,10 +1710,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
 
index 9b6837ef9753ba32c9052a370506480732678a35..094bcbf2f12000df1ea37d3fa2a608a5b83be8b9 100644 (file)
@@ -48,7 +48,6 @@ extern void             gen_conditional_branch (rtx *, enum rtx_code);
 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
 
index 782aa72cbb1ba9e06f364fff0444a6b52019c2de..7a31b4782bbfbdeca194dfcdb4cf2ef64e5e5112 100644 (file)
@@ -168,6 +168,7 @@ static bool iq2000_pass_by_reference  (CUMULATIVE_ARGS *, enum machine_mode,
                                       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  (CUMULATIVE_ARGS *, enum machine_mode,
 #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;
 \f
 /* Return nonzero if we split the address into high and low parts.  */
@@ -1357,7 +1361,7 @@ iq2000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
 \f
 /* Implement va_start.  */
 
-void
+static void
 iq2000_va_start (tree valist, rtx nextarg)
 {
   int int_arg_words;
index dcf7ab62f06f0059e2703d260b0c52de972b3649..f7beb540bedaf49209f9db869d765926bde8f7af 100644 (file)
@@ -475,12 +475,6 @@ typedef struct iq2000_args
   fprintf (FILE, "\t.set\tat\n");                                      \
 }
 
-\f
-/* Implementing the Varargs Macros.  */
-
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  iq2000_va_start (valist, nextarg)
-
 \f
 /* Trampolines for Nested Functions.  */
 
index ed7a7890faf77784c8f4f68684d8d675e5dacc76..064d56849085c46c0f3a1d1f9ca23d15c1d1dce4 100644 (file)
@@ -223,7 +223,6 @@ extern rtx mips_function_arg (const CUMULATIVE_ARGS *,
 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);
index 918f23758125b7e938650fc5eeaded4082c6ea52..42e15a0320cf53e8e9215918191aa2bc70396db3 100644 (file)
@@ -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)
@@ -12445,6 +12445,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
 
index b4778a8577d66789293f34ee939a659b041e407e..c3713e018b9585fa69961ebc9a0ac6bc085f8996 100644 (file)
@@ -2097,9 +2097,6 @@ typedef struct mips_args {
 #define MIPS_STACK_ALIGN(LOC) \
   (TARGET_NEWABI ? ((LOC) + 15) & -16 : ((LOC) + 7) & -8)
 
-\f
-/* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START mips_va_start
 \f
 /* Output assembler code to FILE to increment profiler label # LABELNO
    for profiling a function entry.  */
index 633988b73d7f15dea223beaeab78f4139ee5d480..d8fe2bd50a11a0eae52abaf4a22e3e8dda5e3e06 100644 (file)
@@ -20,10 +20,6 @@ along with GCC; see the file COPYING3.  If not see
 
 #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);
index 0fb57cc1bd1aa607f23db21b4ff2b8822d501b37..9fde69986e75b487d7392be6314058a4d04fd568 100644 (file)
@@ -74,6 +74,7 @@ static bool mn10300_rtx_costs (rtx, int, int, 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 (CUMULATIVE_ARGS *, enum machine_mode,
 
 #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 ();
index 9cb8244c1f63ee9d5b32a47f2bc5ece95c08c96c..824227546f0bc4b6825bfb7a035d57ed010a8984 100644 (file)
@@ -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)
 \f
 /* 1 if X is an rtx for a constant that is a valid address.  */
 
index 5c959edd9ad1584ca20b4e36ff8a09f5b2adfef1..99717dc5eff0a3e82b62cdc8724e7c36dd15409d 100644 (file)
@@ -58,7 +58,6 @@ extern void       mt_final_prescan_insn (rtx, rtx *, int);
 #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
index 9d5c2b9e7f2fe58161d80b849a917d293469e0c9..ff621a30733211f6642aceef3bc692c07246e897 100644 (file)
@@ -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.  */
index 47de208483af05be743320fa6f17a9b69a2c6b2c..58122f62118d4228744837a1b975b5dcd6c1c78c 100644 (file)
@@ -124,6 +124,7 @@ static void pa_asm_out_destructor (rtx, int);
 #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 ();
index 56e4e131f9acadcea5bc55045464eabf3b169729..8a7fb63eaca1b66a03986c28a1f324770b53f71d 100644 (file)
@@ -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)
 \f
 /* Addressing modes, and classification of registers for them. 
 
index 56bb376a77d4bb3459b86cc22b10e1ca40791b0f..4c031e7de63dda4fe2c2ca57ae0c23e66db6515b 100644 (file)
@@ -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);
index 3367e0848da2ce03e429d0fa65bd14bf7ba67bf0..a2baf46107f52f044213cd97f725b06fcbaa2356 100644 (file)
@@ -899,6 +899,7 @@ static void rs6000_darwin_file_start (void);
 #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 *default_cpu)
     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.  */
@@ -6495,7 +6504,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;
index 7fb2002be5c494df62f4c26ef85380bec85edcea..3693f53cc54d9af87bc70a71697671c2ec4560f7 100644 (file)
@@ -1498,10 +1498,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)
 
index bfefb0daa33aa5a06622234dcd63eff9f5af1dee..7e329f2a5656a31d965ced7daafb00e0bd3498b0 100644 (file)
@@ -122,6 +122,5 @@ extern void s390_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
 #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 */
index c1c4668308185c03fd9919c4e6f58f38e775ddbb..f7d80dbc01c231e4e8483273548d0e613881164c 100644 (file)
@@ -7978,7 +7978,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;
@@ -9331,6 +9331,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
 
index bd2102b4cef2a449e577c2ac5707f1ac1eb4a188..35cc9477b8c394d35d25c8f032e348bcbcd853f7 100644 (file)
@@ -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)
index e236a0ecd1ade27ff1381783e51c7cf84609134a..25d9ce4339215d68c74a5cf835f3a0e96037ff03 100644 (file)
@@ -120,9 +120,6 @@ extern void sh_expand_binop_v2sf (enum rtx_code, rtx, rtx, rtx);
 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);
index 8d82fa2b2a218f334dd8455604b2a69e86634d72..4088ef73cdfb775ab93c80de1007e3d52ceb470f 100644 (file)
@@ -248,6 +248,7 @@ static void sh_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tre
 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 (const_tree);
 
 #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;
index d5329d9c6e1200f7511954601581850a186ec7e7..844ea23c633f987b84155c5b46f00c481707700b 100644 (file)
@@ -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)
index 217948af08d885fa2300db725ab7ab3826499b5d..7c56925c01d05b626b3652dd85972040fa72bdf3 100644 (file)
@@ -31,7 +31,6 @@ extern struct rtx_def *function_arg (const CUMULATIVE_ARGS *,
                                     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
index ca3463060a3d1c0050a47ef9aecd4531b0abcd7c..c54dbb325ac562cc064793f3f43783375f343144 100644 (file)
@@ -409,6 +409,7 @@ static bool sparc_promote_prototypes (const_tree);
 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 ();
index 0ff70f6395d6a05ef816be85cdd347c9a7dac9d6..53983d46421e11b81f0a6776f7183c607f5df79b 100644 (file)
@@ -1700,10 +1700,6 @@ do {                                                                     \
     else                                                       \
       sparc_initialize_trampoline (TRAMP, FNADDR, CXT)
 \f
-/* 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()                \
index ab85d5debb3d72a72d7c03199e6da1dfecfd2861..e2c339bf1c5bffdb4b98d4ec3635f044c565e69d 100644 (file)
@@ -61,7 +61,6 @@ extern int spu_initial_elimination_offset (int from, int to);
 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);
index 79693b829d6173bfb81c3568858c8e56ba88362e..4592e667f08b1b2dd5e218a56bdfa6f371228232 100644 (file)
@@ -117,6 +117,7 @@ static int spu_naked_function_p (tree func);
 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_attribute_table[];
 #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;
index 74b06a77bfc7c3896bd950445fdf18df09d54cca..3d038cab46e4726d180b9a3c7a14bceaec16b2a7 100644 (file)
@@ -380,11 +380,6 @@ targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin;       \
 #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)
-
 \f
 /* Scalar Return */
 
index c3c1c7aeec5d283783fbd2e46a3f1906be96d57f..1110720223e399e9c2d3c5f228881c531eb8fce2 100644 (file)
@@ -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
index b41440e6d4eadaa3df41d275d66e7bb17eead7c0..2f738e5a0bb9f98394e98f93be5e1d61662cfb39 100644 (file)
@@ -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 type, const_tree fntype ATTRIBUTE_UNUSED)
 
 #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
 
index bd218a6ed04699fa911a93bf7cd93949250d9e5f..a75a776192c1225ce698efb1931b845746428082 100644 (file)
@@ -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) */
 \f
-/* 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)
-\f
 /* Trampolines for Nested Functions.  */
 
 #define TRAMPOLINE_SIZE 8
index 2f35ca097d0db6af971415b53f425d19dce69084..5ea777ca232856db96cb97c2844d1f83dd34e278 100644 (file)
@@ -58,7 +58,6 @@ extern rtx xtensa_legitimize_address (rtx, rtx, enum machine_mode);
 
 #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);
index 76df1d271cb7a6bdbfa8145b50809315311f0b19..c9d9b908429803e827e980f5574a0c4b551466bd 100644 (file)
@@ -179,6 +179,9 @@ static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
 #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;
index 7887345f9f51c338f7cbd3a2940fa89ed6164cee..e2b94e102b262ee0555d7e3de37fe7403e1a96ff 100644 (file)
@@ -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.
 
index c2f7d3f2ff3a40fe0c4f3e219116248205f646c7..e15b5d9cc092057c0fd415d5a5746d01e303f918 100644 (file)
 #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
   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,                          \
index 27f5d5e795588b2195a0408ff5d73809ef560c2c..12b01da362c5a7ed717bc7f5bc806fe0d0e3cd86 100644 (file)
@@ -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);
index 19d82563a81379748dd894869c8aef020a6b370f..15f14c4c6085acd1fd3d3be189d111ddc47f0a99 100644 (file)
@@ -2708,6 +2708,78 @@ optimize_stack_restore (basic_block bb, tree call, block_stmt_iterator i)
   return integer_zero_node;
 }
 \f
+/* 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 ();
+    }
+}
+\f
 /* Convert EXPR into a GIMPLE value suitable for substitution on the
    RHS of an assignment.  Insert the necessary statements before
    iterator *SI_P. 
@@ -2794,6 +2866,16 @@ execute_fold_all_builtins (void)
 
              case BUILT_IN_STACK_RESTORE:
                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 */