* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130650
138bc75d-0d04-0410-961f-
82ee72b054a4
+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
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;
}
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);
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. */
#endif
}
-void
+static void
alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT offset;
#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. */
#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
#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
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);
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 *);
#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. */
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. */
#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)
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 *);
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);
#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
\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;
#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. */
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);
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. */
/* Implement va_start. */
-void
+static void
ix86_va_start (tree valist, rtx nextarg)
{
HOST_WIDE_INT words, n_gpr, n_fpr;
#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
#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
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
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
#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. */
\f
/* Implement va_start. */
-void
+static void
iq2000_va_start (tree valist, rtx nextarg)
{
int int_arg_words;
}
\f
-/* Implementing the Varargs Macros. */
-
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
- iq2000_va_start (valist, nextarg)
-
-\f
/* Trampolines for Nested Functions. */
/* A C statement to output, on the stream FILE, assembler code for a
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);
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)
#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
(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. */
#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);
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,
#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;
offset, 0, 0, OPTAB_LIB_WIDEN));
}
-void
+static void
mn10300_va_start (tree valist, rtx nextarg)
{
nextarg = expand_builtin_saveregs ();
((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. */
#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
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. */
#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);
#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
offset, 0, 0, OPTAB_LIB_WIDEN));
}
-void
+static void
hppa_va_start (tree valist, rtx nextarg)
{
nextarg = expand_builtin_saveregs ();
#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.
#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);
#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);
#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
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. */
/* Implement va_start. */
-void
+static void
rs6000_va_start (tree valist, rtx nextarg)
{
HOST_WIDE_INT words, n_gpr, n_fpr;
#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)
#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 */
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;
#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
#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)
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);
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);
#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
/* 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;
/* 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)
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
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 *,
#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
/* Implement `va_start' for stdarg. */
-void
+static void
sparc_va_start (tree valist, rtx nextarg)
{
nextarg = expand_builtin_saveregs ();
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() \
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);
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);
#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
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;
#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 */
#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
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;
#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
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
#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);
#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
/* 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;
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.
#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, \
/* 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);
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.
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: