diff options
author | Jiong Wang <jiong.wang@arm.com> | 2016-05-27 13:05:34 +0000 |
---|---|---|
committer | Jiong Wang <jiwang@gcc.gnu.org> | 2016-05-27 13:05:34 +0000 |
commit | 88e3bdd195b7cc070eb7525c75b748fb55920b2e (patch) | |
tree | 05ef7d57add6ed3f7dcbb24ba66f62bf55c4720b /gcc | |
parent | 3fd6b9cc8bb19571726203e309e0b2472e6b8e43 (diff) | |
download | gcc-88e3bdd195b7cc070eb7525c75b748fb55920b2e.zip gcc-88e3bdd195b7cc070eb7525c75b748fb55920b2e.tar.gz gcc-88e3bdd195b7cc070eb7525c75b748fb55920b2e.tar.bz2 |
[AArch64] PR target/63596, honor tree-stdarg analysis result to improve VAARG codegen
gcc/
PR target/63596
* config/aarch64/aarch64.c (aarch64_expand_builtin_va_start): Honor
tree-stdarg analysis results.
(aarch64_setup_incoming_varargs): Likewise.
gcc/testsuite/
* gcc.target/aarch64/va_arg_1.c: New testcase.
* gcc.target/aarch64/va_arg_2.c: Likewise.
* gcc.target/aarch64/va_arg_3.c: Likewise.
From-SVN: r236819
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 37 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/va_arg_1.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/va_arg_2.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/va_arg_3.c | 26 |
6 files changed, 92 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4e9498b..55966de 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2016-05-27 Jiong Wang <jiong.wang@arm.com> + PR target/63596 + * config/aarch64/aarch64.c (aarch64_expand_builtin_va_start): Honor + tree-stdarg analysis results. + (aarch64_setup_incoming_varargs): Likewise. + +2016-05-27 Jiong Wang <jiong.wang@arm.com> + * config/aarch64/aarch64.c (aarch64_build_builtin_va_list): Initialize va_list_gpr_counter_field and va_list_fpr_counter_field. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index abb2b7b..2315939 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -9330,7 +9330,7 @@ aarch64_build_builtin_va_list (void) FIELD_DECL, get_identifier ("__vr_offs"), integer_type_node); - /* Tell tree-stdarg pass what's our internal offset fields. + /* Tell tree-stdarg pass about our internal offset fields. NOTE: va_list_gpr/fpr_counter_field are only used for tree comparision purpose to identify whether the code is updating va_list internal offset fields through irregular way. */ @@ -9369,15 +9369,17 @@ aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED) tree f_stack, f_grtop, f_vrtop, f_groff, f_vroff; tree stack, grtop, vrtop, groff, vroff; tree t; - int gr_save_area_size; - int vr_save_area_size; + int gr_save_area_size = cfun->va_list_gpr_size; + int vr_save_area_size = cfun->va_list_fpr_size; int vr_offset; cum = &crtl->args.info; - gr_save_area_size - = (NUM_ARG_REGS - cum->aapcs_ncrn) * UNITS_PER_WORD; - vr_save_area_size - = (NUM_FP_ARG_REGS - cum->aapcs_nvrn) * UNITS_PER_VREG; + if (cfun->va_list_gpr_size) + gr_save_area_size = MIN ((NUM_ARG_REGS - cum->aapcs_ncrn) * UNITS_PER_WORD, + cfun->va_list_gpr_size); + if (cfun->va_list_fpr_size) + vr_save_area_size = MIN ((NUM_FP_ARG_REGS - cum->aapcs_nvrn) + * UNITS_PER_VREG, cfun->va_list_fpr_size); if (!TARGET_FLOAT) { @@ -9711,7 +9713,8 @@ aarch64_setup_incoming_varargs (cumulative_args_t cum_v, machine_mode mode, { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); CUMULATIVE_ARGS local_cum; - int gr_saved, vr_saved; + int gr_saved = cfun->va_list_gpr_size; + int vr_saved = cfun->va_list_fpr_size; /* The caller has advanced CUM up to, but not beyond, the last named argument. Advance a local copy of CUM past the last "real" named @@ -9719,9 +9722,14 @@ aarch64_setup_incoming_varargs (cumulative_args_t cum_v, machine_mode mode, local_cum = *cum; aarch64_function_arg_advance (pack_cumulative_args(&local_cum), mode, type, true); - /* Found out how many registers we need to save. */ - gr_saved = NUM_ARG_REGS - local_cum.aapcs_ncrn; - vr_saved = NUM_FP_ARG_REGS - local_cum.aapcs_nvrn; + /* Found out how many registers we need to save. + Honor tree-stdvar analysis results. */ + if (cfun->va_list_gpr_size) + gr_saved = MIN (NUM_ARG_REGS - local_cum.aapcs_ncrn, + cfun->va_list_gpr_size / UNITS_PER_WORD); + if (cfun->va_list_fpr_size) + vr_saved = MIN (NUM_FP_ARG_REGS - local_cum.aapcs_nvrn, + cfun->va_list_fpr_size / UNITS_PER_VREG); if (!TARGET_FLOAT) { @@ -9749,7 +9757,7 @@ aarch64_setup_incoming_varargs (cumulative_args_t cum_v, machine_mode mode, /* We can't use move_block_from_reg, because it will use the wrong mode, storing D regs only. */ machine_mode mode = TImode; - int off, i; + int off, i, vr_start; /* Set OFF to the offset from virtual_incoming_args_rtx of the first vector register. The VR save area lies below @@ -9758,14 +9766,15 @@ aarch64_setup_incoming_varargs (cumulative_args_t cum_v, machine_mode mode, STACK_BOUNDARY / BITS_PER_UNIT); off -= vr_saved * UNITS_PER_VREG; - for (i = local_cum.aapcs_nvrn; i < NUM_FP_ARG_REGS; ++i) + vr_start = V0_REGNUM + local_cum.aapcs_nvrn; + for (i = 0; i < vr_saved; ++i) { rtx ptr, mem; ptr = plus_constant (Pmode, virtual_incoming_args_rtx, off); mem = gen_frame_mem (mode, ptr); set_mem_alias_set (mem, get_varargs_alias_set ()); - aarch64_emit_move (mem, gen_rtx_REG (mode, V0_REGNUM + i)); + aarch64_emit_move (mem, gen_rtx_REG (mode, vr_start + i)); off += UNITS_PER_VREG; } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dece85f..70b3725 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,12 @@ 2016-05-27 Jiong Wang <jiong.wang@arm.com> + PR target/63596 + * gcc.target/aarch64/va_arg_1.c: New testcase. + * gcc.target/aarch64/va_arg_2.c: Likewise. + * gcc.target/aarch64/va_arg_3.c: Likewise. + +2016-05-27 Jiong Wang <jiong.wang@arm.com> + * gcc.dg/tree-ssa/stdarg-2.c: Enable all testcases for AArch64. * gcc.dg/tree-ssa/stdarg-3.c: Likewise. * gcc.dg/tree-ssa/stdarg-4.c: Likewise. diff --git a/gcc/testsuite/gcc.target/aarch64/va_arg_1.c b/gcc/testsuite/gcc.target/aarch64/va_arg_1.c new file mode 100644 index 0000000..e8e3cda --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/va_arg_1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 --save-temps" } */ + +int +f (int a, ...) +{ + /* { dg-final { scan-assembler-not "str" } } */ + return a; +} + +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/va_arg_2.c b/gcc/testsuite/gcc.target/aarch64/va_arg_2.c new file mode 100644 index 0000000..f5c46cb --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/va_arg_2.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 --save-temps" } */ + +int +foo (char *fmt, ...) +{ + int d; + __builtin_va_list ap; + + __builtin_va_start (ap, fmt); + d = __builtin_va_arg (ap, int); + __builtin_va_end (ap); + + /* { dg-final { scan-assembler-not "x7" } } */ + return d; +} + +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/va_arg_3.c b/gcc/testsuite/gcc.target/aarch64/va_arg_3.c new file mode 100644 index 0000000..7f7601a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/va_arg_3.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 --save-temps" } */ + +int d2i (double a); + +int +foo (char *fmt, ...) +{ + int d, e; + double f, g; + __builtin_va_list ap; + + __builtin_va_start (ap, fmt); + d = __builtin_va_arg (ap, int); + f = __builtin_va_arg (ap, double); + g = __builtin_va_arg (ap, double); + d += d2i (f); + d += d2i (g); + __builtin_va_end (ap); + + /* { dg-final { scan-assembler-not "x7" } } */ + /* { dg-final { scan-assembler-not "q7" } } */ + return d; +} + +/* { dg-final { cleanup-saved-temps } } */ |