diff options
author | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-08-05 14:38:57 +0000 |
---|---|---|
committer | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-08-05 14:38:57 +0000 |
commit | 374e0781dc6795c78d97f0de8cd2b6873431accb (patch) | |
tree | 3358ab37533d02c8b3f99a2f7f2186b9bb130e3c | |
parent | c9a95885532b214c49415e6b80aaaab5a0ce7959 (diff) | |
download | gcc-374e0781dc6795c78d97f0de8cd2b6873431accb.tar.gz |
Merged r150260 through r150468 into branch.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/ifunc@150485 138bc75d-0d04-0410-961f-82ee72b054a4
749 files changed, 29564 insertions, 8238 deletions
diff --git a/ChangeLog b/ChangeLog index 50a2ec58942..daac975f804 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-07-31 Christian Bruel <christian.bruel@st.com> + + * configure.ac (sh*-*-elf): Don't add target-libgloss to noconfigdirs. + * configure: Regenerate. + 2009-07-28 Rask Ingemann Lambertsen <ccc94453@vip.cybercity.dk> * MAINTAINERS (Write After Approval): Update my e-mail address. diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog index fa53669ca2a..0e37031371e 100644 --- a/boehm-gc/ChangeLog +++ b/boehm-gc/ChangeLog @@ -1,3 +1,7 @@ +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force. + 2009-07-17 Michael Meissner <meissner@linux.vnet.ibm.com> PR boehm-gc/40785 diff --git a/boehm-gc/configure.ac b/boehm-gc/configure.ac index 2206f76eaa2..52ab0b5fa47 100644 --- a/boehm-gc/configure.ac +++ b/boehm-gc/configure.ac @@ -49,7 +49,7 @@ m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) m4_define([_AC_ARG_VAR_PRECIOUS],[]) AC_PROG_CC AC_PROG_CXX -m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) +m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) AM_PROG_CC_C_O diff --git a/config/ChangeLog b/config/ChangeLog index 6bd7bbf5416..51d62d787b3 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -1,3 +1,13 @@ +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * extensions.m4 (AC_USE_SYSTEM_EXTENSIONS): Do not expand + for Autoconf 2.62 or newer. + * tls.m4 (GCC_CHECK_TLS): Fix m4 quotation. + * no-executables.m4 (_AC_COMPILER_EXEEXT): Fix m4 quotation. + * override.m4 (m4_copy_force, m4_rename_force): Provide + macros if not defined. + (AC_PREREQ): Use m4_copy_force. + 2009-07-17 Joseph Myers <joseph@codesourcery.com> PR other/40784 diff --git a/config/extensions.m4 b/config/extensions.m4 index 8ae4a675e2b..eb59f272119 100644 --- a/config/extensions.m4 +++ b/config/extensions.m4 @@ -1,7 +1,7 @@ -# serial 5 -*- Autoconf -*- +# serial 6 -*- Autoconf -*- # Enable extensions on systems that normally disable them. -# Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc. +# Copyright (C) 2003, 2006, 2007, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -12,6 +12,8 @@ # enough in this area it's likely we'll need to redefine # AC_USE_SYSTEM_EXTENSIONS for quite some time. +m4_version_prereq([2.62],, [ + # AC_USE_SYSTEM_EXTENSIONS # ------------------------ # Enable extensions on systems that normally disable them, @@ -74,3 +76,4 @@ AC_BEFORE([$0], [AC_RUN_IFELSE])dnl AC_DEFINE([_TANDEM_SOURCE]) ])# AC_USE_SYSTEM_EXTENSIONS +]) diff --git a/config/no-executables.m4 b/config/no-executables.m4 index c4d0b70c375..90616245ef9 100644 --- a/config/no-executables.m4 +++ b/config/no-executables.m4 @@ -25,7 +25,7 @@ AC_BEFORE([$0], [_AC_COMPILER_EXEEXT]) AC_BEFORE([$0], [AC_LINK_IFELSE]) m4_define([_AC_COMPILER_EXEEXT], -AC_LANG_CONFTEST([AC_LANG_PROGRAM()]) +[AC_LANG_CONFTEST([AC_LANG_PROGRAM()]) # FIXME: Cleanup? AS_IF([AC_TRY_EVAL(ac_link)], [gcc_no_link=no], [gcc_no_link=yes]) if test x$gcc_no_link = xyes; then @@ -35,7 +35,7 @@ if test x$gcc_no_link = xyes; then cross_compiling=yes EXEEXT= else - m4_defn([_AC_COMPILER_EXEEXT])dnl + ]m4_defn([_AC_COMPILER_EXEEXT])dnl fi ) diff --git a/config/override.m4 b/config/override.m4 index 9bb149620c4..bf112db99a8 100644 --- a/config/override.m4 +++ b/config/override.m4 @@ -12,6 +12,16 @@ dnl dnl The _GCC_AUTOCONF_VERSION_TEST ensures that exactly the desired dnl Autoconf version is used. It should be kept for consistency. +dnl Provide m4_copy_force and m4_rename_force for old Autoconf versions. + +m4_ifndef([m4_copy_force], +[m4_define([m4_copy_force], +[m4_ifdef([$2], [m4_undefine([$2])])m4_copy($@)])]) + +m4_ifndef([m4_rename_force], +[m4_define([m4_rename_force], +[m4_ifdef([$2], [m4_undefine([$2])])m4_rename($@)])]) + dnl m4_PACKAGE_VERSION is an undocumented Autoconf macro. dnl We use it because this fix is intended for 2.59 only. dnl A feature test for the broken AC_CONFIG_SUBDIRS instead @@ -25,7 +35,7 @@ ifdef([m4_PACKAGE_VERSION], [dnl AC_DEFUN a commonly used macro so this file is picked up. m4_copy([AC_PREREQ], [_AC_PREREQ]) AC_DEFUN([AC_PREREQ], [frob]) -m4_copy([_AC_PREREQ], [AC_PREREQ]) +m4_copy_force([_AC_PREREQ], [AC_PREREQ]) dnl Ensure exactly this Autoconf version is used diff --git a/config/tls.m4 b/config/tls.m4 index 099bdc257a8..ef7e6d0b555 100644 --- a/config/tls.m4 +++ b/config/tls.m4 @@ -11,8 +11,8 @@ AC_DEFUN([GCC_CHECK_TLS], [ chktls_save_LDFLAGS="$LDFLAGS" LDFLAGS="-static $LDFLAGS" AC_LINK_IFELSE([int main() { return 0; }], - AC_RUN_IFELSE([__thread int a; int b; int main() { return a = b; }], - [gcc_cv_have_tls=yes], [gcc_cv_have_tls=no],[]), + [AC_RUN_IFELSE([__thread int a; int b; int main() { return a = b; }], + [gcc_cv_have_tls=yes], [gcc_cv_have_tls=no],[])], [gcc_cv_have_tls=yes]) LDFLAGS="$chktls_save_LDFLAGS" if test $gcc_cv_have_tls = yes; then diff --git a/configure b/configure index 8ba3c9cfe83..7bebf1e591d 100755 --- a/configure +++ b/configure @@ -2650,7 +2650,12 @@ case "${target}" in i[3456789]86-*-msdosdjgpp*) ;; # don't add gprof back in *) skipdirs=`echo " ${skipdirs} " | sed -e 's/ gprof / /'` ;; esac - noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" + case "${target}" in + sh*-*-elf) + noconfigdirs="$noconfigdirs ${libgcj}" ;; + *) + noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" ;; + esac ;; sparclet-*-aout* | sparc86x-*-*) libgloss_dir=sparc diff --git a/configure.ac b/configure.ac index 22cd976bbbd..30721eb9883 100644 --- a/configure.ac +++ b/configure.ac @@ -874,7 +874,12 @@ case "${target}" in i[[3456789]]86-*-msdosdjgpp*) ;; # don't add gprof back in *) skipdirs=`echo " ${skipdirs} " | sed -e 's/ gprof / /'` ;; esac - noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" + case "${target}" in + sh*-*-elf) + noconfigdirs="$noconfigdirs ${libgcj}" ;; + *) + noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" ;; + esac ;; sparclet-*-aout* | sparc86x-*-*) libgloss_dir=sparc diff --git a/fixincludes/ChangeLog b/fixincludes/ChangeLog index 35260caca66..9747c00c640 100644 --- a/fixincludes/ChangeLog +++ b/fixincludes/ChangeLog @@ -1,3 +1,16 @@ +2009-08-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> + + * inclhack.def (hpux_inttype_int_least8_t): Also apply on hpux10*. + (hpux_inttype_int8_t): Likewise. + * fixincl.x: Regenerate. + +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * Makefile.in (AUTOCONF, AUTOHEADER, ACLOCAL, ACLOCAL_AMFLAGS): + New variables. + ($(srcdir)/configure, $(srcdir)/config.h.in, $(srcdir)/aclocal.m4): + Use them. + 2009-07-04 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> * inclhack.def (darwin_stdint_5, darwin_stdint_6, diff --git a/fixincludes/Makefile.in b/fixincludes/Makefile.in index 1f89cf9edeb..f91a70d2e6e 100644 --- a/fixincludes/Makefile.in +++ b/fixincludes/Makefile.in @@ -63,6 +63,11 @@ itoolsdatadir = $(libsubdir)/install-tools # Locate mkinstalldirs. mkinstalldirs=$(SHELL) $(srcdir)/../mkinstalldirs +AUTOCONF = autoconf +AUTOHEADER = autoheader +ACLOCAL = aclocal +ACLOCAL_AMFLAGS = -I ../gcc -I .. -I ../config + default : all # Now figure out from those variables how to compile and link. @@ -159,13 +164,13 @@ config.status: $(srcdir)/configure $(SHELL) ./config.status --recheck $(srcdir)/configure: @MAINT@ $(srcdir)/configure.ac $(srcdir)/aclocal.m4 - cd $(srcdir) && autoconf + cd $(srcdir) && $(AUTOCONF) $(srcdir)/config.h.in: @MAINT@ $(srcdir)/configure.ac - cd $(srcdir) && autoheader + cd $(srcdir) && $(AUTOHEADER) $(srcdir)/aclocal.m4: @MAINT@ $(srcdir)/configure.ac - cd $(srcdir) && aclocal -I ../gcc -I .. -I ../config + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) check : all autogen -T $(srcdir)/check.tpl $(srcdir)/inclhack.def diff --git a/fixincludes/fixincl.x b/fixincludes/fixincl.x index 90eb9370aef..797d962619b 100644 --- a/fixincludes/fixincl.x +++ b/fixincludes/fixincl.x @@ -2,11 +2,11 @@ * * DO NOT EDIT THIS FILE (fixincl.x) * - * It has been AutoGen-ed Saturday July 4, 2009 at 10:06:21 AM CEST + * It has been AutoGen-ed Saturday August 1, 2009 at 09:16:11 PM EDT * From the definitions inclhack.def * and the template file fixincl */ -/* DO NOT SVN-MERGE THIS FILE, EITHER Sat Jul 4 10:06:21 CEST 2009 +/* DO NOT SVN-MERGE THIS FILE, EITHER Sat Aug 1 21:16:12 EDT 2009 * * You must regenerate it. Use the ./genfixes script. * @@ -3874,7 +3874,7 @@ tSCC zHpux_Inttype_Int_Least8_TList[] = * Machine/OS name selection pattern */ tSCC* apzHpux_Inttype_Int_Least8_TMachs[] = { - "*-hp-hpux11.*", + "*-hp-hpux1[01].*", (const char*)NULL }; /* @@ -3911,7 +3911,7 @@ tSCC zHpux_Inttype_Int8_TList[] = * Machine/OS name selection pattern */ tSCC* apzHpux_Inttype_Int8_TMachs[] = { - "*-hp-hpux11.*", + "*-hp-hpux1[01].*", (const char*)NULL }; /* diff --git a/fixincludes/inclhack.def b/fixincludes/inclhack.def index 8cb6b7ed61d..b65ad2c21d6 100644 --- a/fixincludes/inclhack.def +++ b/fixincludes/inclhack.def @@ -2096,7 +2096,7 @@ fix = { fix = { hackname = hpux_inttype_int_least8_t; - mach = "*-hp-hpux11.*"; + mach = "*-hp-hpux1[01].*"; files = sys/_inttypes.h; select = "^[ \t]*typedef[ \t]*char[ \t]*int_least8_t.*"; c_fix = format; @@ -2106,7 +2106,7 @@ fix = { fix = { hackname = hpux_inttype_int8_t; - mach = "*-hp-hpux11.*"; + mach = "*-hp-hpux1[01].*"; files = sys/_inttypes.h; select = "^[ \t]*typedef[ \t]*char[ \t]*int8_t.*"; c_fix = format; diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ca374c343d1..a888baf4235 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,684 @@ +2009-08-03 Janis Johnson <janis187@us.ibm.com> + + PR c/39902 + * simplify-rtx.c (simplify_binary_operation_1): Disable + simplifications for decimal float operations. + +2009-08-03 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/40943 + * tree-ssa.c (warn_uninitialized_var): Even on LHS warn for + operand of INDIRECT_REF. + +2009-08-03 Uros Bizjak <ubizjak@gmail.com> + + * config/alpha/alpha.c (alpha_legitimate_constant_p): Reject CONST + constants referencing TLS symbols. + +2009-08-03 SUGIOKA Toshinobu <sugioka@itonet.co.jp> + + * config/sh/linux-atomic.asm (ATOMIC_COMPARE_AND_SWAP): Rename + __sync_compare_and_swap_* to __sync_val_compare_and_swap_*. + +2009-08-03 Richard Guenther <rguenther@suse.de> + + * tree.c (make_vector_type): Build a main variant first, + get the canonical one and then build the variant. + * tree-ssa.c (useless_type_conversion_p_1): Handle + fixed-point types. + (useless_type_conversion_p): Conversions to pointers to + incomplete record types are useless. + +2009-08-03 Richard Guenther <rguenther@suse.de> + + * tree-cfg.c (pass_warn_unused_result): Mark name that no dump + file will be created. + * omp-low.c (pass_diagnose_omp_blocks): Likewise. + * toplev.c (compile_file): Adjust comment. + +2009-08-03 Kaz Kojima <kkojima@gcc.gnu.org> + + * config/sh/sh-protos.h (sh_promote_function_mode): Remove. + * config/sh/sh.c (sh_promote_function_mode): Wrap long lines. + (TARGET_PROMOTE_FUNCTION_MODE): Define. + (TARGET_PROMOTE_FUNCTION_ARGS): Remove. + (sh_promote_function_mode): Fix typo. + +2009-08-03 Andreas Krebbel <krebbel1@de.ibm.com> + + * explow.c (promote_mode): Mark TYPE and PUNSIGNEDP as possibly unused. + +2009-08-02 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> + + * pa.c (pa_promote_function_mode): Remove ATTRIBUTE_UNUSED from + declaration arguments. + +2009-08-02 Uros Bizjak <ubizjak@gmail.com> + + * config/i386/i386.c (ix86_expand_fp_compare): Use const0_rtx instead + of GEN_INT (0x00) and const1_rtx instead of GEN_INT (0x01). + (ix86_split_ashl): Ditto. + (ix86_expand_vector_init_one_nonzero): Ditto. + (ix86_expand_vector_set): Ditto. + (ix86_expand_reduc_v4sf): Ditto. + +2009-08-02 Paolo Bonzini <bonzini@gnu.org> + + * explow.c (promote_function_mode): Remove assert. + * config/sh/sh.c (sh_promote_function_mode): Declare. + +2009-08-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> + + * config/pa/pa.c (pa_promote_function_mode): Declare. + Change to static. Fix promote_mode call. + + * gthr-dce.h (CONST_CAST2): Define if not defined. + (__gthread_setspecific): Use CONST_CAST2 to fix warning. + + * config.gcc (hppa[12]*-*-hpux10*): Add stdint support. + +2009-08-01 Paolo Bonzini <bonzini@gnu.org> + + * expr.c (store_constructor): Use promote_decl_mode. Remove + now write-only variable unsignedp. + (expand_expr_real_1): Use promote_decl_mode. + * expr.h (promote_function_mode, promote_decl_mode): New. + (promote_mode): Remove last argument. + * function.c (assign_temp): Drop last argument of promote_mode. + (assign_parm_find_data_types): Use promote_function_mode. + (assign_parm_setup_reg): Likewise. + (expand_function_end): Use promote_function_mode. + * calls.c (initialize_argument_information): Use promote_function_mode. + (precompute_arguments): Use promote_mode instead of checking if + only PROMOTE_FUNCTION_MODE is defined. + (expand_call): When making sibcall decisions, use promote_function_mode. + Below, remove an if for targetm.calls.promote_function_return and + and use promote_function_mode. + (emit_library_call_value_1): Use promote_function_mode, fix bug + where promote_mode was passed FOR_CALL == 0 for a return value in an + assertion. + * cfgexpand.c (expand_one_register_var): Use promote_decl_mode. + * explow.c (promote_function_mode, promote_decl_mode): New. + (promote_mode): Keep only the FOR_CALL == 0 case. + * combine.c (setup_incoming_promotion): Remove test of + promote_function_args. Use promote_function_mode. + * stmt.c (expand_value_return): Use promote_decl_mode. + (expand_decl): Use promote_decl_mode. + + * expr.c (store_constructor): Use promote_decl_mode. Remove + now write-only variable unsignedp. + (expand_expr_real_1): Use promote_decl_mode. + * expr.h (promote_function_mode, promote_decl_mode): New. + (promote_mode): Remove last argument. + * function.c (assign_temp): Drop last argument of promote_mode. + (assign_parm_find_data_types): Use promote_function_mode. + (assign_parm_setup_reg): Likewise. + (expand_function_end): Use promote_function_mode. + * calls.c (initialize_argument_information): Use promote_function_mode. + (precompute_arguments): Use promote_mode instead of checking if + only PROMOTE_FUNCTION_MODE is defined. + (expand_call): When making sibcall decisions, use promote_function_mode. + Below, remove an if for targetm.calls.promote_function_return and + and use promote_function_mode. + (emit_library_call_value_1): Use promote_function_mode, fix bug + where promote_mode was passed FOR_CALL == 0 for a return value in an + assertion. + * cfgexpand.c (expand_one_register_var): Use promote_decl_mode. + * explow.c (promote_function_mode, promote_decl_mode): New. + (promote_mode): Keep only the FOR_CALL == 0 case. + * combine.c (setup_incoming_promotion): Remove test of + promote_function_args. Use promote_function_mode. + * stmt.c (expand_value_return): Use promote_decl_mode. + (expand_decl): Use promote_decl_mode. + + * explow.c (promote_function_mode): Just call the target hook. + * targhooks.c (default_promote_function_mode, + default_promote_function_mode_always_promote): New. + * targhooks.h (default_promote_function_mode, + default_promote_function_mode_always_promote): Declare. + * target.h (promote_function_args, promote_function_return): Remove. + (promote_function_mode): New. + * target-def.h (TARGET_PROMOTE_FUNCTION_ARGS, + TARGET_PROMOTE_FUNCTION_RETURN): Remove. + (TARGET_PROMOTE_FUNCTION_MODE): New. + (TARGET_CALLS): Adjust. + * system.h (TARGET_PROMOTE_FUNCTION_ARGS, + TARGET_PROMOTE_FUNCTION_RETURN, PROMOTE_FUNCTION_MODE): Poison. + + * config/s390/s390.h (PROMOTE_FUNCTION_MODE): Move... + * config/s390/s390.c (s390_promote_function_mode): ... here, + with pointer handling. + (TARGET_PROMOTE_FUNCTION_MODE): Define. + (TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN): Remove. + + * config/sparc/sparc.h (PROMOTE_FUNCTION_MODE): Move... + * config/sparc/sparc.c (sparc_promote_function_mode): ... here, + with pointer handling. + (TARGET_PROMOTE_FUNCTION_MODE): Define. + (TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN): Remove. + + * config/sh/sh-protos.h (sh_promote_function_mode): New. + * config/sh/sh.c (sh_promote_function_mode): New. + (TARGET_PROMOTE_FUNCTION_MODE): Define. + (TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN): Remove. + + * config/cris/cris.h (PROMOTE_FUNCTION_MODE): Move... + * config/cris/cris.c (cris_promote_function_mode): ... here. + (TARGET_PROMOTE_FUNCTION_MODE): Define. + (TARGET_PROMOTE_FUNCTION_ARGS): Remove. + + * config/mmix/mmix.h (PROMOTE_FUNCTION_MODE): Move... + * config/mmix/mmix.c (mmix_promote_function_mode): ... here. + (TARGET_PROMOTE_FUNCTION_MODE): Define. + (TARGET_PROMOTE_FUNCTION_ARGS): Remove. + + * config/arm/arm.h (PROMOTE_FUNCTION_MODE): Move... + * config/arm/arm.c (arm_promote_function_mode): ... here, without + complex type handling. + (TARGET_PROMOTE_FUNCTION_MODE): Define. + (TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN): Remove. + + * config/pa/pa.c (pa_promote_function_mode): New. + (TARGET_PROMOTE_FUNCTION_MODE): Define. + (TARGET_PROMOTE_FUNCTION_RETURN): Remove. + + * config/alpha/alpha.c (TARGET_PROMOTE_FUNCTION_ARGS, + TARGET_PROMOTE_FUNCTION_RETURN): Remove. + (TARGET_PROMOTE_FUNCTION_MODE): Define equivalently. + * config/xtensa/xtensa.c: Likewise. + * config/stormy16/stormy16.c: Likewise. + * config/iq2000/iq2000.c: Likewise. + * config/rs6000/rs6000.c: Likewise. + * config/picochip/picochip.c: Likewise. + * config/arc/arc.c: Likewise. + * config/mcore/mcore.c: Likewise. + * config/score/score.c: Likewise. + * config/mips/mips.c: Likewise. + * config/bfin/bfin.c: Likewise. + * config/ia64/ia64.c: Likewise (disabled though). + + * config/frv/frv.h: Remove pointless remark. + + * doc/tm.texi (PROMOTE_FUNCTION_MODE, + TARGET_PROMOTE_FUNCTION_ARGS, + TARGET_PROMOTE_FUNCTION_RETURN): Consolidate into... + (TARGET_PROMOTE_FUNCTION_MODE): ... this. + +2009-08-01 Sebastian Pop <sebastian.pop@amd.com> + + * doc/invoke.texi (-fgraphite-force-parallel): Renamed + -floop-parallelize-all. + * toplev.c (process_options): Rename flag_graphite_force_parallel to + flag_loop_parallelize_all. + * tree-ssa-loop.c (gate_graphite_transforms): Same. + * graphite.c (graphite_transform_loops): Same. + * common.opt: Same. + * graphite-poly.c (apply_poly_transforms): Same. + +2009-07-31 Richard Earnshaw <rearnsha@arm.com> + + PR tree-optimization/40914 + * ipa-prop.c (ipa_get_ptr_load_param): New argument use_delta, + if set, then check the delta field of the PMF record. + (ipa_get_stmt_member_ptr_load_param): Propagate new param use_delta. + (ipa_analyze_call_uses): Handle machines where the vbit for a PMF + call is stored in the delta. + +2009-07-31 Adam Nemet <anemet@caviumnetworks.com> + + * config/mips/mips.md (*clear_upper32_dext): New pattern. + +2009-07-31 Uros Bizjak <ubizjak@gmail.com> + + * config/i386/bsd.h (ASM_BYTE): New define. + * config/i386/darwin.h (ASM_BYTE): Rename from ASM_BYTE_OP. + * config/i386/att.h (ASM_BYTE): New define. Use ASM_BYTE instead of + .byte. Use fputs or putc instead of fprintf where appropriate. + * config/i386/i386-interix.h: Use ASM_BYTE instead of .byte. Use + fputs or putc instead of fprintf where appropriate. + * config/i386/i386elf.h: Ditto. + * config/i386/sysv4.h: Ditto. + + * config/i386/i386.c (TARGET_ASM_BYTE_OP): New define. + * config/i386/i386.md (x86_sahf_1): Use ASM_BYTE instead of .byte. + (*tls_global_dynamic_64): Ditto. + +2009-07-31 Christian Bruel <christian.bruel@st.com> + + * gcc/config.gcc (sh*-*-elf): test with_libgloss. + +2009-07-31 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> + + * config/arm/arm.c (arm_arm_address_cost): Fix typo. + Remove dead code for MINUS. + +2009-07-31 Anthony Green <green@moxielogic.com> + + * config/moxie/moxie.c (moxie_expand_prologue): Use $r5 instead of + $r12 in prologue. + (moxie_expand_epilogue): Ditto for epilogue. + (moxie_setup_incoming_varargs): ABI change. Use 5 registers for + incoming arguments. + (moxie_function_arg): Ditto. + (moxie_pass_by_reference): Ditto. + (moxie_arg_partial_bytes): Ditto. + * config/moxie/moxie.h (CALL_USED_REGISTERS): Ditto. + (FUNCTION_ARG_ADVANCE) Ditto. + (REG_PARM_STACK_SPACE) Ditto. + (FUNCTION_ARG_REGNO_P) Dito. + + * config.gcc: Add moxie linux config support. + * gcc/config/moxie/uclinux.h: New file. + +2009-07-31 DJ Delorie <dj@redhat.com> + + * config/sh/sh.md (UNSPECV_SP_SWITCH_B): New. + (UNSPECV_SP_SWITCH_E): New. + (sp_switch_1): Change to an unspec. + (sp_switch_2): Change to an unspec. Don't use post-inc when we + replace $r15. + * config/sh/sh.c (sh_expand_prologue): Use the constant pool to + reference the new stack's address + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * Makefile.in (OBJS-common): Added dependence on graphite-blocking.o, + graphite-clast-to-gimple.o, graphite-dependences.o, + graphite-interchange.o, graphite-poly.o, graphite-ppl.o, + graphite-scop-detection.o, graphite-sese-to-poly.o, and sese.o. + (graphite-blocking.o, + graphite-clast-to-gimple.o, graphite-dependences.o, + graphite-interchange.o, graphite-poly.o, graphite-ppl.o, + graphite-scop-detection.o, graphite-sese-to-poly.o, and sese.o): New. + * cfgloop.c (alloc_loop): Set loop->can_be_parallel to false. + * cfgloop.h (struct loop): Add can_be_parallel field. + * common.opt (fgraphite-identity): Moved up. + (fgraphite-force-parallel): New flag. + * graphite.c: Rewrite. + * graphite.h: Rewrite. + * passes.c (init_optimization_passes): Schedule a pass of DCE and LIM + after Graphite. + * toplev.c (graphite_out_file): New file descriptor. + (graphite_in_file): New. + (process_options): flag_graphite_force_parallel cannot be used without + Graphite. + * tree-ssa-loop.c: Include toplev.h. + (gate_graphite_transforms): Enable flag_graphite for + flag_graphite_force_parallel. + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * ChangeLog.graphite: New. + * graphite-blocking.c: New. + * graphite-clast-to-gimple.c: New. + * graphite-clast-to-gimple.h: New. + * graphite-dependences.c: New. + * graphite-dependences.h: New. + * graphite-interchange.c: New. + * graphite-poly.c: New. + * graphite-poly.h: New. + * graphite-ppl.c: New. + * graphite-ppl.h: New. + * graphite-scop-detection.c: New. + * graphite-scop-detection.h: New. + * graphite-sese-to-poly.c: New. + * graphite-sese-to-poly.h: New. + * sese.c: New. + * sese.h: New. + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * tree-chrec.c (evolution_function_right_is_integer_cst): New. + * tree-chrec.h (evolution_function_right_is_integer_cst): Declared. + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * tree-chrec.c (operator_is_linear): Handle BIT_NOT_EXPR. + (scev_is_linear_expression): Return false if the evolution is not + affine multivariate. + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * tree-data-ref.c (graphite_find_data_references_in_stmt): New. + * tree-data-ref.h (graphite_find_data_references_in_stmt): Declared. + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * tree-data-ref.c (debug_data_references): New. + (debug_data_reference): New. + * tree-data-ref.h (debug_data_references): Declared. + (debug_data_reference): Declared. + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * tree-data-ref.c (stmt_simple_memref_p: Removed. + * tree-data-ref.h (scop_p): Removed. + (struct data_reference): Remove field scop. + (DR_SCOP): Removed. + (stmt_simple_memref_p): Removed. + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * cfgloop.h (create_empty_loop_on_edge): Pass an extra argument. + * cfgloopmanip.c (create_empty_loop_on_edge): Leave the loop_latch + basic block empty. + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * doc/invoke.texi (-fgraphite-force-parallel): Documented. + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * doc/invoke.texi (-fgraphite-identity): Documented. + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * tree-scalar-evolution.c: Fix comment. + (instantiate_scev_1): Return unknow from scev instantiation if the + result is not above instantiate_below. + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * tree-scalar-evolution.c (compute_overall_effect_of_inner_loop): Not + static anymore. Instantiate the symbols that may have been introduced + by chrec_apply. + * tree-scalar-evolution.h (compute_overall_effect_of_inner_loop): + Declared. + +2009-07-30 DJ Delorie <dj@redhat.com> + + * config/mep/mep.c (mep_asm_init_sections): Add section flags and + .vliw directive to VLIW sections. + +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * Makefile.in (AUTOCONF, ACLOCAL, ACLOCAL_AMFLAGS, aclocal_deps): + New variables. + ($(srcdir)/configure, $(srcdir)/aclocal.m4): New rules. + (AUTOHEADER): New variable. + ($(srcdir)/cstamp-h.in): Use it. + +2009-07-30 Michael Meissner <meissner@linux.vnet.ibm.com> + Pat Haugen <pthaugen@us.ibm.com> + Revital Eres <ERES@il.ibm.com> + + * config/rs6000/vector.md (VEC_F): Add VSX support. + (VEC_A): Ditto. + (VEC_N): Ditto. + (mov<mode>): Ditto. + (vector_load_<mode>): Ditto. + (vector_store_<mode>): Ditto. + (vector GPR move split): Ditto. + (vec_reload_and_plus_<mptrsize>): Ditto. + (vec_reload_and_reg_<mptrsize>): Ditto. + (add<mode>3): Ditto. + (sub<mode>3): Ditto. + (mul<mode>3): Ditto. + (neg<mode>2): Ditto. + (abs<mode>2): Ditto. + (smin<mode>3): Ditto. + (smax<mode>3): Ditto. + (vector_eq<mode>): Ditto. + (vector_gt<mode>): Ditto. + (vector_ge<mode>): Ditto. + (vector_gtu<mode>): Ditto. + (vector_select_<mode>_uns): Ditto. + (vector_eq_<mode>_p): Ditto. + (vector_gt_<mode>_p): Ditto. + (vector_ge_<mode>_p): Ditto. + (vector_gtu_<mode>_p): Ditto. + (cr6_test_for_zero): Ditto. + (cr6_test_for_zero_reverse): Ditto. + (cr6_test_for_lt): Ditto. + (cr6_test_for_lt_reverse): Ditto. + (xor<mode>3): Ditto. + (ior<mode>3): Ditto. + (and<mode>3): Ditto. + (one_cmpl<mode>2): Ditto. + (nor<mode>2): Ditto. + (andc<mode>2): Ditto. + (float<VEC_int<mode>2): Ditto. + (unsigned_float<VEC_int><mode>2): Ditto. + (fix_trunc<mode><VEC_int>2): Ditto. + (fixuns_trunc<mode><VEC_int>2): Ditto. + (vec_init<mode>): + (vec_set<mode>): Ditto. + (vec_extract<mode>): Ditto. + (vec_interleave_highv4sf): Ditto. + (vec_interleave_lowv4sf): Ditto. + (vec_realign_load_<mode>): Ditto. + (vec_shl_<mode>): Ditto. + (vec_shr_<mode>): Ditto. + (div<mode>3): New patterns for VSX. + (vec_interleave_highv2df): Ditto. + (vec_interleave_lowv2df): Ditto. + (vec_pack_trunc_v2df): Ditto. + (vec_pack_sfix_trunc_v2df): Ditto. + (vec_pack_ufix_trunc_v2df): Ditto. + (vec_unpacks_hi_v4sf): Ditto. + (vec_unpacks_lo_v4sf): Ditto. + (vec_unpacks_float_hi_v4si): Ditto. + (vec_unpacku_float_lo_v4si): Ditto. + (vec_unpacku_float_hi_v4si): Ditto. + (vec_unpacks_float_lo_v4si): Ditto. + (movmisalign<mode>): Ditto. + (vector_ceil<mode>2): New patterns for vectorizing math library. + (vector_floor<mode>2): Ditto. + (vector_btrunc<mode>2): Ditto. + (vector_copysign<mode>3): Ditto. + + * config/rs6000/predicates.md (easy_vector_constant_msb): New + predicate for setting the high bit in each word, used for copysign. + + * config/rs6000/ppc-asm.h (f19): Whitespace. + (f32-f63): Define if VSX. + (v0-v31): Define if Altivec. + (vs0-vs63): Define if VSX. + + * config/rs6000/t-rs6000 (MD_INCLUDES): Add power7.md and vsx.md. + + * config/rs6000/power7.md: New file, provide tuning parameters for + -mcpu=power7. + + * config/rs6000/rs6000-c.c (rs6000_macro_to_expand): Add VSX support. + (rs6000_cpu_cpp_builtins): Ditto. + (altivec_overloaded_builtins): Ditto. + (altivec_resolve_overloaded_builtin): Ditto. + + * config/rs6000/rs6000.opt (-mno-vectorize-builtins): Add new + debug switch to disable vectorizing simple math builtin + functions. + + * config/rs6000/rs6000.c (rs6000_builtin_vectorized_function): + Vectorize simple math builtin functions. + (TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION): Define target + hook to vectorize math builtins. + (rs6000_override_options): Enable -mvsx on -mcpu=power7. + (rs6000_builtin_conversion): Add VSX/power7 support. + (rs6000_builtin_vec_perm): Ditto. + (vsplits_constant): Add support for loading up a vector constant + with just the high bit set in each part. + (rs6000_expand_vector_init): Add VSX/power7 support. + (rs6000_expand_vector_set): Ditto. + (rs6000_expand_vector_extract): Ditto. + (rs6000_emit_move): Ditto. + (bdesc_3arg): Ditto. + (bdesc_2arg): Ditto. + (bdesc_1arg): Ditto. + (rs6000_expand_ternop_builtin): Ditto. + (altivec_expand_builtin): Ditto. + (rs6000_expand_unop_builtin): Ditto. + (rs6000_init_builtins): Ditto. + (altivec_init_builtins): Ditto. + (builtin_function_type): Ditto. + (rs6000_common_init_builtins): Ditto. + (rs6000_handle_altivec_attribute); Ditto. + (rs6000_mangle_type): Ditto. + (rs6000_vector_mode_supported_p): Ditto. + (rs6000_mode_dependent_address): Altivec addresses with AND -16 + are mode dependent. + + * config/rs6000/vsx.md: New file for VSX support. + + * config/rs6000/rs6000.h (EASY_VECTOR_MSB): New macro for + identifing values with just the most significant bit set. + (enum rs6000_builtins): Add builtins for VSX. Add simple math + vectorized builtins. + + * config/rs6000/altivec.md (UNSPEC_VRFIP): Delete. + (UNSPEC_VRFIM): Delete. + (splitter for loading up vector with most significant bit): New + splitter for vectorizing copysign. + (altivec_vrfiz): Rename from altivec_fturncv4sf2. Add support for + vectorizing simple math functions. + (altivec_vrfip): Add support for vectorizing simple math functions. + (altivec_vrfim): Ditto. + (altivec_copysign_v4sf3): New insn for Altivec copysign support. + + * config/rs6000/rs6000.md (UNSPEC_BPERM): New constant. + (power7.md, vsx.md): Include for power7 support. + (copysigndf3): Use VSX instructions if -mvsx. + (negdf2_fpr): Ditto. + (absdf2_fpr): Ditto. + (nabsdf2_fpr): Ditto. + (adddf3_fpr): Ditto. + (subdf3_fpr): Ditto. + (muldf3_fpr): Ditto. + (divdf3_fpr): Ditto. + (fix_truncdfdi2_fpr): Ditto. + (cmpdf_internal1): Ditto. + (fred, fred_fpr): Convert into expander/insn to add VSX support. + (btruncdf2, btruncdf2_fpr): Ditto. + (ceildf2, ceildf2_fpr): Ditto. + (floordf2, floordf2_fpr): Ditto. + (floatdidf2, floatdidf2_fpr): Ditto. + (fmadddf4_fpr): Name insn. Use VSX instructions if -mvsx. + (fmsubdf4_fpr): Ditto. + (fnmadddf4_fpr_1): Ditto. + (fnmadddf4_fpr_2): Ditto. + (fnmsubdf4_fpr_1): Ditto. + (fnmsubdf4_fpr_2): Ditto. + (fixuns_truncdfdi2): Add expander for VSX support. + (fix_truncdfdi2): Ditto. + (fix_truncdfsi2): Ditto. + (ftruncdf2): Ditto. + (btruncsf2): Whitespace. + (movdf_hardfloat32): Add support for VSX registers. + (movdf_softfloat32): Ditto. + (movdf_hardfloat64): Ditto. + (movdf_hardfloat64_mfpgpr): Ditto. + (movdf_softfloat64): Ditto. + (movti splitters): Add check for vector registers supporting + TImode in the future. + (bpermd): Add power7 bpermd instruction. + + * config/rs6000/altivec.h (vec_div): Define if VSX. + (vec_mul): Ditto. + (vec_msub): Ditto. + (vec_nmadd): Ditto. + (vec_nearbyint): Ditto. + (vec_rint): Ditto. + (vec_sqrt): Ditto. + (all predicates): Use the generic builtin function, and not the V4SF + specific function so that the predicates will work with VSX's V2DF. + (vec_all_*): Ditto. + (vec_any_*): Ditto. + + * doc/extend.texi (PowerPC Altivec/VSX Built-in Functions): + Document new VSX functions and types. + + * doc/invoke.texi (PowerPc options): Document -mpopcntd, -mvsx + switches. + + * doc/md.texi (PowerPC constraints): Document "wd", "wf", "ws", + "wa", and "j" constraints. Modify "v" to talk about Altivec + instead of just vector. + +2009-07-30 Andrew MacLeod <amacleod@redhat.com> + + PR debug/26475 + * tree-into-ssa.c (insert_phi_nodes_for, rewrite_add_phi_arguments): Set + location for phi arguments. + (rewrite_update_phi_arguments): Find locations for reaching defs. + * tree-ssa-threadupdate.c (create_edge_and_update_destination_phis): + Add location to add_phi_arg calls. + * tree-loop-districbution.c (update_phis_for_loop_copy): Add locations. + * tree-ssa-loop-manip.c (create_iv, add_exit_phis_edge, + split_loop_exit_edge, tree_transform_and_unroll_loop): Add locations. + * tree-tailcall.c (add_successor_phi_arg, eliminate_tail_call, + create_tailcall_accumulator, tree_optimize_tail_calls_1): Add locations. + * tree.h (struct phi_arg_d): Add location_t to PHI arguments. + * tree-phinodes.c (make_phi_node): Initialize location. + (resize_phi_node): Initialize location to UNKNOWN_LOCATION. + (add_phi_arg): Add location parameter. + (remove_phi_arg_num): Move location when moving phi argument. + * omp-low.c (expand_parallel_call, expand_omp_for_static_chunk): Set + location. + * tree-vect-loop-manip.c (slpeel_update_phis_for_duplicate_loop, + slpeel_update_phi_nodes_for_guard1, + slpeel_update_phi_nodes_for_guard2, + slpeel_tree_duplicate_loop_to_edge_cfg, set_prologue_iterations, + vect_loop_versioning): Set locations. + * tree-parloops.c (create_phi_for_local_result, + transform_to_exit_first_loop, create_parallel_loop): Add locations. + * gimple-pretty-print.c (dump_gimple_phi): Dump lineno's if present. + * tree-vect-loop.c (get_initial_def_for_induction, + vect_create_epilog_for_reduction, vect_finalize_reduction): Add + locations. + * tree-flow-inline.h (gimple_phi_arg_location): New. Return locus. + (gimple_phi_arg_location_from_edge): New. Return locus from an edge. + (gimple_phi_arg_set_location): New. Set locus. + (gimple_phi_arg_has_location): New. Check for locus. + (redirect_edge_var_map_location): New. Return locus from var_map. + * tree-vect-data-refs.c (vect_setup_realignment): Set location. + * tree-ssa-phiopt.c (conditional_replacement): Set locus when + combining PHI arguments. + (cond_store_replacement): Set location. + * cfgexpand.c (gimple_assign_rhs_to_tree): Transfer locus if possible. + * grpahite.c (add_loop_exit_phis, add_guard_exit_phis, + scop_add_exit_phis_edge): Add locations. + * tree-cfgcleanup.c (remove_forwarder_block, + remove_forwarder_block_with_phi): Add locations. + * tree-ssa-pre.c (insert_into_preds_of_block): Add locations. + * tree-predcom.c (initialize_root_vars, initialize_root_vars_lm): Add + locations. + * tree-ssa-dce.c (forward_edge_to_pdom): Add locations. + * tree-ssa.c (redirect_edge_var_map_add, ssa_redirect_edge, + flush_pending_stmts): Add source location. + * lambda-code.c (perfect_nestify): Maintain location stack with argument + stack to preserve locations. + * tree-vect-stmts.c (vectorizable_load): Add location. + * tree-inline.c (copy_phis_for_bb): Copy locus. + (setup_one_parameter): Add call locus to inlined parameter stmts. + (initialize_inlined_parameters): Pass in call location as parameter + assignment locus. + (tree_function_versioning): Pass location to setup_one_parameter. + * tree-ssa-phiprop.c (phiprop_insert_phi): Set locations. + * tree-outof-ssa.c (struct _elim_graph): Add source_location vecs for + copy and edge lists. + (insert_partition_copy_on_edge, insert_value_copy_on_edge, + insert_rtx_to_part_on_edge, insert_part_to_rtx_on_edge): Provide a + locus parameter and override the stmt default if provided. + (new_elim_graph, clear_elim_graph, delete_elim_graph, + elim_graph_add_edge, elim_graph_remove_succ_edge, + FOR_EACH_ELIM_GRAPH_SUCC, FOR_EACH_ELIM_GRAPH_PRED, eliminate_build, + elim_forward, elim_unvisited_predecessor, elim_backward, elim_create, + eliminate_phi): Add locus info in elimination graph for each edge and + value copy. + (insert_backedge_copies): Copy locus if present. + * tree-flow.h (struct _edge_var_map): Add locus field. + * tree-switch_conversions.c (fix_phi_nodes): Add locations. + * tree-cfg.c (reinstall_phi_args, gimple_make_forwarder_block, + add_phi_args_after_copy_edge, gimple_lv_adjust_loop_header_phi): Add + locations. + * ipa-struct-reorg.c (make_edge_and_fix_phis_of_dest): Add locations. + +2009-07-30 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/40570 + * ipa-inline.c (cgraph_decide_inlining): Watch out for dead single + use inlining loops. + 2009-07-30 Razya Ladelsky <razya@il.ibm.com> * ssa-loop-manip.c: Include langhooks.h. diff --git a/gcc/ChangeLog.graphite b/gcc/ChangeLog.graphite new file mode 100644 index 00000000000..ff6e748179d --- /dev/null +++ b/gcc/ChangeLog.graphite @@ -0,0 +1,5163 @@ +2009-07-28 Sebastian Pop <sebastian.pop@amd.com> + + * ChangeLog.graphite: Fix indenting, white spaces and 80 columns. + * graphite-blocking.c: Same. + * graphite-clast-to-gimple.c: Same. + * graphite-dependences.c: Same. + * graphite-poly.c: Same. + * graphite-poly.h: Same. + * graphite-ppl.c: Same. + * graphite-scop-detection.c: Same. + * graphite-sese-to-poly.c: Same. + * graphite.c: Same. + +2009-07-28 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (loop_entry_phi_arg): New. + (remove_simple_copy_phi): New. + (remove_invariant_phi): New. + (simple_copy_phi_p): New. + (reduction_phi_p): New. + (gsi_for_ssa_name_def): New. + (insert_out_of_ssa_copy): New. + (insert_out_of_ssa_copy_on_edge): New. + (create_zero_dim_array): New. + (scalar_close_phi_node_p): New. + (rewrite_close_phi_out_of_ssa): New. + (rewrite_phi_out_of_ssa): New. + (rewrite_reductions_out_of_ssa): New. + (build_poly_scop): Call rewrite_reductions_out_of_ssa. + + * testsuite/gcc.dg/graphite/id-11.c: New. + * testsuite/gcc.dg/graphite/id-15.c: New. + * testsuite/gcc.dg/graphite/interchange-1.c: Un-XFAIL. + * testsuite/gcc.dg/graphite/interchange-2.c: Un-XFAIL. + * testsuite/gcc.dg/graphite/interchange-3.c: Un-XFAIL. + * testsuite/gcc.dg/graphite/interchange-4.c: Un-XFAIL. + * testsuite/gcc.dg/graphite/interchange-7.c: Un-XFAIL. + * testsuite/gcc.dg/graphite/scop-matmult.c: Un-XFAIL. + * testsuite/gfortran.dg/graphite/id-13.f: New. + * testsuite/gfortran.dg/graphite/id-5.f: New. + +2009-07-28 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (graphite_loop_normal_form): Do not + check that nb_reductions_in_loop is zero. + * graphite-scop-detection.c (harmful_stmt_in_bb): Don't filter out + reduction phi nodes. + (nb_reductions_in_loop): Removed. + (graphite_can_represent_loop): Do not call nb_reductions_in_loop. + * graphite-sese-to-poly.c (phi_node_is_iv): Removed. + (bb_contains_non_iv_scalar_phi_nodes): Removed. + (scop_contains_non_iv_scalar_phi_nodes): Removed. + (build_poly_scop): Do not call scop_contains_non_iv_scalar_phi_nodes. + +2009-07-28 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (build_cloog_prog): Do not code generate + statements that have an empty iteration domain. + * testsuite/gfortran.dg/graphite/id-16.f: New. + +2009-07-28 Sebastian Pop <sebastian.pop@amd.com> + + * tree-scalar-evolution.c (instantiate_scev_1): Return + chrec_dont_know when the result is not above instantiate_below. + * graphite-scop-detection.c (scopdet_basic_block_info): Fix formatting. + * graphite-sese-to-poly.c (create_linear_expr_from_tree): Assert that + the tree has a known scalar evolution. + * testsuite/gfortran.dg/graphite/id-14.f: New. + * testsuite/gfortran.dg/graphite/id-15.f: New. + +2009-07-28 Sebastian Pop <sebastian.pop@amd.com> + + * sese.c (rename_variables_in_stmt): Pass in an extra parameter + insert_gsi. + (rename_variables): Keep inserting renames after the ones already + inserted. + +2009-07-28 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (compare_bb_depths): New. + (graphite_sort_dominated_info): New. + (build_scop_bbs_1): Call graphite_sort_dominated_info. + (build_scop_scattering): Fix comment. + +2009-07-28 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (graphite_finalize): Call print_loops instead of + dump_function_to_file. + * testsuite/gcc.dg/graphite/graphite.exp: Fix formatting. + * testsuite/gcc.dg/graphite/pr35356-1.c: New. Look for the number of + loops generated in the graphite output file. + * testsuite/gcc.dg/graphite/pr35356-2.c: New. + * testsuite/gcc.dg/graphite/pr35356-3.c: New. XFAILed for now. + * testsuite/gfortran.dg/graphite/id-12.f: New. + +2009-07-24 Li Feng <nemokingdom@gmail.com> + + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-8.c: + Remove 2 XFAIL. + +2009-07-24 Li Feng <nemokingdom@gmail.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-sese-to-poly.c (pdr_add_alias_set): Use data reference's + alias set number build alias in ACCESSES polyhedron. + (build_alias_set_for_drs): New. + (build_pbb_drs): Added build_alias_set_for_drs. + * graphite-dependences.c (poly_drs_may_alias_p): New. + (graphite_carried_dependence_level_k): Check alias information + before building polyhedron. + +2009-07-24 Tobias Grosser <grosser@fim.uni-passau.de> + + * Makefile.in (lambda-code.o): Fix formatting. + +2009-07-24 Tobias Grosser <grosser@fim.uni-passau.de> + + * Merge from mainline (r149350-149952) + +2009-07-18 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-poly.c (apply_poly_transforms): Move strip_mine + before interchange to prepare for loop blocking. + +2009-07-18 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-poly.c (apply_poly_transforms): Add checks after every + transformation. + * graphite-sese-to-poly.c (build_poly_scop): Remove check, as already + done in apply_poly_transforms. + +2009-07-17 Konrad Trifunovic <konrad.trifunovic@gmail.com> + + * graphite-dependences.c (build_lexicographically_gt_constraint): + Replace RES parameter with *RES. + (dependence_polyhedron_1): Pass an address of the parameter RES + instead of value of RES. + +2009-07-16 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (graphite_finalize): Fix comment. + (graphite_transform_loops): Reset scev info after code generation + of each scop. + +2009-07-16 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (graphite_finalize): Call scev_reset. + +2009-07-16 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (compute_cloog_iv_types): Do not create + GBB_CLOOG_IV_TYPES hash table twice. + * graphite-sese-to-poly.c (free_gimple_bb): Call free_data_refs. + (add_condition_to_domain): Clear GMP values. + +2009-07-16 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-dependences.c: Fix formatting. + * graphite-poly.c (free_poly_dr): Also free PDR_DATA_CONTAINER. + (pbb_number_of_iterations): Free ppl_Linear_Expression. + * graphite-sese-to-poly.c: Fix formatting. + * graphite.c (graphite_transform_loops): Create the hash table + after the early return. + +2009-07-16 Sebastian Pop <sebastian.pop@amd.com> + + * testsuite/gcc.dg/graphite/id-14.c: New. + * testsuite/gcc.dg/graphite/pr40157.c: New. + * testsuite/gfortran.dg/graphite/id-11.f: New. + +2009-07-16 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (nb_pbbs_in_loops): New. + (build_poly_scop): Return false when there are no pbbs within + loops to avoid to pass to cloog scops with no loops. + +2009-07-16 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (build_pbb_scattering_polyhedrons): Avoid + useless test "i % 2". + (build_pbb_scattering_polyhedrons): Fix formatting. + (build_poly_dr): Same. + * graphite.c (graphite_transform_loops): Restructure. + +2009-07-14 Razya Ladelsky <razya@il.ibm.com> + + * tree-ssa-loop-manip.c (rewrite_phi_with_iv): Remove + reduction_list parameter. + (rewrite_all_phi_nodes_with_iv): Same. + (canonicalize_loop_ivs): Same. + * tree-parloops.c (struct brli): Removed. + (build_reduction_list_info): Removed. + (build_new_reduction): New. + (analyze_reduction_list): Removed. + (gather_scalar_reductions): Find reductions instead of phi + nodes that can't be canonicalized. + (try_create_reduction_list): Remove reduction_list parameter. + (gen_parallel_loop): Same. + (parallelize_loops): Remove analyze_reductions variable, + initialization and free. + Change reduction_list htab initialization to reduction_info + elements instead of ssa names. + Call try_create_reduction_list and gen_parallel_loop without + analyzed_reduction argument. + * graphite-clast-to-gimple (graphite_loop_normal_form): Call + canonicalize_loop_ivs with one less argument. + * tree-flow.h (canonicalize_loop_ivs): Remove one argument. + +2009-07-14 Konrad Trifunovic <konrad.trifunovic@gmail.com> + + * graphite-dependences.c (new_poly_dr_pair): New. + (dependence_polyhedron): Renamed into dependence_polyhedron_1. + (new_poly_dr_pair): New. + (eq_poly_dr_pair_p): New. + (hash_poly_dr_pair_p): New. + * graphite-dependences.h (struct poly_dr_pair): New. + (eq_poly_dr_pair_p): Declared. + (hash_poly_dr_pair_p): Declared. + * graphite-poly.c (new_scop): Initialize SCOP_ORIGINAL_PDR_PAIRS. + (free_scop): Free SCOP_ORIGINAL_PDR_PAIRS. + * graphite-poly.h (struct scop): Add original_pdr_pairs field. + * Makefile.in (graphite-poly.o): Add dependence on + graphite-dependences.h. + +2009-07-14 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-scop-detection.c (graphite_can_represent_scev): Do not let + polynomials of degree > 1 pass to Graphite. + * tree-chrec.c (scev_is_linear_expression): Call + evolution_function_is_affine_multivariate_p. + * testsuite/gfortran.dg/graphite/id-10.f90: New. + +2009-07-14 Sebastian Pop <sebastian.pop@amd.com> + + * tree-scalar-evolution.c (compute_overall_effect_of_inner_loop): + Instantiate scevs varying in outer loops. + * testsuite/gfortran.dg/graphite/id-9.f: Correct testcase. + +2009-07-14 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (build_loop_iteration_domains): Do not insert + redundant constraint. + +2009-07-14 Sebastian Pop <sebastian.pop@amd.com> + + * testsuite/gcc.dg/graphite/graphite.exp: Fix comments. + * testsuite/gfortran.dg/graphite/graphite.exp: Trigger actions + based on the file names as in the C testsuite. + * testsuite/gfortran.dg/graphite/block-1.f90: Fix patterns. + * testsuite/gfortran.dg/graphite/block-2.f: Same. + * testsuite/gfortran.dg/graphite/block-3.f90: Same. + * testsuite/gfortran.dg/graphite/block-4.f90: Same. + * testsuite/gfortran.dg/graphite/id-1.f90: Same. + * testsuite/gfortran.dg/graphite/id-2.f90: Same. + * testsuite/gfortran.dg/graphite/id-3.f90: Same. + * testsuite/gfortran.dg/graphite/id-4.f90: Same. + * testsuite/gfortran.dg/graphite/id-6.f: Same. + * testsuite/gfortran.dg/graphite/id-9.f: Same. + * testsuite/gfortran.dg/graphite/interchange-1.f: Same. + * testsuite/gfortran.dg/graphite/interchange-2.f: Same. + * testsuite/gfortran.dg/graphite/scop-1.f: Same. + +2009-07-14 Sebastian Pop <sebastian.pop@amd.com> + + * sese.c (expand_scalar_variables_call): New. + (expand_scalar_variables_ssa_name): Handle calls in expander. + +2009-07-13 Sebastian Pop <sebastian.pop@amd.com> + + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-6.c: + Expect to see the pattern twice. + * testsuite/gcc.dg/graphite/interchange-0.c: Un-XFAIL. + * testsuite/gcc.dg/graphite/interchange-5.c: Same. + * testsuite/gcc.dg/graphite/interchange-6.c: Same. + +2009-07-13 Sebastian Pop <sebastian.pop@amd.com> + + * testsuite/gcc.dg/graphite/id-10.c: New. + * testsuite/gcc.dg/graphite/id-12.c: New. + * testsuite/gfortran.dg/graphite/id-7.f: New. + * testsuite/gfortran.dg/graphite/id-8.f: New. + +2009-07-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (pdr_add_data_dimensions): Fix division by + zero. + +2009-07-13 Sebastian Pop <sebastian.pop@amd.com> + + * sese.c (rename_variables_in_stmt): Call fold_convert during renaming. + +2009-07-13 Sebastian Pop <sebastian.pop@amd.com> + + * sese.c (expand_scalar_variables_stmt): Avoid unnecessary expansion. + +2009-07-10 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (pdr_add_memory_accesses): Fix order of + building PDR subscripts. + +2009-07-10 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (pdr_add_data_dimensions): Fix the + computation of array sizes. + +2009-07-10 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (add_param_constraints): Disabled. + +2009-07-10 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-dependences.c (map_into_dep_poly, map_dr_into_dep_poly, + build_pairwise_constraint, dr_equality_constraints, + build_pairwise_scheduling_equality, + build_pairwise_scheduling_inequality, lexicographically_gt_p, + build_lexicographically_gt_constraint, dependence_polyhedron, + graphite_legal_transform_dr, graphite_carried_dependence_level_k): + Move from NNC_Polyhedron to C_Polyhedron. + * graphite-interchange.c (compute_array_size_poly, + gather_access_strides): Dito. + * graphite-poly.c (apply_poly_transforms, new_poly_dr, free_poly_bb, + free_scop, pbb_number_of_iterations): Dito. + * graphite-poly.h (struct poly_dr, pdr_nb_subscripts, struct poly_bb, + pbb_dim_iter_domain, struct scop): Dito. + * graphite-ppl.c (new_Constraint_System_from_Cloog_Matrix, + new_Cloog_Domain_from_ppl_Polyhedron, + new_Cloog_Domain_from_ppl_Pointset_Powerset, ppl_set_coef_gmp, + ppl_insert_dimensions_pointset, ppl_insert_dimensions_pointset, + ppl_strip_loop, ppl_strip_loop, ppl_print_polyhedron_matrix, + ppl_print_powerset_matrix, debug_ppl_polyhedron_matrix, + debug_ppl_powerset_matrix, ppl_read_polyhedron_matrix): Dito. + * graphite-ppl.h (ppl_Pointset_Powerset_C_Polyhedron_t, + new_C_Polyhedron_from_Cloog_Matrix, ppl_print_powerset_matrix, + debug_ppl_powerset_matrix, ppl_insert_dimensions_pointset): Dito. + * graphite-sese-to-poly.c (build_pbb_scattering_polyhedrons, + build_loop_iteration_domains, ppl_constraint_type_from_tree_code, + add_condition_to_domain, add_condition_to_pbb, build_scop_context, + build_scop_iteration_domain, build_poly_dr): Dito + +2009-07-09 Sebastian Pop <sebastian.pop@amd.com> + + * testsuite/gcc.dg/graphite/graphite.exp: Added a rule to execute + run-id-*.c files. + * testsuite/gcc.dg/graphite/run-id-1.c: New. + +2009-07-09 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (build_loop_iteration_domains): Add the + positivity constraint on the symbolic number of iterations. + +2009-07-09 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (build_loop_iteration_domains): Rewrite. + +2009-07-09 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-clast-to-gimple.c (build_scop_context): Removed. + (build_cloog_prog): Directly use SCOP_CONTEXT. + * graphite-poly.c (new_scop): Initialize SCOP_CONTEXT. + (free_scop): Free SCOP_CONTEXT. + (print_scop_context): New. + (print_scop): Call print_scop_context. + (debug_scop_context): New. + * graphite-poly.h (print_scop_context, debug_scop_context): Declared. + (struct scop): Added field context. + (SCOP_CONTEXT): New. + * graphite-sese-to-poly.c (add_param_constraints): New. + (build_scop_context): New. + (build_poly_scop): Call build_scop_context. + +2009-07-09 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (gmp_cst_to_tree): Moved... + * graphite-ppl.c (ppl_set_inhomogeneous_gmp, ppl_set_coef_gmp): New. + (ppl_set_inhomogeneous, ppl_set_coef): Moved... + * graphite-ppl.h: Include double-int.h and tree.h. + (ppl_set_inhomogeneous_gmp, ppl_set_coef_gmp): Declared. + (ppl_set_inhomogeneous, ppl_set_coef): ...here. + (gmp_cst_to_tree): ...here. Reimplemented using mpz_get_double_int. + (tree_int_to_gmp, ppl_set_inhomogeneous_tree, ppl_set_coef_tree): New. + +2009-07-09 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (clast_to_gcc_expression_red): Generate + POINTER_PLUS_EXPR for pointer types. + (clast_to_gcc_expression): Same. + +2009-07-09 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (print_scattering_function): Early return when + PBB_TRANSFORMED_SCATTERING is not initialized. + (print_pbb_domain): Early return when PBB_DOMAIN is not initialized. + +2009-07-08 Sebastian Pop <sebastian.pop@amd.com> + + * tree-parloops.c (analyze_reduction_list): Remove unused variable + to fix bootstrap. + +2009-07-08 Razya Ladelsky <razya@il.ibm.com> + + * tree-parloops.c (analyze_reduction_list): Change return + value to void. + (try_create_reduction_list): Move the call to + analyze_reduction_list to the beginining. + Call reduction_phi with analyzed_reductions as argument + instead of reduction_list. + +2009-07-08 Tobias Grosser <grosser@fim.uni-passau.de> + + * Merge from mainline (r148296:149346) + +2009-07-07 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-scop-detection.c (graphite_can_represent_init): New. + (graphite_can_represent_scev): Call graphite_can_represent_init: + check that the initial value does not contain multiplications of + parameters. + (stmt_has_simple_data_refs_p): New. + (stmt_simple_for_scop_p): Call stmt_simple_for_scop_p. + (is_simple_operand): Fix formatting. + * graphite-sese-to-poly.c (try_generate_gimple_bb): Fix formatting. + +2009-07-07 Sebastian Pop <sebastian.pop@amd.com> + + * testsuite/gcc.dg/graphite/id-13.c: New. + * graphite-sese-to-poly.c (graphite_stmt_p): Do not call + analyze_scalar_evolution, use scalar_evolution_in_region. + (scan_tree_for_params_right_scev): Add extra assert. + (parameter_index_in_region_1): Split from parameter_index_in_region. + (idx_record_params): Use scalar_evolution_in_region. + (find_params_in_bb): Same. + (find_scop_parameters): Same. + (build_loop_iteration_domains): Same. + (create_linear_expr_from_tree): Same. + * sese.c (scalar_evolution_in_region): New. + * sese.h (scalar_evolution_in_region): Declared. + (defined_in_sese_p): New. + * tree-scalar-evolution.c (compute_overall_effect_of_inner_loop): Not + static anymore. + * tree-scalar-evolution.h (compute_overall_effect_of_inner_loop): + Declared. + +2009-07-07 Sebastian Pop <sebastian.pop@amd.com> + + * Makefile.in: Replace dependences on tree-chrec.h with SCEV_H. + TREE_DATA_REF_H also implies SCEV_H. + +2009-07-07 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (print_scop_params): New. + (print_scop): Call print_scop_params. + (debug_scop_params): New. + * graphite-poly.h (print_scop_params, debug_scop_params): Declared. + +2009-07-07 Li Feng <nemokingdom@gmail.com> + + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-4.c: New. + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-5.c: New. + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-6.c: New. + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-7.c: New. + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-8.c: New. + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-9.c: New. + +2009-07-07 Li Feng <nemokingdom@gmail.com> + + * graphite-clast-to-gimple.c (mark_loops_parallel): Dump information + for dependency checking part. + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-1.c: Add + tests for dependency checking. + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-2.c: Ditto. + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-3.c: Ditto. + * testsuite/gcc.dg/graphite/graphite_autopar/graphite_autopar.exp: Add + flag -fdump-tree-graphite-all for autopar testsuites. + +2009-07-06 Sebastian Pop <sebastian.pop@amd.com> + + * Makefile.in (tree-ssa-loop-manip.o): Depends on langhooks.h. + * tree-parloops.c (rewrite_phi_with_iv, rewrite_all_phi_nodes_with_iv, + canonicalize_loop_ivs): Moved... + * tree-ssa-loop-manip.c: ... here. Include langhooks.h. + +2009-07-06 Sebastian Pop <sebastian.pop@amd.com> + + * tree-parloops.c (try_create_reduction_list): Pass an extra + argument analyzed_reductions. Call analyze_reduction_list. + (gen_parallel_loop): Do not call analyze_reduction_list. + (parallelize_loops): Init and finalize analyzed_reductions. + +2009-07-06 Li Feng <nemokingdom@gmail.com> + + * testsuite/gcc.dg/graphite/graphite_autopar/graphite_autopar.exp: + Added flag -fno-loop-strip-mine for autopar testcase. + +2009-07-04 Li Feng <nemokingdom@gmail.com> + + * graphite-dependences.c (graphite_carried_dependence_level_k): Use + transformed scattering dimension instead of unmatch orignal when + calling dependence_polyhedron. + +2009-06-30 Sebastian Pop <sebastian.pop@amd.com> + + * opts.c (decode_options): Enable flag_loop_strip_mine at -O2. + +2009-06-30 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (pbb_number_of_iterations): Check for returned + value 1 from ppl_Pointset_Powerset_NNC_Polyhedron_maximize. + +2009-06-30 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-blocking.c (pbb_strip_mine_profitable_p): New. + (pbb_do_strip_mine): Call pbb_strip_mine_profitable_p. + * graphite-poly.c (pbb_number_of_iterations): New. + * graphite-poly.h (pbb_number_of_iterations): Declared. + (pbb_iterator_dim, pbb_parameter_dim): New. + +2009-06-29 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (graphite_create_new_loop): Revert the + last commit on type of lower and upper bound of loops. + +2009-06-29 Li Feng <nemokingdom@gmail.com> + + * Makefile.in (graphite-clast-to-gimple.o): Added dependence on + graphite-dependences.h. + * graphite-clast-to-gimple.c (new_bb_pbb_def): New. + (mark_bb_with_pbb): New. + (get_stmtfor_depth): New. + (find_pbb_via_hash): New. + (dependency_in_loop_p): New. + (mark_loops_parallel): New. + (free_aux_in_new_loops): New. + (translate_clast): Add parameter BB_PBB_MAPPING. Mark newly created + bb with it's relevant pbb. Mark newly created loops. Remove mark + innermost loop parallel without checking. + (gloog): Add parameter BB_PBB_MAPPING. + * graphite-clast-to-gimple.h (struct bb_pbb_def): New. + (gloog): Change declaration. + (mark_loop_parallel): Make extern. + (free_aux_in_new_loops): Declare. + (bb_pbb_map_hash): New. + (eq_bb_pbb_map): New. + * graphite.c (graphite_transform_loops): Added BB_PBB_MAPPING. Trigger + auto parallelization when flag_graphite_force_parallel is set. + (graphite_finalize): Added free_aux_in_new_loops. + * tree-parloops.c (parallelize_loops): Only generate parallel code for + the innermost loop that marked parallel. Use + flag_graphite_force_parallel instead of loop->can_be_parallel. + (loop_parallel_p): Move inner most checking out of function. + +2009-06-26 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (graphite_create_new_loop): Make the + type of lower and upper bound of loops signed long int. + +2009-06-26 Sebastian Pop <sebastian.pop@amd.com> + + * cfgloopmanip.c (create_empty_loop_on_edge): Gimplify the loop exit + expression outside the loop. + +2009-06-26 Sebastian Pop <sebastian.pop@amd.com> + + * gcc.dg/graphite/interchange-8.c: New. + +2009-06-26 Sebastian Pop <sebastian.pop@amd.com> + + * gcc.dg/graphite/interchange-0.c: XFailed. + * gcc.dg/graphite/interchange-5.c: XFailed. + * gcc.dg/graphite/interchange-6.c: XFailed. + +2009-06-26 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-interchange.c (compute_array_size_poly): The end of the + recursion should return 1. + +2009-06-26 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-interchange.c (compute_array_size_cstr): Allow the + subscript multiplier to be -1. + (compute_array_size): Use PDR_DATA_CONTAINER and not PDR_ACCESSES. + * graphite-poly.c (new_poly_dr): Takes an extra argument for the + data_container. Initializes PDR_DATA_CONTAINER. + (print_pdr_access_layout): New. + (print_pdr): Call print_pdr_access_layout. Print PDR_DATA_CONTAINER. + * graphite-poly.h (struct poly_dr): Adjust comment. Add a new field + data_container. + (PDR_DATA_CONTAINER): New. + (new_poly_dr): Update declaration. + * graphite-sese-to-poly.c (pdr_add_data_dimensions): New. + (build_poly_dr): Call pdr_add_data_dimensions. + +2009-06-26 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.h (struct poly_dr): Fix comment. + * graphite-sese-to-poly.c (pdr_add_alias_set): New. + (pdr_add_memory_accesses): New. + (build_poly_dr): Call pdr_add_memory_accesses and pdr_add_alias_set. + +2009-06-26 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (print_pdrs, debug_pdrs): New. + (print_pbb): Add call to print_pdrs. + * graphite-poly.h (print_pdrs, debug_pdrs): Declared. + +2009-06-24 Konrad Trifunovic <konrad.trifunovic@gmail.com> + Li Feng <nemokingdom@gmail.com> + + * graphite-dependences.c (graphite_carried_dependence_level_k): New. + (dependency_between_pbbs_p): New. + (lexicographically_gt_p): Assure !empty_p before polyhedron + intersection assign. + (build_lexicographically_gt_constraint): Correct lexicographically + judging. + * graphite-dependences.h: New. + * Makefile.in (graphite-dependences.o): Add graphite-dependences.h. + +2009-06-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (print_clast_stmt): New. + (gloog): Print to dump_file the generated clast. + * graphite-clast-to-gimple.h (print_clast_stmt): Declared. + * graphite-interchange.c (pbb_do_interchange): Fix dump formatting. + +2009-06-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (extend_scattering): Increment + PBB_NB_LOCAL_VARIABLES by the number of added dimensions. + +2009-06-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-interchange.c (compute_array_size_poly): Added exit of + recursion condition. Continue iterating even after the first equality. + (compute_array_size): Same. + +2009-06-24 Li Feng <nemokingdom@gmail.com> + + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-1.c: Update + -fdump-tree-final_cleanup to -fdump-tree-optimized. + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-2.c: Ditto. + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-3.c: Ditto. + * testsuite/gcc.dg/graphite/graphite_autopar/graphite_autopar.exp: Ditto. + +2009-06-23 Sebastian Pop <sebastian.pop@amd.com> + + * sese.c (expand_scalar_variables_stmt): Expand scalar variables + only when the use verifies is_gimple_reg. + +2009-06-23 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (build_cloog_prog): Fix memory corruption. + Allocate scaldims after call to unify_scattering_dimensions. + +2009-06-23 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (translate_clast): Fix memory leak. + +2009-06-23 Sebastian Pop <sebastian.pop@amd.com> + Albert Cohen <albert.cohen@inria.fr> + + * graphite-blocking.c (pbb_strip_mine_loop_depth): Do not use local + variables for the strip mining. + +2009-06-23 Sebastian Pop <sebastian.pop@amd.com> + Pranav Garg <pranav.garg2107@gmail.com> + + * Makefile.in (OBJS-common): Added graphite-blocking.o. + (graphite-sese-to-poly.o): Moved down to be in lexicographical order. + (graphite-blocking.o): New rule. + (graphite-poly.o, graphite-ppl.o): Moved to be in lexicographical order. + * graphite-blocking.c: New. + * graphite-poly.c (apply_poly_transforms): Call scop_do_strip_mine for + flag_loop_strip_mine. + (psct_scattering_dim_for_loop_depth): New. + * graphite-poly.h (scop_do_strip_mine): Declared. + (psct_add_local_variable): Increment PBB_NB_LOCAL_VARIABLES. + * tree-ssa-loop.c (gate_graphite_transforms): Do not fail when using + flag_loop_strip_mine. + +2009-06-23 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (extend_scattering): Avoid initializing and freeing + a GMP value and a PPL coefficient at each iteration of a loop. + +2009-06-23 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-dependences.c (dependence_polyhedron): Do not use + pbb_nb_scattering_dims anymore. Use pbb_nb_scattering_orig and + pbb_nb_scattering_transform. + (graphite_legal_transform_dr): Same. + * graphite-poly.c (extend_scattering): Same. + (unify_scattering_dimensions): Same. + (print_scattering_function): Same. + (new_poly_bb): Initialize PBB_NB_SCATTERING_TRANSFORM and + PBB_NB_LOCAL_VARIABLES. + * graphite-poly.h (pbb_nb_scattering): Removed declaration. + (struct poly_bb): Added nb_local_variables and nb_scattering_transform. + (PBB_NB_LOCAL_VARIABLES, PBB_NB_SCATTERING_TRANSFORM): New. + (pbb_nb_scattering_orig, pbb_nb_scattering_transform): New. + (pbb_nb_scattering_dims, pbb_nb_scattering): Removed. + (pbb_nb_scattering_transform): New. + (pbb_nb_local_vars): Return PBB_NB_LOCAL_VARIABLES. + (psco_scattering_dim): Add assert on parameters. + (psct_scattering_dim): Same. + (psct_scattering_dim_for_loop_depth): Declared. + (psct_local_var_dim): New. + (psco_iterator_dim, psco_parameter_dim): Add assert on parameters. + (psct_iterator_dim, psct_parameter_dim): Same. To maintain the + correct layout, call pbb_nb_local_vars. + (psct_add_local_variable, psct_add_scattering_dimension): New. + * graphite-sese-to-poly.c (build_pbb_scattering_polyhedrons): + Initialize PBB_NB_SCATTERING_TRANSFORM. + +2009-06-23 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-ppl.c (set_inhomogeneous): Renamed ppl_set_inhomogeneous. + (set_coef): Renamed ppl_set_coef. + * graphite-ppl.h (ppl_set_inhomogeneous, ppl_set_coef): Declared. + +2009-06-23 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-dependences.c (build_pairwise_scheduling_inequality): Don't + test a boolean against 1. + * graphite-interchange.c (pbb_interchange_loop_depths): Do not build + a new polyhedron for the PBB_TRANSFORMED_SCATTERING. + (pbb_do_interchange): Returns true when a transform has been performed. + (scop_do_interchange): Same. + * graphite-poly.c (apply_poly_transforms): Use the return value of + scop_do_interchange. + * graphite-poly.h (scop_do_interchange): Update declaration. + +2009-06-23 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-clast-to-gimple.c (gloog): Reset loop->aux right + after last use. + * sese.c (sese_reset_aux_in_loops): New. + * sese.h (sese_reset_aux_in_loops): New. + +2009-06-19 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (scan_tree_for_params_int): Pass in the + multiplier and multiply the constant by the multiplier. + (scan_tree_for_params): Bound the multiplier to its MULT_EXPR. + (build_poly_dr): Do not use the multiplier to define the subscript. + +2009-06-19 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (new_poly_dr): Pass an extra argument for the + compiler's data reference. Initialize PDR_CDR. + (print_pdr): Call dump_data_reference. + * graphite-poly.h (struct poly_dr): Rename black_box into pbb. + Add compiler_dr field. + (PDR_BB): Renamed PDR_PBB. + (PDR_CDR): New. + * graphite-sese-to-poly.c (build_poly_dr): Pass to new_poly_dr + GCC's data reference representation. + * tree-data-ref.c (debug_data_references, debug_data_reference): New. + * tree-data-ref.h (debug_data_references, debug_data_reference): Decl. + +2009-06-19 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (print_scattering_function): Also print the layout. + * graphite-poly.h (pbb_nb_local_vars): New. + +2009-06-19 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (print_pbb_domain): Also print the layout names. + +2009-06-19 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (print_pdr, debug_pdr): New. + * graphite-poly.h (print_pdr, debug_pdr): Declared. + (PDR_BASE): Removed. + +2009-06-18 Sebastian Pop <sebastian.pop@amd.com> + + * gcc/testsuite/gcc.dg/graphite/interchange-{1..7}.c: New avatars of + ltrans-{1..6,8}.c. + +2009-06-18 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-interchange.c (compute_subscript): Allow also -1 in the + subscript identification column. + (pbb_do_interchange): Print to dump_file that some loops "will be + interchanged". Rely on that chain of characters in the testcases. + * gcc.dg/graphite/interchange-0.c: New. + * gcc.dg/graphite/graphite.exp: Iterate over the testsuite + interchange-*.c files and compile them with -floop-interchange. + +2009-06-18 Pranav Garg <pranav.garg2107@gmail.com> + + * graphite-interchange.c (interchange_profitable_p): Renamed + pbb_interchange_profitable_p. + +2009-06-18 Sebastian Pop <sebastian.pop@amd.com> + Harsha Jagasia <harsha.jagasia@amd.com> + Pranav Garg <pranav.garg2107@gmail.com> + + * graphite-interchange.c (interchange_profitable_p): Make static. + (pbb_interchange_loop_depths, pbb_do_interchange, + scop_do_interchange): New. + * graphite-poly.c (apply_poly_transforms): Call scop_do_interchange + for flag_loop_interchange. + * graphite-poly.h (scop_do_interchange): Declared. + * tree-ssa-loop.c (gate_graphite_transforms): Do not fail when + flag_loop_interchange is used. + +2009-06-18 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-dependences.c (dependence_polyhedron): Update use of + pbb_nb_scattering_dims. + * graphite-poly.h (pbb_nb_scattering_dims): Do not pass SCOP. + (pbb_nb_scattering): Update use of pbb_nb_scattering_dims. + (psco_scattering_dim, psct_scattering_dim, psco_iterator_dim, + psct_iterator_dim, psco_parameter_dim, psct_parameter_dim): New. + +2009-06-16 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c: Cleanup foo. + +2009-06-16 Sebastian Pop <sebastian.pop@amd.com> + + * Merge from mainline (r143684:148293). + * Disabled libpcp until it gets fixed. + +2009-06-05 Sebastian Pop <sebastian.pop@amd.com> + Harsha Jagasia <harsha.jagasia@amd.com> + + * graphite-interchange.c: New. + * Makefile.in (graphite-interchange.o): New. + * graphite-poly.h (interchange_profitable_p): Declared. + * graphite-ppl.h (value_max): New. + +2009-06-04 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-dependences.c (dependence_polyhedron): Use pdr_dim. + * graphite-poly.h: Fix some comments. + (pdr_dim): New. + (pdr_scop): New. + +2009-06-04 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.h + (pdr_accessp_nb_subscripts): Renamed pdr_nb_subscripts. + (pdr_accessp_nb_iterators): Renamed pdr_dim_iter_domain. + (pdr_accessp_nb_params): Renamed pdr_nb_params. + (pdr_accessp_alias_set_dim): Renamed pdr_alias_set_dim. + (pdr_accessp_subscript_dim): Renamed pdr_subscript_dim. + (pdr_accessp_iterator_dim): Renamed pdr_iterator_dim. + (pdr_accessp_param_dim): Renamed pdr_parameter_dim. + (pbb_nb_loops): Renamed pbb_dim_iter_domain. + * graphite-clast-to-gimple.c: Same. + * graphite-dependences.c: Same. + * graphite-poly.c: Same. + * graphite-sese-to-poly.c: Same. + +2009-06-03 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (build_iv_mapping): Insert full + expressions for an IV rename, as returned by clast_to_gcc_expression. + (copy_renames): Rename new_name to expr. + * sese.c (debug_rename_elt): Same. + (get_rename): Same. + (set_rename): Same. + (sese_adjust_liveout_phis): Call force_gimple_operand before using + the information from the rename map. + (rename_variables_in_stmt): Same. + (add_loop_exit_phis): Rename new_name to expr. + (insert_loop_close_phis): Same. + (add_guard_exit_phis): Same. Call force_gimple_operand. + * sese.h (struct rename_map_elt): Rename new_name to expr. + (new_rename_map_elt): Same. + +2009-06-03 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (build_iv_mapping): Use set_rename. + * sese.c (set_rename): Make it extern. + * sese.h (set_rename): Declared. + +2009-06-03 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (extend_scattering): Free values. + * graphite-ppl.c (new_Cloog_Domain_from_ppl_Pointset_Powerset): + Free iterators. + (ppl_print_powerset_matrix): Same. + * graphite-scop-detection.c (free_scops_1): New. + (limit_scops): Call free_scops_1. + * graphite-sese-to-poly.c (build_scop_bbs_1): Free dom. + (build_poly_dr): Free PPL coefficients. + * tree-parloops.c (rewrite_all_phi_nodes_with_iv): Free bbs. + +2009-06-02 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-dependences.c: New. + * graphite-data-ref.c: Removed. + * graphite-data-ref.h: Removed. + * Makefile.in (graphite-data-ref.o): Removed. + (graphite-dependences.o): Added. + * graphite-clast-to-gimple.c: Remove dependence on graphite-data-ref.h. + * graphite-poly.c: Same. + Move the data dependence testing to graphite-dependences.c. + +2009-05-19 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-scop-detection.c (graphite_can_represent_loop): Renamed + from graphite_cannot_represent_loop. Code refactored. + (scopdet_basic_block_info): Call graphite_can_represent_loop. + +2009-05-17 Li Feng <nemokingdom@gmail.com> + + * testsuite/gcc.dg/graphite/graphite_autopar/graphite_autopar.exp: + Cover all the testcases (not only the filtered ones). + +2009-05-17 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-scop-detection.c (stmt_simple_for_scop_p): Remove + unnecessary check. Update comments. Move check for REAL_TYPE here. + (harmful_stmt_in_bb): Remove checks for conditions. This is already + done in (stmt_simple_for_scop_p). + +2009-05-14 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (print_global_statistics): New. + (print_graphite_scop_statistic): New. + (print_graphite_statistics): New. + (graphite_initialize, graphite_transform_loops): Print statistics. + * graphite-scop-detection (build_scops): Print statistics. + (print_graphite_scop_statistics): New. + (print_graphite_statistics): New. + +2009-05-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (struct clast_name_index): Removed. + (debug_clast_name_index): Removed. + (debug_clast_name_indexes_1): Removed. + (debug_clast_name_indexes): Removed. + (clast_name_index_elt_info): Removed. + (eq_clast_name_indexes): Removed. + (clast_name_to_index): Removed. + (new_clast_name_index): Removed. + (save_clast_name_index): Removed. + (save_var_name): Moved... + (init_sese_params_index): Removed. + (clast_name_to_gcc): Remove use of name_tree. + (initialize_cloog_names): Same. + (gloog): Do not call init_sese_params_index. + * graphite-sese-to-poly.c (save_var_name): ...here. + (parameter_index_in_region): New. + * sese.c (new_sese): Initialize SESE_PARAMS_NAMES. + (parameter_index_in_region): Removed. + (is_parameter): Remove use of name_tree. + * sese.h (struct name_tree): Removed. + (struct sese): Remove use of name_tree. New field params_names. + (SESE_PARAMS_NAMES): New. + (SESE_PARAMS): Remove duplicate. + (parameter_index_in_region): Removed. + (sese_nb_params): Remove use of name_tree. + (struct clast_name_index): New. + (new_clast_name_index): New. + (clast_name_to_index): New. + (save_clast_name_index): New. + (debug_clast_name_index): New. + (debug_clast_name_indexes_1): New. + (debug_clast_name_indexes): New. + (clast_name_index_elt_info): New. + (eq_clast_name_indexes): New. + +2009-05-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (compute_cloog_iv_types_1): Call + pbb_to_depth_to_oldiv. Remove call to oldiv_for_loop. + (graphite_loop_normal_form): Do not pass region. Do not + initialize SESE_OLDIVS. + (build_graphite_loop_normal_form): Update call to + graphite_loop_normal_form. + * sese.c (debug_oldivs): Removed. + (new_sese): Do not initialize SESE_OLDIVS. + (free_sese): Do not free SESE_OLDIVS. + (oldiv_for_loop): Removed. + * sese.h (struct sese): Remove old_ivs. + (SESE_OLDIVS): Removed. + (oldiv_for_loop): Removed. + +2009-05-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (clast_name_to_gcc): Pass newivs, + remove ivstack. Remove call to loop_iv_stack_get_iv_from_name, + replaced by a call to newivs_to_depth_to_newiv. + (clast_to_gcc_expression): Pass newivs, remove ivstack. + (clast_to_gcc_expression_red): Same. + (gcc_type_for_clast_expr): Same. + (gcc_type_for_clast_eq): Same. + (graphite_translate_clast_equation): Same. + (graphite_create_guard_cond_expr): Same. + (graphite_create_new_guard): Same. + (graphite_create_new_loop): Same. + (build_iv_mapping): Same. + (translate_clast): Same. + (gloog): Same. + (loop_iv_stack_patch_for_consts): Removed. * + sese.c (iv_stack_entry_is_constant): Removed. + (iv_stack_entry_is_iv): Removed. + (loop_iv_stack_push_iv): Removed. + (loop_iv_stack_insert_constant): Removed. + (loop_iv_stack_pop): Removed. + (loop_iv_stack_get_iv): Removed. + (loop_iv_stack_get_iv_from_name): Removed. + (debug_loop_iv_stack): Removed. + (free_loop_iv_stack): Removed. + (loop_iv_stack_remove_constants): Removed. * + sese.h (iv_stack_entry_kind): Removed. + (iv_stack_entry_data_union): Removed. + (iv_stack_entry_struct): Removed. + (iv_stack_entry_p): Removed. + (debug_oldivs, debug_loop_iv_stack, loop_iv_stack_insert_constant, + loop_iv_stack_get_iv_from_name, loop_iv_stack_push_iv, + loop_iv_stack_get_iv, loop_iv_stack_remove_constants, + loop_iv_stack_pop, free_loop_iv_stack): Removed. + (gbb_loop_at_index): Fix indenting. + (gbb_loop_index): Removed. + +2009-05-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (clast_name_to_gcc): Do not use strcmp. + Call clast_name_to_index. + +2009-05-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (clast_name_to_gcc): Pass region, + do not pass params. Get params from SESE_PARAMS. + (clast_to_gcc_expression): Same. + (clast_to_gcc_expression_red): Same. + (gcc_type_for_clast_eq): Same. + (graphite_translate_clast_equation): Same. + (graphite_create_new_loop): Same. + * sese.c (rename_variables_in_stmt): Fix comment. + +2009-05-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (graphite_create_new_loop): Pass + newivs_index. + Call save_clast_name_index. + (translate_clast): Pass newivs_index. + (gloog): Create and free newivs_index. + +2009-05-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (clast_name_index): New structure. + (clast_name_index_p): New type. + (debug_clast_name_index): New. + (debug_clast_name_indexes_1): New. + (debug_clast_name_indexes): New. + (clast_name_index_elt_info): New. + (eq_clast_name_indexes): New. + (clast_name_to_index): New. + (new_clast_name_index): New. + (save_clast_name_index): New. + (init_sese_params_index): New. + (gloog): Call init_sese_params_index. + * graphite-clast-to-gimple.h (debug_clast_name_indexes): Declared. + * sese.c (new_sese): Initialize SESE_PARAMS_INDEX. + (free_sese): Free SESE_PARAMS_INDEX. + * sese.h (struct sese): Add params_index. + (SESE_PARAMS_INDEX): New. + +2009-05-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (newivs_to_depth_to_newiv): New. + (graphite_create_new_loop): Pass the newivs vector. Push the + newly created IV to newivs. + (translate_clast): Pass the newivs vector. + (gloog): Create and destroy the newivs vector. + +2009-05-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (pbb_to_depth_to_oldiv): New. + (graphite_loop_normal_form): Initialize loop->aux with the unique + IV that has been created. + +2009-05-13 Tobias Grosser <grosser@fim.uni-passau.de> + + * tree-chrec.c (evolution_function_right_is_integer_cst): Allow + scev with parameters in the base part. They where forbidden + exidently. + +2009-05-11 Li Feng <nemokingdom@gmail.com> + + * testsuite/gcc.dg/graphite/graphite.exp: Set different default + compile options by file names. + * testsuite/gcc.dg/graphite/block{0-6}.c: Remove dg-option line. + * testsuite/gcc.dg/graphite/id-{1-9}.c: Ditto. + * testsuite/gcc.dg/graphite/scop-{0-20}.c: Ditto. + * testsuite/gcc.dg/graphite/scop-matmult.c: Ditto. + +2009-05-08 Li Feng <nemokingdom@gmail.com> + + * testsuite/gcc.dg/graphite/graphite_autopar/graphite_autopar.exp: New. + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-1.c: New. + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-2.c: New. + * testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-3.c: New. + +2009-05-07 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-scop-detection (build_scops_1): Fix little bug introduced + by final cleanup. + +2009-05-07 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-scop-detection.c (graphite_can_represent_scev): Only + allow integer constant strides. + (graphite_can_represent_expr): Depend on outermost_loop. + (stmt_simple_memref_p, graphite_cannot_represent_loop, + harmful_stmt_in_bb, is_simple_operand, stmt_simple_for_scop_p, + build_scops_1): Same. + (scopdet_basic_block_info): Same and insert layered SCoP + detection. + (try_generate_gimple_bb): Cleanup. + (build_scops): Enable data references. + + * testsuite/gcc.dg/graphite/id-5.c: New. + * testsuite/gcc.dg/graphite/id-9.c: New. + * tree-chrec.c (evolution_function_right_is_integer_cst): New. + * tree-chrec.h (evolution_function_right_is_integer_cst): New. + +2009-05-06 Tobias Grosser <grosser@fim.uni-passau.de> + + * sese.c (expand_scalar_variables_ssa_name): Only build expressions, + that we have not yet built for this SCoP. + +2009-05-06 Tobias Grosser <grosser@fim.uni-passau.de> + + * sese.c (expand_scalar_variables_expr): Fix expand_scalar_variables + for complex numbers. + +2009-05-06 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-ppl.c: Fix build if cloog is not available. + +2009-05-04 Li Feng <nemokingdom@gmail.com> + + * tree-parloops.c (loop_parallel_p): Remove construction of + NITER and REDUCTION_LIST. + (try_get_loop_niter): New. + (try_create_reduction_list): New. + (parallelize_loops): Bypass the failed checkings in autopar + when can_be_parallel in loop structure is set to true. + +2009-05-01 Tobias Grosser <grosser@fim.uni-passau.de> + + * testsuite/gcc.dg/graphite/id-6.c: Update testcase. + * testsuite/gcc.dg/graphite/scop-3.c: Dito. + +2009-05-01 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-scop-detection.c (stmt_simple_for_scop_p): + Enable EQ_EXPR and NE_EXPR again. + +2009-04-30 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-scop-detection.c (graphite_can_represent_scev): + Add check if scev is affine multivariate. + (harmful_stmt_in_bb): Check if we can represent the conditions. + (scopdet_basic_block_info (basic_block bb, VEC): Pass the loop to + harmful_stmt_in_bb. + * testsuite/gcc.dg/graphite/id-7.c: New. + +2009-04-30 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-sese-to-poly.c (bb_contains_non_iv_scalar_phi_nodes): + Check all bbs in region, not only the bbs that are represented in + GRAPHITE. + (build_poly_scop): Add newline. + * testsuite/gcc.dg/graphite/id-8.c: New. + +2009-04-30 Li Feng <nemokingdom@gmail.com> + + * cfgloop.c (alloc_loop): Initialize can_be_parallel to false + when loop initialize. + * cfgloop.h (struct loop): Introduce flag can_be_parallel. + * common.opt: Declare flag_graphite_force_parallel. + * graphite-clast-to-gimple.c (translate_clast): Mark the innermost + loop parallel. + * graphite-poly.c (apply_poly_transforms): Introduce + flag_graphite_force_parallel. + * tree-ssa-loop.c (gate_graphite_transforms): ditto. + * toplev.c (process_options): ditto and replace a not correctly + encoded space. + +2009-04-30 Li Feng <nemokingdom@gmail.com> + + * graphite-clast-to-gimple.c (loop_iv_stack_patch_for_consts): + Change the call of gbb_loop_at_index and/or gbb_loop_index due + to the redefinition. + (compute_cloog_iv_types_1): ditto. + (build_iv_mapping): ditto. + * graphite-sese-to-poly.c (new_gimple_bb): Remove GBB_LOOPS related + initialization. + (free_gimple_bb): Removed GBB_LOOPS related free part. + (build_bb_loops): Removed. + * sese.h (struct gimple_bb): Removed loops. + (GBB_LOOPS): Removed. + (gbb_loop_at_index): Instead of using GBB_LOOPS, we use sese instead. + (gbb_loop_index): ditto. + +2009-04-24 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-scop-detection.c (graphite_can_represent_scev): Do not + allow non constant strides. + * testsuite/gcc.dg/graphite/scop-20.c: New. + +2009-04-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-scop-detection.c (dot_all_scops): Fix system call + return value warning. + (dot_scop): Same. + +2009-04-24 Sebastian Pop <sebastian.pop@amd.com> + + * testsuite/gcc.dg/graphite/id-6.c: Fix pattern. + * testsuite/gcc.dg/graphite/scop-3.c: Same. + +2009-04-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (map_into_dep_poly, map_dr_into_dep_poly, + build_pairwise_constraint, dr_equality_constraints, + build_pairwise_scheduling_equality, + build_pairwise_scheduling_inequality, lexicographically_gt_p, + build_lexicographically_gt_constraint, dependence_polyhedron, + graphite_legal_transform_dr, graphite_legal_transform_bb, + graphite_legal_transform): New. + * graphite-poly.h (graphite_legal_transform): Declared. + * graphite-sese-to-poly.c (build_poly_scop): Call to + graphite_legal_transform is disabled for the moment. + +2009-04-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.h (pbb_nb_scattering_dims): New. + (pbb_nb_scattering): Use it. + +2009-04-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-ppl.c (ppl_insert_dimensions_pointset): Add + Pointset_Powerset version of ppl_insert_dimensions. + * graphite-ppl.h (ppl_insert_dimensions_pointset): Declared. + +2009-04-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-ppl.c (ppl_insert_dimensions): Fix formatting. + +2009-04-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.h: Fix comment. + +2009-04-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (build_poly_dr): Fix data ref multiplier. + +2009-04-24 Tobias Grosser <grosser@fim.uni-passau.de> + + * sese.c (expand_scalar_variables_stmt): Only iterate over the old + statements. + +2009-04-24 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-sese-to-poly.c (var_used_in_not_loop_header_phi_node): New. + (graphite_stmt_p): Represent bbs necessary to build the phi nodes of + conditions. + +2009-04-20 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-scop-detection.c (stmt_simple_for_scop_p): Do not + handle EQ_EXPR and NE_EXPR. + +2009-04-17 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-poly.h (poly_dr): Fix comment. + +2009-04-09 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-poly.c (new_poly_bb): Do not initialize PBB_DOMAIN + with a zero dimension polyhedron. + (find_scop_parameters): Move the call to scop_set_nb_params here. + (build_loop_iteration_domains): Store in loop->aux the iteration + domain polyhedron. + (build_scop_iteration_domain): Fix PBB_DOMAIN for bbs not surrounded + by any loop in scop. + (build_poly_scop): Do not call scop_set_nb_params. + +2009-04-09 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-sese-to-poly.c (add_condition_to_pbb): Pass code to + add_condition_to_domain not GT_EXPR. + +2009-04-09 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-ppl.c (debug_ppl_powerset_matrix): New. + * graphite-ppl.h (debug_ppl_powerset_matrix): New. + * graphite-sese-to-poly.c (add_condition_to_pbb): Use + upper_bound_assign to calculate unions. + * testsuite/gcc.dg/graphite/id-6.c: New. + +2009-04-09 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-scop-detection.c (canonicalize_loop_closed_ssa): Do not + handle abnormal edges. + +2009-04-09 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-poly.c (new_poly_dr, free_poly_dr): New. + (free_poly_bb): Also free poly_drs. + * graphite-poly.h (new_poly_dr, free_poly_dr): New. + (poly_dr): Polyhedron to Pointset_Powerset. + (pdr_accessp_nb_subscripts): Same. + * graphite-sese-to-poly.c (build_poly_dr): Same. And actually build + poly_drs. + +2009-04-08 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (initialize_cloog_names): Change cloog + names into more meaningful names. + +2009-04-08 Sebastian Pop <sebastian.pop@amd.com> + + * testsuite/gfortran.dg/graphite/interchange-1.c: New. + * testsuite/gfortran.dg/graphite/interchange-2.c: New. + +2009-04-08 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (graphite_loop_normal_form): Do not build + the reduction_list. + * tree-parloops.c (rewrite_phi_with_iv): New. + (rewrite_all_phi_nodes_with_iv): New. + (canonicalize_loop_ivs): Call them. + +2009-04-08 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (try_generate_gimple_bb): Use + graphite_find_data_references_in_stmt. + * tree-data-ref.c (graphite_find_data_references_in_stmt): New. + * tree-data-ref.h (graphite_find_data_references_in_stmt): Declared. + +2009-04-08 Sebastian Pop <sebastian.pop@amd.com> + + * sese.c (add_loop_exit_phis): Don't fail on non SSA_NAME renames. + +2009-04-08 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (build_scop_bbs_1): Use bb_in_sese_p + instead of bb_in_region. + (flag_bb_in_region): Same. Renamed flag_bb_in_sese. + (build_sese_conditions): Use flag_bb_in_sese. + * sese.c (register_bb_in_sese): Removed. + (new_sese): Remove initialization of SESE_REGION_BBS. + (free_sese): Do not free SESE_REGION_BBS. + * sese.h (struct sese): Remove field region_basic_blocks. + (SESE_REGION_BBS): Removed. + (bb_in_sese_p): Implement in function of bb_in_region. + +2009-04-08 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-scop-detection.c (limit_scops): Deal only with single exit + loops. + +2009-04-08 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-scop-detection.c (stmt_simple_for_scop_p): Allow NE_EXPR + and EQ_EXPR. + * graphite-sese-to-poly.c (create_linear_expr_from_tree): New. + (add_condition_to_domain): New. + (add_condition_to_pbb): New. + (add_conditions_to_domain): Cleanup and handle of NE_EXPR and EQ_EXPR. + * testsuite/gcc.dg/graphite/scop-3.c: Update number of detected SCoPs. + +2009-04-08 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-clast-to-gimple.c (build_cloog_prog): ppl_Polyhedron -> + ppl_Pointset_Powerset. + * graphite-poly.c (new_poly_bb, free_poly_bb): Same. + * graphite-poly.h (poly_bb): poly_bb.domain Same. + (pbb_nb_loops): Same. + * graphite-sese-to-poly.c (build_loop_iteration_domains, + add_conditions_to_domain): Same. + * graphite-ppl.c (new_Cloog_Domain_from_ppl_Pointset_Powerset): New. + (ppl_print_polyhedron_matrix): ppl_Polyhedron_t -> + ppl_const_Polyhedron_t. + (ppl_print_powerset_matrix): New. + * graphite-ppl.h (new_Cloog_Domain_from_ppl_Pointset_Powerset, + ppl_print_powerset_matrix): New. + (ppl_print_polyhedron_matrix): Updated. + +2009-04-07 Sebastian Pop <sebastian.pop@amd.com> + + * tree-scalar-evolution.c (analyze_scalar_evolution_1): Fix comment. + +2009-04-07 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (extend_scattering): Fix indenting. Free cstr. + (print_iteration_domains, debug_iteration_domain, + debug_iteration_domains): New. + * graphite-poly.h (print_iteration_domains, debug_iteration_domain, + debug_iteration_domains): Declared. + * graphite-sese-to-poly.c (build_pbb_scattering_polyhedrons): Fix + indenting. + +2009-04-03 Tobias Grosser <grosser@fim.uni-passau.de> + Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.h (print_iteration_domain): New. + * graphite-sese-to-poly.c (add_conditions_to_domain): Fixed bug. + (build_sese_conditions_1, build_sese_conditions_after, + build_sese_conditions_before): New. + (build_sese_conditions): Rewritten. + +2009-04-03 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + Cleanup of code generation liveouts. + * graphite-clast-to-gimple.c (translate_clast): Use a single + rename_map instead of one per translated statement. + Do not use SESE_LIVEOUT_RENAMES. + (graphite_loop_normal_form): Do not use SESE_REDUCTION_LIST. + (gloog): Do not use SESE_LIVEOUT_RENAMES. + * graphite-scop-detection.c (harmful_stmt_in_bb): Return the close + phi node of a reduction: when a loop contains a reduction used outside + the loop, there should be a scalar close phi node on the exit block. + * sese.c (new_sese): Do not initialize SESE_LIVEOUT, + SESE_LIVEOUT_RENAMES, and SESE_REDUCTION_LIST. + (free_sese): Do not free them. + (sese_build_liveouts_use): Do not use them. + (sese_build_liveouts_bb): Same. + (sese_build_liveouts): Same. + (sese_insert_phis_for_liveouts): Same. + (sese_adjust_phis_for_liveouts): Same. Renamed sese_adjust_liveout_phis. + (defined_in_loop_p): New. + (alive_after_loop): New. + (close_phi_not_yet_inserted_p): New. + (struct alep, alep_p): New. + (add_loop_exit_phis): Remove from the rename_map all the names defined + in the code generated loop. + (insert_loop_close_phis): Traverse the rename_map passed to it. + Don't use SESE_LIVEOUT_RENAMES. + (default_liveout_before_guard): Renamed default_before_guard. + (insert_guard_phis): Do not use SESE_LIVEOUT_RENAMES. + (graphite_copy_stmts_from_block): Do not directly call set_rename. + (register_sese_liveout_renames): Removed. + (copy_bb_and_scalar_dependences): Do not call it. + * sese.h (struct sese): Removed fields: liveout, liveout_renames, and + reduction_list. + (SESE_LIVEOUT): Removed. + (SESE_LIVEOUT_RENAMES): Removed. + (SESE_REDUCTION_LIST): Removed. + (sese_build_liveouts): Removed. + (sese_adjust_phis_for_liveouts): Renamed sese_adjust_liveout_phis. + (insert_loop_close_phis): Pass a htab_t instead of a sese. + (insert_guard_phis): Same. + (rename_map_elt): Declare a VEC of them. + * tree-parloops.c (canonicalize_loop_ivs): reduction_list contains + trees not pointers to trees. + + Rewrite in canonical close SSA form: + * graphite-scop-detection.c (contains_only_close_phi_nodes): New. + (limit_scops): Close the scop after the block containing the close phi + nodes. + (canonicalize_loop_closed_ssa): New. + (canonicalize_loop_closed_ssa_form): New. + (build_scops): Call canonicalize_loop_closed_ssa_form. + + * graphite-sese-to-poly.c: Fix typos. + +2009-04-03 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (print_scattering_function, print_pbb_domain): + Extended. + (dump_gbb_conditions, dump_gbb_cases, print_iteration_domain): New. + (print_pbb): Add conditions. + +2009-04-01 Tobias Grosser <grosser@fim.uni-passau.de> + Sebastian Pop <sebastian.pop@amd.com> + + * graphite-scop-detection.c (bb_in_sd_region): Use bb_in_region. + * graphite-sese-to-poly.c (all_non_dominated_preds_marked_p): New. + (build_scop_bbs_1): New. + (build_scop_bbs): Rewrite. + * sese.h (bb_in_region): New. + +2009-03-29 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-poly.c (new_poly_bb, free_poly_bb): Initialize/free + poly_drs vector. + (print_scop): Style. + * graphite-poly.h (poly_bb): Add drs vector. + (PBB_DRS): Add accessor. + * graphite-sese-to-poly.c (build_poly_dr): New. + (build_pbb_drs, build_scop_drs): New. + (build_poly_scop): call build_scop_drs (Disabled at the moment). + +2009-03-29 Tobias Grosser <grosser@fim.uni-passau.de> + + * tree-ssa-loop.c: Include forgotten toplev.h + +2009-03-29 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-poly.c: (apply_poly_transforms): sorry -> gcc_unreachable. + * testsuite/gcc.dg/graphite/pr37883.c: Remove -floop-* + * testsuite/gcc.dg/graphite/pr37928.c: Same + * testsuite/gcc.dg/graphite/pr38409.c: Same + * testsuite/gcc.dg/graphite/pr38498.c: Same + * testsuite/gcc.dg/graphite/pr38559.c: Same + * testsuite/gcc.dg/graphite/pr39335.c: Same + * testsuite/gcc.dg/graphite/pr39335_1.c: Same + * testsuite/gfortran.dg/graphite/block-2.f: Same + * tree-ssa-loop.c (gate_graphite_transforms): Always fail if called + with -floop-*. + +2009-03-28 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-sese-to-poly.c (ref_nb_loops, build_access_matrix_with_af, + build_access_matrix, build_scop_data_accesses): Remove access function + building. (We get a new version soon). + (build_bb_loops, scan_tree_for_params_right_scev): Update. + * sese.h (nb_loops_around_loop_in_sese): Remove. + (sese_loop_depth): Do not use SESE_LOOP_NEST any more. + +2009-03-27 Tobias Grosser <grosser@fim.uni-passau.de> + Sebastian Pop <sebastian.pop@amd.com> + + * graphite-scop-detection.c (struct scopdet_info): Rename last + field to exit. + (scopdet_basic_block_info, build_scops_1): Don't use + CDI_POST_DOMINATORS. CDI_POST_DOMINATORS should never be used. + +2009-03-26 Tobias Grosser <grosser@fim.uni-passau.de> + Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (gloog): Call sese_build_liveouts. + * sese.c (sese_build_liveouts_use): Renamed from + sese_build_livein_liveouts_use. Remove liveins. + (sese_build_liveouts_bb): Renamed from sese_build_livein_liveouts_bb. + Call sese_build_liveouts_use. + (sese_build_liveouts): Renamed from sese_build_livein_liveouts. + Call sese_build_liveouts_bb. + (new_sese, free_sese): Remove liveins. + (sese_add_exit_phis_var): Deleted. + (sese_insert_phis_for_liveouts): Call sese_add_exit_phis_edge + directly. + (graphite_copy_stmts_from_block): Remove SESE_NUM_VER. + + * sese.h (sese): Remove num_ver and livein. + (SESE_LIVEIN, SESE_LIVEIN_VER, SESE_NUM_VER): Removed. + +2009-03-25 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-sese-to-poly.c (build_scop_scattering): Fix compile. + +2009-03-25 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-sese-to-poly.c (compare_prefix_loops): Removed. + (build_scop_scattering): Do not use compare_prefix_loops any more. + (nb_common_loops): New. + +2009-03-24 Sebastian Pop <sebastian.pop@amd.com> + + * sese.c (get_new_name_from_old_name): Renamed get_rename. + (register_old_and_new_names): Renamed set_rename. + +2009-03-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-scop-detection.h (nb_reductions_in_loop): Revert removal + of the decl from the previous commit. + +2009-03-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-scop-detection.c (dot_scop): New. + * graphite-scop-detection.h (dot_scop): Declared. + +2009-03-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (compare_prefix_loops): Fix compare. + +2009-03-24 Sebastian Pop <sebastian.pop@amd.com> + + * cfgloopmanip.c (create_empty_loop_on_edge): Generate the loop exit + condition at the end of the loop. + * graphite.c (graphite_initialize, graphite_finalize): Print to + dump_file the compiled function. + * graphite-clast-to-gimple.c (graphite_create_new_loop): Update use + of create_empty_loop_on_edge. + (translate_clast): Update the code generation of loops for the new + shape of loops. + * cfgloop.h (create_empty_loop_on_edge): Update declaration. + +2009-03-24 Sebastian Pop <sebastian.pop@amd.com> + + Reverted the patch from 2009-03-19. + +2009-03-19 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-poly.c (new_poly_bb, free_poly_bb): Initialize/free + poly_drs vector. + (print_scop): Style. + * graphite-poly.h (poly_bb): Add drs vector. + (PBB_DRS): Add accessor. + * graphite-sese-to-poly.c (ref_nb_loops): Remove. + (build_access_matrix_with_af, build_access_matrix, + build_scop_data_accesses): Delete. + (build_poly_dr): New. + (build_pbb_drs, build_scop_drs): New. + (build_poly_scop): call build_scop_drs. + +2009-03-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-scop-detection.c (dot_all_scops_1): Close the table + once per basic block. + +2009-03-13 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-scop-detection.c (graphite_can_represent_scev): New. + (graphite_can_represent_expr): Renamed from loop_affine_expr + and enhanced. + (stmt_simple_for_scop_p): Call graphite_can_represent_expr. + (graphite_cannot_represent_loop): Add scop_entry to parameters. + (scopdet_basic_block_info): Actually define entry_block. + (stmt_simple_memref_p): Moved here from ... + + * tree-data-ref.c (stmt_simple_memref_p): here. + * tree-data-ref.h (stmt_simple_memref_p): Removed. + +2009-03-13 Tobias Grosser <grosser@fim.uni-passau.de> + + * testsuite/gcc.dg/graphite/id-4.c: New. + +2009-03-12 Sebastian Pop <sebastian.pop@amd.com> + + * sese.c (expand_scalar_variables_expr): Handle tcc_comparison. + (register_old_and_new_names): Update the content of the map. + When there was already a rename_map_elt in the map at that + location, free it. + (copy_bb_and_scalar_dependences): Do rename_variables after + expand_scalar_variables. + * graphite-clast-to-gimple.c (build_iv_mapping): Update the content + of the map. When there was already a rename_map_elt in the + map at that location, free it. + (translate_clast): Pass the rename_map. Do not initialize and free + a rename_map per stmt_user. + (gloog): Initialize and free one rename_map and pass it to + translate_clast. + +2009-03-12 Sebastian Pop <sebastian.pop@amd.com> + + * sese.c (expand_scalar_variables_stmt, + expand_scalar_variables_ssa_name): Add a gimple_stmt_iterator + parameter. + (expand_scalar_variables_expr): Handle REALPART_EXPR and IMAGPART_EXPR. + (expand_scalar_variables): Pass to expand_scalar_variables_stmt + the gimple_stmt_iterator of the statement to be expanded. + * graphite-scop-detection.c (is_simple_operand): Do handle + REALPART_EXPR. + +2009-03-11 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-scop-detection.c (is_simple_operand): Do not handle + REALPART_EXPR. + * testsuite/gcc.dg/graphite/id-2.c: New. + + * graphite-sese-to-poly.c (build_bb_loops, + add_value_to_dim, scan_tree_for_params_right_scev, + scan_tree_for_params_int, scan_tree_for_params, idx_record_params, + find_params_in_bb, build_loop_iteration_domains, + add_conditions_to_domain): Remove subtract. + +2009-03-11 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-clast-to-gimple.c (loop_iv_stack_patch_for_consts, + build_iv_mapping, compute_cloog_iv_types_1, build_cloog_prog): + pbb_loop_at_index -> gbb_loop_at_index. + * graphite-poly.c (new_poly_bb, new_scop): New accessors. + (debug_loop_vec): Delete. + * graphite-poly.h (poly_bb, scop): Change black_box and region to void + pointer. Move LOOPS to gimple_bb_p and insert nb_params. + (PBB_LOOPS): Removed. + (PBB_BLACK_BOX): Insert cast. + (pbb_set_black_box): New setter. + (pbb_loop_at_index, pbb_loop_index): Removed. + (scop_set_region, scop_set_nb_params): New. + * graphite-sese-to-poly.c (new_gimple_bb, free_gimple_bb, + build_scop_scattering, build_bb_loops): Add GBB_LOOPS. + (build_poly_scop): Use scop_set_nb_params. + * sese.h (gimple_bb): Add LOOPS. + (GBB_LOOPS, gbb_loop_index, gbb_loop_at_index): New. + +2009-03-11 Tobias Grosser <grosser@fim.uni-passau.de> + + Revert previous commit. + +2009-03-11 Sebastian Pop <sebastian.pop@amd.com> + + * sese.c (expand_scalar_variables_expr): Handle tcc_comparison. + (register_old_and_new_names): Update the content of the map. + When there was already a rename_map_elt in the map at that + location, free it. + (copy_bb_and_scalar_dependences): Do rename_variables after + expand_scalar_variables. + * graphite-clast-to-gimple.c (build_iv_mapping): Update the content + of the map. When there was already a rename_map_elt in the + map at that location, free it. + (translate_clast): Pass the rename_map. Do not initialize and free + a rename_map per stmt_user. + (gloog): Initialize and free one rename_map and pass it to + translate_clast. + +2009-03-11 Tobias Grosser <grosser@fim.uni-passau.de> + + Remove forgotten line in revert. + +2009-03-11 Sebastian Pop <sebastian.pop@amd.com> + + Revert previous commit. + +2009-03-10 Sebastian Pop <sebastian.pop@amd.com> + + * sese.c (register_old_and_new_names): Update the content + of the map. When there was already a rename_map_elt in the + map at that location, free it. + (copy_bb_and_scalar_dependences): Do rename_variables after + expand_scalar_variables. + * graphite-clast-to-gimple.c (build_iv_mapping): Update the content + of the map. When there was already a rename_map_elt in the + map at that location, free it. + (translate_clast): Pass the rename_map. Do not initialize and free + a rename_map per stmt_user. + (gloog): Initialize and free one rename_map and pass it to + translate_clast. + +2009-03-10 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (translate_clast): context_loop + is never NULL. + +2009-03-10 Tobias Grosser <grosser@fim.uni-passau.de> + Sebastian Pop <sebastian.pop@amd.com> + + * graphite-ppl.c (ppl_insert_dimensions): Fix stupid mistake + of the use of ppl_Polyhedron_map_space_dimensions. + +2009-03-10 Tobias Grosser <grosser@fim.uni-passau.de> + Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (unify_scattering_dimensions): Fix types. + * graphite-poly.h (poly_dr_p, poly_dr, POLY_DR_TYPE, PDR_BB, + PDR_TYPE, PDR_ACCESSES, pdr_accessp_nb_subscripts, + pdr_accessp_nb_iterators, pdr_accessp_nb_params, + pdr_accessp_alias_set_dim, pdr_accessp_subscript_dim, + pdr_accessp_iterator_dim, pdr_accessp_param_dim, + pbb_nb_params): New. + (pbb_nb_loops, pbb_nb_scattering, scop_nb_params, + nb_loops_around_pbb): Adapt return types. + +2009-03-09 Tobias Grosser <grosser@fim.uni-passau.de> + + * Makefile.in (graphite.o, graphite-sese-to-poly.o, + graphite-clast-to-gimple.o, graphite-data-ref.o, + graphite-scop-detection.o, graphite-poly.o): Add + more headers. + +2009-03-05 Tobias Grosser <grosser@fim.uni-passau.de> + + * Makefile.in (graphite.o, graphite-sese-to-poly.o, + graphite-clast-to-gimple.o, graphite-data-ref.o, + graphite-scop-detection.o, graphite-poly.o): Add graphite-poly.h. + +2009-03-04 Tobias Grosser <grosser@fim.uni-passau.de> + + * testsuite/gcc.dg/graphite/pr37485.c: Remove -floop-block + * testsuite/gcc.dg/graphite/pr37828.c: Same. + * testsuite/gcc.dg/graphite/pr37684.c: Same. + * testsuite/gcc.dg/graphite/block-0.c: Same. + * testsuite/gcc.dg/graphite/block-1.c: Same. + * testsuite/gcc.dg/graphite/block-2.c: Same. + * testsuite/gcc.dg/graphite/block-3.c: Same. + * testsuite/gcc.dg/graphite/block-4.c: Same. + * testsuite/gcc.dg/graphite/block-5.c: Same. + * testsuite/gcc.dg/graphite/block-6.c: Same. + * testsuite/gfortran.dg/graphite/pr38083.f90: Same. + * testsuite/gfortran.dg/graphite/block-1.f90: Same. + * testsuite/gfortran.dg/graphite/block-3.f90: Same. + * testsuite/gfortran.dg/graphite/pr37852.f90: Same. + * testsuite/gfortran.dg/graphite/block-4.f90: Same. + * testsuite/gfortran.dg/graphite/pr37980.f90: Same. + * testsuite/gfortran.dg/graphite/pr38953.f90: Same. + * testsuite/gfortran.dg/graphite/pr37857.f90: Same. + * opts.c: Remove -floop-block from -O2. + * graphite-poly.c: Fail if -floop-block -floop-interchange or + -floop-strip-mine are used. + +2009-03-04 Tobias Grosser <grosser@fim.uni-passau.de> + Sebastian Pop <sebastian.pop@amd.com> + + * graphite-clast-to-gimple.c (build_cloog_prog): Unify scattering + dimensions. + * graphite-poly.c (pbb_compare, graphite_sort_pbbs, + graphite_trans_bb_move_loop, graphite_trans_bb_strip_mine, + strip_mine_profitable_p, is_interchange_valid, + graphite_trans_bb_block, graphite_trans_loop_block, + graphite_trans_scop_block): Temporary removed. + (extend_scattering, unify_scattering_dimensions): New. + (print_scattering_function, graphite_read_transforms): + PBB_SCATTERING -> PBB_TRANSFORMED_SCATTERING. + (graphite_generate_scattering_fns): Removed. + (apply_poly_transforms): Cleanup. + (free_poly_bb): Add PBB_SCATTERING -> PBB_TRANSFORMED_SCATTERING. + (schedule_to_scattering): Moved. + (PBB_STATIC_SCHEDULE, PBB_SCATTERING): Removed. + (PBB_ORIGINAL_SCATTERING, PBB_TRANSFORMED_SCATTERING): New. + (pbb_nb_scattering): New. + (SCOP_ENTRY, SCOP_EXIT, SCOP_REGION_BBS, SCOP_DEP_GRAPH, SCOP_PARAMS, + SCOP_LOOP_NEST, SCOP_PARAMS, SCOP_OLDIVS, SCOP_LIVEOUT_RENAMES): + Removed. + * graphite-ppl.c (ppl_insert_dimensions): Extended and renamed from + shift_poly. + (ppl_strip_loop): PBB_SCATTERING -> PBB_TRANSFORMED_SCATTERING. + * graphite-scop-detection.c (dot_all_scops_1): PBB_SCATTERING + -> PBB_TRANSFORMED_SCATTERING. + * graphite-sese-to-poly.c (build_scop_bbs): Remove region. + (build_pbb_scattering_polyhedron): Moved from schedule_to_scattering. + (build_scop_scattering): Renamed from build_scop_canonical_schedules. + (check_poly_representation): Do not return bool. + (graphite_transform_loops): Reformat. + * sese.h (SESE_ENTRY_BB, SESE_EXIT_BB): New. + +2009-03-04 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c (print_pbb_domain, print_pbb, print_scop, + debug_pbb_domain, debug_pbb, debug_scop): New. + * graphite-poly.h (print_pbb_domain, print_pbb, print_scop, + debug_pbb_domain, debug_pbb, debug_scop): Declared. + +2009-03-02 Sebastian Pop <sebastian.pop@amd.com> + + PR middle-end/39335 + * tree-parloops.c (canonicalize_loop_ivs): Call fold_convert + when the type precision of the induction variable should be + larger than the type precision of nit. + (gen_parallel_loop): Update use of canonicalize_loop_ivs. + * graphite-clast-to-gimple.c (graphite_loop_normal_form): Same. + * tree-flow.h (canonicalize_loop_ivs): Update declaration. + + * testsuite/gcc.dg/graphite/pr39335_1.c: New. + * testsuite/gcc.dg/graphite/pr39335.c: New. + +2009-03-02 Sebastian Pop <sebastian.pop@amd.com> + + * tree-parloops.c (canonicalize_loop_ivs): reduction_list contains + SSA_NAMES not struct reduction_info. + +2009-03-02 Sebastian Pop <sebastian.pop@amd.com> + + * sese.c (expand_scalar_variables_expr): Handle ADDR_EXPR. + +2009-02-27 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * sese.c (new_sese): Initialize SESE_REDUCTION_LIST. + (free_sese): Free SESE_REDUCTION_LIST. + * sese.h (struct sese): Add field reduction_list. + (SESE_REDUCTION_LIST): New. + * graphite-clast-to-gimple.c (graphite_loop_normal_form): Call + canonicalize_loop_ivs on SESE_REDUCTION_LIST. + +2009-02-27 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * tree-flow.h (gather_scalar_reductions): Use struct loop * instead + of loop_p. + +2009-02-27 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * tree-parloops.c (struct brli, build_reduction_list_info, + analyze_reduction_list, gather_scalar_reductions): New. + (loop_parallel_p): Build a reduction list containing only + PHI_RESULT SSA_NAMEs: call gather_scalar_reductions. + (gen_parallel_loop): Call the analysis analyze_reduction_list. + (parallelize_loops): Now reduction_list is a htab_t of SSA_NAMEs. + * tree-flow.h (gather_scalar_reductions): Declared. + +2009-02-26 Sebastian Pop <sebastian.pop@amd.com> + + PR middle-end/39308 + * graphite-clast-to-gimple.c (graphite_loop_normal_form): Do not call + number_of_iterations_exit from a gcc_assert. + +2009-02-25 Sebastian Pop <sebastian.pop@amd.com> + Jan Sjodin <jan.sjodin@amd.com> + + * output.h (graphite_out_file, graphite_in_file): Declared. + * toplev.c (graphite_out_file, graphite_in_file): New. + (init_asm_output): Initialize graphite_in_file and graphite_out_file. + * graphite-clast-to-gimple.c (build_cloog_prog): Read PBB_SCATTERING. + Don't call schedule_to_scattering. + * common.opt (fgraphite-write, fgraphite-read): New. + * graphite-poly.c: Include output.h. + (print_scattering_function, print_scattering_functions, + debug_scattering_function, debug_scattering_functions, + graphite_write_transforms, graphite_read_transforms, + graphite_generate_scattering_fns): New. + (apply_poly_transforms): Do not apply transform if flag_graphite_read. + Call graphite_generate_scattering_fns, graphite_write_transforms, + graphite_read_transforms. + (new_poly_bb): Initialize PBB_SCATTERING. + (free_poly_bb): Free PBB_SCATTERING. + (schedule_to_scattering): Does not return, initialize PBB_SCATTERING. + * graphite-poly.h (struct poly_bb): Add field scattering. + (PBB_SCATTERING): New. + (print_scattering_function, print_scattering_functions, + debug_scattering_function, debug_scattering_functions): Declared. + * graphite-ppl.c (cloog_matrix_to_ppl_constraint): Matrices contain + GMP values, not integers! + (ppl_print_polyhedron_matrix, debug_ppl_polyhedron_matrix, + ppl_read_polyhedron_matrix): New. + * graphite-ppl.h (ppl_print_polyhedron_matrix, + debug_ppl_polyhedron_matrix, + ppl_read_polyhedron_matrix): Declared. + * Makefile.in (graphite-poly.o): Depends on output.h. + +2009-02-23 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + Revert this change: + * graphite-scop-detection.c (stmt_simple_for_scop_p): Analyze + scalar evolutions in the scop_entry->loop_father. + +2009-02-23 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.h (ref_nb_loops): Remove declaration. + (struct gimple_bb, gimple_bb_p, GBB_BB, GBB_DATA_REFS, GBB_CONDITIONS, + GBB_CONDITION_CASES, GBB_CLOOG_IV_TYPES, gbb_loop, print_gimple_bb, + debug_gbb): Moved to sese.h. + * sese.h: As said. + +2009-02-23 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-data-ref.[ch]: Disable. + +2009-02-23 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-scop-detection.c (stmt_simple_for_scop_p): Analyze + scalar evolutions in the scop_entry->loop_father. + +2009-02-23 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-scop-detection.c (nb_reductions_in_loop): Moved here... + (graphite_cannot_represent_loop_niter): Renamed + graphite_cannot_represent_loop. Call nb_reductions_in_loop. + (limit_scops): build_sese_loop_nests does not return a bool. + * graphite-scop-detection.h (nb_reductions_in_loop): Declared. + * sese.c (nb_reductions_in_loop): ... from here. + (graphite_loop_normal_form): ... from here. + (sese_record_loop): Does not fail, so does not return a bool. + (build_sese_loop_nests): Same. + * sese.h (build_sese_loop_nests): Update declaration. + * graphite-clast-to-gimple.c (graphite_loop_normal_form): Moved here... + (build_graphite_loop_normal_form): New. + (gloog): Call build_graphite_loop_normal_form. + * graphite-sese-to-poly.c (build_poly_scop): Don't fail on + build_sese_loop_nests. + + * testsuite/gcc.dg/graphite/id-1.c: New. + +2009-02-23 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-sese-to-poly.c (scan_tree_for_params): Remove REAL_CST. + The SCoP detection fix is sufficient. + +2009-02-21 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/39260 + * graphite-scop-detection.c (harmful_stmt_in_bb): Stop a SCoP when + the basic block contains a condition with a real type. + * graphite-sese-to-poly.c (scan_tree_for_params): Handle REAL_CST. + + * gcc.dg/graphite/pr39260.c: New. + +2009-02-21 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-poly.c: Inlcude params.h. + (graphite_trans_loop_block): Use PARAM_LOOP_BLOCK_TILE_SIZE for + the size of a tile. + * Makefile.in (graphite-poly.o): Depend on PARAMS_H. + * params.def (PARAM_LOOP_BLOCK_TILE_SIZE): Define. + +2009-02-20 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-scop-detection.c (dot_all_scops_1, + dot_all_scops): Moved here. + * graphite-scop-detection.h (dot_all_scops): Declared here. + * graphite.c (graphite_initialize, graphite_finalize): New. + (graphite_transform_loops): Cleaned up. + * sese.c (debug_oldivs): Moved here. + * graphite-poly.c (graphite_apply_transformations): Renamed + apply_poly_transforms. + (debug_loop_vec): Moved here. + * graphite-sese-to-poly.c (build_bb_loops, build_sese_conditions_1, + scop_contains_non_iv_scalar_phi_nodes, build_sese_conditions, + find_scop_parameters, build_scop_iteration_domain, + add_conditions_to_constraints, build_scop_canonical_schedules, + build_scop_data_accesses): Now static. + (build_poly_scop, check_poly_representation): New. + +2009-02-20 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (graphite_stmt_p, new_gimple_bb, free_gimple_bb, + remove_gbbs_in_scop, free_scops, try_generate_gimple_bb, + build_scop_bbs, ref_nb_loops, compare_prefix_loops, + build_scop_canonical_schedules, build_bb_loops, add_value_to_dim, + scan_tree_for_params_right_scev, scan_tree_for_params_int, + scan_tree_for_params, struct irp_data, dx_record_params, + find_params_in_bb, find_scop_parameters, gbb_from_bb, + build_loop_iteration_domains, add_conditions_to_domain, + phi_node_is_iv, bb_contains_non_iv_scalar_phi_nodes, + scop_contains_non_iv_scalar_phi_nodes, build_sese_conditions_1, + build_sese_conditions, add_conditions_to_constraints, + build_scop_iteration_domain, build_access_matrix_with_af, + build_access_matrix, + build_scop_data_accesses): Moved to graphite-sese-to-poly.c. + + * graphite-sese-to-poly.c: New. + * graphite-sese-to-poly.h: New. + + * Makefile.in: Add new rule for graphite-sese-to-poly.o. + +2009-02-20 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c: Split graphite code generation to a new file. + (graphite_verify, gmp_cst_to_tree, clast_name_to_gcc, + max_precision_type, clast_to_gcc_expression_red, + clast_to_gcc_expression, gcc_type_for_clast_expr, + gcc_type_for_clast_eq, loop_iv_stack_patch_for_consts, + graphite_translate_clast_equation, graphite_create_guard_cond_expr, + graphite_create_new_guard, clast_get_body_of_loop, + gcc_type_for_cloog_iv, gcc_type_for_iv_of_clast_loop, + graphite_create_new_loop, build_iv_mapping, copy_renames, + translate_clast, find_cloog_iv_in_expr, compute_cloog_iv_types_1, + compute_cloog_iv_types, free_scattering, save_var_name, + initialize_cloog_names, build_scop_context, build_cloog_prog, + set_cloog_options, debug_clast_stmt, scop_to_clast, + print_generated_program, debug_generated_program, + gloog): Moved to graphite-clast-to-gimple.c. + + (struct cloog_prog_clast): Moved to graphite-clast-to-gimple.h. + + (iv_stack_entry_is_constant, iv_stack_entry_is_iv, + loop_iv_stack_push_iv, loop_iv_stack_insert_constant, + loop_iv_stack_pop, loop_iv_stack_get_iv, + loop_iv_stack_get_iv_from_name, debug_loop_iv_stack, + free_loop_iv_stack, loop_iv_stack_remove_constants, + debug_rename_elt, debug_rename_map_1, debug_rename_map, + rename_map_elt_info, eq_rename_map_elts, debug_ivtype_elt, + debug_ivtype_map_1, debug_ivtype_map, ivtype_map_elt_info, + eq_ivtype_map_elts, sese_add_exit_phis_edge, + sese_add_exit_phis_var, sese_insert_phis_for_liveouts, + get_vdef_before_sese, sese_adjust_vphi, + get_new_name_from_old_name, sese_adjust_phis_for_liveouts, + oldiv_for_loop, rename_variables_in_stmt, is_parameter, + is_iv, expand_scalar_variables_ssa_name, + expand_scalar_variables_expr, expand_scalar_variables_stmt, + expand_scalar_variables, rename_variables, remove_condition, + get_true_edge_from_guard_bb, get_false_edge_from_guard_bb, + add_loop_exit_phis, insert_loop_close_phis, struct igp, + default_liveout_before_guard, add_guard_exit_phis, + insert_guard_phis, register_old_and_new_names, + graphite_copy_stmts_from_block, register_sese_liveout_renames, + copy_bb_and_scalar_dependences, outermost_loop_in_sese, + if_region_set_false_region, create_if_region_on_edge, + move_sese_in_condition): Moved to sese.c. + + (nb_loops_around_loop_in_sese, struct ifsese, if_region_entry, + if_region_exit, if_region_get_condition_block, + struct rename_map_elt, new_rename_map_elt, enum iv_stack_entry_kind, + union iv_stack_entry_data_union, struct iv_stack_entry_struct, + iv_stack_entry_p, loop_iv_stack, struct ivtype_map_elt, + ivtype_map_elt, new_ivtype_map_elt, + recompute_all_dominators): Moved to sese.h. + + * graphite-clast-to-gimple.c: New. + * graphite-clast-to-gimple.h: New. + * Makefile.in: Add new rule for graphite-clast-to-gimple.o. + * sese.c: Modified as said above. + * sese.h: Same. + +2009-02-20 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c: Split scop detection to a new file. + (enum gbb_type, gbb_type, get_bb_type, struct sd_region_p, sd_region, + move_sd_regions, loop_affine_expr, exclude_component_ref, + is_simple_operand, stmt_simple_for_scop_p, harmful_stmt_in_bb, + graphite_cannot_represent_loop_niter, struct scopdet_info, + scopdet_basic_block_info, build_scops_1, bb_in_sd_region, + find_single_entry_edge, find_single_exit_edge, + create_single_entry_edge, sd_region_without_exit, + create_single_exit_edge, unmark_exit_edges, mark_exit_edges, + create_sese_edges, build_graphite_scops, limit_scops, build_scops): + Moved to graphite-scop-detection.c. + + * graphite-scop-detection.c: New. + * graphite-scop-detection.h: New. + * Makefile.in: Add new rule for graphite-scop-detection.o. + + * sese.c: Include tree-chrec.h, tree-data-ref.h, and + tree-scalar-evolution.h. + (nb_reductions_in_loop, graphite_loop_normal_form, sese_record_loop, + build_sese_loop_nests): Moved here from graphite.c. + (param_index): Renamed parameter_index_in_region. + +2009-02-18 Tobias Grosser <grosser@fim.uni-passau.de> + Sebastian Pop <sebastian.pop@amd.com> + + * gcc.dg/graphite/block-0.c: Expected to fail now. + * gcc.dg/graphite/block-1.c: Same. + * gcc.dg/graphite/block-5.c: Same. + * gcc.dg/graphite/block-6.c: Same. + +2009-02-18 Tobias Grosser <grosser@fim.uni-passau.de> + Sebastian Pop <sebastian.pop@amd.com> + + * graphite.h: Separate from graphite_bb_p the polyhedral + representation in poly_bb_p and the GCC specifics in gimple_bb_p. + (struct data_dependence_polyhedron, RDGE_DDP, ddp_p): Moved to + graphite-data-ref.h. + (struct poly_bb, PBB_SCOP, PBB_STATIC_SCHEDULE, PBB_DOMAIN, + PBB_BLACK_BOX, PBB_LOOPS, pbb_nb_loops, pbb_loop_at_index, + pbb_loop_index, struct scop, SCOP_BBS, SCOP_REGION, SCOP_ENTRY, + SCOP_EXIT, SCOP_REGION_BBS, SCOP_DEP_GRAPH, SCOP_PARAMS, + SCOP_LOOP_NEST, SCOP_PARAMS, SCOP_OLDIVS, SCOP_LIVEOUT_RENAMES, + scop_nb_params): Moved to graphite-poly.h. + * graphite-data-ref.c: Same. + * graphite-data-ref.h: New. + * graphite.c: Same. + (pbb_compare, graphite_sort_pbbs, graphite_trans_bb_move_loop, + graphite_trans_bb_strip_mine, strip_mine_profitable_p, + is_interchange_valid, graphite_trans_bb_block, + graphite_trans_loop_block, scop_max_loop_depth, + graphite_trans_scop_block, graphite_apply_transformations, + new_poly_bb, free_poly_bb, new_scop, free_scop): Moved to + graphite-poly.c. + * graphite-poly.h: New. + * graphite-poly.c: New. + * Makefile.in (OBJS-common): Add graphite-poly.o. + (graphite-poly.o): New rule. + * tree-data-ref.h (struct data_reference): Remove unused scop field. + (DR_SCOP): Removed. + +2009-02-18 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c: Replace gb -> gbb. + * graphite.h: Same. + * graphite-data-ref.c: Same. + +2009-02-18 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * Makefile.in (OBJS-commmon): Add sese.o. + (sese.o): New. + (graphite.o): Add sese.h. + * graphite.c (bb_in_ss_p, loop_in_sese_p, + sese_build_livein_liveouts_use, sese_build_livein_liveouts_bb, + sese_build_livein_liveouts, register_bb_in_sese, new_sese, free_sese): + Move to sese. + (block_before_scop): Add missing return. + (new_scop, free_scop): Remove SESE data structures. + (scop_record_loop, scan_tree_for_params, find_params_in_bb, + find_scop_parameters, build_loop_iteration_domains, + add_conditions_to_domain, register_scop_liveout_renames, + copy_bb_and_scalar_dependences): Scop -> SESE. + + (add_conditions_to_domain): SCoP -> SESE and remove check + (scop_contains_non_iv_scalar_phi_nodes): New. + (build_scop_conditions_1, build_scop_conditions): Remove check for + non iv scalar phi nodes. + (print_scop_statistics): New. + (graphite_transform_loops): Cleanup. + + * graphite.h: Move to sese & cleanup. + * sese.c: New. + * sese.h: New. + +2009-02-16 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (build_scop_conditions_1): Conditions are only + at the end of a basic block. + +2009-02-16 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau> + + * graphite.h (struct graphite_bb): Remove compressed_alpha_matrix + field. + (GBB_ALPHA): Removed. + +2009-02-16 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite-data-ref.c (graphite_test_dependence): Don't use + GBB_DYNAMIC_SCHEDULE. + * graphite.c (new_graphite_bb): Same. + (free_graphite_bb): Same. + (build_scop_dynamic_schedules): Removed. + (graphite_transform_loops): Don't call it. + * graphite.h (struct graphite_bb): Remove dynamic_schedule field. + (GBB_DYNAMIC_SCHEDULE): Removed. + +2009-02-16 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (schedule_to_scattering): Don't use CloogMatrix. + (print_graphite_bb): Same. + (build_cloog_prog): Same. + +2009-02-16 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (build_cloog_prog): Don't use CloogMatrix. + +2009-02-16 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (build_scop_context): Don't use CloogMatrix. + * graphite-ppl.c (new_Cloog_Domain_from_ppl_Polyhedron): New. + * graphite-ppl.h (new_Cloog_Domain_from_ppl_Polyhedron): Declared. + +2009-02-16 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.h (struct scop): Move params, old_ivs, loops, loop_nest, + liveout_renames, add_params fields... + (struct sese): ... here. + (SESE_PARAMS, SESE_LOOPS, SESE_LOOP_NEST, SESE_ADD_PARAMS, + SESE_PARAMS, SESE_OLDIVS, SESE_LIVEOUT_RENAMES): New. + +2009-02-16 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (print_scop): Do not print the CLooG program. + (new_scop, free_scop, initialize_cloog_names, build_scop_context, + build_cloog_prog, gloog): Don't use SCOP_PROG. + (find_transform): Renamed scop_to_clast. + (print_generated_program, debug_generated_program): New. + (graphite_transform_loops): Adapt to new interface. + * graphite.h (struct scop): Remove program field. + (SCOP_PROG): Removed. + (print_generated_program, debug_generated_program): Declared. + +2009-02-16 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-data-ref.c (schedule_precedes_p, schedule_same_p): New. + (statement_precedes_p): Use schedule_same_p and schedule_precedes_p. + * graphite.c (gbb_compare, schedule_to_scattering, print_graphite_bb, + free_graphite_bb, build_scop_canonical_schedules, + graphite_trans_bb_strip_mine, graphite_trans_scop_block): Static + schedules are now represented using a ppl_Linear_Expression_t. + * graphite.h (struct graphite_bb): Same. + * graphite-ppl.c (ppl_lexico_compare_linear_expressions): New. + * graphite-ppl.h (ppl_lexico_compare_linear_expressions): Declared. + +2009-02-15 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c: Free local memory. + * graphite-ppl.c: Same. + +2009-02-15 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (const_column_index, get_first_matching_sign_row_index, + get_lower_bound_row, get_upper_bound_row, copy_constraint, + swap_constraint_variables, scale_constraint_variable): Removed. + (graphite_trans_bb_strip_mine): Remove pong. + * graphite-ppl.c: Include missing header files. + (set_inhomogeneous, set_coef, shift_poly, ppl_strip_loop): New. + * graphite-ppl.h (ppl_strip_loop): Declared. + * Makefile.in (graphite-ppl.o): Adjust dependences. + +2009-02-14 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (build_loop_iteration_domains): Remove ping pong. + (build_scop_iteration_domain): Same. + +2009-02-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (scan_tree_for_params, add_conditions_to_domain): Remove + ping pong. + (add_value_to_dim, scan_tree_for_params_right_scev, + scan_tree_for_params_int): New. + * graphite-ppl.c (oppose_constraint): New. + (insert_constraint_into_matrix): Implement missing cases. + * graphite-ppl.h (insert_constraint_into_matrix): Declared. + +2009-02-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (graphite_trans_bb_move_loop): Remove ping pong, + use ppl_move_dimension. + +2009-02-12 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-data-ref.c: Domains are now ppl_Polyhedra_t. + * graphite.c: Same. + * graphite.h: Same. + * graphite-ppl.c: Same. + * graphite-ppl.h: Same. + +2009-02-12 Sebastian Pop <sebastian.pop@amd.com> + + Revert last 3 commits. + +2009-02-10 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (scan_tree_for_params, add_conditions_to_domain): Remove + ping pong. + (add_value_to_dim, scan_tree_for_params_right_scev, + scan_tree_for_params_int): New. + * graphite-ppl.c (oppose_constraint): New. + (insert_constraint_into_matrix): Implement missing cases. + * graphite-ppl.h (insert_constraint_into_matrix): Declared. + +2009-02-10 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (graphite_trans_bb_move_loop): Remove unused variables. + +2009-02-10 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (graphite_trans_bb_move_loop): Remove ping pong, + use ppl_move_dimension. + * graphite-ppl.c (ppl_move_dimension): New. + * graphite-ppl.h (ppl_move_dimension): Declared. + +2009-02-10 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c: Do not include cloog/cloog.h. + (print_graphite_bb): Remove ping pong, call PPL print function. + +2009-02-10 Tobias Grosser <grosser@fim.uni-passau.de> + + * Makefile.in (OBJS-common): Add graphite-ppl.o. + (graphite.o): Add dependence on graphite-ppl.h. + (graphite-ppl.o): New. + (graphite-data-ref.c): Ping pong between PPL data structures + and matrices. + * graphite-ppl.c: New. + * graphite-ppl.h: New. + * graphite.c: Include graphite-ppl.h. + (print_graphite_bb, add_conditions_to_domain, build_cloog_prog, + graphite_trans_bb_move_loop, graphite_trans_bb_strip_mine): + Ping pong between PPL data structures and matrices. + (new_graphite_bb): Create a PPL constraint system. + Call ppl_delete_Constraint_System instead of cloog_matrix_free. + (build_loop_iteration_domains): Use PPL functions. + * graphite.h: Include graphite-ppl.h. Fix comments. + (graphite_bb): Use a ppl_Constraint_System_t instead of + CloogMatrix for representing the domain. + (scop): Remove static_schedule. + (gbb_nb_loops): Ping pong between PPL data structures and matrices. + +2009-02-06 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c: Fix some comments. + +2009-02-05 Sebastian Pop <sebastian.pop@amd.com> + + PR middle-end/38953 + * graphite.c (if_region_set_false_region): After moving a region + in the false branch of a condition, remove the empty dummy + basic block. + (gloog): Remove wrong fix for PR38953. + +2009-02-03 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (bb_in_sese_p, sese_build_livein_liveouts_use, + sese_build_livein_liveouts_bb, sese_build_livein_liveouts, + register_bb_in_sese, new_sese, free_sese): Moved. + (dot_scop_1, build_scop_loop_nests, build_loop_iteration_domains, + outermost_loop_in_scop, build_scop_iteration_domain, + expand_scalar_variables_ssa_name, get_vdef_before_scop, + limit_scops): Use bb_in_sese_p instead of bb_in_scop_p. + Use loop_in_sese_p instead of loop_in_scop_p. + (new_graphite_bb, new_scop, gloog): Do not initialize SCOP_BBS_B. + (free_scop): Do not free SCOP_BBS_B. + (nb_loops_around_loop_in_scop, nb_loops_around_gb, + ref_nb_loops): Moved here... + * graphite.h (ref_nb_loops): ... from here. + (struct scop): Remove bbs_b bitmap. + (SCOP_BBS_B, bb_in_scop_p, loop_in_scop_p): Removed. + * testsuite/gcc.dg/graphite/scop-19.c: New + +2009-02-03 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (scopdet_basic_block_info): Fix bug in scop + detection. + +2009-01-30 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (new_loop_to_cloog_loop_str, hash_loop_to_cloog_loop, + eq_loop_to_cloog_loop): Remove. + (new_scop, free_scop): Remove SCOP_LOOP2CLOOG_LOOP. + * graphite.h (struct scop): Remove loop2cloog_loop. + (loop_domain_dim, loop_iteration_vector_dim): Remove. + +2009-01-30 Tobias Grosser <grosser@fim.uni-passau.de> + + * opts.c (decode_options): Only add graphite options to O2 + if we compile with graphite enabled. + +2009-01-26 Sebastian Pop <sebastian.pop@amd.com> + + * Merge from mainline (r143163:143684). + +2009-01-26 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (debug_value): Removed. + * graphite.h (debug_value): Removed. + +2009-01-23 Sebastian Pop <sebastian.pop@amd.com> + + * passes.c (init_optimization_passes): Do not call pass_copy_prop + after graphite: pass_copy_prop does not maintain a proper loop closed + SSA form. pass_copy_prop should be fixed. + +2009-01-23 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (scop_adjust_phis_for_liveouts): Fix warning. + +2009-01-23 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (graphite_verify): Add a call to verify_loop_closed_ssa. + (gloog): Split the exit of the scop when the scop exit is a loop exit. + (graphite_transform_loops): Only call cleanup_tree_cfg if gloog + changed the CFG. + +2009-01-20 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (gloog): Return true when code gen succeeded. + (graphite_transform_loops): Do not call cleanup_tree_cfg if + the code of the function did not changed. After cleanup_tree_cfg + call rewrite_into_loop_closed_ssa to maintain the loop closed ssa + form. + +2009-01-19 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (stmt_simple_for_scop_p): Also handle cases when + gimple_call_lhs is NULL. + +2009-01-16 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <tobi.grosser@amd.com> + + * graphite.c (graphite_trans_scop_block): Do not block single + nested loops. + +2009-01-15 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <tobi.grosser@amd.com> + + * graphite.c (build_scop_canonical_schedules): Start schedules at + zero. + +2009-01-15 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <tobi.grosser@amd.com> + + * graphite.c (compare_prefix_loops): New. + (build_scop_canonical_schedules): Rewritten. + (graphite_transform_loops): Move build_scop_canonical_schedules + after build_scop_iteration_domain. + +2009-01-14 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <tobi.grosser@amd.com> + + * graphite.c (add_conditions_to_domain): Add the loops to + the dimension of the iteration domain. Do copy the domain + only when it exists. + (build_scop_conditions_1): Do not call add_conditions_to_domain. + (add_conditions_to_constraints): New. + (can_generate_code_stmt, can_generate_code): Removed. + (gloog): Do not call can_generate_code. + (graphite_transform_loops): Call add_conditions_to_constraints + after building the iteration domain. + +2009-01-14 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <tobi.grosser@amd.com> + Jan Sjodin <jan.sjodin@amd.com> + + * graphite.c (scan_tree_for_params): On substractions negate + all the coefficients of the term. + (clast_to_gcc_expression_red): New. Handle reduction expressions + of more than two operands. + (clast_to_gcc_expression): Call clast_to_gcc_expression_red. + (get_vdef_before_scop): Handle also the case of default definitions. + +2009-01-14 Sebastian Pop <sebastian.pop@amd.com> + + PR middle-end/38431 + * graphite.c (get_vdef_before_scop, scop_adjust_vphi): New. + (scop_adjust_phis_for_liveouts): Call scop_adjust_vphi. + (gloog): Do not call cleanup_tree_cfg. + (graphite_transform_loops): Call cleanup_tree_cfg after all + scops have been code generated. + +2009-01-13 Sebastian Pop <sebastian.pop@amd.com> + + * passes.c (init_optimization_passes): Schedule after + graphite transforms pass_copy_prop, pass_dce_loop and pass_lim. + +2009-01-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (expand_scalar_variables_stmt): Do not pass loop_p. + Fix comment. + (expand_scalar_variables_ssa_name): Do not pass loop_p. Fix comment. + Set the type of an expression to the type of its assign statement. + (expand_scalar_variables_expr): Do not pass loop_p. + Fix comment. Stop recursion on tcc_constant or tcc_declaration. + (copy_bb_and_scalar_dependences): Do not pass loop_p. + (translate_clast): Update call to copy_bb_and_scalar_dependences. + +2009-01-11 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (expand_scalar_variables_ssa_name): Set the type of + an expression to the gimple_expr_type of its assign statement. + (expand_scalar_variables_expr): Stop recursion on tcc_constant + or tcc_declaration. + +2009-01-11 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/38786 + * testsuite/gcc.dg/graphite/pr38786.c: New. + * graphite.c (expand_scalar_variables_ssa_name): New, outlined from + the SSA_NAME case of expand_scalar_variables_expr. + (expand_scalar_variables_expr): Also gather the scalar computation + used to index the memory access. + (expand_scalar_variables_stmt): Pass to expand_scalar_variables_expr + the gimple_stmt_iterator where it inserts new code. + +2009-01-10 Sebastian Pop <sebastian.pop@amd.com> + + * testsuite/gcc.dg/graphite/block-3.c: Fix compile error on 32bit. + +2009-01-10 Sebastian Pop <sebastian.pop@amd.com> + + * opts.c (decode_options): Enable flag_graphite_identity and + flag_loop_block in -O2 and above. + +2009-01-08 Sebastian Pop <sebastian.pop@amd.com> + + * libjava/classpath/lib/gnu/java/awt/peer/gtk/GtkMouseInfoPeer.class: + Fix merge problem: replace with the file from trunk. + +2009-01-08 Sebastian Pop <sebastian.pop@amd.com> + + * Merge from mainline (r141727:143163). + +2009-01-07 Sebastian Pop <sebastian.pop@amd.com> + Jan Sjodin <jan.sjodin@amd.com> + + PR tree-optimization/38559 + * testsuite/gcc.dg/graphite/pr38559.c: New. + + * graphite.c (debug_value, copy_constraint, + swap_constraint_variables, scale_constraint_variable, ): New. + (get_lower_bound, get_upper_bound): Removed. + (graphite_trans_bb_strip_mine): Clean up this code that works + only for constant number of iterations. Fully copy upper and + lower bound constraints, not only the constant part of them. + * graphite.h (debug_value): Declared. + +2009-01-06 Jan Sjodin <jan.sjodin@amd.com> + + PR tree-optimization/38492 + PR tree-optimization/38498 + * tree-check.c (operator_is_linear, scev_is_linear_expression): New. + * tree-chrec.h (scev_is_linear_expression): Declared. + * graphite.c (graphite_cannot_represent_loop_niter): New. + (scopdet_basic_block_info): Call graphite_cannot_represent_loop_niter. + (graphite_loop_normal_form): Use gcc_assert. + (scan_tree_for_params): Use CASE_CONVERT. + (phi_node_is_iv, bb_contains_non_iv_scalar_phi_nodes): New. + (build_scop_conditions_1): Call bb_contains_non_iv_scalar_phi_nodes. + Use gcc_assert. Discard scops that contain unhandled cases. + (build_scop_conditions): Return a boolean status for unhandled cases. + (strip_mine_profitable_p): Print the loop number, not its depth. + (is_interchange_valid): Pass the depth of the loop nest, don't + recompute it wrongly. + (graphite_trans_bb_block): Same. + (graphite_trans_bb_block): Print tentative of loop blocking. + (graphite_trans_scop_block): Do not print that the loop has been + blocked. + (graphite_transform_loops): Do not handle scops that contain condition + scalar phi nodes. + + * testsuite/gcc.dg/graphite/pr38500.c: Fixed warning as committed + in trunk. + * testsuite/gcc.dg/graphite/block-0.c: Update test. + * testsuite/gcc.dg/graphite/block-1.c: Same. + * testsuite/gcc.dg/graphite/block-2.c: Remove xfail and test for + blocking. + * testsuite/gcc.dg/graphite/block-4.c: Remove test for strip mine. + * testsuite/gcc.dg/graphite/block-3.c: New. + * testsuite/gcc.dg/graphite/pr38498.c: New. + +2008-12-22 Harsha Jagasia <harsha.jagasia@amd.com> + + PR tree-optimization/38510 + * gcc.dg/graphite/pr38510.c: New. + * graphite.c (recompute_all_dominators): Call mark_irreducible_loops. + (translate_clast): Call recompute_all_dominators before + graphite_verify. + (gloog): Call recompute_all_dominators before graphite_verify. + +2008-12-12 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/38492 + * graphite.c (rename_map_elt, debug_rename_elt, + debug_rename_map_1, debug_rename_map, new_rename_map_elt, + rename_map_elt_info, eq_rename_map_elts, + get_new_name_from_old_name, bb_in_sese_p): Moved around. + (sese_find_uses_to_rename_use): Renamed sese_build_livein_liveouts_use. + (sese_find_uses_to_rename_bb): Renamed sese_build_livein_liveouts_bb. + (sese_build_livein_liveouts): New. + (new_sese, free_sese): New. + (new_scop): Call new_sese. + (free_scop): Call free_sese. + (rename_variables_from_edge, rename_phis_end_scop): Removed. + (register_old_new_names): Renamed register_old_and_new_names. + (register_scop_liveout_renames, add_loop_exit_phis, + insert_loop_close_phis, struct igp, + default_liveout_before_guard, add_guard_exit_phis, + insert_guard_phis, copy_renames): New. + (translate_clast): Call insert_loop_close_phis and insert_guard_phis. + (sese_add_exit_phis_edge): Renamed scop_add_exit_phis_edge. + (rewrite_into_sese_closed_ssa): Renamed scop_insert_phis_for_liveouts. + (scop_adjust_phis_for_liveouts): New. + (gloog): Call scop_adjust_phis_for_liveouts. + + * graphite.h (struct sese): Documented. Added fields liveout, + num_ver and livein. + (SESE_LIVEOUT, SESE_LIVEIN, SESE_LIVEIN_VER, SESE_NUM_VER): New. + (new_sese, free_sese, sese_build_livein_liveouts): Declared. + (struct scop): Added field liveout_renames. + (SCOP_LIVEOUT_RENAMES): New. + +2008-12-11 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/38409 + * gcc.dg/graphite/pr38409.c: New. + * graphite.c (nb_reductions_in_loop): Use simple_iv. + +2008-12-11 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (gcc_type_for_cloog_iv): By default return + integer_type_node. + (graphite_create_new_loop): Don't fold_convert the already + fold_convert-ed expression. + +2008-12-11 Harsha Jagasia <harsha.jagasia@amd.com> + + PR tree-optimization/38446 + * gcc.dg/graphite/pr38446.c: New. + * graphite.c (register_bb_in_sese): New. + (bb_in_sese_p): Check if bb belongs to sese region by explicitly + looking at the bbs in the region. + * graphite.h (sese): Add region_basic_blocks pointer set to + structure and initialize at the time of defining new scop. + +2008-12-11 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (new_graphite_bb): Initialize GBB_STATIC_SCHEDULE. + (find_params_in_bb): Do not free data refs. + (free_graphite_bb): Add FIXME on disabled free_data_refs. + +2008-12-11 Sebastian Pop <sebastian.pop@amd.com> + + * testsuite/gcc.dg/graphite/scop-16.c: Test only scop specific info. + * testsuite/gcc.dg/graphite/scop-17.c: Same. + * testsuite/gcc.dg/graphite/block-5.c: New. + * testsuite/gcc.dg/graphite/block-6.c: New. + * testsuite/gcc.dg/graphite/pr37485.c: Clean dump file after. + * testsuite/gcc.dg/graphite/pr37684.c: Same. + * testsuite/gcc.dg/graphite/block-2.c: Same. + + * graphite.c (struct ivtype_map_elt): New. + (debug_ivtype_elt, debug_ivtype_map_1, debug_ivtype_map, + new_ivtype_map_elt, ivtype_map_elt_info, eq_ivtype_map_elts, + gcc_type_for_cloog_iv): New. + (loop_iv_stack_patch_for_consts): Use the type of the induction + variable from the original loop, except for the automatically + generated loops, i.e., in the case of a strip-mined loop, in + which case there is no original loop: in that case just use + integer_type_node. + (new_graphite_bb): Initialize GBB_CLOOG_IV_TYPES. + (free_graphite_bb): Free GBB_CLOOG_IV_TYPES. + (clast_name_to_gcc): Accept params to be NULL. + (clast_to_gcc_expression): Take an extra parameter for the type. + Convert to that type all the expressions built by this function. + (gcc_type_for_clast_expr, gcc_type_for_clast_eq): New. + (graphite_translate_clast_equation): Compute the type of the + clast_equation before translating its LHS and RHS. + (clast_get_body_of_loop, gcc_type_for_iv_of_clast_loop): New. + (graphite_create_new_loop): Compute the type of the induction + variable before translating the lower and upper bounds and before + creating the induction variable. + (rename_variables_from_edge, rename_phis_end_scop): New. + (copy_bb_and_scalar_dependences): Call rename_phis_end_scop. + (sese_add_exit_phis_edge): Do not use integer_zero_node. + (find_cloog_iv_in_expr, compute_cloog_iv_types_1, + compute_cloog_iv_types): New. + (gloog): Call compute_cloog_iv_types before starting the + translation of the clast. + + * graphite.h (struct graphite_bb): New field cloog_iv_types. + (GBB_CLOOG_IV_TYPES): New. + (debug_ivtype_map): Declared. + (oldiv_for_loop): New. + +2008-12-10 Tobias Grosser <grosser@fim.uni-passau.de> + + PR middle-end/38459 + * graphite.c (new_scop): Initialize SCOP_ADD_PARAMS. + (param_index): Assert if parameter is not know after parameter + detection. + (find_params_in_bb): Detect params directly in GBB_CONDITIONS. + (find_scop_parameters): Mark, that we have finished parameter + detection. + (graphite_transform_loops): Move condition detection before parameter + detection. + * graphite.h (struct scop): Add SCOP_ADD_PARAMS. + * testsuite/gfortran.dg/graphite/pr38459.f90: New. + +2008-12-09 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (graphite_transform_loops): Always call find_transform () + in ENABLE_CHECKING. So we test these code paths, even if we do not + generate code. + +2008-12-09 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (print_graphite_bb): Fix printing to file != dump_file. + (print_scop): Ditto. + +2008-12-08 Tobias Grosser <grosser@fim.uni-passau.de> + + PR middle-end/38084 + Fix testsuite/gfortran.dg/graphite/id-3.f90. + * graphite.c (scopdet_basic_block_info): Fix bug that found some + regions more than once. + +2008-12-03 Sebastian Pop <sebastian.pop@amd.com> + + Fix testsuite/gfortran.dg/graphite/id-4.f90. + * graphite.c (scan_tree_for_params): Do not compute the multiplicand + when not needed. + +2008-12-03 Sebastian Pop <sebastian.pop@amd.com> + + Fix testsuite/gfortran.dg/graphite/id-1.f90. + * graphite.c (gmp_cst_to_tree): Pass the type in parameter. + (loop_iv_stack_patch_for_consts): Update use of gmp_cst_to_tree. + (max_precision_type): New. + (value_clast): Removed. + (clast_to_gcc_expression): Be more careful to types of expressions. + Use max_precision_type and update use of gmp_cst_to_tree. + (graphite_translate_clast_equation): Use max_precision_type. + (graphite_create_guard_cond_expr): Do not use integer_type_node, + use the type of the condition. + (graphite_create_new_loop): Do not use integer_type_node, use the + max_precision_type of lb and ub. + +2008-12-03 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (build_scops_1): Initialize open_scop.exit + and sinfo.last. + +2008-12-02 Sebastian Pop <sebastian.pop@amd.com> + + * testsuite/gcc.dg/graphite/pr38084.c: New. + * testsuite/gfortran.dg/graphite/id-1.f90: New. + * testsuite/gfortran.dg/graphite/id-2.f90: New. + * testsuite/gfortran.dg/graphite/id-3.f90: New. + * testsuite/gfortran.dg/graphite/id-4.f90: New. + * testsuite/gfortran.dg/graphite/pr37857.f90: New. + +2008-12-02 Sebastian Pop <sebastian.pop@amd.com> + Jan Sjodin <jan.sjodin@amd.com> + Harsha Jagasia <harsha.jagasia@amd.com> + + PR middle-end/37852 + PR middle-end/37883 + PR middle-end/37928 + PR middle-end/37980 + PR middle-end/38038 + PR middle-end/38039 + PR middle-end/38073 + PR middle-end/38083 + PR middle-end/38125 + + * testsuite/gcc.dg/graphite/pr38073.c: New. + * testsuite/gcc.dg/graphite/pr37928.c: New. + * testsuite/gcc.dg/graphite/pr37883.c: New. + * testsuite/gcc.dg/graphite/pr38125.c: New. + * testsuite/gfortran.dg/graphite/pr38083.f90: New. + * testsuite/gfortran.dg/graphite/pr37852.f90: New. + * testsuite/gfortran.dg/graphite/pr37980.f90: New. + + * testsuite/gcc.dg/graphite/scop-18.c: Remove reduction, test for + the number of detected scops. Copy exact same test for loop + blocking... + * testsuite/gcc.dg/graphite/block-1.c: Fix the number of expected + loops to be blocked as reductions are not handled. + * testsuite/gcc.dg/graphite/block-4.c: ...here. New. + + * tree-phinodes.c (remove_phi_nodes): New, extracted from... + * tree-cfg.c (remove_phi_nodes_and_edges_for_unreachable_block): + ...here. + * tree-flow.h (remove_phi_nodes, canonicalize_loop_ivs): Declared. + * Makefile.in (graphite.o): Depend on value-prof.h. + (graphite.o-warn): Removed -Wno-error. + * tree-parloops.c (canonicalize_loop_ivs): Allow reduction_list + to be a NULL pointer. Call update_stmt. Return the newly created + cannonical induction variable. + + * graphite.h (debug_rename_map): Declared. Fix some comments. + + * graphite.c: Reimplement the code generation from graphite to gimple. + Include value-prof.h. + (loop_iv_stack_get_iv): Do not return NULL for constant substitutions. + (get_old_iv_from_ssa_name): Removed. + (graphite_stmt_p): New. + (new_graphite_bb): Test for useful statements before building a + graphite statement for the basic block. + (free_graphite_bb): Do not free GBB_DATA_REFS: this is a bug + in free_data_ref that calls BITMAP_FREE (DR_VOPS (dr)) without + reason. + (recompute_all_dominators, graphite_verify, + nb_reductions_in_loop, graphite_loop_normal_form): New. + (scop_record_loop): Call graphite_loop_normal_form. + (build_scop_loop_nests): Iterate over all the blocks of the + function instead of relying on the incomplete information from + SCOP_BBS. Return the success of the operation. + (find_params_in_bb): Use the data from GBB_DATA_REFS. + (add_bb_domains): Removed. + (build_loop_iteration_domains): Don't call add_bb_domains. + Add the iteration domain only to the basic blocks that have been + translated to graphite. + (build_scop_conditions_1): Add constraints only if the basic + block have been translated to graphite. + (build_scop_data_accesses): Completely disabled until data + dependence is correctly implemented. + (debug_rename_elt, debug_rename_map_1, debug_rename_map): New. + (remove_all_edges_1, remove_all_edges): Removed. + (get_new_name_from_old_name): New. + (graphite_rename_variables_in_stmt): Renamed + rename_variables_in_stmt. Call get_new_name_from_old_name. + Use replace_exp and update_stmt. + (is_old_iv): Renamed is_iv. + (expand_scalar_variables_stmt): Extra parameter for renaming map. + Use replace_exp and update_stmt. + (expand_scalar_variables_expr): Same. Use the map to get the + new names for the renaming of induction variables and for the + renaming of variables after a basic block has been copied. + (expand_scalar_variables): Same. + (graphite_rename_variables): Renamed rename_variables. + (move_phi_nodes): Removed. + (get_false_edge_from_guard_bb): New. + (build_iv_mapping): Do not insert the induction variable of a + loop in the renaming iv map if the basic block does not belong + to that loop. + (register_old_new_names, graphite_copy_stmts_from_block, + copy_bb_and_scalar_dependences): New. + (translate_clast): Heavily reimplemented: copy basic blocks, + do not move them. Finally, in call cleanup_tree_cfg in gloog. + At each translation step call graphite_verify ensuring the + consistency of the SSA, loops and dominators information. + (collect_virtual_phis, find_vdef_for_var_in_bb, + find_vdef_for_var_1, find_vdef_for_var, + patch_phis_for_virtual_defs): Removed huge hack. + (mark_old_loops, remove_dead_loops, skip_phi_defs, + collect_scop_exit_phi_args, patch_scop_exit_phi_args, + gbb_can_be_ignored, scop_remove_ignoreable_gbbs, ): Removed. + (remove_sese_region, ifsese, if_region_entry, if_region_exit, + if_region_get_condition_block, if_region_set_false_region, + create_if_region_on_edge, move_sese_in_condition, bb_in_sese_p, + sese_find_uses_to_rename_use, sese_find_uses_to_rename_bb, + sese_add_exit_phis_edge, sese_add_exit_phis_var, + rewrite_into_sese_closed_ssa): New. + (gloog): Remove dead code. Early return if code cannot be + generated. Call cleanup_tree_cfg once the scop has been code + generated. + (graphite_trans_scop_block, graphite_trans_loop_block): Do not + block loops with less than two loops. + (graphite_apply_transformations): Remove the call to + scop_remove_ignoreable_gbbs. + (limit_scops): When build_scop_loop_nests fails, continue on + the next scop. Fix open_scop.entry. + (graphite_transform_loops): Call recompute_all_dominators: force the + recomputation of correct CDI_DOMINATORS and CDI_POST_DOMINATORS. + Call initialize_original_copy_tables and free_original_copy_tables + to be able to copy basic blocks during code generation. + When build_scop_loop_nests fails, continue on next scop. + (value_clast): New union. + (clast_to_gcc_expression): Fix type cast warning. + +2008-11-09 Sebastian Pop <sebastian.pop@amd.com> + + * Merge from mainline (r140838:141727). + +2008-11-05 Tobias Grosser <grosser@fim.uni-passau.de> + + PR middle-end/37833 + + * graphite.c (scan_tree_for_params): Add POINTER_PLUS_EXPR. + +2008-11-05 Tobias Grosser <grosser@fim.uni-passau.de> + + PR middle-end/37943 + + * graphite.c (scopdet_basic_block_info): Fix loops with multiple + exits and conditions. + * testsuite/gcc.dg/graphite/pr37943.c: New. + +2008-10-23 Tobias Grosser <grosser@fim.uni-passau.de> + + PR middle-end/37886 + * graphite.c (gloog): Replace EXIT_BLOCK_PTR with scop exit. + +2008-10-23 Tobias Grosser <grosser@fim.uni-passau.de> + + * doc/invoke.texi: Fix spaces. + +2008-10-22 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/37891 + Reverted last commit. + * graphite.c (create_single_entry_edge): Set + EDGE_IRREDUCIBLE_LOOP and BB_IRREDUCIBLE_LOOP. + +2008-10-21 Sebastian Pop <sebastian.pop@amd.com> + Mitul Thakkar <mitul.thakkar@amd.com> + + * graphite.c (create_single_entry_edge): Set + EDGE_IRREDUCIBLE_LOOP and BB_IRREDUCIBLE_LOOP. + +2008-10-16 Tobias Grosser <grosser@fim.uni-passau.de> + + * doc/invoke.texi: Add -fgraphite-identity. + * graphite.c (graphite_apply_transformations): Check for + -fgraphite-identity. + * toplev.c (process_options): Add flag_graphite_identity. + * tree-ssa-loop.c: Add flag_graphite_identity. + +2008-10-14 Sebastian Pop <sebastian.pop@amd.com> + + Undo changes from 2008-10-02: + * tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Convert + operand type when copying the operand to a variable of different type. + * cfgloopmanip.c (create_empty_loop_on_edge): Write exit condition + with the IV name after increment. + +2008-10-14 Sebastian Pop <sebastian.pop@amd.com> + Harsha Jagasia <harsha.jagasia@amd.com> + + PR tree-optimization/37828 + * testsuite/gcc.dg/graphite/pr37828.c: New. + * graphite.c (graphite_trans_loop_block): Do not loop block + single nested loops. + +2008-10-09 Harsha Jagasia <harsha.jagasia@amd.com> + Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (struct rename_map_elt, new_rename_map_elt, + rename_map_elt_info, eq_rename_map_elts): New. + (graphite_rename_ivs_stmt): Renamed graphite_rename_variables_in_stmt. + (expand_scalar_variables_expr): Change parameters. + (expand_scalar_variables_stmt): Same. + (expand_scalar_variables): Same. + (graphite_rename_ivs): Rename graphite_rename_variables. + (build_iv_mapping): New. + (translate_clast): Call build_iv_mapping. + * graphite.h (gbb_p): New name. + +2008-10-03 Harsha Jagasia <harsha.jagasia@amd.com> + + PR tree-optimization/37684 + * gcc.dg/graphite/pr37684.c: New. + * graphite.c (exclude_component_ref): New. + (is_simple_operand): Call exclude_component_ref. + +2008-10-02 Jan Sjodin <jan.sjodin@amd.com> + Harsha Jagasia <harsha.jagasia@amd.com> + + PR tree-optimization/37485 + * gcc.dg/graphite/block-2.c: New + * graphite.c (gmp_cst_to_tree): Moved. + (iv_stack_entry_is_constant): New. + (iv_stack_entry_is_iv): New. + (loop_iv_stack_push): Renamed to loop_iv_stack_push_iv. + (loop_iv_stack_insert_constant): New. + (loop_iv_stack_pop): Use new datatpype. + (loop_iv_stack_get_iv): Same. + (loop_iv_stack_get_iv_from_name): Same. + (loop_iv_stack_debug): Renamed to debug_loop_iv_stack. + (loop_iv_stack_patch_for_consts): New. + (loop_iv_stack_remove_constants): New. + (graphite_create_new_loop): Use loop_iv_stack_push_iv. + (translate_clast): Call loop_iv_stack_patch_for_consts and + loop_iv_stack_remove_constants. + (gloog): Use new datatype. Redirect construction edge to end + block to avoid accidental deletion. + * graphite.h (enum iv_stack_entry_kind): New. Tag for data in + iv stack entry. + (union iv_stack_entry_data): New. Data in iv stack entry. + (struct iv_stack_entry): New. Datatype for iv stack entries. + +2008-10-02 Sebastian Pop <sebastian.pop@amd.com> + + * tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Convert + operand type when copying the operand to a variable of different type. + +2008-10-02 Sebastian Pop <sebastian.pop@amd.com> + + * cfgloopmanip.c (create_empty_loop_on_edge): Write exit condition + with the IV name after increment. + +2008-10-02 Sebastian Pop <sebastian.pop@amd.com> + + * Merge from mainline (r140164:140838). + +2008-09-10 Konrad Trifunovic <konrad.trifunovic@inria.fr> + + * graphite-data-ref.c: New. + * graphite.c (print_scop): Also dump the dependence graph. + (bb_in_scop_p, loop_in_scop_p, nb_loops_around_gb): Moved... + (new_scop): Initialize SCOP_DEP_GRAPH. + (build_scop_dynamic_schedules): New. + (build_access_matrix_with_af): Fixed column numbering. + (graphite_transform_loops): Call build_scop_dynamic_schedules. + * graphite.h: Add ifndef/define guards against multiple inclusion. + (struct scop): Add dep_graph field. + (SCOP_DEP_GRAPH): Defined. + (ref_nb_loops): Fixed and moved to other position. + (bb_in_scop_p, loop_in_scop_p, nb_loops_around_gb): ... here. + (nb_loops_around_loop_in_scop): New. + (graphite_dump_dependence_graph): Declared. + (graphite_build_rdg_all_levels): Declared. + (graphite_test_dependence): Declared. + * Makefile.in (graphite-data-ref.o): New target. + +2008-09-09 Sebastian Pop <sebastian.pop@amd.com> + + * Merge from mainline (139870:140164). + +2008-09-01 Sebastian Pop <sebastian.pop@amd.com> + + * Merge from mainline (138275:139870). + * testsuite/gcc.dg/graphite/scop-matmult.c: XFailed as one of + the commits from trunk broke the niter detection. + +2008-09-01 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c: Add more documentation. Fix formatting. + (debug_loop_vec, debug_oldivs, loop_iv_stack, + loop_iv_stack_debug): Moved... + (schedule_to_scattering): Move before use. + (dot_all_scops): Include in "#if 0" the code for system + call dotty. + + * graphite.h: (debug_loop_vec, debug_oldivs, loop_iv_stack, + loop_iv_stack_debug): ...here. + +2008-08-29 Jan Sjodin <jan.sjodin@amd.com> + + * tree-phinodes.c (make_phi_node): Extern. + (add_phi_node_to_bb): New. + (create_phi_node): Call add_phi_node_to_bb. + * tree-ssa-loop-ivopts.c (get_phi_with_result): New. + (remove_statement): Handle case where stored phi was updated + and is no longer the same. + * graphite.c (is_parameter): New. + (is_old_iv): New. + (expand_scalar_variables_expr): New. + (expand_scalar_variables_stmt): New. + (expand_scalar_variables): New. + (move_phi_nodes): Create new phi instead of moving old one. + (translate_clast): Call expand_scalar_variables. + (find_vdef_for_var_in_bb): Also scan regular definitions. + (skip_phi_defs): New. + (collect_scop_exit_phi_args): New. + (patch_scop_exit_phi_args): New. + (gloog): Patch phis after scop. + * tree-flow.h: (add_phi_node_to_bb): Declared. + (make_phi_node): Declared. + +2008-08-26 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (end_scop): Split the entry of the scop when it + is the header of the loop in which the scop is ending. + (build_scops_1, limit_scops): Update uses of end_scop. + +2008-08-26 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (dot_all_scops_1): Do not fail on uninitialized + SCOP_ENTRY or SCOP_EXIT. + +2008-08-25 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (get_construction_edge): Removed. + (gloog): Construction edge is the scop entry edge. + +2008-08-25 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (can_generate_for_scop): Removed. + (gloog): Do not call it. + +2008-08-25 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (new_scop): Entry of a scop is an edge. + Initialize SESE region. + (free_scop): Free SESE region. + (build_scops_1, scopdet_bb_info): Work on edges, not on bbs. + (split_difficult_bb): New, split from end_scop. + (end_scop): Exit of a scop is an edge. + (build_scop_bbs): Never check CDI_POST_DOMINATORS: this info is + not automatically updated and thus is always wrong. + * graphite.h (struct sese): New. + (SESE_ENTRY): New. + (SESE_EXIT): New. + (struct scop): New field for a SESE region. Remove entry, exit. + (SCOP_ENTRY, SCOP_EXIT): Update definitions to match same + semantics as before. Moved comment around. + +2008-08-25 Tobias Grosser <grosser@fim.uni-passau.de> + Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (graphite_transform_loops): Always enable gloog + and find_transform when ENABLE_CHECKING. + +2008-08-25 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (graphite_transform_loops): Move pretty printer + of SCOPs before doing any transform. Remove call to print_scops + and dot_all_scops_1. + +2008-08-25 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (dump_gbb_conditions): Don't try to print NULL pointers. + (print_graphite_bb): Same. + +2008-08-25 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (dot_all_scops_1): Cleanup. + (move_scops): Fix comment. + +2008-08-25 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (build_scop_bbs): Revert commit 139355: + + 2008-08-20 Sebastian Pop <sebastian.pop@amd.com> + Dwarakanath Rajagopal <dwarak.rajagopal@amd.com> + + * graphite.c (build_scop_bbs): Factor up code. + +2008-08-25 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (gloog): Update dominator info. + +2008-08-25 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (remove_cond_exprs): Do not fail on empty bbs. + +2008-08-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (new_graphite_bb): Remove GBB_INDEX_TO_NUM_MAP + initialization. + (free_graphite_bb): Remove GBB_INDEX_TO_NUM_MAP free. + (translate_clast): Correct formatting. + * graphite.h (struct num_map): Removed. + (struct graphite_bb): Remove num_map field. + (GBB_INDEX_TO_NUM_MAP): Removed. + +2008-08-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (build_access_matrix_with_af): Fix comments. + (build_scop_data_accesses): Same. + +2008-08-24 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (build_scop_data_accesses): Don't construct + access matrices. Add a FIXME and an assert condition that + should pass when the access matrices will be needed. + +2008-08-24 Sebastian Pop <sebastian.pop@amd.com> + + * tree-data-ref.c (stmt_simple_memref_p): Don't call + really_constant_p. + * graphite.c (build_graphite_bb): Renamed new_graphite_bb. + Moved close by free_graphite_bb. + (free_graphite_bb): Call free_data_refs. Reset bb->aux. + (new_scop): Move close by free_scop. + (graphite_transform_loops): Avoid linear scan to reset bb->aux. + +2008-08-22 Jan Sjodin <jan.sjodin@amd.com> + + * cfgloopmanip.c (create_empty_if_region_on_edge): New. + * graphite.c (clast_to_gcc_expression): Call gmp_cst_to_tree + instead of recursive call. + (graphite_translate_clast_equation): New. + (graphite_create_guard_cond_expr): New. + (graphite_create_new_guard): New. + (get_stack_index_from_iv): Removed. + (graphite_rename_ivs_stmt): Use gbb_loop_index. + (get_true_edge_from_guard_bb): New. + (translate_clast): Handle stmt_guard in clast. + (get_construction_edge): Allow construction edge detection for + a scope entry with multiple predecessors if one predecessor is + the immediate dominator of scope entry. + (can_generate_code_stmt): Enable code generation for clast_guard. + (gloog): Use correct context loop. Removed check for post dominators. + * cfgloop.h (create_empty_if_region_on_edge): Declared. + +2008-08-21 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (remove_dead_loops): Document better which + loops are removed. + +2008-08-21 Sebastian Pop <sebastian.pop@amd.com> + + * Makefile.in: Rename POLYLIBLIBS and POLYLIBINC to PPLLIBS + and PPLINC. + (graphite.o): Also depends on pointer-set.h. + +2008-08-21 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (scop_record_loop): Fix compile warning. + +2008-08-21 Harsha Jagasia <harsha.jagasia@amd.com> + Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (scop_record_loop): DECL_NAME can be NULL. + +2008-08-21 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (build_graphite_bb): Initialize bb->aux to + point to the graphite_bb_p. + (graphite_bb_from_bb): Renamed gbb_from_bb; returns the + content of bb->aux. + (add_bb_domains): Does not use the scop parameter. + (graphite_transform_loops): Clean bb->aux at the end. + +2008-08-20 Dwarakanath Rajagopal <dwarak.rajagopal@amd.com> + Sebastian Pop <sebastian.pop@amd.com> + + * testsuite/lib/target-supports.exp + (check_effective_target_fgraphite): New. + + * testsuite/gcc.dg/graphite/graphite.exp: Early exit when + check_effective_target_fgraphite returns false. + Set dg-do-what-default to compile. + (scan-graphite-dump-times): Removed. + * testsuite/gfortran.dg/graphite/graphite.exp: Same. + + * testsuite/gcc.dg/graphite/scop-0.c: Do not use "dg-do compile". + Use scan-tree-dump-times instead of scan-graphite-dump-times. + * testsuite/gcc.dg/graphite/scop-1.c: Same. + * testsuite/gcc.dg/graphite/scop-2.c: Same. + * testsuite/gcc.dg/graphite/scop-3.c: Same. + * testsuite/gcc.dg/graphite/scop-4.c: Same. + * testsuite/gcc.dg/graphite/scop-5.c: Same. + * testsuite/gcc.dg/graphite/scop-6.c: Same. + * testsuite/gcc.dg/graphite/scop-7.c: Same. + * testsuite/gcc.dg/graphite/scop-8.c: Same. + * testsuite/gcc.dg/graphite/scop-9.c: Same. + * testsuite/gcc.dg/graphite/scop-10.c: Same. + * testsuite/gcc.dg/graphite/scop-11.c: Same. + * testsuite/gcc.dg/graphite/scop-12.c: Same. + * testsuite/gcc.dg/graphite/scop-13.c: Same. + * testsuite/gcc.dg/graphite/scop-matmult.c: Same. + * testsuite/gcc.dg/graphite/scop-14.c: Same. + * testsuite/gcc.dg/graphite/scop-15.c: Same. + * testsuite/gcc.dg/graphite/block-0.c: Same. + * testsuite/gcc.dg/graphite/scop-16.c: Same. + * testsuite/gcc.dg/graphite/block-1.c: Same. + * testsuite/gcc.dg/graphite/scop-17.c: Same. + * testsuite/gcc.dg/graphite/scop-18.c: Same. + * testsuite/gfortran.dg/graphite/block-1.f90: Same. + * testsuite/gfortran.dg/graphite/scop-1.f: Same. + * testsuite/gfortran.dg/graphite/block-2.f: Same. + +2008-08-20 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c: Fix some XXX comments. + (build_scop_dynamic_schedules): Removed. + +2008-08-20 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.h (scop_max_loop_depth): Moved... + * graphite.c (scop_max_loop_depth): ...here. + (remove_all_edges_1): New. + (remove_all_edges): Factored code. + (remove_cond_exprs): Check only the last statement for + a GIMPLE_COND expression. + +2008-08-20 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (scan_tree_for_params): Early return when the + expression is a chrec_dont_know. Handle case NEGATE_EXPR. + (find_scop_parameters): Factor out code. + (graphite_trans_bb_strip_mine): Remove dead code. + +2008-08-20 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (clast_to_gcc_expression, graphite_create_new_loop, + graphite_trans_bb_move_loop): Factor asserts. + (gloog): Perform sanity checks only for ENABLE_CHECKING. + Do not call calculate_dominance_info and estimate_bb_frequencies. + +2008-08-20 Jan Sjodin <jan.sjodin@amd.com> + + * graphite.c (create_loops_mapping, free_loops_mapping, + create_loops_mapping_num, debug_loop_mapping_1, + debug_loop_mapping, graphite_loops_mapping_max_loop_num, + get_loop_mapping_for_num, graphite_loops_mapping_add_child, + graphite_loops_mapping_add_child_num, + graphite_loops_mapping_insert_child, + graphite_loops_mapping_parent, get_loop_mapped_depth_for_num, + get_loop_mapped_depth, split_loop_mapped_depth_for_num, + loop_mapped_depth_split_loop, swap_loop_mapped_depth_for_num, + create_num_from_index, get_num_from_index, + swap_loop_mapped_depth): Removed. + (new_scop): Do not initialize SCOP_LOOPS_MAPPING. + (free_scop): Do not call free_loops_mapping. + (graphite_get_new_iv_stack_index_from_old_iv): Renamed + get_stack_index_from_iv. Use GBB_LOOPS instead of calling + get_loop_mapped_depth. + (graphite_trans_bb_move_loop): Do not update the loop mapping. + (graphite_trans_bb_strip_mine): Same. + * graphite.h (graphite_loops_mapping, graphite_loop_node): Removed. + (struct scop): Remove field loops_mapping. + +2008-08-20 Sebastian Pop <sebastian.pop@amd.com> + Dwarakanath Rajagopal <dwarak.rajagopal@amd.com> + + * graphite.c (scop_record_loop): Factor out one level of the + condition by early return. + (build_scop_loop_nests): Format following FSF coding style. + (build_scop_dynamic_schedules): Factor out code. + (scopdet_bb_info): Reindent. Default case should not be reachable. + +2008-08-20 Sebastian Pop <sebastian.pop@amd.com> + Dwarakanath Rajagopal <dwarak.rajagopal@amd.com> + + * graphite.c (loop_affine_expr): Check for DECL_P or struct + assignments that are not handled as simple operands for now. + +2008-08-20 Sebastian Pop <sebastian.pop@amd.com> + Dwarakanath Rajagopal <dwarak.rajagopal@amd.com> + + * graphite.c (build_scop_bbs): Factor up code. + +2008-08-20 Sebastian Pop <sebastian.pop@amd.com> + Dwarakanath Rajagopal <dwarak.rajagopal@amd.com> + + * graphite.c (stmt_simple_for_scop_p): Factor code out + of the loop. + (enum gbb_type): New. Group all the GBB_* types under it. + (is_loop_exit): Moved... + (end_scop): Enable BB spliting. + * cfgloop.c (is_loop_exit): ...here. Reimplemented. + * cfgloop.h (is_loop_exit): Declared. + +2008-08-20 Sebastian Pop <sebastian.pop@amd.com> + + * doc/invoke.texi: Remove strides from examples containing + DO loops when the strides are equal to 1. + +2008-08-20 Harsha Jagasia <harsha.jagasia@amd.com> + Dwarakanath Rajagopal <dwarak.rajagopal@amd.com> + + * graphite.c (graphite_trans_scop_block): Or the result with + the result from graphite_trans_loop_block. + * testsuite/gcc.dg/graphite/block-1.c: New. + * testsuite/gfortran.dg/graphite/block-1.f90: New. + * testsuite/gfortran.dg/graphite/block-2.f: New. + +2008-08-20 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (graphite_transform_loops): Call cloog_initialize + and cloog_finalize. + +2008-08-20 Sebastian Pop <sebastian.pop@amd.com> + + * tree-data-ref.c) (stmt_simple_memref_p): New. + * tree-data-ref.h (stmt_simple_memref_p): Declared. + * graphite.c (stmt_simple_memref_for_scop_p): Removed. + (is_simple_operand): Call stmt_simple_memref_p. + + * testsuite/gcc.dg/graphite/scop-matmult.c: Updated for not + using pointer arithmetic, as this is optimized by PRE and + makes the code too difficult to analyze. + + * testsuite/gcc.dg/graphite/scop-18.c: Same. + +2008-08-20 Sebastian Pop <sebastian.pop@amd.com> + + * gdbinit.in (pgg): New. + +2008-08-15 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (graphite_trans_loop_block): Fix warning. + +2008-08-15 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (graphite_trans_loop_block): Fix my merge error. + +2008-08-15 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (graphite_trans_bb_block): Remove check for + flag_loop_strip_mine, flag_loop_block, flag_loop_interchange. + Check if loop blocking is profitable for every loop, before applying + the changes. + (graphite_apply_transformations): Call graphite_trans_bb_block only, + if flag_loop_block is set. + +2008-08-14 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c: Add some more documentation for the loop + mapping. + +2008-08-14 Sebastian Pop <sebastian.pop@amd.com> + + * Makefile.in (tree-data-ref.o): Remove dependence on graphite.h. + * graphite.c: Format on less than 80 columns. + * graphite.h: Same. + +2008-08-14 Sebastian Pop <sebastian.pop@amd.com> + + * cfgloopmanip.c (loopify): Use update_dominators_in_loop. + +2008-08-14 Sebastian Pop <sebastian.pop@amd.com> + + * doc/invoke.texi (floop-block, floop-strip-mine, + floop-interchange): Update documentation with examples. + +2008-08-13 Sebastian Pop <sebastian.pop@amd.com> + + * cfgloopmanip.c (create_empty_loop_on_edge): Don't call + add_referenced_var. + * graphite.c (graphite_create_new_loop): Call add_referenced_var. + +2008-08-13 Sebastian Pop <sebastian.pop@amd.com> + + * cfgloopmanip.c (create_empty_loop_on_edge): Improve documentation. + Factor gcc_asserts into a single one. Use force_gimple_operand_gsi. + * tree-scalar-evolution.c: Revert useless changes. + * tree-phinodes.c: Same. + * cfghooks.c: Same. + * vec.h: Same. + * tree-vectorizer.h: Same. + * tree-flow.h: Same. + * tree-cfg.c: Same. + * common.opt (fgraphite): Update documentation. + +2008-08-12 Harsha Jagasia <harsha.jagasia@amd.com> + + * doc/invoke.texi (-floop-block, -floop-strip-mine, + -floop-interchange): Add more text for explaining what each of these + flags is doing. + * tree-into-ssa.c (gimple_vec): Moved to... + * graphite.c: Include gimple.h. + (gimple_vec): Moved to... + (del_loop_to_cloog_loop): Removed. + (loop_affine_expr): Do not call create_data_ref when the + operand is a constant. + (new_scop): Use free instead of del_loop_to_cloog_loop. + * Makefile.in (graphite.o): Depend on GIMPLE_H. + * gimple.h (gimple_vec): ... here. + +2008-08-11 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (scopdet_bb_info): Only allow loops with known number of + latch executions. + (build_loop_iteration_domains): Fail, if latch executions unknown. + +2008-08-11 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (add_conditions_to_domain): New. + (build_scop_conditions_1): Call add_conditions_to_domain. + (set_cloog_options): Allow to disable optimizations. + +2008-08-11 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (find_params_in_bb): Look for parameters in conditions. + Do not use walk_dominator_tree. + (find_scop_parameters): Do not use walk_dominator_tree. + +2008-08-11 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (scan_tree_for_params) Add / Subtract inequality. + (idx_record_params): Adapt. + * graphite.h (scop_gimple_loop_depth): New. + +2008-08-11 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (build_scop_dynamic_schedules): Remove value_init. + (scan_tree_for_params): Remove value_init. + (build_scop_context): Remove value_init. + (build_loop_iteration_domains): Remove value_init. + (schedule_to_scattering): Remove value_init. + (graphite_trans_bb_strip_mine): Remove value_init. + +2008-08-11 Tobias Grosser <grosser@fim.uni-passau.de> + + * gcc/graphite.c (limit_scops): New. + (graphite_transform_loops): Add limit SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-0.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-1.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-10.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-11.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-12.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-13.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-14.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-15.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-16.c: Update number of SCoPs. + Change loop numbers. + * gcc/testsuite/gcc.dg/graphite/scop-17.c: Update number of SCoPs. + Change loop numbers. + * gcc/testsuite/gcc.dg/graphite/scop-18.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-2.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-3.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-4.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-5.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-6.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-7.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-8.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-9.c: Update number of SCoPs. + * gcc/testsuite/gcc.dg/graphite/scop-matmult.c: Update number of SCoPs. + +2008-08-11 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (graphite_transform_loops): Call always find_transform. + +2008-08-08 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (free_loops_mapping): New. + (stmt_simple_for_scop_p): Fix typo. + (stmt_simple_for_scop_p): Fix tuples functions, that + broke polyhedron. + (free_graphite_bb): Fix some memleaks. + (free_scop): Fix some memleaks. + (scopdet_bb_info): Do not forget some tmp SCoPs. + (find_params_in_bb): Fix some memleaks. + (clast_to_gcc_expression): Fix warning. + +2008-08-07 Tobias Grosser <grosser@fim.uni-passau.de> + + * testsuite/gcc.dg/graphite/scop-16.c: Fix for 32bit. + * testsuite/gcc.dg/graphite/scop-17.c: Fix for 32bit. + +2008-08-04 Sebastian Pop <sebastian.pop@amd.com> + + * tree-ssa-loop.c (tree-ssa-loop.o): Do not include toplev.h. + Move code ifdef-ed HAVE_cloog... + * graphite.c: Include toplev.h. + ... here. + * Makefile.in (OBJS-common): Always build graphite.o. + (BACKEND): Remove @GRAPHITE@. + (tree-ssa-loop.o): Do not depend on TOPLEV_H. + (graphite.o): Depend on TOPLEV_H. + +2008-08-04 Sebastian Pop <sebastian.pop@amd.com> + + * Makefile.in (tree-ssa-loop.o): Depend on TOPLEV_H. + Remove typo left from polylib to ppl conversion. + * graphite.c (graphite_transforms): Use sorry instead of fatal. + +2008-08-03 Sebastian Pop <sebastian.pop@amd.com> + + * toplev.c (process_options): Move the graphite loop optimization + flags... + * tree-ssa-loop.c (graphite_transforms): ... here. + When not configured with CLooG, print to dump_file that + Graphite transforms were not performed. + * testsuite/gcc.dg/graphite/graphite.exp (scan-graphite-dump-times): + New. + * testsuite/gcc.dg/graphite/*.c: Updated all testcases to use + scan-graphite-dump-times. + +2008-08-03 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (dot_scop, dot_all_scops): Do not call system. + Do not open /tmp/scop.dot and /tmp/allscops.dot. + +2008-08-02 Sebastian Pop <sebastian.pop@amd.com> + Jan Sjodin <jan.sjodin@amd.com> + + * configure: Regenerated. + * omp-low.c (expand_omp_sections): Remove now unused code. + * config.in (HAVE_polylib): Removed. + * configure.ac (HAVE_polylib, POLYLIBLIBS, POLYLIBINC): Removed. + (PPLLIBS, PPLINC): Added. + * graphite.c: Replace unsigned with int wherever possible. + Don't access Cloog's data structures, but use accessor functions. + Clast's stmt->type is now implemented as a vtable: change the + switches of stmt->type into ifs. + (polylib/polylibgmp.h): Don't include. + (initialize_dependence_polyhedron, + initialize_data_dependence_polyhedron, is_empty_polyhedron, + statement_precedes_p, test_dependence, build_rdg_all_levels, + dump_dependence_graph): Removed until this code is cleaned up + or ported to Cloog. + * Makefile.in (POLYLIBLIBS): Renamed PPLLIBS. + (POLYLIBINC): Renamed PPLINC. + +2008-08-01 Harsha Jagasia <harsha.jagasia@amd.com> + Dwarakanath Rajagopal <dwarak.rajagopal@amd.com> + Jan Sjodin <jan.sjodin@amd.com> + + Finish the merge and tuplification of graphite. + +2008-07-24 Sebastian Pop <sebastian.pop@amd.com> + Jan Sjodin <jan.sjodin@amd.com> + + Partial merge from mainline (138072:138275). + * graphite.c still has to be tuplified. + +2008-07-29 Jan Sjodin <jan.sjodin@amd.com> + + * graphite.c (graphite_loops_mapping_max_loop_num): New. + (create_num_from_index): New. + (get_num_from_index): Also pass in the graphite BB. + (free_graphite_bb): Free GBB_INDEX_TO_NUM_MAP. + (build_graphite_bb): Initialize GBB_INDEX_TO_NUM_MAP. + (graphite_trans_bb_strip_mine): Call create_num_from_index. + (is_interchange_valid): Return false when failing. + * graphite.h (struct num_map): New. + (struct graphite_bb): New field num_map. + (GBB_LOOPS_MAPPING): Renamed GBB_INDEX_TO_NUM_MAP. + +2008-07-29 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (dump_gbb_conditions): Print also conditions like + "if (a)". Remove dublicated code and use print_generic_expr (). + (stmt_simple_for_scop_p): Only allow conditions we can handle + {<, <=, >, >=}. + +2008-07-25 Jan Sjodin <jan.sjodin@amd.com> + + * graphite.h (struct scop): Removed new_ivs field. + (SCOP_NEWIVS): Deleted. + * graphite.c (new_scop, free_scop, clast_name_to_gcc, + clast_to_gcc_expression, graphite_create_new_loop): + Removed use of new_ivs. + +2008-07-25 Jan Sjodin <jan.sjodin@amd.com> + + * graphite.c (debug_oldivs, debug_loop_vec, create_loops_mapping, + create_loops_mapping_num, debug_loop_mapping_1): New. + (debug_loop_mapping): Call debug_loop_mapping_1. + (get_loop_mapping_for_num, + graphite_loops_mapping_add_child, + graphite_loops_mapping_add_child_num, + graphite_loops_mapping_insert_child, + graphite_loops_mapping_parent, + split_loop_mapped_depth_for_num, + loop_mapped_depth_split_loop): New. + (increment_loop_mapped_depths): Removed. + (swap_loop_mapped_depth_for_num): Reimplemented. + (new_scop): Call create_loops_mapping. + (scop_record_loop): Call graphite_loops_mapping_insert_child. + (translate_clast): Pass the old loop father in parameter, and pass + it to get_old_iv_from_ssa_name. + (remove_edges_around_useless_blocks, can_generate_code_stmt, + can_generate_code, can_generate_for_scop): New. + (graphite_trans_bb_block): Returns false when it fails to transform. + * graphite.h (graphite_loop_node, graphite_loops_mapping): New. + +2008-07-25 Sebastian Pop <sebastian.pop@amd.com> + + Reverted all the changes related to the streamization and + loop fusion. + These changes are now tracked in the streamization branch. + +2008-07-25 Sebastian Pop <sebastian.pop@amd.com> + Jan Sjodin <jan.sjodin@amd.com> + + * graphite.c (gbb_compare): Correctly constify. + (gbb_can_be_ignored): Indent. + (graphite_trans_scop_swap_1and2): Add legality check. + Remove dead FIXMEs. + +2008-07-25 Sebastian Pop <sebastian.pop@amd.com> + + Remove fallouts from "Reverted the Condate changes". + * tree.h: Remove unused decl. + * testsuite/gcc.dg/tree-checker: Same. + * timevar.def: Remove counter. + +2008-07-24 Sebastian Pop <sebastian.pop@amd.com> + + * Merge from mainline (135673:138072). + + Reverted the MIRO changes (from 2008-04-05) that are now + tracked in the miro branch. + * tree-bounds.c: Removed. + * tree-bounds.h: Removed. + + Reverted the Condate changes (from 2006-07-04, 2007-03-20) that + are now tracked in the condate branch. + * tree-check.c: Removed. + * tree-match.c: Removed. + * condate.y: Removed. + +2008-07-24 Dwarakanath Rajagopal <dwarak.rajagopal@amd.com> + + * common.opt: New user flag -floop-block, -floop-strip-mine + and -floop-interchange. + * toplev.c (process_options): Enable -fgraphite pass if any one of the + graphite loop optimization flags is turned on. + * graphite.c (graphite_apply_transformations): Add flag_loop_block, + flag_loop_strip_mine and flag_loop_interchange checks before + optimizations. + * doc/invoke.texi: Remove -fgraphite and add -floop-block, + -floop-strip-mine and -floop-interchange. + * testsuite/gcc.dg/graphite/block-0.c: Add -floop-block and remove + -fgraphite. + * testsuite/gcc.dg/graphite/scop-16.c: Ditto. + * testsuite/gcc.dg/graphite/scop-17.c: Ditto. + * testsuite/gcc.dg/graphite/scop-18.c: Ditto. + +2008-07-23 Jan Sjodin <jan.sjodin@amd.com> + Sebastian Pop <sebastian.pop@amd.com> + + * cfgloopmanip.c (update_dominators_in_loop): Make it static. + (create_empty_loop_on_edge): More fixes. + * tree-phinodes.c (resize_phi_node): Extern. + (unlink_phi_node, move_phi_node): New split from remove_phi_node. + * cfghooks.c (update_dominator_information): New split from + split_edge. + * tree-vectorizer.c (rename_variables_in_bb): Extern. + * tree-dfa.c (collect_dfa_stats): Start walking the CFG on the + successor of the function entry block. + + * graphite.c: Include pointer-set.h. + (debug_loop_mapping, increment_loop_mapped_depths, + get_loop_mapped_depth_for_num, get_loop_mapped_depth, + set_loop_mapped_depth_for_num, set_loop_mapped_depth, + swap_loop_mapped_depth_for_num, get_num_from_index, + swap_loop_mapped_depth, loop_iv_stack_debug, + loop_iv_stack_push, loop_iv_stack_pop, loop_iv_stack_get_iv, + loop_iv_stack_get_iv_from_name, loop_iv_stack_debug, + get_old_iv_from_ssa_name): New. + (new_scop): Initialize SCOP_LOOPS_MAPPING. + (free_scop): Free SCOP_LOOPS_MAPPING. + (scop_record_loop): Record old ivs. + (create_var_name): Removed. + (initialize_cloog_names): Allocate double space in case strip mine + applies to all loops once. + (clast_name_to_gcc): Look up in the map ivstack passed in parameter. + (clast_to_gcc_expression): Same. Implement more clast to gimple + translation. + (graphite_create_new_loop): Pass in ivstack. + (remove_all_edges): Pass in the construction_edge. + (graphite_remove_iv): Removed. + (graphite_rename_ivs, graphite_rename_ivs_stmt, + remove_cond_exprs): Rewritten. + (move_phi_nodes): New. + (disconnect_virtual_phi_nodes, disconnect_cond_expr): Removed. + (translate_clast): Pass in ivstack. Rewrite some cases. + (set_cloog_options, debug_clast_stmt): New. + (find_transform): Use set_cloog_options. + (outermost_loop_layer): Removed. + (get_construction_edge, collect_virtual_phis, find_vdef_for_var_in_bb, + find_vdef_for_var_1, find_vdef_for_var, patch_phis_for_virtual_defs, + mark_old_loops, remove_dead_loops): New. + (gloog): Rewritten. + (graphite_trans_bb_move_loop): Call swap_loop_mapped_depth. + (const_column_index, get_first_matching_sign_row_index, + get_lower_bound_row, get_upper_bound_row, get_lower_bound, + get_upper_bound): New. + (graphite_trans_bb_strip_mine): Also update the iv map. + + * graphite.h (graphite_loops_mapping, GBB_LOOPS_MAPPING): New. + (struct name_tree): Add a loop field. + (struct scop): Add a graphite_loops_mapping field. + (SCOP_LOOPS_MAPPING): New. + (debug_clast_stmt): Declare. + * lambda.h (find_induction_var_from_exit_cond): Declare. + (lambda-code.c): (find_induction_var_from_exit_cond): Extern. + * cfgloop.h (update_dominators_in_loop): Removed declaration. + (create_empty_loop_on_edge): Updated. + * tree-flow.h (remove_bb, resize_phi_node, move_phi_node, + rename_variables_in_bb): Declare. + * tree-cfg.c (remove_bb): Extern. + + * testsuite/gcc.dg/graphite/block-0.c: New. + +2008-07-21 Dwarakanath Rajagopal <dwarak.rajagopal@amd.com> + Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (strip_mine_profitable_p): New. + (graphite_trans_bb_block): Disable strip mining if not profitable. + + * testsuite/gcc.dg/graphite/scop-18.c: New. + * testsuite/gcc.dg/graphite/scop-17.c: Fixed. + * testsuite/gcc.dg/graphite/scop-16.c: Fixed. + +2008-07-17 Harsha Jagasia <harsha.jagasia@amd.com> + Jan Sjodin <jan.sjodin@amd.com> + Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (is_interchange_valid): New. + (graphite_trans_bb_block): Check loop nest of basic block for legality + of interchange. + + * graphite.h (gbb_inner_most_loop_index, outer_most_loop_1, + outer_most_loop, gbb_outer_most_loop_index): New. + + * tree-loop-linear.c (perfect_loop_nest_depth): Remove static. + * tree-flow.h (perfect_loop_nest_depth): Declare as extern. + * testsuite/gcc.dg/graphite/scop-16.c: New. + * testsuite/gcc.dg/graphite/scop-17.c: New. + +2008-07-11 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (scop_remove_ignoreable_gbbs): Also update bitmap. + (graphite_trans_scop_block): Ignore SCoPs without bbs. + +2008-07-11 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (new_scop): Initialize SCOP_EXIT. + (scopdet_info): Add. + (scopdet_bb_info): Rename from is_bb_addable. Cleanup, bugfixes. + (build_scops_1): Cleanup, bugfixes. + (build_scops): Cleanup. + + * testsuite/gcc.dg/graphite/scop-matmult.c: Remove duplicated code. + * testsuite/gcc.dg/graphite/scop-15.c: Add SCoP numbers. + +2008-07-10 Harsha Jagasia <harsha.jagasia@amd.com> + + * testsuite/gfortran.dg/graphite/scop-1.f: Update to reduced test case. + + * testsuite/gfortran.dg/graphite/graphite.exp: Use + DEFAULT_GRAPHITE_FLAGS. + + * testsuite/gcc.dg/graphite/scop-15.c: Update to reduced test case. + +2008-07-10 Harsha Jagasia <harsha.jagasia@amd.com> + + * graphite.c (scan_tree_for_params): Do not assert any more if + MULT_EXPR parameter is negative. + + * testsuite/gfortran.dg/graphite/scop-1.f: New. + + * testsuite/gfortran.dg/graphite/graphite.exp: New. + + * testsuite/gcc.dg/graphite/scop-15.c: New. + +2008-07-10 Harsha Jagasia <harsha.jagasia@amd.com> + + * graphite.c (is_bb_addable): Fix segfault in spec gzip and reformat. + +2008-07-10 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (graphite_trans_bb_swap_loops): Rename from + graphite_swap_loops. + (graphite_trans_bb_move_loop): New. + (graphite_trans_bb_strip_mine): Rename from graphite_strip_mine_loop. + (graphite_trans_bb_block): New. + (graphite_trans_loop_block): New. + (graphite_trans_scop_swap_1and2): Rename from + graphite_trans_swap_1and2. + (graphite_trans_scop_strip): Rename from graphite_trans_strip. + (graphite_trans_scop_block): New. + (graphite_apply_transformations): Rename from + graphite_transformations. + + * testsuite/gcc.dg/graphite/scop-matmult.c: New. + +2008-07-10 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (gbb_compare): New. + (graphite_sort_gbbs): New. + (gbb_can_be_ignored): New. + (scop_remove_ignoreable_gbbs): New. + (graphite_transformations): Cleanup and add + scop_remove_ignoreable_gbbs. + * lambda.h (lambda_vector_compare): New. + +2008-07-09 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (print_graphite_bb): Correct printing of static schedule. + (graphite_swap_loops): int -> unsigned + (graphite_strip_mine_loop): int -> unsigned, Fix SCHEDULE + (graphite_transformations): New. + (graphite_transform_loops): Move to graphite_transformations. + * graphite.h (gbb_nb_loops): Return unsigned. + +2008-07-04 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (scan_tree_for_params): Fix insertion of parameters into + the domain matrix. This makes scop-0.c work again. + +2008-06-20 Richard Guenther <rguenther@suse.de> + + * graphite.h: Adjust copyright to GPLv3. + * graphite.c: Likewise. + (stmt_simple_memref_for_scop_p): Split out from ... + (stmt_simple_for_scop_p): ... here. Fix handling of calls + and simplify. + (get_bb_type): Optimize. + (is_pred): Remove. + (is_bb_addable): Fix memleak, replace is_pred call with + single_pred. + (build_scops): Use current_loops. + (param_index): Fix memleak. + +2008-06-20 Konrad Trifunovic <konrad.trifunovic@inria.fr> + + * graphite.c: Fix formatting. + +2008-06-19 Konrad Trifunovic <konrad.trifunovic@inria.fr> + + * graphite.c (new_scop): Memory allocation for SCOP_{NEWIVS, OLDIVS}. + (free_scop): Memory deallocation for SCOP_NEWIVS, SCOP_OLDIVS. + (create_var_name, save_var_name): Newly defined functions. + (initialize_cloog_names): Part of the code factored out to + save_var_name. + (clast_to_gcc_expression): Now handles the case of clast_red_sum + in clast_reduction statement. + (graphite_create_new_loop): Now takes a new parameter + for outer_loop. + (translate_clast): Now also takes the context_loop and bb_exit + parameters. Rewritten the code so that it creates a gimple code + inside the given context. + (outermost_loop_layer, graphite_remove_iv, graphite_rename_ivs, + remove_cond_expr, disconnect_cond_expr, + disconnect_virtual_phi_nodes): Newly defined functions. + * graphite.h (struct scop): added old_ivs vector. + SCOP_OLDIVS: New macro. + +2008-06-19 Sebastian Pop <sebastian.pop@amd.com> + + * cfgloopmanip.c: Add missing function comments, fix formatting. + +2008-06-18 Konrad Trifunovic <konrad.trifunovic@inria.fr> + + * cfgloopmanip.c (update_dominators_in_loop): Defined. + (create_empty_loop_on_edge): Defined. + * tree-parloops.c (canonicalize_loop_ivs): Returns tree + instead of void. + * cfgloop.h (create_empty_loop_on_edge): Declared as extern. + (update_dominators_in_loop): Declared as extern + * tree-flow.h (canonicalize_loop_ivs): Declared as extern. + +2008-06-16 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (print_graphite_bb): Allow changing number of loops + in SCoP domain. + (initialize_cloog_names): Allow changing number of loops. + (build_cloog_prog): Simplify. + (find_transform): Enable cloog option --strides. + (graphite_swap_loops): New. + (graphite_strip_mine_loop): New. + (graphite_trans_swap_1and2): New. + (graphite_trans_strip): New. + (graphite_transform_loops): Add graphite_trans_strip. + * graphite.h (scop_max_loop_depth): New. + +2008-06-15 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (build_scop_iteration_domain): Remove forgotten + line. (Fixes compile) + +2008-06-15 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (print_graphite_bb): Add output of GBB_LOOPS. + (build_graphite_bb): Add GBB_LOOPS and GBB_DOMAIN and reorder. + (build_bb_loops): New. + (graphite_transform_loops): Add build_bb_loops. + (schedule_to_scattering): Use gbb_nb_loops to support changing loop + numbers. + * graphite.h (graphite_bb): Add loops. + (gbb_nb_loops): New. + (gbb_loop_at_index): New. + (gbb_loop_index): New. + (nb_params_in_scop): Renamed to scop_nb_params. Updated all functions + using nb_params_in_scop. + +2008-06-14 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (print_graphite_bb): Adapt to minimized schedule. + (build_scop_canonical_schedules): Build minimized schedule. + (schedule_to_scattering): Adapt to minimized schedule. + * graphite.h (graphite_bb): Add/Update descriptions. + +2008-06-14 Adrien Eliche <aeliche@isty.uvsq.fr> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (print_graphite_bb): Add condition printing. + (dump_value): New. + (dump_gbb_conditions): New. + (build_scop_conditions_1): New. + (build_scop_conditions): New. + * graphite.h (graphite_bb): Add conditions. + +2008-06-14 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (print_graphite_bb): + (free_graphite_bb): New. + (free_scop): Free bbs. + (get_bb_type): Free doms. + (build_scop_context): Free context matrix. + (build_loop_iteration_domains): Remove unused code. + (build_cloog_prog): Free scattering function and blocklist. + (find_transform): Free options. + +2008-06-13 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (loop_body_to_cloog_stmts): Rename to add_bb_domains. + Remove unnecessery cloog data structures. Make a copy of the domain + (setup_cloog_loop): Rename to build_loop_iteration_domains. Remove + unnecessary cloog data structures. Fix memory leaks. Remove insert + into SCOP_LOOP2CLOOG_LOOP as the inserted CloogLoops will never be + used. + (build_scop_iteration_domain): Remove unnecessary cloog + data structures. Fix memory leaks. + (graphite_transform_loops): Disable build_scop_dynamic_schedules as it + uses SCOP_LOOP2CLOOG_LOOP, that is at the moment not working. + +2008-06-12 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (find_scop_params): Remove initialize_cloog_names. + +2008-06-12 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (end_scop): Style fix. + (schedule_to_scattering): Style and comment fix. + +2008-06-12 Tobias Grosser <grosser@fim.uni-passau.de> + * graphite.c (print_graphite_bb): Fix definiton of + schedule_to_scattering. + (initialize_cloog_names): Change nb_scattdims to max loop + depth in SCoP. + (schedule_to_scattering): Take parameter for number of scattering + dimensions. + (build_cloog_prog): Only build as much scattering dimensions as + necessary. + +2008-06-12 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (end_scop): Disable bb splitting. Fixes SIGSEGV + in polyhedron/aermod.f90. + +2008-06-11 Tobias Grosser <grosser@fim.uni-passau.de> + Dwarak Rajagopal <dwarak.rajagopal@amd.com> + Harsha Jagasia <harsha.jagasia@amd.com> + + * graphite.c (is_bb_addable): Fix segfault. + +2008-06-10 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (is_bb_addable): Fix memory leak, handling of loops + with multiple exits and conditional handling in edge cases. + (is_loop_exit): Fix memory leak. (Forgotten in last commit) + + * testsuite/gcc.dg/graphite/scop-14.c: New. + +2008-06-06 Tobias Grosser <grosser@fim.uni-passau.de> + Adrien Eliche <aeliche@isty.uvsq.fr> + + * graphite.c (is_bb_addable): Add more comments and enhance + readablity of the source code. Fix memory leak. + (is_loop_exit): Fix memory leak. + +2008-06-05 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (first_loop_in_scop): Deleted. + (setup_cloog_loop): Only walk the loop chain for inner loops. + (build_scop_iteration_domain): Execute setup_cloog_loop for + all loops in the first layer. + +2008-06-05 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (scan_tree_for_params): Change the way params are + added to be indepenent of the number of loops. + (setup_cloog_loop): Revert to short matrix format. Fix parameter + handling. + (build_cloog_prog): Revert to short matrix format. + +2008-06-05 Sebastian Pop <sebastian.pop@amd.com> + Dwarak Rajagopal <dwarak.rajagopal@amd.com> + + * tree-loop-fusion.c (fuse_loops): Fix uninitialized variable + warning. + +2008-06-05 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (nb_data_refs_in_scop): New. + (graphite_transform_loops): Print more stats: number of + loops, basic blocks and data references per scop. + +2008-06-04 Sebastian Pop <sebastian.pop@amd.com> + Jan Sjodin <jan.sjodin@amd.com> + + * graphite.c (loop_affine_expr, idx_record_params, + find_scop_parameters, setup_cloog_loop): Use instantiate_scev + instead of instantiate_parameters. + +2008-06-04 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (schedule_to_scattering): Fix scattering dimensions, + add support for parameters, add STATIC_SCHEDULE at the right places, + cleanup. + +2008-06-04 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (build_scop_loop_nests): Only add the loops, that + are contained completely in the SCoP. + (build_cloog_prog): Disable scattering, until schedule_to_scattering + and the domains are fixed. + (build_scop_canonical_schedules): Add support for bbs not contained + in any SCoP. + +2008-06-04 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.h (scop_contains_loop): Update comments to match + the actual behavior. + (scop_contains_loop): New. + * graphite.c (schedule_to_scattering): Use scop_contains_loop. + +2008-06-04 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (get_bb_type): On function body, i.e. loop_0, + don't mark blocks as GBB_LOOP_SING_EXIT_HEADER, mark them + as GBB_COND_HEADER. + +2008-06-04 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (graphite_transform_loops): Early return when + there are no loops in the function. + +2008-05-31 Sebastian Pop <sebastian.pop@amd.com> + Jan Sjodin <jan.sjodin@amd.com> + + * graphite.c (scan_tree_for_params, setup_cloog_loop): Compute the + offset of the last loop. + (setup_cloog_loop): Copy the entire outer constraint matrix. + +2008-05-31 Sebastian Pop <sebastian.pop@amd.com> + Jan Sjodin <jan.sjodin@amd.com> + + * graphite.c (stmt_in_scop_p, function_parameter_p, + invariant_in_scop_p): Removed. + (scan_tree_for_params): Can be used with no constraint + matrix for gathering parameters. + (idx_record_params): Don't use idx_record_param, instead use + scan_tree_for_params. + (find_scop_parameters): Same. + (setup_cloog_loop, build_scop_iteration_domain, build_cloog_prog): + Fix the size of loop domains. + (schedule_to_scattering): Exit when the outer loop is not in scop. + (find_transform): Enable build_cloog_prog. + +2008-05-31 Sebastian Pop <sebastian.pop@amd.com> + Jan Sjodin <jan.sjodin@amd.com> + + * graphite.c (schedule_to_scattering): Make scattering domains + uniformly of the same size, as required by CLooG 0.14.0 and before. + +2008-05-31 Sebastian Pop <sebastian.pop@amd.com> + Jan Sjodin <jan.sjodin@amd.com> + + * graphite.c (schedule_to_scattering): Rewrite, correct the + translation of the scheduling function to scattering. + (build_cloog_prog): Call schedule_to_scattering only once. + * graphite.h (scop_loop_index): Do not fail for loops not + in the scop: return -1. + +2008-05-30 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (build_graphite_bb): Initialize GBB_DOMAIN. + (loop_body_to_cloog_stmts): Export GBB_DOMAIN. + (setup_cloog_loop): Export GBB_DOMAIN. + (build_cloog_prog): New. Create new CLOOG_PROG, which should be + able to rebuild the original control flow. + * graphite.h (graphite_bb): Add domain field and access macro. + (GBB_DOMAIN): New. + +2008-05-30 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (debug_gbb): New. + (print_scop, build_graphite_bb): Use SCOP_BBS. + (build_scop_bbs): Reimplemented. + (dfs_bb_in_scop_p): Removed. + (build_scop_loop_nests): Reorder loops inserted in + SCOP_LOOP_NEST: outer loops should come first. + (build_scop_canonical_schedules): Reinitialize at zero + the components of the SCOP_STATIC_SCHEDULE for the loops + that have already been parsed. + + * graphite.h (debug_gbb): Declared. + +2008-05-30 Sebastian Pop <sebastian.pop@amd.com> + Jan Sjodin <jan.sjodin@amd.com> + + * graphite.c (create_empty_loop): Renamed graphite_create_new_loop. + (graphite_loop_to_gcc_loop): Removed. + (remove_all_edges): New. + (graphite_stmt_to_gcc_stmt): Renamed translate_clast. + (gloog): Remove useless code. + +2008-05-29 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (get_bb_type): Reworked. We distinguish between + loops with one or multiple exits. + (is_loop_exit): New. + (is_pred): New. + (is_bb_addable): Rework condition handling, now support for case + case statements and loops with multiple exits. + + * testsuite/gcc.dg/graphite/scop-11.c: New. + * testsuite/gcc.dg/graphite/scop-12.c: New. + * testsuite/gcc.dg/graphite/scop-13.c: New. + +2008-05-29 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (dot_all_scops_1): Fix some colors. Reuse colors, if + we have too many colors. + +2008-05-22 Sandeep Maram <smaram_b04@iiita.ac.in> + + * doc/invoke.texi (-ftree-loop-fusion): Document. + * tree-pass.h (pass_loop_fusion): Declared. + * tree-loop-fusion.c: New. + * timevar.def (TV_TREE_LOOP_FUSION): Declared. + * tree-data-ref.c (find_data_references_in_loop): Make extern. + * tree-data-ref.h (find_data_references_in_loop): Declared. + * common.opt (ftree-loop-fusion): Declared. + * Makefile.in (tree-loop-fusion.o): Added rule and to OBJS-common. + +2008-05-21 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (build_access_matrix): Fix typo from the merge. + +2008-05-20 Sebastian Pop <sebastian.pop@amd.com> + + * Merge from mainline (130800:135673). + +2008-05-07 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (end_scop): The exit of the scop is not part of the scop. + Update dominators after splitting. + +2008-05-07 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (is_bb_addable): Return the harmful statement. + Factor up some code. + (end_scop): New. Splits end of scope bbs on a harmful statement. + (build_scops_1): Call end_scop. + +2008-05-07 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c: (succs_at_same_depth, end_scop, all_preds_visited_p, + all_succs_visited_p, start_new_scop_for_each_succ, start_new_scop, + add_dominators_to_open_scops, stop_last_open_scop, scop_end_loop, + build_scops_1): Removed. + (build_scops_2): Renamed build_scops_1. + +2008-05-06 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c: Fix formatting. + +2008-05-06 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (get_bb_type): New. + (move_scops): New. + (build_scops_2): New. + (is_bb_addable): New. + (build_scops): Switch the scop detection. + (build_scop_bbs): Add entry bb to scop. + * graphite.h (struct scop): Update comment. + +2008-05-06 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (dot_all_scops_1): Fix some incorrect colors and add + more colors. + +2008-05-06 Tobias Grosser <grosser@fim.uni-passau.de> + + * testsuite/gcc.dg/graphite/scop-1.c: Update. + * testsuite/gcc.dg/graphite/scop-2.c: Update. + * testsuite/gcc.dg/graphite/scop-4.c: Update. + * testsuite/gcc.dg/graphite/scop-5.c: Add. + * testsuite/gcc.dg/graphite/scop-6.c: Add. + +2008-05-06 Sebastian Pop <sebastian.pop@amd.com> + + * testsuite/gcc.dg/graphite/scop-0.c: Add. + * testsuite/gcc.dg/graphite/scop-7.c: Add. + * testsuite/gcc.dg/graphite/scop-8.c: Add. + * testsuite/gcc.dg/graphite/scop-9.c: Add. + * testsuite/gcc.dg/graphite/scop-10.c: Add. + +2008-05-06 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (scop_affine_expr): Renamed to loop_affine_expr. + Check affine expressions depending on the outermost loop + instead of a scop. + (stmt_simple_for_scop_p): Same. + (harmfule_stmt_in_scop): Same. + +2008-04-28 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (dot_all_scops): Remove incorrect difficult bb coloring, + mark entry and exit, that are not part of the SCoP and update HTML + formatting. + +2008-04-25 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (basic_block_simple_for_scop_p): Renamed + harmful_stmt_in_bb. + (save_scop, preds_at_same_depth, test_for_scop_bound): Removed. + (add_dominators_to_open_scops, build_scops_1): Reimplemented. + (all_preds_visited_p, all_succs_visited_p, + start_new_scop_for_each_succ, start_new_scop, stop_last_open_scop, + scop_end_loop): New. + (build_scops): Do not use dfs_enumerate_from. + + * testsuite/gcc.dg/graphite/scop-{1,2,4}.c: Updated. + +2008-04-23 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c: Add comments to functions that are missing a + description. + (graphite_create_iv): Removed. Merged in graphite_loop_to_gcc_loop. + +2008-04-23 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (nb_params_in_scop): Moved... + (graphite_bb_from_bb, loop_body_to_cloog_stmts): New. + (setup_cloog_loop): Call loop_body_to_cloog_stmts. + (clast_to_gcc_expression): Reduce column size to less than 80. + (graphite_create_iv): Return the new name of the IV. + (find_transform): Set options->esp and options->cpp. + (gloog): Comment out the invalidation of the old loop code. + (initialize_dependence_polyhedron): Replace scop_nb_params with + nb_params_in_scop. + + * graphite.h (nb_params_in_scop): ... here. + (scop_nb_params): Removed. + (loop_domain_dim): Return something even when the loop was not + found in the hash table: avoid ICEing on all the graphite.exp + testcases. + +2008-04-14 Konrad Trifunovic <konrad.trifunovic@inria.fr> + + * tree-chrec.c (for_each_scev_op): SCEV can have 3 operands. + + * graphite.c (build_scop_dynamic_schedules): Schedule is built + according to nesting level. + (find_scop_parameters): Call instantiate_parameters. + (scan_tree_for_params): Extend it to handle general affine bounds. + Inner loop bound can depend on outer loop induction variable. + (setup_cloog_loop): tmp variable is allocated on stack. Call + instantiate_parameters with respect to outermost_loop_in_scop. + (loop_domain_dim, ref_nb_loops, loop_iteration_vector_dim): moved to + graphite.h. + (create_empty_loop): Function loopify should be given edge + probability, instead of edge frequency. Dominance relation from + switch_bb to loop_header. + (clast_to_gcc_expression): Added handling of clast_reduction node. + (gloog): New functionality for removing old loop. + (test_dependence): Factored out from build_rdg_all_levels. + (build_rdg_all_levels): Dependence testing factored out to + test_dependence function. + + * graphite.h (struct graphite_bb): Extended with dynamic_schedule. + (loop_domain_dim, ref_nb_loops, loop_iteration_vector_dim): Moved + from graphite.c + +2008-04-07 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (free_scop, param_index, initialize_cloog_names, + nb_params_in_scop): Use name_tree map instead of just a tree + for keeping track of the variable name associated to that tree. + (create_empty_loop, gmp_cst_to_tree, clast_name_to_gcc, + clast_to_gcc_expression, graphite_create_iv, + graphite_loop_to_gcc_loop, graphite_cond_to_gcc_cond, + graphite_stmt_to_gcc_stmt): New. + (gloog): Call these. + * graphite.h (struct name_tree): New. + (struct scop): Use name_tree instead of tree for params. + Store a vector of name_tree for new_ivs. + (SCOP_NEWIVS): New. + (scop_nb_params): Use name_tree instead of tree. + +2008-04-05 Alexander Lamaison <awl03@doc.ic.ac.uk> + Sebastian Pop <sebastian.pop@amd.com> + + * tree-bounds.c: New. + * tree-bounds.h: New. + * tree-pass.h: Declare pass_bounds_early and pass_bounds_late. + * passes.c: Schedule pass_bounds_early, pass_bounds_late. + * builtins.c (expand_builtin_alloca): Add flag_bounds as for + flag_mudflap. + * gcc.c: Same. + * toplev.c: Same. + * c-cppbuiltin.c: Same. + * c-pragma.c: Same. + * common.opt: Same. + * varasm.c: Same. + * tree-outof-ssa.c: Same. + * c-common.c: Same. + * Makefile.in: Same. + +2008-03-15 Antoniu Pop <antoniu.pop@gmail.com> + Sebastian Pop <sebastian.pop@amd.com> + + * tree-loop-distribution.c (remaining_stmts, + upstream_mem_writes): Removed static variables. + (copy_loop_before, create_bb_after_loop, + mark_nodes_having_upstream_mem_writes, free_rdg_components, + rdg_build_components, rdg_build_partitions, + dump_rdg_partitions): Extern. + (generate_loops_for_partition, generate_code_for_partition): Do not + return a bool. + (already_processed_vertex_p, predecessor_has_mem_write, + mark_nodes_having_upstream_mem_writes, has_upstream_mem_writes, + rdg_flag_all_uses, rdg_flag_uses, rdg_flag_vertex_and_dependent, + rdg_flag_loop_exits, rdg_flag_similar_memory_accesses, + build_rdg_partition_for_component, rdg_build_partitions, ldist_gen): + Pass remaining_stmts and upstream_mem_writes as parameters. + (rdg_component): Moved... + (build_rdg_partition_for_component): Do not aggregate components when + flag_streamize_loops is set. + (gen_sequential_loops): New. + (ldist_gen): Call gen_sequential_loops. + + * tree-pass.h (pass_loop_streamization): Declared. + + * omp-low.c (expand_omp_sections): Call add_bb_to_loop on created + basic blocks when loops structures exist. + + * builtin-types.def (BT_FN_VOID_PTR_PTR_INT): New. + + * tree-ssa-loop-ivopts.c (expr_invariant_in_region_p): New. + + * tree-parloops.c (take_address_of, eliminate_local_variables_1, + eliminate_local_variables_stmt, eliminate_local_variables, + separate_decls_in_loop_name, separate_decls_in_loop_stmt, + separate_decls_in_loop, gen_parallel_loop): Make them work on a region + of code delimited by two edges in the CFG. + (separate_decls_in_loop_name): Renamed separate_decls_in_region_name. + (separate_decls_in_loop_stmt): Renamed separate_decls_in_region_stmt. + (separate_decls_in_loop): Renamed separate_decls_in_region. Isolate + the case of parallelisation of reductions. + (create_loop_fn): Extern. + (create_omp_parallel_region): New. + + * tree-data-ref.c (dump_data_dependence_relation): Don't call + dump_data_reference for printing dra and drb. + (create_rdg_edge_for_ddr, create_rdg_edges_for_scalar): Initialise + RDGE_RELATION. + (build_rdg): Don't call free_dependence_relations for the moment, as + we attach dependence relations on each edge of the RDG. + To be fixed later. + + * tree-data-ref.h (rdg_component): ...here. + (struct rdg_edge): New field ddr_p relation. + (RDGE_RELATION): New. + (create_bb_after_loop, copy_loop_before, + mark_nodes_having_upstream_mem_writes, rdg_build_components, + rdg_build_partitions, dump_rdg_partitions, + free_rdg_components): Declared. + + * omp-builtins.def (BUILT_IN_GOMP_STREAM_ALIGN_PUSH, + BUILT_IN_GOMP_STREAM_ALIGN_POP): New. + + * tree-loop-streamization.c: New. + + * tree-flow.h (gather_blocks_in_sese_region, create_loop_fn, + create_omp_parallel_region, expr_invariant_in_region_p): Declared. + + * Makefile.in (tree-loop-streamization.o): Added to OBJS-common. + + * tree-cfg.c (gather_blocks_in_sese_region): Extern. + + * passes.c: Schedule pass_loop_streamization. + +2008-03-08 Tobias Grosser <grosser@fmi.uni-passau.de> + + * graphite.c (dot_all_scops_1): Fix formatting for difficult bbs and + update comment. + +2008-03-07 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (dot_all_scops): Update formatting. + Bbs can now be part of more than one SCoP. + +2008-03-04 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (new_loop_to_cloog_loop_str, setup_cloog_loop): Fix + malloc problems. + (loop_domain_dim): Check for unregistered toplev SCOP loop. + * graphite.h (loop_to_cloog_loop): New. + +2008-03-04 Konrad Trifunovic <konrad.trifunovic@inria.fr> + + * graphite.c (loop_domain_dim, ref_nb_loops, + loop_iteration_vector_dim): New. + (build_access_matrix_with_af, build_access_matrix, + initialize_dependence_polyhedron): Fixed for new matrix layout. + No longer assume that all iteration domains are of the same + dimensionality. + +2008-03-02 Sebastian Pop <sebastian.pop@amd.com> + + * tree-scalar-evolution.c (instantiate_parameters_1): An SSA_NAME + defined in a loop at depth 0 is invariant. + * tree-chrec.c (evolution_function_is_invariant_rec_p): Ditto. + * tree-ssa-loop-ivopts.c (expr_invariant_in_loop_p): Should never + be called at loop depth 0. + + * graphite.c (basic_block_simple_for_scop_p): Take the scop as + a parameter. + (dot_all_scops_1): Update use of basic_block_simple_for_scop_p. + (down_open_scop): Removed. + (loop_in_scop_p): Redefined. + (scop_affine_expr): New argument: scop. + (stmt_simple_for_scop_p): New argument: scop. RETURN_EXPR is not + a harmful statement ending a scop. + (basic_block_simple_for_scop_p): New argument: scop. + (get_loop_start): Removed. + (new_scop): Initialize SCOP_LOOPS. + (free_scop): Free SCOP_LOOPS. + (succs_at_same_depth, preds_at_same_depth): New. + (end_scop): Test the validity of a scop. + (add_dominators_to_open_scops): New. + (test_for_scop_bound): Call add_dominators_to_open_scops. + Add cases for opening and closing multiple scops. + (build_scops, build_scop_bbs): Iterate over basic blocks in + depth first order. + (build_graphite_bb): Pass scop directly. + (dfs_bb_in_scop_p): New. + (scop_record_loop): Use SCOP_LOOPS for not recording the same loop + several times. + (nb_loops_around_gb): Use loop_in_scop_p. + (schedule_to_scattering): Disabled for the moment the code computing + the "textual order for outer loop". + + * graphite.h (struct scop): New field loops. + (SCOP_LOOPS): New. + (scop_loop_index): Test that the given loop belongs to SCOP_LOOPS. + + * testsuite/gcc.dg/graphite/scop-{1,...,7}.c: Updated. + +2008-02-27 Antoniu Pop <antoniu.pop@gmail.com> + Sebastian Pop <sebastian.pop@amd.com> + + * builtin-types.def (BT_FN_PTR_SIZE_UINT, BT_FN_BOOL_PTR): New. + * common.opt (fstreamize-loops): New. + * omp-builtins.def (BUILT_IN_GOMP_STREAM_CREATE, + BUILT_IN_GOMP_STREAM_PUSH, BUILT_IN_GOMP_STREAM_HEAD, + BUILT_IN_GOMP_STREAM_POP, BUILT_IN_GOMP_STREAM_EOS_P, + BUILT_IN_GOMP_STREAM_SET_EOS, BUILT_IN_GOMP_STREAM_DESTROY): New. + +2008-02-22 Konrad Trifunovic <konrad.trifunovic@inria.fr> + + * tree-data-ref.c (build_empty_rdg): New. + (build_rdg): Use it. + * tree-data-ref.h (build_empty_rdg): Declared. + * graphite.c (free_scop): Free SCOP_LOOP2CLOOG_LOOP. + (find_vertex_for_stmt): Removed. + (build_rdg_all_levels): Use build_empty_rdg and rdg_vertex_for_stmt. + +2008-02-21 Sebastian Pop <sebastian.pop@amd.com> + + * tree-loop-distribution.c (generate_builtin): After cancelling the + loop tree, also delete basic blocks. + (rdg_flag_uses): Stop recursion when a vertex has already been + processed. + +2008-02-15 Konrad Trifunovic <konrad.trifunovic@inria.fr> + + * graphite.c (build_scop_alpha): Removed. + (graphite_transform_loops): Add a dummy call to build_all_rdg_levels + and dump_dependence_graph to avoid compiler warnings. + +2008-02-14 Konrad Trifunovic <konrad.trifunovic@inria.fr> + + * tree-data-ref.c (dr_may_alias_p, create_rdg_vertices): Extern. + * tree-data-ref.h (dr_may_alias_p, create_rdg_vertices): Declared. + * graphite.c (new_loop_to_cloog_loop_str, hash_loop_to_cloog_loop, + eq_loop_to_cloog_loop, del_loop_to_cloog_loop): New. + (new_scop, setup_cloog_loop): Initialize SCOP_LOOP2CLOOG_LOOP. + (initialize_dependence_polyhedron, find_vertex_for_stmt, + initialize_data_dependence_polyhedron, is_empty_polyhedron, + statement_precedes_p, build_rdg_all_levels, build_scop_alpha, + dump_dependence_graph): New. + * graphite.h (struct graphite_bb): New field compressed_alpha_matrix. + (GBB_ALPHA): New. + (struct scop): New field loop2cloog_loop. + (SCOP_LOOP2CLOOG_LOOP, struct data_dependence_polyhedron, + RDGE_DDP, ddp_p, struct loop_to_cloog_loop_str): New. + +2008-02-10 Konrad Trifunovic <konrad.trifunovic@inria.fr> + + * graphite.c (build_graphite_bb): Fix initialization + of the graphite basic block. + +2008-02-05 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (scan_tree_for_params): Rewrite for the new layout of + loop domain matrix. Pass in the number of loops contained in the + constraint matrix. + (nb_loops_around_gb): Moved before setup_cloog_loop that uses it. + (setup_cloog_loop): Rewrite for the new layout of loop domain matrix: + loops that are not surrounding the current loop are not represented + in the domain constraint matrix. + (build_scop_iteration_domain): Initial domain constraint matrix + contains only the eq/ineq, cst, and scop parameters columns. + +2008-01-29 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (schedule_to_scattering, nb_loops_around_gb): New. + (print_graphite_bb): Print scattering. + +2008-01-29 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (initialize_cloog_names): Initialize names of + scattering variables. + +2009-01-29 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (dot_all_scops_1): Disable debug output while + printing graph. + +2008-01-29 Tobias Grosser <grosser@fim.uni-passau.de> + + * graphite.c (find_transform): Change cloog output language to C. + +2008-01-27 Sebastian Pop <sebastian.pop@amd.com> + + * tree-loop-distribution.c (generate_memset_zero, + generate_builtin, generate_code_for_partition, + rdg_flag_all_uses): New. + (rdg_flag_uses): Gather in the same partition the statements defining + the VUSES of the current statement. + (rdg_flag_similar_stores): Renamed rdg_flag_similar_memory_accesses. + Gather in the same partition not only the stores to the same memory + access, but also the reads. + (ldist_generate_loops): Renamed ldist_gen. + +2008-01-24 Sebastian Pop <sebastian.pop@amd.com> + Tobias Grosser <grosser@fmi.uni-passau.de> + + * graphite.c (setup_cloog_loop): Chain all cloog loops with the + next pointer, don't use the inner pointer. + +2008-01-20 Tobias Grosser <grosser@fmi.uni-passau.de> + + * graphite.c (dot_all_scops, dot_all_scops_1): New. + (find_transform): Call dot_all_1. + * graphite.h (dot_all_scops): Declared. + +2007-12-14 Sebastian Pop <sebastian.pop@amd.com> + + * tree-loop-distribution.c: Fix apsi.f ICE. + (create_bb_after_loop): New. + (generate_loops_for_partition): Use it. + * testsuite/gfortran.dg/ldist-1.f90: New. + + * tree-data-ref.c (dot_rdg): Use /tmp/rdg.dot for dotty format. + * graphite.c (dot_scop): Use /tmp/scop.dot for dotty format. + +2007-12-13 Tobias Grosser <grosser@fmi.uni-passau.de> + + * graphite.c (find_transform): Dump cloog program sent to cloog. + +2007-12-13 Tobias Grosser <grosser@fmi.uni-passau.de> + + * graphite.c (initialize_cloog_names): Initialize cloog + iterator names. + +2007-12-13 Tobias Grosser <grosser@fmi.uni-passau.de> + + * graphite.c (build_scop_context): Fix typo, for the matrix + format: insert '0 >= 0' instead of '-1 >= 0'. + +2007-12-13 Sebastian Pop <sebastian.pop@amd.com> + + * Fix merge problems. + +2007-12-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (setup_cloog_loop): Fix typo. + +2007-12-12 Sebastian Pop <sebastian.pop@amd.com> + + * doc/invoke.texi (-ftree-loop-distribution): Documented. + * tree-loop-distribution.c: Reimplemented. + * tree-pass.h (pass_loop_distribution): New. + * tree-scalar-evolution.c (number_of_iterations_for_all_loops): Use + print_loops. + * graphds.h (struct graph): New field indexes. + * timevar.def (TV_TREE_LOOP_DISTRIBUTION): New. + + * tree-vect-analyze.c: Remove declaration of static functions when not + needed. + * tree-vectorizer.c: Same. + (rename_variables_in_loop): Now extern. + (slpeel_tree_duplicate_loop_to_edge_cfg): Renamed + tree_duplicate_loop_to_edge_cfg. Reset PENDING_STMT for edges after + calling redirect_edge_and_branch_force. + + * tree-vectorizer.h (tree_duplicate_loop_on_edge): Declared. + + * tree-data-ref.c: Don't include tree-chrec.h. + (debug_data_dependence_relations): New. + (dump_data_dependence_relation): Call dump_data_reference on data refs + in the relation. + (same_access_functions): Moved... + (find_vertex_for_stmt): Renamed rdg_vertex_for_stmt. + (dump_rdg_vertex, debug_rdg_vertex, dump_rdg_component, + debug_rdg_component, dump_rdg, debug_rdg, dot_rdg_1, dot_rdg, + struct rdg_vertex_info, ): New. + (create_rdg_edge_for_ddr): Compute the dependence level before looking + at DDR_REVERSED_P. + (create_rdg_vertices): Initialize the htab of graph->indexes. + Initialize RDG_MEM_WRITE_STMT and RDG_MEM_READS_STMT. + (stmts_from_loop): Don't save LABEL_EXPR. + (hash_stmt_vertex_info, eq_stmt_vertex_info, + hash_stmt_vertex_del): New. + (build_rdg): Initialize rdg->indexes. + (free_rdg, stores_from_loop, ref_base_address, + rdg_defs_used_in_other_loops_p, have_similar_memory_accesses, + have_similar_memory_accesses_1, ref_base_address_1, + remove_similar_memory_refs): New. + + * tree-data-ref.h: Include tree-chrec.h. + (debug_data_dependence_relations): Declared. + (same_access_functions): ...here. Now static inline. + (ddr_is_anti_dependent, ddrs_have_anti_deps, + ddr_dependence_level): New. + (struct rdg_vertex): New fields has_mem_write, has_mem_reads. + (RDGV_HAS_MEM_WRITE, RDGV_HAS_MEM_READS, RDG_STMT, RDG_MEM_WRITE_STMT, + RDG_MEM_READS_STMT): New. + (dump_rdg_vertex, debug_rdg_vertex, dump_rdg_component, + debug_rdg_component, dump_rdg, debug_rdg, dot_rdg, + rdg_vertex_for_stmt): Declared. + (struct rdg_edge): New field level. + (RDGE_LEVEL, free_rdg): New. + (stores_from_loop, remove_similar_memory_refs, + rdg_defs_used_in_other_loops_p, + have_similar_memory_accesses): Declared. + (rdg_has_similar_memory_accesses): New. + + * lambda.h (dependence_level): New. + * common.opt (ftree-loop-distribution): New. + * tree-flow.h (debug_loop_ir): Renamed debug_loops. + (print_loop_ir): Renamed print_loops. + (debug_loop, debug_loop_num, print_loops_bb, mark_virtual_ops_in_bb, + tree_duplicate_loop_to_edge_cfg, rename_variables_in_loop): Declared. + * Makefile.in (TREE_DATA_REF_H): Depends on tree-chrec.h. + (tree-loop-distribution.o): Added. + * tree-cfg.c (mark_virtual_ops_in_region): Use mark_virtual_ops_in_bb. + (mark_virtual_ops_in_bb): New. + (print_loops_bb, debug_loop_num, debug_loop): New. + * passes.c: Scheduled pass_loop_distribution. + +2007-12-12 Konrad Trifunovic <konrad.trifunovic@inria.fr> + + * graphite.c (scan_tree_for_params): Correct the number of columns + for polylib format. + (nb_flat_iterator): New. + (setup_cloog_loop): Initialize to 1 the first column for inequalities. + (build_scop_iteration_domain): Correct the number of columns for + polylib format. + +2007-12-12 Sebastian Pop <sebastian.pop@amd.com> + + * Merge from mainline (129697:130800). + +2007-10-30 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (build_graphite_bb): SCoP's basic blocks are post + dominated by SCoP's exit. + (graphite_transform_loops): Compute post dominators. + +2007-10-28 Sebastian Pop <sebastian.pop@amd.com> + + * Merge from mainline (127169:129697). + +2007-10-28 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.c (affine_expr): Renamed scop_affine_expr. Use an extra + parameter for the basic block that contains the expression. Use + outermost_loop_in_scop for evolution_function_is_affine_multivariate_p. + (stmt_simple_for_scop_p): Pass to scop_affine_expr the basic block of + the expression. + * graphite.h (gbb_loop): New. + (GBB_LOOP): Removed. + +2007-08-03 Sebastian Pop <sebpop@gmail.com> + + * Makefile.in: Fix merge problem. + +2007-08-03 Sebastian Pop <sebpop@gmail.com> + + * Merge from mainline (125309:127169). + * tree-loop-distribution.c: Disabled. + +2007-06-05 Sebastian Pop <sebpop@gmail.com> + + * Merge from mainline (r123693:125309). + +2007-05-30 Sebastian Pop <sebpop@gmail.com> + + * tree-loop-distribution.c (correct_modify_expr_p): Renamed + correct_modify_p + (correct_modify_p, check_statements, number_of_lvalue_uses, + number_of_scalar_dependences, create_edges): Use GIMPLE_MODIFY_STMT + instead of MODIFY_EXPR. + (update_edge_with_ddv): Don't pass index_of_edge. Initialize + and push new edges. + +2007-05-24 Sebastian Pop <sebpop@gmail.com> + + * tree-loop-distribution.c (struct rdg): Replace arrays by + VECs for edges and vertices. + (RDG_NBV, RDG_NBE, RDG_VERTEX, RDG_EDGE): Removed. + (RDGV_NB_PARTITIONS): New. + (PRDG_NBV, PRDG_NBE): Removed. + (build_scc_graph, correct_partitions_p, mark_partitions, build_prdg, + dump_rdg, find_vertex_with_stmt, create_vertices, free_rdg, + number_of_scalar_dependences, create_edges, build_rdg): Use VECs. + +2007-05-17 Georges-Andre Silber <silber@cri.ensmp.fr> + Sebastian Pop <sebpop@gmail.com> + + * doc/invoke.texi (-ftree-loop-distribution): Document. + * tree-loop-distribution.c: New file. + * tree-pass.h (pass_loop_distribution): Declared. + * timevar.def (TV_TREE_LOOP_DISTRIBUTION): New. + * tree-data-ref.c (initialize_data_dependence_relation): Initialize + and set reversed_p. + * tree-data-ref.h (data_dependence_relation): Add reversed_p. + (DDR_REVERSED_P): New. + * common.opt (-ftree-loop-distribution): New. + * tree-flow.h (distribute_loops): Declared. + * Makefile.in (OBJS-common): Depend on tree-loop-distribution.o. + * passes.c (init_optimization_passes): Schedule loop distribution. + +2007-05-12 Sebastian Pop <sebastian.pop@inria.fr> + + * graphite.c (print_graphite_bb): Don't call dump_data_references. + (print_scop): Don't print when scop is NULL. + (build_scop_context, find_transform): Don't output to stderr. + +2007-05-09 Sebastian Pop <sebastian.pop@inria.fr> + + * tree-data-ref.c: Don't include graphite.h. + Comment out the code for printing data reference's scop. + (build_access_matrix_with_af): Moved... + * tree-data-ref.h (build_access_matrix_with_af): Removed declaration. + * graphite.c (build_access_matrix_with_af): ... here. Now static. + (print_graphite_bb): Print basic block's schedule. + (print_scop): Don't print the schedule, call cloog's pretty printer. + (bb_in_scop_p): A basic block is in a scop only if it is both + dominated and postdominated by the scop's entry and exit basic blocks. + (function_parameter_p): New. + (invariant_in_scop_p): Use function_parameter_p. + (new_scop, save_scop): New. + (end_scop, test_for_scop_bound, build_scops): Use new_scop, and + save_scop. + (scan_tree_for_params): Directly build the constraint as CloogMatrix. + (loop_in_scop_p): New. + (scop_record_loop): Use loop_in_scop_p. + (build_scop_domain): Renamed build_scop_iteration_domain. + (setup_cloog_loop, initialize_cloog_names, find_scop_parameters, + nb_params_in_scop, build_scop_context, first_loop_in_scop, + setup_cloog_loop, dot_scop_1, dot_scop): New. + * graphite.h (GBB_LOOP, SCOP_PROG, dot_scop): New. + (struct scop): Add a pointer to cloog's representation of a program. + +2007-04-14 Sebastian Pop <sebastian.pop@inria.fr> + + * doc/invoke.texi (-ftree-check-verbose): Renamed + -ftree-checks-verbose. + * common.opt (flag_tree_check_verbose): Renamed + flag_tree_checks_verbose. + * tree-check.c (tree_check_warning): Use flag_tree_checks_verbose. + +2007-04-14 Sebastian Pop <sebastian.pop@inria.fr> + + * configure: Regenerated. + * config.in: Regenerated. + * tree-ssa-loop.c (graphite_transforms): Execute + graphite_transform_loops only when HAVE_cloog. + * configure.ac (HAVE_polylib, HAVE_cloog, GRAPHITE): Defined. + * graphite.c: Include polylibgmp.h and cloog.h. + (graphite_transform_loops): Removed loops parameter. + * tree-flow.h (graphite_transform_loops): Update declaration. + * Makefile.in (POLYLIBLIBS, POLYLIBINC, CLOOGLIBS, CLOOGINC): New. + (LIBS): Depend on CLOOGLIBS and on POLYLIBLIBS. + (INCLUDES): Depend on POLYLIBINC and on CLOOGINC. + (OBJS-common): Remove dependence on graphite.o. + (BACKEND): Depend on @GRAPHITE@. + +2007-04-13 Sebastian Pop <sebastian.pop@inria.fr> + + * doc/invoke.texi (-ftree-check-verbose): Documented. + * testsuite/gcc.dg/tree-checker/tree-checks-1.c: New. + * testsuite/gcc.dg/tree-checker/tree-checks-2.c: New. + * testsuite/gcc.dg/tree-checker/tree-checks-3.c: New. + * testsuite/gcc.dg/tree-checker/tree-checks-4.c: New. + * testsuite/gcc.dg/tree-checker/tree-checks.exp: New. + * testsuite/gcc.dg/tree-checker/condates.crp: New. + * common.opt (ftree-checks-verbose): New. + * tree-check.c (tree_check_warning): Move extra stderr output + under control of flag_tree_check_verbose. + +2007-04-12 Sebastian Pop <sebastian.pop@inria.fr> + + * tree-match.c: Fix comments formatting. + * tree-match.h: Fix comments formatting. + * tree-check.c: Fix comments formatting. + (tree_check_init): Restructure. + +2007-04-12 Nic Volanschi <nic.volanschi@free.fr> + + * doc/invoke.texi (-ftree-check, -ftree-checks): Documented. + +2007-04-10 Sebastian Pop <sebastian.pop@inria.fr> + + * Merge from mainline (r120733:123693). + +2007-03-20 Nic Volanschi <nic.volanschi@free.fr> + + * condate.y: New file. + * tree-match.h (struct patt_info_s): New field sign. + (struct condate_s): New field msg. + (normalize_condate, name_condate, add_condate): New. + (conds[], condate_parse): Made extern. + * tree-check.c (tree_check_warning): First arg changed to cond; + warning reformatted. + (tree_check_init): Reset the TREE_VISITED bit on every CFG node. + (tree_scan): New. + (tree_check): Process trivial condates. + (read_delimited_string): Removed. + (print_cond): Print name and msg. + (conds[]): Made extern. + (parse_tree_check_file_once): Rewritten to use the parser in + condate.y. + Processing of option --tree_check_string moved to tree_scan(). + * Makefile.in: Added condate.y + +2007-03-12 Sebastian Pop <sebastian.pop@inria.fr> + + * tree-pretty-print.c (dump_generic_bb_buff, lazy_dump_generic_node): + Use VECs instead of varrays. + * diagnostic.h (lazy_dump_generic_node): Update declaration. + * Makefile.in (pretty-print.o): Depend on vec.h. + * pretty-print.c: Include tree.h and vec.h. + (pp_clear_state, pp_write_list_to_stream, pp_base_format, + pp_base_format, pp_construct, pp_base_string, pp_lazy_mode, + new_tree_chunk, pp_add_tree, pp_add_string, pp_add_char, pp_write_list, + pp_free_list): Use VECs instead of varrays. + * pretty-print.h: Do not include varray.h. + (struct tree_chunk_s): Declaration moved before its use. + (output_buffer): Rename varray field to chunks. + * tree-match.c (tree_equal, chunk_1st_char, chunks_lookahead, + tree_1st_char, match_chunks_pattinfo, match_tree_pattinfo, + save_global_holes): Use VECs instead of varrays. + * tree-match.h: Declare VECs of cfg_node, and hole_p. + * tree-check.c (scan_cfg_stmts, push_node, + print_matching_stmt): Removed. + (tree_check_instance, push_global_holes_if_new, tree_check, + execute_tree_check): Use VECs instead of varrays. + (gate_tree_check): Don't execute the CFG check when basic_block_info + is not available. + +2007-01-12 Sebastian Pop <sebastian.pop@inria.fr> + + * Merge from mainline (r115016:120733). + +2007-01-12 Sebastian Pop <sebastian.pop@inria.fr> + + * Merge from mainline (r117632:117661). + +2007-01-12 Sebastian Pop <sebastian.pop@inria.fr> + + * tree-dump.c (dump_option_value_in): Add TDF_DEBUG. + * tree-pass.h (TDF_DEBUG, debug_p): New. + * tree-scalar-evolution.c (set_scalar_evolution, get_scalar_evolution, + get_scalar_evolution, add_to_evolution, set_nb_iterations_in_loop, + get_loop_exit_condition, analyze_evolution_in_loop, + analyze_initial_condition, analyze_scalar_evolution, + instantiate_parameters, number_of_latch_executions): Use debug_p. + * tree-chrec.c (chrec_apply): Use debug_p. + * tree-data-ref.c: Include graphite.h. + (dump_data_reference): Print also the access matrix. + (analyze_array, analyze_indirect_ref, init_data_ref, + analyze_offset_expr, address_analysis, object_analysis, + create_data_ref, finalize_ddr_dependent, + non_affine_dependence_relation, analyze_ziv_subscript, + analyze_siv_subscript_cst_affine, + compute_overlap_steps_for_affine_1_2, analyze_subscript_affine_affine, + can_use_analyze_subscript_affine_affine, analyze_siv_subscript, + analyze_miv_subscript, analyze_overlapping_iterations, + build_classic_dist_vector, subscript_dependence_tester, + compute_affine_dependence, analyze_all_data_dependences): Use debug_p. + (build_access_matrix_with_af): No longer static. + * tree-data-ref.h (scop_p): ... declaration here. + (data_reference.scop): New field. + (DR_SCOP, DR_ACCESS_MATRIX): New. + (build_access_matrix_with_af, dr_num_subscripts): Declared. + * graphite.c (print_graphite_bb): Call dump_data_references. + (print_scop): Use scop_nb_loops and scop_dim_domain. + (test_for_scop_bound): Use debug_p. + (scan_tree_for_params): Use scop_nb_loops, scop_nb_loops and + scop_nb_params. + (scop_loop_index): Moved... + (scop_record_loop): New. + (build_scop_loop_nests): Use scop_record_loop. + (build_scop_domain): Use scop_dim_domain. + (build_access_matrix): Implemented. + (build_scop_canonical_schedules): Use scop_nb_loops. + (build_graphite_bb): Initialize GBB_SCOP. + * graphite.h (scop_p): Moved... + (graphite_bb.scop): New field. + (graphite_bb.iteration_domain, GBB_DOMAIN, scop.nb_params, + scop.nb_loops, scop.dim_domain, SCOP_NB_LOOPS, SCOP_NB_PARAMS, + SCOP_DIM_DOMAIN, SCOP_STMTS): Removed. + (scop_nb_params, scop_nb_loops, scop_dim_domain, gbb_dim_domain, + scop_loop_index): New. + * Makefile.in (tree-data-ref.o): Depends on graphite.h. + +2007-01-05 Sebastian Pop <sebastian.pop@inria.fr> + + * Merge from mainline (r117661:120450). + +2006-10-12 Sebastian Pop <sebastian.pop@inria.fr> + + * tree-scalar-evolution.c (instantiate_parameters_1): Don't stop + at the first declaration outside the varying loop, instantiate as + far as possible. + * tree-chrec.c (for_each_scev_op): New. + * tree-chrec.h (for_each_scev_op): Declared. + * tree-ssa-loop.c (pass_graphite_trans): Don't dump the function. + * tree-data-ref.c (get_references_in_stmt, + find_data_references_in_stmt): New, from trunk. + (find_data_references_in_loop): Use get_references_in_stmt + and find_data_references_in_loop, modified as in trunk. + (build_access_matrix_with_af): New. + * tree-data-ref.h (data_reference): Add a field access_matrix. + (data_ref_loc): New, as in trunk. + * graphite.c (print_graphite_bb, bb_in_scop_p, stmt_in_scop_p, + invariant_in_scop_p, param_index, scan_tree_for_params, + scop_loop_index, build_scop_loop_nests, build_scop_domain, irp_data, + idx_record_param, idx_record_params, build_access_matrix, + build_scop_data_accesses, build_scop_canonical_schedules, + build_graphite_bb, build_scop_bbs, find_params_in_bb, + build_scop_params): New. + * graphite.h (graphite_bb): New. + (scop): Add fields static_schedule, params, loop_nest, + iteration_domain. + * lambda.h: Declare vecs of lambda_matrix. + * tree-flow.h (print_loop_ir_bb): Declared. + * tree-cfg.c (print_loop_ir_bb): New. + (print_loop): Use print_loop_ir_bb. + +2006-10-12 Sebastian Pop <pop@cri.ensmp.fr> + + * Merge from mainline (r115016:117632). + +2006-10-11 Sebastian Pop <pop@cri.ensmp.fr> + + * graphite.c (debug_scops): Adjust definition for avoiding a bootstrap + break due to a warning. + +2006-10-10 Sebastian Pop <pop@cri.ensmp.fr> + + * graphite.c (print_scops, debug_scops): New. + (graphite_transform): Renamed graphite_find_transform. + * graphite.h (debug_scops): Declared. + +2006-08-17 Sebastian Pop <pop@cri.ensmp.fr> + + * tree-match.c: Reformat following the GNU style. + * tree-match.h: Reformat following the GNU style. + * tree-pattern.h: Removed empty file. + * Makefile.in: Remove references to tree-pattern.h. + * tree-check.c: Reformat following the GNU style. + (execute_tree_check): Move gate condition code to... + (gate_tree_check): ...here. New function. + (pass_check): Use the gate function. + +2006-07-04 Nic Volanschi <nic.volanschi@free.fr> + + * tree-pattern.h: New. Tree pattern matching and checking using + concrete syntax. + * tree-check.c: New. Tree/CFG checking pass. + * tree-match.c: New. Library for tree pattern matching. + * opts.c, common.opt: Add options --ftree-check & --ftree-checks. + * toplev.c, flags.h: Add globals for tree-check pass. + * Makefile.in: Integrate the files in tree-check pass. + * timevar.def, tree-optimize.c, tree-pass.h: Register tree-check pass. + * pretty-print.c, pretty-print.h, tree-pretty-print.c, diagnostic.h: + Introduce a "lazy" pretty-print mode. + * tree.c, tree.h: Add tree_name. + +2006-07-04 Sebastian Pop <pop@cri.ensmp.fr> + + * doc/invoke.texi (-fgraphite): Correct typo. + * tree-scalar-evolution.c (number_of_iterations_for_all_loops): Update + use of print_loop_ir. + * testsuite/gcc.dg/graphite/scop-1.c: New. + * testsuite/gcc.dg/graphite/scop-2.c: New. + * testsuite/gcc.dg/graphite/graphite.exp: New. + * graphite.c: Include domwalk.h. + (print_scop): Print only the entry and exit blocks. + (debug_scop): No longer static. + (affine_expr): Fix formating. Return also true when the expression is + constant. + (stmt_simple_for_scop_p): Fix formating. + (build_scops): Use domwalk. + (get_loop_start, end_scop, test_for_scop_bound): New. + (graphite_transform_loops): Avoid printing on stderr. + * graphite.h (debug_scop): Declared. + * tree-flow.h (debug_loop_ir, print_loop_ir): Update declarations. + * Makefile.in (graphite.o): Depend on domwalk.h. + * tree-cfg.c (print_loop, print_pred_bbs, print_succ_bbs): Remove + declarations for static functions. + (print_loop, print_loop_ir, debug_loop_ir): Use an extra parameter for + controlling output verbosity. + +2006-06-26 Sebastian Pop <pop@cri.ensmp.fr> + Plesco Alexandru <shurikx@gmail.com> + + * doc/invoke.texi (-fgraphite): Document. + * tree-pass.h (pass_graphite_transforms): Declared. + * timevar.def (TV_GRAPHITE_TRANSFORMS): New. + * tree-ssa-loop.c (graphite_transforms, gate_graphite_transforms): New. + (pass_graphite_transforms): Defined. + * tree-data-ref.c (free_data_ref, data_reference): Extern. + * tree-data-ref.h (free_data_ref, data_reference): Declared. + * graphite.c, graphite.h: New. + * common.opt (fgraphite): Declared. + * tree-flow.h (graphite_transform_loops): Declared. + * Makefile.in (OBJS-common): Add graphite.o. + (graphite.o): New rule. + * passes.c (pass_graphite_transforms): Scheduled. + diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index dbbb8700ffb..95b618e41f3 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20090730 +20090804 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index eeac7deab6a..b43e6ee574f 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1178,6 +1178,14 @@ OBJS-common = \ graph.o \ graphds.o \ graphite.o \ + graphite-blocking.o \ + graphite-clast-to-gimple.o \ + graphite-dependences.o \ + graphite-interchange.o \ + graphite-poly.o \ + graphite-ppl.o \ + graphite-scop-detection.o \ + graphite-sese-to-poly.o \ gtype-desc.o \ haifa-sched.o \ hooks.o \ @@ -1251,6 +1259,7 @@ OBJS-common = \ sel-sched-ir.o \ sel-sched-dump.o \ sel-sched.o \ + sese.o \ simplify-rtx.o \ sparseset.o \ sreal.o \ @@ -1592,9 +1601,35 @@ cs-tm_p.h: Makefile # might be on a read-only file system. If configured for maintainer mode # then do allow autoconf to be run. -$(srcdir)/configure: @MAINT@ $(srcdir)/configure.ac $(srcdir)/aclocal.m4 \ - $(srcdir)/acinclude.m4 - (cd $(srcdir) && autoconf) +AUTOCONF = autoconf +ACLOCAL = aclocal +ACLOCAL_AMFLAGS = -I ../config -I .. +aclocal_deps = \ + $(srcdir)/../libtool.m4 \ + $(srcdir)/../ltoptions.m4 \ + $(srcdir)/../ltsugar.m4 \ + $(srcdir)/../ltversion.m4 \ + $(srcdir)/../lt~obsolete.m4 \ + $(srcdir)/../config/acx.m4 \ + $(srcdir)/../config/codeset.m4 \ + $(srcdir)/../config/extensions.m4 \ + $(srcdir)/../config/gettext-sister.m4 \ + $(srcdir)/../config/iconv.m4 \ + $(srcdir)/../config/lcmessage.m4 \ + $(srcdir)/../config/lib-ld.m4 \ + $(srcdir)/../config/lib-link.m4 \ + $(srcdir)/../config/lib-prefix.m4 \ + $(srcdir)/../config/override.m4 \ + $(srcdir)/../config/progtest.m4 \ + $(srcdir)/../config/unwind_ipinfo.m4 \ + $(srcdir)/../config/warnings.m4 \ + $(srcdir)/acinclude.m4 + +$(srcdir)/configure: @MAINT@ $(srcdir)/configure.ac $(srcdir)/aclocal.m4 + (cd $(srcdir) && $(AUTOCONF)) + +$(srcdir)/aclocal.m4 : @MAINT@ $(aclocal_deps) + (cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)) gccbug: $(srcdir)/gccbug.in CONFIG_FILES=gccbug CONFIG_HEADERS= ./config.status @@ -1611,9 +1646,10 @@ gccbug: $(srcdir)/gccbug.in # Don't run autoheader automatically either. # Only run it if maintainer mode is enabled. +@MAINT@ AUTOHEADER = autoheader @MAINT@ $(srcdir)/config.in: $(srcdir)/cstamp-h.in @MAINT@ $(srcdir)/cstamp-h.in: $(srcdir)/configure.ac -@MAINT@ (cd $(srcdir) && autoheader) +@MAINT@ (cd $(srcdir) && $(AUTOHEADER)) @MAINT@ @rm -f $(srcdir)/cstamp-h.in @MAINT@ echo timestamp > $(srcdir)/cstamp-h.in auto-host.h: cstamp-h ; @true @@ -2423,11 +2459,64 @@ tree-data-ref.o: tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \ $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \ $(TREE_DATA_REF_H) $(TREE_PASS_H) langhooks.h +sese.o: sese.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TOPLEV_H) \ + $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) $(GIMPLE_H) \ + domwalk.h pointer-set.h value-prof.h graphite.o: graphite.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TOPLEV_H) \ $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) $(GIMPLE_H) \ - $(TREE_DATA_REF_H) $(SCEV_H) $(TREE_PASS_H) tree-chrec.h graphite.h \ - pointer-set.h value-prof.h + $(TREE_DATA_REF_H) tree-pass.h graphite.h \ + pointer-set.h value-prof.h graphite-ppl.h sese.h \ + graphite-scop-detection.h graphite-clast-to-gimple.h \ + graphite-poly.h graphite-sese-to-poly.h +graphite-blocking.o: graphite-blocking.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h \ + $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \ + $(TOPLEV_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \ + $(GIMPLE_H) $(TREE_DATA_REF_H) tree-pass.h \ + graphite.h graphite-poly.h graphite-ppl.h +graphite-clast-to-gimple.o: graphite-clast-to-gimple.c $(CONFIG_H) \ + $(SYSTEM_H) coretypes.h $(TM_H) \ + $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TOPLEV_H) \ + $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) $(GIMPLE_H) \ + $(TREE_DATA_REF_H) tree-pass.h graphite.h \ + pointer-set.h value-prof.h graphite-ppl.h sese.h \ + graphite-scop-detection.h graphite-clast-to-gimple.h graphite-poly.h \ + graphite-dependences.h +graphite-dependences.o: graphite-dependences.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h \ + $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \ + $(TOPLEV_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \ + $(GIMPLE_H) $(TREE_DATA_REF_H) tree-pass.h \ + graphite.h graphite-poly.h graphite-ppl.h graphite-dependences.h +graphite-interchange.o: graphite-interchange.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h \ + $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \ + $(TOPLEV_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \ + $(GIMPLE_H) $(TREE_DATA_REF_H) tree-pass.h \ + graphite.h graphite-poly.h graphite-ppl.h +graphite-poly.o: graphite-poly.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TOPLEV_H) \ + $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) $(GIMPLE_H) \ + $(TREE_DATA_REF_H) tree-pass.h graphite.h graphite-dependences.h \ + pointer-set.h value-prof.h graphite-ppl.h sese.h output.h graphite-poly.h +graphite-ppl.o: graphite-ppl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(GGC_H) graphite-ppl.h +graphite-scop-detection.o: graphite-scop-detection.c $(CONFIG_H) $(SYSTEM_H) \ + $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TOPLEV_H) \ + $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) $(GIMPLE_H) \ + $(TREE_DATA_REF_H) tree-pass.h graphite.h $(TM_H) \ + value-prof.h graphite-ppl.h sese.h pointer-set.h coretypes.h \ + graphite-scop-detection.h graphite-poly.h +graphite-sese-to-poly.o: graphite-sese-to-poly.c $(CONFIG_H) \ + $(SYSTEM_H) coretypes.h $(TM_H) \ + $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TOPLEV_H) \ + $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) $(GIMPLE_H) \ + $(TREE_DATA_REF_H) tree-pass.h graphite.h \ + pointer-set.h value-prof.h graphite-ppl.h sese.h \ + graphite-scop-detection.h graphite-sese-to-poly.h $(PARAMS_H) \ + graphite-clast-to-gimple.h graphite-poly.h tree-vect-loop.o: tree-vect-loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(GGC_H) $(TREE_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) \ $(TREE_DUMP_H) $(CFGLOOP_H) $(EXPR_H) $(RECOG_H) $(OPTABS_H) $(TOPLEV_H) \ diff --git a/gcc/aclocal.m4 b/gcc/aclocal.m4 index 72765902458..99756b180cf 100644 --- a/gcc/aclocal.m4 +++ b/gcc/aclocal.m4 @@ -92,6 +92,11 @@ if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then fi ]) +m4_include([../libtool.m4]) +m4_include([../ltoptions.m4]) +m4_include([../ltsugar.m4]) +m4_include([../ltversion.m4]) +m4_include([../lt~obsolete.m4]) m4_include([../config/acx.m4]) m4_include([../config/codeset.m4]) m4_include([../config/extensions.m4]) @@ -105,9 +110,4 @@ m4_include([../config/override.m4]) m4_include([../config/progtest.m4]) m4_include([../config/unwind_ipinfo.m4]) m4_include([../config/warnings.m4]) -m4_include([../libtool.m4]) -m4_include([../ltoptions.m4]) -m4_include([../ltsugar.m4]) -m4_include([../ltversion.m4]) -m4_include([../lt~obsolete.m4]) m4_include([acinclude.m4]) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 35aa5423619..bf7b6c7c2c4 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2009-08-02 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/gigi.h (end_subprog_body): Tweak comment. + * gcc-interface/utils.c (end_subprog_body): Likewise. + * gcc-interface/trans.c (gigi): Likewise. + (gnat_to_gnu): Likewise. + 2009-07-30 Ben Brosgol <brosgol@adacore.com> * gnat_ugn.texi: Correct minor texi glitch. @@ -520,9 +527,14 @@ 2009-07-23 Thomas Quinot <quinot@adacore.com> * scos.ads: Minor typo fix + * gcc-interface/decl.c (validate_alignment): For the case of an implicit array base type, look for alignment clause on first subtype. - Code clean up. + +2009-07-23 Robert Dewar <dewar@adacore.com> + + * gcc-interface/decl.c (gnat_to_gnu_field): Don't check for overlap + with tagged parent if tagged parent is fully repped. 2009-07-23 Ed Schonberg <schonberg@adacore.com> diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index 05a46869f6e..a6171b26578 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -677,8 +677,7 @@ extern tree create_label_decl (tree label_name); appearing in the subprogram. */ extern void begin_subprog_body (tree subprog_decl); -/* Finish the definition of the current subprogram BODY and compile it all the - way to assembler language output. */ +/* Finish the definition of the current subprogram BODY and finalize it. */ extern void end_subprog_body (tree body); /* Build a template of type TEMPLATE_TYPE from the array bounds of ARRAY_TYPE. diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 0dcc5937e1a..84053a4c2e8 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -626,8 +626,7 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name, /* Finally see if we have any elaboration procedures to deal with. */ for (info = elab_info_list; info; info = info->next) { - tree gnu_body = DECL_SAVED_TREE (info->elab_proc); - tree gnu_stmts; + tree gnu_body = DECL_SAVED_TREE (info->elab_proc), gnu_stmts; /* Unshare SAVE_EXPRs between subprograms. These are not unshared by the gimplifier for obvious reasons, but it turns out that we need to @@ -639,21 +638,16 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name, an upstream bug for which we would not change the outcome. */ walk_tree_without_duplicates (&gnu_body, unshare_save_expr, NULL); - - /* We should have a BIND_EXPR, but it may or may not have any statements - in it. If it doesn't have any, we have nothing to do. */ + /* We should have a BIND_EXPR but it may not have any statements in it. + If it doesn't have any, we have nothing to do except for setting the + flag on the GNAT node. Otherwise, process the function as others. */ gnu_stmts = gnu_body; if (TREE_CODE (gnu_stmts) == BIND_EXPR) gnu_stmts = BIND_EXPR_BODY (gnu_stmts); - - /* If there are no statements, there is no elaboration code. */ if (!gnu_stmts || !STATEMENT_LIST_HEAD (gnu_stmts)) - { - Set_Has_No_Elaboration_Code (info->gnat_node, 1); - } + Set_Has_No_Elaboration_Code (info->gnat_node, 1); else { - /* Process the function as others. */ begin_subprog_body (info->elab_proc); end_subprog_body (gnu_body); } @@ -5294,12 +5288,11 @@ gnat_to_gnu (Node_Id gnat_node) gnu_result = alloc_stmt_list (); break; - /* SCIL nodes require no processing by this backend */ - case N_SCIL_Dispatch_Table_Object_Init: case N_SCIL_Dispatch_Table_Tag_Init: case N_SCIL_Dispatching_Call: case N_SCIL_Tag_Init: + /* SCIL nodes require no processing for GCC. */ gnu_result = alloc_stmt_list (); break; diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 1548f6de8bd..e61a0fad537 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -2069,8 +2069,7 @@ gnat_genericize (tree fndecl) pointer_set_destroy (p_set); } -/* Finish the definition of the current subprogram BODY and compile it all the - way to assembler language output. */ +/* Finish the definition of the current subprogram BODY and finalize it. */ void end_subprog_body (tree body) @@ -2109,8 +2108,7 @@ end_subprog_body (tree body) /* Dump functions before gimplification. */ dump_function (TDI_original, fndecl); - /* We do different things for nested and non-nested functions. - ??? This should be in cgraph. */ + /* ??? This special handling of nested functions is probably obsolete. */ if (!DECL_CONTEXT (fndecl)) cgraph_finalize_function (fndecl, false); else diff --git a/gcc/calls.c b/gcc/calls.c index bac4f8bb5d9..6d186c581c3 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1122,13 +1122,9 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, } } - mode = TYPE_MODE (type); unsignedp = TYPE_UNSIGNED (type); - - if (targetm.calls.promote_function_args (fndecl - ? TREE_TYPE (fndecl) - : fntype)) - mode = promote_mode (type, mode, &unsignedp, 1); + mode = promote_function_mode (type, TYPE_MODE (type), &unsignedp, + fndecl ? TREE_TYPE (fndecl) : fntype, 0); args[i].unsignedp = unsignedp; args[i].mode = mode; @@ -1308,29 +1304,33 @@ precompute_arguments (int num_actuals, struct arg_data *args) for (i = 0; i < num_actuals; i++) { + tree type; enum machine_mode mode; if (TREE_CODE (args[i].tree_value) != CALL_EXPR) continue; /* If this is an addressable type, we cannot pre-evaluate it. */ - gcc_assert (!TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value))); + type = TREE_TYPE (args[i].tree_value); + gcc_assert (!TREE_ADDRESSABLE (type)); args[i].initial_value = args[i].value = expand_normal (args[i].tree_value); - mode = TYPE_MODE (TREE_TYPE (args[i].tree_value)); + mode = TYPE_MODE (type); if (mode != args[i].mode) { + int unsignedp = args[i].unsignedp; args[i].value = convert_modes (args[i].mode, mode, args[i].value, args[i].unsignedp); -#if defined(PROMOTE_FUNCTION_MODE) && !defined(PROMOTE_MODE) + /* CSE will replace this only if it contains args[i].value pseudo, so convert it down to the declared mode using a SUBREG. */ if (REG_P (args[i].value) - && GET_MODE_CLASS (args[i].mode) == MODE_INT) + && GET_MODE_CLASS (args[i].mode) == MODE_INT + && promote_mode (type, mode, &unsignedp) != args[i].mode) { args[i].initial_value = gen_lowpart_SUBREG (mode, args[i].value); @@ -1338,7 +1338,6 @@ precompute_arguments (int num_actuals, struct arg_data *args) SUBREG_PROMOTED_UNSIGNED_SET (args[i].initial_value, args[i].unsignedp); } -#endif } } } @@ -2346,17 +2345,17 @@ expand_call (tree exp, rtx target, int ignore) tree caller_res = DECL_RESULT (current_function_decl); caller_unsignedp = TYPE_UNSIGNED (TREE_TYPE (caller_res)); - caller_mode = caller_promoted_mode = DECL_MODE (caller_res); + caller_mode = DECL_MODE (caller_res); callee_unsignedp = TYPE_UNSIGNED (TREE_TYPE (funtype)); - callee_mode = callee_promoted_mode = TYPE_MODE (TREE_TYPE (funtype)); - if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl))) - caller_promoted_mode - = promote_mode (TREE_TYPE (caller_res), caller_mode, - &caller_unsignedp, 1); - if (targetm.calls.promote_function_return (funtype)) - callee_promoted_mode - = promote_mode (TREE_TYPE (funtype), callee_mode, - &callee_unsignedp, 1); + callee_mode = TYPE_MODE (TREE_TYPE (funtype)); + caller_promoted_mode + = promote_function_mode (TREE_TYPE (caller_res), caller_mode, + &caller_unsignedp, + TREE_TYPE (current_function_decl), 1); + callee_promoted_mode + = promote_function_mode (TREE_TYPE (caller_res), callee_mode, + &callee_unsignedp, + TREE_TYPE (funtype), 1); if (caller_mode != VOIDmode && (caller_promoted_mode != callee_promoted_mode || ((caller_mode != caller_promoted_mode @@ -3030,38 +3029,37 @@ expand_call (tree exp, rtx target, int ignore) else target = copy_to_reg (avoid_likely_spilled_reg (valreg)); - if (targetm.calls.promote_function_return(funtype)) + /* If we promoted this return value, make the proper SUBREG. + TARGET might be const0_rtx here, so be careful. */ + if (REG_P (target) + && TYPE_MODE (TREE_TYPE (exp)) != BLKmode + && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp))) { - /* If we promoted this return value, make the proper SUBREG. - TARGET might be const0_rtx here, so be careful. */ - if (REG_P (target) - && TYPE_MODE (TREE_TYPE (exp)) != BLKmode - && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp))) + tree type = TREE_TYPE (exp); + int unsignedp = TYPE_UNSIGNED (type); + int offset = 0; + enum machine_mode pmode; + + /* Ensure we promote as expected, and get the new unsignedness. */ + pmode = promote_function_mode (type, TYPE_MODE (type), &unsignedp, + funtype, 1); + gcc_assert (GET_MODE (target) == pmode); + + if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN) + && (GET_MODE_SIZE (GET_MODE (target)) + > GET_MODE_SIZE (TYPE_MODE (type)))) { - tree type = TREE_TYPE (exp); - int unsignedp = TYPE_UNSIGNED (type); - int offset = 0; - enum machine_mode pmode; - - pmode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1); - /* If we don't promote as expected, something is wrong. */ - gcc_assert (GET_MODE (target) == pmode); - - if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN) - && (GET_MODE_SIZE (GET_MODE (target)) - > GET_MODE_SIZE (TYPE_MODE (type)))) - { - offset = GET_MODE_SIZE (GET_MODE (target)) - - GET_MODE_SIZE (TYPE_MODE (type)); - if (! BYTES_BIG_ENDIAN) - offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD; - else if (! WORDS_BIG_ENDIAN) - offset %= UNITS_PER_WORD; - } - target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset); - SUBREG_PROMOTED_VAR_P (target) = 1; - SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp); + offset = GET_MODE_SIZE (GET_MODE (target)) + - GET_MODE_SIZE (TYPE_MODE (type)); + if (! BYTES_BIG_ENDIAN) + offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD; + else if (! WORDS_BIG_ENDIAN) + offset %= UNITS_PER_WORD; } + + target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset); + SUBREG_PROMOTED_VAR_P (target) = 1; + SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp); } /* If size of args is variable or this was a constructor call for a stack @@ -3876,15 +3874,14 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, } else { - /* Convert to the proper mode if PROMOTE_MODE has been active. */ + /* Convert to the proper mode if a promotion has been active. */ if (GET_MODE (valreg) != outmode) { int unsignedp = TYPE_UNSIGNED (tfom); - gcc_assert (targetm.calls.promote_function_return (tfom)); - gcc_assert (promote_mode (tfom, outmode, &unsignedp, 0) + gcc_assert (promote_function_mode (tfom, outmode, &unsignedp, + fndecl ? TREE_TYPE (fndecl) : fntype, 1) == GET_MODE (valreg)); - valreg = convert_modes (outmode, GET_MODE (valreg), valreg, 0); } diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 359433922d5..07d6dd30974 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -74,6 +74,9 @@ gimple_assign_rhs_to_tree (gimple stmt) else gcc_unreachable (); + if (gimple_has_location (stmt) && CAN_HAVE_LOCATION_P (t)) + SET_EXPR_LOCATION (t, gimple_location (stmt)); + return t; } @@ -1199,9 +1202,7 @@ expand_one_register_var (tree var) { tree decl = SSAVAR (var); tree type = TREE_TYPE (decl); - int unsignedp = TYPE_UNSIGNED (type); - enum machine_mode reg_mode - = promote_mode (type, DECL_MODE (decl), &unsignedp, 0); + enum machine_mode reg_mode = promote_decl_mode (decl, NULL); rtx x = gen_reg_rtx (reg_mode); set_rtl (var, x); diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c index e74284e8988..b9af098d070 100644 --- a/gcc/cfgloop.c +++ b/gcc/cfgloop.c @@ -338,6 +338,7 @@ alloc_loop (void) loop->exits = GGC_CNEW (struct loop_exit); loop->exits->next = loop->exits->prev = loop->exits; + loop->can_be_parallel = false; return loop; } diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 2bc965b577b..d6c26bf0ba0 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -157,6 +157,9 @@ struct GTY ((chain_next ("%h.next"))) loop { /* Head of the cyclic list of the exits of the loop. */ struct loop_exit *exits; + + /* True if the loop can be parallel. */ + bool can_be_parallel; }; /* Flags for state of loop structure. */ @@ -283,7 +286,7 @@ extern bool can_duplicate_loop_p (const struct loop *loop); extern edge create_empty_if_region_on_edge (edge, tree); extern struct loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree, - tree *, struct loop *); + tree *, tree *, struct loop *); extern struct loop * duplicate_loop (struct loop *, struct loop *); extern bool duplicate_loop_to_header_edge (struct loop *, edge, unsigned, sbitmap, edge, diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c index 28cfa3cfc9a..40e3f8e9a59 100644 --- a/gcc/cfgloopmanip.c +++ b/gcc/cfgloopmanip.c @@ -588,31 +588,35 @@ create_empty_if_region_on_edge (edge entry_edge, tree condition) /* create_empty_loop_on_edge | - | ------------- ------------------------ - | | pred_bb | | pred_bb | - | ------------- | IV_0 = INITIAL_VALUE | - | | ------------------------ - | | ______ | ENTRY_EDGE - | | ENTRY_EDGE / V V - | | ====> | ----------------------------- - | | | | IV_BEFORE = phi (IV_0, IV) | - | | | | loop_header | - | V | | IV_BEFORE <= UPPER_BOUND | - | ------------- | -----------------------\----- - | | succ_bb | | | \ - | ------------- | | \ exit_e - | | V V--------- - | | -------------- | succ_bb | - | | | loop_latch | ---------- - | | |IV = IV_BEFORE + STRIDE - | | -------------- - | \ / - | \ ___ / + | - pred_bb - ------ pred_bb ------ + | | | | iv0 = initial_value | + | -----|----- ---------|----------- + | | ______ | entry_edge + | | entry_edge / | | + | | ====> | -V---V- loop_header ------------- + | V | | iv_before = phi (iv0, iv_after) | + | - succ_bb - | ---|----------------------------- + | | | | | + | ----------- | ---V--- loop_body --------------- + | | | iv_after = iv_before + stride | + | | | if (iv_after <= upper_bound) | + | | ---|--------------\-------------- + | | | \ exit_e + | | V \ + | | - loop_latch - V- succ_bb - + | | | | | | + | | /------------- ----------- + | \ ___ / Creates an empty loop as shown above, the IV_BEFORE is the SSA_NAME that is used before the increment of IV. IV_BEFORE should be used for adding code to the body that uses the IV. OUTER is the outer loop in - which the new loop should be inserted. */ + which the new loop should be inserted. + + Both INITIAL_VALUE and UPPER_BOUND expressions are gimplified and + inserted on the loop entry edge. This implies that this function + should be used only when the UPPER_BOUND expression is a loop + invariant. */ struct loop * create_empty_loop_on_edge (edge entry_edge, @@ -620,6 +624,7 @@ create_empty_loop_on_edge (edge entry_edge, tree stride, tree upper_bound, tree iv, tree *iv_before, + tree *iv_after, struct loop *outer) { basic_block loop_header, loop_latch, succ_bb, pred_bb; @@ -627,13 +632,11 @@ create_empty_loop_on_edge (edge entry_edge, int freq; gcov_type cnt; gimple_stmt_iterator gsi; - bool insert_after; gimple_seq stmts; gimple cond_expr; tree exit_test; edge exit_e; int prob; - tree upper_bound_gimplified; gcc_assert (entry_edge && initial_value && stride && upper_bound && iv); @@ -667,6 +670,11 @@ create_empty_loop_on_edge (edge entry_edge, /* Update dominators. */ update_dominators_in_loop (loop); + /* Modify edge flags. */ + exit_e = single_exit (loop); + exit_e->flags = EDGE_LOOP_EXIT | EDGE_FALSE_VALUE; + single_pred_edge (loop_latch)->flags = EDGE_TRUE_VALUE; + /* Construct IV code in loop. */ initial_value = force_gimple_operand (initial_value, &stmts, true, iv); if (stmts) @@ -675,24 +683,20 @@ create_empty_loop_on_edge (edge entry_edge, gsi_commit_edge_inserts (); } - standard_iv_increment_position (loop, &gsi, &insert_after); - create_iv (initial_value, stride, iv, loop, &gsi, insert_after, - iv_before, NULL); - - /* Modify edge flags. */ - exit_e = single_exit (loop); - exit_e->flags = EDGE_LOOP_EXIT | EDGE_FALSE_VALUE; - single_pred_edge (loop_latch)->flags = EDGE_TRUE_VALUE; + upper_bound = force_gimple_operand (upper_bound, &stmts, true, NULL); + if (stmts) + { + gsi_insert_seq_on_edge (loop_preheader_edge (loop), stmts); + gsi_commit_edge_inserts (); + } - gsi = gsi_last_bb (exit_e->src); + gsi = gsi_last_bb (loop_header); + create_iv (initial_value, stride, iv, loop, &gsi, false, + iv_before, iv_after); - upper_bound_gimplified = - force_gimple_operand_gsi (&gsi, upper_bound, true, NULL, - false, GSI_NEW_STMT); - gsi = gsi_last_bb (exit_e->src); - - cond_expr = gimple_build_cond - (LE_EXPR, *iv_before, upper_bound_gimplified, NULL_TREE, NULL_TREE); + /* Insert loop exit condition. */ + cond_expr = gimple_build_cond + (LE_EXPR, *iv_after, upper_bound, NULL_TREE, NULL_TREE); exit_test = gimple_cond_lhs (cond_expr); exit_test = force_gimple_operand_gsi (&gsi, exit_test, true, NULL, @@ -701,6 +705,8 @@ create_empty_loop_on_edge (edge entry_edge, gsi = gsi_last_bb (exit_e->src); gsi_insert_after (&gsi, cond_expr, GSI_NEW_STMT); + split_block_after_labels (loop_header); + return loop; } diff --git a/gcc/combine.c b/gcc/combine.c index 3f39bc3b286..6a0e6ec5c93 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -1333,9 +1333,6 @@ setup_incoming_promotions (rtx first) tree arg; bool strictly_local = false; - if (!targetm.calls.promote_function_args (TREE_TYPE (cfun->decl))) - return; - for (arg = DECL_ARGUMENTS (current_function_decl); arg; arg = TREE_CHAIN (arg)) { @@ -1365,7 +1362,8 @@ setup_incoming_promotions (rtx first) /* The mode and signedness of the argument as it is actually passed, after any TARGET_PROMOTE_FUNCTION_ARGS-driven ABI promotions. */ - mode3 = promote_mode (DECL_ARG_TYPE (arg), mode2, &uns3, 1); + mode3 = promote_function_mode (DECL_ARG_TYPE (arg), mode2, &uns3, + TREE_TYPE (cfun->decl), 0); /* The mode of the register in which the argument is being passed. */ mode4 = GET_MODE (reg); diff --git a/gcc/common.opt b/gcc/common.opt index ada94e95a18..d8507d1d1d1 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -571,6 +571,16 @@ fgraphite Common Report Var(flag_graphite) Enable in and out of Graphite representation +; This option is not documented as it does not perform any useful optimization. +fgraphite-identity +Common Report Var(flag_graphite_identity) Optimization +Enable Graphite Identity transformation + +; This option is not documented as it will be removed +floop-parallelize-all +Common Report Var(flag_loop_parallelize_all) Optimization +Mark all loops as parallel + floop-strip-mine Common Report Var(flag_loop_strip_mine) Optimization Enable Loop Strip Mining transformation @@ -583,11 +593,6 @@ floop-block Common Report Var(flag_loop_block) Optimization Enable Loop Blocking transformation -; This option is not documented as it does not perform any useful optimization. -fgraphite-identity -Common Report Var(flag_graphite_identity) Optimization -Enable Graphite Identity transformation - fguess-branch-probability Common Report Var(flag_guess_branch_prob) Optimization Enable guessing of branch probabilities diff --git a/gcc/config.gcc b/gcc/config.gcc index ddc8fc869eb..2c8dd98b45c 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -894,6 +894,15 @@ moxie-*-elf) extra_parts="crti.o crtn.o crtbegin.o crtend.o" tmake_file="${tmake_file} moxie/t-moxie moxie/t-moxie-softfp soft-fp/t-softfp" ;; +moxie-*-uclinux*) + gas=yes + gnu_ld=yes + tm_file="dbxelf.h elfos.h svr4.h ${tm_file} linux.h glibc-stdint.h moxie/uclinux.h" + extra_parts="crti.o crtn.o crtbegin.o crtend.o" + tmake_file="${tmake_file} moxie/t-moxie moxie/t-moxie-softfp soft-fp/t-softfp" + tm_defines="${tm_defines} UCLIBC_DEFAULT=1" + extra_options="${extra_options} linux.opt" + ;; h8300-*-rtems*) tmake_file="h8300/t-h8300 h8300/t-elf t-rtems h8300/t-rtems" tm_file="h8300/h8300.h dbxelf.h elfos.h h8300/elf.h h8300/rtems.h rtems.h newlib-stdint.h" @@ -942,6 +951,8 @@ hppa[12]*-*-hpux10*) extra_options="${extra_options} pa/pa-hpux1010.opt" ;; esac + use_gcc_stdint=provide + tm_file="${tm_file} hpux-stdint.h" tmake_file="pa/t-pa-hpux10 pa/t-pa-hpux pa/t-hpux-shlib" case ${enable_threads} in "") @@ -2087,7 +2098,7 @@ sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \ sh*-*-linux*) tmake_file="${tmake_file} sh/t-linux" tm_file="${tm_file} linux.h glibc-stdint.h sh/linux.h" ;; sh*-*-netbsd*) tm_file="${tm_file} netbsd.h netbsd-elf.h sh/netbsd-elf.h" ;; - sh*-superh-elf) if test x$with_libgloss != xno; then + sh*-*-elf) if test x$with_libgloss != xno; then with_libgloss=yes tm_file="${tm_file} sh/newlib.h" fi diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index a9f5fba7ca5..fe515d4d0f2 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -2062,11 +2062,22 @@ alpha_legitimate_constant_p (rtx x) switch (GET_CODE (x)) { - case CONST: case LABEL_REF: case HIGH: return true; + case CONST: + if (GET_CODE (XEXP (x, 0)) == PLUS + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT) + x = XEXP (XEXP (x, 0), 0); + else + return true; + + if (GET_CODE (x) != SYMBOL_REF) + return true; + + /* FALLTHRU */ + case SYMBOL_REF: /* TLS symbols are never valid. */ return SYMBOL_REF_TLS_MODEL (x) == 0; @@ -10818,10 +10829,8 @@ alpha_init_libfuncs (void) #undef TARGET_MACHINE_DEPENDENT_REORG #define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false #undef TARGET_RETURN_IN_MEMORY diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index 66709c7f31c..f53c8988b4f 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -133,10 +133,8 @@ static const struct attribute_spec arc_attribute_table[] = #undef TARGET_ADDRESS_COST #define TARGET_ADDRESS_COST arc_address_cost -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 85b4995ab0c..83db0ec1cda 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -125,6 +125,8 @@ static int arm_adjust_cost (rtx, rtx, rtx, int); static int count_insns_for_constant (HOST_WIDE_INT, int); static int arm_get_strip_length (int); static bool arm_function_ok_for_sibcall (tree, tree); +static enum machine_mode arm_promote_function_mode (const_tree, enum machine_mode, + int *, const_tree, int); static void arm_internal_label (FILE *, const char *, unsigned long); static void arm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree); @@ -329,10 +331,8 @@ static const struct attribute_spec arm_attribute_table[] = #undef TARGET_INIT_LIBFUNCS #define TARGET_INIT_LIBFUNCS arm_init_libfuncs -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE arm_promote_function_mode #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES arm_promote_prototypes #undef TARGET_PASS_BY_REFERENCE @@ -3072,7 +3072,7 @@ arm_canonicalize_comparison (enum rtx_code code, enum machine_mode mode, /* Define how to find the value returned by a function. */ rtx -arm_function_value(const_tree type, const_tree func ATTRIBUTE_UNUSED) +arm_function_value(const_tree type, const_tree func) { enum machine_mode mode; int unsignedp ATTRIBUTE_UNUSED; @@ -3081,7 +3081,7 @@ arm_function_value(const_tree type, const_tree func ATTRIBUTE_UNUSED) mode = TYPE_MODE (type); /* Promote integer types. */ if (INTEGRAL_TYPE_P (type)) - PROMOTE_FUNCTION_MODE (mode, unsignedp, type); + mode = arm_promote_function_mode (type, mode, &unsignedp, func, 1); /* Promotes small structs returned in a register to full-word size for big-endian AAPCS. */ @@ -6329,9 +6329,9 @@ arm_arm_address_cost (rtx x) if (c == MEM || c == LABEL_REF || c == SYMBOL_REF) return 10; - if (c == PLUS || c == MINUS) + if (c == PLUS) { - if (GET_CODE (XEXP (x, 0)) == CONST_INT) + if (GET_CODE (XEXP (x, 1)) == CONST_INT) return 2; if (ARITHMETIC_P (XEXP (x, 0)) || ARITHMETIC_P (XEXP (x, 1))) @@ -19094,6 +19094,19 @@ arm_promote_prototypes (const_tree t ATTRIBUTE_UNUSED) return !TARGET_AAPCS_BASED; } +static enum machine_mode +arm_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, + enum machine_mode mode, + int *punsignedp ATTRIBUTE_UNUSED, + const_tree fntype ATTRIBUTE_UNUSED, + int for_return ATTRIBUTE_UNUSED) +{ + if (GET_MODE_CLASS (mode) == MODE_INT + && GET_MODE_SIZE (mode) < 4) + return SImode; + + return mode; +} /* AAPCS based ABIs use short enums by default. */ diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 58ced2e7e51..082b5fabc3a 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -501,11 +501,6 @@ extern int arm_arch_hwdiv; (MODE) = SImode; \ } -#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \ - if (GET_MODE_CLASS (MODE) == MODE_INT \ - && GET_MODE_SIZE (MODE) < 4) \ - (MODE) = SImode; - /* Define this if most significant bit is lowest numbered in instructions that operate on numbered bit-fields. */ #define BITS_BIG_ENDIAN 0 diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 4f213062a4f..13887480d1f 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -6296,12 +6296,8 @@ bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, #undef TARGET_SCHED_ISSUE_RATE #define TARGET_SCHED_ISSUE_RATE bfin_issue_rate -#undef TARGET_PROMOTE_PROTOTYPES -#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote #undef TARGET_ARG_PARTIAL_BYTES #define TARGET_ARG_PARTIAL_BYTES bfin_arg_partial_bytes diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index 66fc05d0f6e..a9fe9dee52f 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -85,6 +85,9 @@ static int in_code = 0; /* Fix for reg_overlap_mentioned_p. */ static int cris_reg_overlap_mentioned_p (rtx, rtx); +static enum machine_mode cris_promote_function_mode (const_tree, enum machine_mode, + int *, const_tree, int); + static void cris_print_base (rtx, FILE *); static void cris_print_index (rtx, FILE *); @@ -166,8 +169,9 @@ int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION; #undef TARGET_ADDRESS_COST #define TARGET_ADDRESS_COST cris_address_cost -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE cris_promote_function_mode + #undef TARGET_STRUCT_VALUE_RTX #define TARGET_STRUCT_VALUE_RTX cris_struct_value_rtx #undef TARGET_SETUP_INCOMING_VARARGS @@ -3753,6 +3757,25 @@ cris_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, || CRIS_FUNCTION_ARG_SIZE (mode, type) > 8); } +/* A combination of defining TARGET_PROMOTE_FUNCTION_MODE, promoting arguments + and *not* defining TARGET_PROMOTE_PROTOTYPES or PROMOTE_MODE gives the + best code size and speed for gcc, ipps and products in gcc-2.7.2. */ + +enum machine_mode +cris_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, + enum machine_mode mode, + int *punsignedp ATTRIBUTE_UNUSED, + const_tree fntype ATTRIBUTE_UNUSED, + int for_return) +{ + /* Defining PROMOTE_FUNCTION_RETURN in gcc-2.7.2 uncovered bug 981110 (even + when modifying FUNCTION_VALUE to return the promoted mode). Maybe + pointless as of now, but let's keep the old behavior. */ + if (for_return) + return mode; + return CRIS_PROMOTED_MODE (mode, *punsignedp, type); +} + static int cris_arg_partial_bytes (CUMULATIVE_ARGS *ca, enum machine_mode mode, diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h index 920e354417e..39291079662 100644 --- a/gcc/config/cris/cris.h +++ b/gcc/config/cris/cris.h @@ -352,24 +352,10 @@ extern int target_flags; #define UNITS_PER_WORD 4 -/* A combination of defining PROMOTE_FUNCTION_MODE, - TARGET_PROMOTE_FUNCTION_ARGS that always returns true - and *not* defining TARGET_PROMOTE_PROTOTYPES or PROMOTE_MODE gives the - best code size and speed for gcc, ipps and products in gcc-2.7.2. */ #define CRIS_PROMOTED_MODE(MODE, UNSIGNEDP, TYPE) \ (GET_MODE_CLASS (MODE) == MODE_INT && GET_MODE_SIZE (MODE) < 4) \ ? SImode : MODE -#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \ - (MODE) = CRIS_PROMOTED_MODE (MODE, UNSIGNEDP, TYPE) - -/* Defining PROMOTE_FUNCTION_RETURN in gcc-2.7.2 uncovers bug 981110 (even - if defining FUNCTION_VALUE with MODE as PROMOTED_MODE ;-) - - FIXME: Report this when cris.h is part of GCC, so others can easily - see the problem. Maybe check other systems that define - TARGET_PROMOTE_FUNCTION_RETURN that always returns true. */ - /* We will be using prototype promotion, so they will be 32 bit. */ #define PARM_BOUNDARY 32 diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h index 483ed77e9f7..dfb3fb8eeb1 100644 --- a/gcc/config/frv/frv.h +++ b/gcc/config/frv/frv.h @@ -1764,10 +1764,6 @@ typedef struct frv_stack { (Actually, on most machines, scalar values are returned in the same place regardless of mode). - If `TARGET_PROMOTE_FUNCTION_RETURN' is defined to return true, you - must apply the same promotion rules specified in `PROMOTE_MODE' if - VALTYPE is a scalar type. - If the precise function being called is known, FUNC is a tree node (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer. This makes it possible to use a different value-returning convention for specific diff --git a/gcc/config/i386/att.h b/gcc/config/i386/att.h index 6586ddd3d87..30616904fe2 100644 --- a/gcc/config/i386/att.h +++ b/gcc/config/i386/att.h @@ -31,6 +31,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* Assembler pseudos to introduce constants of various size. */ +#define ASM_BYTE "\t.byte\t" #define ASM_SHORT "\t.value\t" #define ASM_LONG "\t.long\t" #define ASM_QUAD "\t.quad\t" /* Should not be used for 32bit compilation. */ @@ -43,7 +44,7 @@ do \ { size_t i = 0, limit = (SIZE); \ while (i < limit) \ { if (i%10 == 0) { if (i!=0) putc ('\n', (FILE)); \ - fputs ("\t.byte\t", (FILE)); } \ + fputs (ASM_BYTE, (FILE)); } \ else putc (',', (FILE)); \ fprintf ((FILE), "0x%x", ((PTR)[i++] & 0377)) ;} \ putc ('\n', (FILE)); \ diff --git a/gcc/config/i386/bsd.h b/gcc/config/i386/bsd.h index 229777a4640..e408ccdb032 100644 --- a/gcc/config/i386/bsd.h +++ b/gcc/config/i386/bsd.h @@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see /* Assembler pseudos to introduce constants of various size. */ +#define ASM_BYTE "\t.byte\t" #define ASM_SHORT "\t.word\t" #define ASM_LONG "\t.long\t" #define ASM_QUAD "\t.quad\t" /* Should not be used for 32bit compilation. */ diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h index 039f52f77ba..eb9ee70a04d 100644 --- a/gcc/config/i386/darwin.h +++ b/gcc/config/i386/darwin.h @@ -189,7 +189,7 @@ extern void darwin_x86_file_end (void); /* Assembler pseudos to introduce constants of various size. */ -#define ASM_BYTE_OP "\t.byte\t" +#define ASM_BYTE "\t.byte\t" #define ASM_SHORT "\t.word\t" #define ASM_LONG "\t.long\t" #define ASM_QUAD "\t.quad\t" diff --git a/gcc/config/i386/i386-interix.h b/gcc/config/i386/i386-interix.h index 380b46c3d3c..060b82ca245 100644 --- a/gcc/config/i386/i386-interix.h +++ b/gcc/config/i386/i386-interix.h @@ -209,7 +209,7 @@ along with GCC; see the file COPYING3. If not see else \ { \ if (bytes_in_chunk == 0) \ - fprintf ((FILE), "\t.byte\t"); \ + fputs (ASM_BYTE, (FILE)); \ else \ fputc (',', (FILE)); \ fprintf ((FILE), "0x%02x", *_ascii_bytes); \ @@ -217,7 +217,7 @@ along with GCC; see the file COPYING3. If not see } \ } \ if (bytes_in_chunk > 0) \ - fprintf ((FILE), "\n"); \ + fputc ('\n', (FILE)); \ } \ while (0) @@ -277,11 +277,11 @@ do { \ #define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \ do \ { \ - fprintf ((FILE), "%s", SET_ASM_OP); \ + fputs (SET_ASM_OP, (FILE)); \ assemble_name (FILE, LABEL1); \ - fprintf (FILE, ","); \ + fputc (',', (FILE)); \ assemble_name (FILE, LABEL2); \ - fprintf (FILE, "\n"); \ + fputc ('\n', (FILE)); \ } \ while (0) @@ -359,4 +359,4 @@ extern void i386_pe_unique_section (tree, int); #define SUBTARGET_RETURN_IN_MEMORY(TYPE, FNTYPE) \ (TYPE_MODE (TYPE) == BLKmode \ - || (AGGREGATE_TYPE_P (TYPE) && int_size_in_bytes (TYPE) > 8 ))
\ No newline at end of file + || (AGGREGATE_TYPE_P (TYPE) && int_size_in_bytes (TYPE) > 8 )) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 042ff4419f6..ff6373ef00e 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -14814,13 +14814,13 @@ ix86_expand_fp_compare (enum rtx_code code, rtx op0, rtx op1, rtx scratch) if (code == LT && TARGET_IEEE_FP) { emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45))); - emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x01))); + emit_insn (gen_cmpqi_ext_3 (scratch, const1_rtx)); intcmp_mode = CCmode; code = EQ; } else { - emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x01))); + emit_insn (gen_testqi_ext_ccno_0 (scratch, const1_rtx)); code = NE; } break; @@ -14834,8 +14834,7 @@ ix86_expand_fp_compare (enum rtx_code code, rtx op0, rtx op1, rtx scratch) else { emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45))); - emit_insn (gen_xorqi_cc_ext_1 (scratch, scratch, - GEN_INT (0x01))); + emit_insn (gen_xorqi_cc_ext_1 (scratch, scratch, const1_rtx)); code = NE; } break; @@ -14868,7 +14867,6 @@ ix86_expand_fp_compare (enum rtx_code code, rtx op0, rtx op1, rtx scratch) { emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x40))); code = NE; - break; } break; case NE: @@ -17028,14 +17026,15 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode) emit_insn ((mode == DImode ? gen_lshrsi3 - : gen_lshrdi3) (high[0], high[0], GEN_INT (mode == DImode ? 5 : 6))); + : gen_lshrdi3) (high[0], high[0], + GEN_INT (mode == DImode ? 5 : 6))); emit_insn ((mode == DImode ? gen_andsi3 - : gen_anddi3) (high[0], high[0], GEN_INT (1))); + : gen_anddi3) (high[0], high[0], const1_rtx)); emit_move_insn (low[0], high[0]); emit_insn ((mode == DImode ? gen_xorsi3 - : gen_xordi3) (low[0], low[0], GEN_INT (1))); + : gen_xordi3) (low[0], low[0], const1_rtx)); } emit_insn ((mode == DImode @@ -28105,7 +28104,7 @@ ix86_expand_vector_init_one_nonzero (bool mmx_ok, enum machine_mode mode, if (mode != V4SFmode && TARGET_SSE2) { emit_insn (gen_sse2_pshufd_1 (new_target, new_target, - GEN_INT (1), + const1_rtx, GEN_INT (one_var == 1 ? 0 : 1), GEN_INT (one_var == 2 ? 0 : 1), GEN_INT (one_var == 3 ? 0 : 1))); @@ -28125,7 +28124,7 @@ ix86_expand_vector_init_one_nonzero (bool mmx_ok, enum machine_mode mode, tmp = new_target; emit_insn (gen_sse_shufps_v4sf (tmp, tmp, tmp, - GEN_INT (1), + const1_rtx, GEN_INT (one_var == 1 ? 0 : 1), GEN_INT (one_var == 2 ? 0+4 : 1+4), GEN_INT (one_var == 3 ? 0+4 : 1+4))); @@ -28788,8 +28787,8 @@ ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt) ix86_expand_vector_set (false, target, val, 0); /* target = A X C D */ emit_insn (gen_sse_shufps_v4sf (target, target, tmp, - GEN_INT (1), GEN_INT (0), - GEN_INT (2+4), GEN_INT (3+4))); + const1_rtx, const0_rtx, + GEN_INT (2+4), GEN_INT (3+4))); return; case 2: @@ -28799,8 +28798,8 @@ ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt) ix86_expand_vector_set (false, tmp, val, 0); /* target = A B X D */ emit_insn (gen_sse_shufps_v4sf (target, target, tmp, - GEN_INT (0), GEN_INT (1), - GEN_INT (0+4), GEN_INT (3+4))); + const0_rtx, const1_rtx, + GEN_INT (0+4), GEN_INT (3+4))); return; case 3: @@ -28810,8 +28809,8 @@ ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt) ix86_expand_vector_set (false, tmp, val, 0); /* target = A B X D */ emit_insn (gen_sse_shufps_v4sf (target, target, tmp, - GEN_INT (0), GEN_INT (1), - GEN_INT (2+4), GEN_INT (0+4))); + const0_rtx, const1_rtx, + GEN_INT (2+4), GEN_INT (0+4))); return; default: @@ -29104,8 +29103,8 @@ ix86_expand_reduc_v4sf (rtx (*fn) (rtx, rtx, rtx), rtx dest, rtx in) emit_insn (fn (tmp2, tmp1, in)); emit_insn (gen_sse_shufps_v4sf (tmp3, tmp2, tmp2, - GEN_INT (1), GEN_INT (1), - GEN_INT (1+4), GEN_INT (1+4))); + const1_rtx, const1_rtx, + GEN_INT (1+4), GEN_INT (1+4))); emit_insn (fn (dest, tmp2, tmp3)); } @@ -30491,6 +30490,9 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree) #undef TARGET_ASM_CLOSE_PAREN #define TARGET_ASM_CLOSE_PAREN "" +#undef TARGET_ASM_BYTE_OP +#define TARGET_ASM_BYTE_OP ASM_BYTE + #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP ASM_SHORT #undef TARGET_ASM_ALIGNED_SI_OP diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index f50bcc19320..3d832f11249 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1555,7 +1555,7 @@ #ifdef HAVE_AS_IX86_SAHF return "sahf"; #else - return ".byte\t0x9e"; + return ASM_BYTE "0x9e"; #endif } [(set_attr "length" "1") @@ -16473,7 +16473,7 @@ (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] UNSPEC_TLS_GD)] "TARGET_64BIT" - { return ".byte\t0x66\n\tlea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; } + { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; } [(set_attr "type" "multi") (set_attr "length" "16")]) diff --git a/gcc/config/i386/i386elf.h b/gcc/config/i386/i386elf.h index ba53749acc9..44cf6818f7c 100644 --- a/gcc/config/i386/i386elf.h +++ b/gcc/config/i386/i386elf.h @@ -63,7 +63,7 @@ along with GCC; see the file COPYING3. If not see const unsigned char *limit = _ascii_bytes + (LENGTH); \ unsigned bytes_in_chunk = 0; \ for (; _ascii_bytes < limit; _ascii_bytes++) \ - { \ + { \ const unsigned char *p; \ if (bytes_in_chunk >= 64) \ { \ @@ -85,7 +85,7 @@ along with GCC; see the file COPYING3. If not see else \ { \ if (bytes_in_chunk == 0) \ - fprintf ((FILE), "\t.byte\t"); \ + fputs (ASM_BYTE, (FILE)); \ else \ fputc (',', (FILE)); \ fprintf ((FILE), "0x%02x", *_ascii_bytes); \ @@ -93,7 +93,7 @@ along with GCC; see the file COPYING3. If not see } \ } \ if (bytes_in_chunk > 0) \ - fprintf ((FILE), "\n"); \ + fputc ('\n', (FILE)); \ } \ while (0) diff --git a/gcc/config/i386/sysv4.h b/gcc/config/i386/sysv4.h index bedac7a58b6..63c0cbc85a7 100644 --- a/gcc/config/i386/sysv4.h +++ b/gcc/config/i386/sysv4.h @@ -55,7 +55,7 @@ along with GCC; see the file COPYING3. If not see const unsigned char *limit = _ascii_bytes + (LENGTH); \ unsigned bytes_in_chunk = 0; \ for (; _ascii_bytes < limit; _ascii_bytes++) \ - { \ + { \ const unsigned char *p; \ if (bytes_in_chunk >= 64) \ { \ @@ -77,7 +77,7 @@ along with GCC; see the file COPYING3. If not see else \ { \ if (bytes_in_chunk == 0) \ - fprintf ((FILE), "\t.byte\t"); \ + fputs (ASM_BYTE, (FILE)); \ else \ fputc (',', (FILE)); \ fprintf ((FILE), "0x%02x", *_ascii_bytes); \ @@ -85,7 +85,7 @@ along with GCC; see the file COPYING3. If not see } \ } \ if (bytes_in_chunk > 0) \ - fprintf ((FILE), "\n"); \ + fputc ('\n', (FILE)); \ } \ while (0) @@ -103,10 +103,10 @@ along with GCC; see the file COPYING3. If not see do { \ if ((SIZE) == 4 && ((ENCODING) & 0x70) == DW_EH_PE_datarel) \ { \ - fputs (ASM_LONG, FILE); \ - assemble_name (FILE, XSTR (ADDR, 0)); \ - fputs (((ENCODING) & DW_EH_PE_indirect ? "@GOT" : "@GOTOFF"), FILE); \ - goto DONE; \ + fputs (ASM_LONG, (FILE)); \ + assemble_name (FILE, XSTR (ADDR, 0)); \ + fputs (((ENCODING) & DW_EH_PE_indirect ? "@GOT" : "@GOTOFF"), (FILE)); \ + goto DONE; \ } \ } while (0) diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index b2e950e52b8..71acdab0bb9 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -459,14 +459,8 @@ static const struct attribute_spec ia64_attribute_table[] = /* ??? ABI doesn't allow us to define this. */ #if 0 -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true -#endif - -/* ??? ABI doesn't allow us to define this. */ -#if 0 -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote #endif /* ??? Investigate. */ diff --git a/gcc/config/iq2000/iq2000.c b/gcc/config/iq2000/iq2000.c index b99043efa99..ff0c868aaf2 100644 --- a/gcc/config/iq2000/iq2000.c +++ b/gcc/config/iq2000/iq2000.c @@ -189,10 +189,8 @@ static bool iq2000_legitimate_address_p (enum machine_mode, rtx, bool); #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true @@ -2186,15 +2184,14 @@ iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED, FUNC. */ rtx -iq2000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED) +iq2000_function_value (const_tree valtype, const_tree func) { int reg = GP_RETURN; enum machine_mode mode = TYPE_MODE (valtype); int unsignedp = TYPE_UNSIGNED (valtype); - /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns true, - we must promote the mode just as PROMOTE_MODE does. */ - mode = promote_mode (valtype, mode, &unsignedp, 1); + /* Since we promote return types, we must promote the mode here too. */ + mode = promote_function_mode (valtype, mode, &unsignedp, func, 1); return gen_rtx_REG (mode, reg); } diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c index 3b0adef1074..170b4b00de6 100644 --- a/gcc/config/mcore/mcore.c +++ b/gcc/config/mcore/mcore.c @@ -192,10 +192,8 @@ static const struct attribute_spec mcore_attribute_table[] = #undef TARGET_MACHINE_DEPENDENT_REORG #define TARGET_MACHINE_DEPENDENT_REORG mcore_reorg -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true @@ -2730,14 +2728,15 @@ handle_structs_in_regs (enum machine_mode mode, const_tree type, int reg) } rtx -mcore_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED) +mcore_function_value (const_tree valtype, const_tree func) { enum machine_mode mode; int unsigned_p; mode = TYPE_MODE (valtype); - mode = promote_mode (valtype, mode, &unsigned_p, 1); + /* Since we promote return types, we must promote the mode here too. */ + mode = promote_function_mode (valtype, mode, &unsignedp, func, 1); return handle_structs_in_regs (mode, valtype, FIRST_RET_REG); } diff --git a/gcc/config/mep/mep.c b/gcc/config/mep/mep.c index dd229ee05d3..cf2e7d53fc0 100644 --- a/gcc/config/mep/mep.c +++ b/gcc/config/mep/mep.c @@ -7360,16 +7360,16 @@ mep_asm_init_sections (void) "\t.section .srodata,\"a\""); vtext_section - = get_unnamed_section (0, output_section_asm_op, - "\t.section .vtext,\"ax\""); + = get_unnamed_section (SECTION_CODE | SECTION_MEP_VLIW, output_section_asm_op, + "\t.section .vtext,\"axv\"\n\t.vliw"); vftext_section - = get_unnamed_section (0, output_section_asm_op, - "\t.section .vftext,\"ax\""); + = get_unnamed_section (SECTION_CODE | SECTION_MEP_VLIW, output_section_asm_op, + "\t.section .vftext,\"axv\"\n\t.vliw"); ftext_section - = get_unnamed_section (0, output_section_asm_op, - "\t.section .ftext,\"ax\""); + = get_unnamed_section (SECTION_CODE, output_section_asm_op, + "\t.section .ftext,\"ax\"\n\t.core"); } diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index d5d6eeea8d5..222cb8942f9 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -279,7 +279,7 @@ extern void mips_expand_prologue (void); extern void mips_expand_before_return (void); extern void mips_expand_epilogue (bool); extern bool mips_can_use_return_insn (void); -extern rtx mips_function_value (const_tree, enum machine_mode); +extern rtx mips_function_value (const_tree, const_tree, enum machine_mode); extern bool mips_cannot_change_mode_class (enum machine_mode, enum machine_mode, enum reg_class); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 4a10fb47244..083b253faf0 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -4976,7 +4976,7 @@ mips_return_fpr_pair (enum machine_mode mode, VALTYPE is null and MODE is the mode of the return value. */ rtx -mips_function_value (const_tree valtype, enum machine_mode mode) +mips_function_value (const_tree valtype, const_tree func, enum machine_mode mode) { if (valtype) { @@ -4986,9 +4986,9 @@ mips_function_value (const_tree valtype, enum machine_mode mode) mode = TYPE_MODE (valtype); unsigned_p = TYPE_UNSIGNED (valtype); - /* Since TARGET_PROMOTE_FUNCTION_RETURN unconditionally returns true, - we must promote the mode just as PROMOTE_MODE does. */ - mode = promote_mode (valtype, mode, &unsigned_p, 1); + /* Since TARGET_PROMOTE_FUNCTION_MODE unconditionally promotes, + return values, promote the mode here too. */ + mode = promote_function_mode (valtype, mode, &unsigned_p, func, 1); /* Handle structures whose fields are returned in $f0/$f2. */ switch (mips_fpr_return_fields (valtype, fields)) @@ -14851,10 +14851,8 @@ mips_final_postscan_insn (FILE *file, rtx insn, rtx *opvec, int noperands) #undef TARGET_GIMPLIFY_VA_ARG_EXPR #define TARGET_GIMPLIFY_VA_ARG_EXPR mips_gimplify_va_arg_expr -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index a3ab2f8bb8f..8515ce10408 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -2204,10 +2204,10 @@ enum reg_class #define FP_ARG_LAST (FP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1) #define LIBCALL_VALUE(MODE) \ - mips_function_value (NULL_TREE, MODE) + mips_function_value (NULL_TREE, NULL_TREE, MODE) #define FUNCTION_VALUE(VALTYPE, FUNC) \ - mips_function_value (VALTYPE, VOIDmode) + mips_function_value (VALTYPE, FUNC, VOIDmode) /* 1 if N is a possible register number for a function value. On the MIPS, R2 R3 and F0 F2 are the only register thus used. diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index af429ca90f9..02e99375195 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -2785,7 +2785,7 @@ [(set (match_operand:DI 0 "register_operand" "=d,d") (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,W") (const_int 4294967295)))] - "TARGET_64BIT" + "TARGET_64BIT && !ISA_HAS_EXT_INS" { if (which_alternative == 0) return "#"; @@ -2802,6 +2802,21 @@ [(set_attr "move_type" "shift_shift,load") (set_attr "mode" "DI")]) +(define_insn "*clear_upper32_dext" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,W") + (const_int 4294967295)))] + "TARGET_64BIT && ISA_HAS_EXT_INS" +{ + if (which_alternative == 0) + return "dext\t%0,%1,0,32"; + + operands[1] = gen_lowpart (SImode, operands[1]); + return "lwu\t%0,%1"; +} + [(set_attr "move_type" "arith,load") + (set_attr "mode" "DI")]) + (define_expand "zero_extend<SHORT:mode><GPR:mode>2" [(set (match_operand:GPR 0 "register_operand") (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))] diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c index 67b1b2323b5..9e94279b85a 100644 --- a/gcc/config/mmix/mmix.c +++ b/gcc/config/mmix/mmix.c @@ -135,6 +135,9 @@ static void mmix_file_start (void); static void mmix_file_end (void); static bool mmix_rtx_costs (rtx, int, int, int *, bool); static rtx mmix_struct_value_rtx (tree, int); +static enum machine_mode mmix_promote_function_mode (const_tree, + enum machine_mode, + int *, const_tree, int); static bool mmix_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static bool mmix_frame_pointer_required (void); @@ -188,14 +191,9 @@ static bool mmix_frame_pointer_required (void); #undef TARGET_MACHINE_DEPENDENT_REORG #define TARGET_MACHINE_DEPENDENT_REORG mmix_reorg -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true -#if 0 -/* Apparently not doing TRT if int < register-size. FIXME: Perhaps - FUNCTION_VALUE and LIBCALL_VALUE needs tweaking as some ports say. */ -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true -#endif +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE mmix_promote_function_mode + #undef TARGET_STRUCT_VALUE_RTX #define TARGET_STRUCT_VALUE_RTX mmix_struct_value_rtx @@ -2692,6 +2690,28 @@ mmix_intval (rtx x) fatal_insn ("MMIX Internal: This is not a constant:", x); } +/* Worker function for TARGET_PROMOTE_FUNCTION_MODE. */ + +enum machine_mode +mmix_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, + enum machine_mode mode, + int *punsignedp ATTRIBUTE_UNUSED, + const_tree fntype ATTRIBUTE_UNUSED, + int for_return) +{ + /* Apparently not doing TRT if int < register-size. FIXME: Perhaps + FUNCTION_VALUE and LIBCALL_VALUE needs tweaking as some ports say. */ + if (for_return) + return mode; + + /* Promotion of modes currently generates slow code, extending before + operation, so we do it only for arguments. */ + if (GET_MODE_CLASS (mode) == MODE_INT + && GET_MODE_SIZE (mode) < 8) + return DImode; + else + return mode; +} /* Worker function for TARGET_STRUCT_VALUE_RTX. */ static rtx diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h index 72e35680ef5..41466545e21 100644 --- a/gcc/config/mmix/mmix.h +++ b/gcc/config/mmix/mmix.h @@ -182,23 +182,6 @@ extern int target_flags; #define FLOAT_WORDS_BIG_ENDIAN 1 #define UNITS_PER_WORD 8 -/* FIXME: Promotion of modes currently generates slow code, extending - before every operation. */ -/* I'm a little bit undecided about this one. It might be beneficial to - promote all operations. */ - -#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \ - do { \ - if (GET_MODE_CLASS (MODE) == MODE_INT \ - && GET_MODE_SIZE (MODE) < 8) \ - { \ - (MODE) = DImode; \ - /* Do the following some time later, \ - scrutinizing differences. */ \ - if (0) (UNSIGNEDP) = 0; \ - } \ - } while (0) - /* We need to align everything to 64 bits that can affect the alignment of other types. Since address N is interpreted in MMIX as (N modulo access_size), we must align. */ diff --git a/gcc/config/moxie/moxie.c b/gcc/config/moxie/moxie.c index 897717b40df..39a5c10bb69 100644 --- a/gcc/config/moxie/moxie.c +++ b/gcc/config/moxie/moxie.c @@ -284,12 +284,12 @@ moxie_expand_prologue (void) { insn = emit_insn (gen_movsi - (gen_rtx_REG (Pmode, MOXIE_R12), + (gen_rtx_REG (Pmode, MOXIE_R5), GEN_INT (-cfun->machine->size_for_adjusting_sp))); RTX_FRAME_RELATED_P (insn) = 1; insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, - gen_rtx_REG (Pmode, MOXIE_R12))); + gen_rtx_REG (Pmode, MOXIE_R5))); RTX_FRAME_RELATED_P (insn) = 1; } } @@ -303,7 +303,7 @@ moxie_expand_epilogue (void) if (cfun->machine->callee_saved_reg_size != 0) { - reg = gen_rtx_REG (Pmode, MOXIE_R12); + reg = gen_rtx_REG (Pmode, MOXIE_R5); if (cfun->machine->callee_saved_reg_size <= 255) { emit_move_insn (reg, hard_frame_pointer_rtx); @@ -359,14 +359,14 @@ moxie_setup_incoming_varargs (CUMULATIVE_ARGS *cum, int *pretend_size, int no_rtl) { int regno; - int regs = 4 - *cum; + int regs = 7 - *cum; *pretend_size = regs < 0 ? 0 : GET_MODE_SIZE (SImode) * regs; if (no_rtl) return; - for (regno = *cum; regno < 4; regno++) + for (regno = *cum; regno < 7; regno++) { rtx reg = gen_rtx_REG (SImode, regno); rtx slot = gen_rtx_PLUS (Pmode, @@ -395,7 +395,7 @@ rtx moxie_function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode, tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED) { - if (cum < 4) + if (cum < 7) return gen_rtx_REG (mode, cum); else return NULL_RTX; @@ -420,7 +420,7 @@ moxie_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, else size = GET_MODE_SIZE (mode); - return size > 8; + return size > 4*5; } /* Some function arguments will only partially fit in the registers @@ -434,7 +434,7 @@ moxie_arg_partial_bytes (CUMULATIVE_ARGS *cum, { int bytes_left, size; - if (*cum >= 4) + if (*cum >= 7) return 0; if (moxie_pass_by_reference (cum, mode, type, named)) @@ -448,7 +448,7 @@ moxie_arg_partial_bytes (CUMULATIVE_ARGS *cum, else size = GET_MODE_SIZE (mode); - bytes_left = 8 - ((*cum - 2) * 4); + bytes_left = (4 * 5) - ((*cum - 2) * 4); if (size > bytes_left) return bytes_left; diff --git a/gcc/config/moxie/moxie.h b/gcc/config/moxie/moxie.h index bf3d7e3eb6b..f50a6b2a27e 100644 --- a/gcc/config/moxie/moxie.h +++ b/gcc/config/moxie/moxie.h @@ -144,7 +144,7 @@ enum reg_class #define REG_CLASS_CONTENTS \ { { 0x00000000 }, /* Empty */ \ - { 0x0003FFFF }, /* $fp, $sp, $r0 to $r5, ?fp */ \ + { 0x0003FFFF }, /* $fp, $sp, $r0 to $r13, ?fp */ \ { 0x00040000 }, /* $pc */ \ { 0x00080000 }, /* ?cc */ \ { 0x000FFFFF } /* All registers */ \ @@ -166,7 +166,7 @@ enum reg_class 1, 1, 1, 1 } #define CALL_USED_REGISTERS { 1, 1, 1, 1, \ - 0, 0, 0, 0, \ + 1, 1, 1, 1, \ 0, 0, 0, 0, \ 0, 0, 1, 1, \ 1, 1, 1, 1 } @@ -263,7 +263,7 @@ enum reg_class : (unsigned) int_size_in_bytes (TYPE)) #define FUNCTION_ARG_ADVANCE(CUM,MODE,TYPE,NAMED) \ - (CUM = (CUM < MOXIE_R2 ? \ + (CUM = (CUM < MOXIE_R5 ? \ CUM + ((3 + MOXIE_FUNCTION_ARG_SIZE(MODE,TYPE))/4) : CUM )) /* How Scalar Function Values Are Returned */ @@ -299,7 +299,7 @@ enum reg_class /* Define this if it is the responsibility of the caller to allocate the area reserved for arguments passed in registers. */ -#define REG_PARM_STACK_SPACE(FNDECL) (2 * UNITS_PER_WORD) +#define REG_PARM_STACK_SPACE(FNDECL) (5 * UNITS_PER_WORD) /* Offset from the argument pointer register to the first argument's address. On some machines it may depend on the data type of the @@ -425,7 +425,7 @@ do \ /* The register number of the stack pointer register, which must also be a fixed register according to `FIXED_REGISTERS'. */ -#define STACK_POINTER_REGNUM 1 +#define STACK_POINTER_REGNUM MOXIE_SP /* The register number of the frame pointer register, which is used to access automatic variables in the stack frame. */ @@ -448,17 +448,9 @@ do \ #define HARD_FRAME_POINTER_REGNUM MOXIE_FP -#if 0 -#define ELIMINABLE_REGS \ -{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ - { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \ - { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ - { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }} -#else #define ELIMINABLE_REGS \ {{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }} -#endif /* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the initial difference between the specified pair of @@ -471,7 +463,7 @@ do \ /* A C expression that is nonzero if REGNO is the number of a hard register in which function arguments are sometimes passed. */ -#define FUNCTION_ARG_REGNO_P(r) (r == MOXIE_R0 || r == MOXIE_R1) +#define FUNCTION_ARG_REGNO_P(r) (r >= MOXIE_R0 && r <= MOXIE_R4) /* A C expression that is nonzero if REGNO is the number of a hard register in which the values of called function may come back. */ diff --git a/gcc/config/moxie/uclinux.h b/gcc/config/moxie/uclinux.h new file mode 100644 index 00000000000..0e5ee3d6b6b --- /dev/null +++ b/gcc/config/moxie/uclinux.h @@ -0,0 +1,39 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC \ + "%{!shared: crt1%O%s} crti%O%s crtbegin%O%s" + +#undef LINK_SPEC +#define LINK_SPEC "-elf2flt" + +#define TARGET_OS_CPP_BUILTINS() LINUX_TARGET_OS_CPP_BUILTINS() + +/* Like the definition in gcc.c, but for purposes of uClinux, every link is + static. */ +#define MFWRAP_SPEC " %{fmudflap|fmudflapth: \ + --wrap=malloc --wrap=free --wrap=calloc --wrap=realloc\ + --wrap=mmap --wrap=munmap --wrap=alloca\ + %{fmudflapth: --wrap=pthread_create\ +}} %{fmudflap|fmudflapth: --wrap=main}" diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 8e8db865e2b..e60ddde0535 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -159,6 +159,9 @@ static enum reg_class pa_secondary_reload (bool, rtx, enum reg_class, enum machine_mode, secondary_reload_info *); static void pa_extra_live_on_entry (bitmap); +static enum machine_mode pa_promote_function_mode (const_tree, + enum machine_mode, int *, + const_tree, int); /* The following extra sections are only used for SOM. */ static GTY(()) section *som_readonly_data_section; @@ -285,8 +288,8 @@ static size_t n_deferred_plabels = 0; #define TARGET_INIT_LIBFUNCS pa_hpux_init_libfuncs #endif -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE pa_promote_function_mode #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true @@ -9187,11 +9190,25 @@ insn_refs_are_delayed (rtx insn) && get_attr_type (insn) == TYPE_MILLI)); } +/* Promote the return value, but not the arguments. */ + +static enum machine_mode +pa_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, + enum machine_mode mode, + int *punsignedp ATTRIBUTE_UNUSED, + const_tree fntype ATTRIBUTE_UNUSED, + int for_return) +{ + if (!for_return) + return mode; + return promote_mode (type, mode, punsignedp); +} + /* On the HP-PA the value is found in register(s) 28(-29), unless the mode is SF or DF. Then the value is returned in fr4 (32). - This must perform the same promotions as PROMOTE_MODE, else - TARGET_PROMOTE_FUNCTION_RETURN will not work correctly. + This must perform the same promotions as PROMOTE_MODE, else promoting + return values in TARGET_PROMOTE_FUNCTION_MODE will not work correctly. Small structures must be returned in a PARALLEL on PA64 in order to match the HP Compiler ABI. */ diff --git a/gcc/config/picochip/picochip.c b/gcc/config/picochip/picochip.c index 358ef71e36b..ecec1f7121e 100644 --- a/gcc/config/picochip/picochip.c +++ b/gcc/config/picochip/picochip.c @@ -254,10 +254,8 @@ static char picochip_get_vliw_alu_id (void); #undef TARGET_ARG_PARTIAL_BYTES #define TARGET_ARG_PARTIAL_BYTES picochip_arg_partial_bytes -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true @@ -4144,7 +4142,7 @@ warn_of_byte_access (void) } rtx -picochip_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED, +picochip_function_value (const_tree valtype, const_tree func, bool outgoing ATTRIBUTE_UNUSED) { enum machine_mode mode = TYPE_MODE (valtype); @@ -4152,7 +4150,7 @@ picochip_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED, /* Since we define PROMOTE_FUNCTION_RETURN, we must promote the mode just as PROMOTE_MODE does. */ - mode = promote_mode (valtype, mode, &unsignedp, 1); + mode = promote_function_mode (valtype, mode, &unsignedp, func, 1); return gen_rtx_REG (mode, 0); diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h index 7b397997dd3..bc4f30f7cb2 100644 --- a/gcc/config/rs6000/altivec.h +++ b/gcc/config/rs6000/altivec.h @@ -306,6 +306,17 @@ #define vec_splats __builtin_vec_splats #define vec_promote __builtin_vec_promote +#ifdef __VSX__ +/* VSX additions */ +#define vec_div __builtin_vec_div +#define vec_mul __builtin_vec_mul +#define vec_msub __builtin_vec_msub +#define vec_nmadd __builtin_vec_nmadd +#define vec_nearbyint __builtin_vec_nearbyint +#define vec_rint __builtin_vec_rint +#define vec_sqrt __builtin_vec_sqrt +#endif + /* Predicates. For C++, we use templates in order to allow non-parenthesized arguments. For C, instead, we use macros since non-parenthesized arguments were @@ -356,14 +367,14 @@ __altivec_scalar_pred(vec_any_out, __builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, a1, a2)) __altivec_unary_pred(vec_all_nan, - __builtin_altivec_vcmpeqfp_p (__CR6_EQ, a1, a1)) + __builtin_altivec_vcmpeq_p (__CR6_EQ, a1, a1)) __altivec_unary_pred(vec_any_nan, - __builtin_altivec_vcmpeqfp_p (__CR6_LT_REV, a1, a1)) + __builtin_altivec_vcmpeq_p (__CR6_LT_REV, a1, a1)) __altivec_unary_pred(vec_all_numeric, - __builtin_altivec_vcmpeqfp_p (__CR6_LT, a1, a1)) + __builtin_altivec_vcmpeq_p (__CR6_LT, a1, a1)) __altivec_unary_pred(vec_any_numeric, - __builtin_altivec_vcmpeqfp_p (__CR6_EQ_REV, a1, a1)) + __builtin_altivec_vcmpeq_p (__CR6_EQ_REV, a1, a1)) __altivec_scalar_pred(vec_all_eq, __builtin_vec_vcmpeq_p (__CR6_LT, a1, a2)) @@ -384,13 +395,13 @@ __altivec_scalar_pred(vec_any_lt, __builtin_vec_vcmpgt_p (__CR6_EQ_REV, a2, a1)) __altivec_scalar_pred(vec_all_ngt, - __builtin_altivec_vcmpgtfp_p (__CR6_EQ, a1, a2)) + __builtin_altivec_vcmpgt_p (__CR6_EQ, a1, a2)) __altivec_scalar_pred(vec_all_nlt, - __builtin_altivec_vcmpgtfp_p (__CR6_EQ, a2, a1)) + __builtin_altivec_vcmpgt_p (__CR6_EQ, a2, a1)) __altivec_scalar_pred(vec_any_ngt, - __builtin_altivec_vcmpgtfp_p (__CR6_LT_REV, a1, a2)) + __builtin_altivec_vcmpgt_p (__CR6_LT_REV, a1, a2)) __altivec_scalar_pred(vec_any_nlt, - __builtin_altivec_vcmpgtfp_p (__CR6_LT_REV, a2, a1)) + __builtin_altivec_vcmpgt_p (__CR6_LT_REV, a2, a1)) /* __builtin_vec_vcmpge_p is vcmpgefp for floating-point vector types, while for integer types it is converted to __builtin_vec_vcmpgt_p, @@ -405,13 +416,13 @@ __altivec_scalar_pred(vec_any_ge, __builtin_vec_vcmpge_p (__CR6_EQ_REV, a1, a2)) __altivec_scalar_pred(vec_all_nge, - __builtin_altivec_vcmpgefp_p (__CR6_EQ, a1, a2)) + __builtin_altivec_vcmpge_p (__CR6_EQ, a1, a2)) __altivec_scalar_pred(vec_all_nle, - __builtin_altivec_vcmpgefp_p (__CR6_EQ, a2, a1)) + __builtin_altivec_vcmpge_p (__CR6_EQ, a2, a1)) __altivec_scalar_pred(vec_any_nge, - __builtin_altivec_vcmpgefp_p (__CR6_LT_REV, a1, a2)) + __builtin_altivec_vcmpge_p (__CR6_LT_REV, a1, a2)) __altivec_scalar_pred(vec_any_nle, - __builtin_altivec_vcmpgefp_p (__CR6_LT_REV, a2, a1)) + __builtin_altivec_vcmpge_p (__CR6_LT_REV, a2, a1)) #undef __altivec_scalar_pred #undef __altivec_unary_pred @@ -423,11 +434,11 @@ __altivec_scalar_pred(vec_any_nle, #define vec_all_in(a1, a2) __builtin_altivec_vcmpbfp_p (__CR6_EQ, (a1), (a2)) #define vec_any_out(a1, a2) __builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, (a1), (a2)) -#define vec_all_nan(a1) __builtin_altivec_vcmpeqfp_p (__CR6_EQ, (a1), (a1)) -#define vec_any_nan(a1) __builtin_altivec_vcmpeqfp_p (__CR6_LT_REV, (a1), (a1)) +#define vec_all_nan(a1) __builtin_vec_vcmpeq_p (__CR6_EQ, (a1), (a1)) +#define vec_any_nan(a1) __builtin_vec_vcmpeq_p (__CR6_LT_REV, (a1), (a1)) -#define vec_all_numeric(a1) __builtin_altivec_vcmpeqfp_p (__CR6_LT, (a1), (a1)) -#define vec_any_numeric(a1) __builtin_altivec_vcmpeqfp_p (__CR6_EQ_REV, (a1), (a1)) +#define vec_all_numeric(a1) __builtin_vec_vcmpeq_p (__CR6_LT, (a1), (a1)) +#define vec_any_numeric(a1) __builtin_vec_vcmpeq_p (__CR6_EQ_REV, (a1), (a1)) #define vec_all_eq(a1, a2) __builtin_vec_vcmpeq_p (__CR6_LT, (a1), (a2)) #define vec_all_ne(a1, a2) __builtin_vec_vcmpeq_p (__CR6_EQ, (a1), (a2)) @@ -439,10 +450,10 @@ __altivec_scalar_pred(vec_any_nle, #define vec_any_gt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ_REV, (a1), (a2)) #define vec_any_lt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ_REV, (a2), (a1)) -#define vec_all_ngt(a1, a2) __builtin_altivec_vcmpgtfp_p (__CR6_EQ, (a1), (a2)) -#define vec_all_nlt(a1, a2) __builtin_altivec_vcmpgtfp_p (__CR6_EQ, (a2), (a1)) -#define vec_any_ngt(a1, a2) __builtin_altivec_vcmpgtfp_p (__CR6_LT_REV, (a1), (a2)) -#define vec_any_nlt(a1, a2) __builtin_altivec_vcmpgtfp_p (__CR6_LT_REV, (a2), (a1)) +#define vec_all_ngt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ, (a1), (a2)) +#define vec_all_nlt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ, (a2), (a1)) +#define vec_any_ngt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT_REV, (a1), (a2)) +#define vec_any_nlt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT_REV, (a2), (a1)) /* __builtin_vec_vcmpge_p is vcmpgefp for floating-point vector types, while for integer types it is converted to __builtin_vec_vcmpgt_p, @@ -452,10 +463,10 @@ __altivec_scalar_pred(vec_any_nle, #define vec_any_le(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ_REV, (a2), (a1)) #define vec_any_ge(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ_REV, (a1), (a2)) -#define vec_all_nge(a1, a2) __builtin_altivec_vcmpgefp_p (__CR6_EQ, (a1), (a2)) -#define vec_all_nle(a1, a2) __builtin_altivec_vcmpgefp_p (__CR6_EQ, (a2), (a1)) -#define vec_any_nge(a1, a2) __builtin_altivec_vcmpgefp_p (__CR6_LT_REV, (a1), (a2)) -#define vec_any_nle(a1, a2) __builtin_altivec_vcmpgefp_p (__CR6_LT_REV, (a2), (a1)) +#define vec_all_nge(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ, (a1), (a2)) +#define vec_all_nle(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ, (a2), (a1)) +#define vec_any_nge(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT_REV, (a1), (a2)) +#define vec_any_nle(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT_REV, (a2), (a1)) #endif /* These do not accept vectors, so they do not have a __builtin_vec_* diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 58af47c15ce..53b1054d200 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -20,8 +20,8 @@ ;; <http://www.gnu.org/licenses/>. (define_constants - [(UNSPEC_VCMPBFP 50) ;; 51-62 deleted + [(UNSPEC_VCMPBFP 64) (UNSPEC_VMSUMU 65) (UNSPEC_VMSUMM 66) (UNSPEC_VMSUMSHM 68) @@ -66,9 +66,9 @@ (UNSPEC_VSUMSWS 135) (UNSPEC_VPERM 144) (UNSPEC_VPERM_UNS 145) - (UNSPEC_VRFIP 148) + ;; 148 deleted (UNSPEC_VRFIN 149) - (UNSPEC_VRFIM 150) + ;; 150 deleted (UNSPEC_VCFUX 151) (UNSPEC_VCFSX 152) (UNSPEC_VCTUXS 153) @@ -220,6 +220,35 @@ } [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")]) +;; Load up a vector with the most significant bit set by loading up -1 and +;; doing a shift left +(define_split + [(set (match_operand:VM 0 "altivec_register_operand" "") + (match_operand:VM 1 "easy_vector_constant_msb" ""))] + "VECTOR_UNIT_ALTIVEC_P (<MODE>mode) && reload_completed" + [(const_int 0)] +{ + rtx dest = operands[0]; + enum machine_mode mode = GET_MODE (operands[0]); + rtvec v; + int i, num_elements; + + if (mode == V4SFmode) + { + mode = V4SImode; + dest = gen_lowpart (V4SImode, dest); + } + + num_elements = GET_MODE_NUNITS (mode); + v = rtvec_alloc (num_elements); + for (i = 0; i < num_elements; i++) + RTVEC_ELT (v, i) = constm1_rtx; + + emit_insn (gen_vec_initv4si (dest, gen_rtx_PARALLEL (mode, v))); + emit_insn (gen_rtx_SET (VOIDmode, dest, gen_rtx_ASHIFT (mode, dest, dest))); + DONE; +}) + (define_split [(set (match_operand:VM 0 "altivec_register_operand" "") (match_operand:VM 1 "easy_vector_constant_add_self" ""))] @@ -1310,7 +1339,7 @@ "vspltis<VI_char> %0,%1" [(set_attr "type" "vecperm")]) -(define_insn "*altivec_ftruncv4sf2" +(define_insn "*altivec_vrfiz" [(set (match_operand:V4SF 0 "register_operand" "=v") (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))] "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" @@ -1337,10 +1366,10 @@ "vperm %0,%1,%2,%3" [(set_attr "type" "vecperm")]) -(define_insn "altivec_vrfip" +(define_insn "altivec_vrfip" ; ceil [(set (match_operand:V4SF 0 "register_operand" "=v") (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] - UNSPEC_VRFIP))] + UNSPEC_FRIP))] "TARGET_ALTIVEC" "vrfip %0,%1" [(set_attr "type" "vecfloat")]) @@ -1353,10 +1382,10 @@ "vrfin %0,%1" [(set_attr "type" "vecfloat")]) -(define_insn "altivec_vrfim" +(define_insn "*altivec_vrfim" ; floor [(set (match_operand:V4SF 0 "register_operand" "=v") (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] - UNSPEC_VRFIM))] + UNSPEC_FRIM))] "TARGET_ALTIVEC" "vrfim %0,%1" [(set_attr "type" "vecfloat")]) @@ -1431,6 +1460,28 @@ "vrefp %0,%1" [(set_attr "type" "vecfloat")]) +(define_expand "altivec_copysign_v4sf3" + [(use (match_operand:V4SF 0 "register_operand" "")) + (use (match_operand:V4SF 1 "register_operand" "")) + (use (match_operand:V4SF 2 "register_operand" ""))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + " +{ + rtx mask = gen_reg_rtx (V4SImode); + rtvec v = rtvec_alloc (4); + unsigned HOST_WIDE_INT mask_val = ((unsigned HOST_WIDE_INT)1) << 31; + + RTVEC_ELT (v, 0) = GEN_INT (mask_val); + RTVEC_ELT (v, 1) = GEN_INT (mask_val); + RTVEC_ELT (v, 2) = GEN_INT (mask_val); + RTVEC_ELT (v, 3) = GEN_INT (mask_val); + + emit_insn (gen_vec_initv4si (mask, gen_rtx_PARALLEL (V4SImode, v))); + emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2], + gen_lowpart (V4SFmode, mask))); + DONE; +}") + (define_insn "altivec_vsldoi_<mode>" [(set (match_operand:VM 0 "register_operand" "=v") (unspec:VM [(match_operand:VM 1 "register_operand" "v") diff --git a/gcc/config/rs6000/power7.md b/gcc/config/rs6000/power7.md new file mode 100644 index 00000000000..3b6a95e284e --- /dev/null +++ b/gcc/config/rs6000/power7.md @@ -0,0 +1,318 @@ +;; Scheduling description for IBM POWER7 processor. +;; Copyright (C) 2009 Free Software Foundation, Inc. +;; +;; Contributed by Pat Haugen (pthaugen@us.ibm.com). + +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; 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/>. + +(define_automaton "power7iu,power7lsu,power7vsu,power7misc") + +(define_cpu_unit "iu1_power7,iu2_power7" "power7iu") +(define_cpu_unit "lsu1_power7,lsu2_power7" "power7lsu") +(define_cpu_unit "vsu1_power7,vsu2_power7" "power7vsu") +(define_cpu_unit "bpu_power7,cru_power7" "power7misc") +(define_cpu_unit "du1_power7,du2_power7,du3_power7,du4_power7,du5_power7" + "power7misc") + + +(define_reservation "DU_power7" + "du1_power7|du2_power7|du3_power7|du4_power7") + +(define_reservation "DU2F_power7" + "du1_power7+du2_power7") + +(define_reservation "DU4_power7" + "du1_power7+du2_power7+du3_power7+du4_power7") + +(define_reservation "FXU_power7" + "iu1_power7|iu2_power7") + +(define_reservation "VSU_power7" + "vsu1_power7|vsu2_power7") + +(define_reservation "LSU_power7" + "lsu1_power7|lsu2_power7") + + +; Dispatch slots are allocated in order conforming to program order. +(absence_set "du1_power7" "du2_power7,du3_power7,du4_power7,du5_power7") +(absence_set "du2_power7" "du3_power7,du4_power7,du5_power7") +(absence_set "du3_power7" "du4_power7,du5_power7") +(absence_set "du4_power7" "du5_power7") + + +; LS Unit +(define_insn_reservation "power7-load" 2 + (and (eq_attr "type" "load") + (eq_attr "cpu" "power7")) + "DU_power7,LSU_power7") + +(define_insn_reservation "power7-load-ext" 3 + (and (eq_attr "type" "load_ext") + (eq_attr "cpu" "power7")) + "DU2F_power7,LSU_power7,FXU_power7") + +(define_insn_reservation "power7-load-update" 2 + (and (eq_attr "type" "load_u") + (eq_attr "cpu" "power7")) + "DU2F_power7,LSU_power7+FXU_power7") + +(define_insn_reservation "power7-load-update-indexed" 3 + (and (eq_attr "type" "load_ux") + (eq_attr "cpu" "power7")) + "DU4_power7,FXU_power7,LSU_power7+FXU_power7") + +(define_insn_reservation "power7-load-ext-update" 4 + (and (eq_attr "type" "load_ext_u") + (eq_attr "cpu" "power7")) + "DU2F_power7,LSU_power7+FXU_power7,FXU_power7") + +(define_insn_reservation "power7-load-ext-update-indexed" 4 + (and (eq_attr "type" "load_ext_ux") + (eq_attr "cpu" "power7")) + "DU4_power7,FXU_power7,LSU_power7+FXU_power7,FXU_power7") + +(define_insn_reservation "power7-fpload" 3 + (and (eq_attr "type" "fpload") + (eq_attr "cpu" "power7")) + "DU_power7,LSU_power7") + +(define_insn_reservation "power7-fpload-update" 3 + (and (eq_attr "type" "fpload_u,fpload_ux") + (eq_attr "cpu" "power7")) + "DU2F_power7,LSU_power7+FXU_power7") + +(define_insn_reservation "power7-store" 6 ; store-forwarding latency + (and (eq_attr "type" "store") + (eq_attr "cpu" "power7")) + "DU_power7,LSU_power7+FXU_power7") + +(define_insn_reservation "power7-store-update" 6 + (and (eq_attr "type" "store_u") + (eq_attr "cpu" "power7")) + "DU2F_power7,LSU_power7+FXU_power7,FXU_power7") + +(define_insn_reservation "power7-store-update-indexed" 6 + (and (eq_attr "type" "store_ux") + (eq_attr "cpu" "power7")) + "DU4_power7,LSU_power7+FXU_power7,FXU_power7") + +(define_insn_reservation "power7-fpstore" 6 + (and (eq_attr "type" "fpstore") + (eq_attr "cpu" "power7")) + "DU_power7,LSU_power7+VSU_power7") + +(define_insn_reservation "power7-fpstore-update" 6 + (and (eq_attr "type" "fpstore_u,fpstore_ux") + (eq_attr "cpu" "power7")) + "DU_power7,LSU_power7+VSU_power7+FXU_power7") + +(define_insn_reservation "power7-larx" 3 + (and (eq_attr "type" "load_l") + (eq_attr "cpu" "power7")) + "DU4_power7,LSU_power7") + +(define_insn_reservation "power7-stcx" 10 + (and (eq_attr "type" "store_c") + (eq_attr "cpu" "power7")) + "DU4_power7,LSU_power7") + +(define_insn_reservation "power7-vecload" 3 + (and (eq_attr "type" "vecload") + (eq_attr "cpu" "power7")) + "DU_power7,LSU_power7") + +(define_insn_reservation "power7-vecstore" 6 + (and (eq_attr "type" "vecstore") + (eq_attr "cpu" "power7")) + "DU_power7,LSU_power7+VSU_power7") + +(define_insn_reservation "power7-sync" 11 + (and (eq_attr "type" "sync") + (eq_attr "cpu" "power7")) + "DU4_power7,LSU_power7") + + +; FX Unit +(define_insn_reservation "power7-integer" 1 + (and (eq_attr "type" "integer,insert_word,insert_dword,shift,trap,\ + var_shift_rotate,exts") + (eq_attr "cpu" "power7")) + "DU_power7,FXU_power7") + +(define_insn_reservation "power7-cntlz" 2 + (and (eq_attr "type" "cntlz") + (eq_attr "cpu" "power7")) + "DU_power7,FXU_power7") + +(define_insn_reservation "power7-two" 2 + (and (eq_attr "type" "two") + (eq_attr "cpu" "power7")) + "DU_power7+DU_power7,FXU_power7,FXU_power7") + +(define_insn_reservation "power7-three" 3 + (and (eq_attr "type" "three") + (eq_attr "cpu" "power7")) + "DU_power7+DU_power7+DU_power7,FXU_power7,FXU_power7,FXU_power7") + +(define_insn_reservation "power7-cmp" 1 + (and (eq_attr "type" "cmp,fast_compare") + (eq_attr "cpu" "power7")) + "DU_power7,FXU_power7") + +(define_insn_reservation "power7-compare" 2 + (and (eq_attr "type" "compare,delayed_compare,var_delayed_compare") + (eq_attr "cpu" "power7")) + "DU2F_power7,FXU_power7,FXU_power7") + +(define_bypass 3 "power7-cmp,power7-compare" "power7-crlogical,power7-delayedcr") + +(define_insn_reservation "power7-mul" 4 + (and (eq_attr "type" "imul,imul2,imul3,lmul") + (eq_attr "cpu" "power7")) + "DU_power7,FXU_power7") + +(define_insn_reservation "power7-mul-compare" 5 + (and (eq_attr "type" "imul_compare,lmul_compare") + (eq_attr "cpu" "power7")) + "DU2F_power7,FXU_power7,nothing*3,FXU_power7") + +(define_insn_reservation "power7-idiv" 36 + (and (eq_attr "type" "idiv") + (eq_attr "cpu" "power7")) + "DU2F_power7,iu1_power7*36|iu2_power7*36") + +(define_insn_reservation "power7-ldiv" 68 + (and (eq_attr "type" "ldiv") + (eq_attr "cpu" "power7")) + "DU2F_power7,iu1_power7*68|iu2_power7*68") + +(define_insn_reservation "power7-isync" 1 ; + (and (eq_attr "type" "isync") + (eq_attr "cpu" "power7")) + "DU4_power7,FXU_power7") + + +; CR Unit +(define_insn_reservation "power7-mtjmpr" 4 + (and (eq_attr "type" "mtjmpr") + (eq_attr "cpu" "power7")) + "du1_power7,FXU_power7") + +(define_insn_reservation "power7-mfjmpr" 5 + (and (eq_attr "type" "mfjmpr") + (eq_attr "cpu" "power7")) + "du1_power7,cru_power7+FXU_power7") + +(define_insn_reservation "power7-crlogical" 3 + (and (eq_attr "type" "cr_logical") + (eq_attr "cpu" "power7")) + "du1_power7,cru_power7") + +(define_insn_reservation "power7-delayedcr" 3 + (and (eq_attr "type" "delayed_cr") + (eq_attr "cpu" "power7")) + "du1_power7,cru_power7") + +(define_insn_reservation "power7-mfcr" 6 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "power7")) + "du1_power7,cru_power7") + +(define_insn_reservation "power7-mfcrf" 3 + (and (eq_attr "type" "mfcrf") + (eq_attr "cpu" "power7")) + "du1_power7,cru_power7") + +(define_insn_reservation "power7-mtcr" 3 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "power7")) + "DU4_power7,cru_power7+FXU_power7") + + +; BR Unit +; Branches take dispatch Slot 4. The presence_sets prevent other insn from +; grabbing previous dispatch slots once this is assigned. +(define_insn_reservation "power7-branch" 3 + (and (eq_attr "type" "jmpreg,branch") + (eq_attr "cpu" "power7")) + "(du5_power7\ + |du4_power7+du5_power7\ + |du3_power7+du4_power7+du5_power7\ + |du2_power7+du3_power7+du4_power7+du5_power7\ + |du1_power7+du2_power7+du3_power7+du4_power7+du5_power7),bpu_power7") + + +; VS Unit (includes FP/VSX/VMX/DFP) +(define_insn_reservation "power7-fp" 6 + (and (eq_attr "type" "fp,dmul") + (eq_attr "cpu" "power7")) + "DU_power7,VSU_power7") + +(define_bypass 8 "power7-fp" "power7-branch") + +(define_insn_reservation "power7-fpcompare" 4 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "power7")) + "DU_power7,VSU_power7") + +(define_insn_reservation "power7-sdiv" 26 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "power7")) + "DU_power7,VSU_power7") + +(define_insn_reservation "power7-ddiv" 32 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "power7")) + "DU_power7,VSU_power7") + +(define_insn_reservation "power7-sqrt" 31 + (and (eq_attr "type" "ssqrt") + (eq_attr "cpu" "power7")) + "DU_power7,VSU_power7") + +(define_insn_reservation "power7-dsqrt" 43 + (and (eq_attr "type" "dsqrt") + (eq_attr "cpu" "power7")) + "DU_power7,VSU_power7") + +(define_insn_reservation "power7-vecsimple" 2 + (and (eq_attr "type" "vecsimple") + (eq_attr "cpu" "power7")) + "du1_power7,VSU_power7") + +(define_insn_reservation "power7-veccmp" 7 + (and (eq_attr "type" "veccmp") + (eq_attr "cpu" "power7")) + "du1_power7,VSU_power7") + +(define_insn_reservation "power7-vecfloat" 7 + (and (eq_attr "type" "vecfloat") + (eq_attr "cpu" "power7")) + "du1_power7,VSU_power7") + +(define_bypass 6 "power7-vecfloat" "power7-vecfloat") + +(define_insn_reservation "power7-veccomplex" 7 + (and (eq_attr "type" "veccomplex") + (eq_attr "cpu" "power7")) + "du1_power7,VSU_power7") + +(define_insn_reservation "power7-vecperm" 3 + (and (eq_attr "type" "vecperm") + (eq_attr "cpu" "power7")) + "du2_power7,VSU_power7") diff --git a/gcc/config/rs6000/ppc-asm.h b/gcc/config/rs6000/ppc-asm.h index 147f1092753..c963eb98abb 100644 --- a/gcc/config/rs6000/ppc-asm.h +++ b/gcc/config/rs6000/ppc-asm.h @@ -87,7 +87,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define f16 16 #define f17 17 #define f18 18 -#define f19 19 +#define f19 19 #define f20 20 #define f21 21 #define f22 22 @@ -101,6 +101,143 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define f30 30 #define f31 31 +#ifdef __VSX__ +#define f32 32 +#define f33 33 +#define f34 34 +#define f35 35 +#define f36 36 +#define f37 37 +#define f38 38 +#define f39 39 +#define f40 40 +#define f41 41 +#define f42 42 +#define f43 43 +#define f44 44 +#define f45 45 +#define f46 46 +#define f47 47 +#define f48 48 +#define f49 49 +#define f50 30 +#define f51 51 +#define f52 52 +#define f53 53 +#define f54 54 +#define f55 55 +#define f56 56 +#define f57 57 +#define f58 58 +#define f59 59 +#define f60 60 +#define f61 61 +#define f62 62 +#define f63 63 +#endif + +#ifdef __ALTIVEC__ +#define v0 0 +#define v1 1 +#define v2 2 +#define v3 3 +#define v4 4 +#define v5 5 +#define v6 6 +#define v7 7 +#define v8 8 +#define v9 9 +#define v10 10 +#define v11 11 +#define v12 12 +#define v13 13 +#define v14 14 +#define v15 15 +#define v16 16 +#define v17 17 +#define v18 18 +#define v19 19 +#define v20 20 +#define v21 21 +#define v22 22 +#define v23 23 +#define v24 24 +#define v25 25 +#define v26 26 +#define v27 27 +#define v28 28 +#define v29 29 +#define v30 30 +#define v31 31 +#endif + +#ifdef __VSX__ +#define vs0 0 +#define vs1 1 +#define vs2 2 +#define vs3 3 +#define vs4 4 +#define vs5 5 +#define vs6 6 +#define vs7 7 +#define vs8 8 +#define vs9 9 +#define vs10 10 +#define vs11 11 +#define vs12 12 +#define vs13 13 +#define vs14 14 +#define vs15 15 +#define vs16 16 +#define vs17 17 +#define vs18 18 +#define vs19 19 +#define vs20 20 +#define vs21 21 +#define vs22 22 +#define vs23 23 +#define vs24 24 +#define vs25 25 +#define vs26 26 +#define vs27 27 +#define vs28 28 +#define vs29 29 +#define vs30 30 +#define vs31 31 +#define vs32 32 +#define vs33 33 +#define vs34 34 +#define vs35 35 +#define vs36 36 +#define vs37 37 +#define vs38 38 +#define vs39 39 +#define vs40 40 +#define vs41 41 +#define vs42 42 +#define vs43 43 +#define vs44 44 +#define vs45 45 +#define vs46 46 +#define vs47 47 +#define vs48 48 +#define vs49 49 +#define vs50 30 +#define vs51 51 +#define vs52 52 +#define vs53 53 +#define vs54 54 +#define vs55 55 +#define vs56 56 +#define vs57 57 +#define vs58 58 +#define vs59 59 +#define vs60 60 +#define vs61 61 +#define vs62 62 +#define vs63 63 +#endif + /* * Macros to glue together two tokens. */ diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 3e5c1a1a8df..cf25cb7bf0f 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -377,6 +377,16 @@ return EASY_VECTOR_15_ADD_SELF (val); }) +;; Same as easy_vector_constant but only for EASY_VECTOR_MSB. +(define_predicate "easy_vector_constant_msb" + (and (match_code "const_vector") + (and (match_test "TARGET_ALTIVEC") + (match_test "easy_altivec_constant (op, mode)"))) +{ + HOST_WIDE_INT val = const_vector_elt_as_int (op, GET_MODE_NUNITS (mode) - 1); + return EASY_VECTOR_MSB (val, GET_MODE_INNER (mode)); +}) + ;; Return 1 if operand is constant zero (scalars and vectors). (define_predicate "zero_constant" (and (match_code "const_int,const_double,const_vector") diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c index 3b3ba96b5cd..94354528ebf 100644 --- a/gcc/config/rs6000/rs6000-c.c +++ b/gcc/config/rs6000/rs6000-c.c @@ -214,7 +214,8 @@ rs6000_macro_to_expand (cpp_reader *pfile, const cpp_token *tok) if (rid_code == RID_UNSIGNED || rid_code == RID_LONG || rid_code == RID_SHORT || rid_code == RID_SIGNED || rid_code == RID_INT || rid_code == RID_CHAR - || rid_code == RID_FLOAT) + || rid_code == RID_FLOAT + || (rid_code == RID_DOUBLE && TARGET_VSX)) { expand_this = C_CPP_HASHNODE (__vector_keyword); /* If the next keyword is bool or pixel, it @@ -329,7 +330,42 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile) if (TARGET_NO_LWSYNC) builtin_define ("__NO_LWSYNC__"); if (TARGET_VSX) - builtin_define ("__VSX__"); + { + builtin_define ("__VSX__"); + + /* For the VSX builtin functions identical to Altivec functions, just map + the altivec builtin into the vsx version (the altivec functions + generate VSX code if -mvsx). */ + builtin_define ("__builtin_vsx_xxland=__builtin_vec_and"); + builtin_define ("__builtin_vsx_xxlandc=__builtin_vec_andc"); + builtin_define ("__builtin_vsx_xxlnor=__builtin_vec_nor"); + builtin_define ("__builtin_vsx_xxlor=__builtin_vec_or"); + builtin_define ("__builtin_vsx_xxlxor=__builtin_vec_xor"); + builtin_define ("__builtin_vsx_xxsel=__builtin_vec_sel"); + builtin_define ("__builtin_vsx_vperm=__builtin_vec_perm"); + + /* Also map the a and m versions of the multiply/add instructions to the + builtin for people blindly going off the instruction manual. */ + builtin_define ("__builtin_vsx_xvmaddadp=__builtin_vsx_xvmadddp"); + builtin_define ("__builtin_vsx_xvmaddmdp=__builtin_vsx_xvmadddp"); + builtin_define ("__builtin_vsx_xvmaddasp=__builtin_vsx_xvmaddsp"); + builtin_define ("__builtin_vsx_xvmaddmsp=__builtin_vsx_xvmaddsp"); + builtin_define ("__builtin_vsx_xvmsubadp=__builtin_vsx_xvmsubdp"); + builtin_define ("__builtin_vsx_xvmsubmdp=__builtin_vsx_xvmsubdp"); + builtin_define ("__builtin_vsx_xvmsubasp=__builtin_vsx_xvmsubsp"); + builtin_define ("__builtin_vsx_xvmsubmsp=__builtin_vsx_xvmsubsp"); + builtin_define ("__builtin_vsx_xvnmaddadp=__builtin_vsx_xvnmadddp"); + builtin_define ("__builtin_vsx_xvnmaddmdp=__builtin_vsx_xvnmadddp"); + builtin_define ("__builtin_vsx_xvnmaddasp=__builtin_vsx_xvnmaddsp"); + builtin_define ("__builtin_vsx_xvnmaddmsp=__builtin_vsx_xvnmaddsp"); + builtin_define ("__builtin_vsx_xvnmsubadp=__builtin_vsx_xvnmsubdp"); + builtin_define ("__builtin_vsx_xvnmsubmdp=__builtin_vsx_xvnmsubdp"); + builtin_define ("__builtin_vsx_xvnmsubasp=__builtin_vsx_xvnmsubsp"); + builtin_define ("__builtin_vsx_xvnmsubmsp=__builtin_vsx_xvnmsubsp"); + } + + /* Tell users they can use __builtin_bswap{16,64}. */ + builtin_define ("__HAVE_BSWAP__"); /* May be overridden by target configuration. */ RS6000_CPU_CPP_ENDIAN_BUILTINS(); @@ -393,7 +429,7 @@ struct altivec_builtin_types }; const struct altivec_builtin_types altivec_overloaded_builtins[] = { - /* Unary AltiVec builtins. */ + /* Unary AltiVec/VSX builtins. */ { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V8HI, @@ -402,6 +438,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_ABS, VSX_BUILTIN_XVABSDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, { ALTIVEC_BUILTIN_VEC_ABSS, ALTIVEC_BUILTIN_ABSS_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, { ALTIVEC_BUILTIN_VEC_ABSS, ALTIVEC_BUILTIN_ABSS_V8HI, @@ -410,8 +448,12 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, { ALTIVEC_BUILTIN_VEC_CEIL, ALTIVEC_BUILTIN_VRFIP, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_CEIL, VSX_BUILTIN_XVRDPIP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, { ALTIVEC_BUILTIN_VEC_EXPTE, ALTIVEC_BUILTIN_VEXPTEFP, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_FLOOR, VSX_BUILTIN_XVRDPIM, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, { ALTIVEC_BUILTIN_VEC_FLOOR, ALTIVEC_BUILTIN_VRFIM, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, { ALTIVEC_BUILTIN_VEC_LOGE, ALTIVEC_BUILTIN_VLOGEFP, @@ -444,6 +486,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, { ALTIVEC_BUILTIN_VEC_TRUNC, ALTIVEC_BUILTIN_VRFIZ, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_TRUNC, VSX_BUILTIN_XVRDPIZ, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, { ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHSB, RS6000_BTI_V8HI, RS6000_BTI_V16QI, 0, 0 }, { ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHSB, @@ -489,7 +533,7 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { { ALTIVEC_BUILTIN_VEC_VUPKLSB, ALTIVEC_BUILTIN_VUPKLSB, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 }, - /* Binary AltiVec builtins. */ + /* Binary AltiVec/VSX builtins. */ { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, @@ -528,6 +572,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDFP, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, VSX_BUILTIN_XVADDDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_VADDFP, ALTIVEC_BUILTIN_VADDFP, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, @@ -673,9 +719,9 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 }, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 }, { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 }, + RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, @@ -727,9 +773,9 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 }, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 }, { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 }, + RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, @@ -812,6 +858,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQFP, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPEQ, VSX_BUILTIN_XVCMPEQDP, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_VCMPEQFP, ALTIVEC_BUILTIN_VCMPEQFP, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, @@ -832,6 +880,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { { ALTIVEC_BUILTIN_VEC_CMPGE, ALTIVEC_BUILTIN_VCMPGEFP, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPGE, VSX_BUILTIN_XVCMPGEDP, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTUB, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTSB, @@ -846,6 +896,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTFP, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPGT, VSX_BUILTIN_XVCMPGTDP, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_VCMPGTFP, ALTIVEC_BUILTIN_VCMPGTFP, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, { ALTIVEC_BUILTIN_VEC_VCMPGTSW, ALTIVEC_BUILTIN_VCMPGTSW, @@ -874,6 +926,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, { ALTIVEC_BUILTIN_VEC_CMPLE, ALTIVEC_BUILTIN_VCMPGEFP, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPLE, VSX_BUILTIN_XVCMPGEDP, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTUB, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTSB, @@ -888,6 +942,12 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTFP, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPLT, VSX_BUILTIN_XVCMPGTDP, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_COPYSIGN, VSX_BUILTIN_CPSGNDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_COPYSIGN, ALTIVEC_BUILTIN_COPYSIGN_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, { ALTIVEC_BUILTIN_VEC_CTF, ALTIVEC_BUILTIN_VCFUX, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, 0 }, { ALTIVEC_BUILTIN_VEC_CTF, ALTIVEC_BUILTIN_VCFSX, @@ -900,6 +960,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_V4SI, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, { ALTIVEC_BUILTIN_VEC_CTU, ALTIVEC_BUILTIN_VCTUXS, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, + { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_XVDIVSP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_XVDIVDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, @@ -1234,6 +1298,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXFP, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, VSX_BUILTIN_XVMAXDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_VMAXFP, ALTIVEC_BUILTIN_VMAXFP, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, { ALTIVEC_BUILTIN_VEC_VMAXSW, ALTIVEC_BUILTIN_VMAXSW, @@ -1410,6 +1476,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINFP, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, VSX_BUILTIN_XVMINDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_VMINFP, ALTIVEC_BUILTIN_VMINFP, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, { ALTIVEC_BUILTIN_VEC_VMINSW, ALTIVEC_BUILTIN_VMINSW, @@ -1460,6 +1528,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, { ALTIVEC_BUILTIN_VEC_VMINUB, ALTIVEC_BUILTIN_VMINUB, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { VSX_BUILTIN_VEC_MUL, VSX_BUILTIN_XVMULSP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { VSX_BUILTIN_VEC_MUL, VSX_BUILTIN_XVMULDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULEUB, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULESB, @@ -1492,6 +1564,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_V8HI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, { ALTIVEC_BUILTIN_VEC_VMULOUB, ALTIVEC_BUILTIN_VMULOUB, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_NEARBYINT, VSX_BUILTIN_XVRDPI, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_NEARBYINT, VSX_BUILTIN_XVRSPI, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, @@ -1523,9 +1599,9 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 }, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 }, { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 }, + RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, @@ -1622,6 +1698,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_unsigned_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, { ALTIVEC_BUILTIN_VEC_VPKSHUS, ALTIVEC_BUILTIN_VPKSHUS, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_RINT, VSX_BUILTIN_XVRDPIC, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_RINT, VSX_BUILTIN_XVRSPIC, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLB, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLB, @@ -1658,6 +1738,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, { ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLW, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SQRT, VSX_BUILTIN_XVSQRTDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_SQRT, VSX_BUILTIN_XVSQRTSP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, { ALTIVEC_BUILTIN_VEC_VSLW, ALTIVEC_BUILTIN_VSLW, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, { ALTIVEC_BUILTIN_VEC_VSLW, ALTIVEC_BUILTIN_VSLW, @@ -1984,6 +2068,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBFP, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, VSX_BUILTIN_XVSUBDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_VSUBFP, ALTIVEC_BUILTIN_VSUBFP, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, @@ -2145,9 +2231,9 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 }, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 }, { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 }, + RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 }, { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, @@ -2191,7 +2277,7 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - /* Ternary AltiVec builtins. */ + /* Ternary AltiVec/VSX builtins. */ { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, RS6000_BTI_void, ~RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, @@ -2354,6 +2440,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_void, ~RS6000_BTI_float, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, { ALTIVEC_BUILTIN_VEC_MADD, ALTIVEC_BUILTIN_VMADDFP, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VEC_MADD, VSX_BUILTIN_XVMADDDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, { ALTIVEC_BUILTIN_VEC_MADDS, ALTIVEC_BUILTIN_VMHADDSHS, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, { ALTIVEC_BUILTIN_VEC_MLADD, ALTIVEC_BUILTIN_VMLADDUHM, @@ -2366,6 +2454,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, { ALTIVEC_BUILTIN_VEC_MRADDS, ALTIVEC_BUILTIN_VMHRADDSHS, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, + { VSX_BUILTIN_VEC_MSUB, VSX_BUILTIN_XVMSUBSP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, + { VSX_BUILTIN_VEC_MSUB, VSX_BUILTIN_XVMSUBDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, { ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMUBM, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI }, { ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMMBM, @@ -2390,8 +2482,14 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V4SI }, { ALTIVEC_BUILTIN_VEC_VMSUMUHS, ALTIVEC_BUILTIN_VMSUMUHS, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI }, + { VSX_BUILTIN_VEC_NMADD, VSX_BUILTIN_XVNMADDSP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, + { VSX_BUILTIN_VEC_NMADD, VSX_BUILTIN_XVNMADDDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, { ALTIVEC_BUILTIN_VEC_NMSUB, ALTIVEC_BUILTIN_VNMSUBFP, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VEC_NMSUB, VSX_BUILTIN_XVNMSUBDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_unsigned_V16QI }, { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DI, @@ -2812,6 +2910,54 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI }, { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_NOT_OPAQUE }, /* Predicates. */ { ALTIVEC_BUILTIN_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUB_P, @@ -2852,6 +2998,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI }, { ALTIVEC_BUILTIN_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTFP_P, RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VCMPGT_P, VSX_BUILTIN_XVCMPGTDP_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, { ALTIVEC_BUILTIN_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, @@ -2900,6 +3048,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI }, { ALTIVEC_BUILTIN_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQFP_P, RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VCMPEQ_P, VSX_BUILTIN_XVCMPEQDP_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, /* cmpge is the same as cmpgt for all cases except floating point. @@ -2943,6 +3093,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI }, { ALTIVEC_BUILTIN_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGEFP_P, RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VCMPGE_P, VSX_BUILTIN_XVCMPGEDP_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, { (enum rs6000_builtins) 0, (enum rs6000_builtins) 0, 0, 0, 0, 0 } }; @@ -3064,8 +3216,10 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, const struct altivec_builtin_types *desc; unsigned int n; - if (fcode < ALTIVEC_BUILTIN_OVERLOADED_FIRST - || fcode > ALTIVEC_BUILTIN_OVERLOADED_LAST) + if ((fcode < ALTIVEC_BUILTIN_OVERLOADED_FIRST + || fcode > ALTIVEC_BUILTIN_OVERLOADED_LAST) + && (fcode < VSX_BUILTIN_OVERLOADED_FIRST + || fcode > VSX_BUILTIN_OVERLOADED_LAST)) return NULL_TREE; /* For now treat vec_splats and vec_promote as the same. */ @@ -3105,11 +3259,12 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, && !INTEGRAL_TYPE_P (type)) goto bad; unsigned_p = TYPE_UNSIGNED (type); - if (type == long_long_unsigned_type_node - || type == long_long_integer_type_node) - goto bad; switch (TYPE_MODE (type)) { + case DImode: + type = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node); + size = 2; + break; case SImode: type = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node); size = 4; @@ -3123,6 +3278,7 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, size = 16; break; case SFmode: type = V4SF_type_node; size = 4; break; + case DFmode: type = V2DF_type_node; size = 2; break; default: goto bad; } @@ -3139,7 +3295,8 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, return build_constructor (type, vec); } - /* For now use pointer tricks to do the extaction. */ + /* For now use pointer tricks to do the extaction, unless we are on VSX + extracting a double from a constant offset. */ if (fcode == ALTIVEC_BUILTIN_VEC_EXTRACT) { tree arg1; @@ -3148,6 +3305,7 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, tree arg1_inner_type; tree decl, stmt; tree innerptrtype; + enum machine_mode mode; /* No second argument. */ if (nargs != 2) @@ -3164,6 +3322,25 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, goto bad; if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2))) goto bad; + + /* If we can use the VSX xxpermdi instruction, use that for extract. */ + mode = TYPE_MODE (arg1_type); + if ((mode == V2DFmode || mode == V2DImode) && VECTOR_MEM_VSX_P (mode) + && TREE_CODE (arg2) == INTEGER_CST + && TREE_INT_CST_HIGH (arg2) == 0 + && (TREE_INT_CST_LOW (arg2) == 0 || TREE_INT_CST_LOW (arg2) == 1)) + { + tree call = NULL_TREE; + + if (mode == V2DFmode) + call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DF]; + else if (mode == V2DImode) + call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DI]; + + if (call) + return build_call_expr (call, 2, arg1, arg2); + } + /* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2). */ arg1_inner_type = TREE_TYPE (arg1_type); arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2, @@ -3193,7 +3370,8 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, return stmt; } - /* For now use pointer tricks to do the insertation. */ + /* For now use pointer tricks to do the insertation, unless we are on VSX + inserting a double to a constant offset.. */ if (fcode == ALTIVEC_BUILTIN_VEC_INSERT) { tree arg0; @@ -3203,7 +3381,8 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, tree arg1_inner_type; tree decl, stmt; tree innerptrtype; - + enum machine_mode mode; + /* No second or third arguments. */ if (nargs != 3) { @@ -3220,6 +3399,27 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, goto bad; if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2))) goto bad; + + /* If we can use the VSX xxpermdi instruction, use that for insert. */ + mode = TYPE_MODE (arg1_type); + if ((mode == V2DFmode || mode == V2DImode) && VECTOR_UNIT_VSX_P (mode) + && TREE_CODE (arg2) == INTEGER_CST + && TREE_INT_CST_HIGH (arg2) == 0 + && (TREE_INT_CST_LOW (arg2) == 0 || TREE_INT_CST_LOW (arg2) == 1)) + { + tree call = NULL_TREE; + + if (mode == V2DFmode) + call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V2DF]; + else if (mode == V2DImode) + call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V2DI]; + + /* Note, __builtin_vec_insert_<xxx> has vector and scalar types + reversed. */ + if (call) + return build_call_expr (call, 3, arg1, arg0, arg2); + } + /* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2) = arg0. */ arg1_inner_type = TREE_TYPE (arg1_type); arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2, diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index b077c83c2db..8c0feb55057 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -837,6 +837,7 @@ static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool); static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int, enum machine_mode, bool, bool, bool); static bool rs6000_reg_live_or_pic_offset_p (int); +static tree rs6000_builtin_vectorized_function (unsigned int, tree, tree); static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int); static void rs6000_restore_saved_cr (rtx, int); static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT); @@ -1346,10 +1347,8 @@ static const struct attribute_spec rs6000_attribute_table[] = /* On rs6000, function arguments are promoted, as are function return values. */ -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote #undef TARGET_RETURN_IN_MEMORY #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory @@ -1395,6 +1394,10 @@ static const struct attribute_spec rs6000_attribute_table[] = #undef TARGET_HANDLE_OPTION #define TARGET_HANDLE_OPTION rs6000_handle_option +#undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION +#define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \ + rs6000_builtin_vectorized_function + #undef TARGET_DEFAULT_TARGET_FLAGS #define TARGET_DEFAULT_TARGET_FLAGS \ (TARGET_DEFAULT) @@ -1871,20 +1874,14 @@ rs6000_init_hard_regno_mode_ok (void) } } - /* V2DImode, prefer vsx over altivec, since the main use will be for - vectorized floating point conversions. */ + /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract. + Altivec doesn't have 64-bit support. */ if (TARGET_VSX) { rs6000_vector_mem[V2DImode] = VECTOR_VSX; rs6000_vector_unit[V2DImode] = VECTOR_NONE; rs6000_vector_align[V2DImode] = align64; } - else if (TARGET_ALTIVEC) - { - rs6000_vector_mem[V2DImode] = VECTOR_ALTIVEC; - rs6000_vector_unit[V2DImode] = VECTOR_NONE; - rs6000_vector_align[V2DImode] = align64; - } /* DFmode, see if we want to use the VSX unit. */ if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE) @@ -2169,7 +2166,7 @@ rs6000_override_options (const char *default_cpu) {"power7", PROCESSOR_POWER7, POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD - /* | MASK_VSX */}, /* Don't add MASK_ISEL by default */ + | MASK_VSX}, /* Don't add MASK_ISEL by default */ {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK}, {"powerpc64", PROCESSOR_POWERPC64, POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}, @@ -2765,6 +2762,14 @@ rs6000_builtin_conversion (unsigned int tcode, tree type) case FIX_TRUNC_EXPR: switch (TYPE_MODE (type)) { + case V2DImode: + if (!VECTOR_UNIT_VSX_P (V2DFmode)) + return NULL_TREE; + + return TYPE_UNSIGNED (type) + ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS] + : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS]; + case V4SImode: if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode)) return NULL_TREE; @@ -2780,6 +2785,14 @@ rs6000_builtin_conversion (unsigned int tcode, tree type) case FLOAT_EXPR: switch (TYPE_MODE (type)) { + case V2DImode: + if (!VECTOR_UNIT_VSX_P (V2DFmode)) + return NULL_TREE; + + return TYPE_UNSIGNED (type) + ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP] + : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP]; + case V4SImode: if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode)) return NULL_TREE; @@ -2908,6 +2921,22 @@ rs6000_builtin_vec_perm (tree type, tree *mask_element_type) d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF]; break; + case V2DFmode: + if (!TARGET_ALLOW_DF_PERMUTE) + return NULL_TREE; + + d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF]; + break; + + case V2DImode: + if (!TARGET_ALLOW_DF_PERMUTE) + return NULL_TREE; + + d = (uns_p + ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS] + : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]); + break; + default: return NULL_TREE; } @@ -2981,6 +3010,136 @@ rs6000_parse_fpu_option (const char *option) return FPU_NONE; } +/* Returns a function decl for a vectorized version of the builtin function + with builtin function code FN and the result vector type TYPE, or NULL_TREE + if it is not available. */ + +static tree +rs6000_builtin_vectorized_function (unsigned int fn, tree type_out, + tree type_in) +{ + enum machine_mode in_mode, out_mode; + int in_n, out_n; + + if (TREE_CODE (type_out) != VECTOR_TYPE + || TREE_CODE (type_in) != VECTOR_TYPE + || !TARGET_VECTORIZE_BUILTINS) + return NULL_TREE; + + out_mode = TYPE_MODE (TREE_TYPE (type_out)); + out_n = TYPE_VECTOR_SUBPARTS (type_out); + in_mode = TYPE_MODE (TREE_TYPE (type_in)); + in_n = TYPE_VECTOR_SUBPARTS (type_in); + + switch (fn) + { + case BUILT_IN_COPYSIGN: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP]; + break; + case BUILT_IN_COPYSIGNF: + if (out_mode != SFmode || out_n != 4 + || in_mode != SFmode || in_n != 4) + break; + if (VECTOR_UNIT_VSX_P (V4SFmode)) + return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP]; + if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) + return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF]; + break; + case BUILT_IN_SQRT: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP]; + break; + case BUILT_IN_SQRTF: + if (VECTOR_UNIT_VSX_P (V4SFmode) + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP]; + break; + case BUILT_IN_CEIL: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP]; + break; + case BUILT_IN_CEILF: + if (out_mode != SFmode || out_n != 4 + || in_mode != SFmode || in_n != 4) + break; + if (VECTOR_UNIT_VSX_P (V4SFmode)) + return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP]; + if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) + return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP]; + break; + case BUILT_IN_FLOOR: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM]; + break; + case BUILT_IN_FLOORF: + if (out_mode != SFmode || out_n != 4 + || in_mode != SFmode || in_n != 4) + break; + if (VECTOR_UNIT_VSX_P (V4SFmode)) + return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM]; + if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) + return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM]; + break; + case BUILT_IN_TRUNC: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ]; + break; + case BUILT_IN_TRUNCF: + if (out_mode != SFmode || out_n != 4 + || in_mode != SFmode || in_n != 4) + break; + if (VECTOR_UNIT_VSX_P (V4SFmode)) + return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ]; + if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) + return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ]; + break; + case BUILT_IN_NEARBYINT: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && flag_unsafe_math_optimizations + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI]; + break; + case BUILT_IN_NEARBYINTF: + if (VECTOR_UNIT_VSX_P (V4SFmode) + && flag_unsafe_math_optimizations + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI]; + break; + case BUILT_IN_RINT: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && !flag_trapping_math + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC]; + break; + case BUILT_IN_RINTF: + if (VECTOR_UNIT_VSX_P (V4SFmode) + && !flag_trapping_math + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC]; + break; + default: + break; + } + return NULL_TREE; +} + + /* Implement TARGET_HANDLE_OPTION. */ static bool @@ -3621,6 +3780,11 @@ vspltis_constant (rtx op, unsigned step, unsigned copies) && (splat_val >= 0 || (step == 1 && copies == 1))) ; + /* Also check if are loading up the most significant bit which can be done by + loading up -1 and shifting the value left by -1. */ + else if (EASY_VECTOR_MSB (splat_val, inner)) + ; + else return false; @@ -3971,8 +4135,6 @@ rs6000_expand_vector_init (rtx target, rtx vals) emit_insn (gen_rtx_SET (VOIDmode, target, const_vec)); return; } - else if (all_same && int_vector_p) - ; /* Splat vector element. */ else { /* Load from constant pool. */ @@ -3981,8 +4143,66 @@ rs6000_expand_vector_init (rtx target, rtx vals) } } - /* Store value to stack temp. Load vector element. Splat. */ - if (all_same) + /* Double word values on VSX can use xxpermdi or lxvdsx. */ + if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode)) + { + if (all_same) + { + rtx element = XVECEXP (vals, 0, 0); + if (mode == V2DFmode) + emit_insn (gen_vsx_splat_v2df (target, element)); + else + emit_insn (gen_vsx_splat_v2di (target, element)); + } + else + { + rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0)); + rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1)); + if (mode == V2DFmode) + emit_insn (gen_vsx_concat_v2df (target, op0, op1)); + else + emit_insn (gen_vsx_concat_v2di (target, op0, op1)); + } + return; + } + + /* With single precision floating point on VSX, know that internally single + precision is actually represented as a double, and either make 2 V2DF + vectors, and convert these vectors to single precision, or do one + conversion, and splat the result to the other elements. */ + if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode)) + { + if (all_same) + { + rtx freg = gen_reg_rtx (V4SFmode); + rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0)); + + emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg)); + emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx)); + } + else + { + rtx dbl_even = gen_reg_rtx (V2DFmode); + rtx dbl_odd = gen_reg_rtx (V2DFmode); + rtx flt_even = gen_reg_rtx (V4SFmode); + rtx flt_odd = gen_reg_rtx (V4SFmode); + + emit_insn (gen_vsx_concat_v2sf (dbl_even, + copy_to_reg (XVECEXP (vals, 0, 0)), + copy_to_reg (XVECEXP (vals, 0, 1)))); + emit_insn (gen_vsx_concat_v2sf (dbl_odd, + copy_to_reg (XVECEXP (vals, 0, 2)), + copy_to_reg (XVECEXP (vals, 0, 3)))); + emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even)); + emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd)); + emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd)); + } + return; + } + + /* Store value to stack temp. Load vector element. Splat. However, splat + of 64-bit items is not supported on Altivec. */ + if (all_same && GET_MODE_SIZE (mode) <= 4) { mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0); emit_move_insn (adjust_address_nv (mem, inner_mode, 0), @@ -4040,6 +4260,14 @@ rs6000_expand_vector_set (rtx target, rtx val, int elt) int width = GET_MODE_SIZE (inner_mode); int i; + if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode)) + { + rtx (*set_func) (rtx, rtx, rtx, rtx) + = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di); + emit_insn (set_func (target, target, val, GEN_INT (elt))); + return; + } + /* Load single variable value. */ mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0); emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val); @@ -4077,6 +4305,14 @@ rs6000_expand_vector_extract (rtx target, rtx vec, int elt) enum machine_mode inner_mode = GET_MODE_INNER (mode); rtx mem, x; + if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode)) + { + rtx (*extract_func) (rtx, rtx, rtx) + = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di); + emit_insn (extract_func (target, vec, GEN_INT (elt))); + return; + } + /* Allocate mode-sized buffer. */ mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0); @@ -5447,6 +5683,10 @@ rs6000_mode_dependent_address (rtx addr) case PRE_MODIFY: return TARGET_UPDATE; + /* AND is only allowed in Altivec loads. */ + case AND: + return true; + default: break; } @@ -6048,6 +6288,8 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) case V2SFmode: case V2SImode: case V1DImode: + case V2DFmode: + case V2DImode: if (CONSTANT_P (operands[1]) && !easy_vector_constant (operands[1], mode)) operands[1] = force_const_mem (mode, operands[1]); @@ -8192,6 +8434,59 @@ static const struct builtin_description bdesc_3arg[] = { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL }, + { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP }, + { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP }, + { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP }, + { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP }, + + { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP }, + { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP }, + { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP }, + { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP }, + + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD }, + + { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI }, + { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF }, + { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF }, + { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI }, + { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI }, + { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI }, + { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS }, + { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS }, + { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS }, + { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS }, + + { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI }, + { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF }, + { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF }, + { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI }, + { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI }, + { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI }, + { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS }, + { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS }, + { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS }, + { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS }, + + { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF }, + { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI }, + { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF }, + { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI }, + { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI }, + { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI }, + { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI }, + { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF }, + { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI }, + + { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI }, + { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF }, + { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF }, + { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI }, + { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI }, + { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI }, + { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI }, + { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB }, { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD }, { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 }, @@ -8337,9 +8632,50 @@ static struct builtin_description bdesc_2arg[] = { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS }, { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS }, { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR }, - - { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD }, - { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP }, + { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF }, + + { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP }, + { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP }, + { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP }, + { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP }, + { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP }, + { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP }, + { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE }, + { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG }, + { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP }, + { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP }, + { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP }, + + { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP }, + { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP }, + { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP }, + { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP }, + { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP }, + { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP }, + { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE }, + { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG }, + { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP }, + { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP }, + { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP }, + + { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP }, + { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP }, + { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE }, + { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG }, + { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP }, + { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP }, + + { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF }, + { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI }, + { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF }, + { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI }, + { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF }, + { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI }, + { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF }, + { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI }, + + { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD }, + { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM }, @@ -8377,6 +8713,7 @@ static struct builtin_description bdesc_2arg[] = { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN }, { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX }, { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW }, @@ -8466,6 +8803,9 @@ static struct builtin_description bdesc_2arg[] = { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS }, { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR }, + { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL }, + { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV }, + { 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 }, { 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 }, { 0, CODE_FOR_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 }, @@ -8661,6 +9001,19 @@ static const struct builtin_description_predicates bdesc_altivec_preds[] = { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P }, + { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p", + VSX_BUILTIN_XVCMPEQSP_P }, + { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p", + VSX_BUILTIN_XVCMPGESP_P }, + { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p", + VSX_BUILTIN_XVCMPGTSP_P }, + { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p", + VSX_BUILTIN_XVCMPEQDP_P }, + { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p", + VSX_BUILTIN_XVCMPGEDP_P }, + { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p", + VSX_BUILTIN_XVCMPGTDP_P }, + { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P }, { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p", @@ -8724,7 +9077,11 @@ static const struct builtin_description bdesc_abs[] = { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI }, { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI }, { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI }, - { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI } + { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }, + { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP }, + { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP }, + { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP }, + { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP }, }; /* Simple unary operations: VECb = foo (unsigned literal) or VECb = @@ -8735,10 +9092,10 @@ static struct builtin_description bdesc_1arg[] = { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP }, { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP }, { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP }, - { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM }, + { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM }, { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN }, - { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP }, - { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ }, + { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP }, + { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ }, { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP }, { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB }, { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH }, @@ -8750,6 +9107,65 @@ static struct builtin_description bdesc_1arg[] = { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX }, { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH }, + { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP }, + { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP }, + { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP }, + { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE }, + { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG }, + { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP }, + + { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP }, + { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP }, + { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP }, + { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE }, + { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG }, + { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP }, + + { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP }, + { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP }, + { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP }, + { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP }, + { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE }, + { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG }, + + { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS }, + { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS }, + { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS }, + { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP }, + { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP }, + { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS }, + + { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS }, + { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS }, + { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP }, + { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP }, + + { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS }, + { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS }, + { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP }, + { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP }, + { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI }, + { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC }, + { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM }, + { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP }, + { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ }, + + { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS }, + { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS }, + { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP }, + { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP }, + { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI }, + { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC }, + { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM }, + { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP }, + { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ }, + + { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI }, + { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC }, + { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM }, + { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP }, + { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL }, @@ -8770,6 +9186,10 @@ static struct builtin_description bdesc_1arg[] = { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB }, + { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT }, + { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT }, + { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT }, + { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF }, { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF }, { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI }, @@ -9293,6 +9713,36 @@ rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target) } break; + case CODE_FOR_vsx_xxpermdi_v2df: + case CODE_FOR_vsx_xxpermdi_v2di: + case CODE_FOR_vsx_xxsldwi_v16qi: + case CODE_FOR_vsx_xxsldwi_v8hi: + case CODE_FOR_vsx_xxsldwi_v4si: + case CODE_FOR_vsx_xxsldwi_v4sf: + case CODE_FOR_vsx_xxsldwi_v2di: + case CODE_FOR_vsx_xxsldwi_v2df: + /* Only allow 2-bit unsigned literals. */ + STRIP_NOPS (arg2); + if (TREE_CODE (arg2) != INTEGER_CST + || TREE_INT_CST_LOW (arg2) & ~0x3) + { + error ("argument 3 must be a 2-bit unsigned literal"); + return const0_rtx; + } + break; + + case CODE_FOR_vsx_set_v2df: + case CODE_FOR_vsx_set_v2di: + /* Only allow 1-bit unsigned literals. */ + STRIP_NOPS (arg2); + if (TREE_CODE (arg2) != INTEGER_CST + || TREE_INT_CST_LOW (arg2) & ~0x1) + { + error ("argument 3 must be a 1-bit unsigned literal"); + return const0_rtx; + } + break; + default: break; } @@ -9602,8 +10052,10 @@ altivec_expand_builtin (tree exp, rtx target, bool *expandedp) enum machine_mode tmode, mode0; unsigned int fcode = DECL_FUNCTION_CODE (fndecl); - if (fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST - && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST) + if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST + && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST) + || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST + && fcode <= VSX_BUILTIN_OVERLOADED_LAST)) { *expandedp = true; error ("unresolved overload for Altivec builtin %qF", fndecl); @@ -9711,18 +10163,24 @@ altivec_expand_builtin (tree exp, rtx target, bool *expandedp) case ALTIVEC_BUILTIN_VEC_INIT_V8HI: case ALTIVEC_BUILTIN_VEC_INIT_V16QI: case ALTIVEC_BUILTIN_VEC_INIT_V4SF: + case VSX_BUILTIN_VEC_INIT_V2DF: + case VSX_BUILTIN_VEC_INIT_V2DI: return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target); case ALTIVEC_BUILTIN_VEC_SET_V4SI: case ALTIVEC_BUILTIN_VEC_SET_V8HI: case ALTIVEC_BUILTIN_VEC_SET_V16QI: case ALTIVEC_BUILTIN_VEC_SET_V4SF: + case VSX_BUILTIN_VEC_SET_V2DF: + case VSX_BUILTIN_VEC_SET_V2DI: return altivec_expand_vec_set_builtin (exp); case ALTIVEC_BUILTIN_VEC_EXT_V4SI: case ALTIVEC_BUILTIN_VEC_EXT_V8HI: case ALTIVEC_BUILTIN_VEC_EXT_V16QI: case ALTIVEC_BUILTIN_VEC_EXT_V4SF: + case VSX_BUILTIN_VEC_EXT_V2DF: + case VSX_BUILTIN_VEC_EXT_V2DI: return altivec_expand_vec_ext_builtin (exp, target); default: @@ -10245,6 +10703,11 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, if (fcode == RS6000_BUILTIN_BSWAP_HI) return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target); + if (fcode == POWER7_BUILTIN_BPERMD) + return rs6000_expand_binop_builtin (((TARGET_64BIT) + ? CODE_FOR_bpermd_di + : CODE_FOR_bpermd_si), exp, target); + if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE) { @@ -10500,6 +10963,33 @@ rs6000_init_builtins (void) TYPE_NAME (pixel_V8HI_type_node) = tdecl; (*lang_hooks.decls.pushdecl) (tdecl); + if (TARGET_VSX) + { + tdecl = build_decl (BUILTINS_LOCATION, + TYPE_DECL, get_identifier ("__vector double"), + unsigned_V2DI_type_node); + TYPE_NAME (V2DF_type_node) = tdecl; + (*lang_hooks.decls.pushdecl) (tdecl); + + tdecl = build_decl (BUILTINS_LOCATION, + TYPE_DECL, get_identifier ("__vector long"), + V2DI_type_node); + TYPE_NAME (V2DI_type_node) = tdecl; + (*lang_hooks.decls.pushdecl) (tdecl); + + tdecl = build_decl (BUILTINS_LOCATION, + TYPE_DECL, get_identifier ("__vector unsigned long"), + unsigned_V2DI_type_node); + TYPE_NAME (unsigned_V2DI_type_node) = tdecl; + (*lang_hooks.decls.pushdecl) (tdecl); + + tdecl = build_decl (BUILTINS_LOCATION, + TYPE_DECL, get_identifier ("__vector __bool long"), + bool_V2DI_type_node); + TYPE_NAME (bool_V2DI_type_node) = tdecl; + (*lang_hooks.decls.pushdecl) (tdecl); + } + if (TARGET_PAIRED_FLOAT) paired_init_builtins (); if (TARGET_SPE) @@ -10531,6 +11021,15 @@ rs6000_init_builtins (void) RS6000_BUILTIN_RECIP); } + if (TARGET_POPCNTD) + { + enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode; + tree ftype = builtin_function_type (mode, mode, mode, VOIDmode, + POWER7_BUILTIN_BPERMD, + "__builtin_bpermd"); + def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype, + POWER7_BUILTIN_BPERMD); + } if (TARGET_POWERPC) { /* Don't use builtin_function_type here, as it maps HI/QI to SI. */ @@ -10969,6 +11468,10 @@ altivec_init_builtins (void) = build_function_type_list (integer_type_node, integer_type_node, V4SF_type_node, V4SF_type_node, NULL_TREE); + tree int_ftype_int_v2df_v2df + = build_function_type_list (integer_type_node, + integer_type_node, V2DF_type_node, + V2DF_type_node, NULL_TREE); tree v4si_ftype_v4si = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE); tree v8hi_ftype_v8hi @@ -10977,6 +11480,8 @@ altivec_init_builtins (void) = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE); tree v4sf_ftype_v4sf = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE); + tree v2df_ftype_v2df + = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE); tree void_ftype_pcvoid_int_int = build_function_type_list (void_type_node, pcvoid_type_node, integer_type_node, @@ -11079,8 +11584,10 @@ altivec_init_builtins (void) { enum machine_mode mode1; tree type; - bool is_overloaded = dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST - && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST; + bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST + && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST) + || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST + && dp->code <= VSX_BUILTIN_OVERLOADED_LAST)); if (is_overloaded) mode1 = VOIDmode; @@ -11104,6 +11611,9 @@ altivec_init_builtins (void) case V4SFmode: type = int_ftype_int_v4sf_v4sf; break; + case V2DFmode: + type = int_ftype_int_v2df_v2df; + break; default: gcc_unreachable (); } @@ -11134,6 +11644,9 @@ altivec_init_builtins (void) case V4SFmode: type = v4sf_ftype_v4sf; break; + case V2DFmode: + type = v2df_ftype_v2df; + break; default: gcc_unreachable (); } @@ -11193,6 +11706,19 @@ altivec_init_builtins (void) def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype, ALTIVEC_BUILTIN_VEC_INIT_V4SF); + if (TARGET_VSX) + { + ftype = build_function_type_list (V2DF_type_node, double_type_node, + double_type_node, NULL_TREE); + def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype, + VSX_BUILTIN_VEC_INIT_V2DF); + + ftype = build_function_type_list (V2DI_type_node, intDI_type_node, + intDI_type_node, NULL_TREE); + def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype, + VSX_BUILTIN_VEC_INIT_V2DI); + } + /* Access to the vec_set patterns. */ ftype = build_function_type_list (V4SI_type_node, V4SI_type_node, intSI_type_node, @@ -11218,6 +11744,21 @@ altivec_init_builtins (void) def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype, ALTIVEC_BUILTIN_VEC_SET_V4SF); + if (TARGET_VSX) + { + ftype = build_function_type_list (V2DF_type_node, V2DF_type_node, + double_type_node, + integer_type_node, NULL_TREE); + def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype, + VSX_BUILTIN_VEC_SET_V2DF); + + ftype = build_function_type_list (V2DI_type_node, V2DI_type_node, + intDI_type_node, + integer_type_node, NULL_TREE); + def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype, + VSX_BUILTIN_VEC_SET_V2DI); + } + /* Access to the vec_extract patterns. */ ftype = build_function_type_list (intSI_type_node, V4SI_type_node, integer_type_node, NULL_TREE); @@ -11238,6 +11779,19 @@ altivec_init_builtins (void) integer_type_node, NULL_TREE); def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype, ALTIVEC_BUILTIN_VEC_EXT_V4SF); + + if (TARGET_VSX) + { + ftype = build_function_type_list (double_type_node, V2DF_type_node, + integer_type_node, NULL_TREE); + def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype, + VSX_BUILTIN_VEC_EXT_V2DF); + + ftype = build_function_type_list (intDI_type_node, V2DI_type_node, + integer_type_node, NULL_TREE); + def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype, + VSX_BUILTIN_VEC_EXT_V2DI); + } } /* Hash function for builtin functions with up to 3 arguments and a return @@ -11333,6 +11887,14 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0, case ALTIVEC_BUILTIN_VSEL_8HI_UNS: case ALTIVEC_BUILTIN_VSEL_4SI_UNS: case ALTIVEC_BUILTIN_VSEL_2DI_UNS: + case VSX_BUILTIN_VPERM_16QI_UNS: + case VSX_BUILTIN_VPERM_8HI_UNS: + case VSX_BUILTIN_VPERM_4SI_UNS: + case VSX_BUILTIN_VPERM_2DI_UNS: + case VSX_BUILTIN_XXSEL_16QI_UNS: + case VSX_BUILTIN_XXSEL_8HI_UNS: + case VSX_BUILTIN_XXSEL_4SI_UNS: + case VSX_BUILTIN_XXSEL_2DI_UNS: h.uns_p[0] = 1; h.uns_p[1] = 1; h.uns_p[2] = 1; @@ -11346,6 +11908,12 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0, case ALTIVEC_BUILTIN_VPERM_4SF: case ALTIVEC_BUILTIN_VPERM_2DI: case ALTIVEC_BUILTIN_VPERM_2DF: + case VSX_BUILTIN_VPERM_16QI: + case VSX_BUILTIN_VPERM_8HI: + case VSX_BUILTIN_VPERM_4SI: + case VSX_BUILTIN_VPERM_4SF: + case VSX_BUILTIN_VPERM_2DI: + case VSX_BUILTIN_VPERM_2DF: h.uns_p[3] = 1; break; @@ -11442,8 +12010,10 @@ rs6000_common_init_builtins (void) || (mask == 0 && !TARGET_PAIRED_FLOAT)) continue; - if (d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST - && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST) + if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST + && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST) + || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST + && d->code <= VSX_BUILTIN_OVERLOADED_LAST)) { if (! (type = opaque_ftype_opaque_opaque_opaque)) type = opaque_ftype_opaque_opaque_opaque @@ -11481,8 +12051,10 @@ rs6000_common_init_builtins (void) || (mask == 0 && !TARGET_PAIRED_FLOAT)) continue; - if (d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST - && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST) + if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST + && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST) + || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST + && d->code <= VSX_BUILTIN_OVERLOADED_LAST)) { if (! (type = opaque_ftype_opaque_opaque)) type = opaque_ftype_opaque_opaque @@ -11537,14 +12109,15 @@ rs6000_common_init_builtins (void) enum machine_mode mode0, mode1; tree type; int mask = d->mask; - bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST - && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST; if ((mask != 0 && (mask & target_flags) == 0) || (mask == 0 && !TARGET_PAIRED_FLOAT)) continue; - if (is_overloaded) + if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST + && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST) + || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST + && d->code <= VSX_BUILTIN_OVERLOADED_LAST)) { if (! (type = opaque_ftype_opaque)) type = opaque_ftype_opaque @@ -22228,18 +22801,24 @@ rs6000_handle_altivec_attribute (tree *node, mode = TYPE_MODE (type); /* Check for invalid AltiVec type qualifiers. */ - if (type == long_unsigned_type_node || type == long_integer_type_node) - { - if (TARGET_64BIT) - error ("use of %<long%> in AltiVec types is invalid for 64-bit code"); - else if (rs6000_warn_altivec_long) - warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>"); - } - else if (type == long_long_unsigned_type_node - || type == long_long_integer_type_node) - error ("use of %<long long%> in AltiVec types is invalid"); - else if (type == double_type_node) - error ("use of %<double%> in AltiVec types is invalid"); + if (!TARGET_VSX) + { + if (type == long_unsigned_type_node || type == long_integer_type_node) + { + if (TARGET_64BIT) + error ("use of %<long%> in AltiVec types is invalid for " + "64-bit code without -mvsx"); + else if (rs6000_warn_altivec_long) + warning (0, "use of %<long%> in AltiVec types is deprecated; " + "use %<int%>"); + } + else if (type == long_long_unsigned_type_node + || type == long_long_integer_type_node) + error ("use of %<long long%> in AltiVec types is invalid without " + "-mvsx"); + else if (type == double_type_node) + error ("use of %<double%> in AltiVec types is invalid without -mvsx"); + } else if (type == long_double_type_node) error ("use of %<long double%> in AltiVec types is invalid"); else if (type == boolean_type_node) @@ -22255,6 +22834,9 @@ rs6000_handle_altivec_attribute (tree *node, unsigned_p = TYPE_UNSIGNED (type); switch (mode) { + case DImode: + result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node); + break; case SImode: result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node); break; @@ -22265,10 +22847,12 @@ rs6000_handle_altivec_attribute (tree *node, result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node); break; case SFmode: result = V4SF_type_node; break; + case DFmode: result = V2DF_type_node; break; /* If the user says 'vector int bool', we may be handed the 'bool' attribute _before_ the 'vector' attribute, and so select the proper type in the 'b' case below. */ case V4SImode: case V8HImode: case V16QImode: case V4SFmode: + case V2DImode: case V2DFmode: result = type; default: break; } @@ -22276,6 +22860,7 @@ rs6000_handle_altivec_attribute (tree *node, case 'b': switch (mode) { + case DImode: case V2DImode: result = bool_V2DI_type_node; break; case SImode: case V4SImode: result = bool_V4SI_type_node; break; case HImode: case V8HImode: result = bool_V8HI_type_node; break; case QImode: case V16QImode: result = bool_V16QI_type_node; @@ -22320,6 +22905,7 @@ rs6000_mangle_type (const_tree type) if (type == bool_short_type_node) return "U6__bools"; if (type == pixel_type_node) return "u7__pixel"; if (type == bool_int_type_node) return "U6__booli"; + if (type == bool_long_type_node) return "U6__booll"; /* Mangle IBM extended float long double as `g' (__float128) on powerpc*-linux where long-double-64 previously was the default. */ @@ -24557,7 +25143,7 @@ rs6000_vector_mode_supported_p (enum machine_mode mode) if (TARGET_SPE && SPE_VECTOR_MODE (mode)) return true; - else if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)) + else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)) return true; else diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 3153243b30d..0c5e59333ab 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1883,6 +1883,10 @@ typedef struct rs6000_args && EASY_VECTOR_15((n) >> 1) \ && ((n) & 1) == 0) +#define EASY_VECTOR_MSB(n,mode) \ + (((unsigned HOST_WIDE_INT)n) == \ + ((((unsigned HOST_WIDE_INT)GET_MODE_MASK (mode)) + 1) >> 1)) + /* Try a machine-dependent way of reloading an illegitimate address operand. If we find one, push the reload and jump to WIN. This @@ -2678,6 +2682,7 @@ enum rs6000_builtins ALTIVEC_BUILTIN_VEC_EXT_V8HI, ALTIVEC_BUILTIN_VEC_EXT_V16QI, ALTIVEC_BUILTIN_VEC_EXT_V4SF, + ALTIVEC_BUILTIN_COPYSIGN_V4SF, /* Altivec overloaded builtins. */ ALTIVEC_BUILTIN_VCMPEQ_P, @@ -2703,6 +2708,7 @@ enum rs6000_builtins ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VEC_CMPLE, ALTIVEC_BUILTIN_VEC_CMPLT, + ALTIVEC_BUILTIN_VEC_COPYSIGN, ALTIVEC_BUILTIN_VEC_CTF, ALTIVEC_BUILTIN_VEC_CTS, ALTIVEC_BUILTIN_VEC_CTU, @@ -2745,6 +2751,7 @@ enum rs6000_builtins ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VEC_MULO, + ALTIVEC_BUILTIN_VEC_NEARBYINT, ALTIVEC_BUILTIN_VEC_NMSUB, ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VEC_OR, @@ -2755,6 +2762,7 @@ enum rs6000_builtins ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VEC_RE, ALTIVEC_BUILTIN_VEC_RL, + ALTIVEC_BUILTIN_VEC_RINT, ALTIVEC_BUILTIN_VEC_ROUND, ALTIVEC_BUILTIN_VEC_RSQRTE, ALTIVEC_BUILTIN_VEC_SEL, @@ -2772,6 +2780,7 @@ enum rs6000_builtins ALTIVEC_BUILTIN_VEC_SPLTB, ALTIVEC_BUILTIN_VEC_SPLTH, ALTIVEC_BUILTIN_VEC_SPLTW, + ALTIVEC_BUILTIN_VEC_SQRT, ALTIVEC_BUILTIN_VEC_SR, ALTIVEC_BUILTIN_VEC_SRA, ALTIVEC_BUILTIN_VEC_SRL, @@ -3228,6 +3237,8 @@ enum rs6000_builtins VSX_BUILTIN_XSRSQRTEDP, VSX_BUILTIN_XSSQRTDP, VSX_BUILTIN_XSSUBDP, + VSX_BUILTIN_CPSGNDP, + VSX_BUILTIN_CPSGNSP, VSX_BUILTIN_XSTDIVDP_FE, VSX_BUILTIN_XSTDIVDP_FG, VSX_BUILTIN_XSTSQRTDP_FE, diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index ae1ea99d0a3..9524fe81f13 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -101,6 +101,7 @@ (UNSPEC_RSQRT 48) (UNSPEC_TOCREL 49) (UNSPEC_MACHOPIC_OFFSET 50) + (UNSPEC_BPERM 51) ]) ;; @@ -167,6 +168,7 @@ (include "power4.md") (include "power5.md") (include "power6.md") +(include "power7.md") (include "cell.md") (include "xfpu.md") @@ -5900,9 +5902,18 @@ (match_dup 5)) (match_dup 3) (match_dup 4)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && !HONOR_NANS (DFmode) && !HONOR_SIGNED_ZEROS (DFmode)" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && ((TARGET_PPC_GFXOPT + && !HONOR_NANS (DFmode) + && !HONOR_SIGNED_ZEROS (DFmode)) + || VECTOR_UNIT_VSX_P (DFmode))" { + if (VECTOR_UNIT_VSX_P (DFmode)) + { + emit_insn (gen_vsx_copysigndf3 (operands[0], operands[1], + operands[2], CONST0_RTX (DFmode))); + DONE; + } operands[3] = gen_reg_rtx (DFmode); operands[4] = gen_reg_rtx (DFmode); operands[5] = CONST0_RTX (DFmode); @@ -6037,7 +6048,8 @@ (define_insn "*negdf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (neg:DF (match_operand:DF 1 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !VECTOR_UNIT_VSX_P (DFmode)" "fneg %0,%1" [(set_attr "type" "fp")]) @@ -6050,14 +6062,16 @@ (define_insn "*absdf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (abs:DF (match_operand:DF 1 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !VECTOR_UNIT_VSX_P (DFmode)" "fabs %0,%1" [(set_attr "type" "fp")]) (define_insn "*nabsdf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "d"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !VECTOR_UNIT_VSX_P (DFmode)" "fnabs %0,%1" [(set_attr "type" "fp")]) @@ -6072,7 +6086,8 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%d") (match_operand:DF 2 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !VECTOR_UNIT_VSX_P (DFmode)" "{fa|fadd} %0,%1,%2" [(set_attr "type" "fp") (set_attr "fp_type" "fp_addsub_d")]) @@ -6088,7 +6103,8 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (minus:DF (match_operand:DF 1 "gpc_reg_operand" "d") (match_operand:DF 2 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !VECTOR_UNIT_VSX_P (DFmode)" "{fs|fsub} %0,%1,%2" [(set_attr "type" "fp") (set_attr "fp_type" "fp_addsub_d")]) @@ -6104,7 +6120,8 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") (match_operand:DF 2 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !VECTOR_UNIT_VSX_P (DFmode)" "{fm|fmul} %0,%1,%2" [(set_attr "type" "dmul") (set_attr "fp_type" "fp_mul_d")]) @@ -6122,7 +6139,8 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (div:DF (match_operand:DF 1 "gpc_reg_operand" "d") (match_operand:DF 2 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU + && !VECTOR_UNIT_VSX_P (DFmode)" "{fd|fdiv} %0,%1,%2" [(set_attr "type" "ddiv")]) @@ -6138,73 +6156,81 @@ DONE; }) -(define_insn "fred" +(define_expand "fred" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRES))] - "TARGET_POPCNTB && flag_finite_math_only" + "(TARGET_POPCNTB || VECTOR_UNIT_VSX_P (DFmode)) && flag_finite_math_only" + "") + +(define_insn "*fred_fpr" + [(set (match_operand:DF 0 "gpc_reg_operand" "=f") + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))] + "TARGET_POPCNTB && flag_finite_math_only && !VECTOR_UNIT_VSX_P (DFmode)" "fre %0,%1" [(set_attr "type" "fp")]) -(define_insn "" +(define_insn "*fmadddf4_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") (match_operand:DF 2 "gpc_reg_operand" "d")) (match_operand:DF 3 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT + && VECTOR_UNIT_NONE_P (DFmode)" "{fma|fmadd} %0,%1,%2,%3" [(set_attr "type" "dmul") (set_attr "fp_type" "fp_maddsub_d")]) -(define_insn "" +(define_insn "*fmsubdf4_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") (match_operand:DF 2 "gpc_reg_operand" "d")) (match_operand:DF 3 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT + && VECTOR_UNIT_NONE_P (DFmode)" "{fms|fmsub} %0,%1,%2,%3" [(set_attr "type" "dmul") (set_attr "fp_type" "fp_maddsub_d")]) -(define_insn "" +(define_insn "*fnmadddf4_fpr_1" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") (match_operand:DF 2 "gpc_reg_operand" "d")) (match_operand:DF 3 "gpc_reg_operand" "d"))))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT - && HONOR_SIGNED_ZEROS (DFmode)" + && HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)" "{fnma|fnmadd} %0,%1,%2,%3" [(set_attr "type" "dmul") (set_attr "fp_type" "fp_maddsub_d")]) -(define_insn "" +(define_insn "*fnmadddf4_fpr_2" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "d")) (match_operand:DF 2 "gpc_reg_operand" "d")) (match_operand:DF 3 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT - && ! HONOR_SIGNED_ZEROS (DFmode)" + && ! HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)" "{fnma|fnmadd} %0,%1,%2,%3" [(set_attr "type" "dmul") (set_attr "fp_type" "fp_maddsub_d")]) -(define_insn "" +(define_insn "*fnmsubdf4_fpr_1" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") (match_operand:DF 2 "gpc_reg_operand" "d")) (match_operand:DF 3 "gpc_reg_operand" "d"))))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT - && HONOR_SIGNED_ZEROS (DFmode)" + && HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)" "{fnms|fnmsub} %0,%1,%2,%3" [(set_attr "type" "dmul") (set_attr "fp_type" "fp_maddsub_d")]) -(define_insn "" +(define_insn "*fnmsubdf4_fpr_2" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (minus:DF (match_operand:DF 3 "gpc_reg_operand" "d") (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") (match_operand:DF 2 "gpc_reg_operand" "d"))))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT - && ! HONOR_SIGNED_ZEROS (DFmode)" + && ! HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)" "{fnms|fnmsub} %0,%1,%2,%3" [(set_attr "type" "dmul") (set_attr "fp_type" "fp_maddsub_d")]) @@ -6213,7 +6239,8 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "d")))] "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS - && TARGET_DOUBLE_FLOAT" + && TARGET_DOUBLE_FLOAT + && !VECTOR_UNIT_VSX_P (DFmode)" "fsqrt %0,%1" [(set_attr "type" "dsqrt")]) @@ -6308,6 +6335,12 @@ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" "") +(define_expand "fixuns_truncdfdi2" + [(set (match_operand:DI 0 "register_operand" "") + (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))] + "TARGET_HARD_FLOAT && TARGET_VSX" + "") + ; For each of these conversions, there is a define_expand, a define_insn ; with a '#' template, and a define_split (with C code). The idea is ; to allow constant folding with the template of the define_insn, @@ -6549,24 +6582,38 @@ "{fcirz|fctiwz} %0,%1" [(set_attr "type" "fp")]) -(define_insn "btruncdf2" +(define_expand "btruncdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIZ))] "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "") + +(define_insn "*btruncdf2_fpr" + [(set (match_operand:DF 0 "gpc_reg_operand" "=f") + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))] + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !VECTOR_UNIT_VSX_P (DFmode)" "friz %0,%1" [(set_attr "type" "fp")]) (define_insn "btruncsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT " + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "friz %0,%1" [(set_attr "type" "fp")]) -(define_insn "ceildf2" +(define_expand "ceildf2" + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "")] UNSPEC_FRIP))] + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "") + +(define_insn "*ceildf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIP))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !VECTOR_UNIT_VSX_P (DFmode)" "frip %0,%1" [(set_attr "type" "fp")]) @@ -6577,10 +6624,17 @@ "frip %0,%1" [(set_attr "type" "fp")]) -(define_insn "floordf2" +(define_expand "floordf2" + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "")] UNSPEC_FRIM))] + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "") + +(define_insn "*floordf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIM))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !VECTOR_UNIT_VSX_P (DFmode)" "frim %0,%1" [(set_attr "type" "fp")]) @@ -6591,6 +6645,7 @@ "frim %0,%1" [(set_attr "type" "fp")]) +;; No VSX equivalent to frin (define_insn "rounddf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIN))] @@ -6605,6 +6660,12 @@ "frin %0,%1" [(set_attr "type" "fp")]) +(define_expand "ftruncdf2" + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (fix:DF (match_operand:DF 1 "gpc_reg_operand" "")))] + "VECTOR_UNIT_VSX_P (DFmode)" + "") + ; An UNSPEC is used so we don't have to support SImode in FP registers. (define_insn "stfiwx" [(set (match_operand:SI 0 "memory_operand" "=Z") @@ -6620,17 +6681,40 @@ "TARGET_HARD_FLOAT && !TARGET_FPRS" "") -(define_insn "floatdidf2" +(define_expand "floatdidf2" + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))] + "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode)) + && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" + "") + +(define_insn "*floatdidf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (float:DF (match_operand:DI 1 "gpc_reg_operand" "!d#r")))] - "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" + "(TARGET_POWERPC64 || TARGET_XILINX_FPU) + && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS + && !VECTOR_UNIT_VSX_P (DFmode)" "fcfid %0,%1" [(set_attr "type" "fp")]) -(define_insn "fix_truncdfdi2" +(define_expand "floatunsdidf2" + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "")))] + "TARGET_VSX" + "") + +(define_expand "fix_truncdfdi2" + [(set (match_operand:DI 0 "gpc_reg_operand" "") + (fix:DI (match_operand:DF 1 "gpc_reg_operand" "")))] + "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode)) + && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" + "") + +(define_insn "*fix_truncdfdi2_fpr" [(set (match_operand:DI 0 "gpc_reg_operand" "=!d#r") (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d")))] - "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" + "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT + && TARGET_DOUBLE_FLOAT && TARGET_FPRS && !VECTOR_UNIT_VSX_P (DFmode)" "fctidz %0,%1" [(set_attr "type" "fp")]) @@ -8956,8 +9040,8 @@ ;; The "??" is a kludge until we can figure out a more reasonable way ;; of handling these non-offsettable values. (define_insn "*movdf_hardfloat32" - [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,d,d,m,!r,!r,!r") - (match_operand:DF 1 "input_operand" "r,m,r,d,m,d,G,H,F"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,ws,?wa,ws,?wa,Z,?Z,d,d,m,wa,!r,!r,!r") + (match_operand:DF 1 "input_operand" "r,m,r,ws,wa,Z,Z,ws,wa,d,m,d,j,G,H,F"))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" @@ -9036,19 +9120,30 @@ return \"\"; } case 3: - return \"fmr %0,%1\"; case 4: - return \"lfd%U1%X1 %0,%1\"; + return \"xxlor %x0,%x1,%x1\"; case 5: - return \"stfd%U0%X0 %1,%0\"; case 6: + return \"lxsd%U1x %x0,%y1\"; case 7: case 8: + return \"stxsd%U0x %x1,%y0\"; + case 9: + return \"fmr %0,%1\"; + case 10: + return \"lfd%U1%X1 %0,%1\"; + case 11: + return \"stfd%U0%X0 %1,%0\"; + case 12: + return \"xxlxor %x0,%x0,%x0\"; + case 13: + case 14: + case 15: return \"#\"; } }" - [(set_attr "type" "two,load,store,fp,fpload,fpstore,*,*,*") - (set_attr "length" "8,16,16,4,4,4,8,12,16")]) + [(set_attr "type" "two,load,store,fp,fp,fpload,fpload,fpstore,fpstore,fp,fpload,fpstore,vecsimple,*,*,*") + (set_attr "length" "8,16,16,4,4,4,4,4,4,4,4,4,4,8,12,16")]) (define_insn "*movdf_softfloat32" [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r") @@ -9096,19 +9191,26 @@ ; ld/std require word-aligned displacements -> 'Y' constraint. ; List Y->r and r->Y before r->r for reload. (define_insn "*movdf_hardfloat64_mfpgpr" - [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,d,d,m,*c*l,!r,*h,!r,!r,!r,r,d") - (match_operand:DF 1 "input_operand" "r,Y,r,d,m,d,r,h,0,G,H,F,d,r"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,ws,?wa,ws,?wa,Z,?Z,d,d,m,wa,*c*l,!r,*h,!r,!r,!r,r,d") + (match_operand:DF 1 "input_operand" "r,Y,r,ws,?wa,Z,Z,ws,wa,d,m,d,j,r,h,0,G,H,F,d,r"))] "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS - && TARGET_DOUBLE_FLOAT + && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" "@ std%U0%X0 %1,%0 ld%U1%X1 %0,%1 mr %0,%1 + xxlor %x0,%x1,%x1 + xxlor %x0,%x1,%x1 + lxsd%U1x %x0,%y1 + lxsd%U1x %x0,%y1 + stxsd%U0x %x1,%y0 + stxsd%U0x %x1,%y0 fmr %0,%1 lfd%U1%X1 %0,%1 stfd%U0%X0 %1,%0 + xxlxor %x0,%x0,%x0 mt%0 %1 mf%1 %0 {cror 0,0,0|nop} @@ -9117,33 +9219,40 @@ # mftgpr %0,%1 mffgpr %0,%1" - [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr") - (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16,4,4")]) + [(set_attr "type" "store,load,*,fp,fp,fpload,fpload,fpstore,fpstore,fp,fpload,fpstore,vecsimple,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr") + (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16,4,4")]) ; ld/std require word-aligned displacements -> 'Y' constraint. ; List Y->r and r->Y before r->r for reload. (define_insn "*movdf_hardfloat64" - [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,d,d,m,*c*l,!r,*h,!r,!r,!r") - (match_operand:DF 1 "input_operand" "r,Y,r,d,m,d,r,h,0,G,H,F"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,ws,?wa,ws,?wa,Z,?Z,d,d,m,wa,*c*l,!r,*h,!r,!r,!r") + (match_operand:DF 1 "input_operand" "r,Y,r,ws,wa,Z,Z,ws,wa,d,m,d,j,r,h,0,G,H,F"))] "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS - && TARGET_DOUBLE_FLOAT + && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" "@ std%U0%X0 %1,%0 ld%U1%X1 %0,%1 mr %0,%1 + xxlor %x0,%x1,%x1 + xxlor %x0,%x1,%x1 + lxsd%U1x %x0,%y1 + lxsd%U1x %x0,%y1 + stxsd%U0x %x1,%y0 + stxsd%U0x %x1,%y0 fmr %0,%1 lfd%U1%X1 %0,%1 stfd%U0%X0 %1,%0 + xxlxor %x0,%x0,%x0 mt%0 %1 mf%1 %0 {cror 0,0,0|nop} # # #" - [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*") - (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16")]) + [(set_attr "type" "store,load,*,fp,fp,fpload,fpload,fpstore,fpstore,fp,fpload,fpstore,vecsimple,mtjmpr,mfjmpr,*,*,*,*") + (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16")]) (define_insn "*movdf_softfloat64" [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h") @@ -9720,15 +9829,16 @@ (define_insn "*movti_ppc64" [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o<>,r") (match_operand:TI 1 "input_operand" "r,r,m"))] - "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode) - || gpc_reg_operand (operands[1], TImode))" + "(TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode) + || gpc_reg_operand (operands[1], TImode))) + && VECTOR_MEM_NONE_P (TImode)" "#" [(set_attr "type" "*,store,load")]) (define_split [(set (match_operand:TI 0 "gpc_reg_operand" "") (match_operand:TI 1 "const_double_operand" ""))] - "TARGET_POWERPC64" + "TARGET_POWERPC64 && VECTOR_MEM_NONE_P (TImode)" [(set (match_dup 2) (match_dup 4)) (set (match_dup 3) (match_dup 5))] " @@ -9754,7 +9864,7 @@ (define_split [(set (match_operand:TI 0 "nonimmediate_operand" "") (match_operand:TI 1 "input_operand" ""))] - "reload_completed + "reload_completed && VECTOR_MEM_NONE_P (TImode) && gpr_or_gpr_p (operands[0], operands[1])" [(pc)] { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) @@ -12647,7 +12757,8 @@ [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "d") (match_operand:DF 2 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !VECTOR_UNIT_VSX_P (DFmode)" "fcmpu %0,%1,%2" [(set_attr "type" "fpcompare")]) @@ -15320,9 +15431,19 @@ }" [(set_attr "type" "load")]) +(define_insn "bpermd_<mode>" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r") + (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))] + "TARGET_POPCNTD" + "bpermd %0,%1,%2" + [(set_attr "type" "integer")]) + + (include "sync.md") (include "vector.md") +(include "vsx.md") (include "altivec.md") (include "spe.md") (include "dfp.md") diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index ac61ffc582e..90af9dce47b 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -151,6 +151,10 @@ malign-branch-targets Target Undocumented Report Var(TARGET_ALIGN_BRANCH_TARGETS) Init(-1) ; Explicitly set/unset whether rs6000_align_branch_targets is set +mvectorize-builtins +Target Undocumented Report Var(TARGET_VECTORIZE_BUILTINS) Init(-1) +; Explicitly control whether we vectorize the builtins or not. + mupdate Target Report Var(TARGET_UPDATE) Init(1) Generate load/store with update instructions diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000 index 0b8e311078d..66a367a7b62 100644 --- a/gcc/config/rs6000/t-rs6000 +++ b/gcc/config/rs6000/t-rs6000 @@ -53,6 +53,7 @@ MD_INCLUDES = $(srcdir)/config/rs6000/rios1.md \ $(srcdir)/config/rs6000/power4.md \ $(srcdir)/config/rs6000/power5.md \ $(srcdir)/config/rs6000/power6.md \ + $(srcdir)/config/rs6000/power7.md \ $(srcdir)/config/rs6000/cell.md \ $(srcdir)/config/rs6000/xfpu.md \ $(srcdir)/config/rs6000/predicates.md \ @@ -60,6 +61,7 @@ MD_INCLUDES = $(srcdir)/config/rs6000/rios1.md \ $(srcdir)/config/rs6000/darwin.md \ $(srcdir)/config/rs6000/sync.md \ $(srcdir)/config/rs6000/vector.md \ + $(srcdir)/config/rs6000/vsx.md \ $(srcdir)/config/rs6000/altivec.md \ $(srcdir)/config/rs6000/spe.md \ $(srcdir)/config/rs6000/dfp.md \ diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md index 1546db7a74f..6366e4fe0e7 100644 --- a/gcc/config/rs6000/vector.md +++ b/gcc/config/rs6000/vector.md @@ -1,6 +1,7 @@ -;; Expander definitions for vector support. No instructions are in this file, -;; this file provides the generic vector expander, and the actual vector -;; instructions will be in altivec.md. +;; Expander definitions for vector support between altivec & vsx. No +;; instructions are in this file, this file provides the generic vector +;; expander, and the actual vector instructions will be in altivec.md and +;; vsx.md ;; Copyright (C) 2009 ;; Free Software Foundation, Inc. @@ -27,10 +28,10 @@ (define_mode_iterator VEC_I [V16QI V8HI V4SI]) ;; Vector float modes -(define_mode_iterator VEC_F [V4SF]) +(define_mode_iterator VEC_F [V4SF V2DF]) ;; Vector arithmetic modes -(define_mode_iterator VEC_A [V16QI V8HI V4SI V4SF]) +(define_mode_iterator VEC_A [V16QI V8HI V4SI V4SF V2DF]) ;; Vector modes that need alginment via permutes (define_mode_iterator VEC_K [V16QI V8HI V4SI V4SF]) @@ -41,6 +42,9 @@ ;; Vector modes for moves. Don't do TImode here. (define_mode_iterator VEC_M [V16QI V8HI V4SI V2DI V4SF V2DF]) +;; Vector modes for types that don't need a realignment under VSX +(define_mode_iterator VEC_N [V4SI V4SF V2DI V2DF]) + ;; Vector comparison modes (define_mode_iterator VEC_C [V16QI V8HI V4SI V4SF V2DF]) @@ -75,7 +79,7 @@ (define_expand "mov<mode>" [(set (match_operand:VEC_M 0 "nonimmediate_operand" "") (match_operand:VEC_M 1 "any_operand" ""))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" + "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" { if (can_create_pseudo_p ()) { @@ -89,24 +93,25 @@ } }) -;; Generic vector floating point load/store instructions. +;; Generic vector floating point load/store instructions. These will match +;; insns defined in vsx.md or altivec.md depending on the switches. (define_expand "vector_load_<mode>" [(set (match_operand:VEC_M 0 "vfloat_operand" "") (match_operand:VEC_M 1 "memory_operand" ""))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" + "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "vector_store_<mode>" [(set (match_operand:VEC_M 0 "memory_operand" "") (match_operand:VEC_M 1 "vfloat_operand" ""))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" + "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" "") ;; Splits if a GPR register was chosen for the move (define_split [(set (match_operand:VEC_L 0 "nonimmediate_operand" "") (match_operand:VEC_L 1 "input_operand" ""))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode) + "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed && gpr_or_gpr_p (operands[0], operands[1])" [(pc)] @@ -149,7 +154,7 @@ (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r") (match_operand:P 2 "reg_or_cint_operand" "rI")) (const_int -16)))] - "TARGET_ALTIVEC && (reload_in_progress || reload_completed)" + "(TARGET_ALTIVEC || TARGET_VSX) && (reload_in_progress || reload_completed)" "#" "&& reload_completed" [(set (match_dup 0) @@ -167,7 +172,7 @@ [(set (match_operand:P 0 "gpc_reg_operand" "=b") (and:P (match_operand:P 1 "gpc_reg_operand" "r") (const_int -16)))] - "TARGET_ALTIVEC && (reload_in_progress || reload_completed)" + "(TARGET_ALTIVEC || TARGET_VSX) && (reload_in_progress || reload_completed)" "#" "&& reload_completed" [(parallel [(set (match_dup 0) @@ -180,68 +185,131 @@ [(set (match_operand:VEC_F 0 "vfloat_operand" "") (plus:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") (match_operand:VEC_F 2 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "sub<mode>3" [(set (match_operand:VEC_F 0 "vfloat_operand" "") (minus:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") (match_operand:VEC_F 2 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "mul<mode>3" [(set (match_operand:VEC_F 0 "vfloat_operand" "") (mult:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") (match_operand:VEC_F 2 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode) && TARGET_FUSED_MADD" + "(VECTOR_UNIT_VSX_P (<MODE>mode) + || (VECTOR_UNIT_ALTIVEC_P (<MODE>mode) && TARGET_FUSED_MADD))" " { - emit_insn (gen_altivec_mulv4sf3 (operands[0], operands[1], operands[2])); - DONE; + if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) + { + emit_insn (gen_altivec_mulv4sf3 (operands[0], operands[1], operands[2])); + DONE; + } }") +(define_expand "div<mode>3" + [(set (match_operand:VEC_F 0 "vfloat_operand" "") + (div:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") + (match_operand:VEC_F 2 "vfloat_operand" "")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "") + (define_expand "neg<mode>2" [(set (match_operand:VEC_F 0 "vfloat_operand" "") (neg:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" " { - emit_insn (gen_altivec_negv4sf2 (operands[0], operands[1])); - DONE; + if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) + { + emit_insn (gen_altivec_negv4sf2 (operands[0], operands[1])); + DONE; + } }") (define_expand "abs<mode>2" [(set (match_operand:VEC_F 0 "vfloat_operand" "") (abs:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" " { - emit_insn (gen_altivec_absv4sf2 (operands[0], operands[1])); - DONE; + if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) + { + emit_insn (gen_altivec_absv4sf2 (operands[0], operands[1])); + DONE; + } }") (define_expand "smin<mode>3" [(set (match_operand:VEC_F 0 "register_operand" "") (smin:VEC_F (match_operand:VEC_F 1 "register_operand" "") (match_operand:VEC_F 2 "register_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "smax<mode>3" [(set (match_operand:VEC_F 0 "register_operand" "") (smax:VEC_F (match_operand:VEC_F 1 "register_operand" "") (match_operand:VEC_F 2 "register_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") +(define_expand "sqrt<mode>2" + [(set (match_operand:VEC_F 0 "vfloat_operand" "") + (sqrt:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "") + (define_expand "ftrunc<mode>2" [(set (match_operand:VEC_F 0 "vfloat_operand" "") (fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" + "") + +(define_expand "vector_ceil<mode>2" + [(set (match_operand:VEC_F 0 "vfloat_operand" "") + (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "")] + UNSPEC_FRIP))] + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" + "") + +(define_expand "vector_floor<mode>2" + [(set (match_operand:VEC_F 0 "vfloat_operand" "") + (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "")] + UNSPEC_FRIM))] + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") +(define_expand "vector_btrunc<mode>2" + [(set (match_operand:VEC_F 0 "vfloat_operand" "") + (fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" + "") + +(define_expand "vector_copysign<mode>3" + [(set (match_operand:VEC_F 0 "vfloat_operand" "") + (if_then_else:VEC_F + (ge:VEC_F (match_operand:VEC_F 2 "vfloat_operand" "") + (match_dup 3)) + (abs:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")) + (neg:VEC_F (abs:VEC_F (match_dup 1)))))] + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" + " +{ + if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) + { + emit_insn (gen_altivec_copysign_v4sf3 (operands[0], operands[1], + operands[2])); + DONE; + } + + operands[3] = CONST0_RTX (<MODE>mode); +}") + ;; Vector comparisons (define_expand "vcond<mode>" @@ -252,7 +320,7 @@ (match_operand:VEC_F 5 "vfloat_operand" "")]) (match_operand:VEC_F 1 "vfloat_operand" "") (match_operand:VEC_F 2 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" " { if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], @@ -302,21 +370,21 @@ [(set (match_operand:VEC_C 0 "vlogical_operand" "") (eq:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "") (match_operand:VEC_C 2 "vlogical_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "vector_gt<mode>" [(set (match_operand:VEC_C 0 "vlogical_operand" "") (gt:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "") (match_operand:VEC_C 2 "vlogical_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "vector_ge<mode>" [(set (match_operand:VEC_C 0 "vlogical_operand" "") (ge:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "") (match_operand:VEC_C 2 "vlogical_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "vector_gtu<mode>" @@ -342,7 +410,7 @@ (const_int 0)) (match_operand:VEC_L 2 "vlogical_operand" "") (match_operand:VEC_L 1 "vlogical_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "vector_select_<mode>_uns" @@ -352,7 +420,7 @@ (const_int 0)) (match_operand:VEC_L 2 "vlogical_operand" "") (match_operand:VEC_L 1 "vlogical_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") ;; Expansions that compare vectors producing a vector result and a predicate, @@ -366,7 +434,7 @@ (set (match_operand:VEC_A 0 "vlogical_operand" "") (eq:VEC_A (match_dup 1) (match_dup 2)))])] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "vector_gt_<mode>_p" @@ -378,7 +446,7 @@ (set (match_operand:VEC_A 0 "vlogical_operand" "") (gt:VEC_A (match_dup 1) (match_dup 2)))])] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "vector_ge_<mode>_p" @@ -390,7 +458,7 @@ (set (match_operand:VEC_F 0 "vfloat_operand" "") (ge:VEC_F (match_dup 1) (match_dup 2)))])] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "vector_gtu_<mode>_p" @@ -402,16 +470,16 @@ (set (match_operand:VEC_I 0 "vlogical_operand" "") (gtu:VEC_I (match_dup 1) (match_dup 2)))])] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") -;; AltiVec predicates. +;; AltiVec/VSX predicates. (define_expand "cr6_test_for_zero" [(set (match_operand:SI 0 "register_operand" "=r") (eq:SI (reg:CC 74) (const_int 0)))] - "TARGET_ALTIVEC" + "TARGET_ALTIVEC || TARGET_VSX" "") (define_expand "cr6_test_for_zero_reverse" @@ -419,14 +487,14 @@ (eq:SI (reg:CC 74) (const_int 0))) (set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))] - "TARGET_ALTIVEC" + "TARGET_ALTIVEC || TARGET_VSX" "") (define_expand "cr6_test_for_lt" [(set (match_operand:SI 0 "register_operand" "=r") (lt:SI (reg:CC 74) (const_int 0)))] - "TARGET_ALTIVEC" + "TARGET_ALTIVEC || TARGET_VSX" "") (define_expand "cr6_test_for_lt_reverse" @@ -434,7 +502,7 @@ (lt:SI (reg:CC 74) (const_int 0))) (set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))] - "TARGET_ALTIVEC" + "TARGET_ALTIVEC || TARGET_VSX" "") @@ -443,82 +511,94 @@ [(set (match_operand:VEC_L 0 "vlogical_operand" "") (xor:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") (match_operand:VEC_L 2 "vlogical_operand" "")))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" + "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "ior<mode>3" [(set (match_operand:VEC_L 0 "vlogical_operand" "") (ior:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") (match_operand:VEC_L 2 "vlogical_operand" "")))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" + "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "and<mode>3" [(set (match_operand:VEC_L 0 "vlogical_operand" "") (and:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") (match_operand:VEC_L 2 "vlogical_operand" "")))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" + "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "one_cmpl<mode>2" [(set (match_operand:VEC_L 0 "vlogical_operand" "") (not:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" + "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "nor<mode>3" [(set (match_operand:VEC_L 0 "vlogical_operand" "") (not:VEC_L (ior:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") (match_operand:VEC_L 2 "vlogical_operand" ""))))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" + "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "andc<mode>3" [(set (match_operand:VEC_L 0 "vlogical_operand" "") (and:VEC_L (not:VEC_L (match_operand:VEC_L 2 "vlogical_operand" "")) (match_operand:VEC_L 1 "vlogical_operand" "")))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" + "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" "") ;; Same size conversions (define_expand "float<VEC_int><mode>2" [(set (match_operand:VEC_F 0 "vfloat_operand" "") (float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" " { - emit_insn (gen_altivec_vcfsx (operands[0], operands[1], const0_rtx)); - DONE; + if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) + { + emit_insn (gen_altivec_vcfsx (operands[0], operands[1], const0_rtx)); + DONE; + } }") (define_expand "unsigned_float<VEC_int><mode>2" [(set (match_operand:VEC_F 0 "vfloat_operand" "") (unsigned_float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" " { - emit_insn (gen_altivec_vcfux (operands[0], operands[1], const0_rtx)); - DONE; + if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) + { + emit_insn (gen_altivec_vcfux (operands[0], operands[1], const0_rtx)); + DONE; + } }") (define_expand "fix_trunc<mode><VEC_int>2" [(set (match_operand:<VEC_INT> 0 "vint_operand" "") (fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" " { - emit_insn (gen_altivec_vctsxs (operands[0], operands[1], const0_rtx)); - DONE; + if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) + { + emit_insn (gen_altivec_vctsxs (operands[0], operands[1], const0_rtx)); + DONE; + } }") (define_expand "fixuns_trunc<mode><VEC_int>2" [(set (match_operand:<VEC_INT> 0 "vint_operand" "") (unsigned_fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" " { - emit_insn (gen_altivec_vctuxs (operands[0], operands[1], const0_rtx)); - DONE; + if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) + { + emit_insn (gen_altivec_vctuxs (operands[0], operands[1], const0_rtx)); + DONE; + } }") @@ -526,7 +606,7 @@ (define_expand "vec_init<mode>" [(match_operand:VEC_E 0 "vlogical_operand" "") (match_operand:VEC_E 1 "" "")] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" + "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" { rs6000_expand_vector_init (operands[0], operands[1]); DONE; @@ -536,7 +616,7 @@ [(match_operand:VEC_E 0 "vlogical_operand" "") (match_operand:<VEC_base> 1 "register_operand" "") (match_operand 2 "const_int_operand" "")] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" + "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" { rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2])); DONE; @@ -546,7 +626,7 @@ [(match_operand:<VEC_base> 0 "register_operand" "") (match_operand:VEC_E 1 "vlogical_operand" "") (match_operand 2 "const_int_operand" "")] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" + "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" { rs6000_expand_vector_extract (operands[0], operands[1], INTVAL (operands[2])); @@ -568,7 +648,7 @@ (const_int 3) (const_int 1)])) (const_int 5)))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" "") (define_expand "vec_interleave_lowv4sf" @@ -585,23 +665,171 @@ (const_int 1) (const_int 3)])) (const_int 5)))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" + "") + +(define_expand "vec_interleave_highv2df" + [(set (match_operand:V2DF 0 "vfloat_operand" "") + (vec_concat:V2DF + (vec_select:DF (match_operand:V2DF 1 "vfloat_operand" "") + (parallel [(const_int 0)])) + (vec_select:DF (match_operand:V2DF 2 "vfloat_operand" "") + (parallel [(const_int 0)]))))] + "VECTOR_UNIT_VSX_P (V2DFmode)" + "") + +(define_expand "vec_interleave_lowv2df" + [(set (match_operand:V2DF 0 "vfloat_operand" "") + (vec_concat:V2DF + (vec_select:DF (match_operand:V2DF 1 "vfloat_operand" "") + (parallel [(const_int 1)])) + (vec_select:DF (match_operand:V2DF 2 "vfloat_operand" "") + (parallel [(const_int 1)]))))] + "VECTOR_UNIT_VSX_P (V2DFmode)" "") +;; Convert double word types to single word types +(define_expand "vec_pack_trunc_v2df" + [(match_operand:V4SF 0 "vfloat_operand" "") + (match_operand:V2DF 1 "vfloat_operand" "") + (match_operand:V2DF 2 "vfloat_operand" "")] + "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" +{ + rtx r1 = gen_reg_rtx (V4SFmode); + rtx r2 = gen_reg_rtx (V4SFmode); + + emit_insn (gen_vsx_xvcvdpsp (r1, operands[1])); + emit_insn (gen_vsx_xvcvdpsp (r2, operands[2])); + emit_insn (gen_vec_extract_evenv4sf (operands[0], r1, r2)); + DONE; +}) + +(define_expand "vec_pack_sfix_trunc_v2df" + [(match_operand:V4SI 0 "vint_operand" "") + (match_operand:V2DF 1 "vfloat_operand" "") + (match_operand:V2DF 2 "vfloat_operand" "")] + "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" +{ + rtx r1 = gen_reg_rtx (V4SImode); + rtx r2 = gen_reg_rtx (V4SImode); + + emit_insn (gen_vsx_xvcvdpsxws (r1, operands[1])); + emit_insn (gen_vsx_xvcvdpsxws (r2, operands[2])); + emit_insn (gen_vec_extract_evenv4si (operands[0], r1, r2)); + DONE; +}) + +(define_expand "vec_pack_ufix_trunc_v2df" + [(match_operand:V4SI 0 "vint_operand" "") + (match_operand:V2DF 1 "vfloat_operand" "") + (match_operand:V2DF 2 "vfloat_operand" "")] + "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" +{ + rtx r1 = gen_reg_rtx (V4SImode); + rtx r2 = gen_reg_rtx (V4SImode); + + emit_insn (gen_vsx_xvcvdpuxws (r1, operands[1])); + emit_insn (gen_vsx_xvcvdpuxws (r2, operands[2])); + emit_insn (gen_vec_extract_evenv4si (operands[0], r1, r2)); + DONE; +}) + +;; Convert single word types to double word +(define_expand "vec_unpacks_hi_v4sf" + [(match_operand:V2DF 0 "vfloat_operand" "") + (match_operand:V4SF 1 "vfloat_operand" "")] + "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" +{ + rtx reg = gen_reg_rtx (V4SFmode); + + emit_insn (gen_vec_interleave_highv4sf (reg, operands[1], operands[1])); + emit_insn (gen_vsx_xvcvspdp (operands[0], reg)); + DONE; +}) + +(define_expand "vec_unpacks_lo_v4sf" + [(match_operand:V2DF 0 "vfloat_operand" "") + (match_operand:V4SF 1 "vfloat_operand" "")] + "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" +{ + rtx reg = gen_reg_rtx (V4SFmode); + + emit_insn (gen_vec_interleave_lowv4sf (reg, operands[1], operands[1])); + emit_insn (gen_vsx_xvcvspdp (operands[0], reg)); + DONE; +}) + +(define_expand "vec_unpacks_float_hi_v4si" + [(match_operand:V2DF 0 "vfloat_operand" "") + (match_operand:V4SI 1 "vint_operand" "")] + "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" +{ + rtx reg = gen_reg_rtx (V4SImode); + + emit_insn (gen_vec_interleave_highv4si (reg, operands[1], operands[1])); + emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg)); + DONE; +}) + +(define_expand "vec_unpacks_float_lo_v4si" + [(match_operand:V2DF 0 "vfloat_operand" "") + (match_operand:V4SI 1 "vint_operand" "")] + "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" +{ + rtx reg = gen_reg_rtx (V4SImode); + + emit_insn (gen_vec_interleave_lowv4si (reg, operands[1], operands[1])); + emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg)); + DONE; +}) + +(define_expand "vec_unpacku_float_hi_v4si" + [(match_operand:V2DF 0 "vfloat_operand" "") + (match_operand:V4SI 1 "vint_operand" "")] + "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" +{ + rtx reg = gen_reg_rtx (V4SImode); + + emit_insn (gen_vec_interleave_highv4si (reg, operands[1], operands[1])); + emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg)); + DONE; +}) + +(define_expand "vec_unpacku_float_lo_v4si" + [(match_operand:V2DF 0 "vfloat_operand" "") + (match_operand:V4SI 1 "vint_operand" "")] + "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" +{ + rtx reg = gen_reg_rtx (V4SImode); + + emit_insn (gen_vec_interleave_lowv4si (reg, operands[1], operands[1])); + emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg)); + DONE; +}) + + ;; Align vector loads with a permute. (define_expand "vec_realign_load_<mode>" [(match_operand:VEC_K 0 "vlogical_operand" "") (match_operand:VEC_K 1 "vlogical_operand" "") (match_operand:VEC_K 2 "vlogical_operand" "") (match_operand:V16QI 3 "vlogical_operand" "")] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" + "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" { emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1], operands[2], operands[3])); DONE; }) +;; Under VSX, vectors of 4/8 byte alignments do not need to be aligned +;; since the load already handles it. +(define_expand "movmisalign<mode>" + [(set (match_operand:VEC_N 0 "vfloat_operand" "") + (match_operand:VEC_N 1 "vfloat_operand" ""))] + "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_ALLOW_MOVMISALIGN" + "") + ;; Vector shift left in bits. Currently supported ony for shift ;; amounts that can be expressed as byte shifts (divisible by 8). @@ -627,9 +855,18 @@ if (bitshift_val & 0x7) FAIL; byteshift_val = bitshift_val >> 3; - shift = gen_rtx_CONST_INT (QImode, byteshift_val); - insn = gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1], - shift); + if (TARGET_VSX && (byteshift_val & 0x3) == 0) + { + shift = gen_rtx_CONST_INT (QImode, byteshift_val >> 2); + insn = gen_vsx_xxsldwi_<mode> (operands[0], operands[1], operands[1], + shift); + } + else + { + shift = gen_rtx_CONST_INT (QImode, byteshift_val); + insn = gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1], + shift); + } emit_insn (insn); DONE; @@ -659,9 +896,18 @@ if (bitshift_val & 0x7) FAIL; byteshift_val = 16 - (bitshift_val >> 3); - shift = gen_rtx_CONST_INT (QImode, byteshift_val); - insn = gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1], - shift); + if (TARGET_VSX && (byteshift_val & 0x3) == 0) + { + shift = gen_rtx_CONST_INT (QImode, byteshift_val >> 2); + insn = gen_vsx_xxsldwi_<mode> (operands[0], operands[1], operands[1], + shift); + } + else + { + shift = gen_rtx_CONST_INT (QImode, byteshift_val); + insn = gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1], + shift); + } emit_insn (insn); DONE; diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md new file mode 100644 index 00000000000..c6aafa6fac0 --- /dev/null +++ b/gcc/config/rs6000/vsx.md @@ -0,0 +1,1339 @@ +;; VSX patterns. +;; Copyright (C) 2009 +;; Free Software Foundation, Inc. +;; Contributed by Michael Meissner <meissner@linux.vnet.ibm.com> + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; 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/>. + +;; Iterator for both scalar and vector floating point types supported by VSX +(define_mode_iterator VSX_B [DF V4SF V2DF]) + +;; Iterator for the 2 64-bit vector types +(define_mode_iterator VSX_D [V2DF V2DI]) + +;; Iterator for the 2 32-bit vector types +(define_mode_iterator VSX_W [V4SF V4SI]) + +;; Iterator for vector floating point types supported by VSX +(define_mode_iterator VSX_F [V4SF V2DF]) + +;; Iterator for logical types supported by VSX +(define_mode_iterator VSX_L [V16QI V8HI V4SI V2DI V4SF V2DF TI]) + +;; Iterator for memory move. Handle TImode specially to allow +;; it to use gprs as well as vsx registers. +(define_mode_iterator VSX_M [V16QI V8HI V4SI V2DI V4SF V2DF]) + +;; Iterator for types for load/store with update +(define_mode_iterator VSX_U [V16QI V8HI V4SI V2DI V4SF V2DF TI DF]) + +;; Map into the appropriate load/store name based on the type +(define_mode_attr VSm [(V16QI "vw4") + (V8HI "vw4") + (V4SI "vw4") + (V4SF "vw4") + (V2DF "vd2") + (V2DI "vd2") + (DF "d") + (TI "vw4")]) + +;; Map into the appropriate suffix based on the type +(define_mode_attr VSs [(V16QI "sp") + (V8HI "sp") + (V4SI "sp") + (V4SF "sp") + (V2DF "dp") + (V2DI "dp") + (DF "dp") + (SF "sp") + (TI "sp")]) + +;; Map the register class used +(define_mode_attr VSr [(V16QI "v") + (V8HI "v") + (V4SI "v") + (V4SF "wf") + (V2DI "wd") + (V2DF "wd") + (DF "ws") + (SF "d") + (TI "wd")]) + +;; Map the register class used for float<->int conversions +(define_mode_attr VSr2 [(V2DF "wd") + (V4SF "wf") + (DF "!f#r")]) + +(define_mode_attr VSr3 [(V2DF "wa") + (V4SF "wa") + (DF "!f#r")]) + +;; Map the register class for sp<->dp float conversions, destination +(define_mode_attr VSr4 [(SF "ws") + (DF "f") + (V2DF "wd") + (V4SF "v")]) + +;; Map the register class for sp<->dp float conversions, destination +(define_mode_attr VSr5 [(SF "ws") + (DF "f") + (V2DF "v") + (V4SF "wd")]) + +;; Same size integer type for floating point data +(define_mode_attr VSi [(V4SF "v4si") + (V2DF "v2di") + (DF "di")]) + +(define_mode_attr VSI [(V4SF "V4SI") + (V2DF "V2DI") + (DF "DI")]) + +;; Word size for same size conversion +(define_mode_attr VSc [(V4SF "w") + (V2DF "d") + (DF "d")]) + +;; Bitsize for DF load with update +(define_mode_attr VSbit [(SI "32") + (DI "64")]) + +;; Map into either s or v, depending on whether this is a scalar or vector +;; operation +(define_mode_attr VSv [(V16QI "v") + (V8HI "v") + (V4SI "v") + (V4SF "v") + (V2DI "v") + (V2DF "v") + (TI "v") + (DF "s")]) + +;; Appropriate type for add ops (and other simple FP ops) +(define_mode_attr VStype_simple [(V2DF "vecfloat") + (V4SF "vecfloat") + (DF "fp")]) + +(define_mode_attr VSfptype_simple [(V2DF "fp_addsub_d") + (V4SF "fp_addsub_s") + (DF "fp_addsub_d")]) + +;; Appropriate type for multiply ops +(define_mode_attr VStype_mul [(V2DF "vecfloat") + (V4SF "vecfloat") + (DF "dmul")]) + +(define_mode_attr VSfptype_mul [(V2DF "fp_mul_d") + (V4SF "fp_mul_s") + (DF "fp_mul_d")]) + +;; Appropriate type for divide ops. For now, just lump the vector divide with +;; the scalar divides +(define_mode_attr VStype_div [(V2DF "ddiv") + (V4SF "sdiv") + (DF "ddiv")]) + +(define_mode_attr VSfptype_div [(V2DF "fp_div_d") + (V4SF "fp_div_s") + (DF "fp_div_d")]) + +;; Appropriate type for sqrt ops. For now, just lump the vector sqrt with +;; the scalar sqrt +(define_mode_attr VStype_sqrt [(V2DF "dsqrt") + (V4SF "sdiv") + (DF "ddiv")]) + +(define_mode_attr VSfptype_sqrt [(V2DF "fp_sqrt_d") + (V4SF "fp_sqrt_s") + (DF "fp_sqrt_d")]) + +;; Iterator and modes for sp<->dp conversions +;; Because scalar SF values are represented internally as double, use the +;; V4SF type to represent this than SF. +(define_mode_iterator VSX_SPDP [DF V4SF V2DF]) + +(define_mode_attr VS_spdp_res [(DF "V4SF") + (V4SF "V2DF") + (V2DF "V4SF")]) + +(define_mode_attr VS_spdp_insn [(DF "xscvdpsp") + (V4SF "xvcvspdp") + (V2DF "xvcvdpsp")]) + +(define_mode_attr VS_spdp_type [(DF "fp") + (V4SF "vecfloat") + (V2DF "vecfloat")]) + +;; Map the scalar mode for a vector type +(define_mode_attr VS_scalar [(V2DF "DF") + (V2DI "DI") + (V4SF "SF") + (V4SI "SI") + (V8HI "HI") + (V16QI "QI")]) + +;; Appropriate type for load + update +(define_mode_attr VStype_load_update [(V16QI "vecload") + (V8HI "vecload") + (V4SI "vecload") + (V4SF "vecload") + (V2DI "vecload") + (V2DF "vecload") + (TI "vecload") + (DF "fpload")]) + +;; Appropriate type for store + update +(define_mode_attr VStype_store_update [(V16QI "vecstore") + (V8HI "vecstore") + (V4SI "vecstore") + (V4SF "vecstore") + (V2DI "vecstore") + (V2DF "vecstore") + (TI "vecstore") + (DF "fpstore")]) + +;; Constants for creating unspecs +(define_constants + [(UNSPEC_VSX_CONCAT 500) + (UNSPEC_VSX_CVDPSXWS 501) + (UNSPEC_VSX_CVDPUXWS 502) + (UNSPEC_VSX_CVSPDP 503) + (UNSPEC_VSX_CVSXWDP 504) + (UNSPEC_VSX_CVUXWDP 505) + (UNSPEC_VSX_CVSXDSP 506) + (UNSPEC_VSX_CVUXDSP 507) + (UNSPEC_VSX_CVSPSXDS 508) + (UNSPEC_VSX_CVSPUXDS 509) + (UNSPEC_VSX_MADD 510) + (UNSPEC_VSX_MSUB 511) + (UNSPEC_VSX_NMADD 512) + (UNSPEC_VSX_NMSUB 513) + (UNSPEC_VSX_RSQRTE 514) + (UNSPEC_VSX_TDIV 515) + (UNSPEC_VSX_TSQRT 516) + (UNSPEC_VSX_XXPERMDI 517) + (UNSPEC_VSX_SET 518) + (UNSPEC_VSX_ROUND_I 519) + (UNSPEC_VSX_ROUND_IC 520) + (UNSPEC_VSX_SLDWI 521)]) + +;; VSX moves +(define_insn "*vsx_mov<mode>" + [(set (match_operand:VSX_M 0 "nonimmediate_operand" "=Z,<VSr>,<VSr>,?Z,?wa,?wa,*o,*r,*r,<VSr>,?wa,v,wZ,v") + (match_operand:VSX_M 1 "input_operand" "<VSr>,Z,<VSr>,wa,Z,wa,r,o,r,j,j,W,v,wZ"))] + "VECTOR_MEM_VSX_P (<MODE>mode) + && (register_operand (operands[0], <MODE>mode) + || register_operand (operands[1], <MODE>mode))" +{ + switch (which_alternative) + { + case 0: + case 3: + return "stx<VSm>%U0x %x1,%y0"; + + case 1: + case 4: + return "lx<VSm>%U0x %x0,%y1"; + + case 2: + case 5: + return "xxlor %x0,%x1,%x1"; + + case 6: + case 7: + case 8: + return "#"; + + case 9: + case 10: + return "xxlxor %x0,%x0,%x0"; + + case 11: + return output_vec_const_move (operands); + + case 12: + return "stvx %1,%y0"; + + case 13: + return "lvx %0,%y1"; + + default: + gcc_unreachable (); + } +} + [(set_attr "type" "vecstore,vecload,vecsimple,vecstore,vecload,vecsimple,*,*,*,vecsimple,vecsimple,*,vecstore,vecload")]) + +;; Unlike other VSX moves, allow the GPRs, since a normal use of TImode is for +;; unions. However for plain data movement, slightly favor the vector loads +(define_insn "*vsx_movti" + [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,wa,wa,?o,?r,?r,wa,v,v,wZ") + (match_operand:TI 1 "input_operand" "wa,Z,wa,r,o,r,j,W,wZ,v"))] + "VECTOR_MEM_VSX_P (TImode) + && (register_operand (operands[0], TImode) + || register_operand (operands[1], TImode))" +{ + switch (which_alternative) + { + case 0: + return "stxvd2%U0x %x1,%y0"; + + case 1: + return "lxvd2%U0x %x0,%y1"; + + case 2: + return "xxlor %x0,%x1,%x1"; + + case 3: + case 4: + case 5: + return "#"; + + case 6: + return "xxlxor %x0,%x0,%x0"; + + case 7: + return output_vec_const_move (operands); + + case 8: + return "stvx %1,%y0"; + + case 9: + return "lvx %0,%y1"; + + default: + gcc_unreachable (); + } +} + [(set_attr "type" "vecstore,vecload,vecsimple,*,*,*,vecsimple,*,vecstore,vecload")]) + +;; Load/store with update +;; Define insns that do load or store with update. Because VSX only has +;; reg+reg addressing, pre-decrement or pre-increment is unlikely to be +;; generated. +;; +;; In all these cases, we use operands 0 and 1 for the register being +;; incremented because those are the operands that local-alloc will +;; tie and these are the pair most likely to be tieable (and the ones +;; that will benefit the most). + +(define_insn "*vsx_load<VSX_U:mode>_update_<P:mptrsize>" + [(set (match_operand:VSX_U 3 "vsx_register_operand" "=<VSr>,?wa") + (mem:VSX_U (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") + (match_operand:P 2 "gpc_reg_operand" "r,r")))) + (set (match_operand:P 0 "gpc_reg_operand" "=b,b") + (plus:P (match_dup 1) + (match_dup 2)))] + "<P:tptrsize> && TARGET_UPDATE && VECTOR_MEM_VSX_P (<MODE>mode)" + "lx<VSm>ux %x3,%0,%2" + [(set_attr "type" "<VSX_U:VStype_load_update>")]) + +(define_insn "*vsx_store<mode>_update_<P:mptrsize>" + [(set (mem:VSX_U (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") + (match_operand:P 2 "gpc_reg_operand" "r,r"))) + (match_operand:VSX_U 3 "gpc_reg_operand" "<VSr>,?wa")) + (set (match_operand:P 0 "gpc_reg_operand" "=b,b") + (plus:P (match_dup 1) + (match_dup 2)))] + "<P:tptrsize> && TARGET_UPDATE && VECTOR_MEM_VSX_P (<MODE>mode)" + "stx<VSm>ux %x3,%0,%2" + [(set_attr "type" "<VSX_U:VStype_store_update>")]) + +;; We may need to have a varient on the pattern for use in the prologue +;; that doesn't depend on TARGET_UPDATE. + + +;; VSX scalar and vector floating point arithmetic instructions +(define_insn "*vsx_add<mode>3" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (plus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>add<VSs> %x0,%x1,%x2" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "*vsx_sub<mode>3" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (minus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>sub<VSs> %x0,%x1,%x2" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "*vsx_mul<mode>3" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (mult:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>mul<VSs> %x0,%x1,%x2" + [(set_attr "type" "<VStype_mul>") + (set_attr "fp_type" "<VSfptype_mul>")]) + +(define_insn "*vsx_div<mode>3" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (div:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>div<VSs> %x0,%x1,%x2" + [(set_attr "type" "<VStype_div>") + (set_attr "fp_type" "<VSfptype_div>")]) + +;; *tdiv* instruction returning the FG flag +(define_expand "vsx_tdiv<mode>3_fg" + [(set (match_dup 3) + (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "") + (match_operand:VSX_B 2 "vsx_register_operand" "")] + UNSPEC_VSX_TDIV)) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (gt:SI (match_dup 3) + (const_int 0)))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" +{ + operands[3] = gen_reg_rtx (CCFPmode); +}) + +;; *tdiv* instruction returning the FE flag +(define_expand "vsx_tdiv<mode>3_fe" + [(set (match_dup 3) + (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "") + (match_operand:VSX_B 2 "vsx_register_operand" "")] + UNSPEC_VSX_TDIV)) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (eq:SI (match_dup 3) + (const_int 0)))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" +{ + operands[3] = gen_reg_rtx (CCFPmode); +}) + +(define_insn "*vsx_tdiv<mode>3_internal" + [(set (match_operand:CCFP 0 "cc_reg_operand" "=x,x") + (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")] + UNSPEC_VSX_TDIV))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>tdiv<VSs> %0,%x1,%x2" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "vsx_fre<mode>2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] + UNSPEC_FRES))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>re<VSs> %x0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "*vsx_neg<mode>2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (neg:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>neg<VSs> %x0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "*vsx_abs<mode>2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (abs:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>abs<VSs> %x0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "vsx_nabs<mode>2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (neg:VSX_B + (abs:VSX_B + (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa"))))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>nabs<VSs> %x0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "vsx_smax<mode>3" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (smax:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>max<VSs> %x0,%x1,%x2" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "*vsx_smin<mode>3" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (smin:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>min<VSs> %x0,%x1,%x2" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "*vsx_sqrt<mode>2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (sqrt:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>sqrt<VSs> %x0,%x1" + [(set_attr "type" "<VStype_sqrt>") + (set_attr "fp_type" "<VSfptype_sqrt>")]) + +(define_insn "vsx_rsqrte<mode>2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] + UNSPEC_VSX_RSQRTE))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>rsqrte<VSs> %x0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +;; *tsqrt* returning the fg flag +(define_expand "vsx_tsqrt<mode>2_fg" + [(set (match_dup 3) + (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")] + UNSPEC_VSX_TSQRT)) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (gt:SI (match_dup 3) + (const_int 0)))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" +{ + operands[3] = gen_reg_rtx (CCFPmode); +}) + +;; *tsqrt* returning the fe flag +(define_expand "vsx_tsqrt<mode>2_fe" + [(set (match_dup 3) + (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")] + UNSPEC_VSX_TSQRT)) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (eq:SI (match_dup 3) + (const_int 0)))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" +{ + operands[3] = gen_reg_rtx (CCFPmode); +}) + +(define_insn "*vsx_tsqrt<mode>2_internal" + [(set (match_operand:CCFP 0 "cc_reg_operand" "=x,x") + (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] + UNSPEC_VSX_TSQRT))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>tsqrt<VSs> %0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +;; Fused vector multiply/add instructions + +;; Note we have a pattern for the multiply/add operations that uses unspec and +;; does not check -mfused-madd to allow users to use these ops when they know +;; they want the fused multiply/add. + +(define_expand "vsx_fmadd<mode>4" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "") + (plus:VSX_B + (mult:VSX_B + (match_operand:VSX_B 1 "vsx_register_operand" "") + (match_operand:VSX_B 2 "vsx_register_operand" "")) + (match_operand:VSX_B 3 "vsx_register_operand" "")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" +{ + if (!TARGET_FUSED_MADD) + { + emit_insn (gen_vsx_fmadd<mode>4_2 (operands[0], operands[1], operands[2], + operands[3])); + DONE; + } +}) + +(define_insn "*vsx_fmadd<mode>4_1" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") + (plus:VSX_B + (mult:VSX_B + (match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")) + (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode) && TARGET_FUSED_MADD" + "@ + x<VSv>madda<VSs> %x0,%x1,%x2 + x<VSv>maddm<VSs> %x0,%x1,%x3 + x<VSv>madda<VSs> %x0,%x1,%x2 + x<VSv>maddm<VSs> %x0,%x1,%x3" + [(set_attr "type" "<VStype_mul>") + (set_attr "fp_type" "<VSfptype_mul>")]) + +(define_insn "vsx_fmadd<mode>4_2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") + (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0") + (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")] + UNSPEC_VSX_MADD))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "@ + x<VSv>madda<VSs> %x0,%x1,%x2 + x<VSv>maddm<VSs> %x0,%x1,%x3 + x<VSv>madda<VSs> %x0,%x1,%x2 + x<VSv>maddm<VSs> %x0,%x1,%x3" + [(set_attr "type" "<VStype_mul>") + (set_attr "fp_type" "<VSfptype_mul>")]) + +(define_expand "vsx_fmsub<mode>4" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "") + (minus:VSX_B + (mult:VSX_B + (match_operand:VSX_B 1 "vsx_register_operand" "") + (match_operand:VSX_B 2 "vsx_register_operand" "")) + (match_operand:VSX_B 3 "vsx_register_operand" "")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" +{ + if (!TARGET_FUSED_MADD) + { + emit_insn (gen_vsx_fmsub<mode>4_2 (operands[0], operands[1], operands[2], + operands[3])); + DONE; + } +}) + +(define_insn "*vsx_fmsub<mode>4_1" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") + (minus:VSX_B + (mult:VSX_B + (match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")) + (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode) && TARGET_FUSED_MADD" + "@ + x<VSv>msuba<VSs> %x0,%x1,%x2 + x<VSv>msubm<VSs> %x0,%x1,%x3 + x<VSv>msuba<VSs> %x0,%x1,%x2 + x<VSv>msubm<VSs> %x0,%x1,%x3" + [(set_attr "type" "<VStype_mul>") + (set_attr "fp_type" "<VSfptype_mul>")]) + +(define_insn "vsx_fmsub<mode>4_2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") + (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0") + (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")] + UNSPEC_VSX_MSUB))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "@ + x<VSv>msuba<VSs> %x0,%x1,%x2 + x<VSv>msubm<VSs> %x0,%x1,%x3 + x<VSv>msuba<VSs> %x0,%x1,%x2 + x<VSv>msubm<VSs> %x0,%x1,%x3" + [(set_attr "type" "<VStype_mul>") + (set_attr "fp_type" "<VSfptype_mul>")]) + +(define_expand "vsx_fnmadd<mode>4" + [(match_operand:VSX_B 0 "vsx_register_operand" "") + (match_operand:VSX_B 1 "vsx_register_operand" "") + (match_operand:VSX_B 2 "vsx_register_operand" "") + (match_operand:VSX_B 3 "vsx_register_operand" "")] + "VECTOR_UNIT_VSX_P (<MODE>mode)" +{ + if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)) + { + emit_insn (gen_vsx_fnmadd<mode>4_1 (operands[0], operands[1], + operands[2], operands[3])); + DONE; + } + else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)) + { + emit_insn (gen_vsx_fnmadd<mode>4_2 (operands[0], operands[1], + operands[2], operands[3])); + DONE; + } + else + { + emit_insn (gen_vsx_fnmadd<mode>4_3 (operands[0], operands[1], + operands[2], operands[3])); + DONE; + } +}) + +(define_insn "vsx_fnmadd<mode>4_1" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") + (neg:VSX_B + (plus:VSX_B + (mult:VSX_B + (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSr>,wa,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")) + (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa"))))] + "VECTOR_UNIT_VSX_P (<MODE>mode) && TARGET_FUSED_MADD + && HONOR_SIGNED_ZEROS (DFmode)" + "@ + x<VSv>nmadda<VSs> %x0,%x1,%x2 + x<VSv>nmaddm<VSs> %x0,%x1,%x3 + x<VSv>nmadda<VSs> %x0,%x1,%x2 + x<VSv>nmaddm<VSs> %x0,%x1,%x3" + [(set_attr "type" "<VStype_mul>") + (set_attr "fp_type" "<VSfptype_mul>")]) + +(define_insn "vsx_fnmadd<mode>4_2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") + (minus:VSX_B + (mult:VSX_B + (neg:VSX_B + (match_operand:VSX_B 1 "gpc_reg_operand" "<VSr>,<VSr>,wa,wa")) + (match_operand:VSX_B 2 "gpc_reg_operand" "<VSr>,0,wa,0")) + (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode) && TARGET_FUSED_MADD + && !HONOR_SIGNED_ZEROS (DFmode)" + "@ + x<VSv>nmadda<VSs> %x0,%x1,%x2 + x<VSv>nmaddm<VSs> %x0,%x1,%x3 + x<VSv>nmadda<VSs> %x0,%x1,%x2 + x<VSv>nmaddm<VSs> %x0,%x1,%x3" + [(set_attr "type" "<VStype_mul>") + (set_attr "fp_type" "<VSfptype_mul>")]) + +(define_insn "vsx_fnmadd<mode>4_3" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") + (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSr>,wa,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0") + (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")] + UNSPEC_VSX_NMADD))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "@ + x<VSv>nmadda<VSs> %x0,%x1,%x2 + x<VSv>nmaddm<VSs> %x0,%x1,%x3 + x<VSv>nmadda<VSs> %x0,%x1,%x2 + x<VSv>nmaddm<VSs> %x0,%x1,%x3" + [(set_attr "type" "<VStype_mul>") + (set_attr "fp_type" "<VSfptype_mul>")]) + +(define_expand "vsx_fnmsub<mode>4" + [(match_operand:VSX_B 0 "vsx_register_operand" "") + (match_operand:VSX_B 1 "vsx_register_operand" "") + (match_operand:VSX_B 2 "vsx_register_operand" "") + (match_operand:VSX_B 3 "vsx_register_operand" "")] + "VECTOR_UNIT_VSX_P (<MODE>mode)" +{ + if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)) + { + emit_insn (gen_vsx_fnmsub<mode>4_1 (operands[0], operands[1], + operands[2], operands[3])); + DONE; + } + else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)) + { + emit_insn (gen_vsx_fnmsub<mode>4_2 (operands[0], operands[1], + operands[2], operands[3])); + DONE; + } + else + { + emit_insn (gen_vsx_fnmsub<mode>4_3 (operands[0], operands[1], + operands[2], operands[3])); + DONE; + } +}) + +(define_insn "vsx_fnmsub<mode>4_1" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") + (neg:VSX_B + (minus:VSX_B + (mult:VSX_B + (match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")) + (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa"))))] + "VECTOR_UNIT_VSX_P (<MODE>mode) && TARGET_FUSED_MADD + && HONOR_SIGNED_ZEROS (DFmode)" + "@ + x<VSv>nmsuba<VSs> %x0,%x1,%x2 + x<VSv>nmsubm<VSs> %x0,%x1,%x3 + x<VSv>nmsuba<VSs> %x0,%x1,%x2 + x<VSv>nmsubm<VSs> %x0,%x1,%x3" + [(set_attr "type" "<VStype_mul>") + (set_attr "fp_type" "<VSfptype_mul>")]) + +(define_insn "vsx_fnmsub<mode>4_2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") + (minus:VSX_B + (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa") + (mult:VSX_B + (match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0"))))] + "VECTOR_UNIT_VSX_P (<MODE>mode) && TARGET_FUSED_MADD + && !HONOR_SIGNED_ZEROS (DFmode)" + "@ + x<VSv>nmsuba<VSs> %x0,%x1,%x2 + x<VSv>nmsubm<VSs> %x0,%x1,%x3 + x<VSv>nmsuba<VSs> %x0,%x1,%x2 + x<VSv>nmsubm<VSs> %x0,%x1,%x3" + [(set_attr "type" "<VStype_mul>") + (set_attr "fp_type" "<VSfptype_mul>")]) + +(define_insn "vsx_fnmsub<mode>4_3" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") + (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0") + (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")] + UNSPEC_VSX_NMSUB))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "@ + x<VSv>nmsuba<VSs> %x0,%x1,%x2 + x<VSv>nmsubm<VSs> %x0,%x1,%x3 + x<VSv>nmsuba<VSs> %x0,%x1,%x2 + x<VSv>nmsubm<VSs> %x0,%x1,%x3" + [(set_attr "type" "<VStype_mul>") + (set_attr "fp_type" "<VSfptype_mul>")]) + +;; Vector conditional expressions (no scalar version for these instructions) +(define_insn "vsx_eq<mode>" + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") + (eq:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "xvcmpeq<VSs> %x0,%x1,%x2" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "vsx_gt<mode>" + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") + (gt:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "xvcmpgt<VSs> %x0,%x1,%x2" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "*vsx_ge<mode>" + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") + (ge:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "xvcmpge<VSs> %x0,%x1,%x2" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +;; Floating point scalar compare +(define_insn "*vsx_cmpdf_internal1" + [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,?y") + (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "ws,wa") + (match_operand:DF 2 "gpc_reg_operand" "ws,wa")))] + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && VECTOR_UNIT_VSX_P (DFmode)" + "xscmpudp %0,%x1,%x2" + [(set_attr "type" "fpcompare")]) + +;; Compare vectors producing a vector result and a predicate, setting CR6 to +;; indicate a combined status +(define_insn "*vsx_eq_<mode>_p" + [(set (reg:CC 74) + (unspec:CC + [(eq:CC (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,?wa") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,?wa"))] + UNSPEC_PREDICATE)) + (set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") + (eq:VSX_F (match_dup 1) + (match_dup 2)))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "xvcmpeq<VSs>. %x0,%x1,%x2" + [(set_attr "type" "veccmp")]) + +(define_insn "*vsx_gt_<mode>_p" + [(set (reg:CC 74) + (unspec:CC + [(gt:CC (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,?wa") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,?wa"))] + UNSPEC_PREDICATE)) + (set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") + (gt:VSX_F (match_dup 1) + (match_dup 2)))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "xvcmpgt<VSs>. %x0,%x1,%x2" + [(set_attr "type" "veccmp")]) + +(define_insn "*vsx_ge_<mode>_p" + [(set (reg:CC 74) + (unspec:CC + [(ge:CC (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,?wa") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,?wa"))] + UNSPEC_PREDICATE)) + (set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") + (ge:VSX_F (match_dup 1) + (match_dup 2)))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "xvcmpge<VSs>. %x0,%x1,%x2" + [(set_attr "type" "veccmp")]) + +;; Vector select +(define_insn "*vsx_xxsel<mode>" + [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") + (if_then_else:VSX_L + (ne:CC (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,wa") + (const_int 0)) + (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,wa") + (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_MEM_VSX_P (<MODE>mode)" + "xxsel %x0,%x3,%x2,%x1" + [(set_attr "type" "vecperm")]) + +(define_insn "*vsx_xxsel<mode>_uns" + [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") + (if_then_else:VSX_L + (ne:CCUNS (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,wa") + (const_int 0)) + (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,wa") + (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_MEM_VSX_P (<MODE>mode)" + "xxsel %x0,%x3,%x2,%x1" + [(set_attr "type" "vecperm")]) + +;; Copy sign +(define_insn "vsx_copysign<mode>3" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (if_then_else:VSX_B + (ge:VSX_B (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa") + (match_operand:VSX_B 3 "zero_constant" "j,j")) + (abs:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")) + (neg:VSX_B (abs:VSX_B (match_dup 1)))))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>cpsgn<VSs> %x0,%x2,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +;; For the conversions, limit the register class for the integer value to be +;; the fprs because we don't want to add the altivec registers to movdi/movsi. +;; For the unsigned tests, there isn't a generic double -> unsigned conversion +;; in rs6000.md so don't test VECTOR_UNIT_VSX_P, just test against VSX. +(define_insn "vsx_float<VSi><mode>2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (float:VSX_B (match_operand:<VSI> 1 "vsx_register_operand" "<VSr2>,<VSr3>")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>cvsx<VSc><VSs> %x0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "vsx_floatuns<VSi><mode>2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (unsigned_float:VSX_B (match_operand:<VSI> 1 "vsx_register_operand" "<VSr2>,<VSr3>")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>cvux<VSc><VSs> %x0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "vsx_fix_trunc<mode><VSi>2" + [(set (match_operand:<VSI> 0 "vsx_register_operand" "=<VSr2>,?<VSr3>") + (fix:<VSI> (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>cv<VSs>sx<VSc>s %x0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "vsx_fixuns_trunc<mode><VSi>2" + [(set (match_operand:<VSI> 0 "vsx_register_operand" "=<VSr2>,?<VSr3>") + (unsigned_fix:<VSI> (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>cv<VSs>ux<VSc>s %x0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +;; Math rounding functions +(define_insn "vsx_x<VSv>r<VSs>i" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] + UNSPEC_VSX_ROUND_I))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>r<VSs>i %x0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "vsx_x<VSv>r<VSs>ic" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] + UNSPEC_VSX_ROUND_IC))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>r<VSs>ic %x0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "vsx_btrunc<mode>2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (fix:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>r<VSs>iz %x0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "*vsx_b2trunc<mode>2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] + UNSPEC_FRIZ))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>r<VSs>iz %x0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "vsx_floor<mode>2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] + UNSPEC_FRIM))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>r<VSs>im %x0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + +(define_insn "vsx_ceil<mode>2" + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") + (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] + UNSPEC_FRIP))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "x<VSv>r<VSs>ip %x0,%x1" + [(set_attr "type" "<VStype_simple>") + (set_attr "fp_type" "<VSfptype_simple>")]) + + +;; VSX convert to/from double vector + +;; Convert between single and double precision +;; Don't use xscvspdp and xscvdpsp for scalar conversions, since the normal +;; scalar single precision instructions internally use the double format. +;; Prefer the altivec registers, since we likely will need to do a vperm +(define_insn "vsx_<VS_spdp_insn>" + [(set (match_operand:<VS_spdp_res> 0 "vsx_register_operand" "=<VSr4>,?wa") + (unspec:<VS_spdp_res> [(match_operand:VSX_SPDP 1 "vsx_register_operand" "<VSr5>,wa")] + UNSPEC_VSX_CVSPDP))] + "VECTOR_UNIT_VSX_P (<MODE>mode)" + "<VS_spdp_insn> %x0,%x1" + [(set_attr "type" "<VS_spdp_type>")]) + +;; xscvspdp, represent the scalar SF type as V4SF +(define_insn "vsx_xscvspdp" + [(set (match_operand:DF 0 "vsx_register_operand" "=ws,?wa") + (unspec:DF [(match_operand:V4SF 1 "vsx_register_operand" "wa,wa")] + UNSPEC_VSX_CVSPDP))] + "VECTOR_UNIT_VSX_P (DFmode)" + "xscvspdp %x0,%x1" + [(set_attr "type" "fp")]) + +;; xscvdpsp used for splat'ing a scalar to V4SF, knowing that the internal SF +;; format of scalars is actually DF. +(define_insn "vsx_xscvdpsp_scalar" + [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa") + (unspec:V4SF [(match_operand:SF 1 "vsx_register_operand" "f")] + UNSPEC_VSX_CVSPDP))] + "VECTOR_UNIT_VSX_P (DFmode)" + "xscvdpsp %x0,%x1" + [(set_attr "type" "fp")]) + +;; Convert from 64-bit to 32-bit types +;; Note, favor the Altivec registers since the usual use of these instructions +;; is in vector converts and we need to use the Altivec vperm instruction. + +(define_insn "vsx_xvcvdpsxws" + [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa") + (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")] + UNSPEC_VSX_CVDPSXWS))] + "VECTOR_UNIT_VSX_P (V2DFmode)" + "xvcvdpsxws %x0,%x1" + [(set_attr "type" "vecfloat")]) + +(define_insn "vsx_xvcvdpuxws" + [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa") + (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")] + UNSPEC_VSX_CVDPUXWS))] + "VECTOR_UNIT_VSX_P (V2DFmode)" + "xvcvdpuxws %x0,%x1" + [(set_attr "type" "vecfloat")]) + +(define_insn "vsx_xvcvsxdsp" + [(set (match_operand:V4SI 0 "vsx_register_operand" "=wd,?wa") + (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wf,wa")] + UNSPEC_VSX_CVSXDSP))] + "VECTOR_UNIT_VSX_P (V2DFmode)" + "xvcvsxdsp %x0,%x1" + [(set_attr "type" "vecfloat")]) + +(define_insn "vsx_xvcvuxdsp" + [(set (match_operand:V4SI 0 "vsx_register_operand" "=wd,?wa") + (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wf,wa")] + UNSPEC_VSX_CVUXDSP))] + "VECTOR_UNIT_VSX_P (V2DFmode)" + "xvcvuxwdp %x0,%x1" + [(set_attr "type" "vecfloat")]) + +;; Convert from 32-bit to 64-bit types +(define_insn "vsx_xvcvsxwdp" + [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa") + (unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")] + UNSPEC_VSX_CVSXWDP))] + "VECTOR_UNIT_VSX_P (V2DFmode)" + "xvcvsxwdp %x0,%x1" + [(set_attr "type" "vecfloat")]) + +(define_insn "vsx_xvcvuxwdp" + [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa") + (unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")] + UNSPEC_VSX_CVUXWDP))] + "VECTOR_UNIT_VSX_P (V2DFmode)" + "xvcvuxwdp %x0,%x1" + [(set_attr "type" "vecfloat")]) + +(define_insn "vsx_xvcvspsxds" + [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa") + (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")] + UNSPEC_VSX_CVSPSXDS))] + "VECTOR_UNIT_VSX_P (V2DFmode)" + "xvcvspsxds %x0,%x1" + [(set_attr "type" "vecfloat")]) + +(define_insn "vsx_xvcvspuxds" + [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa") + (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")] + UNSPEC_VSX_CVSPUXDS))] + "VECTOR_UNIT_VSX_P (V2DFmode)" + "xvcvspuxds %x0,%x1" + [(set_attr "type" "vecfloat")]) + +;; Logical and permute operations +(define_insn "*vsx_and<mode>3" + [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") + (and:VSX_L + (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,?wa") + (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,?wa")))] + "VECTOR_MEM_VSX_P (<MODE>mode)" + "xxland %x0,%x1,%x2" + [(set_attr "type" "vecsimple")]) + +(define_insn "*vsx_ior<mode>3" + [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") + (ior:VSX_L (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,?wa") + (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,?wa")))] + "VECTOR_MEM_VSX_P (<MODE>mode)" + "xxlor %x0,%x1,%x2" + [(set_attr "type" "vecsimple")]) + +(define_insn "*vsx_xor<mode>3" + [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") + (xor:VSX_L + (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,?wa") + (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,?wa")))] + "VECTOR_MEM_VSX_P (<MODE>mode)" + "xxlxor %x0,%x1,%x2" + [(set_attr "type" "vecsimple")]) + +(define_insn "*vsx_one_cmpl<mode>2" + [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") + (not:VSX_L + (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,?wa")))] + "VECTOR_MEM_VSX_P (<MODE>mode)" + "xxlnor %x0,%x1,%x1" + [(set_attr "type" "vecsimple")]) + +(define_insn "*vsx_nor<mode>3" + [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") + (not:VSX_L + (ior:VSX_L + (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,?wa") + (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,?wa"))))] + "VECTOR_MEM_VSX_P (<MODE>mode)" + "xxlnor %x0,%x1,%x2" + [(set_attr "type" "vecsimple")]) + +(define_insn "*vsx_andc<mode>3" + [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") + (and:VSX_L + (not:VSX_L + (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,?wa")) + (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,?wa")))] + "VECTOR_MEM_VSX_P (<MODE>mode)" + "xxlandc %x0,%x1,%x2" + [(set_attr "type" "vecsimple")]) + + +;; Permute operations + +;; Build a V2DF/V2DI vector from two scalars +(define_insn "vsx_concat_<mode>" + [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa") + (unspec:VSX_D + [(match_operand:<VS_scalar> 1 "vsx_register_operand" "ws,wa") + (match_operand:<VS_scalar> 2 "vsx_register_operand" "ws,wa")] + UNSPEC_VSX_CONCAT))] + "VECTOR_MEM_VSX_P (<MODE>mode)" + "xxpermdi %x0,%x1,%x2,0" + [(set_attr "type" "vecperm")]) + +;; Special purpose concat using xxpermdi to glue two single precision values +;; together, relying on the fact that internally scalar floats are represented +;; as doubles. This is used to initialize a V4SF vector with 4 floats +(define_insn "vsx_concat_v2sf" + [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa") + (unspec:V2DF + [(match_operand:SF 1 "vsx_register_operand" "f,f") + (match_operand:SF 2 "vsx_register_operand" "f,f")] + UNSPEC_VSX_CONCAT))] + "VECTOR_MEM_VSX_P (V2DFmode)" + "xxpermdi %x0,%x1,%x2,0" + [(set_attr "type" "vecperm")]) + +;; Set the element of a V2DI/VD2F mode +(define_insn "vsx_set_<mode>" + [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa") + (unspec:VSX_D [(match_operand:VSX_D 1 "vsx_register_operand" "wd,wa") + (match_operand:<VS_scalar> 2 "vsx_register_operand" "ws,wa") + (match_operand:QI 3 "u5bit_cint_operand" "i,i")] + UNSPEC_VSX_SET))] + "VECTOR_MEM_VSX_P (<MODE>mode)" +{ + if (INTVAL (operands[3]) == 0) + return \"xxpermdi %x0,%x1,%x2,1\"; + else if (INTVAL (operands[3]) == 1) + return \"xxpermdi %x0,%x2,%x1,0\"; + else + gcc_unreachable (); +} + [(set_attr "type" "vecperm")]) + +;; Extract a DF/DI element from V2DF/V2DI +(define_insn "vsx_extract_<mode>" + [(set (match_operand:<VS_scalar> 0 "vsx_register_operand" "=ws,d,?wa") + (vec_select:<VS_scalar> (match_operand:VSX_D 1 "vsx_register_operand" "wd,wd,wa") + (parallel + [(match_operand:QI 2 "u5bit_cint_operand" "i,i,i")])))] + "VECTOR_MEM_VSX_P (<MODE>mode)" +{ + gcc_assert (UINTVAL (operands[2]) <= 1); + operands[3] = GEN_INT (INTVAL (operands[2]) << 1); + return \"xxpermdi %x0,%x1,%x1,%3\"; +} + [(set_attr "type" "vecperm")]) + +;; Optimize extracting element 0 from memory +(define_insn "*vsx_extract_<mode>_zero" + [(set (match_operand:<VS_scalar> 0 "vsx_register_operand" "=ws,d,?wa") + (vec_select:<VS_scalar> + (match_operand:VSX_D 1 "indexed_or_indirect_operand" "Z,Z,Z") + (parallel [(const_int 0)])))] + "VECTOR_MEM_VSX_P (<MODE>mode) && WORDS_BIG_ENDIAN" + "lxsd%U1x %x0,%y1" + [(set_attr "type" "fpload") + (set_attr "length" "4")]) + +;; General double word oriented permute, allow the other vector types for +;; optimizing the permute instruction. +(define_insn "vsx_xxpermdi_<mode>" + [(set (match_operand:VSX_L 0 "vsx_register_operand" "=wd,?wa") + (unspec:VSX_L [(match_operand:VSX_L 1 "vsx_register_operand" "wd,wa") + (match_operand:VSX_L 2 "vsx_register_operand" "wd,wa") + (match_operand:QI 3 "u5bit_cint_operand" "i,i")] + UNSPEC_VSX_XXPERMDI))] + "VECTOR_MEM_VSX_P (<MODE>mode)" + "xxpermdi %x0,%x1,%x2,%3" + [(set_attr "type" "vecperm")]) + +;; Varient of xxpermdi that is emitted by the vec_interleave functions +(define_insn "*vsx_xxpermdi2_<mode>" + [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd") + (vec_concat:VSX_D + (vec_select:<VS_scalar> + (match_operand:VSX_D 1 "vsx_register_operand" "wd") + (parallel + [(match_operand:QI 2 "u5bit_cint_operand" "i")])) + (vec_select:<VS_scalar> + (match_operand:VSX_D 3 "vsx_register_operand" "wd") + (parallel + [(match_operand:QI 4 "u5bit_cint_operand" "i")]))))] + "VECTOR_MEM_VSX_P (<MODE>mode)" +{ + gcc_assert ((UINTVAL (operands[2]) <= 1) && (UINTVAL (operands[4]) <= 1)); + operands[5] = GEN_INT (((INTVAL (operands[2]) & 1) << 1) + | (INTVAL (operands[4]) & 1)); + return \"xxpermdi %x0,%x1,%x3,%5\"; +} + [(set_attr "type" "vecperm")]) + +;; V2DF/V2DI splat +(define_insn "vsx_splat_<mode>" + [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,wd,wd,?wa,?wa,?wa") + (vec_duplicate:VSX_D + (match_operand:<VS_scalar> 1 "input_operand" "ws,f,Z,wa,wa,Z")))] + "VECTOR_MEM_VSX_P (<MODE>mode)" + "@ + xxpermdi %x0,%x1,%x1,0 + xxpermdi %x0,%x1,%x1,0 + lxvdsx %x0,%y1 + xxpermdi %x0,%x1,%x1,0 + xxpermdi %x0,%x1,%x1,0 + lxvdsx %x0,%y1" + [(set_attr "type" "vecperm,vecperm,vecload,vecperm,vecperm,vecload")]) + +;; V4SF/V4SI splat +(define_insn "vsx_xxspltw_<mode>" + [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa") + (vec_duplicate:VSX_W + (vec_select:<VS_scalar> + (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa") + (parallel + [(match_operand:QI 2 "u5bit_cint_operand" "i,i")]))))] + "VECTOR_MEM_VSX_P (<MODE>mode)" + "xxspltw %x0,%x1,%2" + [(set_attr "type" "vecperm")]) + +;; V4SF/V4SI interleave +(define_insn "vsx_xxmrghw_<mode>" + [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa") + (vec_merge:VSX_W + (vec_select:VSX_W + (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa") + (parallel [(const_int 0) + (const_int 2) + (const_int 1) + (const_int 3)])) + (vec_select:VSX_W + (match_operand:VSX_W 2 "vsx_register_operand" "wf,wa") + (parallel [(const_int 2) + (const_int 0) + (const_int 3) + (const_int 1)])) + (const_int 5)))] + "VECTOR_MEM_VSX_P (<MODE>mode)" + "xxmrghw %x0,%x1,%x2" + [(set_attr "type" "vecperm")]) + +(define_insn "vsx_xxmrglw_<mode>" + [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa") + (vec_merge:VSX_W + (vec_select:VSX_W + (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa") + (parallel [(const_int 2) + (const_int 0) + (const_int 3) + (const_int 1)])) + (vec_select:VSX_W + (match_operand:VSX_W 2 "vsx_register_operand" "wf,?wa") + (parallel [(const_int 0) + (const_int 2) + (const_int 1) + (const_int 3)])) + (const_int 5)))] + "VECTOR_MEM_VSX_P (<MODE>mode)" + "xxmrglw %x0,%x1,%x2" + [(set_attr "type" "vecperm")]) + +;; Shift left double by word immediate +(define_insn "vsx_xxsldwi_<mode>" + [(set (match_operand:VSX_L 0 "vsx_register_operand" "=wa") + (unspec:VSX_L [(match_operand:VSX_L 1 "vsx_register_operand" "wa") + (match_operand:VSX_L 2 "vsx_register_operand" "wa") + (match_operand:QI 3 "u5bit_cint_operand" "i")] + UNSPEC_VSX_SLDWI))] + "VECTOR_MEM_VSX_P (<MODE>mode)" + "xxsldwi %x0,%x1,%x2,%3" + [(set_attr "type" "vecperm")]) diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 2329138cf1f..8b9ad5aedb5 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -125,6 +125,6 @@ extern void s390_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, int); #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 rtx s390_function_value (const_tree, const_tree, enum machine_mode); #endif /* RTX_CODE */ #endif /* TREE_CODE */ diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index f5b2fa73d1f..25203ab52b6 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -8343,17 +8343,36 @@ s390_return_in_memory (const_tree type, const_tree fundecl ATTRIBUTE_UNUSED) return true; } +/* Function arguments and return values are promoted to word size. */ + +static enum machine_mode +s390_promote_function_mode (const_tree type, enum machine_mode mode, + int *punsignedp, + const_tree fntype ATTRIBUTE_UNUSED, + int for_return ATTRIBUTE_UNUSED) +{ + if (INTEGRAL_MODE_P (mode) + && GET_MODE_SIZE (mode) < UNITS_PER_WORD) + { + if (POINTER_TYPE_P (type)) + *punsignedp = POINTERS_EXTEND_UNSIGNED; + return Pmode; + } + + return mode; +} + /* Define where to return a (scalar) value of type TYPE. If TYPE is null, define where to return a (scalar) value of mode MODE from a libcall. */ rtx -s390_function_value (const_tree type, enum machine_mode mode) +s390_function_value (const_tree type, const_tree fn, enum machine_mode mode) { if (type) { int unsignedp = TYPE_UNSIGNED (type); - mode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1); + mode = promote_function_mode (type, TYPE_MODE (type), &unsignedp, fn, 1); } gcc_assert (GET_MODE_CLASS (mode) == MODE_INT || SCALAR_FLOAT_MODE_P (mode)); @@ -9998,10 +10017,8 @@ s390_reorg (void) #undef TARGET_GIMPLIFY_VA_ARG_EXPR #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE s390_promote_function_mode #undef TARGET_PASS_BY_REFERENCE #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index f34b7f22567..4772367eee5 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -216,13 +216,6 @@ extern int s390_arch_flags; #endif #define MAX_BITS_PER_WORD 64 -/* Function arguments and return values are promoted to word size. */ -#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \ -if (INTEGRAL_MODE_P (MODE) && \ - GET_MODE_SIZE (MODE) < UNITS_PER_WORD) { \ - (MODE) = Pmode; \ - } - /* Allocation boundary (in *bits*) for storing arguments in argument list. */ #define PARM_BOUNDARY (TARGET_64BIT ? 64 : 32) @@ -697,10 +690,10 @@ CUMULATIVE_ARGS; /* Scalar return values. */ #define FUNCTION_VALUE(VALTYPE, FUNC) \ - s390_function_value ((VALTYPE), VOIDmode) + s390_function_value ((VALTYPE), (FUNC), VOIDmode) #define LIBCALL_VALUE(MODE) \ - s390_function_value (NULL, (MODE)) + s390_function_value (NULL, NULL, (MODE)) /* Only gpr 2 and fpr 0 are ever used as return registers. */ #define FUNCTION_VALUE_REGNO_P(N) ((N) == 2 || (N) == 16) diff --git a/gcc/config/score/score.c b/gcc/config/score/score.c index b75f3cfaebf..0241383fc86 100644 --- a/gcc/config/score/score.c +++ b/gcc/config/score/score.c @@ -89,11 +89,8 @@ #undef TARGET_ASM_OUTPUT_MI_THUNK #define TARGET_ASM_OUTPUT_MI_THUNK score_output_mi_thunk -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true - -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true diff --git a/gcc/config/score/score3.c b/gcc/config/score/score3.c index 4258d29e525..385620d33d6 100644 --- a/gcc/config/score/score3.c +++ b/gcc/config/score/score3.c @@ -859,15 +859,14 @@ score3_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode, VALTYPE is the return type and MODE is VOIDmode. For libcalls, VALTYPE is null and MODE is the mode of the return value. */ rtx -score3_function_value (tree valtype, tree func ATTRIBUTE_UNUSED, - enum machine_mode mode) +score3_function_value (tree valtype, tree func, enum machine_mode mode) { if (valtype) { int unsignedp; mode = TYPE_MODE (valtype); unsignedp = TYPE_UNSIGNED (valtype); - mode = promote_mode (valtype, mode, &unsignedp, 1); + mode = promote_function_mode (valtype, mode, &unsignedp, func, 1); } return gen_rtx_REG (mode, RT_REGNUM); } diff --git a/gcc/config/score/score7.c b/gcc/config/score/score7.c index 9ab6ebd3004..368ac03a3ba 100644 --- a/gcc/config/score/score7.c +++ b/gcc/config/score/score7.c @@ -850,15 +850,14 @@ score7_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode, VALTYPE is the return type and MODE is VOIDmode. For libcalls, VALTYPE is null and MODE is the mode of the return value. */ rtx -score7_function_value (tree valtype, tree func ATTRIBUTE_UNUSED, - enum machine_mode mode) +score7_function_value (tree valtype, tree func, enum machine_mode mode) { if (valtype) { int unsignedp; mode = TYPE_MODE (valtype); unsignedp = TYPE_UNSIGNED (valtype); - mode = promote_mode (valtype, mode, &unsignedp, 1); + mode = promote_function_mode (valtype, mode, &unsignedp, func, 1); } return gen_rtx_REG (mode, RT_REGNUM); } diff --git a/gcc/config/sh/linux-atomic.asm b/gcc/config/sh/linux-atomic.asm index fd3a7720e99..04b7d507c15 100644 --- a/gcc/config/sh/linux-atomic.asm +++ b/gcc/config/sh/linux-atomic.asm @@ -54,10 +54,10 @@ ATOMIC_TEST_AND_SET (2,w,extu.w) ATOMIC_TEST_AND_SET (4,l,mov) #define ATOMIC_COMPARE_AND_SWAP(N,T,EXTS,EXT) \ - .global __sync_compare_and_swap_##N; \ - HIDDEN_FUNC(__sync_compare_and_swap_##N); \ + .global __sync_val_compare_and_swap_##N; \ + HIDDEN_FUNC(__sync_val_compare_and_swap_##N); \ .align 2; \ -__sync_compare_and_swap_##N:; \ +__sync_val_compare_and_swap_##N:; \ mova 1f, r0; \ EXTS r5, r5; \ mov r15, r1; \ @@ -69,7 +69,7 @@ __sync_compare_and_swap_##N:; \ 1: mov r1, r15; \ rts; \ EXT r2, r0; \ - ENDFUNC(__sync_compare_and_swap_##N) + ENDFUNC(__sync_val_compare_and_swap_##N) ATOMIC_COMPARE_AND_SWAP (1,b,exts.b,extu.b) ATOMIC_COMPARE_AND_SWAP (2,w,exts.w,extu.w) diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 788b0fe1391..337be6b0df0 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -257,6 +257,11 @@ 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, gimple_seq *, gimple_seq *); +static enum machine_mode sh_promote_function_mode (const_tree type, + enum machine_mode, + int *punsignedp, + const_tree funtype, + int for_return); static bool sh_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static bool sh_callee_copies (CUMULATIVE_ARGS *, enum machine_mode, @@ -437,10 +442,8 @@ static const struct attribute_spec sh_attribute_table[] = #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES sh_promote_prototypes -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS sh_promote_prototypes -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN sh_promote_prototypes +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE sh_promote_function_mode #undef TARGET_STRUCT_VALUE_RTX #define TARGET_STRUCT_VALUE_RTX sh_struct_value_rtx @@ -6743,13 +6746,19 @@ sh_expand_prologue (void) /* If we're supposed to switch stacks at function entry, do so now. */ if (sp_switch_attr) { + rtx lab, newsrc; /* The argument specifies a variable holding the address of the stack the interrupt function should switch to/from at entry/exit. */ + tree arg = TREE_VALUE ( TREE_VALUE (sp_switch_attr)); const char *s - = ggc_strdup (TREE_STRING_POINTER (TREE_VALUE (sp_switch_attr))); + = ggc_strdup (TREE_STRING_POINTER (arg)); rtx sp_switch = gen_rtx_SYMBOL_REF (Pmode, s); - emit_insn (gen_sp_switch_1 (sp_switch)); + lab = add_constant (sp_switch, SImode, 0); + newsrc = gen_rtx_LABEL_REF (VOIDmode, lab); + newsrc = gen_const_mem (SImode, newsrc); + + emit_insn (gen_sp_switch_1 (newsrc)); } d = calc_live_regs (&live_regs_mask); @@ -7890,6 +7899,16 @@ sh_dwarf_register_span (rtx reg) DBX_REGISTER_NUMBER (regno)))); } +static enum machine_mode +sh_promote_function_mode (const_tree type, enum machine_mode mode, + int *punsignedp, const_tree funtype, int for_return) +{ + if (sh_promote_prototypes (funtype)) + return promote_mode (type, mode, punsignedp); + else + return mode; +} + bool sh_promote_prototypes (const_tree type) { diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index baba1d98057..52cbe703458 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -404,6 +404,8 @@ static int get_some_local_dynamic_name_1 (rtx *, void *); static bool sparc_rtx_costs (rtx, int, int, int *, bool); static bool sparc_promote_prototypes (const_tree); static rtx sparc_struct_value_rtx (tree, int); +static enum machine_mode sparc_promote_function_mode (const_tree, enum machine_mode, + int *, const_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); @@ -524,17 +526,8 @@ static bool fpu_option_set = false; #undef TARGET_ADDRESS_COST #define TARGET_ADDRESS_COST hook_int_rtx_bool_0 -/* This is only needed for TARGET_ARCH64, but since PROMOTE_FUNCTION_MODE is a - no-op for TARGET_ARCH32 this is ok. Otherwise we'd need to add a runtime - test for this value. */ -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true - -/* This is only needed for TARGET_ARCH64, but since PROMOTE_FUNCTION_MODE is a - no-op for TARGET_ARCH32 this is ok. Otherwise we'd need to add a runtime - test for this value. */ -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE sparc_promote_function_mode #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES sparc_promote_prototypes @@ -4642,6 +4635,36 @@ sparc_promote_prototypes (const_tree fntype ATTRIBUTE_UNUSED) return TARGET_ARCH32 ? true : false; } +/* Handle promotion of pointer and integer arguments. */ + +static enum machine_mode +sparc_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, + enum machine_mode mode, + int *punsignedp ATTRIBUTE_UNUSED, + const_tree fntype ATTRIBUTE_UNUSED, + int for_return ATTRIBUTE_UNUSED) +{ + if (POINTER_TYPE_P (type)) + { + *punsignedp = POINTERS_EXTEND_UNSIGNED; + return Pmode; + } + + /* For TARGET_ARCH64 we need this, as we don't have instructions + for arithmetic operations which do zero/sign extension at the same time, + so without this we end up with a srl/sra after every assignment to an + user variable, which means very very bad code. */ + + if (TARGET_ARCH64 + && GET_MODE_CLASS (mode) == MODE_INT + && GET_MODE_SIZE (mode) < UNITS_PER_WORD) + return word_mode; + + return mode; +} + + + /* Handle the TARGET_STRICT_ARGUMENT_NAMING target hook. */ static bool @@ -5784,7 +5807,8 @@ function_value (const_tree type, enum machine_mode mode, int incoming_p) mclass = MODE_INT; } - /* This must match PROMOTE_FUNCTION_MODE. */ + /* This must match sparc_promote_function_mode. + ??? Maybe 32-bit pointers should actually remain in Pmode? */ else if (mclass == MODE_INT && GET_MODE_SIZE (mode) < UNITS_PER_WORD) mode = word_mode; } diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 31c74095f75..3b713611f84 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -636,16 +636,6 @@ extern struct sparc_cpu_select sparc_select[]; if ptr_mode and Pmode are the same. */ #define POINTERS_EXTEND_UNSIGNED 1 -/* For TARGET_ARCH64 we need this, as we don't have instructions - for arithmetic operations which do zero/sign extension at the same time, - so without this we end up with a srl/sra after every assignment to an - user variable, which means very very bad code. */ -#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \ -if (TARGET_ARCH64 \ - && GET_MODE_CLASS (MODE) == MODE_INT \ - && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \ - (MODE) = word_mode; - /* Allocation boundary (in *bits*) for storing arguments in argument list. */ #define PARM_BOUNDARY (TARGET_ARCH64 ? 64 : 32) diff --git a/gcc/config/stormy16/stormy16.c b/gcc/config/stormy16/stormy16.c index 2e646f98d4c..06b96c7b8ce 100644 --- a/gcc/config/stormy16/stormy16.c +++ b/gcc/config/stormy16/stormy16.c @@ -2640,10 +2640,8 @@ xstormy16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) #undef TARGET_GIMPLIFY_VA_ARG_EXPR #define TARGET_GIMPLIFY_VA_ARG_EXPR xstormy16_gimplify_va_arg_expr -#undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true -#undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index 38f300aeef7..77ba2d9d017 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -185,10 +185,8 @@ static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] = #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 -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h index a9987c7609f..84d320bc95b 100644 --- a/gcc/config/xtensa/xtensa.h +++ b/gcc/config/xtensa/xtensa.h @@ -582,7 +582,7 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER]; /* Define how to find the value returned by a library function assuming the value has mode MODE. Because we have defined - TARGET_PROMOTE_FUNCTION_RETURN that returns true, we have to + TARGET_PROMOTE_FUNCTION_MODE to promote everything, we have to perform the same promotions as PROMOTE_MODE. */ #define XTENSA_LIBCALL_VALUE(MODE, OUTGOINGP) \ gen_rtx_REG ((GET_MODE_CLASS (MODE) == MODE_INT \ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c52c6da89e1..970b6dc5152 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,60 @@ +2009-08-04 Dodji Seketeli <dodji@redhat.com> + + PR c++/39987 + * pt.c (tsubst_default_argument): Let access checks of the + default argument happen in the context of the current function. + +2009-08-04 Manuel López-Ibáñez <manu@gcc.gnu.org> + + PR c++/16696 + * call.c (build_new_op): Only try prefix operator if -fpermissive, + otherwise just error. + +2009-08-04 Dodji Seketeli <dodji@redhat.com> + + PR debug/39706 + * error.c (lang_decl_name): Print qualified names for decls + in namespace scope. + +2009-08-03 Jason Merrill <jason@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + PR c++/40948 + * init.c (build_vec_init): Look through a TARGET_EXPR around a + CONSTRUCTOR. + +2009-07-31 Jason Merrill <jason@redhat.com> + Douglas Gregor <doug.gregor@gmail.com> + + Remove implicit binding of lvalues to rvalue references (N2831) + * call.c (convert_class_to_reference): Binding an lvalue to an + rvalue reference is bad. If the user-defined conversion is bad, + set bad_p before merging conversions. + (maybe_handle_ref_bind): Don't push down bad_p. + (reference_binding): Binding an lvalue to an rvalue reference is bad. + (convert_like_real): Give a helpful error about binding lvalue + to rvalue reference. + (reference_related_p): No longer static. + * typeck.c (build_typed_address): New. + (build_static_cast_1): Add static_cast from lvalue to &&. + * cp-tree.h: Adjust. + +2009-07-31 Jason Merrill <jason@redhat.com> + + * call.c (reference_binding): Rename lvalue_p to is_lvalue. + Do direct binding of "rvalues" in memory to rvalue references. + * tree.c (lvalue_p_1): Can't be both non-addressable lvalue and + "rvalue" in memory. + * typeck.c (build_static_cast_1): Do direct binding of memory + "rvalues" to rvalue references. + * cvt.c (cp_fold_convert): New. + * cp-tree.h: Declare it. + +2009-07-31 Jason Merrill <jason@redhat.com> + + * typeck.c (build_address): Do fold away ADDR_EXPR of INDIRECT_REF. + * tree.c (rvalue): Use cp_build_qualified_type, not TYPE_MAIN_VARIANT. + 2009-07-29 Jason Merrill <jason@redhat.com> PR c++/14912 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index a457b9c7cfd..5304feb2d44 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -190,7 +190,6 @@ static struct z_candidate *add_candidate conversion **, tree, tree, int); static tree source_type (conversion *); static void add_warning (struct z_candidate *, struct z_candidate *); -static bool reference_related_p (tree, tree); static bool reference_compatible_p (tree, tree); static conversion *convert_class_to_reference (tree, tree, tree, int); static conversion *direct_reference_binding (tree, conversion *); @@ -971,7 +970,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, /* Returns nonzero if T1 is reference-related to T2. */ -static bool +bool reference_related_p (tree t1, tree t2) { t1 = TYPE_MAIN_VARIANT (t1); @@ -1115,6 +1114,11 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags) = TYPE_REF_IS_RVALUE (TREE_TYPE (TREE_TYPE (cand->fn))) == TYPE_REF_IS_RVALUE (reference_type); cand->second_conv->bad_p |= cand->convs[0]->bad_p; + + /* Don't allow binding of lvalues to rvalue references. */ + if (TYPE_REF_IS_RVALUE (reference_type) + && !TYPE_REF_IS_RVALUE (TREE_TYPE (TREE_TYPE (cand->fn)))) + cand->second_conv->bad_p = true; } } } @@ -1142,13 +1146,13 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags) build_identity_conv (TREE_TYPE (expr), expr)); conv->cand = cand; + if (cand->viable == -1) + conv->bad_p = true; + /* Merge it with the standard conversion sequence from the conversion function's return type to the desired type. */ cand->second_conv = merge_conversion_sequences (conv, cand->second_conv); - if (cand->viable == -1) - conv->bad_p = true; - return cand->second_conv; } @@ -1210,7 +1214,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) tree tfrom; bool related_p; bool compatible_p; - cp_lvalue_kind lvalue_p = clk_none; + cp_lvalue_kind is_lvalue = clk_none; if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr)) { @@ -1223,7 +1227,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) if (TREE_CODE (from) == REFERENCE_TYPE) { /* Anything with reference type is an lvalue. */ - lvalue_p = clk_ordinary; + is_lvalue = clk_ordinary; from = TREE_TYPE (from); } @@ -1240,11 +1244,11 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) } } - if (lvalue_p == clk_none && expr) - lvalue_p = real_lvalue_p (expr); + if (is_lvalue == clk_none && expr) + is_lvalue = real_lvalue_p (expr); tfrom = from; - if ((lvalue_p & clk_bitfield) != 0) + if ((is_lvalue & clk_bitfield) != 0) tfrom = unlowered_expr_type (expr); /* Figure out whether or not the types are reference-related and @@ -1261,12 +1265,15 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) /* Directly bind reference when target expression's type is compatible with the reference and expression is an lvalue. In DR391, the wording in [8.5.3/5 dcl.init.ref] is changed to also require direct bindings for - const and rvalue references to rvalues of compatible class type. */ + const and rvalue references to rvalues of compatible class type. + We should also do direct bindings for non-class "rvalues" derived from + rvalue references. */ if (compatible_p - && (lvalue_p - || (!(flags & LOOKUP_NO_TEMP_BIND) - && (CP_TYPE_CONST_NON_VOLATILE_P(to) || TYPE_REF_IS_RVALUE (rto)) - && CLASS_TYPE_P (from)))) + && (is_lvalue + || (((CP_TYPE_CONST_NON_VOLATILE_P (to) + && !(flags & LOOKUP_NO_TEMP_BIND)) + || TYPE_REF_IS_RVALUE (rto)) + && (CLASS_TYPE_P (from) || (expr && lvalue_p (expr)))))) { /* [dcl.init.ref] @@ -1293,10 +1300,10 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto); else conv->rvaluedness_matches_p - = (TYPE_REF_IS_RVALUE (rto) == !lvalue_p); + = (TYPE_REF_IS_RVALUE (rto) == !is_lvalue); - if ((lvalue_p & clk_bitfield) != 0 - || ((lvalue_p & clk_packed) != 0 && !TYPE_PACKED (to))) + if ((is_lvalue & clk_bitfield) != 0 + || ((is_lvalue & clk_packed) != 0 && !TYPE_PACKED (to))) /* For the purposes of overload resolution, we ignore the fact this expression is a bitfield or packed field. (In particular, [over.ics.ref] says specifically that a function with a @@ -1310,6 +1317,11 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) actually occurs. */ conv->need_temporary_p = true; + /* Don't allow binding of lvalues to rvalue references. */ + if (is_lvalue && TYPE_REF_IS_RVALUE (rto) + && !(flags & LOOKUP_PREFER_RVALUE)) + conv->bad_p = true; + return conv; } /* [class.conv.fct] A conversion function is never used to convert a @@ -4248,13 +4260,23 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, if (!(complain & tf_error)) return error_mark_node; - /* Look for an `operator++ (int)'. If they didn't have - one, then we fall back to the old way of doing things. */ + /* Look for an `operator++ (int)'. Pre-1985 C++ didn't + distinguish between prefix and postfix ++ and + operator++() was used for both, so we allow this with + -fpermissive. */ if (flags & LOOKUP_COMPLAIN) - permerror (input_location, "no %<%D(int)%> declared for postfix %qs, " - "trying prefix operator instead", - fnname, - operator_name_info[code].name); + { + const char *msg = (flag_permissive) + ? G_("no %<%D(int)%> declared for postfix %qs," + " trying prefix operator instead") + : G_("no %<%D(int)%> declared for postfix %qs"); + permerror (input_location, msg, fnname, + operator_name_info[code].name); + } + + if (!flag_permissive) + return error_mark_node; + if (code == POSTINCREMENT_EXPR) code = PREINCREMENT_EXPR; else @@ -4963,6 +4985,19 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, { tree ref_type = totype; + if (convs->bad_p && TYPE_REF_IS_RVALUE (ref_type) + && real_lvalue_p (expr)) + { + if (complain & tf_error) + { + error ("cannot bind %qT lvalue to %qT", + TREE_TYPE (expr), totype); + if (fn) + error (" initializing argument %P of %q+D", argnum, fn); + } + return error_mark_node; + } + /* If necessary, create a temporary. VA_ARG_EXPR and CONSTRUCTOR expressions are special cases @@ -6461,7 +6496,6 @@ maybe_handle_ref_bind (conversion **ics) conversion *old_ics = *ics; *ics = old_ics->u.next; (*ics)->user_conv_p = old_ics->user_conv_p; - (*ics)->bad_p = old_ics->bad_p; return old_ics; } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ea08fbc53bf..5fe7937012e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4272,6 +4272,7 @@ extern tree set_up_extended_ref_temp (tree, tree, tree *, tree *); extern tree initialize_reference (tree, tree, tree, tree *); extern tree make_temporary_var_for_ref_to_temp (tree, tree); extern tree strip_top_quals (tree); +extern bool reference_related_p (tree, tree); extern tree perform_implicit_conversion (tree, tree, tsubst_flags_t); extern tree perform_implicit_conversion_flags (tree, tree, tsubst_flags_t, int); extern tree perform_direct_initialization_if_possible (tree, tree, bool, @@ -4345,6 +4346,7 @@ extern tree force_rvalue (tree); extern tree ocp_convert (tree, tree, int, int); extern tree cp_convert (tree, tree); extern tree cp_convert_and_check (tree, tree); +extern tree cp_fold_convert (tree, tree); extern tree convert_to_void (tree, const char */*implicit context*/, tsubst_flags_t); extern tree convert_force (tree, tree, int); @@ -5067,6 +5069,7 @@ extern tree cp_build_binary_op (location_t, #define cxx_sizeof(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, true) extern tree build_ptrmemfunc_access_expr (tree, tree); extern tree build_address (tree); +extern tree build_typed_address (tree, tree); extern tree build_nop (tree, tree); extern tree non_reference (tree); extern tree lookup_anon_field (tree, tree); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index c42d21cb3cd..cdc6a10a825 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -539,7 +539,16 @@ force_rvalue (tree expr) return expr; } + +/* Fold away simple conversions, but make sure the result is an rvalue. */ + +tree +cp_fold_convert (tree type, tree expr) +{ + return rvalue (fold_convert (type, expr)); +} + /* C++ conversions, preference to static cast conversions. */ tree diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 25a05801622..239ff9ac07c 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -2331,7 +2331,10 @@ lang_decl_name (tree decl, int v, bool translate) reinit_cxx_pp (); pp_translate_identifiers (cxx_pp) = translate; - if (v == 1 && DECL_CLASS_SCOPE_P (decl)) + if (v == 1 + && (DECL_CLASS_SCOPE_P (decl) + || (DECL_NAMESPACE_SCOPE_P (decl) + && CP_DECL_CONTEXT (decl) != global_namespace))) { dump_type (CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER); pp_cxx_colon_colon (cxx_pp); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 3da8ab8464c..4462428321b 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2695,6 +2695,12 @@ build_vec_init (tree base, tree maxindex, tree init, gcc_assert (!init); inner_elt_type = strip_array_types (type); + + /* Look through the TARGET_EXPR around a compound literal. */ + if (init && TREE_CODE (init) == TARGET_EXPR + && TREE_CODE (TARGET_EXPR_INITIAL (init)) == CONSTRUCTOR) + init = TARGET_EXPR_INITIAL (init); + if (init && TREE_CODE (atype) == ARRAY_TYPE && (from_array == 2 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ed45324b9ab..c0c61c5a426 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8253,11 +8253,11 @@ tsubst_default_argument (tree fn, tree type, tree arg) cp_function_chain->x_current_class_ref = saved_class_ref; } - pop_access_scope (fn); - /* Make sure the default argument is reasonable. */ arg = check_default_argument (type, arg); + pop_access_scope (fn); + return arg; } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 83869c17a1b..9e194fca444 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -214,10 +214,14 @@ lvalue_p_1 (const_tree ref) /* Otherwise, it's an lvalue, and it has all the odd properties contributed by either operand. */ op1_lvalue_kind = op1_lvalue_kind | op2_lvalue_kind; - /* It's not an ordinary lvalue if it involves either a bit-field or - a class rvalue. */ + /* It's not an ordinary lvalue if it involves any other kind. */ if ((op1_lvalue_kind & ~clk_ordinary) != clk_none) op1_lvalue_kind &= ~clk_ordinary; + /* It can't be both a pseudo-lvalue and a non-addressable lvalue. + A COND_EXPR of those should be wrapped in a TARGET_EXPR. */ + if ((op1_lvalue_kind & (clk_rvalueref|clk_class)) + && (op1_lvalue_kind & (clk_bitfield|clk_packed))) + op1_lvalue_kind = clk_none; return op1_lvalue_kind; } @@ -530,7 +534,7 @@ rvalue (tree expr) Non-class rvalues always have cv-unqualified types. */ type = TREE_TYPE (expr); if (!CLASS_TYPE_P (type) && cp_type_quals (type)) - type = TYPE_MAIN_VARIANT (type); + type = cp_build_qualified_type (type, TYPE_UNQUALIFIED); /* We need to do this for rvalue refs as well to get the right answer from decltype; see c++/36628. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 5b3b3ed1395..404eafedce4 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4276,21 +4276,31 @@ condition_conversion (tree expr) return t; } -/* Return an ADDR_EXPR giving the address of T. This function - attempts no optimizations or simplifications; it is a low-level - primitive. */ +/* Returns the address of T. This function will fold away + ADDR_EXPR of INDIRECT_REF. */ tree build_address (tree t) { - tree addr; - if (error_operand_p (t) || !cxx_mark_addressable (t)) return error_mark_node; + t = build_fold_addr_expr (t); + if (TREE_CODE (t) != ADDR_EXPR) + t = rvalue (t); + return t; +} - addr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t); +/* Returns the address of T with type TYPE. */ - return addr; +tree +build_typed_address (tree t, tree type) +{ + if (error_operand_p (t) || !cxx_mark_addressable (t)) + return error_mark_node; + t = build_fold_addr_expr_with_type (t, type); + if (TREE_CODE (t) != ADDR_EXPR) + t = rvalue (t); + return t; } /* Return a NOP_EXPR converting EXPR to TYPE. */ @@ -5309,7 +5319,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, if (TREE_CODE (type) == REFERENCE_TYPE && CLASS_TYPE_P (TREE_TYPE (type)) && CLASS_TYPE_P (intype) - && real_lvalue_p (expr) + && (TYPE_REF_IS_RVALUE (type) || real_lvalue_p (expr)) && DERIVED_FROM_P (intype, TREE_TYPE (type)) && can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)), build_pointer_type (TYPE_MAIN_VARIANT @@ -5335,7 +5345,19 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, base, /*nonnull=*/false); /* Convert the pointer to a reference -- but then remember that there are no expressions with reference type in C++. */ - return convert_from_reference (build_nop (type, expr)); + return convert_from_reference (cp_fold_convert (type, expr)); + } + + /* "An lvalue of type cv1 T1 can be cast to type rvalue reference to + cv2 T2 if cv2 T2 is reference-compatible with cv1 T1 (8.5.3)." */ + if (TREE_CODE (type) == REFERENCE_TYPE + && TYPE_REF_IS_RVALUE (type) + && real_lvalue_p (expr) + && reference_related_p (TREE_TYPE (type), intype) + && (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype))) + { + expr = build_typed_address (expr, type); + return convert_from_reference (expr); } orig = expr; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index c1a78fdfae1..fed7c2b9539 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7322,7 +7322,7 @@ instructions, but allow the compiler to schedule those calls. * MIPS Loongson Built-in Functions:: * Other MIPS Built-in Functions:: * picoChip Built-in Functions:: -* PowerPC AltiVec Built-in Functions:: +* PowerPC AltiVec/VSX Built-in Functions:: * SPARC VIS Built-in Functions:: * SPU Built-in Functions:: @end menu @@ -9800,7 +9800,7 @@ GCC defines the preprocessor macro @code{___GCC_HAVE_BUILTIN_MIPS_CACHE} when this function is available. @end table -@node PowerPC AltiVec Built-in Functions +@node PowerPC AltiVec/VSX Built-in Functions @subsection PowerPC AltiVec Built-in Functions GCC provides an interface for the PowerPC family of processors to access @@ -9826,6 +9826,19 @@ vector bool int vector float @end smallexample +If @option{-mvsx} is used the following additional vector types are +implemented. + +@smallexample +vector unsigned long +vector signed long +vector double +@end smallexample + +The long types are only implemented for 64-bit code generation, and +the long type is only used in the floating point/integer conversion +instructions. + GCC's implementation of the high-level language interface available from C and C++ code differs from Motorola's documentation in several ways. @@ -10091,6 +10104,8 @@ vector signed char vec_vavgsb (vector signed char, vector signed char); vector unsigned char vec_vavgub (vector unsigned char, vector unsigned char); +vector float vec_copysign (vector float); + vector float vec_ceil (vector float); vector signed int vec_cmpb (vector float, vector float); @@ -11693,6 +11708,92 @@ int vec_any_numeric (vector float); int vec_any_out (vector float, vector float); @end smallexample +If the vector/scalar (VSX) instruction set is available, the following +additional functions are available: + +@smallexample +vector double vec_abs (vector double); +vector double vec_add (vector double, vector double); +vector double vec_and (vector double, vector double); +vector double vec_and (vector double, vector bool long); +vector double vec_and (vector bool long, vector double); +vector double vec_andc (vector double, vector double); +vector double vec_andc (vector double, vector bool long); +vector double vec_andc (vector bool long, vector double); +vector double vec_ceil (vector double); +vector bool long vec_cmpeq (vector double, vector double); +vector bool long vec_cmpge (vector double, vector double); +vector bool long vec_cmpgt (vector double, vector double); +vector bool long vec_cmple (vector double, vector double); +vector bool long vec_cmplt (vector double, vector double); +vector float vec_div (vector float, vector float); +vector double vec_div (vector double, vector double); +vector double vec_floor (vector double); +vector double vec_madd (vector double, vector double, vector double); +vector double vec_max (vector double, vector double); +vector double vec_min (vector double, vector double); +vector float vec_msub (vector float, vector float, vector float); +vector double vec_msub (vector double, vector double, vector double); +vector float vec_mul (vector float, vector float); +vector double vec_mul (vector double, vector double); +vector float vec_nearbyint (vector float); +vector double vec_nearbyint (vector double); +vector float vec_nmadd (vector float, vector float, vector float); +vector double vec_nmadd (vector double, vector double, vector double); +vector double vec_nmsub (vector double, vector double, vector double); +vector double vec_nor (vector double, vector double); +vector double vec_or (vector double, vector double); +vector double vec_or (vector double, vector bool long); +vector double vec_or (vector bool long, vector double); +vector double vec_perm (vector double, + vector double, + vector unsigned char); +vector float vec_rint (vector float); +vector double vec_rint (vector double); +vector double vec_sel (vector double, vector double, vector bool long); +vector double vec_sel (vector double, vector double, vector unsigned long); +vector double vec_sub (vector double, vector double); +vector float vec_sqrt (vector float); +vector double vec_sqrt (vector double); +vector double vec_trunc (vector double); +vector double vec_xor (vector double, vector double); +vector double vec_xor (vector double, vector bool long); +vector double vec_xor (vector bool long, vector double); +int vec_all_eq (vector double, vector double); +int vec_all_ge (vector double, vector double); +int vec_all_gt (vector double, vector double); +int vec_all_le (vector double, vector double); +int vec_all_lt (vector double, vector double); +int vec_all_nan (vector double); +int vec_all_ne (vector double, vector double); +int vec_all_nge (vector double, vector double); +int vec_all_ngt (vector double, vector double); +int vec_all_nle (vector double, vector double); +int vec_all_nlt (vector double, vector double); +int vec_all_numeric (vector double); +int vec_any_eq (vector double, vector double); +int vec_any_ge (vector double, vector double); +int vec_any_gt (vector double, vector double); +int vec_any_le (vector double, vector double); +int vec_any_lt (vector double, vector double); +int vec_any_nan (vector double); +int vec_any_ne (vector double, vector double); +int vec_any_nge (vector double, vector double); +int vec_any_ngt (vector double, vector double); +int vec_any_nle (vector double, vector double); +int vec_any_nlt (vector double, vector double); +int vec_any_numeric (vector double); +@end smallexample + +GCC provides a few other builtins on Powerpc to access certain instructions: +@smallexample +float __builtin_recipdivf (float, float); +float __builtin_rsqrtf (float); +double __builtin_recipdiv (double, double); +long __builtin_bpermd (long, long); +int __builtin_bswap16 (int); +@end smallexample + @node SPARC VIS Built-in Functions @subsection SPARC VIS Built-in Functions diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index c256ddeb174..a4bb385da4c 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -346,7 +346,8 @@ Objective-C and Objective-C++ Dialects}. -fira-region=@var{region} -fira-coalesce -fno-ira-share-save-slots @gol -fno-ira-share-spill-slots -fira-verbose=@var{n} @gol -fivopts -fkeep-inline-functions -fkeep-static-consts @gol --floop-block -floop-interchange -floop-strip-mine @gol +-floop-block -floop-interchange -floop-strip-mine -fgraphite-identity @gol +-floop-parallelize-all @gol -fmerge-all-constants -fmerge-constants -fmodulo-sched @gol -fmodulo-sched-allow-regmoves -fmove-loop-invariants -fmudflap @gol -fmudflapir -fmudflapth -fno-branch-count-reg -fno-default-inline @gol @@ -738,7 +739,8 @@ See RS/6000 and PowerPC Options. -maltivec -mno-altivec @gol -mpowerpc-gpopt -mno-powerpc-gpopt @gol -mpowerpc-gfxopt -mno-powerpc-gfxopt @gol --mmfcrf -mno-mfcrf -mpopcntb -mno-popcntb -mfprnd -mno-fprnd @gol +-mmfcrf -mno-mfcrf -mpopcntb -mno-popcntb -mpopcntd -mno-popcntd @gol +-mfprnd -mno-fprnd @gol -mcmpb -mno-cmpb -mmfpgpr -mno-mfpgpr -mhard-dfp -mno-hard-dfp @gol -mnew-mnemonics -mold-mnemonics @gol -mfull-toc -mminimal-toc -mno-fp-in-toc -mno-sum-in-toc @gol @@ -752,7 +754,7 @@ See RS/6000 and PowerPC Options. -mstrict-align -mno-strict-align -mrelocatable @gol -mno-relocatable -mrelocatable-lib -mno-relocatable-lib @gol -mtoc -mno-toc -mlittle -mlittle-endian -mbig -mbig-endian @gol --mdynamic-no-pic -maltivec -mswdiv @gol +-mdynamic-no-pic -maltivec -mswdiv @gol -mprioritize-restricted-insns=@var{priority} @gol -msched-costly-dep=@var{dependence_type} @gol -minsert-sched-nops=@var{scheme} @gol @@ -6591,6 +6593,21 @@ code transformation, GCC has to be configured with @option{--with-ppl} and @option{--with-cloog} to enable the Graphite loop transformation infrastructure. +@item -fgraphite-identity +@opindex fgraphite-identity +Enable the identity transformation for graphite. For every SCoP we generate +the polyhedral representation and transform it back to gimple. Using +@option{-fgraphite-identity} we can check the costs or benefits of the +GIMPLE -> GRAPHITE -> GIMPLE transformation. Some minimal optimizations +are also performed by the code generator CLooG, like index splitting and +dead code elimination in loops. + +@item -floop-parallelize-all +Use the Graphite data dependence analysis to identify loops that can +be parallelized. Parallelize all the loops that can be analyzed to +not contain loop carried dependences without checking that it is +profitable to parallelize the loops. + @item -fcheck-data-deps @opindex fcheck-data-deps Compare the results of several data dependence analyzers. This option @@ -14116,6 +14133,8 @@ These @samp{-m} options are defined for the IBM RS/6000 and PowerPC: @itemx -mno-mfcrf @itemx -mpopcntb @itemx -mno-popcntb +@itemx -mpopcntd +@itemx -mno-popcntd @itemx -mfprnd @itemx -mno-fprnd @itemx -mcmpb @@ -14140,6 +14159,8 @@ These @samp{-m} options are defined for the IBM RS/6000 and PowerPC: @opindex mno-mfcrf @opindex mpopcntb @opindex mno-popcntb +@opindex mpopcntd +@opindex mno-popcntd @opindex mfprnd @opindex mno-fprnd @opindex mcmpb @@ -14189,6 +14210,9 @@ The @option{-mpopcntb} option allows GCC to generate the popcount and double precision FP reciprocal estimate instruction implemented on the POWER5 processor and other processors that support the PowerPC V2.02 architecture. +The @option{-mpopcntd} option allows GCC to generate the popcount +instruction implemented on the POWER7 processor and other processors +that support the PowerPC V2.06 architecture. The @option{-mfprnd} option allows GCC to generate the FP round to integer instructions implemented on the POWER5+ processor and other processors that support the PowerPC V2.03 architecture. @@ -14267,9 +14291,9 @@ The @option{-mcpu} options automatically enable or disable the following options: @gccoptlist{-maltivec -mfprnd -mhard-float -mmfcrf -mmultiple @gol --mnew-mnemonics -mpopcntb -mpower -mpower2 -mpowerpc64 @gol +-mnew-mnemonics -mpopcntb -mpopcntd -mpower -mpower2 -mpowerpc64 @gol -mpowerpc-gpopt -mpowerpc-gfxopt -msingle-float -mdouble-float @gol --msimple-fpu -mstring -mmulhw -mdlmzb -mmfpgpr} +-msimple-fpu -mstring -mmulhw -mdlmzb -mmfpgpr -mvsx} The particular options set for any particular CPU will vary between compiler versions, depending on what setting seems to produce optimal @@ -14370,6 +14394,14 @@ instructions. This option has been deprecated. Use @option{-mspe} and @option{-mno-spe} instead. +@item -mvsx +@itemx -mno-vsx +@opindex mvsx +@opindex mno-vsx +Generate code that uses (does not use) vector/scalar (VSX) +instructions, and also enable the use of built-in functions that allow +more direct access to the VSX instruction set. + @item -mfloat-gprs=@var{yes/single/double/no} @itemx -mfloat-gprs @opindex mfloat-gprs diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index d9dca7a87ce..0e516b09fc0 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -1916,7 +1916,19 @@ Floating point register (containing 64-bit value) Floating point register (containing 32-bit value) @item v -Vector register +Altivec vector register + +@item wd +VSX vector register to hold vector double data + +@item wf +VSX vector register to hold vector float data + +@item ws +VSX vector register to hold scalar float data + +@item wa +Any VSX register @item h @samp{MQ}, @samp{CTR}, or @samp{LINK} register @@ -2029,6 +2041,9 @@ AND masks that can be performed by two rldic@{l, r@} instructions @item W Vector constant that does not require memory +@item j +Vector constant that is all zeros. + @end table @item Intel 386---@file{config/i386/constraints.md} diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 8157714e1f6..bb4f61b9e83 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -1039,27 +1039,20 @@ sign-extend the result to 64 bits. On such machines, set Do not define this macro if it would never modify @var{m}. @end defmac -@defmac PROMOTE_FUNCTION_MODE -Like @code{PROMOTE_MODE}, but is applied to outgoing function arguments or -function return values, as specified by @code{TARGET_PROMOTE_FUNCTION_ARGS} -and @code{TARGET_PROMOTE_FUNCTION_RETURN}, respectively. - -The default is @code{PROMOTE_MODE}. -@end defmac - -@deftypefn {Target Hook} bool TARGET_PROMOTE_FUNCTION_ARGS (tree @var{fntype}) -This target hook should return @code{true} if the promotion described by -@code{PROMOTE_FUNCTION_MODE} should be done for outgoing function -arguments. -@end deftypefn - -@deftypefn {Target Hook} bool TARGET_PROMOTE_FUNCTION_RETURN (tree @var{fntype}) -This target hook should return @code{true} if the promotion described by -@code{PROMOTE_FUNCTION_MODE} should be done for the return value of -functions. - -If this target hook returns @code{true}, @code{TARGET_FUNCTION_VALUE} -must perform the same promotions done by @code{PROMOTE_FUNCTION_MODE}. +@deftypefn {Target Hook} enum machine_mode TARGET_PROMOTE_FUNCTION_MODE (tree @var{type}, enum machine_mode @var{mode}, int *@var{punsignedp}, tree @var{funtype}, int @var{for_return}) +Like @code{PROMOTE_MODE}, but it is applied to outgoing function arguments or +function return values. The target hook should return the new mode +and possibly change @code{*@var{punsignedp}} if the promotion should +change signedness. This function is called only for scalar @emph{or +pointer} types. + +The default is to not promote arguments and return values. You can +also define the hook to @code{default_promote_function_mode_always_promote} +if you would like to apply the same rules given by @code{PROMOTE_MODE}. + +@var{for_return} allows to distinguish the promotion of arguments and +return values. If this target hook promotes return values, +@code{TARGET_FUNCTION_VALUE} must perform the same promotions done here. @end deftypefn @defmac PARM_BOUNDARY diff --git a/gcc/explow.c b/gcc/explow.c index 198df220fbd..5176d1f918f 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -749,63 +749,96 @@ copy_to_suggested_reg (rtx x, rtx target, enum machine_mode mode) return temp; } -/* Return the mode to use to store a scalar of TYPE and MODE. +/* Return the mode to use to pass or return a scalar of TYPE and MODE. PUNSIGNEDP points to the signedness of the type and may be adjusted to show what signedness to use on extension operations. - FOR_CALL is nonzero if this call is promoting args for a call. */ + FOR_RETURN is nonzero if the caller is promoting the return value + of FNDECL, else it is for promoting args. */ -#if defined(PROMOTE_MODE) && !defined(PROMOTE_FUNCTION_MODE) -#define PROMOTE_FUNCTION_MODE PROMOTE_MODE -#endif +enum machine_mode +promote_function_mode (const_tree type, enum machine_mode mode, int *punsignedp, + const_tree funtype, int for_return) +{ + switch (TREE_CODE (type)) + { + case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE: + case REAL_TYPE: case OFFSET_TYPE: case FIXED_POINT_TYPE: + case POINTER_TYPE: case REFERENCE_TYPE: + return targetm.calls.promote_function_mode (type, mode, punsignedp, funtype, + for_return); + + default: + return mode; + } +} +/* Return the mode to use to store a scalar of TYPE and MODE. + PUNSIGNEDP points to the signedness of the type and may be adjusted + to show what signedness to use on extension operations. */ enum machine_mode -promote_mode (const_tree type, enum machine_mode mode, int *punsignedp, - int for_call ATTRIBUTE_UNUSED) +promote_mode (const_tree type ATTRIBUTE_UNUSED, enum machine_mode mode, + int *punsignedp ATTRIBUTE_UNUSED) { + /* FIXME: this is the same logic that was there until GCC 4.4, but we + probably want to test POINTERS_EXTEND_UNSIGNED even if PROMOTE_MODE + is not defined. The affected targets are M32C, S390, SPARC. */ +#ifdef PROMOTE_MODE const enum tree_code code = TREE_CODE (type); int unsignedp = *punsignedp; -#ifndef PROMOTE_MODE - if (! for_call) - return mode; -#endif - switch (code) { -#ifdef PROMOTE_FUNCTION_MODE case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE: case REAL_TYPE: case OFFSET_TYPE: case FIXED_POINT_TYPE: -#ifdef PROMOTE_MODE - if (for_call) - { -#endif - PROMOTE_FUNCTION_MODE (mode, unsignedp, type); -#ifdef PROMOTE_MODE - } - else - { - PROMOTE_MODE (mode, unsignedp, type); - } -#endif + PROMOTE_MODE (mode, unsignedp, type); + *punsignedp = unsignedp; + return mode; break; -#endif #ifdef POINTERS_EXTEND_UNSIGNED case REFERENCE_TYPE: case POINTER_TYPE: - mode = Pmode; - unsignedp = POINTERS_EXTEND_UNSIGNED; + *punsignedp = POINTERS_EXTEND_UNSIGNED; + return Pmode; break; #endif default: - break; + return mode; } - - *punsignedp = unsignedp; +#else return mode; +#endif } + + +/* Use one of promote_mode or promote_function_mode to find the promoted + mode of DECL. If PUNSIGNEDP is not NULL, store there the unsignedness + of DECL after promotion. */ + +enum machine_mode +promote_decl_mode (const_tree decl, int *punsignedp) +{ + tree type = TREE_TYPE (decl); + int unsignedp = TYPE_UNSIGNED (type); + enum machine_mode mode = DECL_MODE (decl); + enum machine_mode pmode; + + if (TREE_CODE (decl) == RESULT_DECL) + pmode = promote_function_mode (type, mode, &unsignedp, + TREE_TYPE (current_function_decl), 1); + else if (TREE_CODE (decl) == PARM_DECL) + pmode = promote_function_mode (type, mode, &unsignedp, + TREE_TYPE (current_function_decl), 0); + else + pmode = promote_mode (type, mode, &unsignedp); + + if (punsignedp) + *punsignedp = unsignedp; + return pmode; +} + /* Adjust the stack pointer by ADJUST (an rtx for a number of bytes). This pops when ADJUST is positive. ADJUST need not be constant. */ diff --git a/gcc/expr.c b/gcc/expr.c index aafa1aaca4a..08c747ecffb 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -5435,13 +5435,11 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size) enum machine_mode mode; HOST_WIDE_INT bitsize; HOST_WIDE_INT bitpos; - int unsignedp; rtx xtarget = target; if (cleared && initializer_zerop (value)) continue; - unsignedp = TYPE_UNSIGNED (elttype); mode = TYPE_MODE (elttype); if (mode == BLKmode) bitsize = (host_integerp (TYPE_SIZE (elttype), 1) @@ -5497,14 +5495,10 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size) tree exit_cond; expand_normal (hi_index); - unsignedp = TYPE_UNSIGNED (domain); index = build_decl (EXPR_LOCATION (exp), VAR_DECL, NULL_TREE, domain); - - index_r - = gen_reg_rtx (promote_mode (domain, DECL_MODE (index), - &unsignedp, 0)); + index_r = gen_reg_rtx (promote_decl_mode (index, NULL)); SET_DECL_RTL (index, index_r); store_expr (lo_index, index_r, 0, false); @@ -7429,9 +7423,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, /* Get the signedness used for this variable. Ensure we get the same mode we got when the variable was declared. */ - pmode = promote_mode (type, DECL_MODE (exp), &unsignedp, - (TREE_CODE (exp) == RESULT_DECL - || TREE_CODE (exp) == PARM_DECL) ? 1 : 0); + pmode = promote_decl_mode (exp, &unsignedp); gcc_assert (GET_MODE (decl_rtl) == pmode); temp = gen_lowpart_SUBREG (mode, decl_rtl); diff --git a/gcc/expr.h b/gcc/expr.h index caf965e9412..8e23aecb4b9 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -719,8 +719,17 @@ extern rtx force_reg (enum machine_mode, rtx); /* Return given rtx, copied into a new temp reg if it was in memory. */ extern rtx force_not_mem (rtx); +/* Return mode and signedness to use when an argument or result in the + given mode is promoted. */ +extern enum machine_mode promote_function_mode (const_tree, enum machine_mode, int *, + const_tree, int); + +/* Return mode and signedness to use when an object in the given mode + is promoted. */ +extern enum machine_mode promote_mode (const_tree, enum machine_mode, int *); + /* Return mode and signedness to use when object is promoted. */ -extern enum machine_mode promote_mode (const_tree, enum machine_mode, int *, int); +enum machine_mode promote_decl_mode (const_tree, int *); /* Remove some bytes from the stack. An rtx says how many. */ extern void adjust_stack (rtx); diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index f89a8af3e38..5924892e777 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,76 @@ +2009-08-04 Tobias Burnus <burnus@net-b.de> + + PR fortran/40949 + * trans-types.c (gfc_get_function_type): Fix typelist of + functions without argument. + +2009-08-04 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/40875 + * decl.c (add_init_expr_to_sym): Character symbols can only be + initialized with character expressions. + +2009-08-02 Janus Weil <janus@gcc.gnu.org> + + PR fortran/40881 + * decl.c (match_char_length): Warn about old-style character length + declarations. + * match.c (match_arithmetic_if,gfc_match_if): Modify warning message + for arithmetic if. + (gfc_match_goto): Warn about computed gotos. + (gfc_match_return): Warn about alternate return. + (gfc_match_st_function): Warn about statement functions. + * resolve.c (resolve_fl_procedure): Modify warning message for + assumed-length character functions. + +2009-08-01 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/40011 + * error.c : Add static flag 'warnings_not_errors'. + (gfc_error): If 'warnings_not_errors' is set, branch to code + from gfc_warning. + (gfc_clear_error): Reset 'warnings_not_errors'. + (gfc_errors_to_warnings): New function. + * options.c (gfc_post_options): If pedantic and flag_whole_file + change the latter to a value of 2. + * parse.c (parse_module): Add module namespace to gsymbol. + (resolve_all_program_units): New function. + (clean_up_modules): New function. + (translate_all_program_units): New function. + (gfc_parse_file): If whole_file, do not clean up module right + away and add derived types to namespace derived types. In + addition, call the three new functions above. + * resolve.c (not_in_recursive): New function. + (not_entry_self_reference): New function. + (resolve_global_procedure): Symbol must not be IFSRC_UNKNOWN, + procedure must not be in the course of being resolved and + must return false for the two new functions. Pack away the + current derived type list before calling gfc_resolve for the + gsymbol namespace. It is unconditionally an error if the ranks + of the reference and ther procedure do not match. Convert + errors to warnings during call to gfc_procedure_use if not + pedantic or legacy. + (gfc_resolve): Set namespace resolved flag to -1 during + resolution and store current cs_base. + * trans-decl.c (gfc_get_symbol_decl): If whole_file compilation + substitute a use associated variable, if it is available in a + gsymbolnamespace. + (gfc_get_extern_function_decl): If the procedure is use assoc, + do not attempt to find it in a gsymbol because it could be an + interface. If the symbol exists in a module namespace, return + its backend_decl. + * trans-expr.c (gfc_trans_scalar_assign): If a derived type + assignment, set the rhs TYPE_MAIN_VARIANT to that of the rhs. + * trans-types.c (copy_dt_decls_ifequal): Add 'from_gsym' as a + boolean argument. Copy component backend_decls directly if the + components are derived types and from_gsym is true. + (gfc_get_derived_type): If whole_file copy the derived type from + the module if it is use associated, otherwise, if can be found + in another gsymbol namespace, use the existing derived type as + the TYPE_CANONICAL and build normally. + * gfortran.h : Add derived_types and resolved fields to + gfc_namespace. Include prototype for gfc_errors_to_warnings. + 2009-07-29 Tobias Burnus <burnus@net-b.de> PR fortran/40898 diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 392f2a57e68..86f41a3312b 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -655,6 +655,9 @@ match_char_length (gfc_expr **expr) if (m == MATCH_YES) { + if (gfc_notify_std (GFC_STD_F95_OBS, "Obsolescent feature: " + "Old-style character length at %C") == FAILURE) + return MATCH_ERROR; *expr = gfc_int_expr (length); return m; } @@ -1250,9 +1253,13 @@ add_init_expr_to_sym (const char *name, gfc_expr **initp, locus *var_locus) && gfc_check_assign_symbol (sym, init) == FAILURE) return FAILURE; - if (sym->ts.type == BT_CHARACTER && sym->ts.cl) + if (sym->ts.type == BT_CHARACTER && sym->ts.cl + && init->ts.type == BT_CHARACTER) { /* Update symbol character length according initializer. */ + if (gfc_check_assign_symbol (sym, init) == FAILURE) + return FAILURE; + if (sym->ts.cl->length == NULL) { int clen; diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c index 7cb23dd70e6..9d5453e4ceb 100644 --- a/gcc/fortran/error.c +++ b/gcc/fortran/error.c @@ -32,6 +32,8 @@ along with GCC; see the file COPYING3. If not see static int suppress_errors = 0; +static int warnings_not_errors = 0; + static int terminal_width, buffer_flag, errors, warnings; static gfc_error_buf error_buffer, warning_buffer, *cur_error_buffer; @@ -863,6 +865,9 @@ gfc_error (const char *nocmsgid, ...) { va_list argp; + if (warnings_not_errors) + goto warning; + if (suppress_errors) return; @@ -878,6 +883,30 @@ gfc_error (const char *nocmsgid, ...) if (buffer_flag == 0) gfc_increment_error_count(); + + return; + +warning: + + if (inhibit_warnings) + return; + + warning_buffer.flag = 1; + warning_buffer.index = 0; + cur_error_buffer = &warning_buffer; + + va_start (argp, nocmsgid); + error_print (_("Warning:"), _(nocmsgid), argp); + va_end (argp); + + error_char ('\0'); + + if (buffer_flag == 0) + { + warnings++; + if (warnings_are_errors) + gfc_increment_error_count(); + } } @@ -955,6 +984,7 @@ void gfc_clear_error (void) { error_buffer.flag = 0; + warnings_not_errors = 0; } @@ -1042,3 +1072,12 @@ gfc_get_errors (int *w, int *e) if (e != NULL) *e = errors; } + + +/* Switch errors into warnings. */ + +void +gfc_errors_to_warnings (int f) +{ + warnings_not_errors = (f == 1) ? 1 : 0; +} diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 7792cfabab6..da3d5f052b8 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1329,6 +1329,8 @@ typedef struct gfc_namespace gfc_charlen *cl_list, *old_cl_list; + gfc_dt_list *derived_types; + int save_all, seen_save, seen_implicit_none; /* Normally we don't need to refcount namespaces. However when we read @@ -1350,6 +1352,9 @@ typedef struct gfc_namespace /* Set to 1 if resolved has been called for this namespace. */ int resolved; + + /* Set to 1 if code has been generated for this namespace. */ + int translated; } gfc_namespace; @@ -2288,6 +2293,7 @@ void gfc_pop_error (gfc_error_buf *); void gfc_free_error (gfc_error_buf *); void gfc_get_errors (int *, int *); +void gfc_errors_to_warnings (int); /* arith.c */ void gfc_arith_init_1 (void); diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index 9de4da25b7b..b9b9d54d44e 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -1383,8 +1383,8 @@ match_arithmetic_if (void) return MATCH_ERROR; } - if (gfc_notify_std (GFC_STD_F95_OBS, "Obsolescent: arithmetic IF statement " - "at %C") == FAILURE) + if (gfc_notify_std (GFC_STD_F95_OBS, "Obsolescent feature: Arithmetic IF " + "statement at %C") == FAILURE) return MATCH_ERROR; new_st.op = EXEC_ARITHMETIC_IF; @@ -1464,7 +1464,7 @@ gfc_match_if (gfc_statement *if_type) return MATCH_ERROR; } - if (gfc_notify_std (GFC_STD_F95_OBS, "Obsolescent: arithmetic IF " + if (gfc_notify_std (GFC_STD_F95_OBS, "Obsolescent feature: Arithmetic IF " "statement at %C") == FAILURE) return MATCH_ERROR; @@ -2180,6 +2180,10 @@ gfc_match_goto (void) if (gfc_match (" %e%t", &expr) != MATCH_YES) goto syntax; + if (gfc_notify_std (GFC_STD_F95_OBS, "Obsolescent feature: Computed GOTO " + "at %C") == FAILURE) + return MATCH_ERROR; + /* At this point, a computed GOTO has been fully matched and an equivalent SELECT statement constructed. */ @@ -2580,6 +2584,10 @@ gfc_match_return (void) goto cleanup; } + if (gfc_notify_std (GFC_STD_F95_OBS, "Obsolescent feature: Alternate RETURN " + "at %C") == FAILURE) + return MATCH_ERROR; + if (gfc_current_form == FORM_FREE) { /* The following are valid, so we can't require a blank after the @@ -3517,6 +3525,10 @@ gfc_match_st_function (void) sym->value = expr; + if (gfc_notify_std (GFC_STD_F95_OBS, "Obsolescent feature: " + "Statement function at %C") == FAILURE) + return MATCH_ERROR; + return MATCH_YES; undo_error: diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c index ff0a80983da..3e20f8e45d4 100644 --- a/gcc/fortran/options.c +++ b/gcc/fortran/options.c @@ -371,6 +371,9 @@ gfc_post_options (const char **pfilename) gfc_option.warn_tabs = 0; } + if (pedantic && gfc_option.flag_whole_file) + gfc_option.flag_whole_file = 2; + gfc_cpp_post_options (); /* FIXME: return gfc_cpp_preprocess_only (); diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index da16c2b570f..e4463bd7edf 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -3760,6 +3760,8 @@ loop: st = next_statement (); goto loop; } + + s->ns = gfc_current_ns; } @@ -3809,6 +3811,76 @@ add_global_program (void) } +/* Resolve all the program units when whole file scope option + is active. */ +static void +resolve_all_program_units (gfc_namespace *gfc_global_ns_list) +{ + gfc_free_dt_list (); + gfc_current_ns = gfc_global_ns_list; + for (; gfc_current_ns; gfc_current_ns = gfc_current_ns->sibling) + { + gfc_current_locus = gfc_current_ns->proc_name->declared_at; + gfc_resolve (gfc_current_ns); + gfc_current_ns->derived_types = gfc_derived_types; + gfc_derived_types = NULL; + } +} + + +static void +clean_up_modules (gfc_gsymbol *gsym) +{ + if (gsym == NULL) + return; + + clean_up_modules (gsym->left); + clean_up_modules (gsym->right); + + if (gsym->type != GSYM_MODULE || !gsym->ns) + return; + + gfc_current_ns = gsym->ns; + gfc_derived_types = gfc_current_ns->derived_types; + gfc_done_2 (); + gsym->ns = NULL; + return; +} + + +/* Translate all the program units when whole file scope option + is active. This could be in a different order to resolution if + there are forward references in the file. */ +static void +translate_all_program_units (gfc_namespace *gfc_global_ns_list) +{ + int errors; + + gfc_current_ns = gfc_global_ns_list; + gfc_get_errors (NULL, &errors); + + for (; !errors && gfc_current_ns; gfc_current_ns = gfc_current_ns->sibling) + { + gfc_current_locus = gfc_current_ns->proc_name->declared_at; + gfc_derived_types = gfc_current_ns->derived_types; + gfc_generate_code (gfc_current_ns); + gfc_current_ns->translated = 1; + } + + /* Clean up all the namespaces after translation. */ + gfc_current_ns = gfc_global_ns_list; + for (;gfc_current_ns;) + { + gfc_namespace *ns = gfc_current_ns->sibling; + gfc_derived_types = gfc_current_ns->derived_types; + gfc_done_2 (); + gfc_current_ns = ns; + } + + clean_up_modules (gfc_gsym_root); +} + + /* Top level parser. */ gfc_try @@ -3933,15 +4005,24 @@ loop: gfc_dump_module (s.sym->name, errors_before == errors); if (errors == 0) gfc_generate_module_code (gfc_current_ns); + pop_state (); + if (!gfc_option.flag_whole_file) + gfc_done_2 (); + else + { + gfc_current_ns->derived_types = gfc_derived_types; + gfc_derived_types = NULL; + gfc_current_ns = NULL; + } } else { if (errors == 0) gfc_generate_code (gfc_current_ns); + pop_state (); + gfc_done_2 (); } - pop_state (); - gfc_done_2 (); goto loop; prog_units: @@ -3964,35 +4045,23 @@ prog_units: if (!gfc_option.flag_whole_file) goto termination; - /* Do the resolution. */ - gfc_current_ns = gfc_global_ns_list; - for (; gfc_current_ns; gfc_current_ns = gfc_current_ns->sibling) - { - gfc_current_locus = gfc_current_ns->proc_name->declared_at; - gfc_resolve (gfc_current_ns); - } + /* Do the resolution. */ + resolve_all_program_units (gfc_global_ns_list); /* Do the parse tree dump. */ - gfc_current_ns = gfc_option.dump_parse_tree ? gfc_global_ns_list : NULL; + gfc_current_ns + = gfc_option.dump_parse_tree ? gfc_global_ns_list : NULL; + for (; gfc_current_ns; gfc_current_ns = gfc_current_ns->sibling) { gfc_dump_parse_tree (gfc_current_ns, stdout); - fputs ("-----------------------------------------\n\n", stdout); + fputs ("------------------------------------------\n\n", stdout); } - gfc_current_ns = gfc_global_ns_list; - gfc_get_errors (NULL, &errors); - - /* Do the translation. This could be in a different order to - resolution if there are forward references in the file. */ - for (; !errors && gfc_current_ns; gfc_current_ns = gfc_current_ns->sibling) - { - gfc_current_locus = gfc_current_ns->proc_name->declared_at; - gfc_generate_code (gfc_current_ns); - } + /* Do the translation. */ + translate_all_program_units (gfc_global_ns_list); termination: - gfc_free_dt_list (); gfc_end_source_files (); return SUCCESS; diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 053ec839a08..14a111e3ad7 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -1652,6 +1652,47 @@ find_noncopying_intrinsics (gfc_symbol *fnsym, gfc_actual_arglist *actual) The namespace of the gsymbol is resolved and then, once this is done the interface is checked. */ + +static bool +not_in_recursive (gfc_symbol *sym, gfc_namespace *gsym_ns) +{ + if (!gsym_ns->proc_name->attr.recursive) + return true; + + if (sym->ns == gsym_ns) + return false; + + if (sym->ns->parent && sym->ns->parent == gsym_ns) + return false; + + return true; +} + +static bool +not_entry_self_reference (gfc_symbol *sym, gfc_namespace *gsym_ns) +{ + if (gsym_ns->entries) + { + gfc_entry_list *entry = gsym_ns->entries; + + for (; entry; entry = entry->next) + { + if (strcmp (sym->name, entry->sym->name) == 0) + { + if (strcmp (gsym_ns->proc_name->name, + sym->ns->proc_name->name) == 0) + return false; + + if (sym->ns->parent + && strcmp (gsym_ns->proc_name->name, + sym->ns->parent->proc_name->name) == 0) + return false; + } + } + } + return true; +} + static void resolve_global_procedure (gfc_symbol *sym, locus *where, gfc_actual_arglist **actual, int sub) @@ -1668,9 +1709,13 @@ resolve_global_procedure (gfc_symbol *sym, locus *where, gfc_global_used (gsym, where); if (gfc_option.flag_whole_file + && sym->attr.if_source == IFSRC_UNKNOWN && gsym->type != GSYM_UNKNOWN && gsym->ns - && gsym->ns->proc_name) + && gsym->ns->resolved != -1 + && gsym->ns->proc_name + && not_in_recursive (sym, gsym->ns) + && not_entry_self_reference (sym, gsym->ns)) { /* Make sure that translation for the gsymbol occurs before the procedure currently being resolved. */ @@ -1687,9 +1732,41 @@ resolve_global_procedure (gfc_symbol *sym, locus *where, } if (!gsym->ns->resolved) - gfc_resolve (gsym->ns); + { + gfc_dt_list *old_dt_list; + + /* Stash away derived types so that the backend_decls do not + get mixed up. */ + old_dt_list = gfc_derived_types; + gfc_derived_types = NULL; + + gfc_resolve (gsym->ns); + + /* Store the new derived types with the global namespace. */ + if (gfc_derived_types) + gsym->ns->derived_types = gfc_derived_types; + + /* Restore the derived types of this namespace. */ + gfc_derived_types = old_dt_list; + } + + if (gsym->ns->proc_name->attr.function + && gsym->ns->proc_name->as + && gsym->ns->proc_name->as->rank + && (!sym->as || sym->as->rank != gsym->ns->proc_name->as->rank)) + gfc_error ("The reference to function '%s' at %L either needs an " + "explicit INTERFACE or the rank is incorrect", sym->name, + where); + + if (gfc_option.flag_whole_file == 1 + || ((gfc_option.warn_std & GFC_STD_LEGACY) + && + !(gfc_option.warn_std & GFC_STD_GNU))) + gfc_errors_to_warnings (1); gfc_procedure_use (gsym->ns->proc_name, actual, where); + + gfc_errors_to_warnings (0); } if (gsym->type == GSYM_UNKNOWN) @@ -8212,8 +8289,8 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag) /* Appendix B.2 of the standard. Contained functions give an error anyway. Fixed-form is likely to be F77/legacy. */ if (!sym->attr.contained && gfc_current_form != FORM_FIXED) - gfc_notify_std (GFC_STD_F95_OBS, "CHARACTER(*) function " - "'%s' at %L is obsolescent in fortran 95", + gfc_notify_std (GFC_STD_F95_OBS, "Obsolescent feature: " + "CHARACTER(*) function '%s' at %L", sym->name, &sym->declared_at); } @@ -11134,15 +11211,19 @@ void gfc_resolve (gfc_namespace *ns) { gfc_namespace *old_ns; + code_stack *old_cs_base; if (ns->resolved) return; + ns->resolved = -1; old_ns = gfc_current_ns; + old_cs_base = cs_base; resolve_types (ns); resolve_codes (ns); gfc_current_ns = old_ns; + cs_base = old_cs_base; ns->resolved = 1; } diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 783c8f8308e..70b78ed9705 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -1098,6 +1098,32 @@ gfc_get_symbol_decl (gfc_symbol * sym) if (sym->backend_decl) return sym->backend_decl; + /* If use associated and whole file compilation, use the module + declaration. This is only needed for intrinsic types because + they are substituted for one another during optimization. */ + if (gfc_option.flag_whole_file + && sym->attr.flavor == FL_VARIABLE + && sym->ts.type != BT_DERIVED + && sym->attr.use_assoc + && sym->module) + { + gfc_gsymbol *gsym; + + gsym = gfc_find_gsymbol (gfc_gsym_root, sym->module); + if (gsym && gsym->ns && gsym->type == GSYM_MODULE) + { + gfc_symbol *s; + s = NULL; + gfc_find_symbol (sym->name, gsym->ns, 0, &s); + if (s && s->backend_decl) + { + if (sym->ts.type == BT_CHARACTER) + sym->ts.cl->backend_decl = s->ts.cl->backend_decl; + return s->backend_decl; + } + } + } + /* Catch function declarations. Only used for actual parameters and procedure pointers. */ if (sym->attr.flavor == FL_PROCEDURE) @@ -1341,6 +1367,7 @@ gfc_get_extern_function_decl (gfc_symbol * sym) gsym = gfc_find_gsymbol (gfc_gsym_root, sym->name); if (gfc_option.flag_whole_file + && !sym->attr.use_assoc && !sym->backend_decl && gsym && gsym->ns && ((gsym->type == GSYM_SUBROUTINE) || (gsym->type == GSYM_FUNCTION)) @@ -1371,6 +1398,26 @@ gfc_get_extern_function_decl (gfc_symbol * sym) return sym->backend_decl; } + /* See if this is a module procedure from the same file. If so, + return the backend_decl. */ + if (sym->module) + gsym = gfc_find_gsymbol (gfc_gsym_root, sym->module); + + if (gfc_option.flag_whole_file + && gsym && gsym->ns + && gsym->type == GSYM_MODULE) + { + gfc_symbol *s; + + s = NULL; + gfc_find_symbol (sym->name, gsym->ns, 0, &s); + if (s && s->backend_decl) + { + sym->backend_decl = s->backend_decl; + return sym->backend_decl; + } + } + if (sym->attr.intrinsic) { /* Call the resolution function to get the actual name. This is diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index 9bec2e10513..7352db849e0 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -4436,8 +4436,24 @@ gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts, gfc_add_block_to_block (&block, &lse->pre); gfc_add_block_to_block (&block, &rse->pre); + /* TODO This is rather obviously the wrong place to do this. + However, a number of testcases, such as function_kinds_1 + and function_types_2 fail without it, by ICEing at + fold_const: 2710 (fold_convert_loc). */ + if (ts.type == BT_DERIVED + && gfc_option.flag_whole_file + && (TYPE_MAIN_VARIANT (TREE_TYPE (rse->expr)) + != TYPE_MAIN_VARIANT (TREE_TYPE (lse->expr)))) + { + tmp = gfc_evaluate_now (rse->expr, &block); + TYPE_MAIN_VARIANT (TREE_TYPE (tmp)) + = TYPE_MAIN_VARIANT (TREE_TYPE (lse->expr)); + } + else + tmp = rse->expr; + gfc_add_modify (&block, lse->expr, - fold_convert (TREE_TYPE (lse->expr), rse->expr)); + fold_convert (TREE_TYPE (lse->expr), tmp)); } gfc_add_block_to_block (&block, &lse->post); diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index 7b842360280..5ae9a00517f 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -1853,7 +1853,8 @@ gfc_add_field_to_struct (tree *fieldlist, tree context, in 4.4.2 and resolved by gfc_compare_derived_types. */ static int -copy_dt_decls_ifequal (gfc_symbol *from, gfc_symbol *to) +copy_dt_decls_ifequal (gfc_symbol *from, gfc_symbol *to, + bool from_gsym) { gfc_component *to_cm; gfc_component *from_cm; @@ -1876,7 +1877,8 @@ copy_dt_decls_ifequal (gfc_symbol *from, gfc_symbol *to) for (; to_cm; to_cm = to_cm->next, from_cm = from_cm->next) { to_cm->backend_decl = from_cm->backend_decl; - if (!from_cm->attr.pointer && from_cm->ts.type == BT_DERIVED) + if ((!from_cm->attr.pointer || from_gsym) + && from_cm->ts.type == BT_DERIVED) gfc_get_derived_type (to_cm->ts.derived); else if (from_cm->ts.type == BT_CHARACTER) @@ -1916,8 +1918,12 @@ static tree gfc_get_derived_type (gfc_symbol * derived) { tree typenode = NULL, field = NULL, field_type = NULL, fieldlist = NULL; + tree canonical = NULL_TREE; + bool got_canonical = false; gfc_component *c; gfc_dt_list *dt; + gfc_namespace *ns; + gfc_gsymbol *gsym; gcc_assert (derived && derived->attr.flavor == FL_DERIVED); @@ -1949,7 +1955,59 @@ gfc_get_derived_type (gfc_symbol * derived) return derived->backend_decl; } - + +/* If use associated, use the module type for this one. */ + if (gfc_option.flag_whole_file + && derived->backend_decl == NULL + && derived->attr.use_assoc + && derived->module) + { + gsym = gfc_find_gsymbol (gfc_gsym_root, derived->module); + if (gsym && gsym->ns && gsym->type == GSYM_MODULE) + { + gfc_symbol *s; + s = NULL; + gfc_find_symbol (derived->name, gsym->ns, 0, &s); + if (s && s->backend_decl) + { + copy_dt_decls_ifequal (s, derived, true); + goto copy_derived_types; + } + } + } + + /* If a whole file compilation, the derived types from an earlier + namespace can be used as the the canonical type. */ + if (gfc_option.flag_whole_file + && derived->backend_decl == NULL + && !derived->attr.use_assoc + && gfc_global_ns_list) + { + for (ns = gfc_global_ns_list; + ns->translated && !got_canonical; + ns = ns->sibling) + { + dt = ns->derived_types; + for (; dt && !canonical; dt = dt->next) + { + copy_dt_decls_ifequal (dt->derived, derived, true); + if (derived->backend_decl) + got_canonical = true; + } + } + } + + /* Store up the canonical type to be added to this one. */ + if (got_canonical) + { + if (TYPE_CANONICAL (derived->backend_decl)) + canonical = TYPE_CANONICAL (derived->backend_decl); + else + canonical = derived->backend_decl; + + derived->backend_decl = NULL_TREE; + } + /* derived->backend_decl != 0 means we saw it before, but its components' backend_decl may have not been built. */ if (derived->backend_decl) @@ -2065,6 +2123,7 @@ gfc_get_derived_type (gfc_symbol * derived) /* Now we have the final fieldlist. Record it, then lay out the derived type, including the fields. */ TYPE_FIELDS (typenode) = fieldlist; + TYPE_CANONICAL (typenode) = canonical; gfc_finish_type (typenode); gfc_set_decl_location (TYPE_STUB_DECL (typenode), &derived->declared_at); @@ -2083,9 +2142,10 @@ gfc_get_derived_type (gfc_symbol * derived) derived->backend_decl = typenode; - /* Add this backend_decl to all the other, equal derived types. */ +copy_derived_types: + for (dt = gfc_derived_types; dt; dt = dt->next) - copy_dt_decls_ifequal (derived, dt->derived); + copy_dt_decls_ifequal (derived, dt->derived, false); return derived->backend_decl; } @@ -2264,8 +2324,7 @@ gfc_get_function_type (gfc_symbol * sym) while (nstr--) typelist = gfc_chainon_list (typelist, gfc_charlen_type_node); - if (typelist) - typelist = gfc_chainon_list (typelist, void_type_node); + typelist = gfc_chainon_list (typelist, void_type_node); if (alternate_return) type = integer_type_node; diff --git a/gcc/function.c b/gcc/function.c index e31c12ada35..2294b971547 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -922,7 +922,7 @@ assign_temp (tree type_or_decl, int keep, int memory_required, #ifdef PROMOTE_MODE if (! dont_promote) - mode = promote_mode (type, mode, &unsignedp, 0); + mode = promote_mode (type, mode, &unsignedp); #endif return gen_reg_rtx (mode); @@ -2167,6 +2167,7 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm, { tree nominal_type, passed_type; enum machine_mode nominal_mode, passed_mode, promoted_mode; + int unsignedp; memset (data, 0, sizeof (*data)); @@ -2219,13 +2220,9 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm, } /* Find mode as it is passed by the ABI. */ - promoted_mode = passed_mode; - if (targetm.calls.promote_function_args (TREE_TYPE (current_function_decl))) - { - int unsignedp = TYPE_UNSIGNED (passed_type); - promoted_mode = promote_mode (passed_type, promoted_mode, - &unsignedp, 1); - } + unsignedp = TYPE_UNSIGNED (passed_type); + promoted_mode = promote_function_mode (passed_type, passed_mode, &unsignedp, + TREE_TYPE (current_function_decl), 0); egress: data->nominal_type = nominal_type; @@ -2778,7 +2775,8 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, /* This is not really promoting for a call. However we need to be consistent with assign_parm_find_data_types and expand_expr_real_1. */ promoted_nominal_mode - = promote_mode (data->nominal_type, data->nominal_mode, &unsignedp, 1); + = promote_function_mode (data->nominal_type, data->nominal_mode, &unsignedp, + TREE_TYPE (current_function_decl), 0); parmreg = gen_reg_rtx (promoted_nominal_mode); @@ -4722,10 +4720,9 @@ expand_function_end (void) else if (GET_MODE (real_decl_rtl) != GET_MODE (decl_rtl)) { int unsignedp = TYPE_UNSIGNED (TREE_TYPE (decl_result)); - - if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl))) - promote_mode (TREE_TYPE (decl_result), GET_MODE (decl_rtl), - &unsignedp, 1); + promote_function_mode (TREE_TYPE (decl_result), + GET_MODE (decl_rtl), &unsignedp, + TREE_TYPE (current_function_decl), 1); convert_move (real_decl_rtl, decl_rtl, unsignedp); } diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 1deb9c81a0a..70ab4e1b800 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -1150,6 +1150,22 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags) } for (i = 0; i < gimple_phi_num_args (phi); i++) { + if ((flags & TDF_LINENO) && gimple_phi_arg_has_location (phi, i)) + { + expanded_location xloc; + + xloc = expand_location (gimple_phi_arg_location (phi, i)); + pp_character (buffer, '['); + if (xloc.file) + { + pp_string (buffer, xloc.file); + pp_string (buffer, " : "); + } + pp_decimal_int (buffer, xloc.line); + pp_string (buffer, ":"); + pp_decimal_int (buffer, xloc.column); + pp_string (buffer, "] "); + } dump_generic_node (buffer, gimple_phi_arg_def (phi, i), spc, flags, false); pp_character (buffer, '('); diff --git a/gcc/graphite-blocking.c b/gcc/graphite-blocking.c new file mode 100644 index 00000000000..4961c7f6d5a --- /dev/null +++ b/gcc/graphite-blocking.c @@ -0,0 +1,210 @@ +/* Heuristics and transform for loop blocking and strip mining on + polyhedral representation. + + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Sebastian Pop <sebastian.pop@amd.com> and + Pranav Garg <pranav.garg2107@gmail.com>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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/>. */ +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "ggc.h" +#include "tree.h" +#include "rtl.h" +#include "output.h" +#include "basic-block.h" +#include "diagnostic.h" +#include "tree-flow.h" +#include "toplev.h" +#include "tree-dump.h" +#include "timevar.h" +#include "cfgloop.h" +#include "tree-chrec.h" +#include "tree-data-ref.h" +#include "tree-scalar-evolution.h" +#include "tree-pass.h" +#include "domwalk.h" +#include "value-prof.h" +#include "pointer-set.h" +#include "gimple.h" +#include "params.h" + +#ifdef HAVE_cloog +#include "cloog/cloog.h" +#include "ppl_c.h" +#include "sese.h" +#include "graphite-ppl.h" +#include "graphite.h" +#include "graphite-poly.h" + + +/* Strip mines with a factor STRIDE the loop around PBB at depth + LOOP_DEPTH. The following example comes from the wiki page: + http://gcc.gnu.org/wiki/Graphite/Strip_mine + + The strip mine of a loop with a tile of 64 can be obtained with a + scattering function as follows: + + $ cat ./albert_strip_mine.cloog + # language: C + c + + # parameter {n | n >= 0} + 1 3 + # n 1 + 1 1 0 + 1 + n + + 1 # Number of statements: + + 1 + # {i | 0 <= i <= n} + 2 4 + # i n 1 + 1 1 0 0 + 1 -1 1 0 + + 0 0 0 + 1 + i + + 1 # Scattering functions + + 3 6 + # NEW OLD i n 1 + 1 -64 0 1 0 0 + 1 64 0 -1 0 63 + 0 0 1 -1 0 0 + + 1 + NEW OLD + + #the output of CLooG is like this: + #$ cloog ./albert_strip_mine.cloog + # for (NEW=0;NEW<=floord(n,64);NEW++) { + # for (OLD=max(64*NEW,0);OLD<=min(64*NEW+63,n);OLD++) { + # S1(i = OLD) ; + # } + # } +*/ + +static bool +pbb_strip_mine_loop_depth (poly_bb_p pbb, int loop_depth, int stride) +{ + ppl_dimension_type iter, dim; + ppl_Polyhedron_t res = PBB_TRANSFORMED_SCATTERING (pbb); + ppl_dimension_type strip = psct_scattering_dim_for_loop_depth (pbb, + loop_depth); + + psct_add_scattering_dimension (pbb, strip); + + iter = psct_iterator_dim (pbb, loop_depth); + ppl_Polyhedron_space_dimension (res, &dim); + + /* Lower bound of the striped loop. */ + { + ppl_Constraint_t new_cstr; + ppl_Linear_Expression_t expr; + + ppl_new_Linear_Expression_with_dimension (&expr, dim); + ppl_set_coef (expr, strip, -1 * stride); + ppl_set_coef (expr, iter, 1); + + ppl_new_Constraint (&new_cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL); + ppl_delete_Linear_Expression (expr); + ppl_Polyhedron_add_constraint (res, new_cstr); + ppl_delete_Constraint (new_cstr); + } + + /* Upper bound of the striped loop. */ + { + ppl_Constraint_t new_cstr; + ppl_Linear_Expression_t expr; + + ppl_new_Linear_Expression_with_dimension (&expr, dim); + ppl_set_coef (expr, strip, stride); + ppl_set_coef (expr, iter, -1); + ppl_set_inhomogeneous (expr, stride - 1); + + ppl_new_Constraint (&new_cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL); + ppl_delete_Linear_Expression (expr); + ppl_Polyhedron_add_constraint (res, new_cstr); + ppl_delete_Constraint (new_cstr); + } + + return true; +} + +/* Returns true when strip mining with STRIDE of the loop around PBB + at depth LOOP_DEPTH is profitable. */ + +static bool +pbb_strip_mine_profitable_p (poly_bb_p pbb, + graphite_dim_t loop_depth, + int stride) +{ + Value niter, strip_stride; + bool res; + + value_init (strip_stride); + value_init (niter); + value_set_si (strip_stride, stride); + pbb_number_of_iterations (pbb, loop_depth, niter); + res = value_gt (niter, strip_stride); + value_clear (strip_stride); + value_clear (niter); + + return res; +} + +/* Strip mines all the loops around PBB. Nothing profitable in all this: + this is just a driver function. */ + +static bool +pbb_do_strip_mine (poly_bb_p pbb) +{ + graphite_dim_t loop_depth; + int stride = 64; + bool transform_done = false; + + for (loop_depth = 0; loop_depth < pbb_dim_iter_domain (pbb); loop_depth++) + if (pbb_strip_mine_profitable_p (pbb, loop_depth, stride)) + transform_done |= pbb_strip_mine_loop_depth (pbb, loop_depth, stride); + + return transform_done; +} + +/* Strip mines all the loops in SCOP. Nothing profitable in all this: + this is just a driver function. */ + +bool +scop_do_strip_mine (scop_p scop) +{ + poly_bb_p pbb; + int i; + bool transform_done = false; + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + transform_done |= pbb_do_strip_mine (pbb); + + return transform_done; +} + +#endif diff --git a/gcc/graphite-clast-to-gimple.c b/gcc/graphite-clast-to-gimple.c new file mode 100644 index 00000000000..bf540a2d1ca --- /dev/null +++ b/gcc/graphite-clast-to-gimple.c @@ -0,0 +1,1317 @@ +/* Translation of CLAST (CLooG AST) to Gimple. + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Sebastian Pop <sebastian.pop@amd.com>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "ggc.h" +#include "tree.h" +#include "rtl.h" +#include "basic-block.h" +#include "diagnostic.h" +#include "tree-flow.h" +#include "toplev.h" +#include "tree-dump.h" +#include "timevar.h" +#include "cfgloop.h" +#include "tree-chrec.h" +#include "tree-data-ref.h" +#include "tree-scalar-evolution.h" +#include "tree-pass.h" +#include "domwalk.h" +#include "value-prof.h" +#include "pointer-set.h" +#include "gimple.h" +#include "sese.h" + +#ifdef HAVE_cloog +#include "cloog/cloog.h" +#include "ppl_c.h" +#include "graphite-ppl.h" +#include "graphite.h" +#include "graphite-poly.h" +#include "graphite-scop-detection.h" +#include "graphite-clast-to-gimple.h" +#include "graphite-dependences.h" + +/* Verifies properties that GRAPHITE should maintain during translation. */ + +static inline void +graphite_verify (void) +{ +#ifdef ENABLE_CHECKING + verify_loop_structure (); + verify_dominators (CDI_DOMINATORS); + verify_dominators (CDI_POST_DOMINATORS); + verify_ssa (false); + verify_loop_closed_ssa (); +#endif +} + +/* For a given loop DEPTH in the loop nest of the original black box + PBB, return the old induction variable associated to that loop. */ + +static inline tree +pbb_to_depth_to_oldiv (poly_bb_p pbb, int depth) +{ + gimple_bb_p gbb = PBB_BLACK_BOX (pbb); + sese region = SCOP_REGION (PBB_SCOP (pbb)); + loop_p loop = gbb_loop_at_index (gbb, region, depth); + + return (tree) loop->aux; +} + +/* For a given scattering dimension, return the new induction variable + associated to it. */ + +static inline tree +newivs_to_depth_to_newiv (VEC (tree, heap) *newivs, int depth) +{ + return VEC_index (tree, newivs, depth); +} + + + +/* Returns the tree variable from the name NAME that was given in + Cloog representation. */ + +static tree +clast_name_to_gcc (const char *name, sese region, VEC (tree, heap) *newivs, + htab_t newivs_index) +{ + int index; + VEC (tree, heap) *params = SESE_PARAMS (region); + htab_t params_index = SESE_PARAMS_INDEX (region); + + if (params && params_index) + { + index = clast_name_to_index (name, params_index); + + if (index >= 0) + return VEC_index (tree, params, index); + } + + gcc_assert (newivs && newivs_index); + index = clast_name_to_index (name, newivs_index); + gcc_assert (index >= 0); + + return newivs_to_depth_to_newiv (newivs, index); +} + +/* Returns the maximal precision type for expressions E1 and E2. */ + +static inline tree +max_precision_type (tree e1, tree e2) +{ + tree type1 = TREE_TYPE (e1); + tree type2 = TREE_TYPE (e2); + return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2; +} + +static tree +clast_to_gcc_expression (tree, struct clast_expr *, sese, VEC (tree, heap) *, + htab_t); + +/* Converts a Cloog reduction expression R with reduction operation OP + to a GCC expression tree of type TYPE. */ + +static tree +clast_to_gcc_expression_red (tree type, enum tree_code op, + struct clast_reduction *r, + sese region, VEC (tree, heap) *newivs, + htab_t newivs_index) +{ + int i; + tree res = clast_to_gcc_expression (type, r->elts[0], region, newivs, + newivs_index); + tree operand_type = (op == POINTER_PLUS_EXPR) ? sizetype : type; + + for (i = 1; i < r->n; i++) + { + tree t = clast_to_gcc_expression (operand_type, r->elts[i], region, + newivs, newivs_index); + res = fold_build2 (op, type, res, t); + } + + return res; +} + +/* Converts a Cloog AST expression E back to a GCC expression tree of + type TYPE. */ + +static tree +clast_to_gcc_expression (tree type, struct clast_expr *e, + sese region, VEC (tree, heap) *newivs, + htab_t newivs_index) +{ + switch (e->type) + { + case expr_term: + { + struct clast_term *t = (struct clast_term *) e; + + if (t->var) + { + if (value_one_p (t->val)) + { + tree name = clast_name_to_gcc (t->var, region, newivs, + newivs_index); + return fold_convert (type, name); + } + + else if (value_mone_p (t->val)) + { + tree name = clast_name_to_gcc (t->var, region, newivs, + newivs_index); + name = fold_convert (type, name); + return fold_build1 (NEGATE_EXPR, type, name); + } + else + { + tree name = clast_name_to_gcc (t->var, region, newivs, + newivs_index); + tree cst = gmp_cst_to_tree (type, t->val); + name = fold_convert (type, name); + return fold_build2 (MULT_EXPR, type, cst, name); + } + } + else + return gmp_cst_to_tree (type, t->val); + } + + case expr_red: + { + struct clast_reduction *r = (struct clast_reduction *) e; + + switch (r->type) + { + case clast_red_sum: + return clast_to_gcc_expression_red + (type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR, + r, region, newivs, newivs_index); + + case clast_red_min: + return clast_to_gcc_expression_red (type, MIN_EXPR, r, region, + newivs, newivs_index); + + case clast_red_max: + return clast_to_gcc_expression_red (type, MAX_EXPR, r, region, + newivs, newivs_index); + + default: + gcc_unreachable (); + } + break; + } + + case expr_bin: + { + struct clast_binary *b = (struct clast_binary *) e; + struct clast_expr *lhs = (struct clast_expr *) b->LHS; + tree tl = clast_to_gcc_expression (type, lhs, region, newivs, + newivs_index); + tree tr = gmp_cst_to_tree (type, b->RHS); + + switch (b->type) + { + case clast_bin_fdiv: + return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr); + + case clast_bin_cdiv: + return fold_build2 (CEIL_DIV_EXPR, type, tl, tr); + + case clast_bin_div: + return fold_build2 (EXACT_DIV_EXPR, type, tl, tr); + + case clast_bin_mod: + return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr); + + default: + gcc_unreachable (); + } + } + + default: + gcc_unreachable (); + } + + return NULL_TREE; +} + +/* Returns the type for the expression E. */ + +static tree +gcc_type_for_clast_expr (struct clast_expr *e, + sese region, VEC (tree, heap) *newivs, + htab_t newivs_index) +{ + switch (e->type) + { + case expr_term: + { + struct clast_term *t = (struct clast_term *) e; + + if (t->var) + return TREE_TYPE (clast_name_to_gcc (t->var, region, newivs, + newivs_index)); + else + return NULL_TREE; + } + + case expr_red: + { + struct clast_reduction *r = (struct clast_reduction *) e; + + if (r->n == 1) + return gcc_type_for_clast_expr (r->elts[0], region, newivs, + newivs_index); + else + { + int i; + for (i = 0; i < r->n; i++) + { + tree type = gcc_type_for_clast_expr (r->elts[i], region, + newivs, newivs_index); + if (type) + return type; + } + return NULL_TREE; + } + } + + case expr_bin: + { + struct clast_binary *b = (struct clast_binary *) e; + struct clast_expr *lhs = (struct clast_expr *) b->LHS; + return gcc_type_for_clast_expr (lhs, region, newivs, + newivs_index); + } + + default: + gcc_unreachable (); + } + + return NULL_TREE; +} + +/* Returns the type for the equation CLEQ. */ + +static tree +gcc_type_for_clast_eq (struct clast_equation *cleq, + sese region, VEC (tree, heap) *newivs, + htab_t newivs_index) +{ + tree type = gcc_type_for_clast_expr (cleq->LHS, region, newivs, + newivs_index); + if (type) + return type; + + return gcc_type_for_clast_expr (cleq->RHS, region, newivs, newivs_index); +} + +/* Translates a clast equation CLEQ to a tree. */ + +static tree +graphite_translate_clast_equation (sese region, + struct clast_equation *cleq, + VEC (tree, heap) *newivs, + htab_t newivs_index) +{ + enum tree_code comp; + tree type = gcc_type_for_clast_eq (cleq, region, newivs, newivs_index); + tree lhs = clast_to_gcc_expression (type, cleq->LHS, region, newivs, + newivs_index); + tree rhs = clast_to_gcc_expression (type, cleq->RHS, region, newivs, + newivs_index); + + if (cleq->sign == 0) + comp = EQ_EXPR; + + else if (cleq->sign > 0) + comp = GE_EXPR; + + else + comp = LE_EXPR; + + return fold_build2 (comp, boolean_type_node, lhs, rhs); +} + +/* Creates the test for the condition in STMT. */ + +static tree +graphite_create_guard_cond_expr (sese region, struct clast_guard *stmt, + VEC (tree, heap) *newivs, + htab_t newivs_index) +{ + tree cond = NULL; + int i; + + for (i = 0; i < stmt->n; i++) + { + tree eq = graphite_translate_clast_equation (region, &stmt->eq[i], + newivs, newivs_index); + + if (cond) + cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq); + else + cond = eq; + } + + return cond; +} + +/* Creates a new if region corresponding to Cloog's guard. */ + +static edge +graphite_create_new_guard (sese region, edge entry_edge, + struct clast_guard *stmt, + VEC (tree, heap) *newivs, + htab_t newivs_index) +{ + tree cond_expr = graphite_create_guard_cond_expr (region, stmt, newivs, + newivs_index); + edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr); + return exit_edge; +} + +/* Walks a CLAST and returns the first statement in the body of a + loop. */ + +static struct clast_user_stmt * +clast_get_body_of_loop (struct clast_stmt *stmt) +{ + if (!stmt + || CLAST_STMT_IS_A (stmt, stmt_user)) + return (struct clast_user_stmt *) stmt; + + if (CLAST_STMT_IS_A (stmt, stmt_for)) + return clast_get_body_of_loop (((struct clast_for *) stmt)->body); + + if (CLAST_STMT_IS_A (stmt, stmt_guard)) + return clast_get_body_of_loop (((struct clast_guard *) stmt)->then); + + if (CLAST_STMT_IS_A (stmt, stmt_block)) + return clast_get_body_of_loop (((struct clast_block *) stmt)->body); + + gcc_unreachable (); +} + +/* Given a CLOOG_IV, returns the type that it should have in GCC land. + If the information is not available, i.e. in the case one of the + transforms created the loop, just return integer_type_node. */ + +static tree +gcc_type_for_cloog_iv (const char *cloog_iv, gimple_bb_p gbb) +{ + struct ivtype_map_elt_s tmp; + PTR *slot; + + tmp.cloog_iv = cloog_iv; + slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, NO_INSERT); + + if (slot && *slot) + return ((ivtype_map_elt) *slot)->type; + + return integer_type_node; +} + +/* Returns the induction variable for the loop that gets translated to + STMT. */ + +static tree +gcc_type_for_iv_of_clast_loop (struct clast_for *stmt_for) +{ + struct clast_stmt *stmt = (struct clast_stmt *) stmt_for; + struct clast_user_stmt *body = clast_get_body_of_loop (stmt); + const char *cloog_iv = stmt_for->iterator; + CloogStatement *cs = body->statement; + poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs); + + return gcc_type_for_cloog_iv (cloog_iv, PBB_BLACK_BOX (pbb)); +} + +/* Creates a new LOOP corresponding to Cloog's STMT. Inserts an + induction variable for the new LOOP. New LOOP is attached to CFG + starting at ENTRY_EDGE. LOOP is inserted into the loop tree and + becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds + CLooG's scattering name to the induction variable created for the + loop of STMT. The new induction variable is inserted in the NEWIVS + vector. */ + +static struct loop * +graphite_create_new_loop (sese region, edge entry_edge, + struct clast_for *stmt, + loop_p outer, VEC (tree, heap) **newivs, + htab_t newivs_index) +{ + tree type = gcc_type_for_iv_of_clast_loop (stmt); + tree lb = clast_to_gcc_expression (type, stmt->LB, region, *newivs, + newivs_index); + tree ub = clast_to_gcc_expression (type, stmt->UB, region, *newivs, + newivs_index); + tree stride = gmp_cst_to_tree (type, stmt->stride); + tree ivvar = create_tmp_var (type, "graphite_IV"); + tree iv, iv_after_increment; + loop_p loop = create_empty_loop_on_edge + (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment, + outer ? outer : entry_edge->src->loop_father); + + add_referenced_var (ivvar); + + save_clast_name_index (newivs_index, stmt->iterator, + VEC_length (tree, *newivs)); + VEC_safe_push (tree, heap, *newivs, iv); + return loop; +} + +/* Inserts in MAP a tuple (OLD_NAME, NEW_NAME) for the induction + variables of the loops around GBB in SESE. */ + +static void +build_iv_mapping (htab_t map, sese region, + VEC (tree, heap) *newivs, htab_t newivs_index, + struct clast_user_stmt *user_stmt) +{ + struct clast_stmt *t; + int index = 0; + CloogStatement *cs = user_stmt->statement; + poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs); + + for (t = user_stmt->substitutions; t; t = t->next, index++) + { + struct clast_expr *expr = (struct clast_expr *) + ((struct clast_assignment *)t)->RHS; + tree type = gcc_type_for_clast_expr (expr, region, newivs, + newivs_index); + tree old_name = pbb_to_depth_to_oldiv (pbb, index); + tree e = clast_to_gcc_expression (type, expr, region, newivs, + newivs_index); + set_rename (map, old_name, e); + } +} + +/* Helper function for htab_traverse. */ + +static int +copy_renames (void **slot, void *s) +{ + struct rename_map_elt_s *entry = (struct rename_map_elt_s *) *slot; + htab_t res = (htab_t) s; + tree old_name = entry->old_name; + tree expr = entry->expr; + struct rename_map_elt_s tmp; + PTR *x; + + tmp.old_name = old_name; + x = htab_find_slot (res, &tmp, INSERT); + + if (!*x) + *x = new_rename_map_elt (old_name, expr); + + return 1; +} + +/* Construct bb_pbb_def with BB and PBB. */ + +static bb_pbb_def * +new_bb_pbb_def (basic_block bb, poly_bb_p pbb) +{ + bb_pbb_def *bb_pbb_p; + + bb_pbb_p = XNEW (bb_pbb_def); + bb_pbb_p->bb = bb; + bb_pbb_p->pbb = pbb; + + return bb_pbb_p; +} + +/* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */ + +static void +mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, htab_t bb_pbb_mapping) +{ + bb_pbb_def tmp; + PTR *x; + + tmp.bb = bb; + x = htab_find_slot (bb_pbb_mapping, &tmp, INSERT); + + if (!*x) + *x = new_bb_pbb_def (bb, pbb); +} + +/* Returns the scattering dimension for STMTFOR. + + FIXME: This is a hackish solution to locate the scattering + dimension in newly created loops. Here the hackish solush + assume that the stmt_for->iterator is always something like: + scat_1 , scat_3 etc., where after "scat_" is loop level in + scattering dimension. +*/ + +static int get_stmtfor_depth (struct clast_for *stmtfor) +{ + const char * iterator = stmtfor->iterator; + const char * depth; + + depth = strchr (iterator, '_'); + if (!strncmp (iterator, "scat_", 5)) + return atoi (depth+1); + + gcc_unreachable(); +} + +/* Translates a CLAST statement STMT to GCC representation in the + context of a SESE. + + - NEXT_E is the edge where new generated code should be attached. + - CONTEXT_LOOP is the loop in which the generated code will be placed + - RENAME_MAP contains a set of tuples of new names associated to + the original variables names. + - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. +*/ + +static edge +translate_clast (sese region, struct loop *context_loop, + struct clast_stmt *stmt, edge next_e, + htab_t rename_map, VEC (tree, heap) **newivs, + htab_t newivs_index, htab_t bb_pbb_mapping) +{ + if (!stmt) + return next_e; + + if (CLAST_STMT_IS_A (stmt, stmt_root)) + return translate_clast (region, context_loop, stmt->next, next_e, + rename_map, newivs, newivs_index, bb_pbb_mapping); + + if (CLAST_STMT_IS_A (stmt, stmt_user)) + { + gimple_bb_p gbb; + basic_block new_bb; + CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement; + poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs); + gbb = PBB_BLACK_BOX (pbb); + + if (GBB_BB (gbb) == ENTRY_BLOCK_PTR) + return next_e; + + build_iv_mapping (rename_map, region, *newivs, newivs_index, + (struct clast_user_stmt *) stmt); + next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), region, + next_e, rename_map); + new_bb = next_e->src; + mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping); + recompute_all_dominators (); + update_ssa (TODO_update_ssa); + graphite_verify (); + return translate_clast (region, context_loop, stmt->next, next_e, + rename_map, newivs, newivs_index, + bb_pbb_mapping); + } + + if (CLAST_STMT_IS_A (stmt, stmt_for)) + { + struct clast_for *stmtfor = (struct clast_for *)stmt; + struct loop *loop + = graphite_create_new_loop (region, next_e, stmtfor, + context_loop, newivs, newivs_index); + edge last_e = single_exit (loop); + edge to_body = single_succ_edge (loop->header); + basic_block after = to_body->dest; + + loop->aux = XNEW (int); + /* Pass scattering level information of the new loop by LOOP->AUX. */ + *((int *)(loop->aux)) = get_stmtfor_depth (stmtfor); + + /* Create a basic block for loop close phi nodes. */ + last_e = single_succ_edge (split_edge (last_e)); + + /* Translate the body of the loop. */ + next_e = translate_clast + (region, loop, ((struct clast_for *) stmt)->body, + single_succ_edge (loop->header), rename_map, newivs, + newivs_index, bb_pbb_mapping); + redirect_edge_succ_nodup (next_e, after); + set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src); + + /* Remove from rename_map all the tuples containing variables + defined in loop's body. */ + insert_loop_close_phis (rename_map, loop); + + recompute_all_dominators (); + graphite_verify (); + return translate_clast (region, context_loop, stmt->next, last_e, + rename_map, newivs, newivs_index, + bb_pbb_mapping); + } + + if (CLAST_STMT_IS_A (stmt, stmt_guard)) + { + edge last_e = graphite_create_new_guard (region, next_e, + ((struct clast_guard *) stmt), + *newivs, newivs_index); + edge true_e = get_true_edge_from_guard_bb (next_e->dest); + edge false_e = get_false_edge_from_guard_bb (next_e->dest); + edge exit_true_e = single_succ_edge (true_e->dest); + edge exit_false_e = single_succ_edge (false_e->dest); + htab_t before_guard = htab_create (10, rename_map_elt_info, + eq_rename_map_elts, free); + + htab_traverse (rename_map, copy_renames, before_guard); + next_e = translate_clast (region, context_loop, + ((struct clast_guard *) stmt)->then, + true_e, rename_map, newivs, newivs_index, + bb_pbb_mapping); + insert_guard_phis (last_e->src, exit_true_e, exit_false_e, + before_guard, rename_map); + + htab_delete (before_guard); + recompute_all_dominators (); + graphite_verify (); + + return translate_clast (region, context_loop, stmt->next, last_e, + rename_map, newivs, newivs_index, + bb_pbb_mapping); + } + + if (CLAST_STMT_IS_A (stmt, stmt_block)) + { + next_e = translate_clast (region, context_loop, + ((struct clast_block *) stmt)->body, + next_e, rename_map, newivs, newivs_index, + bb_pbb_mapping); + recompute_all_dominators (); + graphite_verify (); + return translate_clast (region, context_loop, stmt->next, next_e, + rename_map, newivs, newivs_index, + bb_pbb_mapping); + } + + gcc_unreachable (); +} + +/* Returns the first cloog name used in EXPR. */ + +static const char * +find_cloog_iv_in_expr (struct clast_expr *expr) +{ + struct clast_term *term = (struct clast_term *) expr; + + if (expr->type == expr_term + && !term->var) + return NULL; + + if (expr->type == expr_term) + return term->var; + + if (expr->type == expr_red) + { + int i; + struct clast_reduction *red = (struct clast_reduction *) expr; + + for (i = 0; i < red->n; i++) + { + const char *res = find_cloog_iv_in_expr ((red)->elts[i]); + + if (res) + return res; + } + } + + return NULL; +} + +/* Build for a clast_user_stmt USER_STMT a map between the CLAST + induction variables and the corresponding GCC old induction + variables. This information is stored on each GRAPHITE_BB. */ + +static void +compute_cloog_iv_types_1 (poly_bb_p pbb, struct clast_user_stmt *user_stmt) +{ + gimple_bb_p gbb = PBB_BLACK_BOX (pbb); + struct clast_stmt *t; + int index = 0; + + for (t = user_stmt->substitutions; t; t = t->next, index++) + { + PTR *slot; + struct ivtype_map_elt_s tmp; + struct clast_expr *expr = (struct clast_expr *) + ((struct clast_assignment *)t)->RHS; + + /* Create an entry (clast_var, type). */ + tmp.cloog_iv = find_cloog_iv_in_expr (expr); + if (!tmp.cloog_iv) + continue; + + slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, INSERT); + + if (!*slot) + { + tree oldiv = pbb_to_depth_to_oldiv (pbb, index); + tree type = oldiv ? TREE_TYPE (oldiv) : integer_type_node; + *slot = new_ivtype_map_elt (tmp.cloog_iv, type); + } + } +} + +/* Walk the CLAST tree starting from STMT and build for each + clast_user_stmt a map between the CLAST induction variables and the + corresponding GCC old induction variables. This information is + stored on each GRAPHITE_BB. */ + +static void +compute_cloog_iv_types (struct clast_stmt *stmt) +{ + if (!stmt) + return; + + if (CLAST_STMT_IS_A (stmt, stmt_root)) + goto next; + + if (CLAST_STMT_IS_A (stmt, stmt_user)) + { + CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement; + poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs); + gimple_bb_p gbb = PBB_BLACK_BOX (pbb); + + if (!GBB_CLOOG_IV_TYPES (gbb)) + GBB_CLOOG_IV_TYPES (gbb) = htab_create (10, ivtype_map_elt_info, + eq_ivtype_map_elts, free); + + compute_cloog_iv_types_1 (pbb, (struct clast_user_stmt *) stmt); + goto next; + } + + if (CLAST_STMT_IS_A (stmt, stmt_for)) + { + struct clast_stmt *s = ((struct clast_for *) stmt)->body; + compute_cloog_iv_types (s); + goto next; + } + + if (CLAST_STMT_IS_A (stmt, stmt_guard)) + { + struct clast_stmt *s = ((struct clast_guard *) stmt)->then; + compute_cloog_iv_types (s); + goto next; + } + + if (CLAST_STMT_IS_A (stmt, stmt_block)) + { + struct clast_stmt *s = ((struct clast_block *) stmt)->body; + compute_cloog_iv_types (s); + goto next; + } + + gcc_unreachable (); + + next: + compute_cloog_iv_types (stmt->next); +} + +/* Free the SCATTERING domain list. */ + +static void +free_scattering (CloogDomainList *scattering) +{ + while (scattering) + { + CloogDomain *dom = cloog_domain (scattering); + CloogDomainList *next = cloog_next_domain (scattering); + + cloog_domain_free (dom); + free (scattering); + scattering = next; + } +} + +/* Initialize Cloog's parameter names from the names used in GIMPLE. + Initialize Cloog's iterator names, using 'graphite_iterator_%d' + from 0 to scop_nb_loops (scop). */ + +static void +initialize_cloog_names (scop_p scop, CloogProgram *prog) +{ + sese region = SCOP_REGION (scop); + int i; + int nb_iterators = scop_max_loop_depth (scop); + int nb_scattering = cloog_program_nb_scattdims (prog); + char **iterators = XNEWVEC (char *, nb_iterators * 2); + char **scattering = XNEWVEC (char *, nb_scattering); + + cloog_program_set_names (prog, cloog_names_malloc ()); + cloog_names_set_nb_parameters (cloog_program_names (prog), + VEC_length (tree, SESE_PARAMS (region))); + cloog_names_set_parameters (cloog_program_names (prog), + SESE_PARAMS_NAMES (region)); + + for (i = 0; i < nb_iterators; i++) + { + int len = 4 + 16; + iterators[i] = XNEWVEC (char, len); + snprintf (iterators[i], len, "git_%d", i); + } + + cloog_names_set_nb_iterators (cloog_program_names (prog), + nb_iterators); + cloog_names_set_iterators (cloog_program_names (prog), + iterators); + + for (i = 0; i < nb_scattering; i++) + { + int len = 5 + 16; + scattering[i] = XNEWVEC (char, len); + snprintf (scattering[i], len, "scat_%d", i); + } + + cloog_names_set_nb_scattering (cloog_program_names (prog), + nb_scattering); + cloog_names_set_scattering (cloog_program_names (prog), + scattering); +} + +/* Build cloog program for SCoP. */ + +static void +build_cloog_prog (scop_p scop, CloogProgram *prog) +{ + int i; + int max_nb_loops = scop_max_loop_depth (scop); + poly_bb_p pbb; + CloogLoop *loop_list = NULL; + CloogBlockList *block_list = NULL; + CloogDomainList *scattering = NULL; + int nbs = 2 * max_nb_loops + 1; + int *scaldims; + + cloog_program_set_context + (prog, new_Cloog_Domain_from_ppl_Pointset_Powerset (SCOP_CONTEXT (scop))); + nbs = unify_scattering_dimensions (scop); + scaldims = (int *) xmalloc (nbs * (sizeof (int))); + cloog_program_set_nb_scattdims (prog, nbs); + initialize_cloog_names (scop, prog); + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + { + CloogStatement *stmt; + CloogBlock *block; + + /* Dead code elimination: when the domain of a PBB is empty, + don't generate code for the PBB. */ + if (ppl_Pointset_Powerset_C_Polyhedron_is_empty (PBB_DOMAIN (pbb))) + continue; + + /* Build the new statement and its block. */ + stmt = cloog_statement_alloc (GBB_BB (PBB_BLACK_BOX (pbb))->index); + block = cloog_block_alloc (stmt, 0, NULL, pbb_dim_iter_domain (pbb)); + cloog_statement_set_usr (stmt, pbb); + + /* Build loop list. */ + { + CloogLoop *new_loop_list = cloog_loop_malloc (); + cloog_loop_set_next (new_loop_list, loop_list); + cloog_loop_set_domain + (new_loop_list, + new_Cloog_Domain_from_ppl_Pointset_Powerset (PBB_DOMAIN (pbb))); + cloog_loop_set_block (new_loop_list, block); + loop_list = new_loop_list; + } + + /* Build block list. */ + { + CloogBlockList *new_block_list = cloog_block_list_malloc (); + + cloog_block_list_set_next (new_block_list, block_list); + cloog_block_list_set_block (new_block_list, block); + block_list = new_block_list; + } + + /* Build scattering list. */ + { + /* XXX: Replace with cloog_domain_list_alloc(), when available. */ + CloogDomainList *new_scattering + = (CloogDomainList *) xmalloc (sizeof (CloogDomainList)); + ppl_Polyhedron_t scat; + CloogDomain *dom; + + scat = PBB_TRANSFORMED_SCATTERING (pbb); + dom = new_Cloog_Domain_from_ppl_Polyhedron (scat); + + cloog_set_next_domain (new_scattering, scattering); + cloog_set_domain (new_scattering, dom); + scattering = new_scattering; + } + } + + cloog_program_set_loop (prog, loop_list); + cloog_program_set_blocklist (prog, block_list); + + for (i = 0; i < nbs; i++) + scaldims[i] = 0 ; + + cloog_program_set_scaldims (prog, scaldims); + + /* Extract scalar dimensions to simplify the code generation problem. */ + cloog_program_extract_scalars (prog, scattering); + + /* Apply scattering. */ + cloog_program_scatter (prog, scattering); + free_scattering (scattering); + + /* Iterators corresponding to scalar dimensions have to be extracted. */ + cloog_names_scalarize (cloog_program_names (prog), nbs, + cloog_program_scaldims (prog)); + + /* Free blocklist. */ + { + CloogBlockList *next = cloog_program_blocklist (prog); + + while (next) + { + CloogBlockList *toDelete = next; + next = cloog_block_list_next (next); + cloog_block_list_set_next (toDelete, NULL); + cloog_block_list_set_block (toDelete, NULL); + cloog_block_list_free (toDelete); + } + cloog_program_set_blocklist (prog, NULL); + } +} + +/* Return the options that will be used in GLOOG. */ + +static CloogOptions * +set_cloog_options (void) +{ + CloogOptions *options = cloog_options_malloc (); + + /* Change cloog output language to C. If we do use FORTRAN instead, cloog + will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if + we pass an incomplete program to cloog. */ + options->language = LANGUAGE_C; + + /* Enable complex equality spreading: removes dummy statements + (assignments) in the generated code which repeats the + substitution equations for statements. This is useless for + GLooG. */ + options->esp = 1; + + /* Enable C pretty-printing mode: normalizes the substitution + equations for statements. */ + options->cpp = 1; + + /* Allow cloog to build strides with a stride width different to one. + This example has stride = 4: + + for (i = 0; i < 20; i += 4) + A */ + options->strides = 1; + + /* Disable optimizations and make cloog generate source code closer to the + input. This is useful for debugging, but later we want the optimized + code. + + XXX: We can not disable optimizations, as loop blocking is not working + without them. */ + if (0) + { + options->f = -1; + options->l = INT_MAX; + } + + return options; +} + +/* Prints STMT to STDERR. */ + +void +print_clast_stmt (FILE *file, struct clast_stmt *stmt) +{ + CloogOptions *options = set_cloog_options (); + + pprint (file, stmt, 0, options); + cloog_options_free (options); +} + +/* Prints STMT to STDERR. */ + +void +debug_clast_stmt (struct clast_stmt *stmt) +{ + print_clast_stmt (stderr, stmt); +} + +/* Translate SCOP to a CLooG program and clast. These two + representations should be freed together: a clast cannot be used + without a program. */ + +cloog_prog_clast +scop_to_clast (scop_p scop) +{ + CloogOptions *options = set_cloog_options (); + cloog_prog_clast pc; + + /* Connect new cloog prog generation to graphite. */ + pc.prog = cloog_program_malloc (); + build_cloog_prog (scop, pc.prog); + pc.prog = cloog_program_generate (pc.prog, options); + pc.stmt = cloog_clast_create (pc.prog, options); + + cloog_options_free (options); + return pc; +} + +/* Prints to FILE the code generated by CLooG for SCOP. */ + +void +print_generated_program (FILE *file, scop_p scop) +{ + CloogOptions *options = set_cloog_options (); + cloog_prog_clast pc = scop_to_clast (scop); + + fprintf (file, " (prog: \n"); + cloog_program_print (file, pc.prog); + fprintf (file, " )\n"); + + fprintf (file, " (clast: \n"); + pprint (file, pc.stmt, 0, options); + fprintf (file, " )\n"); + + cloog_options_free (options); + cloog_clast_free (pc.stmt); + cloog_program_free (pc.prog); +} + +/* Prints to STDERR the code generated by CLooG for SCOP. */ + +void +debug_generated_program (scop_p scop) +{ + print_generated_program (stderr, scop); +} + +/* A LOOP is in normal form for Graphite when it contains only one + scalar phi node that defines the main induction variable of the + loop, only one increment of the IV, and only one exit condition. */ + +static void +graphite_loop_normal_form (loop_p loop) +{ + struct tree_niter_desc niter; + tree nit; + gimple_seq stmts; + edge exit = single_dom_exit (loop); + + bool known_niter = number_of_iterations_exit (loop, exit, &niter, false); + + /* At this point we should know the number of iterations, */ + gcc_assert (known_niter); + + nit = force_gimple_operand (unshare_expr (niter.niter), &stmts, true, + NULL_TREE); + if (stmts) + gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts); + + loop->aux = canonicalize_loop_ivs (loop, &nit); +} + +/* Converts REGION to loop normal form: one induction variable per loop. */ + +static void +build_graphite_loop_normal_form (sese region) +{ + int i; + loop_p loop; + + for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++) + graphite_loop_normal_form (loop); +} + +/* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for + the given SCOP. Return true if code generation succeeded. + BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping. +*/ + +bool +gloog (scop_p scop, htab_t bb_pbb_mapping) +{ + edge new_scop_exit_edge = NULL; + VEC (tree, heap) *newivs = VEC_alloc (tree, heap, 10); + loop_p context_loop; + sese region = SCOP_REGION (scop); + ifsese if_region = NULL; + htab_t rename_map, newivs_index; + cloog_prog_clast pc = scop_to_clast (scop); + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "\nCLAST generated by CLooG: \n"); + print_clast_stmt (dump_file, pc.stmt); + fprintf (dump_file, "\n"); + } + + build_graphite_loop_normal_form (region); + recompute_all_dominators (); + graphite_verify (); + + if_region = move_sese_in_condition (region); + sese_insert_phis_for_liveouts (region, + if_region->region->exit->src, + if_region->false_region->exit, + if_region->true_region->exit); + + recompute_all_dominators (); + graphite_verify (); + context_loop = SESE_ENTRY (region)->src->loop_father; + compute_cloog_iv_types (pc.stmt); + + rename_map = htab_create (10, rename_map_elt_info, eq_rename_map_elts, free); + newivs_index = htab_create (10, clast_name_index_elt_info, + eq_clast_name_indexes, free); + + new_scop_exit_edge = translate_clast (region, context_loop, pc.stmt, + if_region->true_region->entry, + rename_map, &newivs, newivs_index, + bb_pbb_mapping); + sese_reset_aux_in_loops (region); + graphite_verify (); + sese_adjust_liveout_phis (region, rename_map, + if_region->region->exit->src, + if_region->false_region->exit, + if_region->true_region->exit); + recompute_all_dominators (); + graphite_verify (); + + htab_delete (rename_map); + htab_delete (newivs_index); + VEC_free (tree, heap, newivs); + cloog_clast_free (pc.stmt); + cloog_program_free (pc.prog); + return true; +} + + + +/* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */ + +static poly_bb_p +find_pbb_via_hash (htab_t bb_pbb_mapping, basic_block bb) +{ + bb_pbb_def tmp; + PTR *slot; + + tmp.bb = bb; + slot = htab_find_slot (bb_pbb_mapping, &tmp, NO_INSERT); + + if (slot && *slot) + return ((bb_pbb_def *) *slot)->pbb; + + return NULL; +} + +/* Free loop->aux in newly created loops by translate_clast. */ + +void +free_aux_in_new_loops (void) +{ + loop_p loop; + loop_iterator li; + + FOR_EACH_LOOP (li, loop, 0) + { + if (!loop->aux) + continue; + free(loop->aux); + loop->aux = NULL; + } +} + +/* Check data dependency in LOOP. BB_PBB_MAPPING is a basic_block and + it's related poly_bb_p mapping. +*/ + +static bool +dependency_in_loop_p (loop_p loop, htab_t bb_pbb_mapping) +{ + unsigned i,j; + int level = 0; + basic_block *bbs = get_loop_body_in_dom_order (loop); + + level = *((int *)(loop->aux)); + + for (i = 0; i < loop->num_nodes; i++) + { + poly_bb_p pbb1 = find_pbb_via_hash (bb_pbb_mapping, bbs[i]); + + if (pbb1 == NULL) + continue; + + for (j = 0; j < loop->num_nodes; j++) + { + poly_bb_p pbb2 = find_pbb_via_hash (bb_pbb_mapping, bbs[j]); + + if (pbb2 == NULL) + continue; + + if (dependency_between_pbbs_p (pbb1, pbb2, level)) + { + free (bbs); + return true; + } + } + } + + free (bbs); + + return false; +} + +/* Mark loop as parallel if data dependency does not exist. + BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping. +*/ + +void mark_loops_parallel (htab_t bb_pbb_mapping) +{ + loop_p loop; + loop_iterator li; + int num_no_dependency = 0; + + FOR_EACH_LOOP (li, loop, 0) + { + if (!loop->aux) + continue; + + if (!dependency_in_loop_p (loop, bb_pbb_mapping)) + { + loop->can_be_parallel = true; + num_no_dependency++; + } + } + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "\n%d loops carried no dependency.\n", + num_no_dependency); + } +} + +#endif diff --git a/gcc/graphite-clast-to-gimple.h b/gcc/graphite-clast-to-gimple.h new file mode 100644 index 00000000000..e0ae6eedb3d --- /dev/null +++ b/gcc/graphite-clast-to-gimple.h @@ -0,0 +1,66 @@ +/* Translation of CLAST (CLooG AST) to Gimple. + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Sebastian Pop <sebastian.pop@amd.com>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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/>. */ + +#ifndef GCC_GRAPHITE_CLAST_TO_GIMPLE_H +#define GCC_GRAPHITE_CLAST_TO_GIMPLE_H + +/* Data structure for CLooG program representation. */ + +typedef struct cloog_prog_clast { + CloogProgram *prog; + struct clast_stmt *stmt; +} cloog_prog_clast; + +/* Stores BB's related PBB. */ + +typedef struct bb_pbb_def +{ + basic_block bb; + poly_bb_p pbb; +}bb_pbb_def; + +extern bool gloog (scop_p, htab_t); +extern cloog_prog_clast scop_to_clast (scop_p); +extern void debug_clast_stmt (struct clast_stmt *); +extern void print_clast_stmt (FILE *, struct clast_stmt *); +extern void debug_clast_name_indexes (htab_t); +extern void mark_loops_parallel (htab_t); +extern void free_aux_in_new_loops (void); + +/* Hash function for data base element BB_PBB. */ + +static inline hashval_t +bb_pbb_map_hash (const void *bb_pbb) +{ + return (hashval_t)(((const bb_pbb_def *)bb_pbb)->bb->index); +} + +/* Compare data base element BB_PBB1 and BB_PBB2. */ + +static inline int +eq_bb_pbb_map (const void *bb_pbb1, const void *bb_pbb2) +{ + const bb_pbb_def *bp1 = (const bb_pbb_def *) bb_pbb1; + const bb_pbb_def *bp2 = (const bb_pbb_def *) bb_pbb2; + return (bp1->bb->index == bp2->bb->index); +} + + +#endif diff --git a/gcc/graphite-dependences.c b/gcc/graphite-dependences.c new file mode 100644 index 00000000000..3cd41ede566 --- /dev/null +++ b/gcc/graphite-dependences.c @@ -0,0 +1,692 @@ +/* Data dependence analysis for Graphite. + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Sebastian Pop <sebastian.pop@amd.com> and + Konrad Trifunovic <konrad.trifunovic@inria.fr>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "ggc.h" +#include "tree.h" +#include "rtl.h" +#include "basic-block.h" +#include "diagnostic.h" +#include "tree-flow.h" +#include "toplev.h" +#include "tree-dump.h" +#include "timevar.h" +#include "cfgloop.h" +#include "tree-chrec.h" +#include "tree-data-ref.h" +#include "tree-scalar-evolution.h" +#include "tree-pass.h" +#include "domwalk.h" +#include "pointer-set.h" +#include "gimple.h" + +#ifdef HAVE_cloog +#include "cloog/cloog.h" +#include "ppl_c.h" +#include "sese.h" +#include "graphite-ppl.h" +#include "graphite.h" +#include "graphite-poly.h" +#include "graphite-dependences.h" + +/* Creates a new polyhedral data reference pair and + returns it. Parameter SOURCE denotes a source data reference + while parameter SINK denotes a sink data reference. Both + SOURCE and SINK define a pair of references, thus they + define an edge in DDG (Data Dependence Graph). */ + +static poly_dr_pair_p +new_poly_dr_pair (poly_dr_p source, + poly_dr_p sink, + ppl_Pointset_Powerset_C_Polyhedron_t ddp) +{ + poly_dr_pair_p pdrpp; + + pdrpp = XNEW (struct poly_dr_pair); + pdrpp->source = source; + pdrpp->sink = sink; + pdrpp->ddp = ddp; + + return pdrpp; +} + +/* Comparison function for poly_dr_pair hash table. */ + +int +eq_poly_dr_pair_p (const void *pdrpp1, const void *pdrpp2) +{ + const struct poly_dr_pair *p1 = (const struct poly_dr_pair *) pdrpp1; + const struct poly_dr_pair *p2 = (const struct poly_dr_pair *) pdrpp2; + + return (p1->source == p2->source + && p1->sink == p2->sink); +} + +/* Hash function for poly_dr_pair hashtable. */ + +hashval_t +hash_poly_dr_pair_p (const void *pdrpp) +{ + const struct poly_dr_pair *p = (const struct poly_dr_pair *) pdrpp; + + return (hashval_t) ((long) p->source + (long) p->sink); +} + +/* Returns a polyhedron of dimension DIM. + + Maps the dimensions [0, ..., cut - 1] of polyhedron P to OFFSET0 + and the dimensions [cut, ..., nb_dim] to DIM - GDIM. */ + +static ppl_Pointset_Powerset_C_Polyhedron_t +map_into_dep_poly (graphite_dim_t dim, graphite_dim_t gdim, + ppl_Pointset_Powerset_C_Polyhedron_t p, + graphite_dim_t cut, + graphite_dim_t offset) +{ + ppl_Pointset_Powerset_C_Polyhedron_t res; + + ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron + (&res, p); + ppl_insert_dimensions_pointset (res, 0, offset); + ppl_insert_dimensions_pointset (res, offset + cut, + dim - offset - cut - gdim); + + return res; +} + +/* Swap [cut0, ..., cut1] to the end of DR: "a CUT0 b CUT1 c" is + transformed into "a CUT0 c CUT1' b" + + Add NB0 zeros before "a": "00...0 a CUT0 c CUT1' b" + Add NB1 zeros between "a" and "c": "00...0 a 00...0 c CUT1' b" + Add DIM - NB0 - NB1 - PDIM zeros between "c" and "b": + "00...0 a 00...0 c 00...0 b". */ + +static ppl_Pointset_Powerset_C_Polyhedron_t +map_dr_into_dep_poly (graphite_dim_t dim, + ppl_Pointset_Powerset_C_Polyhedron_t dr, + graphite_dim_t cut0, graphite_dim_t cut1, + graphite_dim_t nb0, graphite_dim_t nb1) +{ + ppl_dimension_type pdim; + ppl_dimension_type *map; + ppl_Pointset_Powerset_C_Polyhedron_t res; + ppl_dimension_type i; + + ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron + (&res, dr); + ppl_Pointset_Powerset_C_Polyhedron_space_dimension (res, &pdim); + + map = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, pdim); + + /* First mapping: move 'g' vector to right position. */ + for (i = 0; i < cut0; i++) + map[i] = i; + + for (i = cut0; i < cut1; i++) + map[i] = pdim - cut1 + i; + + for (i = cut1; i < pdim; i++) + map[i] = cut0 + i - cut1; + + ppl_Pointset_Powerset_C_Polyhedron_map_space_dimensions (res, map, pdim); + free (map); + + /* After swapping 's' and 'g' vectors, we have to update a new cut. */ + cut1 = pdim - cut1 + cut0; + + ppl_insert_dimensions_pointset (res, 0, nb0); + ppl_insert_dimensions_pointset (res, nb0 + cut0, nb1); + ppl_insert_dimensions_pointset (res, nb0 + nb1 + cut1, + dim - nb0 - nb1 - pdim); + + return res; +} + +/* Builds a constraints of the form "POS1 - POS2 CSTR_TYPE C" */ + +static ppl_Constraint_t +build_pairwise_constraint (graphite_dim_t dim, + graphite_dim_t pos1, graphite_dim_t pos2, + int c, enum ppl_enum_Constraint_Type cstr_type) +{ + ppl_Linear_Expression_t expr; + ppl_Constraint_t cstr; + ppl_Coefficient_t coef; + Value v, v_op, v_c; + + value_init (v); + value_init (v_op); + value_init (v_c); + + value_set_si (v, 1); + value_set_si (v_op, -1); + value_set_si (v_c, c); + + ppl_new_Coefficient (&coef); + ppl_new_Linear_Expression_with_dimension (&expr, dim); + + ppl_assign_Coefficient_from_mpz_t (coef, v); + ppl_Linear_Expression_add_to_coefficient (expr, pos1, coef); + ppl_assign_Coefficient_from_mpz_t (coef, v_op); + ppl_Linear_Expression_add_to_coefficient (expr, pos2, coef); + ppl_assign_Coefficient_from_mpz_t (coef, v_c); + ppl_Linear_Expression_add_to_inhomogeneous (expr, coef); + + ppl_new_Constraint (&cstr, expr, cstr_type); + + ppl_delete_Linear_Expression (expr); + ppl_delete_Coefficient (coef); + value_clear (v); + value_clear (v_op); + value_clear (v_c); + + return cstr; +} + +/* Builds subscript equality constraints. */ + +static ppl_Pointset_Powerset_C_Polyhedron_t +dr_equality_constraints (graphite_dim_t dim, + graphite_dim_t pos, graphite_dim_t nb_subscripts) +{ + ppl_Polyhedron_t subscript_equalities; + ppl_Pointset_Powerset_C_Polyhedron_t res; + Value v, v_op; + graphite_dim_t i; + + value_init (v); + value_init (v_op); + value_set_si (v, 1); + value_set_si (v_op, -1); + + ppl_new_C_Polyhedron_from_space_dimension (&subscript_equalities, dim, 0); + for (i = 0; i < nb_subscripts; i++) + { + ppl_Linear_Expression_t expr; + ppl_Constraint_t cstr; + ppl_Coefficient_t coef; + + ppl_new_Coefficient (&coef); + ppl_new_Linear_Expression_with_dimension (&expr, dim); + + ppl_assign_Coefficient_from_mpz_t (coef, v); + ppl_Linear_Expression_add_to_coefficient (expr, pos + i, coef); + ppl_assign_Coefficient_from_mpz_t (coef, v_op); + ppl_Linear_Expression_add_to_coefficient (expr, pos + i + nb_subscripts, + coef); + + ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL); + ppl_Polyhedron_add_constraint (subscript_equalities, cstr); + + ppl_delete_Linear_Expression (expr); + ppl_delete_Constraint (cstr); + ppl_delete_Coefficient (coef); + } + + ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron + (&res, subscript_equalities); + value_clear (v); + value_clear (v_op); + ppl_delete_Polyhedron (subscript_equalities); + + return res; +} + +/* Builds scheduling equality constraints. */ + +static ppl_Pointset_Powerset_C_Polyhedron_t +build_pairwise_scheduling_equality (graphite_dim_t dim, + graphite_dim_t pos, graphite_dim_t offset) +{ + ppl_Pointset_Powerset_C_Polyhedron_t res; + ppl_Polyhedron_t equalities; + ppl_Constraint_t cstr; + + ppl_new_C_Polyhedron_from_space_dimension (&equalities, dim, 0); + + cstr = build_pairwise_constraint (dim, pos, pos + offset, 0, + PPL_CONSTRAINT_TYPE_EQUAL); + ppl_Polyhedron_add_constraint (equalities, cstr); + ppl_delete_Constraint (cstr); + + ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&res, equalities); + ppl_delete_Polyhedron (equalities); + return res; +} + +/* Builds scheduling inequality constraints. */ + +static ppl_Pointset_Powerset_C_Polyhedron_t +build_pairwise_scheduling_inequality (graphite_dim_t dim, + graphite_dim_t pos, + graphite_dim_t offset, + bool direction) +{ + ppl_Pointset_Powerset_C_Polyhedron_t res; + ppl_Polyhedron_t equalities; + ppl_Constraint_t cstr; + + ppl_new_C_Polyhedron_from_space_dimension (&equalities, dim, 0); + + if (direction) + cstr = build_pairwise_constraint (dim, pos, pos + offset, -1, + PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL); + else + cstr = build_pairwise_constraint (dim, pos, pos + offset, 1, + PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL); + + ppl_Polyhedron_add_constraint (equalities, cstr); + ppl_delete_Constraint (cstr); + + ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&res, equalities); + ppl_delete_Polyhedron (equalities); + return res; +} + +/* Returns true when adding the lexicographical constraints at level I + to the RES dependence polyhedron returns an empty polyhedron. */ + +static bool +lexicographically_gt_p (ppl_Pointset_Powerset_C_Polyhedron_t res, + graphite_dim_t dim, + graphite_dim_t offset, + bool direction, graphite_dim_t i) +{ + ppl_Pointset_Powerset_C_Polyhedron_t ineq; + bool empty_p; + + ineq = build_pairwise_scheduling_inequality (dim, i, offset, + direction); + ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (ineq, res); + empty_p = ppl_Pointset_Powerset_C_Polyhedron_is_empty (ineq); + if (!empty_p) + ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (res, ineq); + ppl_delete_Pointset_Powerset_C_Polyhedron (ineq); + + return !empty_p; +} + +/* Build the precedence constraints for the lexicographical comparison + of time vectors RES following the lexicographical order. */ + +static void +build_lexicographically_gt_constraint (ppl_Pointset_Powerset_C_Polyhedron_t *res, + graphite_dim_t dim, + graphite_dim_t tdim1, + graphite_dim_t offset, + bool direction) +{ + graphite_dim_t i; + + if (lexicographically_gt_p (*res, dim, offset, direction, 0)) + return; + + for (i = 0; i < tdim1 - 1; i++) + { + ppl_Pointset_Powerset_C_Polyhedron_t sceq; + + sceq = build_pairwise_scheduling_equality (dim, i, offset); + ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (*res, sceq); + ppl_delete_Pointset_Powerset_C_Polyhedron (sceq); + + if (lexicographically_gt_p (*res, dim, offset, direction, i + 1)) + return; + } + + if (i == tdim1 - 1) + { + ppl_delete_Pointset_Powerset_C_Polyhedron (*res); + ppl_new_Pointset_Powerset_C_Polyhedron_from_space_dimension (res, dim, 1); + } +} + +/* Build the dependence polyhedron for data references PDR1 and PDR2. */ + +static ppl_Pointset_Powerset_C_Polyhedron_t +dependence_polyhedron_1 (poly_bb_p pbb1, poly_bb_p pbb2, + ppl_Pointset_Powerset_C_Polyhedron_t d1, + ppl_Pointset_Powerset_C_Polyhedron_t d2, + poly_dr_p pdr1, poly_dr_p pdr2, + ppl_Polyhedron_t s1, ppl_Polyhedron_t s2, + bool direction, + bool original_scattering_p) +{ + scop_p scop = PBB_SCOP (pbb1); + graphite_dim_t tdim1 = original_scattering_p ? + pbb_nb_scattering_orig (pbb1) : pbb_nb_scattering_transform (pbb1); + graphite_dim_t tdim2 = original_scattering_p ? + pbb_nb_scattering_orig (pbb2) : pbb_nb_scattering_transform (pbb2); + graphite_dim_t ddim1 = pbb_dim_iter_domain (pbb1); + graphite_dim_t ddim2 = pbb_dim_iter_domain (pbb2); + graphite_dim_t sdim1 = pdr_nb_subscripts (pdr1) + 1; + graphite_dim_t gdim = scop_nb_params (scop); + graphite_dim_t dim1 = pdr_dim (pdr1); + graphite_dim_t dim2 = pdr_dim (pdr2); + graphite_dim_t dim = tdim1 + tdim2 + dim1 + dim2; + ppl_Pointset_Powerset_C_Polyhedron_t res; + ppl_Pointset_Powerset_C_Polyhedron_t id1, id2, isc1, isc2, idr1, idr2; + ppl_Pointset_Powerset_C_Polyhedron_t sc1, sc2, dreq; + + gcc_assert (PBB_SCOP (pbb1) == PBB_SCOP (pbb2)); + ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&sc1, s1); + ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&sc2, s2); + + id1 = map_into_dep_poly (dim, gdim, d1, ddim1, tdim1); + id2 = map_into_dep_poly (dim, gdim, d2, ddim2, tdim1 + ddim1 + tdim2); + isc1 = map_into_dep_poly (dim, gdim, sc1, ddim1 + tdim1, 0); + isc2 = map_into_dep_poly (dim, gdim, sc2, ddim2 + tdim2, tdim1 + ddim1); + + idr1 = map_dr_into_dep_poly (dim, PDR_ACCESSES (pdr1), ddim1, ddim1 + gdim, + tdim1, tdim2 + ddim2); + idr2 = map_dr_into_dep_poly (dim, PDR_ACCESSES (pdr2), ddim2, ddim2 + gdim, + tdim1 + ddim1 + tdim2, sdim1); + + /* Now add the subscript equalities. */ + dreq = dr_equality_constraints (dim, tdim1 + ddim1 + tdim2 + ddim2, sdim1); + + ppl_new_Pointset_Powerset_C_Polyhedron_from_space_dimension (&res, dim, 0); + ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (res, id1); + ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (res, id2); + ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (res, isc1); + ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (res, isc2); + ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (res, idr1); + ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (res, idr2); + ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (res, dreq); + ppl_delete_Pointset_Powerset_C_Polyhedron (id1); + ppl_delete_Pointset_Powerset_C_Polyhedron (id2); + ppl_delete_Pointset_Powerset_C_Polyhedron (sc1); + ppl_delete_Pointset_Powerset_C_Polyhedron (sc2); + ppl_delete_Pointset_Powerset_C_Polyhedron (isc1); + ppl_delete_Pointset_Powerset_C_Polyhedron (isc2); + ppl_delete_Pointset_Powerset_C_Polyhedron (idr1); + ppl_delete_Pointset_Powerset_C_Polyhedron (idr2); + ppl_delete_Pointset_Powerset_C_Polyhedron (dreq); + + if (!ppl_Pointset_Powerset_C_Polyhedron_is_empty (res)) + build_lexicographically_gt_constraint (&res, dim, MIN (tdim1, tdim2), + tdim1 + ddim1, direction); + return res; +} + +/* Build the dependence polyhedron for data references PDR1 and PDR2. + If possible use already cached information. */ + +static ppl_Pointset_Powerset_C_Polyhedron_t +dependence_polyhedron (poly_bb_p pbb1, poly_bb_p pbb2, + ppl_Pointset_Powerset_C_Polyhedron_t d1, + ppl_Pointset_Powerset_C_Polyhedron_t d2, + poly_dr_p pdr1, poly_dr_p pdr2, + ppl_Polyhedron_t s1, ppl_Polyhedron_t s2, + bool direction, + bool original_scattering_p) +{ + poly_dr_pair tmp; + PTR *x = NULL; + ppl_Pointset_Powerset_C_Polyhedron_t res; + + if (original_scattering_p) + { + tmp.source = pdr1; + tmp.sink = pdr2; + x = htab_find_slot (SCOP_ORIGINAL_PDR_PAIRS (PBB_SCOP (pbb1)), + &tmp, INSERT); + + if (x && *x) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "\nddp cache: hit.\n"); + return ((poly_dr_pair *)*x)->ddp; + } + else if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "\nddp cache: miss.\n"); + } + + res = dependence_polyhedron_1 (pbb1, pbb2, d1, d2, pdr1, pdr2, + s1, s2, direction, original_scattering_p); + + if (original_scattering_p) + { + gcc_assert (x && *x == NULL); + *x = new_poly_dr_pair (pdr1, pdr2, res); + + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "\nddp cache: add element.\n"); + } + + return res; +} + +/* Returns true when the PBB_TRANSFORMED_SCATTERING functions of PBB1 + and PBB2 respect the data dependences of PBB_ORIGINAL_SCATTERING + functions. */ + +static bool +graphite_legal_transform_dr (poly_bb_p pbb1, poly_bb_p pbb2, + poly_dr_p pdr1, poly_dr_p pdr2) +{ + ppl_Pointset_Powerset_C_Polyhedron_t d1 = PBB_DOMAIN (pbb1); + ppl_Pointset_Powerset_C_Polyhedron_t d2 = PBB_DOMAIN (pbb2); + ppl_Polyhedron_t so1 = PBB_ORIGINAL_SCATTERING (pbb1); + ppl_Polyhedron_t so2 = PBB_ORIGINAL_SCATTERING (pbb2); + ppl_Pointset_Powerset_C_Polyhedron_t po; + + graphite_dim_t sdim1 = pdr_nb_subscripts (pdr1) + 1; + graphite_dim_t sdim2 = pdr_nb_subscripts (pdr2) + 1; + + if (sdim1 != sdim2) + return true; + + po = dependence_polyhedron (pbb1, pbb2, d1, d2, pdr1, pdr2, so1, so2, + true, true); + + if (ppl_Pointset_Powerset_C_Polyhedron_is_empty (po)) + return true; + else + { + ppl_Polyhedron_t st1 = PBB_TRANSFORMED_SCATTERING (pbb1); + ppl_Polyhedron_t st2 = PBB_TRANSFORMED_SCATTERING (pbb2); + ppl_Pointset_Powerset_C_Polyhedron_t pt; + graphite_dim_t ddim1 = pbb_dim_iter_domain (pbb1); + graphite_dim_t otdim1 = pbb_nb_scattering_orig (pbb1); + graphite_dim_t otdim2 = pbb_nb_scattering_orig (pbb2); + graphite_dim_t ttdim1 = pbb_nb_scattering_transform (pbb1); + graphite_dim_t ttdim2 = pbb_nb_scattering_transform (pbb2); + + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "\nloop carries dependency.\n"); + pt = dependence_polyhedron (pbb1, pbb2, d1, d2, pdr1, pdr2, st1, st2, + false, false); + + /* Extend PO and PT to have the same dimensions. */ + ppl_insert_dimensions_pointset (po, otdim1, ttdim1); + ppl_insert_dimensions_pointset (po, otdim1 + ttdim1 + ddim1 + otdim2, + ttdim2); + ppl_insert_dimensions_pointset (pt, 0, otdim1); + ppl_insert_dimensions_pointset (pt, otdim1 + ttdim1 + ddim1, otdim2); + + ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (po, pt); + return ppl_Pointset_Powerset_C_Polyhedron_is_empty (po); + } +} + +/* Iterates over the data references of PBB1 and PBB2 and detect + whether the transformed schedule is correct. */ + +static bool +graphite_legal_transform_bb (poly_bb_p pbb1, poly_bb_p pbb2) +{ + int i, j; + poly_dr_p pdr1, pdr2; + + for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb1), i, pdr1); i++) + for (j = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb2), j, pdr2); j++) + if (!graphite_legal_transform_dr (pbb1, pbb2, pdr1, pdr2)) + return false; + return true; +} + +/* Iterates over the SCOP and detect whether the transformed schedule + is correct. */ + +bool +graphite_legal_transform (scop_p scop) +{ + int i, j; + poly_bb_p pbb1, pbb2; + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb1); i++) + for (j = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), j, pbb2); j++) + if (!graphite_legal_transform_bb (pbb1, pbb2)) + return false; + + return true; +} + +/* Remove all the dimensions except alias information at dimension + ALIAS_DIM. */ + +static void +build_alias_set_powerset (ppl_Pointset_Powerset_C_Polyhedron_t alias_powerset, + ppl_dimension_type alias_dim) +{ + ppl_dimension_type *ds; + ppl_dimension_type access_dim; + unsigned i, pos = 0; + + ppl_Pointset_Powerset_C_Polyhedron_space_dimension (alias_powerset, + &access_dim); + ds = XNEWVEC (ppl_dimension_type, access_dim-1); + for (i = 0; i < access_dim; i++) + { + if (i == alias_dim) + continue; + + ds[pos] = i; + pos++; + } + + ppl_Pointset_Powerset_C_Polyhedron_remove_space_dimensions (alias_powerset, + ds, + access_dim - 1); + free (ds); +} + +/* Return true when PDR1 and PDR2 may alias. */ + +static bool +poly_drs_may_alias_p (poly_dr_p pdr1, poly_dr_p pdr2) +{ + ppl_Pointset_Powerset_C_Polyhedron_t alias_powerset1, alias_powerset2; + ppl_Pointset_Powerset_C_Polyhedron_t accesses1 = PDR_ACCESSES (pdr1); + ppl_Pointset_Powerset_C_Polyhedron_t accesses2 = PDR_ACCESSES (pdr2); + ppl_dimension_type alias_dim1 = pdr_alias_set_dim (pdr1); + ppl_dimension_type alias_dim2 = pdr_alias_set_dim (pdr2); + int empty_p; + + ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron + (&alias_powerset1, accesses1); + ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron + (&alias_powerset2, accesses2); + + build_alias_set_powerset (alias_powerset1, alias_dim1); + build_alias_set_powerset (alias_powerset2, alias_dim2); + + ppl_Pointset_Powerset_C_Polyhedron_intersection_assign + (alias_powerset1, alias_powerset2); + + empty_p = ppl_Pointset_Powerset_C_Polyhedron_is_empty (alias_powerset1); + + ppl_delete_Pointset_Powerset_C_Polyhedron (alias_powerset1); + ppl_delete_Pointset_Powerset_C_Polyhedron (alias_powerset2); + + return !empty_p; +} + +/* Returns TRUE when the dependence polyhedron between PDR1 and + PDR2 represents a loop carried dependence at level LEVEL. Otherwise + return FALSE. */ + +static bool +graphite_carried_dependence_level_k (poly_dr_p pdr1, poly_dr_p pdr2, + int level) +{ + poly_bb_p pbb1 = PDR_PBB (pdr1); + poly_bb_p pbb2 = PDR_PBB (pdr2); + ppl_Pointset_Powerset_C_Polyhedron_t d1 = PBB_DOMAIN (pbb1); + ppl_Pointset_Powerset_C_Polyhedron_t d2 = PBB_DOMAIN (pbb2); + ppl_Polyhedron_t so1 = PBB_TRANSFORMED_SCATTERING (pbb1); + ppl_Polyhedron_t so2 = PBB_TRANSFORMED_SCATTERING (pbb2); + ppl_Pointset_Powerset_C_Polyhedron_t po; + ppl_Pointset_Powerset_C_Polyhedron_t eqpp; + graphite_dim_t sdim1 = pdr_nb_subscripts (pdr1) + 1; + graphite_dim_t sdim2 = pdr_nb_subscripts (pdr2) + 1; + graphite_dim_t tdim1 = pbb_nb_scattering_transform (pbb1); + graphite_dim_t ddim1 = pbb_dim_iter_domain (pbb1); + ppl_dimension_type dim; + bool empty_p; + + if ((PDR_TYPE (pdr1) == PDR_READ && PDR_TYPE (pdr2) == PDR_READ) + || !poly_drs_may_alias_p (pdr1, pdr2)) + return false; + + if (sdim1 != sdim2) + return true; + + po = dependence_polyhedron (pbb1, pbb2, d1, d2, pdr1, pdr2, so1, so2, + true, false); + if (ppl_Pointset_Powerset_C_Polyhedron_is_empty (po)) + { + ppl_delete_Pointset_Powerset_C_Polyhedron (po); + return false; + } + + ppl_Pointset_Powerset_C_Polyhedron_space_dimension (po, &dim); + eqpp = build_pairwise_scheduling_inequality (dim, level, tdim1 + ddim1, 1); + + ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (eqpp, po); + empty_p = ppl_Pointset_Powerset_C_Polyhedron_is_empty (eqpp); + + ppl_delete_Pointset_Powerset_C_Polyhedron (po); + ppl_delete_Pointset_Powerset_C_Polyhedron (eqpp); + return !empty_p; +} + +/* Check data dependency between PBB1 and PBB2 at level LEVEL. */ + +bool +dependency_between_pbbs_p (poly_bb_p pbb1, poly_bb_p pbb2, int level) +{ + int i, j; + poly_dr_p pdr1, pdr2; + + for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb1), i, pdr1); i++) + for (j = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb2), j, pdr2); j++) + if (graphite_carried_dependence_level_k (pdr1, pdr2, level)) + return true; + + return false; +} + +#endif diff --git a/gcc/graphite-dependences.h b/gcc/graphite-dependences.h new file mode 100644 index 00000000000..ccf0b971b23 --- /dev/null +++ b/gcc/graphite-dependences.h @@ -0,0 +1,50 @@ +/* Graphite polyhedral representation. + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Konrad Trifunovic <konrad.trifunovic@gmail.com> + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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/>. */ + +#ifndef GCC_GRAPHITE_DEPENDENCES_H +#define GCC_GRAPHITE_DEPENDENCES_H + +extern bool graphite_legal_transform (scop_p); +extern bool dependency_between_pbbs_p (poly_bb_p, poly_bb_p, int); + +typedef struct poly_dr_pair *poly_dr_pair_p; + +typedef struct poly_dr_pair +{ + /* Source polyhedral data reference of the dependence. */ + poly_dr_p source; + + /* Sink data reference of the dependence. */ + poly_dr_p sink; + + /* Data dependence polyhedron descibing dependence + between SOURCE and SINK data references. */ + ppl_Pointset_Powerset_C_Polyhedron_t ddp; +}poly_dr_pair; + + +#define PDRP_SOURCE(PDRP) (PDR->source) +#define PDRP_SINK(PDRP) (PDR->sink) +#define PDRP_DDP(PDRP) (PDR->ddp) + +extern int eq_poly_dr_pair_p (const void *, const void *); +extern hashval_t hash_poly_dr_pair_p (const void *); + +#endif diff --git a/gcc/graphite-interchange.c b/gcc/graphite-interchange.c new file mode 100644 index 00000000000..4639afe68d3 --- /dev/null +++ b/gcc/graphite-interchange.c @@ -0,0 +1,398 @@ +/* Interchange heuristics and transform for loop interchange on + polyhedral representation. + + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Sebastian Pop <sebastian.pop@amd.com> and + Harsha Jagasia <harsha.jagasia@amd.com>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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/>. */ +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "ggc.h" +#include "tree.h" +#include "rtl.h" +#include "output.h" +#include "basic-block.h" +#include "diagnostic.h" +#include "tree-flow.h" +#include "toplev.h" +#include "tree-dump.h" +#include "timevar.h" +#include "cfgloop.h" +#include "tree-chrec.h" +#include "tree-data-ref.h" +#include "tree-scalar-evolution.h" +#include "tree-pass.h" +#include "domwalk.h" +#include "value-prof.h" +#include "pointer-set.h" +#include "gimple.h" +#include "params.h" + +#ifdef HAVE_cloog +#include "cloog/cloog.h" +#include "ppl_c.h" +#include "sese.h" +#include "graphite-ppl.h" +#include "graphite.h" +#include "graphite-poly.h" + +/* Returns the subscript dimension defined by CSTR in PDR. */ + +static ppl_dimension_type +compute_subscript (poly_dr_p pdr, ppl_const_Constraint_t cstr) +{ + graphite_dim_t i; + ppl_Linear_Expression_t expr; + ppl_Coefficient_t coef; + Value val; + + value_init (val); + ppl_new_Coefficient (&coef); + + for (i = 0; i < pdr_nb_subscripts (pdr); i++) + { + ppl_dimension_type sub_dim = pdr_subscript_dim (pdr, i); + + ppl_new_Linear_Expression_from_Constraint (&expr, cstr); + ppl_Linear_Expression_coefficient (expr, sub_dim, coef); + ppl_delete_Linear_Expression (expr); + ppl_Coefficient_to_mpz_t (coef, val); + + if (value_notzero_p (val)) + { + gcc_assert (value_one_p (val) + || value_mone_p (val)); + + value_clear (val); + ppl_delete_Coefficient (coef); + return sub_dim; + } + } + + gcc_unreachable (); + return 0; +} + +static void +compute_array_size_cstr (ppl_dimension_type sub_dim, Value res, + ppl_const_Constraint_t cstr) +{ + ppl_Linear_Expression_t expr; + ppl_Coefficient_t coef; + Value val; + + value_init (val); + ppl_new_Coefficient (&coef); + ppl_new_Linear_Expression_from_Constraint (&expr, cstr); + ppl_Linear_Expression_coefficient (expr, sub_dim, coef); + ppl_Coefficient_to_mpz_t (coef, val); + + value_set_si (res, 0); + + if (value_notzero_p (val)) + { + gcc_assert (value_one_p (val) || value_mone_p (val)); + ppl_Linear_Expression_inhomogeneous_term (expr, coef); + ppl_Coefficient_to_mpz_t (coef, res); + value_absolute (res, res); + } + + value_clear (val); + ppl_delete_Coefficient (coef); + ppl_delete_Linear_Expression (expr); +} + +/* Returns in ARRAY_SIZE the size in bytes of the array PDR for the + subscript at dimension SUB_DIM. */ + +static void +compute_array_size_poly (poly_dr_p pdr, ppl_dimension_type sub_dim, Value array_size, + ppl_const_Polyhedron_t ph) +{ + ppl_const_Constraint_System_t pcs; + ppl_Constraint_System_const_iterator_t cit, cend; + ppl_const_Constraint_t cstr; + Value val; + Value res; + + if (sub_dim >= pdr_subscript_dim (pdr, pdr_nb_subscripts (pdr))) + { + value_set_si (array_size, 1); + return; + } + + value_init (val); + value_init (res); + + value_set_si (res, 0); + + ppl_Polyhedron_get_constraints (ph, &pcs); + ppl_new_Constraint_System_const_iterator (&cit); + ppl_new_Constraint_System_const_iterator (&cend); + + for (ppl_Constraint_System_begin (pcs, cit), + ppl_Constraint_System_end (pcs, cend); + !ppl_Constraint_System_const_iterator_equal_test (cit, cend); + ppl_Constraint_System_const_iterator_increment (cit)) + { + ppl_Constraint_System_const_iterator_dereference (cit, &cstr); + + if (ppl_Constraint_type (cstr) == PPL_CONSTRAINT_TYPE_EQUAL) + continue; + + compute_array_size_cstr (sub_dim, val, cstr); + value_max (res, res, val); + } + + compute_array_size_poly (pdr, sub_dim + 1, val, ph); + value_multiply (array_size, res, val); + + value_clear (res); + value_clear (val); +} + +/* Initializes ARRAY_SIZE, the size in bytes of the array for the + subscript at dimension SUB_DIM in PDR. */ + +static void +compute_array_size (poly_dr_p pdr, ppl_dimension_type sub_dim, Value array_size) +{ + ppl_Pointset_Powerset_C_Polyhedron_t data_container = PDR_DATA_CONTAINER (pdr); + ppl_Pointset_Powerset_C_Polyhedron_iterator_t it, end; + Value val; + + value_set_si (array_size, 1); + if (sub_dim >= pdr_subscript_dim (pdr, pdr_nb_subscripts (pdr))) + return; + + value_init (val); + ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&it); + ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&end); + + for (ppl_Pointset_Powerset_C_Polyhedron_iterator_begin (data_container, it), + ppl_Pointset_Powerset_C_Polyhedron_iterator_end (data_container, end); + !ppl_Pointset_Powerset_C_Polyhedron_iterator_equal_test (it, end); + ppl_Pointset_Powerset_C_Polyhedron_iterator_increment (it)) + { + ppl_const_Polyhedron_t ph; + + ppl_Pointset_Powerset_C_Polyhedron_iterator_dereference (it, &ph); + compute_array_size_poly (pdr, sub_dim, val, ph); + value_max (array_size, array_size, val); + } + + value_clear (val); + ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (it); + ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (end); +} + +/* Computes ACCESS_STRIDES, the sum of all the strides of PDR at + LOOP_DEPTH. */ + +static void +gather_access_strides_poly (poly_dr_p pdr, ppl_const_Polyhedron_t ph, + ppl_dimension_type loop_dim, Value res) +{ + ppl_const_Constraint_System_t pcs; + ppl_Constraint_System_const_iterator_t cit, cend; + ppl_const_Constraint_t cstr; + ppl_Linear_Expression_t expr; + ppl_Coefficient_t coef; + Value stride; + Value array_size; + + value_init (array_size); + value_init (stride); + ppl_new_Coefficient (&coef); + value_set_si (res, 0); + + ppl_Polyhedron_get_constraints (ph, &pcs); + ppl_new_Constraint_System_const_iterator (&cit); + ppl_new_Constraint_System_const_iterator (&cend); + + for (ppl_Constraint_System_begin (pcs, cit), + ppl_Constraint_System_end (pcs, cend); + !ppl_Constraint_System_const_iterator_equal_test (cit, cend); + ppl_Constraint_System_const_iterator_increment (cit)) + { + ppl_Constraint_System_const_iterator_dereference (cit, &cstr); + ppl_new_Linear_Expression_from_Constraint (&expr, cstr); + ppl_Linear_Expression_coefficient (expr, loop_dim, coef); + ppl_delete_Linear_Expression (expr); + ppl_Coefficient_to_mpz_t (coef, stride); + + if (value_zero_p (stride)) + continue; + + value_absolute (stride, stride); + compute_array_size (pdr, compute_subscript (pdr, cstr), array_size); + value_multiply (stride, stride, array_size); + value_addto (res, res, stride); + } + + value_clear (array_size); + value_clear (stride); + ppl_delete_Coefficient (coef); + ppl_delete_Constraint_System_const_iterator (cit); + ppl_delete_Constraint_System_const_iterator (cend); +} + +/* Computes ACCESS_STRIDES, the sum of all the strides of PDR at + LOOP_DEPTH. */ + +static void +gather_access_strides (poly_dr_p pdr, graphite_dim_t loop_depth, + Value access_strides) +{ + ppl_dimension_type loop_dim = pdr_iterator_dim (pdr, loop_depth); + + ppl_Pointset_Powerset_C_Polyhedron_t accesses = PDR_ACCESSES (pdr); + ppl_Pointset_Powerset_C_Polyhedron_iterator_t it, end; + Value res; + + value_init (res); + ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&it); + ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&end); + + for (ppl_Pointset_Powerset_C_Polyhedron_iterator_begin (accesses, it), + ppl_Pointset_Powerset_C_Polyhedron_iterator_end (accesses, end); + !ppl_Pointset_Powerset_C_Polyhedron_iterator_equal_test (it, end); + ppl_Pointset_Powerset_C_Polyhedron_iterator_increment (it)) + { + ppl_const_Polyhedron_t ph; + + ppl_Pointset_Powerset_C_Polyhedron_iterator_dereference (it, &ph); + gather_access_strides_poly (pdr, ph, loop_dim, res); + value_addto (access_strides, access_strides, res); + } + + value_clear (res); + ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (it); + ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (end); +} + +/* Returns true when it is profitable to interchange loop at depth1 + and loop at depth2 with depth1 < depth2 for the polyhedral black + box PBB. */ + +static bool +pbb_interchange_profitable_p (graphite_dim_t depth1, graphite_dim_t depth2, poly_bb_p pbb) +{ + int i; + poly_dr_p pdr; + Value access_strides1, access_strides2; + bool res; + + gcc_assert (depth1 < depth2); + + value_init (access_strides1); + value_init (access_strides2); + + value_set_si (access_strides1, 0); + value_set_si (access_strides2, 0); + + for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb), i, pdr); i++) + { + gather_access_strides (pdr, depth1, access_strides1); + gather_access_strides (pdr, depth2, access_strides2); + } + + res = value_lt (access_strides1, access_strides2); + + value_clear (access_strides1); + value_clear (access_strides2); + + return res; +} + +/* Interchanges the loops at DEPTH1 and DEPTH2 of the original + scattering and assigns the resulting polyhedron to the transformed + scattering. */ + +static void +pbb_interchange_loop_depths (graphite_dim_t depth1, graphite_dim_t depth2, poly_bb_p pbb) +{ + ppl_dimension_type i, dim; + ppl_dimension_type *map; + ppl_Polyhedron_t poly = PBB_TRANSFORMED_SCATTERING (pbb); + ppl_dimension_type dim1 = psct_iterator_dim (pbb, depth1); + ppl_dimension_type dim2 = psct_iterator_dim (pbb, depth2); + + ppl_Polyhedron_space_dimension (poly, &dim); + map = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, dim); + + for (i = 0; i < dim; i++) + map[i] = i; + + map[dim1] = dim2; + map[dim2] = dim1; + + ppl_Polyhedron_map_space_dimensions (poly, map, dim); + free (map); +} + +/* Interchanges all the loop depths that are considered profitable for PBB. */ + +static bool +pbb_do_interchange (poly_bb_p pbb, scop_p scop) +{ + graphite_dim_t i, j; + bool transform_done = false; + + for (i = 0; i < pbb_dim_iter_domain (pbb); i++) + for (j = i + 1; j < pbb_dim_iter_domain (pbb); j++) + if (pbb_interchange_profitable_p (i, j, pbb)) + { + pbb_interchange_loop_depths (i, j, pbb); + + if (graphite_legal_transform (scop)) + { + transform_done = true; + + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + "PBB %d: loops at depths %d and %d will be interchanged.\n", + GBB_BB (PBB_BLACK_BOX (pbb))->index, (int) i, (int) j); + } + else + /* Undo the transform. */ + pbb_interchange_loop_depths (j, i, pbb); + } + + return transform_done; +} + +/* Interchanges all the loop depths that are considered profitable for SCOP. */ + +bool +scop_do_interchange (scop_p scop) +{ + int i; + poly_bb_p pbb; + bool transform_done = false; + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + transform_done |= pbb_do_interchange (pbb, scop); + + return transform_done; +} + +#endif + diff --git a/gcc/graphite-poly.c b/gcc/graphite-poly.c new file mode 100644 index 00000000000..2df04af6018 --- /dev/null +++ b/gcc/graphite-poly.c @@ -0,0 +1,752 @@ +/* Graphite polyhedral representation. + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Sebastian Pop <sebastian.pop@amd.com> and + Tobias Grosser <grosser@fim.uni-passau.de>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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/>. */ +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "ggc.h" +#include "tree.h" +#include "rtl.h" +#include "output.h" +#include "basic-block.h" +#include "diagnostic.h" +#include "tree-flow.h" +#include "toplev.h" +#include "tree-dump.h" +#include "timevar.h" +#include "cfgloop.h" +#include "tree-chrec.h" +#include "tree-data-ref.h" +#include "tree-scalar-evolution.h" +#include "tree-pass.h" +#include "domwalk.h" +#include "value-prof.h" +#include "pointer-set.h" +#include "gimple.h" +#include "params.h" + +#ifdef HAVE_cloog +#include "cloog/cloog.h" +#include "ppl_c.h" +#include "sese.h" +#include "graphite-ppl.h" +#include "graphite.h" +#include "graphite-poly.h" +#include "graphite-dependences.h" + +/* Return the maximal loop depth in SCOP. */ + +int +scop_max_loop_depth (scop_p scop) +{ + int i; + poly_bb_p pbb; + int max_nb_loops = 0; + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + { + int nb_loops = pbb_dim_iter_domain (pbb); + if (max_nb_loops < nb_loops) + max_nb_loops = nb_loops; + } + + return max_nb_loops; +} + +/* Extend the scattering matrix of PBB to MAX_SCATTERING scattering + dimensions. */ + +static void +extend_scattering (poly_bb_p pbb, int max_scattering) +{ + ppl_dimension_type nb_old_dims, nb_new_dims; + int nb_added_dims, i; + ppl_Coefficient_t coef; + Value one; + + nb_added_dims = max_scattering - pbb_nb_scattering_transform (pbb); + value_init (one); + value_set_si (one, 1); + ppl_new_Coefficient (&coef); + ppl_assign_Coefficient_from_mpz_t (coef, one); + + gcc_assert (nb_added_dims >= 0); + + nb_old_dims = pbb_nb_scattering_transform (pbb) + pbb_dim_iter_domain (pbb) + + scop_nb_params (PBB_SCOP (pbb)); + nb_new_dims = nb_old_dims + nb_added_dims; + + ppl_insert_dimensions (PBB_TRANSFORMED_SCATTERING (pbb), + pbb_nb_scattering_transform (pbb), nb_added_dims); + PBB_NB_SCATTERING_TRANSFORM (pbb) += nb_added_dims; + + /* Add identity matrix for the added dimensions. */ + for (i = max_scattering - nb_added_dims; i < max_scattering; i++) + { + ppl_Constraint_t cstr; + ppl_Linear_Expression_t expr; + + ppl_new_Linear_Expression_with_dimension (&expr, nb_new_dims); + ppl_Linear_Expression_add_to_coefficient (expr, i, coef); + ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL); + ppl_Polyhedron_add_constraint (PBB_TRANSFORMED_SCATTERING (pbb), cstr); + ppl_delete_Constraint (cstr); + ppl_delete_Linear_Expression (expr); + } + + ppl_delete_Coefficient (coef); + value_clear (one); +} + +/* All scattering matrices in SCOP will have the same number of scattering + dimensions. */ + +int +unify_scattering_dimensions (scop_p scop) +{ + int i; + poly_bb_p pbb; + graphite_dim_t max_scattering = 0; + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + max_scattering = MAX (pbb_nb_scattering_transform (pbb), max_scattering); + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + extend_scattering (pbb, max_scattering); + + return max_scattering; +} + +/* Prints to FILE the scattering function of PBB. */ + +void +print_scattering_function (FILE *file, poly_bb_p pbb) +{ + graphite_dim_t i; + + if (!PBB_TRANSFORMED_SCATTERING (pbb)) + return; + + fprintf (file, "scattering bb_%d (\n", GBB_BB (PBB_BLACK_BOX (pbb))->index); + fprintf (file, "# eq"); + + for (i = 0; i < pbb_nb_scattering_transform (pbb); i++) + fprintf (file, " s%d", (int) i); + + for (i = 0; i < pbb_nb_local_vars (pbb); i++) + fprintf (file, " lv%d", (int) i); + + for (i = 0; i < pbb_dim_iter_domain (pbb); i++) + fprintf (file, " i%d", (int) i); + + for (i = 0; i < pbb_nb_params (pbb); i++) + fprintf (file, " p%d", (int) i); + + fprintf (file, " cst\n"); + + ppl_print_polyhedron_matrix (file, PBB_TRANSFORMED_SCATTERING (pbb)); + + fprintf (file, ")\n"); +} + +/* Prints to FILE the iteration domain of PBB. */ + +void +print_iteration_domain (FILE *file, poly_bb_p pbb) +{ + print_pbb_domain (file, pbb); +} + +/* Prints to FILE the scattering functions of every PBB of SCOP. */ + +void +print_scattering_functions (FILE *file, scop_p scop) +{ + int i; + poly_bb_p pbb; + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + print_scattering_function (file, pbb); +} + +/* Prints to FILE the iteration domains of every PBB of SCOP. */ + +void +print_iteration_domains (FILE *file, scop_p scop) +{ + int i; + poly_bb_p pbb; + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + print_iteration_domain (file, pbb); +} + +/* Prints to STDERR the scattering function of PBB. */ + +void +debug_scattering_function (poly_bb_p pbb) +{ + print_scattering_function (stderr, pbb); +} + +/* Prints to STDERR the iteration domain of PBB. */ + +void +debug_iteration_domain (poly_bb_p pbb) +{ + print_iteration_domain (stderr, pbb); +} + +/* Prints to STDERR the scattering functions of every PBB of SCOP. */ + +void +debug_scattering_functions (scop_p scop) +{ + print_scattering_functions (stderr, scop); +} + +/* Prints to STDERR the iteration domains of every PBB of SCOP. */ + +void +debug_iteration_domains (scop_p scop) +{ + print_iteration_domains (stderr, scop); +} + +/* Apply graphite transformations to all the basic blocks of SCOP. */ + +bool +apply_poly_transforms (scop_p scop) +{ + bool transform_done = false; + + gcc_assert (graphite_legal_transform (scop)); + + /* Generate code even if we did not apply any real transformation. + This also allows to check the performance for the identity + transformation: GIMPLE -> GRAPHITE -> GIMPLE + Keep in mind that CLooG optimizes in control, so the loop structure + may change, even if we only use -fgraphite-identity. */ + if (flag_graphite_identity) + transform_done = true; + + if (flag_loop_parallelize_all) + transform_done = true; + + if (flag_loop_block) + gcc_unreachable (); /* Not yet supported. */ + + if (flag_loop_strip_mine) + { + transform_done |= scop_do_strip_mine (scop); + gcc_assert (graphite_legal_transform (scop)); + } + + if (flag_loop_interchange) + { + transform_done |= scop_do_interchange (scop); + gcc_assert (graphite_legal_transform (scop)); + } + + return transform_done; +} + +/* Create a new polyhedral data reference and add it to PBB. It is defined by + its ACCESSES, its TYPE*/ + +void +new_poly_dr (poly_bb_p pbb, + ppl_Pointset_Powerset_C_Polyhedron_t accesses, + ppl_Pointset_Powerset_C_Polyhedron_t data_container, + enum POLY_DR_TYPE type, void *cdr) +{ + poly_dr_p pdr = XNEW (struct poly_dr); + + PDR_PBB (pdr) = pbb; + PDR_ACCESSES (pdr) = accesses; + PDR_DATA_CONTAINER (pdr) = data_container; + PDR_TYPE (pdr) = type; + PDR_CDR (pdr) = cdr; + VEC_safe_push (poly_dr_p, heap, PBB_DRS (pbb), pdr); +} + +/* Free polyhedral data reference PDR. */ + +void +free_poly_dr (poly_dr_p pdr) +{ + ppl_delete_Pointset_Powerset_C_Polyhedron (PDR_ACCESSES (pdr)); + ppl_delete_Pointset_Powerset_C_Polyhedron (PDR_DATA_CONTAINER (pdr)); + + XDELETE (pdr); +} + +/* Create a new polyhedral black box. */ + +void +new_poly_bb (scop_p scop, void *black_box) +{ + poly_bb_p pbb = XNEW (struct poly_bb); + + PBB_DOMAIN (pbb) = NULL; + PBB_SCOP (pbb) = scop; + pbb_set_black_box (pbb, black_box); + PBB_TRANSFORMED_SCATTERING (pbb) = NULL; + PBB_ORIGINAL_SCATTERING (pbb) = NULL; + PBB_DRS (pbb) = VEC_alloc (poly_dr_p, heap, 3); + PBB_NB_SCATTERING_TRANSFORM (pbb) = 0; + PBB_NB_LOCAL_VARIABLES (pbb) = 0; + VEC_safe_push (poly_bb_p, heap, SCOP_BBS (scop), pbb); +} + +/* Free polyhedral black box. */ + +void +free_poly_bb (poly_bb_p pbb) +{ + int i; + poly_dr_p pdr; + + ppl_delete_Pointset_Powerset_C_Polyhedron (PBB_DOMAIN (pbb)); + + if (PBB_TRANSFORMED_SCATTERING (pbb)) + ppl_delete_Polyhedron (PBB_TRANSFORMED_SCATTERING (pbb)); + + if (PBB_ORIGINAL_SCATTERING (pbb)) + ppl_delete_Polyhedron (PBB_ORIGINAL_SCATTERING (pbb)); + + if (PBB_DRS (pbb)) + for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb), i, pdr); i++) + free_poly_dr (pdr); + + VEC_free (poly_dr_p, heap, PBB_DRS (pbb)); + XDELETE (pbb); +} + +static void +print_pdr_access_layout (FILE *file, poly_dr_p pdr) +{ + graphite_dim_t i; + + fprintf (file, "# eq"); + + for (i = 0; i < pdr_dim_iter_domain (pdr); i++) + fprintf (file, " i%d", (int) i); + + for (i = 0; i < pdr_nb_params (pdr); i++) + fprintf (file, " p%d", (int) i); + + fprintf (file, " alias"); + + for (i = 0; i < pdr_nb_subscripts (pdr); i++) + fprintf (file, " sub%d", (int) i); + + fprintf (file, " cst\n"); +} + +/* Prints to FILE the polyhedral data reference PDR. */ + +void +print_pdr (FILE *file, poly_dr_p pdr) +{ + fprintf (file, "pdr ("); + + switch (PDR_TYPE (pdr)) + { + case PDR_READ: + fprintf (file, "read \n"); + break; + + case PDR_WRITE: + fprintf (file, "write \n"); + break; + + case PDR_MAY_WRITE: + fprintf (file, "may_write \n"); + break; + + default: + gcc_unreachable (); + } + + dump_data_reference (file, (data_reference_p) PDR_CDR (pdr)); + + fprintf (file, "data accesses (\n"); + print_pdr_access_layout (file, pdr); + ppl_print_powerset_matrix (file, PDR_ACCESSES (pdr)); + fprintf (file, ")\n"); + + fprintf (file, "data container (\n"); + print_pdr_access_layout (file, pdr); + ppl_print_powerset_matrix (file, PDR_DATA_CONTAINER (pdr)); + fprintf (file, ")\n"); + + fprintf (file, ")\n"); +} + +/* Prints to STDERR the polyhedral data reference PDR. */ + +void +debug_pdr (poly_dr_p pdr) +{ + print_pdr (stderr, pdr); +} + +/* Creates a new SCOP containing REGION. */ + +scop_p +new_scop (void *region) +{ + scop_p scop = XNEW (struct scop); + + SCOP_DEP_GRAPH (scop) = NULL; + SCOP_CONTEXT (scop) = NULL; + scop_set_region (scop, region); + SCOP_BBS (scop) = VEC_alloc (poly_bb_p, heap, 3); + SCOP_ORIGINAL_PDR_PAIRS (scop) = htab_create (10, hash_poly_dr_pair_p, + eq_poly_dr_pair_p, free); + return scop; +} + +/* Deletes SCOP. */ + +void +free_scop (scop_p scop) +{ + int i; + poly_bb_p pbb; + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + free_poly_bb (pbb); + + VEC_free (poly_bb_p, heap, SCOP_BBS (scop)); + + if (SCOP_CONTEXT (scop)) + ppl_delete_Pointset_Powerset_C_Polyhedron (SCOP_CONTEXT (scop)); + + htab_delete (SCOP_ORIGINAL_PDR_PAIRS (scop)); + XDELETE (scop); +} + +/* Print to FILE the domain of PBB. */ + +void +print_pbb_domain (FILE *file, poly_bb_p pbb) +{ + graphite_dim_t i; + gimple_bb_p gbb = PBB_BLACK_BOX (pbb); + + if (!PBB_DOMAIN (pbb)) + return; + + fprintf (file, "domains bb_%d (\n", GBB_BB (gbb)->index); + fprintf (file, "# eq"); + + for (i = 0; i < pbb_dim_iter_domain (pbb); i++) + fprintf (file, " i%d", (int) i); + + for (i = 0; i < pbb_nb_params (pbb); i++) + fprintf (file, " p%d", (int) i); + + fprintf (file, " cst\n"); + + if (PBB_DOMAIN (pbb)) + ppl_print_powerset_matrix (file, PBB_DOMAIN (pbb)); + + fprintf (file, ")\n"); +} + +/* Dump the cases of a graphite basic block GBB on FILE. */ + +static void +dump_gbb_cases (FILE *file, gimple_bb_p gbb) +{ + int i; + gimple stmt; + VEC (gimple, heap) *cases; + + if (!gbb) + return; + + cases = GBB_CONDITION_CASES (gbb); + if (VEC_empty (gimple, cases)) + return; + + fprintf (file, "cases bb_%d (", GBB_BB (gbb)->index); + + for (i = 0; VEC_iterate (gimple, cases, i, stmt); i++) + print_gimple_stmt (file, stmt, 0, 0); + + fprintf (file, ")\n"); +} + +/* Dump conditions of a graphite basic block GBB on FILE. */ + +static void +dump_gbb_conditions (FILE *file, gimple_bb_p gbb) +{ + int i; + gimple stmt; + VEC (gimple, heap) *conditions; + + if (!gbb) + return; + + conditions = GBB_CONDITIONS (gbb); + if (VEC_empty (gimple, conditions)) + return; + + fprintf (file, "conditions bb_%d (", GBB_BB (gbb)->index); + + for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++) + print_gimple_stmt (file, stmt, 0, 0); + + fprintf (file, ")\n"); +} + +/* Print to FILE all the data references of PBB. */ + +void +print_pdrs (FILE *file, poly_bb_p pbb) +{ + int i; + poly_dr_p pdr; + + for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb), i, pdr); i++) + print_pdr (file, pdr); +} + +/* Print to STDERR all the data references of PBB. */ + +void +debug_pdrs (poly_bb_p pbb) +{ + print_pdrs (stderr, pbb); +} + +/* Print to FILE the domain and scattering function of PBB. */ + +void +print_pbb (FILE *file, poly_bb_p pbb) +{ + dump_gbb_conditions (file, PBB_BLACK_BOX (pbb)); + dump_gbb_cases (file, PBB_BLACK_BOX (pbb)); + print_pdrs (file, pbb); + print_pbb_domain (file, pbb); + print_scattering_function (file, pbb); +} + +/* Print to FILE the parameters of SCOP. */ + +void +print_scop_params (FILE *file, scop_p scop) +{ + int i; + tree t; + + fprintf (file, "parameters (\n"); + for (i = 0; VEC_iterate (tree, SESE_PARAMS (SCOP_REGION (scop)), i, t); i++) + { + fprintf (file, "p_%d -> ", i); + print_generic_expr (file, t, 0); + fprintf (file, "\n"); + } + fprintf (file, ")\n"); +} + +/* Print to FILE the context of SCoP. */ +void +print_scop_context (FILE *file, scop_p scop) +{ + graphite_dim_t i; + + fprintf (file, "context (\n"); + fprintf (file, "# eq"); + + for (i = 0; i < scop_nb_params (scop); i++) + fprintf (file, " p%d", (int) i); + + fprintf (file, " cst\n"); + + if (SCOP_CONTEXT (scop)) + ppl_print_powerset_matrix (file, SCOP_CONTEXT (scop)); + + fprintf (file, ")\n"); +} + +/* Print to FILE the SCOP. */ + +void +print_scop (FILE *file, scop_p scop) +{ + int i; + poly_bb_p pbb; + + print_scop_params (file, scop); + print_scop_context (file, scop); + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + print_pbb (file, pbb); +} + +/* Print to STDERR the domain of PBB. */ + +void +debug_pbb_domain (poly_bb_p pbb) +{ + print_pbb_domain (stderr, pbb); +} + +/* Print to FILE the domain and scattering function of PBB. */ + +void +debug_pbb (poly_bb_p pbb) +{ + print_pbb (stderr, pbb); +} + +/* Print to STDERR the context of SCOP. */ + +void +debug_scop_context (scop_p scop) +{ + print_scop_context (stderr, scop); +} + +/* Print to STDERR the SCOP. */ + +void +debug_scop (scop_p scop) +{ + print_scop (stderr, scop); +} + +/* Print to STDERR the parameters of SCOP. */ + +void +debug_scop_params (scop_p scop) +{ + print_scop_params (stderr, scop); +} + + +/* The dimension in the transformed scattering polyhedron of PBB + containing the scattering iterator for the loop at depth LOOP_DEPTH. */ + +ppl_dimension_type +psct_scattering_dim_for_loop_depth (poly_bb_p pbb, graphite_dim_t loop_depth) +{ + ppl_const_Constraint_System_t pcs; + ppl_Constraint_System_const_iterator_t cit, cend; + ppl_const_Constraint_t cstr; + ppl_Polyhedron_t ph = PBB_TRANSFORMED_SCATTERING (pbb); + ppl_dimension_type iter = psct_iterator_dim (pbb, loop_depth); + ppl_Linear_Expression_t expr; + ppl_Coefficient_t coef; + Value val; + graphite_dim_t i; + + value_init (val); + ppl_new_Coefficient (&coef); + ppl_Polyhedron_get_constraints (ph, &pcs); + ppl_new_Constraint_System_const_iterator (&cit); + ppl_new_Constraint_System_const_iterator (&cend); + + for (ppl_Constraint_System_begin (pcs, cit), + ppl_Constraint_System_end (pcs, cend); + !ppl_Constraint_System_const_iterator_equal_test (cit, cend); + ppl_Constraint_System_const_iterator_increment (cit)) + { + ppl_Constraint_System_const_iterator_dereference (cit, &cstr); + ppl_new_Linear_Expression_from_Constraint (&expr, cstr); + ppl_Linear_Expression_coefficient (expr, iter, coef); + ppl_Coefficient_to_mpz_t (coef, val); + + if (value_zero_p (val)) + { + ppl_delete_Linear_Expression (expr); + continue; + } + + for (i = 0; i < pbb_nb_scattering_transform (pbb); i++) + { + ppl_dimension_type scatter = psct_scattering_dim (pbb, i); + + ppl_Linear_Expression_coefficient (expr, scatter, coef); + ppl_Coefficient_to_mpz_t (coef, val); + + if (value_notzero_p (val)) + { + value_clear (val); + ppl_delete_Linear_Expression (expr); + ppl_delete_Coefficient (coef); + ppl_delete_Constraint_System_const_iterator (cit); + ppl_delete_Constraint_System_const_iterator (cend); + + return scatter; + } + } + } + + gcc_unreachable (); +} + +/* Returns the number of iterations NITER of the loop around PBB at + depth LOOP_DEPTH. */ + +void +pbb_number_of_iterations (poly_bb_p pbb, + graphite_dim_t loop_depth, + Value niter) +{ + ppl_dimension_type loop_iter = pbb_iterator_dim (pbb, loop_depth); + ppl_Linear_Expression_t le; + ppl_Coefficient_t num, denom; + Value dv; + int maximum; + ppl_dimension_type dim; + + value_init (dv); + ppl_new_Coefficient (&num); + ppl_new_Coefficient (&denom); + ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PBB_DOMAIN (pbb), &dim); + ppl_new_Linear_Expression_with_dimension (&le, dim); + ppl_set_coef (le, loop_iter, 1); + ppl_Pointset_Powerset_C_Polyhedron_maximize (PBB_DOMAIN (pbb), le, + num, denom, &maximum); + + if (maximum == 1) + { + ppl_Coefficient_to_mpz_t (num, niter); + ppl_Coefficient_to_mpz_t (denom, dv); + value_division (niter, niter, dv); + } + else + value_set_si (niter, -1); + + value_clear (dv); + ppl_delete_Linear_Expression (le); + ppl_delete_Coefficient (num); + ppl_delete_Coefficient (denom); +} + +#endif + diff --git a/gcc/graphite-poly.h b/gcc/graphite-poly.h new file mode 100644 index 00000000000..83d5fca212b --- /dev/null +++ b/gcc/graphite-poly.h @@ -0,0 +1,581 @@ +/* Graphite polyhedral representation. + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Sebastian Pop <sebastian.pop@amd.com> and + Tobias Grosser <grosser@fim.uni-passau.de>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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/>. */ + +#ifndef GCC_GRAPHITE_POLY_H +#define GCC_GRAPHITE_POLY_H + +typedef struct poly_dr *poly_dr_p; +DEF_VEC_P(poly_dr_p); +DEF_VEC_ALLOC_P (poly_dr_p, heap); + +typedef struct poly_bb *poly_bb_p; +DEF_VEC_P(poly_bb_p); +DEF_VEC_ALLOC_P (poly_bb_p, heap); + +typedef struct scop *scop_p; +DEF_VEC_P(scop_p); +DEF_VEC_ALLOC_P (scop_p, heap); + +typedef ppl_dimension_type graphite_dim_t; + +static inline graphite_dim_t pbb_dim_iter_domain (const struct poly_bb *); +static inline graphite_dim_t pbb_nb_params (const struct poly_bb *); +static inline graphite_dim_t scop_nb_params (scop_p); + +/* A data reference can write or read some memory or we + just know it may write some memory. */ +enum POLY_DR_TYPE +{ + PDR_READ, + /* PDR_MAY_READs are represented using PDR_READS. This does not limit the + expressiveness. */ + PDR_WRITE, + PDR_MAY_WRITE +}; + +struct poly_dr +{ + /* A pointer to compiler's data reference description. */ + void *compiler_dr; + + /* A pointer to the PBB that contains this data reference. */ + poly_bb_p pbb; + + enum POLY_DR_TYPE type; + + /* The access polyhedron contains the polyhedral space this data + reference will access. + + The polyhedron contains these dimensions: + + - The alias set (a): + Every memory access is classified in at least one alias set. + + - The subscripts (s_0, ..., s_n): + The memory is accessed using zero or more subscript dimensions. + + - The iteration domain (variables and parameters) + + Do not hardcode the dimensions. Use the following accessor functions: + - pdr_alias_set_dim + - pdr_subscript_dim + - pdr_iterator_dim + - pdr_parameter_dim + + Example: + + | int A[1335][123]; + | int *p = malloc (); + | + | k = ... + | for i + | { + | if (unknown_function ()) + | p = A; + | ... = p[?][?]; + | for j + | A[i][j+b] = m; + | } + + The data access A[i][j+k] in alias set "5" is described like this: + + | i j k a s0 s1 1 + | 0 0 0 1 0 0 -5 = 0 + |-1 0 0 0 1 0 0 = 0 + | 0 -1 -1 0 0 1 0 = 0 + + The constraints on the data container A[1335][123] are: + + | i j k a s0 s1 1 + | 0 0 0 0 1 0 0 >= 0 + | 0 0 0 0 0 1 0 >= 0 + | 0 0 0 0 -1 0 1335 >= 0 + | 0 0 0 0 0 -1 123 >= 0 + + The pointer "*p" in alias set "5" and "7" is described as a union of + polyhedron: + + + | i k a s0 1 + | 0 0 1 0 -5 = 0 + | 0 0 0 1 0 >= 0 + + "or" + + | i k a s0 1 + | 0 0 1 0 -7 = 0 + | 0 0 0 1 0 >= 0 + + "*p" accesses all of the object allocated with 'malloc'. + + The scalar data access "m" is represented as an array with zero subscript + dimensions. + + | i j k a 1 + | 0 0 0 -1 15 = 0 */ + ppl_Pointset_Powerset_C_Polyhedron_t accesses; + ppl_Pointset_Powerset_C_Polyhedron_t data_container; +}; + +#define PDR_CDR(PDR) (PDR->compiler_dr) +#define PDR_PBB(PDR) (PDR->pbb) +#define PDR_TYPE(PDR) (PDR->type) +#define PDR_ACCESSES(PDR) (PDR->accesses) +#define PDR_DATA_CONTAINER(PDR) (PDR->data_container) + +void new_poly_dr (poly_bb_p, ppl_Pointset_Powerset_C_Polyhedron_t, + ppl_Pointset_Powerset_C_Polyhedron_t, + enum POLY_DR_TYPE, void *); +void free_poly_dr (poly_dr_p); +void debug_pdr (poly_dr_p); +void print_pdr (FILE *, poly_dr_p); +static inline scop_p pdr_scop (poly_dr_p pdr); + +/* The number of subscripts of the PDR. */ + +static inline graphite_dim_t +pdr_nb_subscripts (poly_dr_p pdr) +{ + poly_bb_p pbb = PDR_PBB (pdr); + ppl_dimension_type dim; + + ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PDR_ACCESSES (pdr), + &dim); + return dim - pbb_dim_iter_domain (pbb) - pbb_nb_params (pbb) - 1; +} + +/* The dimension of the iteration domain of the scop of PDR. */ + +static inline ppl_dimension_type +pdr_dim_iter_domain (poly_dr_p pdr) +{ + return pbb_dim_iter_domain (PDR_PBB (pdr)); +} + +/* The number of parameters of the scop of PDR. */ + +static inline ppl_dimension_type +pdr_nb_params (poly_dr_p pdr) +{ + return scop_nb_params (pdr_scop (pdr)); +} + +/* The dimension of the accesses polyhedron of PDR. */ + +static inline graphite_dim_t +pdr_dim (poly_dr_p pdr) +{ + graphite_dim_t alias_nb_dimensions = 1; + + return pbb_dim_iter_domain (PDR_PBB (pdr)) + alias_nb_dimensions + + pdr_nb_subscripts (pdr) + scop_nb_params (pdr_scop (pdr)); +} + +/* The dimension of the alias set in PDR. */ + +static inline ppl_dimension_type +pdr_alias_set_dim (poly_dr_p pdr) +{ + poly_bb_p pbb = PDR_PBB (pdr); + + return pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb); +} + +/* The dimension in PDR containing subscript S. */ + +static inline ppl_dimension_type +pdr_subscript_dim (poly_dr_p pdr, graphite_dim_t s) +{ + poly_bb_p pbb = PDR_PBB (pdr); + + return pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb) + 1 + s; +} + +/* The dimension in PDR containing the loop iterator ITER. */ + +static inline ppl_dimension_type +pdr_iterator_dim (poly_dr_p pdr ATTRIBUTE_UNUSED, graphite_dim_t iter) +{ + return iter; +} + +/* The dimension in PDR containing parameter PARAM. */ + +static inline ppl_dimension_type +pdr_parameter_dim (poly_dr_p pdr, graphite_dim_t param) +{ + poly_bb_p pbb = PDR_PBB (pdr); + + return pbb_dim_iter_domain (pbb) + param; +} + +/* POLY_BB represents a blackbox in the polyhedral model. */ + +struct poly_bb +{ + void *black_box; + + scop_p scop; + + /* The iteration domain of this bb. + Example: + + for (i = a - 7*b + 8; i <= 3*a + 13*b + 20; i++) + for (j = 2; j <= 2*i + 5; j++) + for (k = 0; k <= 5; k++) + S (i,j,k) + + Loop iterators: i, j, k + Parameters: a, b + + | i >= a - 7b + 8 + | i <= 3a + 13b + 20 + | j >= 2 + | j <= 2i + 5 + | k >= 0 + | k <= 5 + + The number of variables in the DOMAIN may change and is not + related to the number of loops in the original code. */ + ppl_Pointset_Powerset_C_Polyhedron_t domain; + + /* The data references we access. */ + VEC (poly_dr_p, heap) *drs; + + /* The scattering function containing the transformations. */ + ppl_Polyhedron_t transformed_scattering; + + + /* The original scattering function. */ + ppl_Polyhedron_t original_scattering; + + /* The number of local variables. */ + int nb_local_variables; + + /* The number of scattering dimensions in the TRANSFORMED scattering. */ + int nb_scattering_transform; +}; + +#define PBB_BLACK_BOX(PBB) ((gimple_bb_p) PBB->black_box) +#define PBB_SCOP(PBB) (PBB->scop) +#define PBB_DOMAIN(PBB) (PBB->domain) +#define PBB_DRS(PBB) (PBB->drs) +#define PBB_TRANSFORMED_SCATTERING(PBB) (PBB->transformed_scattering) +#define PBB_ORIGINAL_SCATTERING(PBB) (PBB->original_scattering) +#define PBB_NB_LOCAL_VARIABLES(PBB) (PBB->nb_local_variables) +#define PBB_NB_SCATTERING_TRANSFORM(PBB) (PBB->nb_scattering_transform) + +extern void new_poly_bb (scop_p, void *); +extern void free_poly_bb (poly_bb_p); +extern void debug_loop_vec (poly_bb_p); +extern void schedule_to_scattering (poly_bb_p, int); +extern void print_pbb_domain (FILE *, poly_bb_p); +extern void print_pbb (FILE *, poly_bb_p); +extern void print_scop_context (FILE *, scop_p); +extern void print_scop (FILE *, scop_p); +extern void debug_pbb_domain (poly_bb_p); +extern void debug_pbb (poly_bb_p); +extern void print_pdrs (FILE *, poly_bb_p); +extern void debug_pdrs (poly_bb_p); +extern void debug_scop_context (scop_p); +extern void debug_scop (scop_p); +extern void print_scop_params (FILE *, scop_p); +extern void debug_scop_params (scop_p); +extern void print_iteration_domain (FILE *, poly_bb_p); +extern void print_iteration_domains (FILE *, scop_p); +extern void debug_iteration_domain (poly_bb_p); +extern void debug_iteration_domains (scop_p); +extern bool scop_do_interchange (scop_p); +extern bool scop_do_strip_mine (scop_p); +extern void pbb_number_of_iterations (poly_bb_p, graphite_dim_t, Value); + +/* The scop that contains the PDR. */ + +static inline scop_p pdr_scop (poly_dr_p pdr) +{ + return PBB_SCOP (PDR_PBB (pdr)); +} + +/* Set black box of PBB to BLACKBOX. */ + +static inline void +pbb_set_black_box (poly_bb_p pbb, void *black_box) +{ + pbb->black_box = black_box; +} + +/* The number of loops around PBB: the dimension of the iteration + domain. */ + +static inline graphite_dim_t +pbb_dim_iter_domain (const struct poly_bb *pbb) +{ + scop_p scop = PBB_SCOP (pbb); + ppl_dimension_type dim; + + ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PBB_DOMAIN (pbb), &dim); + return dim - scop_nb_params (scop); +} + +/* The number of params defined in PBB. */ + +static inline graphite_dim_t +pbb_nb_params (const struct poly_bb *pbb) +{ + scop_p scop = PBB_SCOP (pbb); + + return scop_nb_params (scop); +} + +/* The number of scattering dimensions in the SCATTERING polyhedron + of a PBB for a given SCOP. */ + +static inline graphite_dim_t +pbb_nb_scattering_orig (const struct poly_bb *pbb) +{ + return 2 * pbb_dim_iter_domain (pbb) + 1; +} + +/* The number of scattering dimensions in PBB. */ + +static inline graphite_dim_t +pbb_nb_scattering_transform (const struct poly_bb *pbb) +{ + return PBB_NB_SCATTERING_TRANSFORM (pbb); +} + +/* Returns the number of local variables used in the transformed + scattering polyhedron of PBB. */ + +static inline graphite_dim_t +pbb_nb_local_vars (const struct poly_bb *pbb) +{ + /* For now we do not have any local variables, as we do not do strip + mining for example. */ + return PBB_NB_LOCAL_VARIABLES (pbb); +} + +/* The dimension in the domain of PBB containing the iterator ITER. */ + +static inline ppl_dimension_type +pbb_iterator_dim (poly_bb_p pbb ATTRIBUTE_UNUSED, graphite_dim_t iter) +{ + return iter; +} + +/* The dimension in the domain of PBB containing the iterator ITER. */ + +static inline ppl_dimension_type +pbb_parameter_dim (poly_bb_p pbb, graphite_dim_t param) +{ + return param + + pbb_dim_iter_domain (pbb); +} + +/* The dimension in the original scattering polyhedron of PBB + containing the scattering iterator SCATTER. */ + +static inline ppl_dimension_type +psco_scattering_dim (poly_bb_p pbb ATTRIBUTE_UNUSED, graphite_dim_t scatter) +{ + gcc_assert (scatter < pbb_nb_scattering_orig (pbb)); + return scatter; +} + +/* The dimension in the transformed scattering polyhedron of PBB + containing the scattering iterator SCATTER. */ + +static inline ppl_dimension_type +psct_scattering_dim (poly_bb_p pbb ATTRIBUTE_UNUSED, graphite_dim_t scatter) +{ + gcc_assert (scatter <= pbb_nb_scattering_transform (pbb)); + return scatter; +} + +ppl_dimension_type psct_scattering_dim_for_loop_depth (poly_bb_p, + graphite_dim_t); + +/* The dimension in the transformed scattering polyhedron of PBB of + the local variable LV. */ + +static inline ppl_dimension_type +psct_local_var_dim (poly_bb_p pbb, graphite_dim_t lv) +{ + gcc_assert (lv <= pbb_nb_local_vars (pbb)); + return lv + pbb_nb_scattering_transform (pbb); +} + +/* The dimension in the original scattering polyhedron of PBB + containing the loop iterator ITER. */ + +static inline ppl_dimension_type +psco_iterator_dim (poly_bb_p pbb, graphite_dim_t iter) +{ + gcc_assert (iter < pbb_dim_iter_domain (pbb)); + return iter + pbb_nb_scattering_orig (pbb); +} + +/* The dimension in the transformed scattering polyhedron of PBB + containing the loop iterator ITER. */ + +static inline ppl_dimension_type +psct_iterator_dim (poly_bb_p pbb, graphite_dim_t iter) +{ + gcc_assert (iter < pbb_dim_iter_domain (pbb)); + return iter + + pbb_nb_scattering_transform (pbb) + + pbb_nb_local_vars (pbb); +} + +/* The dimension in the original scattering polyhedron of PBB + containing parameter PARAM. */ + +static inline ppl_dimension_type +psco_parameter_dim (poly_bb_p pbb, graphite_dim_t param) +{ + gcc_assert (param < pbb_nb_params (pbb)); + return param + + pbb_nb_scattering_orig (pbb) + + pbb_dim_iter_domain (pbb); +} + +/* The dimension in the transformed scattering polyhedron of PBB + containing parameter PARAM. */ + +static inline ppl_dimension_type +psct_parameter_dim (poly_bb_p pbb, graphite_dim_t param) +{ + gcc_assert (param < pbb_nb_params (pbb)); + return param + + pbb_nb_scattering_transform (pbb) + + pbb_nb_local_vars (pbb) + + pbb_dim_iter_domain (pbb); +} + +/* Adds to the transformed scattering polyhedron of PBB a new local + variable and returns its index. */ + +static inline graphite_dim_t +psct_add_local_variable (poly_bb_p pbb) +{ + graphite_dim_t nlv = pbb_nb_local_vars (pbb); + ppl_dimension_type lv_column = psct_local_var_dim (pbb, nlv); + ppl_insert_dimensions (PBB_TRANSFORMED_SCATTERING (pbb), lv_column, 1); + PBB_NB_LOCAL_VARIABLES (pbb) += 1; + return nlv; +} + +/* Adds a dimension to the transformed scattering polyhedron of PBB at + INDEX. */ + +static inline void +psct_add_scattering_dimension (poly_bb_p pbb, ppl_dimension_type index) +{ + gcc_assert (index < pbb_nb_scattering_transform (pbb)); + + ppl_insert_dimensions (PBB_TRANSFORMED_SCATTERING (pbb), index, 1); + PBB_NB_SCATTERING_TRANSFORM (pbb) += 1; +} + +/* A SCOP is a Static Control Part of the program, simple enough to be + represented in polyhedral form. */ +struct scop +{ + /* A SCOP is defined as a SESE region. */ + void *region; + + /* Number of parameters in SCoP. */ + graphite_dim_t nb_params; + + /* All the basic blocks in this scop that contain memory references + and that will be represented as statements in the polyhedral + representation. */ + VEC (poly_bb_p, heap) *bbs; + + /* Data dependence graph for this SCoP. */ + struct graph *dep_graph; + + /* The context describes known restrictions concerning the parameters + and relations in between the parameters. + + void f (int8_t a, uint_16_t b) { + c = 2 a + b; + ... + } + + Here we can add these restrictions to the context: + + -128 >= a >= 127 + 0 >= b >= 65,535 + c = 2a + b */ + ppl_Pointset_Powerset_C_Polyhedron_t context; + + /* A hashtable of the original pairs of dependent data references. + For each pair of dependent data references, the dependence + polyhedron is stored also. */ + htab_t original_pdr_pairs; +}; + +#define SCOP_BBS(S) (S->bbs) +#define SCOP_REGION(S) ((sese) S->region) +#define SCOP_DEP_GRAPH(S) (S->dep_graph) +#define SCOP_CONTEXT(S) (S->context) +#define SCOP_ORIGINAL_PDR_PAIRS(S) (S->original_pdr_pairs) + +extern scop_p new_scop (void *); +extern void free_scop (scop_p); +extern void free_scops (VEC (scop_p, heap) *); +extern void print_generated_program (FILE *, scop_p); +extern void debug_generated_program (scop_p); +extern void print_scattering_function (FILE *, poly_bb_p); +extern void print_scattering_functions (FILE *, scop_p); +extern void debug_scattering_function (poly_bb_p); +extern void debug_scattering_functions (scop_p); +extern int scop_max_loop_depth (scop_p); +extern int unify_scattering_dimensions (scop_p); +extern bool apply_poly_transforms (scop_p); +extern bool graphite_legal_transform (scop_p); + +/* Set the region of SCOP to REGION. */ + +static inline void +scop_set_region (scop_p scop, void *region) +{ + scop->region = region; +} + +/* Returns the number of parameters for SCOP. */ + +static inline graphite_dim_t +scop_nb_params (scop_p scop) +{ + return scop->nb_params; +} + +/* Set the number of params of SCOP to NB_PARAMS. */ + +static inline void +scop_set_nb_params (scop_p scop, graphite_dim_t nb_params) +{ + scop->nb_params = nb_params; +} + +#endif diff --git a/gcc/graphite-ppl.c b/gcc/graphite-ppl.c new file mode 100644 index 00000000000..967b6ea7958 --- /dev/null +++ b/gcc/graphite-ppl.c @@ -0,0 +1,616 @@ +/* Gimple Represented as Polyhedra. + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Sebastian Pop <sebastian.pop@amd.com> + and Tobias Grosser <grosser@fim.uni-passau.de> + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "ggc.h" + +#ifdef HAVE_cloog +#include "ppl_c.h" +#include "cloog/cloog.h" +#include "graphite-ppl.h" + +/* Translates row ROW of the CloogMatrix MATRIX to a PPL Constraint. */ + +static ppl_Constraint_t +cloog_matrix_to_ppl_constraint (CloogMatrix *matrix, int row) +{ + int j; + ppl_Constraint_t cstr; + ppl_Coefficient_t coef; + ppl_Linear_Expression_t expr; + ppl_dimension_type dim = matrix->NbColumns - 2; + + ppl_new_Coefficient (&coef); + ppl_new_Linear_Expression_with_dimension (&expr, dim); + + for (j = 1; j < matrix->NbColumns - 1; j++) + { + ppl_assign_Coefficient_from_mpz_t (coef, matrix->p[row][j]); + ppl_Linear_Expression_add_to_coefficient (expr, j - 1, coef); + } + + ppl_assign_Coefficient_from_mpz_t (coef, + matrix->p[row][matrix->NbColumns - 1]); + ppl_Linear_Expression_add_to_inhomogeneous (expr, coef); + ppl_delete_Coefficient (coef); + + if (value_zero_p (matrix->p[row][0])) + ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL); + else + ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL); + + ppl_delete_Linear_Expression (expr); + return cstr; +} + +/* Creates a PPL constraint system from MATRIX. */ + +static void +new_Constraint_System_from_Cloog_Matrix (ppl_Constraint_System_t *pcs, + CloogMatrix *matrix) +{ + int i; + + ppl_new_Constraint_System (pcs); + + for (i = 0; i < matrix->NbRows; i++) + { + ppl_Constraint_t c = cloog_matrix_to_ppl_constraint (matrix, i); + ppl_Constraint_System_insert_Constraint (*pcs, c); + ppl_delete_Constraint (c); + } +} + +/* Creates a PPL Polyhedron from MATRIX. */ + +void +new_C_Polyhedron_from_Cloog_Matrix (ppl_Polyhedron_t *ph, + CloogMatrix *matrix) +{ + ppl_Constraint_System_t cs; + new_Constraint_System_from_Cloog_Matrix (&cs, matrix); + ppl_new_C_Polyhedron_recycle_Constraint_System (ph, cs); +} + +/* Counts the number of constraints in PCS. */ + +static int +ppl_Constrain_System_number_of_constraints (ppl_const_Constraint_System_t pcs) +{ + ppl_Constraint_System_const_iterator_t cit, end; + int num = 0; + + ppl_new_Constraint_System_const_iterator (&cit); + ppl_new_Constraint_System_const_iterator (&end); + + for (ppl_Constraint_System_begin (pcs, cit), + ppl_Constraint_System_end (pcs, end); + !ppl_Constraint_System_const_iterator_equal_test (cit, end); + ppl_Constraint_System_const_iterator_increment (cit)) + num++; + + ppl_delete_Constraint_System_const_iterator (cit); + ppl_delete_Constraint_System_const_iterator (end); + return num; +} + +static void +oppose_constraint (CloogMatrix *m, int row) +{ + int k; + + /* Do not oppose the first column: it is the eq/ineq one. */ + for (k = 1; k < m->NbColumns; k++) + value_oppose (m->p[row][k], m->p[row][k]); +} + +/* Inserts constraint CSTR at row ROW of matrix M. */ + +void +insert_constraint_into_matrix (CloogMatrix *m, int row, + ppl_const_Constraint_t cstr) +{ + ppl_Coefficient_t c; + ppl_dimension_type i, dim, nb_cols = m->NbColumns; + + ppl_Constraint_space_dimension (cstr, &dim); + ppl_new_Coefficient (&c); + + for (i = 0; i < dim; i++) + { + ppl_Constraint_coefficient (cstr, i, c); + ppl_Coefficient_to_mpz_t (c, m->p[row][i + 1]); + } + + for (i = dim; i < nb_cols - 1; i++) + value_set_si (m->p[row][i + 1], 0); + + ppl_Constraint_inhomogeneous_term (cstr, c); + ppl_Coefficient_to_mpz_t (c, m->p[row][nb_cols - 1]); + value_set_si (m->p[row][0], 1); + + switch (ppl_Constraint_type (cstr)) + { + case PPL_CONSTRAINT_TYPE_LESS_THAN: + oppose_constraint (m, row); + case PPL_CONSTRAINT_TYPE_GREATER_THAN: + value_sub_int (m->p[row][nb_cols - 1], + m->p[row][nb_cols - 1], 1); + break; + + case PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL: + oppose_constraint (m, row); + case PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL: + break; + + case PPL_CONSTRAINT_TYPE_EQUAL: + value_set_si (m->p[row][0], 0); + break; + + default: + /* Not yet implemented. */ + gcc_unreachable(); + } + + ppl_delete_Coefficient (c); +} + +/* Creates a CloogMatrix from constraint system PCS. */ + +static CloogMatrix * +new_Cloog_Matrix_from_ppl_Constraint_System (ppl_const_Constraint_System_t pcs) +{ + CloogMatrix *matrix; + ppl_Constraint_System_const_iterator_t cit, end; + ppl_dimension_type dim; + int rows; + int row = 0; + + rows = ppl_Constrain_System_number_of_constraints (pcs); + ppl_Constraint_System_space_dimension (pcs, &dim); + matrix = cloog_matrix_alloc (rows, dim + 2); + ppl_new_Constraint_System_const_iterator (&cit); + ppl_new_Constraint_System_const_iterator (&end); + + for (ppl_Constraint_System_begin (pcs, cit), + ppl_Constraint_System_end (pcs, end); + !ppl_Constraint_System_const_iterator_equal_test (cit, end); + ppl_Constraint_System_const_iterator_increment (cit)) + { + ppl_const_Constraint_t c; + ppl_Constraint_System_const_iterator_dereference (cit, &c); + insert_constraint_into_matrix (matrix, row, c); + row++; + } + + ppl_delete_Constraint_System_const_iterator (cit); + ppl_delete_Constraint_System_const_iterator (end); + + return matrix; +} + +/* Creates a CloogMatrix from polyhedron PH. */ + +CloogMatrix * +new_Cloog_Matrix_from_ppl_Polyhedron (ppl_const_Polyhedron_t ph) +{ + ppl_const_Constraint_System_t pcs; + CloogMatrix *res; + + ppl_Polyhedron_get_constraints (ph, &pcs); + res = new_Cloog_Matrix_from_ppl_Constraint_System (pcs); + + return res; +} + +/* Creates a CloogDomain from polyhedron PH. */ + +CloogDomain * +new_Cloog_Domain_from_ppl_Polyhedron (ppl_const_Polyhedron_t ph) +{ + CloogMatrix *mat = new_Cloog_Matrix_from_ppl_Polyhedron (ph); + CloogDomain *res = cloog_domain_matrix2domain (mat); + cloog_matrix_free (mat); + return res; +} + +/* Creates a CloogDomain from a pointset powerset PS. */ + +CloogDomain * +new_Cloog_Domain_from_ppl_Pointset_Powerset ( + ppl_Pointset_Powerset_C_Polyhedron_t ps) +{ + CloogDomain *res = NULL; + ppl_Pointset_Powerset_C_Polyhedron_iterator_t it, end; + + ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&it); + ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&end); + + for (ppl_Pointset_Powerset_C_Polyhedron_iterator_begin (ps, it), + ppl_Pointset_Powerset_C_Polyhedron_iterator_end (ps, end); + !ppl_Pointset_Powerset_C_Polyhedron_iterator_equal_test (it, end); + ppl_Pointset_Powerset_C_Polyhedron_iterator_increment (it)) + { + ppl_const_Polyhedron_t ph; + CloogDomain *tmp; + + ppl_Pointset_Powerset_C_Polyhedron_iterator_dereference (it, &ph); + tmp = new_Cloog_Domain_from_ppl_Polyhedron (ph); + + if (res == NULL) + res = tmp; + else + res = cloog_domain_union (res, tmp); + } + + ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (it); + ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (end); + + gcc_assert (res != NULL); + + return res; +} + +/* Set the inhomogeneous term of E to X. */ + +void +ppl_set_inhomogeneous_gmp (ppl_Linear_Expression_t e, Value x) +{ + Value v0, v1; + ppl_Coefficient_t c; + + value_init (v0); + value_init (v1); + ppl_new_Coefficient (&c); + + ppl_Linear_Expression_inhomogeneous_term (e, c); + ppl_Coefficient_to_mpz_t (c, v1); + value_oppose (v1, v1); + value_assign (v0, x); + value_addto (v0, v0, v1); + ppl_assign_Coefficient_from_mpz_t (c, v0); + ppl_Linear_Expression_add_to_inhomogeneous (e, c); + + value_clear (v0); + value_clear (v1); + ppl_delete_Coefficient (c); +} + +/* Set E[I] to X. */ + +void +ppl_set_coef_gmp (ppl_Linear_Expression_t e, ppl_dimension_type i, Value x) +{ + Value v0, v1; + ppl_Coefficient_t c; + + value_init (v0); + value_init (v1); + ppl_new_Coefficient (&c); + + ppl_Linear_Expression_coefficient (e, i, c); + ppl_Coefficient_to_mpz_t (c, v1); + value_oppose (v1, v1); + value_assign (v0, x); + value_addto (v0, v0, v1); + ppl_assign_Coefficient_from_mpz_t (c, v0); + ppl_Linear_Expression_add_to_coefficient (e, i, c); + + value_clear (v0); + value_clear (v1); + ppl_delete_Coefficient (c); +} + +/* Insert after X NB_NEW_DIMS empty dimensions into PH. + + With x = 3 and nb_new_dims = 4 + + | d0 d1 d2 d3 d4 + + is transformed to + + | d0 d1 d2 x0 x1 x2 x3 d3 d4 + + | map = {0, 1, 2, 7, 8, 3, 4, 5, 6} +*/ + +void +ppl_insert_dimensions_pointset (ppl_Pointset_Powerset_C_Polyhedron_t ph, int x, + int nb_new_dims) +{ + ppl_dimension_type i, dim; + ppl_dimension_type *map; + ppl_dimension_type x_ppl, nb_new_dims_ppl; + + x_ppl = (ppl_dimension_type) x; + nb_new_dims_ppl = (ppl_dimension_type) nb_new_dims; + + ppl_Pointset_Powerset_C_Polyhedron_space_dimension (ph, &dim); + ppl_Pointset_Powerset_C_Polyhedron_add_space_dimensions_and_embed (ph, nb_new_dims); + + map = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, dim + nb_new_dims); + + for (i = 0; i < x_ppl; i++) + map[i] = i; + + for (i = x_ppl; i < x_ppl + nb_new_dims_ppl; i++) + map[dim + i - x_ppl] = i; + + for (i = x_ppl + nb_new_dims_ppl; i < dim + nb_new_dims_ppl; i++) + map[i - nb_new_dims_ppl] = i; + + ppl_Pointset_Powerset_C_Polyhedron_map_space_dimensions (ph, map, dim + nb_new_dims); + free (map); +} + +/* Insert after X NB_NEW_DIMS empty dimensions into PH. + + With x = 3 and nb_new_dims = 4 + + | d0 d1 d2 d3 d4 + + is transformed to + + | d0 d1 d2 x0 x1 x2 x3 d3 d4 + + | map = {0, 1, 2, 7, 8, 3, 4, 5, 6} +*/ + +void +ppl_insert_dimensions (ppl_Polyhedron_t ph, int x, + int nb_new_dims) +{ + ppl_dimension_type i, dim; + ppl_dimension_type *map; + ppl_dimension_type x_ppl, nb_new_dims_ppl; + + x_ppl = (ppl_dimension_type) x; + nb_new_dims_ppl = (ppl_dimension_type) nb_new_dims; + + ppl_Polyhedron_space_dimension (ph, &dim); + ppl_Polyhedron_add_space_dimensions_and_embed (ph, nb_new_dims); + + map = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, dim + nb_new_dims); + + for (i = 0; i < x_ppl; i++) + map[i] = i; + + for (i = x_ppl; i < x_ppl + nb_new_dims_ppl; i++) + map[dim + i - x_ppl] = i; + + for (i = x_ppl + nb_new_dims_ppl; i < dim + nb_new_dims_ppl; i++) + map[i - nb_new_dims_ppl] = i; + + ppl_Polyhedron_map_space_dimensions (ph, map, dim + nb_new_dims); + free (map); +} + +/* Based on the original polyhedron PH, returns a new polyhedron with + an extra dimension placed at position LOOP + 1 that slices the + dimension LOOP into strips of size STRIDE. */ + +ppl_Polyhedron_t +ppl_strip_loop (ppl_Polyhedron_t ph, ppl_dimension_type loop, int stride) +{ + ppl_const_Constraint_System_t pcs; + ppl_Constraint_System_const_iterator_t cit, end; + ppl_const_Constraint_t cstr; + ppl_Linear_Expression_t expr; + int v; + ppl_dimension_type dim; + ppl_Polyhedron_t res; + ppl_Coefficient_t c; + Value val; + + value_init (val); + ppl_new_Coefficient (&c); + + ppl_Polyhedron_space_dimension (ph, &dim); + ppl_Polyhedron_get_constraints (ph, &pcs); + + /* Start from a copy of the constraints. */ + ppl_new_C_Polyhedron_from_space_dimension (&res, dim + 1, 0); + ppl_Polyhedron_add_constraints (res, pcs); + + /* Add an empty dimension for the strip loop. */ + ppl_insert_dimensions (res, loop, 1); + + /* Identify the constraints that define the lower and upper bounds + of the strip-mined loop, and add them to the strip loop. */ + { + ppl_Polyhedron_t tmp; + + ppl_new_C_Polyhedron_from_space_dimension (&tmp, dim + 1, 0); + ppl_new_Constraint_System_const_iterator (&cit); + ppl_new_Constraint_System_const_iterator (&end); + + for (ppl_Constraint_System_begin (pcs, cit), + ppl_Constraint_System_end (pcs, end); + !ppl_Constraint_System_const_iterator_equal_test (cit, end); + ppl_Constraint_System_const_iterator_increment (cit)) + { + ppl_Constraint_System_const_iterator_dereference (cit, &cstr); + ppl_new_Linear_Expression_from_Constraint (&expr, cstr); + ppl_Linear_Expression_coefficient (expr, loop, c); + ppl_delete_Linear_Expression (expr); + ppl_Coefficient_to_mpz_t (c, val); + v = value_get_si (val); + + if (0 < v || v < 0) + ppl_Polyhedron_add_constraint (tmp, cstr); + } + ppl_delete_Constraint_System_const_iterator (cit); + ppl_delete_Constraint_System_const_iterator (end); + + ppl_insert_dimensions (tmp, loop + 1, 1); + ppl_Polyhedron_get_constraints (tmp, &pcs); + ppl_Polyhedron_add_constraints (res, pcs); + ppl_delete_Polyhedron (tmp); + } + + /* Lower bound of a tile starts at "stride * outer_iv". */ + { + ppl_Constraint_t new_cstr; + ppl_new_Linear_Expression_with_dimension (&expr, dim + 1); + + ppl_set_coef (expr, loop + 1, 1); + ppl_set_coef (expr, loop, -1 * stride); + + ppl_new_Constraint (&new_cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL); + ppl_delete_Linear_Expression (expr); + ppl_Polyhedron_add_constraint (res, new_cstr); + ppl_delete_Constraint (new_cstr); + } + + /* Upper bound of a tile stops at "stride * outer_iv + stride - 1", + or at the old upper bound that is not modified. */ + { + ppl_Constraint_t new_cstr; + ppl_new_Linear_Expression_with_dimension (&expr, dim + 1); + + ppl_set_coef (expr, loop + 1, -1); + ppl_set_coef (expr, loop, stride); + ppl_set_inhomogeneous (expr, stride - 1); + + ppl_new_Constraint (&new_cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL); + ppl_delete_Linear_Expression (expr); + ppl_Polyhedron_add_constraint (res, new_cstr); + ppl_delete_Constraint (new_cstr); + } + + value_clear (val); + ppl_delete_Coefficient (c); + return res; +} + +/* Lexicographically compares two linear expressions A and B and + returns negative when A < B, 0 when A == B and positive when A > B. */ + +int +ppl_lexico_compare_linear_expressions (ppl_Linear_Expression_t a, + ppl_Linear_Expression_t b) +{ + ppl_dimension_type min_length, length1, length2; + ppl_dimension_type i; + ppl_Coefficient_t c; + int res; + Value va, vb; + + ppl_Linear_Expression_space_dimension (a, &length1); + ppl_Linear_Expression_space_dimension (b, &length2); + ppl_new_Coefficient (&c); + value_init (va); + value_init (vb); + + if (length1 < length2) + min_length = length1; + else + min_length = length2; + + for (i = 0; i < min_length; i++) + { + ppl_Linear_Expression_coefficient (a, i, c); + ppl_Coefficient_to_mpz_t (c, va); + ppl_Linear_Expression_coefficient (b, i, c); + ppl_Coefficient_to_mpz_t (c, vb); + res = value_compare (va, vb); + + if (res == 0) + continue; + + value_clear (va); + value_clear (vb); + ppl_delete_Coefficient (c); + return res; + } + + value_clear (va); + value_clear (vb); + ppl_delete_Coefficient (c); + return length1 - length2; +} + +/* Print to FILE the polyhedron PH under its PolyLib matrix form. */ + +void +ppl_print_polyhedron_matrix (FILE *file, ppl_const_Polyhedron_t ph) +{ + CloogMatrix *mat = new_Cloog_Matrix_from_ppl_Polyhedron (ph); + cloog_matrix_print (file, mat); + cloog_matrix_free (mat); +} + +/* Print to FILE the powerset PS in its PolyLib matrix form. */ + +void +ppl_print_powerset_matrix (FILE *file, + ppl_Pointset_Powerset_C_Polyhedron_t ps) +{ + ppl_Pointset_Powerset_C_Polyhedron_iterator_t it, end; + + ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&it); + ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&end); + + for (ppl_Pointset_Powerset_C_Polyhedron_iterator_begin (ps, it), + ppl_Pointset_Powerset_C_Polyhedron_iterator_end (ps, end); + !ppl_Pointset_Powerset_C_Polyhedron_iterator_equal_test (it, end); + ppl_Pointset_Powerset_C_Polyhedron_iterator_increment (it)) + { + ppl_const_Polyhedron_t ph; + + ppl_Pointset_Powerset_C_Polyhedron_iterator_dereference (it, &ph); + ppl_print_polyhedron_matrix (file, ph); + } + + ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (it); + ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (end); +} + +/* Print to STDERR the polyhedron PH under its PolyLib matrix form. */ + +void +debug_ppl_polyhedron_matrix (ppl_Polyhedron_t ph) +{ + ppl_print_polyhedron_matrix (stderr, ph); +} + +/* Print to STDERR the powerset PS in its PolyLib matrix form. */ + +void +debug_ppl_powerset_matrix (ppl_Pointset_Powerset_C_Polyhedron_t ps) +{ + ppl_print_powerset_matrix (stderr, ps); +} + +/* Read from FILE a polyhedron under PolyLib matrix form and return a + PPL polyhedron object. */ + +void +ppl_read_polyhedron_matrix (ppl_Polyhedron_t *ph, FILE *file) +{ + CloogMatrix *mat = cloog_matrix_read (file); + new_C_Polyhedron_from_Cloog_Matrix (ph, mat); + cloog_matrix_free (mat); +} +#endif diff --git a/gcc/graphite-ppl.h b/gcc/graphite-ppl.h new file mode 100644 index 00000000000..8a23c93cc0f --- /dev/null +++ b/gcc/graphite-ppl.h @@ -0,0 +1,133 @@ +/* Gimple Represented as Polyhedra. + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Sebastian Pop <sebastian.pop@inria.fr> + and Tobias Grosser <grosser@fim.uni-passau.de>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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/>. */ +#ifndef GCC_GRAPHITE_PPL_H +#define GCC_GRAPHITE_PPL_H + +#include "double-int.h" +#include "tree.h" + +CloogMatrix *new_Cloog_Matrix_from_ppl_Polyhedron (ppl_const_Polyhedron_t); +CloogDomain *new_Cloog_Domain_from_ppl_Polyhedron (ppl_const_Polyhedron_t); +CloogDomain * new_Cloog_Domain_from_ppl_Pointset_Powerset ( + ppl_Pointset_Powerset_C_Polyhedron_t); +void new_C_Polyhedron_from_Cloog_Matrix (ppl_Polyhedron_t *, CloogMatrix *); +void insert_constraint_into_matrix (CloogMatrix *, int, ppl_const_Constraint_t); +ppl_Polyhedron_t ppl_strip_loop (ppl_Polyhedron_t, ppl_dimension_type, int); +int ppl_lexico_compare_linear_expressions (ppl_Linear_Expression_t, + ppl_Linear_Expression_t); + +void ppl_print_polyhedron_matrix (FILE *, ppl_const_Polyhedron_t); +void ppl_print_powerset_matrix (FILE *, ppl_Pointset_Powerset_C_Polyhedron_t); +void debug_ppl_polyhedron_matrix (ppl_Polyhedron_t); +void debug_ppl_powerset_matrix (ppl_Pointset_Powerset_C_Polyhedron_t); +void ppl_read_polyhedron_matrix (ppl_Polyhedron_t *, FILE *); +void ppl_insert_dimensions (ppl_Polyhedron_t, int, int); +void ppl_insert_dimensions_pointset (ppl_Pointset_Powerset_C_Polyhedron_t, int, + int); +void ppl_set_inhomogeneous_gmp (ppl_Linear_Expression_t, Value); +void ppl_set_coef_gmp (ppl_Linear_Expression_t, ppl_dimension_type, Value); + +/* Assigns to RES the value of the INTEGER_CST T. */ + +static inline void +tree_int_to_gmp (tree t, Value res) +{ + double_int di = tree_to_double_int (t); + mpz_set_double_int (res, di, TYPE_UNSIGNED (TREE_TYPE (t))); +} + +/* Converts a GMP constant VAL to a tree and returns it. */ + +static inline tree +gmp_cst_to_tree (tree type, Value val) +{ + tree t = type ? type : integer_type_node; + Value tmp; + double_int di; + + value_init (tmp); + value_assign (tmp, val); + di = mpz_get_double_int (t, tmp, true); + value_clear (tmp); + + return double_int_to_tree (t, di); +} + +/* Set the inhomogeneous term of E to the integer X. */ + +static inline void +ppl_set_inhomogeneous (ppl_Linear_Expression_t e, int x) +{ + Value v; + value_init (v); + value_set_si (v, x); + ppl_set_inhomogeneous_gmp (e, v); + value_clear (v); +} + +/* Set the inhomogeneous term of E to the tree X. */ + +static inline void +ppl_set_inhomogeneous_tree (ppl_Linear_Expression_t e, tree x) +{ + Value v; + value_init (v); + tree_int_to_gmp (x, v); + ppl_set_inhomogeneous_gmp (e, v); + value_clear (v); +} + +/* Set E[I] to integer X. */ + +static inline void +ppl_set_coef (ppl_Linear_Expression_t e, ppl_dimension_type i, int x) +{ + Value v; + value_init (v); + value_set_si (v, x); + ppl_set_coef_gmp (e, i, v); + value_clear (v); +} + +/* Set E[I] to tree X. */ + +static inline void +ppl_set_coef_tree (ppl_Linear_Expression_t e, ppl_dimension_type i, tree x) +{ + Value v; + value_init (v); + tree_int_to_gmp (x, v); + ppl_set_coef_gmp (e, i, v); + value_clear (v); +} + +/* Sets RES to the max of V1 and V2. */ + +static inline void +value_max (Value res, Value v1, Value v2) +{ + if (value_compare (v1, v2) < 0) + value_assign (res, v2); + value_assign (res, v1); +} + +#endif + diff --git a/gcc/graphite-scop-detection.c b/gcc/graphite-scop-detection.c new file mode 100644 index 00000000000..60cb95ba724 --- /dev/null +++ b/gcc/graphite-scop-detection.c @@ -0,0 +1,1640 @@ +/* Detection of Static Control Parts (SCoP) for Graphite. + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Sebastian Pop <sebastian.pop@amd.com> and + Tobias Grosser <grosser@fim.uni-passau.de>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "ggc.h" +#include "tree.h" +#include "rtl.h" +#include "basic-block.h" +#include "diagnostic.h" +#include "tree-flow.h" +#include "toplev.h" +#include "tree-dump.h" +#include "timevar.h" +#include "cfgloop.h" +#include "tree-chrec.h" +#include "tree-data-ref.h" +#include "tree-scalar-evolution.h" +#include "tree-pass.h" +#include "domwalk.h" +#include "value-prof.h" +#include "pointer-set.h" +#include "gimple.h" +#include "sese.h" + +#ifdef HAVE_cloog +#include "cloog/cloog.h" +#include "ppl_c.h" +#include "graphite-ppl.h" +#include "graphite.h" +#include "graphite-poly.h" +#include "graphite-scop-detection.h" + +/* The type of the analyzed basic block. */ + +typedef enum gbb_type { + GBB_UNKNOWN, + GBB_LOOP_SING_EXIT_HEADER, + GBB_LOOP_MULT_EXIT_HEADER, + GBB_LOOP_EXIT, + GBB_COND_HEADER, + GBB_SIMPLE, + GBB_LAST +} gbb_type; + +/* Detect the type of BB. Loop headers are only marked, if they are + new. This means their loop_father is different to LAST_LOOP. + Otherwise they are treated like any other bb and their type can be + any other type. */ + +static gbb_type +get_bb_type (basic_block bb, struct loop *last_loop) +{ + VEC (basic_block, heap) *dom; + int nb_dom, nb_suc; + struct loop *loop = bb->loop_father; + + /* Check, if we entry into a new loop. */ + if (loop != last_loop) + { + if (single_exit (loop) != NULL) + return GBB_LOOP_SING_EXIT_HEADER; + else if (loop->num != 0) + return GBB_LOOP_MULT_EXIT_HEADER; + else + return GBB_COND_HEADER; + } + + dom = get_dominated_by (CDI_DOMINATORS, bb); + nb_dom = VEC_length (basic_block, dom); + VEC_free (basic_block, heap, dom); + + if (nb_dom == 0) + return GBB_LAST; + + nb_suc = VEC_length (edge, bb->succs); + + if (nb_dom == 1 && nb_suc == 1) + return GBB_SIMPLE; + + return GBB_COND_HEADER; +} + +/* A SCoP detection region, defined using bbs as borders. + + All control flow touching this region, comes in passing basic_block + ENTRY and leaves passing basic_block EXIT. By using bbs instead of + edges for the borders we are able to represent also regions that do + not have a single entry or exit edge. + + But as they have a single entry basic_block and a single exit + basic_block, we are able to generate for every sd_region a single + entry and exit edge. + + 1 2 + \ / + 3 <- entry + | + 4 + / \ This region contains: {3, 4, 5, 6, 7, 8} + 5 6 + | | + 7 8 + \ / + 9 <- exit */ + + +typedef struct sd_region_p +{ + /* The entry bb dominates all bbs in the sd_region. It is part of + the region. */ + basic_block entry; + + /* The exit bb postdominates all bbs in the sd_region, but is not + part of the region. */ + basic_block exit; +} sd_region; + +DEF_VEC_O(sd_region); +DEF_VEC_ALLOC_O(sd_region, heap); + + +/* Moves the scops from SOURCE to TARGET and clean up SOURCE. */ + +static void +move_sd_regions (VEC (sd_region, heap) **source, + VEC (sd_region, heap) **target) +{ + sd_region *s; + int i; + + for (i = 0; VEC_iterate (sd_region, *source, i, s); i++) + VEC_safe_push (sd_region, heap, *target, s); + + VEC_free (sd_region, heap, *source); +} + +/* Something like "n * m" is not allowed. */ + +static bool +graphite_can_represent_init (tree e) +{ + switch (TREE_CODE (e)) + { + case POLYNOMIAL_CHREC: + return graphite_can_represent_init (CHREC_LEFT (e)) + && graphite_can_represent_init (CHREC_RIGHT (e)); + + case MULT_EXPR: + if (chrec_contains_symbols (TREE_OPERAND (e, 0))) + return host_integerp (TREE_OPERAND (e, 1), 0); + else + return host_integerp (TREE_OPERAND (e, 0), 0); + + case PLUS_EXPR: + case POINTER_PLUS_EXPR: + case MINUS_EXPR: + return graphite_can_represent_init (TREE_OPERAND (e, 0)) + && graphite_can_represent_init (TREE_OPERAND (e, 1)); + + case NEGATE_EXPR: + case BIT_NOT_EXPR: + CASE_CONVERT: + case NON_LVALUE_EXPR: + return graphite_can_represent_init (TREE_OPERAND (e, 0)); + + default: + break; + } + + return true; +} + +/* Return true when SCEV can be represented in the polyhedral model. + + An expression can be represented, if it can be expressed as an + affine expression. For loops (i, j) and parameters (m, n) all + affine expressions are of the form: + + x1 * i + x2 * j + x3 * m + x4 * n + x5 * 1 where x1..x5 element of Z + + 1 i + 20 j + (-2) m + 25 + + Something like "i * n" or "n * m" is not allowed. + + OUTERMOST_LOOP defines the outermost loop that can variate. */ + +static bool +graphite_can_represent_scev (tree scev, int outermost_loop) +{ + if (chrec_contains_undetermined (scev)) + return false; + + if (TREE_CODE (scev) == POLYNOMIAL_CHREC + + /* Check for constant strides. With a non constant stride of + 'n' we would have a value of 'iv * n'. */ + && (!evolution_function_right_is_integer_cst (scev) + + /* Check the initial value: 'n * m' cannot be represented. */ + || !graphite_can_represent_init (scev))) + return false; + + /* Only affine functions can be represented. */ + if (!scev_is_linear_expression (scev)) + return false; + + return evolution_function_is_invariant_p (scev, outermost_loop) + || evolution_function_is_affine_multivariate_p (scev, outermost_loop); +} + + +/* Return true when EXPR can be represented in the polyhedral model. + + This means an expression can be represented, if it is linear with + respect to the loops and the strides are non parametric. + LOOP is the place where the expr will be evaluated and OUTERMOST_LOOP + defindes the outermost loop that can variate. SCOP_ENTRY defines the + entry of the region we analyse. */ + +static bool +graphite_can_represent_expr (basic_block scop_entry, loop_p loop, + loop_p outermost_loop, tree expr) +{ + tree scev = analyze_scalar_evolution (loop, expr); + + scev = instantiate_scev (scop_entry, loop, scev); + + return graphite_can_represent_scev (scev, outermost_loop->num); +} + +/* Return false if the tree_code of the operand OP or any of its operands + is component_ref. */ + +static bool +exclude_component_ref (tree op) +{ + int i; + int len; + + if (!op) + return true; + + if (TREE_CODE (op) == COMPONENT_REF) + return false; + + len = TREE_OPERAND_LENGTH (op); + for (i = 0; i < len; ++i) + if (!exclude_component_ref (TREE_OPERAND (op, i))) + return false; + + return true; +} + +/* Return true if the data references of STMT can be represented by + Graphite. */ + +static bool +stmt_has_simple_data_refs_p (loop_p outermost_loop, gimple stmt) +{ + data_reference_p dr; + unsigned i; + int j; + bool res = true; + int loop = outermost_loop->num; + VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5); + + graphite_find_data_references_in_stmt (outermost_loop, stmt, &drs); + + for (j = 0; VEC_iterate (data_reference_p, drs, j, dr); j++) + for (i = 0; i < DR_NUM_DIMENSIONS (dr); i++) + if (!graphite_can_represent_scev (DR_ACCESS_FN (dr, i), loop)) + { + res = false; + goto done; + } + + done: + free_data_refs (drs); + return res; +} + +/* Return true if we can create an affine data-ref for OP in STMT + in regards to OUTERMOST_LOOP. */ + +static bool +stmt_simple_memref_p (loop_p outermost_loop, gimple stmt, tree op) +{ + data_reference_p dr; + unsigned int i; + VEC(tree,heap) *fns; + tree t; + bool res = true; + + dr = create_data_ref (outermost_loop, op, stmt, true); + fns = DR_ACCESS_FNS (dr); + + for (i = 0; VEC_iterate (tree, fns, i, t); i++) + if (!graphite_can_represent_scev (t, outermost_loop->num)) + { + res = false; + break; + } + + free_data_ref (dr); + return res; +} + +/* Return true if the operand OP used in STMT is simple in regards to + OUTERMOST_LOOP. */ + +static bool +is_simple_operand (loop_p outermost_loop, gimple stmt, tree op) +{ + /* It is not a simple operand when it is a declaration, */ + if (DECL_P (op)) + return false; + + /* or a structure, */ + if (AGGREGATE_TYPE_P (TREE_TYPE (op))) + return false; + + /* or a memory access that cannot be analyzed by the data reference + analysis. */ + if (handled_component_p (op) || INDIRECT_REF_P (op)) + if (!stmt_simple_memref_p (outermost_loop, stmt, op)) + return false; + + return exclude_component_ref (op); +} + +/* Return true only when STMT is simple enough for being handled by + Graphite. This depends on SCOP_ENTRY, as the parameters are + initialized relatively to this basic block, the linear functions + are initialized to OUTERMOST_LOOP and BB is the place where we try + to evaluate the STMT. */ + +static bool +stmt_simple_for_scop_p (basic_block scop_entry, loop_p outermost_loop, + gimple stmt, basic_block bb) +{ + loop_p loop = bb->loop_father; + + gcc_assert (scop_entry); + + /* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects. + Calls have side-effects, except those to const or pure + functions. */ + if (gimple_has_volatile_ops (stmt) + || (gimple_code (stmt) == GIMPLE_CALL + && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE))) + || (gimple_code (stmt) == GIMPLE_ASM)) + return false; + + if (!stmt_has_simple_data_refs_p (outermost_loop, stmt)) + return false; + + switch (gimple_code (stmt)) + { + case GIMPLE_RETURN: + case GIMPLE_LABEL: + return true; + + case GIMPLE_COND: + { + tree op; + ssa_op_iter op_iter; + enum tree_code code = gimple_cond_code (stmt); + + /* We can handle all binary comparisons. Inequalities are + also supported as they can be represented with union of + polyhedra. */ + if (!(code == LT_EXPR + || code == GT_EXPR + || code == LE_EXPR + || code == GE_EXPR + || code == EQ_EXPR + || code == NE_EXPR)) + return false; + + FOR_EACH_SSA_TREE_OPERAND (op, stmt, op_iter, SSA_OP_ALL_USES) + if (!graphite_can_represent_expr (scop_entry, loop, outermost_loop, + op) + /* We can not handle REAL_TYPE. Failed for pr39260. */ + || TREE_CODE (TREE_TYPE (op)) == REAL_TYPE) + return false; + + return true; + } + + case GIMPLE_ASSIGN: + { + enum tree_code code = gimple_assign_rhs_code (stmt); + + switch (get_gimple_rhs_class (code)) + { + case GIMPLE_UNARY_RHS: + case GIMPLE_SINGLE_RHS: + return (is_simple_operand (outermost_loop, stmt, + gimple_assign_lhs (stmt)) + && is_simple_operand (outermost_loop, stmt, + gimple_assign_rhs1 (stmt))); + + case GIMPLE_BINARY_RHS: + return (is_simple_operand (outermost_loop, stmt, + gimple_assign_lhs (stmt)) + && is_simple_operand (outermost_loop, stmt, + gimple_assign_rhs1 (stmt)) + && is_simple_operand (outermost_loop, stmt, + gimple_assign_rhs2 (stmt))); + + case GIMPLE_INVALID_RHS: + default: + gcc_unreachable (); + } + } + + case GIMPLE_CALL: + { + size_t i; + size_t n = gimple_call_num_args (stmt); + tree lhs = gimple_call_lhs (stmt); + + if (lhs && !is_simple_operand (outermost_loop, stmt, lhs)) + return false; + + for (i = 0; i < n; i++) + if (!is_simple_operand (outermost_loop, stmt, + gimple_call_arg (stmt, i))) + return false; + + return true; + } + + default: + /* These nodes cut a new scope. */ + return false; + } + + return false; +} + +/* Returns the statement of BB that contains a harmful operation: that + can be a function call with side effects, the induction variables + are not linear with respect to SCOP_ENTRY, etc. The current open + scop should end before this statement. The evaluation is limited using + OUTERMOST_LOOP as outermost loop that may change. */ + +static gimple +harmful_stmt_in_bb (basic_block scop_entry, loop_p outer_loop, basic_block bb) +{ + gimple_stmt_iterator gsi; + + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + if (!stmt_simple_for_scop_p (scop_entry, outer_loop, gsi_stmt (gsi), bb)) + return gsi_stmt (gsi); + + return NULL; +} + +/* Return true when it is not possible to represent LOOP in the + polyhedral representation. This is evaluated taking SCOP_ENTRY and + OUTERMOST_LOOP in mind. */ + +static bool +graphite_can_represent_loop (basic_block scop_entry, loop_p outermost_loop, + loop_p loop) +{ + tree niter = number_of_latch_executions (loop); + + /* Number of iterations unknown. */ + if (chrec_contains_undetermined (niter)) + return false; + + /* Number of iterations not affine. */ + if (!graphite_can_represent_expr (scop_entry, loop, outermost_loop, niter)) + return false; + + return true; +} + +/* Store information needed by scopdet_* functions. */ + +struct scopdet_info +{ + /* Exit of the open scop would stop if the current BB is harmful. */ + basic_block exit; + + /* Where the next scop would start if the current BB is harmful. */ + basic_block next; + + /* The bb or one of its children contains open loop exits. That means + loop exit nodes that are not surrounded by a loop dominated by bb. */ + bool exits; + + /* The bb or one of its children contains only structures we can handle. */ + bool difficult; +}; + +static struct scopdet_info build_scops_1 (basic_block, loop_p, + VEC (sd_region, heap) **, loop_p); + +/* Calculates BB infos. If bb is difficult we add valid SCoPs dominated by BB + to SCOPS. TYPE is the gbb_type of BB. */ + +static struct scopdet_info +scopdet_basic_block_info (basic_block bb, loop_p outermost_loop, + VEC (sd_region, heap) **scops, gbb_type type) +{ + loop_p loop = bb->loop_father; + struct scopdet_info result; + gimple stmt; + + /* XXX: ENTRY_BLOCK_PTR could be optimized in later steps. */ + basic_block entry_block = ENTRY_BLOCK_PTR; + stmt = harmful_stmt_in_bb (entry_block, outermost_loop, bb); + result.difficult = (stmt != NULL); + result.exit = NULL; + + switch (type) + { + case GBB_LAST: + result.next = NULL; + result.exits = false; + + /* Mark bbs terminating a SESE region difficult, if they start + a condition. */ + if (!single_succ_p (bb)) + result.difficult = true; + else + result.exit = single_succ (bb); + + break; + + case GBB_SIMPLE: + result.next = single_succ (bb); + result.exits = false; + result.exit = single_succ (bb); + break; + + case GBB_LOOP_SING_EXIT_HEADER: + { + VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3); + struct scopdet_info sinfo; + edge exit_e = single_exit (loop); + + sinfo = build_scops_1 (bb, outermost_loop, ®ions, loop); + + if (!graphite_can_represent_loop (entry_block, outermost_loop, loop)) + result.difficult = true; + + result.difficult |= sinfo.difficult; + + /* Try again with another loop level. */ + if (result.difficult + && loop_depth (outermost_loop) + 1 == loop_depth (loop)) + { + outermost_loop = loop; + + VEC_free (sd_region, heap, regions); + regions = VEC_alloc (sd_region, heap, 3); + + sinfo = scopdet_basic_block_info (bb, outermost_loop, scops, type); + + result = sinfo; + result.difficult = true; + + if (sinfo.difficult) + move_sd_regions (®ions, scops); + else + { + sd_region open_scop; + open_scop.entry = bb; + open_scop.exit = exit_e->dest; + VEC_safe_push (sd_region, heap, *scops, &open_scop); + VEC_free (sd_region, heap, regions); + } + } + else + { + result.exit = exit_e->dest; + result.next = exit_e->dest; + + /* If we do not dominate result.next, remove it. It's either + the EXIT_BLOCK_PTR, or another bb dominates it and will + call the scop detection for this bb. */ + if (!dominated_by_p (CDI_DOMINATORS, result.next, bb)) + result.next = NULL; + + if (exit_e->src->loop_father != loop) + result.next = NULL; + + result.exits = false; + + if (result.difficult) + move_sd_regions (®ions, scops); + else + VEC_free (sd_region, heap, regions); + } + + break; + } + + case GBB_LOOP_MULT_EXIT_HEADER: + { + /* XXX: For now we just do not join loops with multiple exits. If the + exits lead to the same bb it may be possible to join the loop. */ + VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3); + VEC (edge, heap) *exits = get_loop_exit_edges (loop); + edge e; + int i; + build_scops_1 (bb, loop, ®ions, loop); + + /* Scan the code dominated by this loop. This means all bbs, that are + are dominated by a bb in this loop, but are not part of this loop. + + The easiest case: + - The loop exit destination is dominated by the exit sources. + + TODO: We miss here the more complex cases: + - The exit destinations are dominated by another bb inside + the loop. + - The loop dominates bbs, that are not exit destinations. */ + for (i = 0; VEC_iterate (edge, exits, i, e); i++) + if (e->src->loop_father == loop + && dominated_by_p (CDI_DOMINATORS, e->dest, e->src)) + { + if (loop_outer (outermost_loop)) + outermost_loop = loop_outer (outermost_loop); + + /* Pass loop_outer to recognize e->dest as loop header in + build_scops_1. */ + if (e->dest->loop_father->header == e->dest) + build_scops_1 (e->dest, outermost_loop, ®ions, + loop_outer (e->dest->loop_father)); + else + build_scops_1 (e->dest, outermost_loop, ®ions, + e->dest->loop_father); + } + + result.next = NULL; + result.exit = NULL; + result.difficult = true; + result.exits = false; + move_sd_regions (®ions, scops); + VEC_free (edge, heap, exits); + break; + } + case GBB_COND_HEADER: + { + VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3); + struct scopdet_info sinfo; + VEC (basic_block, heap) *dominated; + int i; + basic_block dom_bb; + basic_block last_exit = NULL; + edge e; + result.exits = false; + + /* First check the successors of BB, and check if it is + possible to join the different branches. */ + for (i = 0; VEC_iterate (edge, bb->succs, i, e); i++) + { + /* Ignore loop exits. They will be handled after the loop + body. */ + if (is_loop_exit (loop, e->dest)) + { + result.exits = true; + continue; + } + + /* Do not follow edges that lead to the end of the + conditions block. For example, in + + | 0 + | /|\ + | 1 2 | + | | | | + | 3 4 | + | \|/ + | 6 + + the edge from 0 => 6. Only check if all paths lead to + the same node 6. */ + + if (!single_pred_p (e->dest)) + { + /* Check, if edge leads directly to the end of this + condition. */ + if (!last_exit) + last_exit = e->dest; + + if (e->dest != last_exit) + result.difficult = true; + + continue; + } + + if (!dominated_by_p (CDI_DOMINATORS, e->dest, bb)) + { + result.difficult = true; + continue; + } + + sinfo = build_scops_1 (e->dest, outermost_loop, ®ions, loop); + + result.exits |= sinfo.exits; + result.difficult |= sinfo.difficult; + + /* Checks, if all branches end at the same point. + If that is true, the condition stays joinable. + Have a look at the example above. */ + if (sinfo.exit) + { + if (!last_exit) + last_exit = sinfo.exit; + + if (sinfo.exit != last_exit) + result.difficult = true; + } + else + result.difficult = true; + } + + if (!last_exit) + result.difficult = true; + + /* Join the branches of the condition if possible. */ + if (!result.exits && !result.difficult) + { + /* Only return a next pointer if we dominate this pointer. + Otherwise it will be handled by the bb dominating it. */ + if (dominated_by_p (CDI_DOMINATORS, last_exit, bb) + && last_exit != bb) + result.next = last_exit; + else + result.next = NULL; + + result.exit = last_exit; + + VEC_free (sd_region, heap, regions); + break; + } + + /* Scan remaining bbs dominated by BB. */ + dominated = get_dominated_by (CDI_DOMINATORS, bb); + + for (i = 0; VEC_iterate (basic_block, dominated, i, dom_bb); i++) + { + /* Ignore loop exits: they will be handled after the loop body. */ + if (loop_depth (find_common_loop (loop, dom_bb->loop_father)) + < loop_depth (loop)) + { + result.exits = true; + continue; + } + + /* Ignore the bbs processed above. */ + if (single_pred_p (dom_bb) && single_pred (dom_bb) == bb) + continue; + + if (loop_depth (loop) > loop_depth (dom_bb->loop_father)) + sinfo = build_scops_1 (dom_bb, outermost_loop, ®ions, + loop_outer (loop)); + else + sinfo = build_scops_1 (dom_bb, outermost_loop, ®ions, loop); + + result.exits |= sinfo.exits; + result.difficult = true; + result.exit = NULL; + } + + VEC_free (basic_block, heap, dominated); + + result.next = NULL; + move_sd_regions (®ions, scops); + + break; + } + + default: + gcc_unreachable (); + } + + return result; +} + +/* Starting from CURRENT we walk the dominance tree and add new sd_regions to + SCOPS. The analyse if a sd_region can be handled is based on the value + of OUTERMOST_LOOP. Only loops inside OUTERMOST loops may change. LOOP + is the loop in which CURRENT is handled. + + TODO: These functions got a little bit big. They definitely should be cleaned + up. */ + +static struct scopdet_info +build_scops_1 (basic_block current, loop_p outermost_loop, + VEC (sd_region, heap) **scops, loop_p loop) +{ + bool in_scop = false; + sd_region open_scop; + struct scopdet_info sinfo; + + /* Initialize result. */ + struct scopdet_info result; + result.exits = false; + result.difficult = false; + result.next = NULL; + result.exit = NULL; + open_scop.entry = NULL; + open_scop.exit = NULL; + sinfo.exit = NULL; + + /* Loop over the dominance tree. If we meet a difficult bb, close + the current SCoP. Loop and condition header start a new layer, + and can only be added if all bbs in deeper layers are simple. */ + while (current != NULL) + { + sinfo = scopdet_basic_block_info (current, outermost_loop, scops, + get_bb_type (current, loop)); + + if (!in_scop && !(sinfo.exits || sinfo.difficult)) + { + open_scop.entry = current; + open_scop.exit = NULL; + in_scop = true; + } + else if (in_scop && (sinfo.exits || sinfo.difficult)) + { + open_scop.exit = current; + VEC_safe_push (sd_region, heap, *scops, &open_scop); + in_scop = false; + } + + result.difficult |= sinfo.difficult; + result.exits |= sinfo.exits; + + current = sinfo.next; + } + + /* Try to close open_scop, if we are still in an open SCoP. */ + if (in_scop) + { + open_scop.exit = sinfo.exit; + gcc_assert (open_scop.exit); + VEC_safe_push (sd_region, heap, *scops, &open_scop); + } + + result.exit = sinfo.exit; + return result; +} + +/* Checks if a bb is contained in REGION. */ + +static bool +bb_in_sd_region (basic_block bb, sd_region *region) +{ + return bb_in_region (bb, region->entry, region->exit); +} + +/* Returns the single entry edge of REGION, if it does not exits NULL. */ + +static edge +find_single_entry_edge (sd_region *region) +{ + edge e; + edge_iterator ei; + edge entry = NULL; + + FOR_EACH_EDGE (e, ei, region->entry->preds) + if (!bb_in_sd_region (e->src, region)) + { + if (entry) + { + entry = NULL; + break; + } + + else + entry = e; + } + + return entry; +} + +/* Returns the single exit edge of REGION, if it does not exits NULL. */ + +static edge +find_single_exit_edge (sd_region *region) +{ + edge e; + edge_iterator ei; + edge exit = NULL; + + FOR_EACH_EDGE (e, ei, region->exit->preds) + if (bb_in_sd_region (e->src, region)) + { + if (exit) + { + exit = NULL; + break; + } + + else + exit = e; + } + + return exit; +} + +/* Create a single entry edge for REGION. */ + +static void +create_single_entry_edge (sd_region *region) +{ + if (find_single_entry_edge (region)) + return; + + /* There are multiple predecessors for bb_3 + + | 1 2 + | | / + | |/ + | 3 <- entry + | |\ + | | | + | 4 ^ + | | | + | |/ + | 5 + + There are two edges (1->3, 2->3), that point from outside into the region, + and another one (5->3), a loop latch, lead to bb_3. + + We split bb_3. + + | 1 2 + | | / + | |/ + |3.0 + | |\ (3.0 -> 3.1) = single entry edge + |3.1 | <- entry + | | | + | | | + | 4 ^ + | | | + | |/ + | 5 + + If the loop is part of the SCoP, we have to redirect the loop latches. + + | 1 2 + | | / + | |/ + |3.0 + | | (3.0 -> 3.1) = entry edge + |3.1 <- entry + | |\ + | | | + | 4 ^ + | | | + | |/ + | 5 */ + + if (region->entry->loop_father->header != region->entry + || dominated_by_p (CDI_DOMINATORS, + loop_latch_edge (region->entry->loop_father)->src, + region->exit)) + { + edge forwarder = split_block_after_labels (region->entry); + region->entry = forwarder->dest; + } + else + /* This case is never executed, as the loop headers seem always to have a + single edge pointing from outside into the loop. */ + gcc_unreachable (); + +#ifdef ENABLE_CHECKING + gcc_assert (find_single_entry_edge (region)); +#endif +} + +/* Check if the sd_region, mentioned in EDGE, has no exit bb. */ + +static bool +sd_region_without_exit (edge e) +{ + sd_region *r = (sd_region *) e->aux; + + if (r) + return r->exit == NULL; + else + return false; +} + +/* Create a single exit edge for REGION. */ + +static void +create_single_exit_edge (sd_region *region) +{ + edge e; + edge_iterator ei; + edge forwarder = NULL; + basic_block exit; + + if (find_single_exit_edge (region)) + return; + + /* We create a forwarder bb (5) for all edges leaving this region + (3->5, 4->5). All other edges leading to the same bb, are moved + to a new bb (6). If these edges where part of another region (2->5) + we update the region->exit pointer, of this region. + + To identify which edge belongs to which region we depend on the e->aux + pointer in every edge. It points to the region of the edge or to NULL, + if the edge is not part of any region. + + 1 2 3 4 1->5 no region, 2->5 region->exit = 5, + \| |/ 3->5 region->exit = NULL, 4->5 region->exit = NULL + 5 <- exit + + changes to + + 1 2 3 4 1->6 no region, 2->6 region->exit = 6, + | | \/ 3->5 no region, 4->5 no region, + | | 5 + \| / 5->6 region->exit = 6 + 6 + + Now there is only a single exit edge (5->6). */ + exit = region->exit; + region->exit = NULL; + forwarder = make_forwarder_block (exit, &sd_region_without_exit, NULL); + + /* Unmark the edges, that are no longer exit edges. */ + FOR_EACH_EDGE (e, ei, forwarder->src->preds) + if (e->aux) + e->aux = NULL; + + /* Mark the new exit edge. */ + single_succ_edge (forwarder->src)->aux = region; + + /* Update the exit bb of all regions, where exit edges lead to + forwarder->dest. */ + FOR_EACH_EDGE (e, ei, forwarder->dest->preds) + if (e->aux) + ((sd_region *) e->aux)->exit = forwarder->dest; + +#ifdef ENABLE_CHECKING + gcc_assert (find_single_exit_edge (region)); +#endif +} + +/* Unmark the exit edges of all REGIONS. + See comment in "create_single_exit_edge". */ + +static void +unmark_exit_edges (VEC (sd_region, heap) *regions) +{ + int i; + sd_region *s; + edge e; + edge_iterator ei; + + for (i = 0; VEC_iterate (sd_region, regions, i, s); i++) + FOR_EACH_EDGE (e, ei, s->exit->preds) + e->aux = NULL; +} + + +/* Mark the exit edges of all REGIONS. + See comment in "create_single_exit_edge". */ + +static void +mark_exit_edges (VEC (sd_region, heap) *regions) +{ + int i; + sd_region *s; + edge e; + edge_iterator ei; + + for (i = 0; VEC_iterate (sd_region, regions, i, s); i++) + FOR_EACH_EDGE (e, ei, s->exit->preds) + if (bb_in_sd_region (e->src, s)) + e->aux = s; +} + +/* Create for all scop regions a single entry and a single exit edge. */ + +static void +create_sese_edges (VEC (sd_region, heap) *regions) +{ + int i; + sd_region *s; + + for (i = 0; VEC_iterate (sd_region, regions, i, s); i++) + create_single_entry_edge (s); + + mark_exit_edges (regions); + + for (i = 0; VEC_iterate (sd_region, regions, i, s); i++) + create_single_exit_edge (s); + + unmark_exit_edges (regions); + + fix_loop_structure (NULL); + +#ifdef ENABLE_CHECKING + verify_loop_structure (); + verify_dominators (CDI_DOMINATORS); + verify_ssa (false); +#endif +} + +/* Create graphite SCoPs from an array of scop detection REGIONS. */ + +static void +build_graphite_scops (VEC (sd_region, heap) *regions, + VEC (scop_p, heap) **scops) +{ + int i; + sd_region *s; + + for (i = 0; VEC_iterate (sd_region, regions, i, s); i++) + { + edge entry = find_single_entry_edge (s); + edge exit = find_single_exit_edge (s); + scop_p scop = new_scop (new_sese (entry, exit)); + VEC_safe_push (scop_p, heap, *scops, scop); + + /* Are there overlapping SCoPs? */ +#ifdef ENABLE_CHECKING + { + int j; + sd_region *s2; + + for (j = 0; VEC_iterate (sd_region, regions, j, s2); j++) + if (s != s2) + gcc_assert (!bb_in_sd_region (s->entry, s2)); + } +#endif + } +} + +/* Returns true when BB contains only close phi nodes. */ + +static bool +contains_only_close_phi_nodes (basic_block bb) +{ + gimple_stmt_iterator gsi; + + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + if (gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL) + return false; + + return true; +} + +/* Print statistics for SCOP to FILE. */ + +static void +print_graphite_scop_statistics (FILE* file, scop_p scop) +{ + long n_bbs = 0; + long n_loops = 0; + long n_stmts = 0; + long n_conditions = 0; + long n_p_bbs = 0; + long n_p_loops = 0; + long n_p_stmts = 0; + long n_p_conditions = 0; + + basic_block bb; + + FOR_ALL_BB (bb) + { + gimple_stmt_iterator psi; + loop_p loop = bb->loop_father; + + if (!bb_in_sese_p (bb, SCOP_REGION (scop))) + continue; + + n_bbs++; + n_p_bbs += bb->count; + + if (VEC_length (edge, bb->succs) > 1) + { + n_conditions++; + n_p_conditions += bb->count; + } + + for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi)) + { + n_stmts++; + n_p_stmts += bb->count; + } + + if (loop->header == bb && loop_in_sese_p (loop, SCOP_REGION (scop))) + { + n_loops++; + n_p_loops += bb->count; + } + + } + + fprintf (file, "\nBefore limit_scops SCoP statistics ("); + fprintf (file, "BBS:%ld, ", n_bbs); + fprintf (file, "LOOPS:%ld, ", n_loops); + fprintf (file, "CONDITIONS:%ld, ", n_conditions); + fprintf (file, "STMTS:%ld)\n", n_stmts); + fprintf (file, "\nBefore limit_scops SCoP profiling statistics ("); + fprintf (file, "BBS:%ld, ", n_p_bbs); + fprintf (file, "LOOPS:%ld, ", n_p_loops); + fprintf (file, "CONDITIONS:%ld, ", n_p_conditions); + fprintf (file, "STMTS:%ld)\n", n_p_stmts); +} + +/* Print statistics for SCOPS to FILE. */ + +static void +print_graphite_statistics (FILE* file, VEC (scop_p, heap) *scops) +{ + int i; + scop_p scop; + + for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++) + print_graphite_scop_statistics (file, scop); +} + +/* Version of free_scops special cased for limit_scops. */ + +static void +free_scops_1 (VEC (scop_p, heap) **scops) +{ + int i; + scop_p scop; + + for (i = 0; VEC_iterate (scop_p, *scops, i, scop); i++) + { + sese region = SCOP_REGION (scop); + free (SESE_PARAMS_NAMES (region)); + SESE_PARAMS_NAMES (region) = 0; + } + + free_scops (*scops); +} + +/* We limit all SCoPs to SCoPs, that are completely surrounded by a loop. + + Example: + + for (i | + { | + for (j | SCoP 1 + for (k | + } | + + * SCoP frontier, as this line is not surrounded by any loop. * + + for (l | SCoP 2 + + This is necessary as scalar evolution and parameter detection need a + outermost loop to initialize parameters correctly. + + TODO: FIX scalar evolution and parameter detection to allow more flexible + SCoP frontiers. */ + +static void +limit_scops (VEC (scop_p, heap) **scops) +{ + VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3); + + int i; + scop_p scop; + + for (i = 0; VEC_iterate (scop_p, *scops, i, scop); i++) + { + int j; + loop_p loop; + sese region = SCOP_REGION (scop); + build_scop_bbs (scop); + build_sese_loop_nests (region); + + for (j = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), j, loop); j++) + if (!loop_in_sese_p (loop_outer (loop), region) + && single_exit (loop)) + { + sd_region open_scop; + open_scop.entry = loop->header; + open_scop.exit = single_exit (loop)->dest; + + /* This is a hack on top of the limit_scops hack. The + limit_scops hack should disappear all together. */ + if (single_succ_p (open_scop.exit) + && contains_only_close_phi_nodes (open_scop.exit)) + open_scop.exit = single_succ_edge (open_scop.exit)->dest; + + VEC_safe_push (sd_region, heap, regions, &open_scop); + } + } + + free_scops_1 (scops); + *scops = VEC_alloc (scop_p, heap, 3); + + create_sese_edges (regions); + build_graphite_scops (regions, scops); + VEC_free (sd_region, heap, regions); +} + +/* Transforms LOOP to the canonical loop closed SSA form. */ + +static void +canonicalize_loop_closed_ssa (loop_p loop) +{ + edge e = single_exit (loop); + basic_block bb; + + if (!e || e->flags & EDGE_ABNORMAL) + return; + + bb = e->dest; + + if (VEC_length (edge, bb->preds) == 1) + split_block_after_labels (bb); + else + { + gimple_stmt_iterator psi; + basic_block close = split_edge (e); + + e = single_succ_edge (close); + + for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi)) + { + gimple phi = gsi_stmt (psi); + unsigned i; + + for (i = 0; i < gimple_phi_num_args (phi); i++) + if (gimple_phi_arg_edge (phi, i) == e) + { + tree res, arg = gimple_phi_arg_def (phi, i); + use_operand_p use_p; + gimple close_phi; + + if (TREE_CODE (arg) != SSA_NAME) + continue; + + close_phi = create_phi_node (arg, close); + res = create_new_def_for (gimple_phi_result (close_phi), + close_phi, + gimple_phi_result_ptr (close_phi)); + add_phi_arg (close_phi, arg, + gimple_phi_arg_edge (close_phi, 0), + UNKNOWN_LOCATION); + use_p = gimple_phi_arg_imm_use_ptr (phi, i); + replace_exp (use_p, res); + update_stmt (phi); + } + } + } +} + +/* Converts the current loop closed SSA form to a canonical form + expected by the Graphite code generation. + + The loop closed SSA form has the following invariant: a variable + defined in a loop that is used outside the loop appears only in the + phi nodes in the destination of the loop exit. These phi nodes are + called close phi nodes. + + The canonical loop closed SSA form contains the extra invariants: + + - when the loop contains only one exit, the close phi nodes contain + only one argument. That implies that the basic block that contains + the close phi nodes has only one predecessor, that is a basic block + in the loop. + + - the basic block containing the close phi nodes does not contain + other statements. +*/ + +static void +canonicalize_loop_closed_ssa_form (void) +{ + loop_iterator li; + loop_p loop; + +#ifdef ENABLE_CHECKING + verify_loop_closed_ssa (); +#endif + + FOR_EACH_LOOP (li, loop, 0) + canonicalize_loop_closed_ssa (loop); + + rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); + update_ssa (TODO_update_ssa); + +#ifdef ENABLE_CHECKING + verify_loop_closed_ssa (); +#endif +} + +/* Find Static Control Parts (SCoP) in the current function and pushes + them to SCOPS. */ + +void +build_scops (VEC (scop_p, heap) **scops) +{ + struct loop *loop = current_loops->tree_root; + VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3); + + canonicalize_loop_closed_ssa_form (); + build_scops_1 (single_succ (ENTRY_BLOCK_PTR), ENTRY_BLOCK_PTR->loop_father, + ®ions, loop); + create_sese_edges (regions); + build_graphite_scops (regions, scops); + + if (dump_file && (dump_flags & TDF_DETAILS)) + print_graphite_statistics (dump_file, *scops); + + limit_scops (scops); + VEC_free (sd_region, heap, regions); + + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "\nnumber of SCoPs: %d\n", + VEC_length (scop_p, *scops)); +} + +/* Pretty print all SCoPs in DOT format and mark them with different colors. + If there are not enough colors, paint later SCoPs gray. + Special nodes: + - "*" after the node number: entry of a SCoP, + - "#" after the node number: exit of a SCoP, + - "()" entry or exit not part of SCoP. */ + +static void +dot_all_scops_1 (FILE *file, VEC (scop_p, heap) *scops) +{ + basic_block bb; + edge e; + edge_iterator ei; + scop_p scop; + const char* color; + int i; + + /* Disable debugging while printing graph. */ + int tmp_dump_flags = dump_flags; + dump_flags = 0; + + fprintf (file, "digraph all {\n"); + + FOR_ALL_BB (bb) + { + int part_of_scop = false; + + /* Use HTML for every bb label. So we are able to print bbs + which are part of two different SCoPs, with two different + background colors. */ + fprintf (file, "%d [label=<\n <TABLE BORDER=\"0\" CELLBORDER=\"1\" ", + bb->index); + fprintf (file, "CELLSPACING=\"0\">\n"); + + /* Select color for SCoP. */ + for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++) + { + sese region = SCOP_REGION (scop); + if (bb_in_sese_p (bb, region) + || (SESE_EXIT_BB (region) == bb) + || (SESE_ENTRY_BB (region) == bb)) + { + switch (i % 17) + { + case 0: /* red */ + color = "#e41a1c"; + break; + case 1: /* blue */ + color = "#377eb8"; + break; + case 2: /* green */ + color = "#4daf4a"; + break; + case 3: /* purple */ + color = "#984ea3"; + break; + case 4: /* orange */ + color = "#ff7f00"; + break; + case 5: /* yellow */ + color = "#ffff33"; + break; + case 6: /* brown */ + color = "#a65628"; + break; + case 7: /* rose */ + color = "#f781bf"; + break; + case 8: + color = "#8dd3c7"; + break; + case 9: + color = "#ffffb3"; + break; + case 10: + color = "#bebada"; + break; + case 11: + color = "#fb8072"; + break; + case 12: + color = "#80b1d3"; + break; + case 13: + color = "#fdb462"; + break; + case 14: + color = "#b3de69"; + break; + case 15: + color = "#fccde5"; + break; + case 16: + color = "#bc80bd"; + break; + default: /* gray */ + color = "#999999"; + } + + fprintf (file, " <TR><TD WIDTH=\"50\" BGCOLOR=\"%s\">", color); + + if (!bb_in_sese_p (bb, region)) + fprintf (file, " ("); + + if (bb == SESE_ENTRY_BB (region) + && bb == SESE_EXIT_BB (region)) + fprintf (file, " %d*# ", bb->index); + else if (bb == SESE_ENTRY_BB (region)) + fprintf (file, " %d* ", bb->index); + else if (bb == SESE_EXIT_BB (region)) + fprintf (file, " %d# ", bb->index); + else + fprintf (file, " %d ", bb->index); + + if (!bb_in_sese_p (bb,region)) + fprintf (file, ")"); + + fprintf (file, "</TD></TR>\n"); + part_of_scop = true; + } + } + + if (!part_of_scop) + { + fprintf (file, " <TR><TD WIDTH=\"50\" BGCOLOR=\"#ffffff\">"); + fprintf (file, " %d </TD></TR>\n", bb->index); + } + fprintf (file, " </TABLE>>, shape=box, style=\"setlinewidth(0)\"]\n"); + } + + FOR_ALL_BB (bb) + { + FOR_EACH_EDGE (e, ei, bb->succs) + fprintf (file, "%d -> %d;\n", bb->index, e->dest->index); + } + + fputs ("}\n\n", file); + + /* Enable debugging again. */ + dump_flags = tmp_dump_flags; +} + +/* Display all SCoPs using dotty. */ + +void +dot_all_scops (VEC (scop_p, heap) *scops) +{ + /* When debugging, enable the following code. This cannot be used + in production compilers because it calls "system". */ +#if 0 + int x; + FILE *stream = fopen ("/tmp/allscops.dot", "w"); + gcc_assert (stream); + + dot_all_scops_1 (stream, scops); + fclose (stream); + + x = system ("dotty /tmp/allscops.dot"); +#else + dot_all_scops_1 (stderr, scops); +#endif +} + +/* Display all SCoPs using dotty. */ + +void +dot_scop (scop_p scop) +{ + VEC (scop_p, heap) *scops = NULL; + + if (scop) + VEC_safe_push (scop_p, heap, scops, scop); + + /* When debugging, enable the following code. This cannot be used + in production compilers because it calls "system". */ +#if 0 + { + int x; + FILE *stream = fopen ("/tmp/allscops.dot", "w"); + gcc_assert (stream); + + dot_all_scops_1 (stream, scops); + fclose (stream); + x = system ("dotty /tmp/allscops.dot"); + } +#else + dot_all_scops_1 (stderr, scops); +#endif + + VEC_free (scop_p, heap, scops); +} + +#endif diff --git a/gcc/graphite-scop-detection.h b/gcc/graphite-scop-detection.h new file mode 100644 index 00000000000..740816d5ac4 --- /dev/null +++ b/gcc/graphite-scop-detection.h @@ -0,0 +1,27 @@ +/* Detection of Static Control Parts (SCoP) for Graphite. + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Sebastian Pop <sebastian.pop@amd.com> and + Tobias Grosser <grosser@fim.uni-passau.de>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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 build_scops (VEC (scop_p, heap) **); +extern void build_scop_bbs (scop_p); +extern int nb_reductions_in_loop (loop_p); +extern void dot_all_scops (VEC (scop_p, heap) *); +extern void dot_scop (scop_p); diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c new file mode 100644 index 00000000000..e20992e9282 --- /dev/null +++ b/gcc/graphite-sese-to-poly.c @@ -0,0 +1,2089 @@ +/* Conversion of SESE regions to Polyhedra. + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Sebastian Pop <sebastian.pop@amd.com>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "ggc.h" +#include "tree.h" +#include "rtl.h" +#include "basic-block.h" +#include "diagnostic.h" +#include "tree-flow.h" +#include "toplev.h" +#include "tree-dump.h" +#include "timevar.h" +#include "cfgloop.h" +#include "tree-chrec.h" +#include "tree-data-ref.h" +#include "tree-scalar-evolution.h" +#include "tree-pass.h" +#include "domwalk.h" +#include "value-prof.h" +#include "pointer-set.h" +#include "gimple.h" +#include "sese.h" + +#ifdef HAVE_cloog +#include "cloog/cloog.h" +#include "ppl_c.h" +#include "graphite-ppl.h" +#include "graphite.h" +#include "graphite-poly.h" +#include "graphite-scop-detection.h" +#include "graphite-clast-to-gimple.h" +#include "graphite-sese-to-poly.h" + +/* Check if VAR is used in a phi node, that is no loop header. */ + +static bool +var_used_in_not_loop_header_phi_node (tree var) +{ + + imm_use_iterator imm_iter; + gimple stmt; + bool result = false; + + FOR_EACH_IMM_USE_STMT (stmt, imm_iter, var) + { + basic_block bb = gimple_bb (stmt); + + if (gimple_code (stmt) == GIMPLE_PHI + && bb->loop_father->header != bb) + result = true; + } + + return result; +} + +/* Returns the index of the phi argument corresponding to the initial + value in the loop. */ + +static size_t +loop_entry_phi_arg (gimple phi) +{ + loop_p loop = gimple_bb (phi)->loop_father; + size_t i; + + for (i = 0; i < gimple_phi_num_args (phi); i++) + if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src)) + return i; + + gcc_unreachable (); + return 0; +} + +/* Removes a simple copy phi node "RES = phi (INIT, RES)" at position + PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */ + +static void +remove_simple_copy_phi (gimple_stmt_iterator *psi) +{ + gimple phi = gsi_stmt (*psi); + tree res = gimple_phi_result (phi); + size_t entry = loop_entry_phi_arg (phi); + tree init = gimple_phi_arg_def (phi, entry); + gimple stmt = gimple_build_assign (res, init); + edge e = gimple_phi_arg_edge (phi, entry); + + remove_phi_node (psi, false); + gsi_insert_on_edge_immediate (e, stmt); + SSA_NAME_DEF_STMT (res) = stmt; +} + +/* Removes an invariant phi node at position PSI by inserting on the + loop ENTRY edge the assignment RES = INIT. */ + +static void +remove_invariant_phi (sese region, gimple_stmt_iterator *psi) +{ + gimple phi = gsi_stmt (*psi); + loop_p loop = loop_containing_stmt (phi); + tree res = gimple_phi_result (phi); + tree scev = scalar_evolution_in_region (region, loop, res); + size_t entry = loop_entry_phi_arg (phi); + edge e = gimple_phi_arg_edge (phi, entry); + tree var; + gimple stmt; + gimple_seq stmts; + gimple_stmt_iterator gsi; + + if (tree_contains_chrecs (scev, NULL)) + scev = gimple_phi_arg_def (phi, entry); + + var = force_gimple_operand (scev, &stmts, true, NULL_TREE); + stmt = gimple_build_assign (res, var); + remove_phi_node (psi, false); + + if (!stmts) + stmts = gimple_seq_alloc (); + + gsi = gsi_last (stmts); + gsi_insert_after (&gsi, stmt, GSI_NEW_STMT); + gsi_insert_seq_on_edge (e, stmts); + gsi_commit_edge_inserts (); + SSA_NAME_DEF_STMT (res) = stmt; +} + +/* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */ + +static inline bool +simple_copy_phi_p (gimple phi) +{ + tree res; + + if (gimple_phi_num_args (phi) != 2) + return false; + + res = gimple_phi_result (phi); + return (res == gimple_phi_arg_def (phi, 0) + || res == gimple_phi_arg_def (phi, 1)); +} + +/* Returns true when the phi node at position PSI is a reduction phi + node in REGION. Otherwise moves the pointer PSI to the next phi to + be considered. */ + +static bool +reduction_phi_p (sese region, gimple_stmt_iterator *psi) +{ + loop_p loop; + tree scev; + affine_iv iv; + gimple phi = gsi_stmt (*psi); + tree res = gimple_phi_result (phi); + + if (!is_gimple_reg (res)) + { + gsi_next (psi); + return false; + } + + loop = loop_containing_stmt (phi); + + if (simple_copy_phi_p (phi)) + { + /* FIXME: PRE introduces phi nodes like these, for an example, + see id-5.f in the fortran graphite testsuite: + + # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)> + */ + remove_simple_copy_phi (psi); + return false; + } + + /* Main induction variables with constant strides in LOOP are not + reductions. */ + if (simple_iv (loop, loop, res, &iv, true)) + { + gsi_next (psi); + return false; + } + + scev = scalar_evolution_in_region (region, loop, res); + if (chrec_contains_undetermined (scev)) + return true; + + if (evolution_function_is_invariant_p (scev, loop->num)) + { + remove_invariant_phi (region, psi); + return false; + } + + /* All the other cases are considered reductions. */ + return true; +} + +/* Returns true when BB will be represented in graphite. Return false + for the basic blocks that contain code eliminated in the code + generation pass: i.e. induction variables and exit conditions. */ + +static bool +graphite_stmt_p (sese region, basic_block bb, + VEC (data_reference_p, heap) *drs) +{ + gimple_stmt_iterator gsi; + loop_p loop = bb->loop_father; + + if (VEC_length (data_reference_p, drs) > 0) + return true; + + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple stmt = gsi_stmt (gsi); + + switch (gimple_code (stmt)) + { + /* Control flow expressions can be ignored, as they are + represented in the iteration domains and will be + regenerated by graphite. */ + case GIMPLE_COND: + case GIMPLE_GOTO: + case GIMPLE_SWITCH: + break; + + case GIMPLE_ASSIGN: + { + tree var = gimple_assign_lhs (stmt); + + /* We need these bbs to be able to construct the phi nodes. */ + if (var_used_in_not_loop_header_phi_node (var)) + return true; + + var = scalar_evolution_in_region (region, loop, var); + if (chrec_contains_undetermined (var)) + return true; + + break; + } + + default: + return true; + } + } + + return false; +} + +/* Store the GRAPHITE representation of BB. */ + +static gimple_bb_p +new_gimple_bb (basic_block bb, VEC (data_reference_p, heap) *drs) +{ + struct gimple_bb *gbb; + + gbb = XNEW (struct gimple_bb); + bb->aux = gbb; + GBB_BB (gbb) = bb; + GBB_DATA_REFS (gbb) = drs; + GBB_CONDITIONS (gbb) = NULL; + GBB_CONDITION_CASES (gbb) = NULL; + GBB_CLOOG_IV_TYPES (gbb) = NULL; + + return gbb; +} + +/* Frees GBB. */ + +static void +free_gimple_bb (struct gimple_bb *gbb) +{ + if (GBB_CLOOG_IV_TYPES (gbb)) + htab_delete (GBB_CLOOG_IV_TYPES (gbb)); + + free_data_refs (GBB_DATA_REFS (gbb)); + + VEC_free (gimple, heap, GBB_CONDITIONS (gbb)); + VEC_free (gimple, heap, GBB_CONDITION_CASES (gbb)); + GBB_BB (gbb)->aux = 0; + XDELETE (gbb); +} + +/* Deletes all gimple bbs in SCOP. */ + +static void +remove_gbbs_in_scop (scop_p scop) +{ + int i; + poly_bb_p pbb; + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + free_gimple_bb (PBB_BLACK_BOX (pbb)); +} + +/* Deletes all scops in SCOPS. */ + +void +free_scops (VEC (scop_p, heap) *scops) +{ + int i; + scop_p scop; + + for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++) + { + remove_gbbs_in_scop (scop); + free_sese (SCOP_REGION (scop)); + free_scop (scop); + } + + VEC_free (scop_p, heap, scops); +} + +/* Generates a polyhedral black box only if the bb contains interesting + information. */ + +static void +try_generate_gimple_bb (scop_p scop, basic_block bb) +{ + VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5); + loop_p nest = outermost_loop_in_sese (SCOP_REGION (scop), bb); + gimple_stmt_iterator gsi; + + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + graphite_find_data_references_in_stmt (nest, gsi_stmt (gsi), &drs); + + if (!graphite_stmt_p (SCOP_REGION (scop), bb, drs)) + free_data_refs (drs); + else + new_poly_bb (scop, new_gimple_bb (bb, drs)); +} + +/* Returns true if all predecessors of BB, that are not dominated by BB, are + marked in MAP. The predecessors dominated by BB are loop latches and will + be handled after BB. */ + +static bool +all_non_dominated_preds_marked_p (basic_block bb, sbitmap map) +{ + edge e; + edge_iterator ei; + + FOR_EACH_EDGE (e, ei, bb->preds) + if (!TEST_BIT (map, e->src->index) + && !dominated_by_p (CDI_DOMINATORS, e->src, bb)) + return false; + + return true; +} + +/* Compare the depth of two basic_block's P1 and P2. */ + +static int +compare_bb_depths (const void *p1, const void *p2) +{ + const_basic_block const bb1 = *(const_basic_block const*)p1; + const_basic_block const bb2 = *(const_basic_block const*)p2; + int d1 = loop_depth (bb1->loop_father); + int d2 = loop_depth (bb2->loop_father); + + if (d1 < d2) + return 1; + + if (d1 > d2) + return -1; + + return 0; +} + +/* Sort the basic blocks from DOM such that the first are the ones at + a deepest loop level. */ + +static void +graphite_sort_dominated_info (VEC (basic_block, heap) *dom) +{ + size_t len = VEC_length (basic_block, dom); + + qsort (VEC_address (basic_block, dom), len, sizeof (basic_block), + compare_bb_depths); +} + +/* Recursive helper function for build_scops_bbs. */ + +static void +build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb) +{ + sese region = SCOP_REGION (scop); + VEC (basic_block, heap) *dom; + + if (TEST_BIT (visited, bb->index) + || !bb_in_sese_p (bb, region)) + return; + + try_generate_gimple_bb (scop, bb); + SET_BIT (visited, bb->index); + + dom = get_dominated_by (CDI_DOMINATORS, bb); + + if (dom == NULL) + return; + + graphite_sort_dominated_info (dom); + + while (!VEC_empty (basic_block, dom)) + { + int i; + basic_block dom_bb; + + for (i = 0; VEC_iterate (basic_block, dom, i, dom_bb); i++) + if (all_non_dominated_preds_marked_p (dom_bb, visited)) + { + build_scop_bbs_1 (scop, visited, dom_bb); + VEC_unordered_remove (basic_block, dom, i); + break; + } + } + + VEC_free (basic_block, heap, dom); +} + +/* Gather the basic blocks belonging to the SCOP. */ + +void +build_scop_bbs (scop_p scop) +{ + sbitmap visited = sbitmap_alloc (last_basic_block); + sese region = SCOP_REGION (scop); + + sbitmap_zero (visited); + build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region)); + + sbitmap_free (visited); +} + +/* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron. + We generate SCATTERING_DIMENSIONS scattering dimensions. + + CLooG 0.15.0 and previous versions require, that all + scattering functions of one CloogProgram have the same number of + scattering dimensions, therefore we allow to specify it. This + should be removed in future versions of CLooG. + + The scattering polyhedron consists of these dimensions: scattering, + loop_iterators, parameters. + + Example: + + | scattering_dimensions = 5 + | used_scattering_dimensions = 3 + | nb_iterators = 1 + | scop_nb_params = 2 + | + | Schedule: + | i + | 4 5 + | + | Scattering polyhedron: + | + | scattering: {s1, s2, s3, s4, s5} + | loop_iterators: {i} + | parameters: {p1, p2} + | + | s1 s2 s3 s4 s5 i p1 p2 1 + | 1 0 0 0 0 0 0 0 -4 = 0 + | 0 1 0 0 0 -1 0 0 0 = 0 + | 0 0 1 0 0 0 0 0 -5 = 0 */ + +static void +build_pbb_scattering_polyhedrons (ppl_Linear_Expression_t static_schedule, + poly_bb_p pbb, int scattering_dimensions) +{ + int i; + scop_p scop = PBB_SCOP (pbb); + int nb_iterators = pbb_dim_iter_domain (pbb); + int used_scattering_dimensions = nb_iterators * 2 + 1; + int nb_params = scop_nb_params (scop); + ppl_Coefficient_t c; + ppl_dimension_type dim = scattering_dimensions + nb_iterators + nb_params; + Value v; + + gcc_assert (scattering_dimensions >= used_scattering_dimensions); + + value_init (v); + ppl_new_Coefficient (&c); + ppl_new_C_Polyhedron_from_space_dimension + (&PBB_TRANSFORMED_SCATTERING (pbb), dim, 0); + + PBB_NB_SCATTERING_TRANSFORM (pbb) = scattering_dimensions; + + for (i = 0; i < scattering_dimensions; i++) + { + ppl_Constraint_t cstr; + ppl_Linear_Expression_t expr; + + ppl_new_Linear_Expression_with_dimension (&expr, dim); + value_set_si (v, 1); + ppl_assign_Coefficient_from_mpz_t (c, v); + ppl_Linear_Expression_add_to_coefficient (expr, i, c); + + /* Textual order inside this loop. */ + if ((i % 2) == 0) + { + ppl_Linear_Expression_coefficient (static_schedule, i / 2, c); + ppl_Coefficient_to_mpz_t (c, v); + value_oppose (v, v); + ppl_assign_Coefficient_from_mpz_t (c, v); + ppl_Linear_Expression_add_to_inhomogeneous (expr, c); + } + + /* Iterations of this loop. */ + else /* if ((i % 2) == 1) */ + { + int loop = (i - 1) / 2; + + value_set_si (v, -1); + ppl_assign_Coefficient_from_mpz_t (c, v); + ppl_Linear_Expression_add_to_coefficient + (expr, scattering_dimensions + loop, c); + } + + ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL); + ppl_Polyhedron_add_constraint (PBB_TRANSFORMED_SCATTERING (pbb), cstr); + ppl_delete_Linear_Expression (expr); + ppl_delete_Constraint (cstr); + } + + value_clear (v); + ppl_delete_Coefficient (c); + + ppl_new_C_Polyhedron_from_C_Polyhedron (&PBB_ORIGINAL_SCATTERING (pbb), + PBB_TRANSFORMED_SCATTERING (pbb)); +} + +/* Build for BB the static schedule. + + The static schedule is a Dewey numbering of the abstract syntax + tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification + + The following example informally defines the static schedule: + + A + for (i: ...) + { + for (j: ...) + { + B + C + } + + for (k: ...) + { + D + E + } + } + F + + Static schedules for A to F: + + DEPTH + 0 1 2 + A 0 + B 1 0 0 + C 1 0 1 + D 1 1 0 + E 1 1 1 + F 2 +*/ + +static void +build_scop_scattering (scop_p scop) +{ + int i; + poly_bb_p pbb; + gimple_bb_p previous_gbb = NULL; + ppl_Linear_Expression_t static_schedule; + ppl_Coefficient_t c; + Value v; + + value_init (v); + ppl_new_Coefficient (&c); + ppl_new_Linear_Expression (&static_schedule); + + /* We have to start schedules at 0 on the first component and + because we cannot compare_prefix_loops against a previous loop, + prefix will be equal to zero, and that index will be + incremented before copying. */ + value_set_si (v, -1); + ppl_assign_Coefficient_from_mpz_t (c, v); + ppl_Linear_Expression_add_to_coefficient (static_schedule, 0, c); + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + { + gimple_bb_p gbb = PBB_BLACK_BOX (pbb); + ppl_Linear_Expression_t common; + int prefix; + int nb_scat_dims = pbb_dim_iter_domain (pbb) * 2 + 1; + + if (previous_gbb) + prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb); + else + prefix = 0; + + previous_gbb = gbb; + ppl_new_Linear_Expression_with_dimension (&common, prefix + 1); + ppl_assign_Linear_Expression_from_Linear_Expression (common, + static_schedule); + + value_set_si (v, 1); + ppl_assign_Coefficient_from_mpz_t (c, v); + ppl_Linear_Expression_add_to_coefficient (common, prefix, c); + ppl_assign_Linear_Expression_from_Linear_Expression (static_schedule, + common); + + build_pbb_scattering_polyhedrons (common, pbb, nb_scat_dims); + + ppl_delete_Linear_Expression (common); + } + + value_clear (v); + ppl_delete_Coefficient (c); + ppl_delete_Linear_Expression (static_schedule); +} + +/* Add the value K to the dimension D of the linear expression EXPR. */ + +static void +add_value_to_dim (ppl_dimension_type d, ppl_Linear_Expression_t expr, + Value k) +{ + Value val; + ppl_Coefficient_t coef; + + ppl_new_Coefficient (&coef); + ppl_Linear_Expression_coefficient (expr, d, coef); + value_init (val); + ppl_Coefficient_to_mpz_t (coef, val); + + value_addto (val, val, k); + + ppl_assign_Coefficient_from_mpz_t (coef, val); + ppl_Linear_Expression_add_to_coefficient (expr, d, coef); + value_clear (val); + ppl_delete_Coefficient (coef); +} + +/* In the context of scop S, scan E, the right hand side of a scalar + evolution function in loop VAR, and translate it to a linear + expression EXPR. */ + +static void +scan_tree_for_params_right_scev (sese s, tree e, int var, + ppl_Linear_Expression_t expr) +{ + if (expr) + { + loop_p loop = get_loop (var); + ppl_dimension_type l = sese_loop_depth (s, loop) - 1; + Value val; + + /* Scalar evolutions should happen in the sese region. */ + gcc_assert (sese_loop_depth (s, loop) > 0); + + /* We can not deal with parametric strides like: + + | p = parameter; + | + | for i: + | a [i * p] = ... */ + gcc_assert (TREE_CODE (e) == INTEGER_CST); + + value_init (val); + value_set_si (val, int_cst_value (e)); + add_value_to_dim (l, expr, val); + value_clear (val); + } +} + +/* Scan the integer constant CST, and add it to the inhomogeneous part of the + linear expression EXPR. K is the multiplier of the constant. */ + +static void +scan_tree_for_params_int (tree cst, ppl_Linear_Expression_t expr, Value k) +{ + Value val; + ppl_Coefficient_t coef; + int v = int_cst_value (cst); + + value_init (val); + value_set_si (val, 0); + + /* Necessary to not get "-1 = 2^n - 1". */ + if (v < 0) + value_sub_int (val, val, -v); + else + value_add_int (val, val, v); + + value_multiply (val, val, k); + ppl_new_Coefficient (&coef); + ppl_assign_Coefficient_from_mpz_t (coef, val); + ppl_Linear_Expression_add_to_inhomogeneous (expr, coef); + value_clear (val); + ppl_delete_Coefficient (coef); +} + +/* Saves in NV at index I a new name for variable P. */ + +static void +save_var_name (char **nv, int i, tree p) +{ + const char *name = get_name (SSA_NAME_VAR (p)); + + if (name) + { + int len = strlen (name) + 16; + nv[i] = XNEWVEC (char, len); + snprintf (nv[i], len, "%s_%d", name, SSA_NAME_VERSION (p)); + } + else + { + nv[i] = XNEWVEC (char, 16); + snprintf (nv[i], 2 + 16, "T_%d", SSA_NAME_VERSION (p)); + } +} + +/* When parameter NAME is in REGION, returns its index in SESE_PARAMS. + Otherwise returns -1. */ + +static inline int +parameter_index_in_region_1 (tree name, sese region) +{ + int i; + tree p; + + gcc_assert (TREE_CODE (name) == SSA_NAME); + + for (i = 0; VEC_iterate (tree, SESE_PARAMS (region), i, p); i++) + if (p == name) + return i; + + return -1; +} + +/* When the parameter NAME is in REGION, returns its index in + SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS + and returns the index of NAME. */ + +static int +parameter_index_in_region (tree name, sese region) +{ + int i; + + gcc_assert (TREE_CODE (name) == SSA_NAME); + + i = parameter_index_in_region_1 (name, region); + if (i != -1) + return i; + + gcc_assert (SESE_ADD_PARAMS (region)); + + i = VEC_length (tree, SESE_PARAMS (region)); + save_var_name (SESE_PARAMS_NAMES (region), i, name); + save_clast_name_index (SESE_PARAMS_INDEX (region), + SESE_PARAMS_NAMES (region)[i], i); + VEC_safe_push (tree, heap, SESE_PARAMS (region), name); + return i; +} + +/* In the context of sese S, scan the expression E and translate it to + a linear expression C. When parsing a symbolic multiplication, K + represents the constant multiplier of an expression containing + parameters. */ + +static void +scan_tree_for_params (sese s, tree e, ppl_Linear_Expression_t c, + Value k) +{ + if (e == chrec_dont_know) + return; + + switch (TREE_CODE (e)) + { + case POLYNOMIAL_CHREC: + scan_tree_for_params_right_scev (s, CHREC_RIGHT (e), + CHREC_VARIABLE (e), c); + scan_tree_for_params (s, CHREC_LEFT (e), c, k); + break; + + case MULT_EXPR: + if (chrec_contains_symbols (TREE_OPERAND (e, 0))) + { + if (c) + { + Value val; + gcc_assert (host_integerp (TREE_OPERAND (e, 1), 0)); + value_init (val); + value_set_si (val, int_cst_value (TREE_OPERAND (e, 1))); + value_multiply (val, val, k); + scan_tree_for_params (s, TREE_OPERAND (e, 0), c, val); + value_clear (val); + } + else + scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k); + } + else + { + if (c) + { + Value val; + gcc_assert (host_integerp (TREE_OPERAND (e, 0), 0)); + value_init (val); + value_set_si (val, int_cst_value (TREE_OPERAND (e, 0))); + value_multiply (val, val, k); + scan_tree_for_params (s, TREE_OPERAND (e, 1), c, val); + value_clear (val); + } + else + scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k); + } + break; + + case PLUS_EXPR: + case POINTER_PLUS_EXPR: + scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k); + scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k); + break; + + case MINUS_EXPR: + { + ppl_Linear_Expression_t tmp_expr = NULL; + + if (c) + { + ppl_dimension_type dim; + ppl_Linear_Expression_space_dimension (c, &dim); + ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim); + } + + scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k); + scan_tree_for_params (s, TREE_OPERAND (e, 1), tmp_expr, k); + + if (c) + { + ppl_subtract_Linear_Expression_from_Linear_Expression (c, + tmp_expr); + ppl_delete_Linear_Expression (tmp_expr); + } + + break; + } + + case NEGATE_EXPR: + { + ppl_Linear_Expression_t tmp_expr = NULL; + + if (c) + { + ppl_dimension_type dim; + ppl_Linear_Expression_space_dimension (c, &dim); + ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim); + } + + scan_tree_for_params (s, TREE_OPERAND (e, 0), tmp_expr, k); + + if (c) + { + ppl_subtract_Linear_Expression_from_Linear_Expression (c, + tmp_expr); + ppl_delete_Linear_Expression (tmp_expr); + } + + break; + } + + case BIT_NOT_EXPR: + { + ppl_Linear_Expression_t tmp_expr = NULL; + + if (c) + { + ppl_dimension_type dim; + ppl_Linear_Expression_space_dimension (c, &dim); + ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim); + } + + scan_tree_for_params (s, TREE_OPERAND (e, 0), tmp_expr, k); + + if (c) + { + ppl_Coefficient_t coef; + Value minus_one; + + ppl_subtract_Linear_Expression_from_Linear_Expression (c, + tmp_expr); + ppl_delete_Linear_Expression (tmp_expr); + value_init (minus_one); + value_set_si (minus_one, -1); + ppl_new_Coefficient_from_mpz_t (&coef, minus_one); + ppl_Linear_Expression_add_to_inhomogeneous (c, coef); + value_clear (minus_one); + ppl_delete_Coefficient (coef); + } + + break; + } + + case SSA_NAME: + { + ppl_dimension_type p = parameter_index_in_region (e, s); + + if (c) + { + ppl_dimension_type dim; + ppl_Linear_Expression_space_dimension (c, &dim); + p += dim - sese_nb_params (s); + add_value_to_dim (p, c, k); + } + break; + } + + case INTEGER_CST: + if (c) + scan_tree_for_params_int (e, c, k); + break; + + CASE_CONVERT: + case NON_LVALUE_EXPR: + scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k); + break; + + default: + gcc_unreachable (); + break; + } +} + +/* Data structure for idx_record_params. */ + +struct irp_data +{ + struct loop *loop; + sese region; +}; + +/* For a data reference with an ARRAY_REF as its BASE, record the + parameters occurring in IDX. DTA is passed in as complementary + information, and is used by the automatic walker function. This + function is a callback for for_each_index. */ + +static bool +idx_record_params (tree base, tree *idx, void *dta) +{ + struct irp_data *data = (struct irp_data *) dta; + + if (TREE_CODE (base) != ARRAY_REF) + return true; + + if (TREE_CODE (*idx) == SSA_NAME) + { + tree scev; + sese region = data->region; + struct loop *loop = data->loop; + Value one; + + scev = scalar_evolution_in_region (region, loop, *idx); + + value_init (one); + value_set_si (one, 1); + scan_tree_for_params (region, scev, NULL, one); + value_clear (one); + } + + return true; +} + +/* Find parameters with respect to REGION in BB. We are looking in memory + access functions, conditions and loop bounds. */ + +static void +find_params_in_bb (sese region, gimple_bb_p gbb) +{ + int i; + data_reference_p dr; + gimple stmt; + loop_p loop = GBB_BB (gbb)->loop_father; + + for (i = 0; VEC_iterate (data_reference_p, GBB_DATA_REFS (gbb), i, dr); i++) + { + struct irp_data irp; + + irp.loop = loop; + irp.region = region; + for_each_index (&dr->ref, idx_record_params, &irp); + } + + /* Find parameters in conditional statements. */ + for (i = 0; VEC_iterate (gimple, GBB_CONDITIONS (gbb), i, stmt); i++) + { + Value one; + tree lhs = scalar_evolution_in_region (region, loop, + gimple_cond_lhs (stmt)); + tree rhs = scalar_evolution_in_region (region, loop, + gimple_cond_rhs (stmt)); + + value_init (one); + value_set_si (one, 1); + scan_tree_for_params (region, lhs, NULL, one); + scan_tree_for_params (region, rhs, NULL, one); + value_clear (one); + } +} + +/* Record the parameters used in the SCOP. A variable is a parameter + in a scop if it does not vary during the execution of that scop. */ + +static void +find_scop_parameters (scop_p scop) +{ + poly_bb_p pbb; + unsigned i; + sese region = SCOP_REGION (scop); + struct loop *loop; + Value one; + + value_init (one); + value_set_si (one, 1); + + /* Find the parameters used in the loop bounds. */ + for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++) + { + tree nb_iters = number_of_latch_executions (loop); + + if (!chrec_contains_symbols (nb_iters)) + continue; + + nb_iters = scalar_evolution_in_region (region, loop, nb_iters); + scan_tree_for_params (region, nb_iters, NULL, one); + } + + value_clear (one); + + /* Find the parameters used in data accesses. */ + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + find_params_in_bb (region, PBB_BLACK_BOX (pbb)); + + scop_set_nb_params (scop, sese_nb_params (region)); + SESE_ADD_PARAMS (region) = false; +} + +/* Returns a gimple_bb from BB. */ + +static inline gimple_bb_p +gbb_from_bb (basic_block bb) +{ + return (gimple_bb_p) bb->aux; +} + +/* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives + the constraints for the surrounding loops. */ + +static void +build_loop_iteration_domains (scop_p scop, struct loop *loop, + ppl_Polyhedron_t outer_ph, int nb) + +{ + int i; + ppl_Polyhedron_t ph; + tree nb_iters = number_of_latch_executions (loop); + ppl_dimension_type dim = nb + 1 + scop_nb_params (scop); + sese region = SCOP_REGION (scop); + + { + ppl_const_Constraint_System_t pcs; + ppl_dimension_type *map + = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, dim); + + ppl_new_C_Polyhedron_from_space_dimension (&ph, dim, 0); + ppl_Polyhedron_get_constraints (outer_ph, &pcs); + ppl_Polyhedron_add_constraints (ph, pcs); + + for (i = 0; i < (int) nb; i++) + map[i] = i; + for (i = (int) nb; i < (int) dim - 1; i++) + map[i] = i + 1; + map[dim - 1] = nb; + + ppl_Polyhedron_map_space_dimensions (ph, map, dim); + free (map); + } + + /* 0 <= loop_i */ + { + ppl_Constraint_t lb; + ppl_Linear_Expression_t lb_expr; + + ppl_new_Linear_Expression_with_dimension (&lb_expr, dim); + ppl_set_coef (lb_expr, nb, 1); + ppl_new_Constraint (&lb, lb_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL); + ppl_delete_Linear_Expression (lb_expr); + ppl_Polyhedron_add_constraint (ph, lb); + ppl_delete_Constraint (lb); + } + + if (TREE_CODE (nb_iters) == INTEGER_CST) + { + ppl_Constraint_t ub; + ppl_Linear_Expression_t ub_expr; + + ppl_new_Linear_Expression_with_dimension (&ub_expr, dim); + + /* loop_i <= cst_nb_iters */ + ppl_set_coef (ub_expr, nb, -1); + ppl_set_inhomogeneous_tree (ub_expr, nb_iters); + ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL); + ppl_Polyhedron_add_constraint (ph, ub); + ppl_delete_Linear_Expression (ub_expr); + ppl_delete_Constraint (ub); + } + else if (!chrec_contains_undetermined (nb_iters)) + { + Value one; + ppl_Constraint_t ub; + ppl_Linear_Expression_t ub_expr; + + value_init (one); + value_set_si (one, 1); + ppl_new_Linear_Expression_with_dimension (&ub_expr, dim); + nb_iters = scalar_evolution_in_region (region, loop, nb_iters); + scan_tree_for_params (SCOP_REGION (scop), nb_iters, ub_expr, one); + value_clear (one); + + /* loop_i <= expr_nb_iters */ + ppl_set_coef (ub_expr, nb, -1); + ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL); + ppl_Polyhedron_add_constraint (ph, ub); + ppl_delete_Linear_Expression (ub_expr); + ppl_delete_Constraint (ub); + } + else + gcc_unreachable (); + + if (loop->inner && loop_in_sese_p (loop->inner, region)) + build_loop_iteration_domains (scop, loop->inner, ph, nb + 1); + + if (nb != 0 + && loop->next + && loop_in_sese_p (loop->next, region)) + build_loop_iteration_domains (scop, loop->next, outer_ph, nb); + + ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron + ((ppl_Pointset_Powerset_C_Polyhedron_t *) &loop->aux, ph); + + ppl_delete_Polyhedron (ph); +} + +/* Returns a linear expression for tree T evaluated in PBB. */ + +static ppl_Linear_Expression_t +create_linear_expr_from_tree (poly_bb_p pbb, tree t) +{ + Value one; + ppl_Linear_Expression_t res; + ppl_dimension_type dim; + sese region = SCOP_REGION (PBB_SCOP (pbb)); + loop_p loop = GBB_BB (PBB_BLACK_BOX (pbb))->loop_father; + + dim = pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb); + ppl_new_Linear_Expression_with_dimension (&res, dim); + + t = scalar_evolution_in_region (region, loop, t); + gcc_assert (!automatically_generated_chrec_p (t)); + + value_init (one); + value_set_si (one, 1); + scan_tree_for_params (region, t, res, one); + value_clear (one); + + return res; +} + +/* Returns the ppl constraint type from the gimple tree code CODE. */ + +static enum ppl_enum_Constraint_Type +ppl_constraint_type_from_tree_code (enum tree_code code) +{ + switch (code) + { + /* We do not support LT and GT to be able to work with C_Polyhedron. + As we work on integer polyhedron "a < b" can be expressed by + "a + 1 <= b". */ + case LT_EXPR: + case GT_EXPR: + gcc_unreachable (); + + case LE_EXPR: + return PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL; + + case GE_EXPR: + return PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL; + + case EQ_EXPR: + return PPL_CONSTRAINT_TYPE_EQUAL; + + default: + gcc_unreachable (); + } +} + +/* Add conditional statement STMT to PS. It is evaluated in PBB and + CODE is used as the comparison operator. This allows us to invert the + condition or to handle inequalities. */ + +static void +add_condition_to_domain (ppl_Pointset_Powerset_C_Polyhedron_t ps, gimple stmt, + poly_bb_p pbb, enum tree_code code) +{ + Value v; + ppl_Coefficient_t c; + ppl_Linear_Expression_t left, right; + ppl_Constraint_t cstr; + enum ppl_enum_Constraint_Type type; + + left = create_linear_expr_from_tree (pbb, gimple_cond_lhs (stmt)); + right = create_linear_expr_from_tree (pbb, gimple_cond_rhs (stmt)); + + /* If we have < or > expressions convert them to <= or >= by adding 1 to + the left or the right side of the expression. */ + if (code == LT_EXPR) + { + value_init (v); + value_set_si (v, 1); + ppl_new_Coefficient (&c); + ppl_assign_Coefficient_from_mpz_t (c, v); + ppl_Linear_Expression_add_to_inhomogeneous (left, c); + ppl_delete_Coefficient (c); + value_clear (v); + + code = LE_EXPR; + } + else if (code == GT_EXPR) + { + value_init (v); + value_set_si (v, 1); + ppl_new_Coefficient (&c); + ppl_assign_Coefficient_from_mpz_t (c, v); + ppl_Linear_Expression_add_to_inhomogeneous (right, c); + ppl_delete_Coefficient (c); + value_clear (v); + + code = GE_EXPR; + } + + type = ppl_constraint_type_from_tree_code (code); + + ppl_subtract_Linear_Expression_from_Linear_Expression (left, right); + + ppl_new_Constraint (&cstr, left, type); + ppl_Pointset_Powerset_C_Polyhedron_add_constraint (ps, cstr); + + ppl_delete_Constraint (cstr); + ppl_delete_Linear_Expression (left); + ppl_delete_Linear_Expression (right); +} + +/* Add conditional statement STMT to pbb. CODE is used as the comparision + operator. This allows us to invert the condition or to handle + inequalities. */ + +static void +add_condition_to_pbb (poly_bb_p pbb, gimple stmt, enum tree_code code) +{ + if (code == NE_EXPR) + { + ppl_Pointset_Powerset_C_Polyhedron_t left = PBB_DOMAIN (pbb); + ppl_Pointset_Powerset_C_Polyhedron_t right; + ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron + (&right, left); + add_condition_to_domain (left, stmt, pbb, LT_EXPR); + add_condition_to_domain (right, stmt, pbb, GT_EXPR); + ppl_Pointset_Powerset_C_Polyhedron_upper_bound_assign (left, + right); + ppl_delete_Pointset_Powerset_C_Polyhedron (right); + } + else + add_condition_to_domain (PBB_DOMAIN (pbb), stmt, pbb, code); +} + +/* Add conditions to the domain of PBB. */ + +static void +add_conditions_to_domain (poly_bb_p pbb) +{ + unsigned int i; + gimple stmt; + gimple_bb_p gbb = PBB_BLACK_BOX (pbb); + VEC (gimple, heap) *conditions = GBB_CONDITIONS (gbb); + + if (VEC_empty (gimple, conditions)) + return; + + for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++) + switch (gimple_code (stmt)) + { + case GIMPLE_COND: + { + enum tree_code code = gimple_cond_code (stmt); + + /* The conditions for ELSE-branches are inverted. */ + if (VEC_index (gimple, gbb->condition_cases, i) == NULL) + code = invert_tree_comparison (code, false); + + add_condition_to_pbb (pbb, stmt, code); + break; + } + + case GIMPLE_SWITCH: + /* Switch statements are not supported right now - fall throught. */ + + default: + gcc_unreachable (); + break; + } +} + +/* Structure used to pass data to dom_walk. */ + +struct bsc +{ + VEC (gimple, heap) **conditions, **cases; + sese region; +}; + +/* Returns non NULL when BB has a single predecessor and the last + statement of that predecessor is a COND_EXPR. */ + +static gimple +single_pred_cond (basic_block bb) +{ + if (single_pred_p (bb)) + { + edge e = single_pred_edge (bb); + basic_block pred = e->src; + gimple stmt = last_stmt (pred); + + if (stmt && gimple_code (stmt) == GIMPLE_COND) + return stmt; + } + return NULL; +} + +/* Call-back for dom_walk executed before visiting the dominated + blocks. */ + +static void +build_sese_conditions_before (struct dom_walk_data *dw_data, + basic_block bb) +{ + struct bsc *data = (struct bsc *) dw_data->global_data; + VEC (gimple, heap) **conditions = data->conditions; + VEC (gimple, heap) **cases = data->cases; + gimple_bb_p gbb = gbb_from_bb (bb); + gimple stmt = single_pred_cond (bb); + + if (!bb_in_sese_p (bb, data->region)) + return; + + if (stmt) + { + edge e = single_pred_edge (bb); + + VEC_safe_push (gimple, heap, *conditions, stmt); + + if (e->flags & EDGE_TRUE_VALUE) + VEC_safe_push (gimple, heap, *cases, stmt); + else + VEC_safe_push (gimple, heap, *cases, NULL); + } + + if (gbb) + { + GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions); + GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases); + } +} + +/* Call-back for dom_walk executed after visiting the dominated + blocks. */ + +static void +build_sese_conditions_after (struct dom_walk_data *dw_data, + basic_block bb) +{ + struct bsc *data = (struct bsc *) dw_data->global_data; + VEC (gimple, heap) **conditions = data->conditions; + VEC (gimple, heap) **cases = data->cases; + + if (!bb_in_sese_p (bb, data->region)) + return; + + if (single_pred_cond (bb)) + { + VEC_pop (gimple, *conditions); + VEC_pop (gimple, *cases); + } +} + +/* Record all conditions in REGION. */ + +static void +build_sese_conditions (sese region) +{ + struct dom_walk_data walk_data; + VEC (gimple, heap) *conditions = VEC_alloc (gimple, heap, 3); + VEC (gimple, heap) *cases = VEC_alloc (gimple, heap, 3); + struct bsc data; + + data.conditions = &conditions; + data.cases = &cases; + data.region = region; + + walk_data.dom_direction = CDI_DOMINATORS; + walk_data.initialize_block_local_data = NULL; + walk_data.before_dom_children = build_sese_conditions_before; + walk_data.after_dom_children = build_sese_conditions_after; + walk_data.global_data = &data; + walk_data.block_local_data_size = 0; + + init_walk_dominator_tree (&walk_data); + walk_dominator_tree (&walk_data, SESE_ENTRY_BB (region)); + fini_walk_dominator_tree (&walk_data); + + VEC_free (gimple, heap, conditions); + VEC_free (gimple, heap, cases); +} + +/* Traverses all the GBBs of the SCOP and add their constraints to the + iteration domains. */ + +static void +add_conditions_to_constraints (scop_p scop) +{ + int i; + poly_bb_p pbb; + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + add_conditions_to_domain (pbb); +} + +/* Add constraints on the possible values of parameter P from the type + of P. */ + +static void +add_param_constraints (scop_p scop, ppl_Polyhedron_t context, graphite_dim_t p) +{ + ppl_Constraint_t cstr; + ppl_Linear_Expression_t le; + tree parameter = VEC_index (tree, SESE_PARAMS (SCOP_REGION (scop)), p); + tree type = TREE_TYPE (parameter); + tree lb, ub; + + /* Disabled until we fix CPU2006. */ + return; + + if (!INTEGRAL_TYPE_P (type)) + return; + + lb = TYPE_MIN_VALUE (type); + ub = TYPE_MAX_VALUE (type); + + if (lb) + { + ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop)); + ppl_set_coef (le, p, -1); + ppl_set_inhomogeneous_tree (le, lb); + ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL); + ppl_Polyhedron_add_constraint (context, cstr); + ppl_delete_Linear_Expression (le); + ppl_delete_Constraint (cstr); + } + + if (ub) + { + ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop)); + ppl_set_coef (le, p, -1); + ppl_set_inhomogeneous_tree (le, ub); + ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL); + ppl_Polyhedron_add_constraint (context, cstr); + ppl_delete_Linear_Expression (le); + ppl_delete_Constraint (cstr); + } +} + +/* Build the context of the SCOP. The context usually contains extra + constraints that are added to the iteration domains that constrain + some parameters. */ + +static void +build_scop_context (scop_p scop) +{ + ppl_Polyhedron_t context; + graphite_dim_t p, n = scop_nb_params (scop); + + ppl_new_C_Polyhedron_from_space_dimension (&context, n, 0); + + for (p = 0; p < n; p++) + add_param_constraints (scop, context, p); + + ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron + (&SCOP_CONTEXT (scop), context); + + ppl_delete_Polyhedron (context); +} + +/* Build the iteration domains: the loops belonging to the current + SCOP, and that vary for the execution of the current basic block. + Returns false if there is no loop in SCOP. */ + +static void +build_scop_iteration_domain (scop_p scop) +{ + struct loop *loop; + sese region = SCOP_REGION (scop); + int i; + ppl_Polyhedron_t ph; + poly_bb_p pbb; + + ppl_new_C_Polyhedron_from_space_dimension (&ph, scop_nb_params (scop), 0); + + for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++) + if (!loop_in_sese_p (loop_outer (loop), region)) + build_loop_iteration_domains (scop, loop, ph, 0); + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + if (gbb_loop (PBB_BLACK_BOX (pbb))->aux) + ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron + (&PBB_DOMAIN (pbb), (ppl_const_Pointset_Powerset_C_Polyhedron_t) + gbb_loop (PBB_BLACK_BOX (pbb))->aux); + else + ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron + (&PBB_DOMAIN (pbb), ph); + + for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++) + if (loop->aux) + { + ppl_delete_Pointset_Powerset_C_Polyhedron + ((ppl_Pointset_Powerset_C_Polyhedron_t) loop->aux); + loop->aux = NULL; + } + + ppl_delete_Polyhedron (ph); +} + +/* Add a constrain to the ACCESSES polyhedron for the alias set of + data reference DR. ACCESSP_NB_DIMS is the dimension of the + ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration + domain. */ + +static void +pdr_add_alias_set (ppl_Polyhedron_t accesses, data_reference_p dr, + ppl_dimension_type accessp_nb_dims, + ppl_dimension_type dom_nb_dims) +{ + ppl_Linear_Expression_t alias; + ppl_Constraint_t cstr; + int alias_set_num = 0; + + if (dr->aux != NULL) + { + alias_set_num = *((int *)(dr->aux)); + free (dr->aux); + dr->aux = NULL; + } + + ppl_new_Linear_Expression_with_dimension (&alias, accessp_nb_dims); + + ppl_set_coef (alias, dom_nb_dims, 1); + ppl_set_inhomogeneous (alias, -alias_set_num); + ppl_new_Constraint (&cstr, alias, PPL_CONSTRAINT_TYPE_EQUAL); + ppl_Polyhedron_add_constraint (accesses, cstr); + + ppl_delete_Linear_Expression (alias); + ppl_delete_Constraint (cstr); +} + +/* Add to ACCESSES polyhedron equalities defining the access functions + to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES + polyhedron, DOM_NB_DIMS is the dimension of the iteration domain. + PBB is the poly_bb_p that contains the data reference DR. */ + +static void +pdr_add_memory_accesses (ppl_Polyhedron_t accesses, data_reference_p dr, + ppl_dimension_type accessp_nb_dims, + ppl_dimension_type dom_nb_dims, + poly_bb_p pbb) +{ + int i, nb_subscripts = DR_NUM_DIMENSIONS (dr); + Value v; + scop_p scop = PBB_SCOP (pbb); + sese region = SCOP_REGION (scop); + + value_init (v); + + for (i = 0; i < nb_subscripts; i++) + { + ppl_Linear_Expression_t fn, access; + ppl_Constraint_t cstr; + ppl_dimension_type subscript = dom_nb_dims + 1 + i; + tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i); + + ppl_new_Linear_Expression_with_dimension (&fn, dom_nb_dims); + ppl_new_Linear_Expression_with_dimension (&access, accessp_nb_dims); + + value_set_si (v, 1); + scan_tree_for_params (region, afn, fn, v); + ppl_assign_Linear_Expression_from_Linear_Expression (access, fn); + + ppl_set_coef (access, subscript, -1); + ppl_new_Constraint (&cstr, access, PPL_CONSTRAINT_TYPE_EQUAL); + ppl_Polyhedron_add_constraint (accesses, cstr); + + ppl_delete_Linear_Expression (fn); + ppl_delete_Linear_Expression (access); + ppl_delete_Constraint (cstr); + } + + value_clear (v); +} + +/* Add constrains representing the size of the accessed data to the + DATA_CONTAINER polyhedron. ACCESSP_NB_DIMS is the dimension of the + DATA_CONTAINER polyhedron, DOM_NB_DIMS is the dimension of the iteration + domain. */ + +static void +pdr_add_data_dimensions (ppl_Polyhedron_t data_container, data_reference_p dr, + ppl_dimension_type accessp_nb_dims, + ppl_dimension_type dom_nb_dims) +{ + tree ref = DR_REF (dr); + int i, nb_subscripts = DR_NUM_DIMENSIONS (dr); + tree array_size; + HOST_WIDE_INT elt_size; + + array_size = TYPE_SIZE (TREE_TYPE (ref)); + if (array_size == NULL_TREE + || TREE_CODE (array_size) != INTEGER_CST) + return; + + elt_size = int_cst_value (array_size); + + for (i = nb_subscripts - 1; i >= 0; i--) + { + ppl_Linear_Expression_t expr; + ppl_Constraint_t cstr; + ppl_dimension_type subscript = dom_nb_dims + 1 + i; + + /* 0 <= subscript */ + ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims); + ppl_set_coef (expr, subscript, 1); + ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL); + ppl_Polyhedron_add_constraint (data_container, cstr); + ppl_delete_Linear_Expression (expr); + ppl_delete_Constraint (cstr); + + ref = TREE_OPERAND (ref, 0); + array_size = TYPE_SIZE (TREE_TYPE (ref)); + if (array_size == NULL_TREE + || TREE_CODE (array_size) != INTEGER_CST) + break; + + /* subscript <= array_size */ + ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims); + ppl_set_coef (expr, subscript, -1); + + if (elt_size) + ppl_set_inhomogeneous (expr, int_cst_value (array_size) / elt_size); + + ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL); + ppl_Polyhedron_add_constraint (data_container, cstr); + ppl_delete_Linear_Expression (expr); + ppl_delete_Constraint (cstr); + + elt_size = int_cst_value (array_size); + } +} + +/* Build data accesses for DR in PBB. */ + +static void +build_poly_dr (data_reference_p dr, poly_bb_p pbb) +{ + ppl_Polyhedron_t accesses, data_container; + ppl_Pointset_Powerset_C_Polyhedron_t accesses_ps, data_container_ps; + ppl_dimension_type dom_nb_dims; + ppl_dimension_type accessp_nb_dims; + + ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PBB_DOMAIN (pbb), + &dom_nb_dims); + accessp_nb_dims = dom_nb_dims + 1 + DR_NUM_DIMENSIONS (dr); + + ppl_new_C_Polyhedron_from_space_dimension (&accesses, accessp_nb_dims, 0); + ppl_new_C_Polyhedron_from_space_dimension (&data_container, + accessp_nb_dims, 0); + + pdr_add_alias_set (accesses, dr, accessp_nb_dims, dom_nb_dims); + pdr_add_memory_accesses (accesses, dr, accessp_nb_dims, dom_nb_dims, pbb); + pdr_add_data_dimensions (data_container, dr, accessp_nb_dims, dom_nb_dims); + + ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&accesses_ps, + accesses); + ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&data_container_ps, + data_container); + ppl_delete_Polyhedron (accesses); + ppl_delete_Polyhedron (data_container); + new_poly_dr (pbb, accesses_ps, data_container_ps, + DR_IS_READ (dr) ? PDR_READ : PDR_WRITE, dr); +} + +/* Group each data reference in DRS with it's alias set num. */ + +static void +build_alias_set_for_drs (VEC (data_reference_p, heap) **drs) +{ + int num_vertex = VEC_length (data_reference_p, *drs); + struct graph *g = new_graph (num_vertex); + data_reference_p dr1, dr2; + int i, j; + int num_component; + int *queue; + + for (i = 0; VEC_iterate (data_reference_p, *drs, i, dr1); i++) + for (j = i+1; VEC_iterate (data_reference_p, *drs, j, dr2); j++) + if (dr_may_alias_p (dr1, dr2)) + { + add_edge (g, i, j); + add_edge (g, j, i); + } + + queue = XNEWVEC (int, num_vertex); + for (i = 0; i < num_vertex; i++) + queue[i] = i; + + num_component = graphds_dfs (g, queue, num_vertex, NULL, true, NULL); + + for (i = 0; i < g->n_vertices; i++) + { + data_reference_p dr = VEC_index (data_reference_p, *drs, i); + dr->aux = XNEW (int); + *((int *)(dr->aux)) = g->vertices[i].component + 1; + } + + free (queue); + free_graph (g); +} + +/* Build the data references for PBB. */ + +static void +build_pbb_drs (poly_bb_p pbb) +{ + int j; + data_reference_p dr; + VEC (data_reference_p, heap) *gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb)); + + build_alias_set_for_drs (&gbb_drs); + + for (j = 0; VEC_iterate (data_reference_p, gbb_drs, j, dr); j++) + build_poly_dr (dr, pbb); +} + +/* Build data references in SCOP. */ + +static void +build_scop_drs (scop_p scop) +{ + int i; + poly_bb_p pbb; + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + build_pbb_drs (pbb); +} + +/* Return a gsi at the position of the VAR definition. */ + +static gimple_stmt_iterator +gsi_for_ssa_name_def (tree var) +{ + gimple stmt; + basic_block bb; + gimple_stmt_iterator gsi; + gimple_stmt_iterator psi; + + gcc_assert (TREE_CODE (var) == SSA_NAME); + + stmt = SSA_NAME_DEF_STMT (var); + bb = gimple_bb (stmt); + + for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi)) + if (stmt == gsi_stmt (psi)) + return gsi_after_labels (bb); + + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + if (stmt == gsi_stmt (gsi)) + { + gsi_next (&gsi); + return gsi; + } + + gcc_unreachable (); + return gsi; +} + +/* Insert the assignment "RES := VAR" just after the definition of VAR. */ + +static void +insert_out_of_ssa_copy (tree res, tree var) +{ + gimple_stmt_iterator gsi = gsi_for_ssa_name_def (var); + gimple stmt; + gimple_seq stmts; + gimple_stmt_iterator si; + + var = force_gimple_operand (var, &stmts, true, NULL_TREE); + stmt = gimple_build_assign (res, var); + if (!stmts) + stmts = gimple_seq_alloc (); + si = gsi_last (stmts); + gsi_insert_after (&si, stmt, GSI_NEW_STMT); + gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT); +} + +/* Insert on edge E the assignment "RES := EXPR". */ + +static void +insert_out_of_ssa_copy_on_edge (edge e, tree res, tree expr) +{ + gimple_stmt_iterator gsi; + gimple_seq stmts; + tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE); + gimple stmt = gimple_build_assign (res, var); + + if (!stmts) + stmts = gimple_seq_alloc (); + + gsi = gsi_last (stmts); + gsi_insert_after (&gsi, stmt, GSI_NEW_STMT); + gsi_insert_seq_on_edge (e, stmts); + gsi_commit_edge_inserts (); +} + +/* Creates a zero dimension array of the same type as VAR. */ + +static tree +create_zero_dim_array (tree var) +{ + tree index_type = build_index_type (integer_zero_node); + tree elt_type = TREE_TYPE (var); + tree array_type = build_array_type (elt_type, index_type); + tree base = create_tmp_var (array_type, "Red"); + + add_referenced_var (base); + + return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE, + NULL_TREE); +} + +/* Returns true when PHI is a loop close phi node. */ + +static bool +scalar_close_phi_node_p (gimple phi) +{ + gcc_assert (gimple_code (phi) == GIMPLE_PHI); + + if (!is_gimple_reg (gimple_phi_result (phi))) + return false; + + return (gimple_phi_num_args (phi) == 1); +} + +/* Rewrite out of SSA the reduction phi node at PSI by creating a zero + dimension array for it. */ + +static void +rewrite_close_phi_out_of_ssa (gimple_stmt_iterator *psi) +{ + gimple phi = gsi_stmt (*psi); + tree res = gimple_phi_result (phi); + tree var = SSA_NAME_VAR (res); + tree zero_dim_array = create_zero_dim_array (var); + gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (phi)); + gimple stmt = gimple_build_assign (res, zero_dim_array); + tree arg = gimple_phi_arg_def (phi, 0); + + insert_out_of_ssa_copy (zero_dim_array, arg); + + remove_phi_node (psi, false); + gsi_insert_before (&gsi, stmt, GSI_NEW_STMT); + SSA_NAME_DEF_STMT (res) = stmt; +} + +/* Rewrite out of SSA the reduction phi node at PSI by creating a zero + dimension array for it. */ + +static void +rewrite_phi_out_of_ssa (gimple_stmt_iterator *psi) +{ + size_t i; + gimple phi = gsi_stmt (*psi); + basic_block bb = gimple_bb (phi); + tree res = gimple_phi_result (phi); + tree var = SSA_NAME_VAR (res); + tree zero_dim_array = create_zero_dim_array (var); + gimple_stmt_iterator gsi; + gimple stmt; + gimple_seq stmts; + + for (i = 0; i < gimple_phi_num_args (phi); i++) + { + tree arg = gimple_phi_arg_def (phi, i); + + /* Try to avoid the insertion on edges as much as possible: this + would avoid the insertion of code on loop latch edges, making + the pattern matching of the vectorizer happy, or it would + avoid the insertion of useless basic blocks. Note that it is + incorrect to insert out of SSA copies close by their + definition when they are more than two loop levels apart: + for example, starting from a double nested loop + + | a = ... + | loop_1 + | loop_2 + | b = phi (a, c) + | c = ... + | end_2 + | end_1 + + the following transform is incorrect + + | a = ... + | Red[0] = a + | loop_1 + | loop_2 + | b = Red[0] + | c = ... + | Red[0] = c + | end_2 + | end_1 + + whereas inserting the copy on the incomming edge is correct + + | a = ... + | loop_1 + | Red[0] = a + | loop_2 + | b = Red[0] + | c = ... + | Red[0] = c + | end_2 + | end_1 + */ + if (TREE_CODE (arg) == SSA_NAME + && is_gimple_reg (arg) + && gimple_bb (SSA_NAME_DEF_STMT (arg)) + && (flow_bb_inside_loop_p (bb->loop_father, + gimple_bb (SSA_NAME_DEF_STMT (arg))) + || flow_bb_inside_loop_p (loop_outer (bb->loop_father), + gimple_bb (SSA_NAME_DEF_STMT (arg))))) + insert_out_of_ssa_copy (zero_dim_array, arg); + else + insert_out_of_ssa_copy_on_edge (gimple_phi_arg_edge (phi, i), + zero_dim_array, arg); + } + + var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE); + + if (!stmts) + stmts = gimple_seq_alloc (); + + stmt = gimple_build_assign (res, var); + remove_phi_node (psi, false); + SSA_NAME_DEF_STMT (res) = stmt; + + gsi = gsi_last (stmts); + gsi_insert_after (&gsi, stmt, GSI_NEW_STMT); + + gsi = gsi_after_labels (bb); + gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT); +} + +/* Rewrite out of SSA all the reduction phi nodes of SCOP. */ + +static void +rewrite_reductions_out_of_ssa (scop_p scop) +{ + basic_block bb; + gimple_stmt_iterator psi; + sese region = SCOP_REGION (scop); + + FOR_EACH_BB (bb) + if (bb_in_region (bb, SESE_ENTRY_BB (region), SESE_EXIT_BB (region))) + for (psi = gsi_start_phis (bb); !gsi_end_p (psi);) + { + if (scalar_close_phi_node_p (gsi_stmt (psi))) + rewrite_close_phi_out_of_ssa (&psi); + else if (reduction_phi_p (region, &psi)) + rewrite_phi_out_of_ssa (&psi); + } + + update_ssa (TODO_update_ssa); +#ifdef ENABLE_CHECKING + verify_ssa (false); + verify_loop_closed_ssa (); +#endif +} + +/* Returns the number of pbbs that are in loops contained in SCOP. */ + +static int +nb_pbbs_in_loops (scop_p scop) +{ + int i; + poly_bb_p pbb; + int res = 0; + + for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) + if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop))) + res++; + + return res; +} + +/* Builds the polyhedral representation for a SESE region. */ + +bool +build_poly_scop (scop_p scop) +{ + sese region = SCOP_REGION (scop); + rewrite_reductions_out_of_ssa (scop); + build_scop_bbs (scop); + + /* FIXME: This restriction is needed to avoid a problem in CLooG. + Once CLooG is fixed, remove this guard. Anyways, it makes no + sense to optimize a scop containing only PBBs that do not belong + to any loops. */ + if (nb_pbbs_in_loops (scop) == 0) + return false; + + build_sese_loop_nests (region); + build_sese_conditions (region); + find_scop_parameters (scop); + + build_scop_iteration_domain (scop); + build_scop_context (scop); + + add_conditions_to_constraints (scop); + build_scop_scattering (scop); + build_scop_drs (scop); + + return true; +} + +/* Always return false. Exercise the scop_to_clast function. */ + +void +check_poly_representation (scop_p scop) +{ +#ifdef ENABLE_CHECKING + cloog_prog_clast pc = scop_to_clast (scop); + cloog_clast_free (pc.stmt); + cloog_program_free (pc.prog); +#endif +} +#endif diff --git a/gcc/graphite-sese-to-poly.h b/gcc/graphite-sese-to-poly.h new file mode 100644 index 00000000000..d6df07f6ef5 --- /dev/null +++ b/gcc/graphite-sese-to-poly.h @@ -0,0 +1,27 @@ +/* Conversion of SESE regions to Polyhedra. + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Sebastian Pop <sebastian.pop@amd.com>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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/>. */ + +#ifndef GCC_GRAPHITE_SESE_TO_POLY_H +#define GCC_GRAPHITE_SESE_TO_POLY_H + +bool build_poly_scop (scop_p); +void check_poly_representation (scop_p); + +#endif diff --git a/gcc/graphite.c b/gcc/graphite.c index a87bca867c9..0c0b60793d8 100644 --- a/gcc/graphite.c +++ b/gcc/graphite.c @@ -20,12 +20,12 @@ along with GCC; see the file COPYING3. If not see /* This pass converts GIMPLE to GRAPHITE, performs some loop transformations and then converts the resulting representation back - to GIMPLE. + to GIMPLE. An early description of this pass can be found in the GCC Summit'06 paper "GRAPHITE: Polyhedral Analyses and Optimizations for GCC". The wiki page http://gcc.gnu.org/wiki/Graphite contains pointers to - the related work. + the related work. One important document to read is CLooG's internal manual: http://repo.or.cz/w/cloog-ppl.git?a=blob_plain;f=doc/cloog.texi;hb=HEAD @@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see #include "value-prof.h" #include "pointer-set.h" #include "gimple.h" +#include "sese.h" #ifdef HAVE_cloog @@ -63,6042 +64,179 @@ along with GCC; see the file COPYING3. If not see #endif #include "cloog/cloog.h" +#include "ppl_c.h" +#include "graphite-ppl.h" #include "graphite.h" +#include "graphite-poly.h" +#include "graphite-scop-detection.h" +#include "graphite-clast-to-gimple.h" +#include "graphite-sese-to-poly.h" -static VEC (scop_p, heap) *current_scops; - -/* Converts a GMP constant V to a tree and returns it. */ - -static tree -gmp_cst_to_tree (tree type, Value v) -{ - return build_int_cst (type, value_get_si (v)); -} - -/* Returns true when BB is in REGION. */ - -static bool -bb_in_sese_p (basic_block bb, sese region) -{ - return pointer_set_contains (SESE_REGION_BBS (region), bb); -} - -/* Returns true when LOOP is in the SESE region R. */ - -static inline bool -loop_in_sese_p (struct loop *loop, sese r) -{ - return (bb_in_sese_p (loop->header, r) - && bb_in_sese_p (loop->latch, r)); -} - -/* For a USE in BB, if BB is outside REGION, mark the USE in the - SESE_LIVEIN and SESE_LIVEOUT sets. */ +/* Print global statistics to FILE. */ static void -sese_build_livein_liveouts_use (sese region, basic_block bb, tree use) +print_global_statistics (FILE* file) { - unsigned ver; - basic_block def_bb; - - if (TREE_CODE (use) != SSA_NAME) - return; + long n_bbs = 0; + long n_loops = 0; + long n_stmts = 0; + long n_conditions = 0; + long n_p_bbs = 0; + long n_p_loops = 0; + long n_p_stmts = 0; + long n_p_conditions = 0; - ver = SSA_NAME_VERSION (use); - def_bb = gimple_bb (SSA_NAME_DEF_STMT (use)); - if (!def_bb - || !bb_in_sese_p (def_bb, region) - || bb_in_sese_p (bb, region)) - return; - - if (!SESE_LIVEIN_VER (region, ver)) - SESE_LIVEIN_VER (region, ver) = BITMAP_ALLOC (NULL); - - bitmap_set_bit (SESE_LIVEIN_VER (region, ver), bb->index); - bitmap_set_bit (SESE_LIVEOUT (region), ver); -} - -/* Marks for rewrite all the SSA_NAMES defined in REGION and that are - used in BB that is outside of the REGION. */ - -static void -sese_build_livein_liveouts_bb (sese region, basic_block bb) -{ - gimple_stmt_iterator bsi; - edge e; - edge_iterator ei; - ssa_op_iter iter; - tree var; - - FOR_EACH_EDGE (e, ei, bb->succs) - for (bsi = gsi_start_phis (e->dest); !gsi_end_p (bsi); gsi_next (&bsi)) - sese_build_livein_liveouts_use (region, bb, - PHI_ARG_DEF_FROM_EDGE (gsi_stmt (bsi), e)); - - for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) - FOR_EACH_SSA_TREE_OPERAND (var, gsi_stmt (bsi), iter, SSA_OP_ALL_USES) - sese_build_livein_liveouts_use (region, bb, var); -} - -/* Build the SESE_LIVEIN and SESE_LIVEOUT for REGION. */ - -void -sese_build_livein_liveouts (sese region) -{ basic_block bb; - SESE_LIVEOUT (region) = BITMAP_ALLOC (NULL); - SESE_NUM_VER (region) = num_ssa_names; - SESE_LIVEIN (region) = XCNEWVEC (bitmap, SESE_NUM_VER (region)); - - FOR_EACH_BB (bb) - sese_build_livein_liveouts_bb (region, bb); -} - -/* Register basic blocks belonging to a region in a pointer set. */ - -static void -register_bb_in_sese (basic_block entry_bb, basic_block exit_bb, sese region) -{ - edge_iterator ei; - edge e; - basic_block bb = entry_bb; - - FOR_EACH_EDGE (e, ei, bb->succs) - { - if (!pointer_set_contains (SESE_REGION_BBS (region), e->dest) && - e->dest->index != exit_bb->index) - { - pointer_set_insert (SESE_REGION_BBS (region), e->dest); - register_bb_in_sese (e->dest, exit_bb, region); - } - } -} - -/* Builds a new SESE region from edges ENTRY and EXIT. */ - -sese -new_sese (edge entry, edge exit) -{ - sese res = XNEW (struct sese_d); - - SESE_ENTRY (res) = entry; - SESE_EXIT (res) = exit; - SESE_REGION_BBS (res) = pointer_set_create (); - register_bb_in_sese (entry->dest, exit->dest, res); - - SESE_LIVEOUT (res) = NULL; - SESE_NUM_VER (res) = 0; - SESE_LIVEIN (res) = NULL; - - return res; -} - -/* Deletes REGION. */ - -void -free_sese (sese region) -{ - int i; - - for (i = 0; i < SESE_NUM_VER (region); i++) - BITMAP_FREE (SESE_LIVEIN_VER (region, i)); - - if (SESE_LIVEIN (region)) - free (SESE_LIVEIN (region)); - - if (SESE_LIVEOUT (region)) - BITMAP_FREE (SESE_LIVEOUT (region)); - - pointer_set_destroy (SESE_REGION_BBS (region)); - XDELETE (region); -} - - - -/* Debug the list of old induction variables for this SCOP. */ - -void -debug_oldivs (scop_p scop) -{ - int i; - name_tree oldiv; - - fprintf (stderr, "Old IVs:"); - - for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, oldiv); i++) - { - fprintf (stderr, "("); - print_generic_expr (stderr, oldiv->t, 0); - fprintf (stderr, ", %s, %d)\n", oldiv->name, oldiv->loop->num); - } - fprintf (stderr, "\n"); -} - -/* Debug the loops around basic block GB. */ - -void -debug_loop_vec (graphite_bb_p gb) -{ - int i; - loop_p loop; - - fprintf (stderr, "Loop Vec:"); - - for (i = 0; VEC_iterate (loop_p, GBB_LOOPS (gb), i, loop); i++) - fprintf (stderr, "%d: %d, ", i, loop ? loop->num : -1); - - fprintf (stderr, "\n"); -} - -/* Returns true if stack ENTRY is a constant. */ - -static bool -iv_stack_entry_is_constant (iv_stack_entry *entry) -{ - return entry->kind == iv_stack_entry_const; -} - -/* Returns true if stack ENTRY is an induction variable. */ - -static bool -iv_stack_entry_is_iv (iv_stack_entry *entry) -{ - return entry->kind == iv_stack_entry_iv; -} - -/* Push (IV, NAME) on STACK. */ - -static void -loop_iv_stack_push_iv (loop_iv_stack stack, tree iv, const char *name) -{ - iv_stack_entry *entry = XNEW (iv_stack_entry); - name_tree named_iv = XNEW (struct name_tree_d); - - named_iv->t = iv; - named_iv->name = name; - - entry->kind = iv_stack_entry_iv; - entry->data.iv = named_iv; - - VEC_safe_push (iv_stack_entry_p, heap, *stack, entry); -} - -/* Inserts a CONSTANT in STACK at INDEX. */ - -static void -loop_iv_stack_insert_constant (loop_iv_stack stack, int index, - tree constant) -{ - iv_stack_entry *entry = XNEW (iv_stack_entry); - - entry->kind = iv_stack_entry_const; - entry->data.constant = constant; - - VEC_safe_insert (iv_stack_entry_p, heap, *stack, index, entry); -} - -/* Pops and frees an element out of STACK. */ - -static void -loop_iv_stack_pop (loop_iv_stack stack) -{ - iv_stack_entry_p entry = VEC_pop (iv_stack_entry_p, *stack); - - free (entry->data.iv); - free (entry); -} - -/* Get the IV at INDEX in STACK. */ - -static tree -loop_iv_stack_get_iv (loop_iv_stack stack, int index) -{ - iv_stack_entry_p entry = VEC_index (iv_stack_entry_p, *stack, index); - iv_stack_entry_data data = entry->data; - - return iv_stack_entry_is_iv (entry) ? data.iv->t : data.constant; -} - -/* Get the IV from its NAME in STACK. */ - -static tree -loop_iv_stack_get_iv_from_name (loop_iv_stack stack, const char* name) -{ - int i; - iv_stack_entry_p entry; - - for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry); i++) + FOR_ALL_BB (bb) { - name_tree iv = entry->data.iv; - if (!strcmp (name, iv->name)) - return iv->t; - } - - return NULL; -} + gimple_stmt_iterator psi; -/* Prints on stderr the contents of STACK. */ + n_bbs++; + n_p_bbs += bb->count; -void -debug_loop_iv_stack (loop_iv_stack stack) -{ - int i; - iv_stack_entry_p entry; - bool first = true; - - fprintf (stderr, "("); - - for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry); i++) - { - if (first) - first = false; - else - fprintf (stderr, " "); - - if (iv_stack_entry_is_iv (entry)) + /* Ignore artificial surrounding loop. */ + if (bb == bb->loop_father->header + && bb->index != 0) { - name_tree iv = entry->data.iv; - fprintf (stderr, "%s:", iv->name); - print_generic_expr (stderr, iv->t, 0); + n_loops++; + n_p_loops += bb->count; } - else - { - tree constant = entry->data.constant; - print_generic_expr (stderr, constant, 0); - fprintf (stderr, ":"); - print_generic_expr (stderr, constant, 0); - } - } - - fprintf (stderr, ")\n"); -} - -/* Frees STACK. */ - -static void -free_loop_iv_stack (loop_iv_stack stack) -{ - int i; - iv_stack_entry_p entry; - - for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry); i++) - { - free (entry->data.iv); - free (entry); - } - - VEC_free (iv_stack_entry_p, heap, *stack); -} - - - -/* Structure containing the mapping between the CLooG's induction - variable and the type of the old induction variable. */ -typedef struct ivtype_map_elt_d -{ - tree type; - const char *cloog_iv; -} *ivtype_map_elt; - -/* Print to stderr the element ELT. */ - -static void -debug_ivtype_elt (ivtype_map_elt elt) -{ - fprintf (stderr, "(%s, ", elt->cloog_iv); - print_generic_expr (stderr, elt->type, 0); - fprintf (stderr, ")\n"); -} - -/* Helper function for debug_ivtype_map. */ - -static int -debug_ivtype_map_1 (void **slot, void *s ATTRIBUTE_UNUSED) -{ - struct ivtype_map_elt_d *entry = (struct ivtype_map_elt_d *) *slot; - debug_ivtype_elt (entry); - return 1; -} - -/* Print to stderr all the elements of MAP. */ - -void -debug_ivtype_map (htab_t map) -{ - htab_traverse (map, debug_ivtype_map_1, NULL); -} - -/* Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW. */ - -static inline ivtype_map_elt -new_ivtype_map_elt (const char *cloog_iv, tree type) -{ - ivtype_map_elt res; - - res = XNEW (struct ivtype_map_elt_d); - res->cloog_iv = cloog_iv; - res->type = type; - - return res; -} - -/* Computes a hash function for database element ELT. */ - -static hashval_t -ivtype_map_elt_info (const void *elt) -{ - return htab_hash_pointer (((const struct ivtype_map_elt_d *) elt)->cloog_iv); -} - -/* Compares database elements E1 and E2. */ - -static int -eq_ivtype_map_elts (const void *e1, const void *e2) -{ - const struct ivtype_map_elt_d *elt1 = (const struct ivtype_map_elt_d *) e1; - const struct ivtype_map_elt_d *elt2 = (const struct ivtype_map_elt_d *) e2; - - return (elt1->cloog_iv == elt2->cloog_iv); -} - - - -/* Given a CLOOG_IV, returns the type that it should have in GCC land. - If the information is not available, i.e. in the case one of the - transforms created the loop, just return integer_type_node. */ - -static tree -gcc_type_for_cloog_iv (const char *cloog_iv, graphite_bb_p gbb) -{ - struct ivtype_map_elt_d tmp; - PTR *slot; - - tmp.cloog_iv = cloog_iv; - slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, NO_INSERT); - - if (slot && *slot) - return ((ivtype_map_elt) *slot)->type; - - return integer_type_node; -} - -/* Inserts constants derived from the USER_STMT argument list into the - STACK. This is needed to map old ivs to constants when loops have - been eliminated. */ - -static void -loop_iv_stack_patch_for_consts (loop_iv_stack stack, - struct clast_user_stmt *user_stmt) -{ - struct clast_stmt *t; - int index = 0; - CloogStatement *cs = user_stmt->statement; - graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs); - for (t = user_stmt->substitutions; t; t = t->next) - { - struct clast_expr *expr = (struct clast_expr *) - ((struct clast_assignment *)t)->RHS; - struct clast_term *term = (struct clast_term *) expr; - - /* FIXME: What should be done with expr_bin, expr_red? */ - if (expr->type == expr_term - && !term->var) + if (VEC_length (edge, bb->succs) > 1) { - loop_p loop = gbb_loop_at_index (gbb, index); - tree oldiv = oldiv_for_loop (GBB_SCOP (gbb), loop); - tree type = oldiv ? TREE_TYPE (oldiv) : integer_type_node; - tree value = gmp_cst_to_tree (type, term->val); - loop_iv_stack_insert_constant (stack, index, value); + n_conditions++; + n_p_conditions += bb->count; } - index = index + 1; - } -} - -/* Removes all constants in the iv STACK. */ -static void -loop_iv_stack_remove_constants (loop_iv_stack stack) -{ - int i; - iv_stack_entry *entry; - - for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry);) - { - if (iv_stack_entry_is_constant (entry)) + for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi)) { - free (VEC_index (iv_stack_entry_p, *stack, i)); - VEC_ordered_remove (iv_stack_entry_p, *stack, i); + n_stmts++; + n_p_stmts += bb->count; } - else - i++; - } -} - -/* Returns a new loop_to_cloog_loop_str structure. */ - -static inline struct loop_to_cloog_loop_str * -new_loop_to_cloog_loop_str (int loop_num, - int loop_position, - CloogLoop *cloog_loop) -{ - struct loop_to_cloog_loop_str *result; - - result = XNEW (struct loop_to_cloog_loop_str); - result->loop_num = loop_num; - result->cloog_loop = cloog_loop; - result->loop_position = loop_position; - - return result; -} - -/* Hash function for SCOP_LOOP2CLOOG_LOOP hash table. */ - -static hashval_t -hash_loop_to_cloog_loop (const void *elt) -{ - return ((const struct loop_to_cloog_loop_str *) elt)->loop_num; -} - -/* Equality function for SCOP_LOOP2CLOOG_LOOP hash table. */ - -static int -eq_loop_to_cloog_loop (const void *el1, const void *el2) -{ - const struct loop_to_cloog_loop_str *elt1, *elt2; - - elt1 = (const struct loop_to_cloog_loop_str *) el1; - elt2 = (const struct loop_to_cloog_loop_str *) el2; - return elt1->loop_num == elt2->loop_num; -} - -/* Compares two graphite bbs and returns an integer less than, equal to, or - greater than zero if the first argument is considered to be respectively - less than, equal to, or greater than the second. - We compare using the lexicographic order of the static schedules. */ - -static int -gbb_compare (const void *p_1, const void *p_2) -{ - const struct graphite_bb *const gbb_1 - = *(const struct graphite_bb *const*) p_1; - const struct graphite_bb *const gbb_2 - = *(const struct graphite_bb *const*) p_2; - - return lambda_vector_compare (GBB_STATIC_SCHEDULE (gbb_1), - gbb_nb_loops (gbb_1) + 1, - GBB_STATIC_SCHEDULE (gbb_2), - gbb_nb_loops (gbb_2) + 1); -} - -/* Sort graphite bbs in SCOP. */ - -static void -graphite_sort_gbbs (scop_p scop) -{ - VEC (graphite_bb_p, heap) *bbs = SCOP_BBS (scop); - - qsort (VEC_address (graphite_bb_p, bbs), - VEC_length (graphite_bb_p, bbs), - sizeof (graphite_bb_p), gbb_compare); -} - -/* Dump conditions of a graphite basic block GBB on FILE. */ - -static void -dump_gbb_conditions (FILE *file, graphite_bb_p gbb) -{ - int i; - gimple stmt; - VEC (gimple, heap) *conditions = GBB_CONDITIONS (gbb); - - if (VEC_empty (gimple, conditions)) - return; - - fprintf (file, "\tbb %d\t: cond = {", GBB_BB (gbb)->index); - - for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++) - print_gimple_stmt (file, stmt, 0, 0); - - fprintf (file, "}\n"); -} - -/* Converts the graphite scheduling function into a cloog scattering - matrix. This scattering matrix is used to limit the possible cloog - output to valid programs in respect to the scheduling function. - - SCATTERING_DIMENSIONS specifies the dimensionality of the scattering - matrix. CLooG 0.14.0 and previous versions require, that all scattering - functions of one CloogProgram have the same dimensionality, therefore we - allow to specify it. (Should be removed in future versions) */ - -static CloogMatrix * -schedule_to_scattering (graphite_bb_p gb, int scattering_dimensions) -{ - int i; - scop_p scop = GBB_SCOP (gb); - - int nb_iterators = gbb_nb_loops (gb); - - /* The cloog scattering matrix consists of these colums: - 1 col = Eq/Inq, - scattering_dimensions cols = Scattering dimensions, - nb_iterators cols = bb's iterators, - scop_nb_params cols = Parameters, - 1 col = Constant 1. - - Example: - - scattering_dimensions = 5 - max_nb_iterators = 2 - nb_iterators = 1 - scop_nb_params = 2 - - Schedule: - ? i - 4 5 - - Scattering Matrix: - s1 s2 s3 s4 s5 i p1 p2 1 - 1 0 0 0 0 0 0 0 -4 = 0 - 0 1 0 0 0 -1 0 0 0 = 0 - 0 0 1 0 0 0 0 0 -5 = 0 */ - int nb_params = scop_nb_params (scop); - int nb_cols = 1 + scattering_dimensions + nb_iterators + nb_params + 1; - int col_const = nb_cols - 1; - int col_iter_offset = 1 + scattering_dimensions; - - CloogMatrix *scat = cloog_matrix_alloc (scattering_dimensions, nb_cols); - - gcc_assert (scattering_dimensions >= nb_iterators * 2 + 1); - - /* Initialize the identity matrix. */ - for (i = 0; i < scattering_dimensions; i++) - value_set_si (scat->p[i][i + 1], 1); - - /* Textual order outside the first loop */ - value_set_si (scat->p[0][col_const], -GBB_STATIC_SCHEDULE (gb)[0]); - - /* For all surrounding loops. */ - for (i = 0; i < nb_iterators; i++) - { - int schedule = GBB_STATIC_SCHEDULE (gb)[i + 1]; - - /* Iterations of this loop. */ - value_set_si (scat->p[2 * i + 1][col_iter_offset + i], -1); - - /* Textual order inside this loop. */ - value_set_si (scat->p[2 * i + 2][col_const], -schedule); } - return scat; + fprintf (file, "\nGlobal statistics ("); + fprintf (file, "BBS:%ld, ", n_bbs); + fprintf (file, "LOOPS:%ld, ", n_loops); + fprintf (file, "CONDITIONS:%ld, ", n_conditions); + fprintf (file, "STMTS:%ld)\n", n_stmts); + fprintf (file, "\nGlobal profiling statistics ("); + fprintf (file, "BBS:%ld, ", n_p_bbs); + fprintf (file, "LOOPS:%ld, ", n_p_loops); + fprintf (file, "CONDITIONS:%ld, ", n_p_conditions); + fprintf (file, "STMTS:%ld)\n", n_p_stmts); } -/* Print the schedules of GB to FILE with INDENT white spaces before. - VERBOSITY determines how verbose the code pretty printers are. */ - -void -print_graphite_bb (FILE *file, graphite_bb_p gb, int indent, int verbosity) -{ - CloogMatrix *scattering; - int i; - loop_p loop; - fprintf (file, "\nGBB (\n"); - - print_loops_bb (file, GBB_BB (gb), indent+2, verbosity); - - if (GBB_DOMAIN (gb)) - { - fprintf (file, " (domain: \n"); - cloog_matrix_print (file, GBB_DOMAIN (gb)); - fprintf (file, " )\n"); - } - - if (GBB_STATIC_SCHEDULE (gb)) - { - fprintf (file, " (static schedule: "); - print_lambda_vector (file, GBB_STATIC_SCHEDULE (gb), - gbb_nb_loops (gb) + 1); - fprintf (file, " )\n"); - } - - if (GBB_LOOPS (gb)) - { - fprintf (file, " (contained loops: \n"); - for (i = 0; VEC_iterate (loop_p, GBB_LOOPS (gb), i, loop); i++) - if (loop == NULL) - fprintf (file, " iterator %d => NULL \n", i); - else - fprintf (file, " iterator %d => loop %d \n", i, - loop->num); - fprintf (file, " )\n"); - } - - if (GBB_DATA_REFS (gb)) - dump_data_references (file, GBB_DATA_REFS (gb)); - - if (GBB_CONDITIONS (gb)) - { - fprintf (file, " (conditions: \n"); - dump_gbb_conditions (file, gb); - fprintf (file, " )\n"); - } - - if (GBB_SCOP (gb) - && GBB_STATIC_SCHEDULE (gb)) - { - fprintf (file, " (scattering: \n"); - scattering = schedule_to_scattering (gb, 2 * gbb_nb_loops (gb) + 1); - cloog_matrix_print (file, scattering); - cloog_matrix_free (scattering); - fprintf (file, " )\n"); - } - - fprintf (file, ")\n"); -} - -/* Print to STDERR the schedules of GB with VERBOSITY level. */ - -void -debug_gbb (graphite_bb_p gb, int verbosity) -{ - print_graphite_bb (stderr, gb, 0, verbosity); -} - - -/* Print SCOP to FILE. VERBOSITY determines how verbose the pretty - printers are. */ - -static void -print_scop (FILE *file, scop_p scop, int verbosity) -{ - if (scop == NULL) - return; - - fprintf (file, "\nSCoP_%d_%d (\n", - SCOP_ENTRY (scop)->index, SCOP_EXIT (scop)->index); - - fprintf (file, " (cloog: \n"); - cloog_program_print (file, SCOP_PROG (scop)); - fprintf (file, " )\n"); - - if (SCOP_BBS (scop)) - { - graphite_bb_p gb; - int i; - - for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++) - print_graphite_bb (file, gb, 0, verbosity); - } - - fprintf (file, ")\n"); -} - -/* Print all the SCOPs to FILE. VERBOSITY determines how verbose the - code pretty printers are. */ +/* Print statistics for SCOP to FILE. */ static void -print_scops (FILE *file, int verbosity) -{ - int i; - scop_p scop; - - for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++) - print_scop (file, scop, verbosity); -} - -/* Debug SCOP. VERBOSITY determines how verbose the code pretty - printers are. */ - -void -debug_scop (scop_p scop, int verbosity) -{ - print_scop (stderr, scop, verbosity); -} - -/* Debug all SCOPs from CURRENT_SCOPS. VERBOSITY determines how - verbose the code pretty printers are. */ - -void -debug_scops (int verbosity) +print_graphite_scop_statistics (FILE* file, scop_p scop) { - print_scops (stderr, verbosity); -} + long n_bbs = 0; + long n_loops = 0; + long n_stmts = 0; + long n_conditions = 0; + long n_p_bbs = 0; + long n_p_loops = 0; + long n_p_stmts = 0; + long n_p_conditions = 0; -/* Pretty print to FILE the SCOP in DOT format. */ - -static void -dot_scop_1 (FILE *file, scop_p scop) -{ - edge e; - edge_iterator ei; basic_block bb; - basic_block entry = SCOP_ENTRY (scop); - basic_block exit = SCOP_EXIT (scop); - - fprintf (file, "digraph SCoP_%d_%d {\n", entry->index, - exit->index); - - FOR_ALL_BB (bb) - { - if (bb == entry) - fprintf (file, "%d [shape=triangle];\n", bb->index); - - if (bb == exit) - fprintf (file, "%d [shape=box];\n", bb->index); - - if (bb_in_sese_p (bb, SCOP_REGION (scop))) - fprintf (file, "%d [color=red];\n", bb->index); - - FOR_EACH_EDGE (e, ei, bb->succs) - fprintf (file, "%d -> %d;\n", bb->index, e->dest->index); - } - - fputs ("}\n\n", file); -} - -/* Display SCOP using dotty. */ - -void -dot_scop (scop_p scop) -{ - dot_scop_1 (stderr, scop); -} - -/* Pretty print all SCoPs in DOT format and mark them with different colors. - If there are not enough colors, paint later SCoPs gray. - Special nodes: - - "*" after the node number: entry of a SCoP, - - "#" after the node number: exit of a SCoP, - - "()" entry or exit not part of SCoP. */ - -static void -dot_all_scops_1 (FILE *file) -{ - basic_block bb; - edge e; - edge_iterator ei; - scop_p scop; - const char* color; - int i; - - /* Disable debugging while printing graph. */ - int tmp_dump_flags = dump_flags; - dump_flags = 0; - - fprintf (file, "digraph all {\n"); FOR_ALL_BB (bb) { - int part_of_scop = false; - - /* Use HTML for every bb label. So we are able to print bbs - which are part of two different SCoPs, with two different - background colors. */ - fprintf (file, "%d [label=<\n <TABLE BORDER=\"0\" CELLBORDER=\"1\" ", - bb->index); - fprintf (file, "CELLSPACING=\"0\">\n"); - - /* Select color for SCoP. */ - for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++) - if (bb_in_sese_p (bb, SCOP_REGION (scop)) - || (SCOP_EXIT (scop) == bb) - || (SCOP_ENTRY (scop) == bb)) - { - switch (i % 17) - { - case 0: /* red */ - color = "#e41a1c"; - break; - case 1: /* blue */ - color = "#377eb8"; - break; - case 2: /* green */ - color = "#4daf4a"; - break; - case 3: /* purple */ - color = "#984ea3"; - break; - case 4: /* orange */ - color = "#ff7f00"; - break; - case 5: /* yellow */ - color = "#ffff33"; - break; - case 6: /* brown */ - color = "#a65628"; - break; - case 7: /* rose */ - color = "#f781bf"; - break; - case 8: - color = "#8dd3c7"; - break; - case 9: - color = "#ffffb3"; - break; - case 10: - color = "#bebada"; - break; - case 11: - color = "#fb8072"; - break; - case 12: - color = "#80b1d3"; - break; - case 13: - color = "#fdb462"; - break; - case 14: - color = "#b3de69"; - break; - case 15: - color = "#fccde5"; - break; - case 16: - color = "#bc80bd"; - break; - default: /* gray */ - color = "#999999"; - } - - fprintf (file, " <TR><TD WIDTH=\"50\" BGCOLOR=\"%s\">", color); - - if (!bb_in_sese_p (bb, SCOP_REGION (scop))) - fprintf (file, " ("); - - if (bb == SCOP_ENTRY (scop) - && bb == SCOP_EXIT (scop)) - fprintf (file, " %d*# ", bb->index); - else if (bb == SCOP_ENTRY (scop)) - fprintf (file, " %d* ", bb->index); - else if (bb == SCOP_EXIT (scop)) - fprintf (file, " %d# ", bb->index); - else - fprintf (file, " %d ", bb->index); - - if (!bb_in_sese_p (bb, SCOP_REGION (scop))) - fprintf (file, ")"); - - fprintf (file, "</TD></TR>\n"); - part_of_scop = true; - } - - if (!part_of_scop) - { - fprintf (file, " <TR><TD WIDTH=\"50\" BGCOLOR=\"#ffffff\">"); - fprintf (file, " %d </TD></TR>\n", bb->index); - } - - fprintf (file, " </TABLE>>, shape=box, style=\"setlinewidth(0)\"]\n"); - } - - FOR_ALL_BB (bb) - { - FOR_EACH_EDGE (e, ei, bb->succs) - fprintf (file, "%d -> %d;\n", bb->index, e->dest->index); - } - - fputs ("}\n\n", file); - - /* Enable debugging again. */ - dump_flags = tmp_dump_flags; -} - -/* Display all SCoPs using dotty. */ - -void -dot_all_scops (void) -{ - /* When debugging, enable the following code. This cannot be used - in production compilers because it calls "system". */ -#if 0 - FILE *stream = fopen ("/tmp/allscops.dot", "w"); - gcc_assert (stream); - - dot_all_scops_1 (stream); - fclose (stream); - - system ("dotty /tmp/allscops.dot"); -#else - dot_all_scops_1 (stderr); -#endif -} - -/* Returns the outermost loop in SCOP that contains BB. */ - -static struct loop * -outermost_loop_in_scop (scop_p scop, basic_block bb) -{ - struct loop *nest; - - nest = bb->loop_father; - while (loop_outer (nest) - && loop_in_sese_p (loop_outer (nest), SCOP_REGION (scop))) - nest = loop_outer (nest); - - return nest; -} - -/* Returns the block preceding the entry of SCOP. */ - -static basic_block -block_before_scop (scop_p scop) -{ - return SESE_ENTRY (SCOP_REGION (scop))->src; -} - -/* Return true when EXPR is an affine function in LOOP with parameters - instantiated relative to SCOP_ENTRY. */ - -static bool -loop_affine_expr (basic_block scop_entry, struct loop *loop, tree expr) -{ - int n = loop->num; - tree scev = analyze_scalar_evolution (loop, expr); - - scev = instantiate_scev (scop_entry, loop, scev); - - return (evolution_function_is_invariant_p (scev, n) - || evolution_function_is_affine_multivariate_p (scev, n)); -} - -/* Return true if REF or any of its subtrees contains a - component_ref. */ - -static bool -contains_component_ref_p (tree ref) -{ - if (!ref) - return false; - - while (handled_component_p (ref)) - { - if (TREE_CODE (ref) == COMPONENT_REF) - return true; - - ref = TREE_OPERAND (ref, 0); - } - - return false; -} - -/* Return true if the operand OP is simple. */ - -static bool -is_simple_operand (loop_p loop, gimple stmt, tree op) -{ - /* It is not a simple operand when it is a declaration, */ - if (DECL_P (op) - /* or a structure, */ - || AGGREGATE_TYPE_P (TREE_TYPE (op)) - /* or a COMPONENT_REF, */ - || contains_component_ref_p (op) - /* or a memory access that cannot be analyzed by the data - reference analysis. */ - || ((handled_component_p (op) || INDIRECT_REF_P (op)) - && !stmt_simple_memref_p (loop, stmt, op))) - return false; - - return true; -} - -/* Return true only when STMT is simple enough for being handled by - Graphite. This depends on SCOP_ENTRY, as the parametetrs are - initialized relatively to this basic block. */ - -static bool -stmt_simple_for_scop_p (basic_block scop_entry, gimple stmt) -{ - basic_block bb = gimple_bb (stmt); - struct loop *loop = bb->loop_father; - - /* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects. - Calls have side-effects, except those to const or pure - functions. */ - if (gimple_has_volatile_ops (stmt) - || (gimple_code (stmt) == GIMPLE_CALL - && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE))) - || (gimple_code (stmt) == GIMPLE_ASM)) - return false; - - switch (gimple_code (stmt)) - { - case GIMPLE_RETURN: - case GIMPLE_LABEL: - return true; - - case GIMPLE_COND: - { - tree op; - ssa_op_iter op_iter; - enum tree_code code = gimple_cond_code (stmt); - - /* We can only handle this kind of conditional expressions. - For inequalities like "if (i != 3 * k)" we need unions of - polyhedrons. Expressions like "if (a)" or "if (a == 15)" need - them for the else branch. */ - if (!(code == LT_EXPR - || code == GT_EXPR - || code == LE_EXPR - || code == GE_EXPR)) - return false; - - if (!scop_entry) - return false; - - FOR_EACH_SSA_TREE_OPERAND (op, stmt, op_iter, SSA_OP_ALL_USES) - if (!loop_affine_expr (scop_entry, loop, op)) - return false; - - return true; - } - - case GIMPLE_ASSIGN: - { - enum tree_code code = gimple_assign_rhs_code (stmt); - - switch (get_gimple_rhs_class (code)) - { - case GIMPLE_UNARY_RHS: - case GIMPLE_SINGLE_RHS: - return (is_simple_operand (loop, stmt, gimple_assign_lhs (stmt)) - && is_simple_operand (loop, stmt, gimple_assign_rhs1 (stmt))); - - case GIMPLE_BINARY_RHS: - return (is_simple_operand (loop, stmt, gimple_assign_lhs (stmt)) - && is_simple_operand (loop, stmt, gimple_assign_rhs1 (stmt)) - && is_simple_operand (loop, stmt, gimple_assign_rhs2 (stmt))); - - case GIMPLE_INVALID_RHS: - default: - gcc_unreachable (); - } - } - - case GIMPLE_CALL: - { - size_t i; - size_t n = gimple_call_num_args (stmt); - tree lhs = gimple_call_lhs (stmt); - - if (lhs && !is_simple_operand (loop, stmt, lhs)) - return false; - - for (i = 0; i < n; i++) - if (!is_simple_operand (loop, stmt, gimple_call_arg (stmt, i))) - return false; - - return true; - } - - default: - /* These nodes cut a new scope. */ - return false; - } - - return false; -} - -/* Returns the statement of BB that contains a harmful operation: that - can be a function call with side effects, the induction variables - are not linear with respect to SCOP_ENTRY, etc. The current open - scop should end before this statement. */ - -static gimple -harmful_stmt_in_bb (basic_block scop_entry, basic_block bb) -{ - gimple_stmt_iterator gsi; - gimple stmt; - - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - if (!stmt_simple_for_scop_p (scop_entry, gsi_stmt (gsi))) - return gsi_stmt (gsi); - - stmt = last_stmt (bb); - if (stmt && gimple_code (stmt) == GIMPLE_COND) - { - tree lhs = gimple_cond_lhs (stmt); - tree rhs = gimple_cond_rhs (stmt); - - if (TREE_CODE (TREE_TYPE (lhs)) == REAL_TYPE - || TREE_CODE (TREE_TYPE (rhs)) == REAL_TYPE) - return stmt; - } - - return NULL; -} - -/* Returns true when BB will be represented in graphite. Return false - for the basic blocks that contain code eliminated in the code - generation pass: i.e. induction variables and exit conditions. */ - -static bool -graphite_stmt_p (scop_p scop, basic_block bb, - VEC (data_reference_p, heap) *drs) -{ - gimple_stmt_iterator gsi; - loop_p loop = bb->loop_father; - - if (VEC_length (data_reference_p, drs) > 0) - return true; - - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple stmt = gsi_stmt (gsi); - - switch (gimple_code (stmt)) - { - /* Control flow expressions can be ignored, as they are - represented in the iteration domains and will be - regenerated by graphite. */ - case GIMPLE_COND: - case GIMPLE_GOTO: - case GIMPLE_SWITCH: - break; - - case GIMPLE_ASSIGN: - { - tree var = gimple_assign_lhs (stmt); - var = analyze_scalar_evolution (loop, var); - var = instantiate_scev (block_before_scop (scop), loop, var); - - if (chrec_contains_undetermined (var)) - return true; - - break; - } - - default: - return true; - } - } - - return false; -} - -/* Store the GRAPHITE representation of BB. */ - -static void -new_graphite_bb (scop_p scop, basic_block bb) -{ - struct graphite_bb *gbb; - VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5); - struct loop *nest = outermost_loop_in_scop (scop, bb); - gimple_stmt_iterator gsi; - - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - find_data_references_in_stmt (nest, gsi_stmt (gsi), &drs); - - if (!graphite_stmt_p (scop, bb, drs)) - { - free_data_refs (drs); - return; - } - - gbb = XNEW (struct graphite_bb); - bb->aux = gbb; - GBB_BB (gbb) = bb; - GBB_SCOP (gbb) = scop; - GBB_DATA_REFS (gbb) = drs; - GBB_DOMAIN (gbb) = NULL; - GBB_CONDITIONS (gbb) = NULL; - GBB_CONDITION_CASES (gbb) = NULL; - GBB_LOOPS (gbb) = NULL; - GBB_STATIC_SCHEDULE (gbb) = NULL; - GBB_CLOOG_IV_TYPES (gbb) = NULL; - VEC_safe_push (graphite_bb_p, heap, SCOP_BBS (scop), gbb); -} - -/* Frees GBB. */ - -static void -free_graphite_bb (struct graphite_bb *gbb) -{ - if (GBB_DOMAIN (gbb)) - cloog_matrix_free (GBB_DOMAIN (gbb)); + gimple_stmt_iterator psi; + loop_p loop = bb->loop_father; - if (GBB_CLOOG_IV_TYPES (gbb)) - htab_delete (GBB_CLOOG_IV_TYPES (gbb)); - - /* FIXME: free_data_refs is disabled for the moment, but should be - enabled. - - free_data_refs (GBB_DATA_REFS (gbb)); */ - - VEC_free (gimple, heap, GBB_CONDITIONS (gbb)); - VEC_free (gimple, heap, GBB_CONDITION_CASES (gbb)); - VEC_free (loop_p, heap, GBB_LOOPS (gbb)); - GBB_BB (gbb)->aux = 0; - XDELETE (gbb); -} - - - -/* Structure containing the mapping between the old names and the new - names used after block copy in the new loop context. */ -typedef struct rename_map_elt_d -{ - tree old_name, new_name; -} *rename_map_elt; - - -/* Print to stderr the element ELT. */ - -static void -debug_rename_elt (rename_map_elt elt) -{ - fprintf (stderr, "("); - print_generic_expr (stderr, elt->old_name, 0); - fprintf (stderr, ", "); - print_generic_expr (stderr, elt->new_name, 0); - fprintf (stderr, ")\n"); -} - -/* Helper function for debug_rename_map. */ - -static int -debug_rename_map_1 (void **slot, void *s ATTRIBUTE_UNUSED) -{ - struct rename_map_elt_d *entry = (struct rename_map_elt_d *) *slot; - debug_rename_elt (entry); - return 1; -} - -/* Print to stderr all the elements of MAP. */ - -void -debug_rename_map (htab_t map) -{ - htab_traverse (map, debug_rename_map_1, NULL); -} - -/* Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW. */ - -static inline rename_map_elt -new_rename_map_elt (tree old_name, tree new_name) -{ - rename_map_elt res; - - res = XNEW (struct rename_map_elt_d); - res->old_name = old_name; - res->new_name = new_name; - - return res; -} - -/* Computes a hash function for database element ELT. */ - -static hashval_t -rename_map_elt_info (const void *elt) -{ - return htab_hash_pointer (((const struct rename_map_elt_d *) elt)->old_name); -} - -/* Compares database elements E1 and E2. */ - -static int -eq_rename_map_elts (const void *e1, const void *e2) -{ - const struct rename_map_elt_d *elt1 = (const struct rename_map_elt_d *) e1; - const struct rename_map_elt_d *elt2 = (const struct rename_map_elt_d *) e2; - - return (elt1->old_name == elt2->old_name); -} - -/* Returns the new name associated to OLD_NAME in MAP. */ - -static tree -get_new_name_from_old_name (htab_t map, tree old_name) -{ - struct rename_map_elt_d tmp; - PTR *slot; - - tmp.old_name = old_name; - slot = htab_find_slot (map, &tmp, NO_INSERT); - - if (slot && *slot) - return ((rename_map_elt) *slot)->new_name; - - return old_name; -} - - - -/* Creates a new scop starting with ENTRY. */ - -static scop_p -new_scop (edge entry, edge exit) -{ - scop_p scop = XNEW (struct scop); - - gcc_assert (entry && exit); - - SCOP_REGION (scop) = new_sese (entry, exit); - SCOP_BBS (scop) = VEC_alloc (graphite_bb_p, heap, 3); - SCOP_OLDIVS (scop) = VEC_alloc (name_tree, heap, 3); - SCOP_LOOPS (scop) = BITMAP_ALLOC (NULL); - SCOP_LOOP_NEST (scop) = VEC_alloc (loop_p, heap, 3); - SCOP_ADD_PARAMS (scop) = true; - SCOP_PARAMS (scop) = VEC_alloc (name_tree, heap, 3); - SCOP_PROG (scop) = cloog_program_malloc (); - cloog_program_set_names (SCOP_PROG (scop), cloog_names_malloc ()); - SCOP_LOOP2CLOOG_LOOP (scop) = htab_create (10, hash_loop_to_cloog_loop, - eq_loop_to_cloog_loop, - free); - SCOP_LIVEOUT_RENAMES (scop) = htab_create (10, rename_map_elt_info, - eq_rename_map_elts, free); - return scop; -} - -/* Deletes SCOP. */ - -static void -free_scop (scop_p scop) -{ - int i; - name_tree p; - struct graphite_bb *gb; - name_tree iv; - - for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++) - free_graphite_bb (gb); - - VEC_free (graphite_bb_p, heap, SCOP_BBS (scop)); - BITMAP_FREE (SCOP_LOOPS (scop)); - VEC_free (loop_p, heap, SCOP_LOOP_NEST (scop)); - - for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, iv); i++) - free (iv); - VEC_free (name_tree, heap, SCOP_OLDIVS (scop)); - - for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++) - free (p); - - VEC_free (name_tree, heap, SCOP_PARAMS (scop)); - cloog_program_free (SCOP_PROG (scop)); - htab_delete (SCOP_LOOP2CLOOG_LOOP (scop)); - htab_delete (SCOP_LIVEOUT_RENAMES (scop)); - free_sese (SCOP_REGION (scop)); - XDELETE (scop); -} - -/* Deletes all scops in SCOPS. */ - -static void -free_scops (VEC (scop_p, heap) *scops) -{ - int i; - scop_p scop; - - for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++) - free_scop (scop); - - VEC_free (scop_p, heap, scops); -} - -typedef enum gbb_type { - GBB_UNKNOWN, - GBB_LOOP_SING_EXIT_HEADER, - GBB_LOOP_MULT_EXIT_HEADER, - GBB_LOOP_EXIT, - GBB_COND_HEADER, - GBB_SIMPLE, - GBB_LAST -} gbb_type; - -/* Detect the type of BB. Loop headers are only marked, if they are - new. This means their loop_father is different to LAST_LOOP. - Otherwise they are treated like any other bb and their type can be - any other type. */ - -static gbb_type -get_bb_type (basic_block bb, struct loop *last_loop) -{ - VEC (basic_block, heap) *dom; - int nb_dom, nb_suc; - struct loop *loop = bb->loop_father; - - /* Check, if we entry into a new loop. */ - if (loop != last_loop) - { - if (single_exit (loop) != NULL) - return GBB_LOOP_SING_EXIT_HEADER; - else if (loop->num != 0) - return GBB_LOOP_MULT_EXIT_HEADER; - else - return GBB_COND_HEADER; - } - - dom = get_dominated_by (CDI_DOMINATORS, bb); - nb_dom = VEC_length (basic_block, dom); - VEC_free (basic_block, heap, dom); - - if (nb_dom == 0) - return GBB_LAST; - - nb_suc = VEC_length (edge, bb->succs); - - if (nb_dom == 1 && nb_suc == 1) - return GBB_SIMPLE; - - return GBB_COND_HEADER; -} - -/* A SCoP detection region, defined using bbs as borders. - All control flow touching this region, comes in passing basic_block ENTRY and - leaves passing basic_block EXIT. By using bbs instead of edges for the - borders we are able to represent also regions that do not have a single - entry or exit edge. - But as they have a single entry basic_block and a single exit basic_block, we - are able to generate for every sd_region a single entry and exit edge. - - 1 2 - \ / - 3 <- entry - | - 4 - / \ This region contains: {3, 4, 5, 6, 7, 8} - 5 6 - | | - 7 8 - \ / - 9 <- exit */ - - -typedef struct sd_region_p -{ - /* The entry bb dominates all bbs in the sd_region. It is part of the - region. */ - basic_block entry; - - /* The exit bb postdominates all bbs in the sd_region, but is not - part of the region. */ - basic_block exit; -} sd_region; - -DEF_VEC_O(sd_region); -DEF_VEC_ALLOC_O(sd_region, heap); - - -/* Moves the scops from SOURCE to TARGET and clean up SOURCE. */ - -static void -move_sd_regions (VEC (sd_region, heap) **source, VEC (sd_region, heap) **target) -{ - sd_region *s; - int i; - - for (i = 0; VEC_iterate (sd_region, *source, i, s); i++) - VEC_safe_push (sd_region, heap, *target, s); - - VEC_free (sd_region, heap, *source); -} - -/* Return true when it is not possible to represent the upper bound of - LOOP in the polyhedral representation. */ - -static bool -graphite_cannot_represent_loop_niter (loop_p loop) -{ - tree niter = number_of_latch_executions (loop); - - return chrec_contains_undetermined (niter) - || !scev_is_linear_expression (niter); -} -/* Store information needed by scopdet_* functions. */ - -struct scopdet_info -{ - /* Where the last open scop would stop if the current BB is harmful. */ - basic_block last; - - /* Where the next scop would start if the current BB is harmful. */ - basic_block next; - - /* The bb or one of its children contains open loop exits. That means - loop exit nodes that are not surrounded by a loop dominated by bb. */ - bool exits; - - /* The bb or one of its children contains only structures we can handle. */ - bool difficult; -}; - - -static struct scopdet_info build_scops_1 (basic_block, VEC (sd_region, heap) **, - loop_p); - -/* Calculates BB infos. If bb is difficult we add valid SCoPs dominated by BB - to SCOPS. TYPE is the gbb_type of BB. */ - -static struct scopdet_info -scopdet_basic_block_info (basic_block bb, VEC (sd_region, heap) **scops, - gbb_type type) -{ - struct loop *loop = bb->loop_father; - struct scopdet_info result; - gimple stmt; - - /* XXX: ENTRY_BLOCK_PTR could be optimized in later steps. */ - stmt = harmful_stmt_in_bb (ENTRY_BLOCK_PTR, bb); - result.difficult = (stmt != NULL); - result.last = NULL; - - switch (type) - { - case GBB_LAST: - result.next = NULL; - result.exits = false; - result.last = bb; - - /* Mark bbs terminating a SESE region difficult, if they start - a condition. */ - if (VEC_length (edge, bb->succs) > 1) - result.difficult = true; - - break; - - case GBB_SIMPLE: - result.next = single_succ (bb); - result.exits = false; - result.last = bb; - break; - - case GBB_LOOP_SING_EXIT_HEADER: - { - VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap,3); - struct scopdet_info sinfo; - - sinfo = build_scops_1 (bb, &tmp_scops, loop); - - result.last = single_exit (bb->loop_father)->src; - result.next = single_exit (bb->loop_father)->dest; - - /* If we do not dominate result.next, remove it. It's either - the EXIT_BLOCK_PTR, or another bb dominates it and will - call the scop detection for this bb. */ - if (!dominated_by_p (CDI_DOMINATORS, result.next, bb)) - result.next = NULL; - - if (result.last->loop_father != loop) - result.next = NULL; - - if (graphite_cannot_represent_loop_niter (loop)) - result.difficult = true; - - if (sinfo.difficult) - move_sd_regions (&tmp_scops, scops); - else - VEC_free (sd_region, heap, tmp_scops); - - result.exits = false; - result.difficult |= sinfo.difficult; - break; - } - - case GBB_LOOP_MULT_EXIT_HEADER: - { - /* XXX: For now we just do not join loops with multiple exits. If the - exits lead to the same bb it may be possible to join the loop. */ - VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap, 3); - VEC (edge, heap) *exits = get_loop_exit_edges (loop); - edge e; - int i; - build_scops_1 (bb, &tmp_scops, loop); - - /* Scan the code dominated by this loop. This means all bbs, that are - are dominated by a bb in this loop, but are not part of this loop. - - The easiest case: - - The loop exit destination is dominated by the exit sources. - - TODO: We miss here the more complex cases: - - The exit destinations are dominated by another bb inside the - loop. - - The loop dominates bbs, that are not exit destinations. */ - for (i = 0; VEC_iterate (edge, exits, i, e); i++) - if (e->src->loop_father == loop - && dominated_by_p (CDI_DOMINATORS, e->dest, e->src)) - { - /* Pass loop_outer to recognize e->dest as loop header in - build_scops_1. */ - if (e->dest->loop_father->header == e->dest) - build_scops_1 (e->dest, &tmp_scops, - loop_outer (e->dest->loop_father)); - else - build_scops_1 (e->dest, &tmp_scops, e->dest->loop_father); - } - - result.next = NULL; - result.last = NULL; - result.difficult = true; - result.exits = false; - move_sd_regions (&tmp_scops, scops); - VEC_free (edge, heap, exits); - break; - } - case GBB_COND_HEADER: - { - VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap, 3); - struct scopdet_info sinfo; - VEC (basic_block, heap) *dominated; - int i; - basic_block dom_bb; - basic_block last_bb = NULL; - edge e; - result.exits = false; - - /* First check the successors of BB, and check if it is possible to join - the different branches. */ - for (i = 0; VEC_iterate (edge, bb->succs, i, e); i++) - { - /* Ignore loop exits. They will be handled after the loop body. */ - if (is_loop_exit (loop, e->dest)) - { - result.exits = true; - continue; - } - - /* Do not follow edges that lead to the end of the - conditions block. For example, in - - | 0 - | /|\ - | 1 2 | - | | | | - | 3 4 | - | \|/ - | 6 - - the edge from 0 => 6. Only check if all paths lead to - the same node 6. */ - - if (!single_pred_p (e->dest)) - { - /* Check, if edge leads directly to the end of this - condition. */ - if (!last_bb) - { - last_bb = e->dest; - } - - if (e->dest != last_bb) - result.difficult = true; - - continue; - } - - if (!dominated_by_p (CDI_DOMINATORS, e->dest, bb)) - { - result.difficult = true; - continue; - } - - sinfo = build_scops_1 (e->dest, &tmp_scops, loop); - - result.exits |= sinfo.exits; - result.last = sinfo.last; - result.difficult |= sinfo.difficult; - - /* Checks, if all branches end at the same point. - If that is true, the condition stays joinable. - Have a look at the example above. */ - if (sinfo.last && single_succ_p (sinfo.last)) - { - basic_block next_tmp = single_succ (sinfo.last); - - if (!last_bb) - last_bb = next_tmp; - - if (next_tmp != last_bb) - result.difficult = true; - } - else - result.difficult = true; - } - - /* If the condition is joinable. */ - if (!result.exits && !result.difficult) - { - /* Only return a next pointer if we dominate this pointer. - Otherwise it will be handled by the bb dominating it. */ - if (dominated_by_p (CDI_DOMINATORS, last_bb, bb) && last_bb != bb) - result.next = last_bb; - else - result.next = NULL; - - VEC_free (sd_region, heap, tmp_scops); - break; - } - - /* Scan remaining bbs dominated by BB. */ - dominated = get_dominated_by (CDI_DOMINATORS, bb); - - for (i = 0; VEC_iterate (basic_block, dominated, i, dom_bb); i++) - { - /* Ignore loop exits: they will be handled after the loop body. */ - if (loop_depth (find_common_loop (loop, dom_bb->loop_father)) - < loop_depth (loop)) - { - result.exits = true; - continue; - } - - /* Ignore the bbs processed above. */ - if (single_pred_p (dom_bb) && single_pred (dom_bb) == bb) - continue; - - if (loop_depth (loop) > loop_depth (dom_bb->loop_father)) - sinfo = build_scops_1 (dom_bb, &tmp_scops, loop_outer (loop)); - else - sinfo = build_scops_1 (dom_bb, &tmp_scops, loop); - - - result.exits |= sinfo.exits; - result.difficult = true; - result.last = NULL; - } - - VEC_free (basic_block, heap, dominated); - - result.next = NULL; - move_sd_regions (&tmp_scops, scops); - - break; - } - - default: - gcc_unreachable (); - } - - return result; -} - -/* Creates the SCoPs and writes entry and exit points for every SCoP. */ - -static struct scopdet_info -build_scops_1 (basic_block current, VEC (sd_region, heap) **scops, loop_p loop) -{ - bool in_scop = false; - sd_region open_scop; - struct scopdet_info sinfo; - - /* Initialize result. */ - struct scopdet_info result; - result.exits = false; - result.difficult = false; - result.next = NULL; - result.last = NULL; - open_scop.entry = NULL; - open_scop.exit = NULL; - sinfo.last = NULL; - - /* Loop over the dominance tree. If we meet a difficult bb, close - the current SCoP. Loop and condition header start a new layer, - and can only be added if all bbs in deeper layers are simple. */ - while (current != NULL) - { - sinfo = scopdet_basic_block_info (current, scops, get_bb_type (current, - loop)); - - if (!in_scop && !(sinfo.exits || sinfo.difficult)) - { - open_scop.entry = current; - open_scop.exit = NULL; - in_scop = true; - } - else if (in_scop && (sinfo.exits || sinfo.difficult)) - { - open_scop.exit = current; - VEC_safe_push (sd_region, heap, *scops, &open_scop); - in_scop = false; - } - - result.difficult |= sinfo.difficult; - result.exits |= sinfo.exits; - - current = sinfo.next; - } - - /* Try to close open_scop, if we are still in an open SCoP. */ - if (in_scop) - { - int i; - edge e; - - for (i = 0; VEC_iterate (edge, sinfo.last->succs, i, e); i++) - if (dominated_by_p (CDI_POST_DOMINATORS, sinfo.last, e->dest)) - open_scop.exit = e->dest; - - if (!open_scop.exit && open_scop.entry != sinfo.last) - open_scop.exit = sinfo.last; - - if (open_scop.exit) - VEC_safe_push (sd_region, heap, *scops, &open_scop); - - } - - result.last = sinfo.last; - return result; -} - -/* Checks if a bb is contained in REGION. */ - -static bool -bb_in_sd_region (basic_block bb, sd_region *region) -{ - return dominated_by_p (CDI_DOMINATORS, bb, region->entry) - && !(dominated_by_p (CDI_DOMINATORS, bb, region->exit) - && !dominated_by_p (CDI_DOMINATORS, region->entry, - region->exit)); -} - -/* Returns the single entry edge of REGION, if it does not exits NULL. */ - -static edge -find_single_entry_edge (sd_region *region) -{ - edge e; - edge_iterator ei; - edge entry = NULL; - - FOR_EACH_EDGE (e, ei, region->entry->preds) - if (!bb_in_sd_region (e->src, region)) - { - if (entry) - { - entry = NULL; - break; - } - - else - entry = e; - } - - return entry; -} - -/* Returns the single exit edge of REGION, if it does not exits NULL. */ - -static edge -find_single_exit_edge (sd_region *region) -{ - edge e; - edge_iterator ei; - edge exit = NULL; - - FOR_EACH_EDGE (e, ei, region->exit->preds) - if (bb_in_sd_region (e->src, region)) - { - if (exit) - { - exit = NULL; - break; - } - - else - exit = e; - } - - return exit; -} - -/* Create a single entry edge for REGION. */ - -static void -create_single_entry_edge (sd_region *region) -{ - if (find_single_entry_edge (region)) - return; - - /* There are multiple predecessors for bb_3 - - | 1 2 - | | / - | |/ - | 3 <- entry - | |\ - | | | - | 4 ^ - | | | - | |/ - | 5 - - There are two edges (1->3, 2->3), that point from outside into the region, - and another one (5->3), a loop latch, lead to bb_3. - - We split bb_3. - - | 1 2 - | | / - | |/ - |3.0 - | |\ (3.0 -> 3.1) = single entry edge - |3.1 | <- entry - | | | - | | | - | 4 ^ - | | | - | |/ - | 5 - - If the loop is part of the SCoP, we have to redirect the loop latches. - - | 1 2 - | | / - | |/ - |3.0 - | | (3.0 -> 3.1) = entry edge - |3.1 <- entry - | |\ - | | | - | 4 ^ - | | | - | |/ - | 5 */ - - if (region->entry->loop_father->header != region->entry - || dominated_by_p (CDI_DOMINATORS, - loop_latch_edge (region->entry->loop_father)->src, - region->exit)) - { - edge forwarder = split_block_after_labels (region->entry); - region->entry = forwarder->dest; - } - else - /* This case is never executed, as the loop headers seem always to have a - single edge pointing from outside into the loop. */ - gcc_unreachable (); - -#ifdef ENABLE_CHECKING - gcc_assert (find_single_entry_edge (region)); -#endif -} - -/* Check if the sd_region, mentioned in EDGE, has no exit bb. */ - -static bool -sd_region_without_exit (edge e) -{ - sd_region *r = (sd_region *) e->aux; - - if (r) - return r->exit == NULL; - else - return false; -} - -/* Create a single exit edge for REGION. */ - -static void -create_single_exit_edge (sd_region *region) -{ - edge e; - edge_iterator ei; - edge forwarder = NULL; - basic_block exit; - - if (find_single_exit_edge (region)) - return; - - /* We create a forwarder bb (5) for all edges leaving this region - (3->5, 4->5). All other edges leading to the same bb, are moved - to a new bb (6). If these edges where part of another region (2->5) - we update the region->exit pointer, of this region. - - To identify which edge belongs to which region we depend on the e->aux - pointer in every edge. It points to the region of the edge or to NULL, - if the edge is not part of any region. - - 1 2 3 4 1->5 no region, 2->5 region->exit = 5, - \| |/ 3->5 region->exit = NULL, 4->5 region->exit = NULL - 5 <- exit - - changes to - - 1 2 3 4 1->6 no region, 2->6 region->exit = 6, - | | \/ 3->5 no region, 4->5 no region, - | | 5 - \| / 5->6 region->exit = 6 - 6 - - Now there is only a single exit edge (5->6). */ - exit = region->exit; - region->exit = NULL; - forwarder = make_forwarder_block (exit, &sd_region_without_exit, NULL); - - /* Unmark the edges, that are no longer exit edges. */ - FOR_EACH_EDGE (e, ei, forwarder->src->preds) - if (e->aux) - e->aux = NULL; - - /* Mark the new exit edge. */ - single_succ_edge (forwarder->src)->aux = region; - - /* Update the exit bb of all regions, where exit edges lead to - forwarder->dest. */ - FOR_EACH_EDGE (e, ei, forwarder->dest->preds) - if (e->aux) - ((sd_region *) e->aux)->exit = forwarder->dest; - -#ifdef ENABLE_CHECKING - gcc_assert (find_single_exit_edge (region)); -#endif -} - -/* Unmark the exit edges of all REGIONS. - See comment in "create_single_exit_edge". */ - -static void -unmark_exit_edges (VEC (sd_region, heap) *regions) -{ - int i; - sd_region *s; - edge e; - edge_iterator ei; - - for (i = 0; VEC_iterate (sd_region, regions, i, s); i++) - FOR_EACH_EDGE (e, ei, s->exit->preds) - e->aux = NULL; -} - - -/* Mark the exit edges of all REGIONS. - See comment in "create_single_exit_edge". */ - -static void -mark_exit_edges (VEC (sd_region, heap) *regions) -{ - int i; - sd_region *s; - edge e; - edge_iterator ei; - - for (i = 0; VEC_iterate (sd_region, regions, i, s); i++) - FOR_EACH_EDGE (e, ei, s->exit->preds) - if (bb_in_sd_region (e->src, s)) - e->aux = s; -} - -/* Free and compute again all the dominators information. */ - -static inline void -recompute_all_dominators (void) -{ - mark_irreducible_loops (); - free_dominance_info (CDI_DOMINATORS); - free_dominance_info (CDI_POST_DOMINATORS); - calculate_dominance_info (CDI_DOMINATORS); - calculate_dominance_info (CDI_POST_DOMINATORS); -} - -/* Verifies properties that GRAPHITE should maintain during translation. */ - -static inline void -graphite_verify (void) -{ -#ifdef ENABLE_CHECKING - verify_loop_structure (); - verify_dominators (CDI_DOMINATORS); - verify_dominators (CDI_POST_DOMINATORS); - verify_ssa (false); - verify_loop_closed_ssa (); -#endif -} - -/* Create for all scop regions a single entry and a single exit edge. */ - -static void -create_sese_edges (VEC (sd_region, heap) *regions) -{ - int i; - sd_region *s; - - for (i = 0; VEC_iterate (sd_region, regions, i, s); i++) - create_single_entry_edge (s); - - mark_exit_edges (regions); - - for (i = 0; VEC_iterate (sd_region, regions, i, s); i++) - create_single_exit_edge (s); - - unmark_exit_edges (regions); - - fix_loop_structure (NULL); - -#ifdef ENABLE_CHECKING - verify_loop_structure (); - verify_dominators (CDI_DOMINATORS); - verify_ssa (false); -#endif -} - -/* Create graphite SCoPs from an array of scop detection regions. */ - -static void -build_graphite_scops (VEC (sd_region, heap) *scop_regions) -{ - int i; - sd_region *s; - - for (i = 0; VEC_iterate (sd_region, scop_regions, i, s); i++) - { - edge entry = find_single_entry_edge (s); - edge exit = find_single_exit_edge (s); - scop_p scop = new_scop (entry, exit); - VEC_safe_push (scop_p, heap, current_scops, scop); - - /* Are there overlapping SCoPs? */ -#ifdef ENABLE_CHECKING - { - int j; - sd_region *s2; - - for (j = 0; VEC_iterate (sd_region, scop_regions, j, s2); j++) - if (s != s2) - gcc_assert (!bb_in_sd_region (s->entry, s2)); - } -#endif - } -} - -/* Find static control parts. */ - -static void -build_scops (void) -{ - struct loop *loop = current_loops->tree_root; - VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap, 3); - - build_scops_1 (single_succ (ENTRY_BLOCK_PTR), &tmp_scops, loop); - create_sese_edges (tmp_scops); - build_graphite_scops (tmp_scops); - VEC_free (sd_region, heap, tmp_scops); -} - -/* Gather the basic blocks belonging to the SCOP. */ - -static void -build_scop_bbs (scop_p scop) -{ - basic_block *stack = XNEWVEC (basic_block, n_basic_blocks + 1); - sbitmap visited = sbitmap_alloc (last_basic_block); - int sp = 0; - - sbitmap_zero (visited); - stack[sp++] = SCOP_ENTRY (scop); - - while (sp) - { - basic_block bb = stack[--sp]; - int depth = loop_depth (bb->loop_father); - int num = bb->loop_father->num; - edge_iterator ei; - edge e; - - /* Scop's exit is not in the scop. Exclude also bbs, which are - dominated by the SCoP exit. These are e.g. loop latches. */ - if (TEST_BIT (visited, bb->index) - || dominated_by_p (CDI_DOMINATORS, bb, SCOP_EXIT (scop)) - /* Every block in the scop is dominated by scop's entry. */ - || !dominated_by_p (CDI_DOMINATORS, bb, SCOP_ENTRY (scop))) + if (!bb_in_sese_p (bb, SCOP_REGION (scop))) continue; - new_graphite_bb (scop, bb); - SET_BIT (visited, bb->index); - - /* First push the blocks that have to be processed last. Note - that this means that the order in which the code is organized - below is important: do not reorder the following code. */ - FOR_EACH_EDGE (e, ei, bb->succs) - if (! TEST_BIT (visited, e->dest->index) - && (int) loop_depth (e->dest->loop_father) < depth) - stack[sp++] = e->dest; - - FOR_EACH_EDGE (e, ei, bb->succs) - if (! TEST_BIT (visited, e->dest->index) - && (int) loop_depth (e->dest->loop_father) == depth - && e->dest->loop_father->num != num) - stack[sp++] = e->dest; - - FOR_EACH_EDGE (e, ei, bb->succs) - if (! TEST_BIT (visited, e->dest->index) - && (int) loop_depth (e->dest->loop_father) == depth - && e->dest->loop_father->num == num - && EDGE_COUNT (e->dest->preds) > 1) - stack[sp++] = e->dest; - - FOR_EACH_EDGE (e, ei, bb->succs) - if (! TEST_BIT (visited, e->dest->index) - && (int) loop_depth (e->dest->loop_father) == depth - && e->dest->loop_father->num == num - && EDGE_COUNT (e->dest->preds) == 1) - stack[sp++] = e->dest; - - FOR_EACH_EDGE (e, ei, bb->succs) - if (! TEST_BIT (visited, e->dest->index) - && (int) loop_depth (e->dest->loop_father) > depth) - stack[sp++] = e->dest; - } - - free (stack); - sbitmap_free (visited); -} - -/* Returns the number of reduction phi nodes in LOOP. */ - -static int -nb_reductions_in_loop (loop_p loop) -{ - int res = 0; - gimple_stmt_iterator gsi; - - for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple phi = gsi_stmt (gsi); - tree scev; - affine_iv iv; - - if (!is_gimple_reg (PHI_RESULT (phi))) - continue; - - scev = analyze_scalar_evolution (loop, PHI_RESULT (phi)); - scev = instantiate_parameters (loop, scev); - if (!simple_iv (loop, loop, PHI_RESULT (phi), &iv, true)) - res++; - } - - return res; -} - -/* A LOOP is in normal form when it contains only one scalar phi node - that defines the main induction variable of the loop, only one - increment of the IV, and only one exit condition. */ - -static tree -graphite_loop_normal_form (loop_p loop) -{ - struct tree_niter_desc niter; - tree nit; - gimple_seq stmts; - edge exit = single_dom_exit (loop); - bool known_niter = number_of_iterations_exit (loop, exit, &niter, false); - - gcc_assert (known_niter); - - nit = force_gimple_operand (unshare_expr (niter.niter), &stmts, true, - NULL_TREE); - if (stmts) - gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts); - - /* One IV per loop. */ - if (nb_reductions_in_loop (loop) > 0) - return NULL_TREE; - - return canonicalize_loop_ivs (loop, NULL, &nit); -} - -/* Record LOOP as occuring in SCOP. Returns true when the operation - was successful. */ - -static bool -scop_record_loop (scop_p scop, loop_p loop) -{ - tree induction_var; - name_tree oldiv; - - if (bitmap_bit_p (SCOP_LOOPS (scop), loop->num)) - return true; - - bitmap_set_bit (SCOP_LOOPS (scop), loop->num); - VEC_safe_push (loop_p, heap, SCOP_LOOP_NEST (scop), loop); - - induction_var = graphite_loop_normal_form (loop); - if (!induction_var) - return false; - - oldiv = XNEW (struct name_tree_d); - oldiv->t = induction_var; - oldiv->name = get_name (SSA_NAME_VAR (oldiv->t)); - oldiv->loop = loop; - VEC_safe_push (name_tree, heap, SCOP_OLDIVS (scop), oldiv); - return true; -} - -/* Build the loop nests contained in SCOP. Returns true when the - operation was successful. */ - -static bool -build_scop_loop_nests (scop_p scop) -{ - unsigned i; - basic_block bb; - struct loop *loop0, *loop1; - - FOR_EACH_BB (bb) - if (bb_in_sese_p (bb, SCOP_REGION (scop))) - { - struct loop *loop = bb->loop_father; - - /* Only add loops if they are completely contained in the SCoP. */ - if (loop->header == bb - && bb_in_sese_p (loop->latch, SCOP_REGION (scop))) - { - if (!scop_record_loop (scop, loop)) - return false; - } - } - - /* Make sure that the loops in the SCOP_LOOP_NEST are ordered. It - can be the case that an inner loop is inserted before an outer - loop. To avoid this, semi-sort once. */ - for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop0); i++) - { - if (VEC_length (loop_p, SCOP_LOOP_NEST (scop)) == i + 1) - break; - - loop1 = VEC_index (loop_p, SCOP_LOOP_NEST (scop), i + 1); - if (loop0->num > loop1->num) - { - VEC_replace (loop_p, SCOP_LOOP_NEST (scop), i, loop1); - VEC_replace (loop_p, SCOP_LOOP_NEST (scop), i + 1, loop0); - } - } - - return true; -} + n_bbs++; + n_p_bbs += bb->count; -/* Calculate the number of loops around LOOP in the SCOP. */ - -static inline int -nb_loops_around_loop_in_scop (struct loop *l, scop_p scop) -{ - int d = 0; - - for (; loop_in_sese_p (l, SCOP_REGION (scop)); d++, l = loop_outer (l)); - - return d; -} - -/* Calculate the number of loops around GB in the current SCOP. */ - -int -nb_loops_around_gb (graphite_bb_p gb) -{ - return nb_loops_around_loop_in_scop (gbb_loop (gb), GBB_SCOP (gb)); -} - -/* Returns the dimensionality of an enclosing loop iteration domain - with respect to enclosing SCoP for a given data reference REF. The - returned dimensionality is homogeneous (depth of loop nest + number - of SCoP parameters + const). */ - -int -ref_nb_loops (data_reference_p ref) -{ - loop_p loop = loop_containing_stmt (DR_STMT (ref)); - scop_p scop = DR_SCOP (ref); - - return nb_loops_around_loop_in_scop (loop, scop) + scop_nb_params (scop) + 2; -} - -/* Build dynamic schedules for all the BBs. */ - -static void -build_scop_dynamic_schedules (scop_p scop) -{ - int i, dim, loop_num, row, col; - graphite_bb_p gb; - - for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++) - { - loop_num = GBB_BB (gb)->loop_father->num; - - if (loop_num != 0) - { - dim = nb_loops_around_gb (gb); - GBB_DYNAMIC_SCHEDULE (gb) = cloog_matrix_alloc (dim, dim); - - for (row = 0; row < GBB_DYNAMIC_SCHEDULE (gb)->NbRows; row++) - for (col = 0; col < GBB_DYNAMIC_SCHEDULE (gb)->NbColumns; col++) - if (row == col) - value_set_si (GBB_DYNAMIC_SCHEDULE (gb)->p[row][col], 1); - else - value_set_si (GBB_DYNAMIC_SCHEDULE (gb)->p[row][col], 0); - } - else - GBB_DYNAMIC_SCHEDULE (gb) = NULL; - } -} - -/* Returns the number of loops that are identical at the beginning of - the vectors A and B. */ - -static int -compare_prefix_loops (VEC (loop_p, heap) *a, VEC (loop_p, heap) *b) -{ - int i; - loop_p ea; - int lb; - - if (!a || !b) - return 0; - - lb = VEC_length (loop_p, b); - - for (i = 0; VEC_iterate (loop_p, a, i, ea); i++) - if (i >= lb - || ea != VEC_index (loop_p, b, i)) - return i; - - return 0; -} - -/* Build for BB the static schedule. - - The STATIC_SCHEDULE is defined like this: - - A - for (i: ...) - { - for (j: ...) - { - B - C - } - - for (k: ...) - { - D - E - } - } - F - - Static schedules for A to F: - - DEPTH - 0 1 2 - A 0 - B 1 0 0 - C 1 0 1 - D 1 1 0 - E 1 1 1 - F 2 -*/ - -static void -build_scop_canonical_schedules (scop_p scop) -{ - int i; - graphite_bb_p gb; - int nb_loops = scop_nb_loops (scop); - lambda_vector static_schedule = lambda_vector_new (nb_loops + 1); - VEC (loop_p, heap) *loops_previous = NULL; - - /* We have to start schedules at 0 on the first component and - because we cannot compare_prefix_loops against a previous loop, - prefix will be equal to zero, and that index will be - incremented before copying. */ - static_schedule[0] = -1; - - for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++) - { - int prefix = compare_prefix_loops (loops_previous, GBB_LOOPS (gb)); - int nb = gbb_nb_loops (gb); - - loops_previous = GBB_LOOPS (gb); - memset (&(static_schedule[prefix + 1]), 0, sizeof (int) * (nb_loops - prefix)); - ++static_schedule[prefix]; - GBB_STATIC_SCHEDULE (gb) = lambda_vector_new (nb + 1); - lambda_vector_copy (static_schedule, - GBB_STATIC_SCHEDULE (gb), nb + 1); - } -} - -/* Build the LOOPS vector for all bbs in SCOP. */ - -static void -build_bb_loops (scop_p scop) -{ - graphite_bb_p gb; - int i; - - for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++) - { - loop_p loop; - int depth; - - depth = nb_loops_around_gb (gb) - 1; - - GBB_LOOPS (gb) = VEC_alloc (loop_p, heap, 3); - VEC_safe_grow_cleared (loop_p, heap, GBB_LOOPS (gb), depth + 1); - - loop = GBB_BB (gb)->loop_father; - - while (scop_contains_loop (scop, loop)) - { - VEC_replace (loop_p, GBB_LOOPS (gb), depth, loop); - loop = loop_outer (loop); - depth--; - } - } -} - -/* Get the index for parameter VAR in SCOP. */ - -static int -param_index (tree var, scop_p scop) -{ - int i; - name_tree p; - name_tree nvar; - - gcc_assert (TREE_CODE (var) == SSA_NAME); - - for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++) - if (p->t == var) - return i; - - gcc_assert (SCOP_ADD_PARAMS (scop)); - - nvar = XNEW (struct name_tree_d); - nvar->t = var; - nvar->name = NULL; - VEC_safe_push (name_tree, heap, SCOP_PARAMS (scop), nvar); - return VEC_length (name_tree, SCOP_PARAMS (scop)) - 1; -} - -/* Scan EXPR and translate it to an inequality vector INEQ that will - be added, or subtracted, in the constraint domain matrix C at row - R. K is the number of columns for loop iterators in C. */ - -static void -scan_tree_for_params (scop_p s, tree e, CloogMatrix *c, int r, Value k, - bool subtract) -{ - int cst_col, param_col; - - if (e == chrec_dont_know) - return; - - switch (TREE_CODE (e)) - { - case POLYNOMIAL_CHREC: - { - tree left = CHREC_LEFT (e); - tree right = CHREC_RIGHT (e); - int var = CHREC_VARIABLE (e); - - if (TREE_CODE (right) != INTEGER_CST) - return; - - if (c) - { - int loop_col = scop_gimple_loop_depth (s, get_loop (var)) + 1; - - if (subtract) - value_sub_int (c->p[r][loop_col], c->p[r][loop_col], - int_cst_value (right)); - else - value_add_int (c->p[r][loop_col], c->p[r][loop_col], - int_cst_value (right)); - } - - switch (TREE_CODE (left)) - { - case POLYNOMIAL_CHREC: - scan_tree_for_params (s, left, c, r, k, subtract); - return; - - case INTEGER_CST: - /* Constant part. */ - if (c) - { - int v = int_cst_value (left); - cst_col = c->NbColumns - 1; - - if (v < 0) - { - v = -v; - subtract = subtract ? false : true; - } - - if (subtract) - value_sub_int (c->p[r][cst_col], c->p[r][cst_col], v); - else - value_add_int (c->p[r][cst_col], c->p[r][cst_col], v); - } - return; - - default: - scan_tree_for_params (s, left, c, r, k, subtract); - return; - } - } - break; - - case MULT_EXPR: - if (chrec_contains_symbols (TREE_OPERAND (e, 0))) - { - if (c) - { - Value val; - gcc_assert (host_integerp (TREE_OPERAND (e, 1), 0)); - value_init (val); - value_set_si (val, int_cst_value (TREE_OPERAND (e, 1))); - value_multiply (k, k, val); - value_clear (val); - } - scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract); - } - else + if (VEC_length (edge, bb->succs) > 1) { - if (c) - { - Value val; - gcc_assert (host_integerp (TREE_OPERAND (e, 0), 0)); - value_init (val); - value_set_si (val, int_cst_value (TREE_OPERAND (e, 0))); - value_multiply (k, k, val); - value_clear (val); - } - scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, subtract); + n_conditions++; + n_p_conditions += bb->count; } - break; - case PLUS_EXPR: - case POINTER_PLUS_EXPR: - scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract); - scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, subtract); - break; - - case MINUS_EXPR: - scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract); - scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, !subtract); - break; - - case NEGATE_EXPR: - scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, !subtract); - break; - - case SSA_NAME: - param_col = param_index (e, s); - - if (c) + for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi)) { - param_col += c->NbColumns - scop_nb_params (s) - 1; - - if (subtract) - value_subtract (c->p[r][param_col], c->p[r][param_col], k); - else - value_addto (c->p[r][param_col], c->p[r][param_col], k); + n_stmts++; + n_p_stmts += bb->count; } - break; - case INTEGER_CST: - if (c) + if (loop->header == bb && loop_in_sese_p (loop, SCOP_REGION (scop))) { - int v = int_cst_value (e); - cst_col = c->NbColumns - 1; - - if (v < 0) - { - v = -v; - subtract = subtract ? false : true; - } - - if (subtract) - value_sub_int (c->p[r][cst_col], c->p[r][cst_col], v); - else - value_add_int (c->p[r][cst_col], c->p[r][cst_col], v); + n_loops++; + n_p_loops += bb->count; } - break; - - CASE_CONVERT: - case NON_LVALUE_EXPR: - scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract); - break; - - default: - gcc_unreachable (); - break; } -} - -/* Data structure for idx_record_params. */ -struct irp_data -{ - struct loop *loop; - scop_p scop; -}; - -/* For a data reference with an ARRAY_REF as its BASE, record the - parameters occurring in IDX. DTA is passed in as complementary - information, and is used by the automatic walker function. This - function is a callback for for_each_index. */ - -static bool -idx_record_params (tree base, tree *idx, void *dta) -{ - struct irp_data *data = (struct irp_data *) dta; - - if (TREE_CODE (base) != ARRAY_REF) - return true; - - if (TREE_CODE (*idx) == SSA_NAME) - { - tree scev; - scop_p scop = data->scop; - struct loop *loop = data->loop; - Value one; - - scev = analyze_scalar_evolution (loop, *idx); - scev = instantiate_scev (block_before_scop (scop), loop, scev); - - value_init (one); - value_set_si (one, 1); - scan_tree_for_params (scop, scev, NULL, 0, one, false); - value_clear (one); - } - - return true; -} - -/* Find parameters with respect to SCOP in BB. We are looking in memory - access functions, conditions and loop bounds. */ - -static void -find_params_in_bb (scop_p scop, graphite_bb_p gb) -{ - int i; - data_reference_p dr; - gimple stmt; - loop_p father = GBB_BB (gb)->loop_father; - - for (i = 0; VEC_iterate (data_reference_p, GBB_DATA_REFS (gb), i, dr); i++) - { - struct irp_data irp; - - irp.loop = father; - irp.scop = scop; - for_each_index (&dr->ref, idx_record_params, &irp); - } - - /* Find parameters in conditional statements. */ - for (i = 0; VEC_iterate (gimple, GBB_CONDITIONS (gb), i, stmt); i++) - { - Value one; - loop_p loop = father; - - tree lhs, rhs; - - lhs = gimple_cond_lhs (stmt); - lhs = analyze_scalar_evolution (loop, lhs); - lhs = instantiate_scev (block_before_scop (scop), loop, lhs); - - rhs = gimple_cond_rhs (stmt); - rhs = analyze_scalar_evolution (loop, rhs); - rhs = instantiate_scev (block_before_scop (scop), loop, rhs); - - value_init (one); - scan_tree_for_params (scop, lhs, NULL, 0, one, false); - value_set_si (one, 1); - scan_tree_for_params (scop, rhs, NULL, 0, one, false); - value_clear (one); - } + fprintf (file, "\nSCoP statistics ("); + fprintf (file, "BBS:%ld, ", n_bbs); + fprintf (file, "LOOPS:%ld, ", n_loops); + fprintf (file, "CONDITIONS:%ld, ", n_conditions); + fprintf (file, "STMTS:%ld)\n", n_stmts); + fprintf (file, "\nSCoP profiling statistics ("); + fprintf (file, "BBS:%ld, ", n_p_bbs); + fprintf (file, "LOOPS:%ld, ", n_p_loops); + fprintf (file, "CONDITIONS:%ld, ", n_p_conditions); + fprintf (file, "STMTS:%ld)\n", n_p_stmts); } -/* Saves in NV the name of variable P->T. */ +/* Print statistics for SCOPS to FILE. */ static void -save_var_name (char **nv, int i, name_tree p) -{ - const char *name = get_name (SSA_NAME_VAR (p->t)); - - if (name) - { - int len = strlen (name) + 16; - nv[i] = XNEWVEC (char, len); - snprintf (nv[i], len, "%s_%d", name, SSA_NAME_VERSION (p->t)); - } - else - { - nv[i] = XNEWVEC (char, 16); - snprintf (nv[i], 2 + 16, "T_%d", SSA_NAME_VERSION (p->t)); - } - - p->name = nv[i]; -} - -/* Return the maximal loop depth in SCOP. */ - -static int -scop_max_loop_depth (scop_p scop) +print_graphite_statistics (FILE* file, VEC (scop_p, heap) *scops) { int i; - graphite_bb_p gbb; - int max_nb_loops = 0; - - for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++) - { - int nb_loops = gbb_nb_loops (gbb); - if (max_nb_loops < nb_loops) - max_nb_loops = nb_loops; - } - - return max_nb_loops; -} - -/* Initialize Cloog's parameter names from the names used in GIMPLE. - Initialize Cloog's iterator names, using 'graphite_iterator_%d' - from 0 to scop_nb_loops (scop). */ - -static void -initialize_cloog_names (scop_p scop) -{ - int i, nb_params = VEC_length (name_tree, SCOP_PARAMS (scop)); - char **params = XNEWVEC (char *, nb_params); - int nb_iterators = scop_max_loop_depth (scop); - int nb_scattering= cloog_program_nb_scattdims (SCOP_PROG (scop)); - char **iterators = XNEWVEC (char *, nb_iterators * 2); - char **scattering = XNEWVEC (char *, nb_scattering); - name_tree p; - - for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++) - save_var_name (params, i, p); - - cloog_names_set_nb_parameters (cloog_program_names (SCOP_PROG (scop)), - nb_params); - cloog_names_set_parameters (cloog_program_names (SCOP_PROG (scop)), - params); - for (i = 0; i < nb_iterators; i++) - { - int len = 18 + 16; - iterators[i] = XNEWVEC (char, len); - snprintf (iterators[i], len, "graphite_iterator_%d", i); - } - - cloog_names_set_nb_iterators (cloog_program_names (SCOP_PROG (scop)), - nb_iterators); - cloog_names_set_iterators (cloog_program_names (SCOP_PROG (scop)), - iterators); - - for (i = 0; i < nb_scattering; i++) - { - int len = 2 + 16; - scattering[i] = XNEWVEC (char, len); - snprintf (scattering[i], len, "s_%d", i); - } - - cloog_names_set_nb_scattering (cloog_program_names (SCOP_PROG (scop)), - nb_scattering); - cloog_names_set_scattering (cloog_program_names (SCOP_PROG (scop)), - scattering); -} - -/* Record the parameters used in the SCOP. A variable is a parameter - in a scop if it does not vary during the execution of that scop. */ - -static void -find_scop_parameters (scop_p scop) -{ - graphite_bb_p gb; - unsigned i; - struct loop *loop; - Value one; - - value_init (one); - value_set_si (one, 1); - - /* Find the parameters used in the loop bounds. */ - for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop); i++) - { - tree nb_iters = number_of_latch_executions (loop); - - if (!chrec_contains_symbols (nb_iters)) - continue; - - nb_iters = analyze_scalar_evolution (loop, nb_iters); - nb_iters = instantiate_scev (block_before_scop (scop), loop, nb_iters); - scan_tree_for_params (scop, nb_iters, NULL, 0, one, false); - } - - value_clear (one); - - /* Find the parameters used in data accesses. */ - for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++) - find_params_in_bb (scop, gb); - - SCOP_ADD_PARAMS (scop) = false; -} - -/* Build the context constraints for SCOP: constraints and relations - on parameters. */ - -static void -build_scop_context (scop_p scop) -{ - int nb_params = scop_nb_params (scop); - CloogMatrix *matrix = cloog_matrix_alloc (1, nb_params + 2); - - /* Insert '0 >= 0' in the context matrix, as it is not allowed to be - empty. */ - - value_set_si (matrix->p[0][0], 1); - - value_set_si (matrix->p[0][nb_params + 1], 0); - - cloog_program_set_context (SCOP_PROG (scop), - cloog_domain_matrix2domain (matrix)); - cloog_matrix_free (matrix); -} - -/* Returns a graphite_bb from BB. */ - -static inline graphite_bb_p -gbb_from_bb (basic_block bb) -{ - return (graphite_bb_p) bb->aux; -} - -/* Builds the constraint matrix for LOOP in SCOP. NB_OUTER_LOOPS is the - number of loops surrounding LOOP in SCOP. OUTER_CSTR gives the - constraints matrix for the surrounding loops. */ - -static void -build_loop_iteration_domains (scop_p scop, struct loop *loop, - CloogMatrix *outer_cstr, int nb_outer_loops) -{ - int i, j, row; - CloogMatrix *cstr; - graphite_bb_p gb; - - int nb_rows = outer_cstr->NbRows + 1; - int nb_cols = outer_cstr->NbColumns + 1; - - /* Last column of CSTR is the column of constants. */ - int cst_col = nb_cols - 1; - - /* The column for the current loop is just after the columns of - other outer loops. */ - int loop_col = nb_outer_loops + 1; - - tree nb_iters = number_of_latch_executions (loop); - - /* When the number of iterations is a constant or a parameter, we - add a constraint for the upper bound of the loop. So add a row - to the constraint matrix before allocating it. */ - if (TREE_CODE (nb_iters) == INTEGER_CST - || !chrec_contains_undetermined (nb_iters)) - nb_rows++; - - cstr = cloog_matrix_alloc (nb_rows, nb_cols); - - /* Copy the outer constraints. */ - for (i = 0; i < outer_cstr->NbRows; i++) - { - /* Copy the eq/ineq and loops columns. */ - for (j = 0; j < loop_col; j++) - value_assign (cstr->p[i][j], outer_cstr->p[i][j]); - - /* Leave an empty column in CSTR for the current loop, and then - copy the parameter columns. */ - for (j = loop_col; j < outer_cstr->NbColumns; j++) - value_assign (cstr->p[i][j + 1], outer_cstr->p[i][j]); - } - - /* 0 <= loop_i */ - row = outer_cstr->NbRows; - value_set_si (cstr->p[row][0], 1); - value_set_si (cstr->p[row][loop_col], 1); - - /* loop_i <= nb_iters */ - if (TREE_CODE (nb_iters) == INTEGER_CST) - { - row++; - value_set_si (cstr->p[row][0], 1); - value_set_si (cstr->p[row][loop_col], -1); - - value_set_si (cstr->p[row][cst_col], - int_cst_value (nb_iters)); - } - else if (!chrec_contains_undetermined (nb_iters)) - { - /* Otherwise nb_iters contains parameters: scan the nb_iters - expression and build its matrix representation. */ - Value one; - - row++; - value_set_si (cstr->p[row][0], 1); - value_set_si (cstr->p[row][loop_col], -1); - - nb_iters = analyze_scalar_evolution (loop, nb_iters); - nb_iters = instantiate_scev (block_before_scop (scop), loop, nb_iters); - - value_init (one); - value_set_si (one, 1); - scan_tree_for_params (scop, nb_iters, cstr, row, one, false); - value_clear (one); - } - else - gcc_unreachable (); - - if (loop->inner && loop_in_sese_p (loop->inner, SCOP_REGION (scop))) - build_loop_iteration_domains (scop, loop->inner, cstr, nb_outer_loops + 1); - - /* Only go to the next loops, if we are not at the outermost layer. These - have to be handled seperately, as we can be sure, that the chain at this - layer will be connected. */ - if (nb_outer_loops != 0 && loop->next && loop_in_sese_p (loop->next, - SCOP_REGION (scop))) - build_loop_iteration_domains (scop, loop->next, outer_cstr, nb_outer_loops); - - for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++) - if (gbb_loop (gb) == loop) - GBB_DOMAIN (gb) = cloog_matrix_copy (cstr); - - cloog_matrix_free (cstr); -} - -/* Add conditions to the domain of GB. */ - -static void -add_conditions_to_domain (graphite_bb_p gb) -{ - unsigned int i,j; - gimple stmt; - VEC (gimple, heap) *conditions = GBB_CONDITIONS (gb); - CloogMatrix *domain = GBB_DOMAIN (gb); - scop_p scop = GBB_SCOP (gb); - - unsigned nb_rows; - unsigned nb_cols; - unsigned nb_new_rows = 0; - unsigned row; - - if (VEC_empty (gimple, conditions)) - return; - - if (domain) - { - nb_rows = domain->NbRows; - nb_cols = domain->NbColumns; - } - else - { - nb_rows = 0; - nb_cols = nb_loops_around_gb (gb) + scop_nb_params (scop) + 2; - } - - /* Count number of necessary new rows to add the conditions to the - domain. */ - for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++) - { - switch (gimple_code (stmt)) - { - case GIMPLE_COND: - { - enum tree_code code = gimple_cond_code (stmt); - - switch (code) - { - case NE_EXPR: - case EQ_EXPR: - /* NE and EQ statements are not supported right know. */ - gcc_unreachable (); - break; - case LT_EXPR: - case GT_EXPR: - case LE_EXPR: - case GE_EXPR: - nb_new_rows++; - break; - default: - gcc_unreachable (); - break; - } - break; - } - case GIMPLE_SWITCH: - /* Switch statements are not supported right know. */ - gcc_unreachable (); - break; - - default: - gcc_unreachable (); - break; - } - } - - - /* Enlarge the matrix. */ - { - CloogMatrix *new_domain; - new_domain = cloog_matrix_alloc (nb_rows + nb_new_rows, nb_cols); - - if (domain) - { - for (i = 0; i < nb_rows; i++) - for (j = 0; j < nb_cols; j++) - value_assign (new_domain->p[i][j], domain->p[i][j]); - - cloog_matrix_free (domain); - } - - domain = new_domain; - GBB_DOMAIN (gb) = new_domain; - } - - /* Add the conditions to the new enlarged domain matrix. */ - row = nb_rows; - for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++) - { - switch (gimple_code (stmt)) - { - case GIMPLE_COND: - { - Value one; - enum tree_code code; - tree left; - tree right; - loop_p loop = GBB_BB (gb)->loop_father; - - left = gimple_cond_lhs (stmt); - right = gimple_cond_rhs (stmt); - - left = analyze_scalar_evolution (loop, left); - right = analyze_scalar_evolution (loop, right); - - left = instantiate_scev (block_before_scop (scop), loop, left); - right = instantiate_scev (block_before_scop (scop), loop, right); - - code = gimple_cond_code (stmt); - - /* The conditions for ELSE-branches are inverted. */ - if (VEC_index (gimple, gb->condition_cases, i) == NULL) - code = invert_tree_comparison (code, false); - - switch (code) - { - case NE_EXPR: - /* NE statements are not supported right know. */ - gcc_unreachable (); - break; - case EQ_EXPR: - value_set_si (domain->p[row][0], 1); - value_init (one); - value_set_si (one, 1); - scan_tree_for_params (scop, left, domain, row, one, true); - value_set_si (one, 1); - scan_tree_for_params (scop, right, domain, row, one, false); - row++; - value_set_si (domain->p[row][0], 1); - value_set_si (one, 1); - scan_tree_for_params (scop, left, domain, row, one, false); - value_set_si (one, 1); - scan_tree_for_params (scop, right, domain, row, one, true); - value_clear (one); - row++; - break; - case LT_EXPR: - value_set_si (domain->p[row][0], 1); - value_init (one); - value_set_si (one, 1); - scan_tree_for_params (scop, left, domain, row, one, true); - value_set_si (one, 1); - scan_tree_for_params (scop, right, domain, row, one, false); - value_sub_int (domain->p[row][nb_cols - 1], - domain->p[row][nb_cols - 1], 1); - value_clear (one); - row++; - break; - case GT_EXPR: - value_set_si (domain->p[row][0], 1); - value_init (one); - value_set_si (one, 1); - scan_tree_for_params (scop, left, domain, row, one, false); - value_set_si (one, 1); - scan_tree_for_params (scop, right, domain, row, one, true); - value_sub_int (domain->p[row][nb_cols - 1], - domain->p[row][nb_cols - 1], 1); - value_clear (one); - row++; - break; - case LE_EXPR: - value_set_si (domain->p[row][0], 1); - value_init (one); - value_set_si (one, 1); - scan_tree_for_params (scop, left, domain, row, one, true); - value_set_si (one, 1); - scan_tree_for_params (scop, right, domain, row, one, false); - value_clear (one); - row++; - break; - case GE_EXPR: - value_set_si (domain->p[row][0], 1); - value_init (one); - value_set_si (one, 1); - scan_tree_for_params (scop, left, domain, row, one, false); - value_set_si (one, 1); - scan_tree_for_params (scop, right, domain, row, one, true); - value_clear (one); - row++; - break; - default: - gcc_unreachable (); - break; - } - break; - } - case GIMPLE_SWITCH: - /* Switch statements are not supported right know. */ - gcc_unreachable (); - break; - - default: - gcc_unreachable (); - break; - } - } -} - -/* Returns true when PHI defines an induction variable in the loop - containing the PHI node. */ - -static bool -phi_node_is_iv (gimple phi) -{ - loop_p loop = gimple_bb (phi)->loop_father; - tree scev = analyze_scalar_evolution (loop, gimple_phi_result (phi)); - - return tree_contains_chrecs (scev, NULL); -} - -/* Returns true when BB contains scalar phi nodes that are not an - induction variable of a loop. */ - -static bool -bb_contains_non_iv_scalar_phi_nodes (basic_block bb) -{ - gimple phi = NULL; - gimple_stmt_iterator si; - - for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si)) - if (is_gimple_reg (gimple_phi_result (gsi_stmt (si)))) - { - /* Store the unique scalar PHI node: at this point, loops - should be in cannonical form, so we expect to see at most - one scalar phi node in the loop header. */ - if (phi - || bb != bb->loop_father->header) - return true; - - phi = gsi_stmt (si); - } - - if (!phi - || phi_node_is_iv (phi)) - return false; - - return true; -} - -/* Helper recursive function. Record in CONDITIONS and CASES all - conditions from 'if's and 'switch'es occurring in BB from SCOP. - - Returns false when the conditions contain scalar computations that - depend on the condition, i.e. when there are scalar phi nodes on - the junction after the condition. Only the computations occurring - on memory can be handled in the polyhedral model: operations that - define scalar evolutions in conditions, that can potentially be - used to index memory, can't be handled by the polyhedral model. */ - -static bool -build_scop_conditions_1 (VEC (gimple, heap) **conditions, - VEC (gimple, heap) **cases, basic_block bb, - scop_p scop) -{ - bool res = true; - int i, j; - graphite_bb_p gbb; - basic_block bb_child, bb_iter; - VEC (basic_block, heap) *dom; - gimple stmt; - - /* Make sure we are in the SCoP. */ - if (!bb_in_sese_p (bb, SCOP_REGION (scop))) - return true; - - if (bb_contains_non_iv_scalar_phi_nodes (bb)) - return false; - - gbb = gbb_from_bb (bb); - if (gbb) - { - GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions); - GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases); - } - - dom = get_dominated_by (CDI_DOMINATORS, bb); - - stmt = last_stmt (bb); - if (stmt) - { - VEC (edge, gc) *edges; - edge e; - - switch (gimple_code (stmt)) - { - case GIMPLE_COND: - edges = bb->succs; - for (i = 0; VEC_iterate (edge, edges, i, e); i++) - if ((dominated_by_p (CDI_DOMINATORS, e->dest, bb)) - && VEC_length (edge, e->dest->preds) == 1) - { - /* Remove the scanned block from the dominator successors. */ - for (j = 0; VEC_iterate (basic_block, dom, j, bb_iter); j++) - if (bb_iter == e->dest) - { - VEC_unordered_remove (basic_block, dom, j); - break; - } - - /* Recursively scan the then or else part. */ - if (e->flags & EDGE_TRUE_VALUE) - VEC_safe_push (gimple, heap, *cases, stmt); - else - { - gcc_assert (e->flags & EDGE_FALSE_VALUE); - VEC_safe_push (gimple, heap, *cases, NULL); - } - - VEC_safe_push (gimple, heap, *conditions, stmt); - if (!build_scop_conditions_1 (conditions, cases, e->dest, scop)) - { - res = false; - goto done; - } - VEC_pop (gimple, *conditions); - VEC_pop (gimple, *cases); - } - break; - - case GIMPLE_SWITCH: - { - unsigned i; - gimple_stmt_iterator gsi_search_gimple_label; - - for (i = 0; i < gimple_switch_num_labels (stmt); ++i) - { - basic_block bb_iter; - size_t k; - size_t n_cases = VEC_length (gimple, *conditions); - unsigned n = gimple_switch_num_labels (stmt); - - bb_child = label_to_block - (CASE_LABEL (gimple_switch_label (stmt, i))); - - for (k = 0; k < n; k++) - if (i != k - && label_to_block - (CASE_LABEL (gimple_switch_label (stmt, k))) == bb_child) - break; - - /* Switches with multiple case values for the same - block are not handled. */ - if (k != n - /* Switch cases with more than one predecessor are - not handled. */ - || VEC_length (edge, bb_child->preds) != 1) - { - res = false; - goto done; - } - - /* Recursively scan the corresponding 'case' block. */ - for (gsi_search_gimple_label = gsi_start_bb (bb_child); - !gsi_end_p (gsi_search_gimple_label); - gsi_next (&gsi_search_gimple_label)) - { - gimple label = gsi_stmt (gsi_search_gimple_label); - - if (gimple_code (label) == GIMPLE_LABEL) - { - tree t = gimple_label_label (label); - - gcc_assert (t == gimple_switch_label (stmt, i)); - VEC_replace (gimple, *cases, n_cases, label); - break; - } - } - - if (!build_scop_conditions_1 (conditions, cases, bb_child, scop)) - { - res = false; - goto done; - } - - /* Remove the scanned block from the dominator successors. */ - for (j = 0; VEC_iterate (basic_block, dom, j, bb_iter); j++) - if (bb_iter == bb_child) - { - VEC_unordered_remove (basic_block, dom, j); - break; - } - } - - VEC_pop (gimple, *conditions); - VEC_pop (gimple, *cases); - break; - } - - default: - break; - } - } - - /* Scan all immediate dominated successors. */ - for (i = 0; VEC_iterate (basic_block, dom, i, bb_child); i++) - if (!build_scop_conditions_1 (conditions, cases, bb_child, scop)) - { - res = false; - goto done; - } - - done: - VEC_free (basic_block, heap, dom); - return res; -} - -/* Record all conditions from SCOP. - - Returns false when the conditions contain scalar computations that - depend on the condition, i.e. when there are scalar phi nodes on - the junction after the condition. Only the computations occurring - on memory can be handled in the polyhedral model: operations that - define scalar evolutions in conditions, that can potentially be - used to index memory, can't be handled by the polyhedral model. */ - -static bool -build_scop_conditions (scop_p scop) -{ - bool res; - VEC (gimple, heap) *conditions = NULL; - VEC (gimple, heap) *cases = NULL; - - res = build_scop_conditions_1 (&conditions, &cases, SCOP_ENTRY (scop), scop); - - VEC_free (gimple, heap, conditions); - VEC_free (gimple, heap, cases); - return res; -} - -/* Traverses all the GBBs of the SCOP and add their constraints to the - iteration domains. */ - -static void -add_conditions_to_constraints (scop_p scop) -{ - int i; - graphite_bb_p gbb; - - for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++) - add_conditions_to_domain (gbb); -} - -/* Build the current domain matrix: the loops belonging to the current - SCOP, and that vary for the execution of the current basic block. - Returns false if there is no loop in SCOP. */ - -static bool -build_scop_iteration_domain (scop_p scop) -{ - struct loop *loop; - CloogMatrix *outer_cstr; - int i; - - /* Build cloog loop for all loops, that are in the uppermost loop layer of - this SCoP. */ - for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop); i++) - if (!loop_in_sese_p (loop_outer (loop), SCOP_REGION (scop))) - { - /* The outermost constraints is a matrix that has: - -first column: eq/ineq boolean - -last column: a constant - -scop_nb_params columns for the parameters used in the scop. */ - outer_cstr = cloog_matrix_alloc (0, scop_nb_params (scop) + 2); - build_loop_iteration_domains (scop, loop, outer_cstr, 0); - cloog_matrix_free (outer_cstr); - } + scop_p scop; - return (i != 0); + for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++) + print_graphite_scop_statistics (file, scop); } -/* Initializes an equation CY of the access matrix using the - information for a subscript from AF, relatively to the loop - indexes from LOOP_NEST and parameter indexes from PARAMS. NDIM is - the dimension of the array access, i.e. the number of - subscripts. Returns true when the operation succeeds. */ +/* Initialize graphite: when there are no loops returns false. */ static bool -build_access_matrix_with_af (tree af, lambda_vector cy, - scop_p scop, int ndim) +graphite_initialize (void) { - int param_col; - - switch (TREE_CODE (af)) + if (number_of_loops () <= 1) { - case POLYNOMIAL_CHREC: - { - struct loop *outer_loop; - tree left = CHREC_LEFT (af); - tree right = CHREC_RIGHT (af); - int var; - - if (TREE_CODE (right) != INTEGER_CST) - return false; - - outer_loop = get_loop (CHREC_VARIABLE (af)); - var = nb_loops_around_loop_in_scop (outer_loop, scop); - cy[var] = int_cst_value (right); - - switch (TREE_CODE (left)) - { - case POLYNOMIAL_CHREC: - return build_access_matrix_with_af (left, cy, scop, ndim); - - case INTEGER_CST: - cy[ndim - 1] = int_cst_value (left); - return true; - - default: - return build_access_matrix_with_af (left, cy, scop, ndim); - } - } - - case PLUS_EXPR: - build_access_matrix_with_af (TREE_OPERAND (af, 0), cy, scop, ndim); - build_access_matrix_with_af (TREE_OPERAND (af, 1), cy, scop, ndim); - return true; - - case MINUS_EXPR: - build_access_matrix_with_af (TREE_OPERAND (af, 0), cy, scop, ndim); - build_access_matrix_with_af (TREE_OPERAND (af, 1), cy, scop, ndim); - return true; - - case INTEGER_CST: - cy[ndim - 1] = int_cst_value (af); - return true; - - case SSA_NAME: - param_col = param_index (af, scop); - cy [ndim - scop_nb_params (scop) + param_col - 1] = 1; - return true; + if (dump_file && (dump_flags & TDF_DETAILS)) + print_global_statistics (dump_file); - default: - /* FIXME: access_fn can have parameters. */ return false; } -} - -/* Initialize the access matrix in the data reference REF with respect - to the loop nesting LOOP_NEST. Return true when the operation - succeeded. */ - -static bool -build_access_matrix (data_reference_p ref, graphite_bb_p gb) -{ - int i, ndim = DR_NUM_DIMENSIONS (ref); - struct access_matrix *am = GGC_NEW (struct access_matrix); - - AM_MATRIX (am) = VEC_alloc (lambda_vector, gc, ndim); - DR_SCOP (ref) = GBB_SCOP (gb); - - for (i = 0; i < ndim; i++) - { - lambda_vector v = lambda_vector_new (ref_nb_loops (ref)); - scop_p scop = GBB_SCOP (gb); - tree af = DR_ACCESS_FN (ref, i); - - if (!build_access_matrix_with_af (af, v, scop, ref_nb_loops (ref))) - return false; - - VEC_quick_push (lambda_vector, AM_MATRIX (am), v); - } - - DR_ACCESS_MATRIX (ref) = am; - return true; -} - -/* Build the access matrices for the data references in the SCOP. */ - -static void -build_scop_data_accesses (scop_p scop) -{ - int i; - graphite_bb_p gb; - - /* FIXME: Construction of access matrix is disabled until some - pass, like the data dependence analysis, is using it. */ - return; - - for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++) - { - int j; - data_reference_p dr; - - /* Construct the access matrix for each data ref, with respect to - the loop nest of the current BB in the considered SCOP. */ - for (j = 0; - VEC_iterate (data_reference_p, GBB_DATA_REFS (gb), j, dr); - j++) - { - bool res = build_access_matrix (dr, gb); - - /* FIXME: At this point the DRs should always have an affine - form. For the moment this fails as build_access_matrix - does not build matrices with parameters. */ - gcc_assert (res); - } - } -} - -/* Returns the tree variable from the name NAME that was given in - Cloog representation. All the parameters are stored in PARAMS, and - all the loop induction variables are stored in IVSTACK. - - FIXME: This is a hack, and Cloog should be fixed to not work with - variable names represented as "char *string", but with void - pointers that could be casted back to a tree. The only problem in - doing that is that Cloog's pretty printer still assumes that - variable names are char *strings. The solution would be to have a - function pointer for pretty-printing that can be redirected to be - print_generic_stmt in our case, or fprintf by default. - ??? Too ugly to live. */ - -static tree -clast_name_to_gcc (const char *name, VEC (name_tree, heap) *params, - loop_iv_stack ivstack) -{ - int i; - name_tree t; - tree iv; - - if (params) - for (i = 0; VEC_iterate (name_tree, params, i, t); i++) - if (!strcmp (name, t->name)) - return t->t; - - iv = loop_iv_stack_get_iv_from_name (ivstack, name); - if (iv) - return iv; - - gcc_unreachable (); -} - -/* Returns the maximal precision type for expressions E1 and E2. */ - -static inline tree -max_precision_type (tree e1, tree e2) -{ - tree type1 = TREE_TYPE (e1); - tree type2 = TREE_TYPE (e2); - return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2; -} - -static tree -clast_to_gcc_expression (tree, struct clast_expr *, VEC (name_tree, heap) *, - loop_iv_stack); - -/* Converts a Cloog reduction expression R with reduction operation OP - to a GCC expression tree of type TYPE. PARAMS is a vector of - parameters of the scop, and IVSTACK contains the stack of induction - variables. */ - -static tree -clast_to_gcc_expression_red (tree type, enum tree_code op, - struct clast_reduction *r, - VEC (name_tree, heap) *params, - loop_iv_stack ivstack) -{ - int i; - tree res = clast_to_gcc_expression (type, r->elts[0], params, ivstack); - - for (i = 1; i < r->n; i++) - { - tree t = clast_to_gcc_expression (type, r->elts[i], params, ivstack); - res = fold_build2 (op, type, res, t); - } - return res; -} - -/* Converts a Cloog AST expression E back to a GCC expression tree of - type TYPE. PARAMS is a vector of parameters of the scop, and - IVSTACK contains the stack of induction variables. */ - -static tree -clast_to_gcc_expression (tree type, struct clast_expr *e, - VEC (name_tree, heap) *params, - loop_iv_stack ivstack) -{ - switch (e->type) - { - case expr_term: - { - struct clast_term *t = (struct clast_term *) e; - - if (t->var) - { - if (value_one_p (t->val)) - { - tree name = clast_name_to_gcc (t->var, params, ivstack); - return fold_convert (type, name); - } - - else if (value_mone_p (t->val)) - { - tree name = clast_name_to_gcc (t->var, params, ivstack); - name = fold_convert (type, name); - return fold_build1 (NEGATE_EXPR, type, name); - } - else - { - tree name = clast_name_to_gcc (t->var, params, ivstack); - tree cst = gmp_cst_to_tree (type, t->val); - name = fold_convert (type, name); - return fold_build2 (MULT_EXPR, type, cst, name); - } - } - else - return gmp_cst_to_tree (type, t->val); - } - - case expr_red: - { - struct clast_reduction *r = (struct clast_reduction *) e; - - switch (r->type) - { - case clast_red_sum: - return clast_to_gcc_expression_red (type, PLUS_EXPR, r, params, ivstack); - - case clast_red_min: - return clast_to_gcc_expression_red (type, MIN_EXPR, r, params, ivstack); - - case clast_red_max: - return clast_to_gcc_expression_red (type, MAX_EXPR, r, params, ivstack); - - default: - gcc_unreachable (); - } - break; - } - - case expr_bin: - { - struct clast_binary *b = (struct clast_binary *) e; - struct clast_expr *lhs = (struct clast_expr *) b->LHS; - tree tl = clast_to_gcc_expression (type, lhs, params, ivstack); - tree tr = gmp_cst_to_tree (type, b->RHS); - - switch (b->type) - { - case clast_bin_fdiv: - return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr); - - case clast_bin_cdiv: - return fold_build2 (CEIL_DIV_EXPR, type, tl, tr); - - case clast_bin_div: - return fold_build2 (EXACT_DIV_EXPR, type, tl, tr); - - case clast_bin_mod: - return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr); - - default: - gcc_unreachable (); - } - } - - default: - gcc_unreachable (); - } - - return NULL_TREE; -} - -/* Returns the type for the expression E. */ - -static tree -gcc_type_for_clast_expr (struct clast_expr *e, - VEC (name_tree, heap) *params, - loop_iv_stack ivstack) -{ - switch (e->type) - { - case expr_term: - { - struct clast_term *t = (struct clast_term *) e; - - if (t->var) - return TREE_TYPE (clast_name_to_gcc (t->var, params, ivstack)); - else - return NULL_TREE; - } - - case expr_red: - { - struct clast_reduction *r = (struct clast_reduction *) e; - - if (r->n == 1) - return gcc_type_for_clast_expr (r->elts[0], params, ivstack); - else - { - int i; - for (i = 0; i < r->n; i++) - { - tree type = gcc_type_for_clast_expr (r->elts[i], params, ivstack); - if (type) - return type; - } - return NULL_TREE; - } - } - - case expr_bin: - { - struct clast_binary *b = (struct clast_binary *) e; - struct clast_expr *lhs = (struct clast_expr *) b->LHS; - return gcc_type_for_clast_expr (lhs, params, ivstack); - } - - default: - gcc_unreachable (); - } - - return NULL_TREE; -} - -/* Returns the type for the equation CLEQ. */ - -static tree -gcc_type_for_clast_eq (struct clast_equation *cleq, - VEC (name_tree, heap) *params, - loop_iv_stack ivstack) -{ - tree type = gcc_type_for_clast_expr (cleq->LHS, params, ivstack); - if (type) - return type; - - return gcc_type_for_clast_expr (cleq->RHS, params, ivstack); -} - -/* Translates a clast equation CLEQ to a tree. */ - -static tree -graphite_translate_clast_equation (scop_p scop, - struct clast_equation *cleq, - loop_iv_stack ivstack) -{ - enum tree_code comp; - tree type = gcc_type_for_clast_eq (cleq, SCOP_PARAMS (scop), ivstack); - tree lhs = clast_to_gcc_expression (type, cleq->LHS, SCOP_PARAMS (scop), ivstack); - tree rhs = clast_to_gcc_expression (type, cleq->RHS, SCOP_PARAMS (scop), ivstack); - - if (cleq->sign == 0) - comp = EQ_EXPR; - - else if (cleq->sign > 0) - comp = GE_EXPR; - - else - comp = LE_EXPR; - - return fold_build2 (comp, type, lhs, rhs); -} - -/* Creates the test for the condition in STMT. */ - -static tree -graphite_create_guard_cond_expr (scop_p scop, struct clast_guard *stmt, - loop_iv_stack ivstack) -{ - tree cond = NULL; - int i; - - for (i = 0; i < stmt->n; i++) - { - tree eq = graphite_translate_clast_equation (scop, &stmt->eq[i], ivstack); - - if (cond) - cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq); - else - cond = eq; - } - - return cond; -} - -/* Creates a new if region corresponding to Cloog's guard. */ - -static edge -graphite_create_new_guard (scop_p scop, edge entry_edge, - struct clast_guard *stmt, - loop_iv_stack ivstack) -{ - tree cond_expr = graphite_create_guard_cond_expr (scop, stmt, ivstack); - edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr); - return exit_edge; -} - -/* Walks a CLAST and returns the first statement in the body of a - loop. */ - -static struct clast_user_stmt * -clast_get_body_of_loop (struct clast_stmt *stmt) -{ - if (!stmt - || CLAST_STMT_IS_A (stmt, stmt_user)) - return (struct clast_user_stmt *) stmt; - - if (CLAST_STMT_IS_A (stmt, stmt_for)) - return clast_get_body_of_loop (((struct clast_for *) stmt)->body); - - if (CLAST_STMT_IS_A (stmt, stmt_guard)) - return clast_get_body_of_loop (((struct clast_guard *) stmt)->then); - - if (CLAST_STMT_IS_A (stmt, stmt_block)) - return clast_get_body_of_loop (((struct clast_block *) stmt)->body); - - gcc_unreachable (); -} - -/* Returns the induction variable for the loop that gets translated to - STMT. */ - -static tree -gcc_type_for_iv_of_clast_loop (struct clast_for *stmt_for) -{ - struct clast_user_stmt *stmt = clast_get_body_of_loop ((struct clast_stmt *) stmt_for); - const char *cloog_iv = stmt_for->iterator; - CloogStatement *cs = stmt->statement; - graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs); - - return gcc_type_for_cloog_iv (cloog_iv, gbb); -} - -/* Creates a new LOOP corresponding to Cloog's STMT. Inserts an induction - variable for the new LOOP. New LOOP is attached to CFG starting at - ENTRY_EDGE. LOOP is inserted into the loop tree and becomes the child - loop of the OUTER_LOOP. */ - -static struct loop * -graphite_create_new_loop (scop_p scop, edge entry_edge, - struct clast_for *stmt, loop_iv_stack ivstack, - loop_p outer) -{ - tree type = gcc_type_for_iv_of_clast_loop (stmt); - VEC (name_tree, heap) *params = SCOP_PARAMS (scop); - tree lb = clast_to_gcc_expression (type, stmt->LB, params, ivstack); - tree ub = clast_to_gcc_expression (type, stmt->UB, params, ivstack); - tree stride = gmp_cst_to_tree (type, stmt->stride); - tree ivvar = create_tmp_var (type, "graphiteIV"); - tree iv_before; - loop_p loop = create_empty_loop_on_edge - (entry_edge, lb, stride, ub, ivvar, &iv_before, - outer ? outer : entry_edge->src->loop_father); - - add_referenced_var (ivvar); - loop_iv_stack_push_iv (ivstack, iv_before, stmt->iterator); - return loop; -} - -/* Rename the SSA_NAMEs used in STMT and that appear in IVSTACK. */ - -static void -rename_variables_in_stmt (gimple stmt, htab_t map) -{ - ssa_op_iter iter; - use_operand_p use_p; - - FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES) - { - tree use = USE_FROM_PTR (use_p); - tree new_name = get_new_name_from_old_name (map, use); - - replace_exp (use_p, new_name); - } - - update_stmt (stmt); -} - -/* Returns true if SSA_NAME is a parameter of SCOP. */ - -static bool -is_parameter (scop_p scop, tree ssa_name) -{ - int i; - VEC (name_tree, heap) *params = SCOP_PARAMS (scop); - name_tree param; - - for (i = 0; VEC_iterate (name_tree, params, i, param); i++) - if (param->t == ssa_name) - return true; - - return false; -} - -/* Returns true if NAME is an induction variable. */ - -static bool -is_iv (tree name) -{ - return gimple_code (SSA_NAME_DEF_STMT (name)) == GIMPLE_PHI; -} - -static void expand_scalar_variables_stmt (gimple, basic_block, scop_p, - htab_t); -static tree -expand_scalar_variables_expr (tree, tree, enum tree_code, tree, basic_block, - scop_p, htab_t, gimple_stmt_iterator *); - -/* Copies at GSI all the scalar computations on which the ssa_name OP0 - depends on in the SCOP: these are all the scalar variables used in - the definition of OP0, that are defined outside BB and still in the - SCOP, i.e. not a parameter of the SCOP. The expression that is - returned contains only induction variables from the generated code: - MAP contains the induction variables renaming mapping, and is used - to translate the names of induction variables. */ - -static tree -expand_scalar_variables_ssa_name (tree op0, basic_block bb, - scop_p scop, htab_t map, - gimple_stmt_iterator *gsi) -{ - tree var0, var1, type; - gimple def_stmt; - enum tree_code subcode; - - if (is_parameter (scop, op0) - || is_iv (op0)) - return get_new_name_from_old_name (map, op0); - - def_stmt = SSA_NAME_DEF_STMT (op0); - - if (gimple_bb (def_stmt) == bb) - { - /* If the defining statement is in the basic block already - we do not need to create a new expression for it, we - only need to ensure its operands are expanded. */ - expand_scalar_variables_stmt (def_stmt, bb, scop, map); - return get_new_name_from_old_name (map, op0); - } - else - { - if (gimple_code (def_stmt) != GIMPLE_ASSIGN - || !bb_in_sese_p (gimple_bb (def_stmt), SCOP_REGION (scop))) - return get_new_name_from_old_name (map, op0); - - var0 = gimple_assign_rhs1 (def_stmt); - subcode = gimple_assign_rhs_code (def_stmt); - var1 = gimple_assign_rhs2 (def_stmt); - type = gimple_expr_type (def_stmt); - - return expand_scalar_variables_expr (type, var0, subcode, var1, bb, scop, - map, gsi); - } -} - -/* Copies at GSI all the scalar computations on which the expression - OP0 CODE OP1 depends on in the SCOP: these are all the scalar - variables used in OP0 and OP1, defined outside BB and still defined - in the SCOP, i.e. not a parameter of the SCOP. The expression that - is returned contains only induction variables from the generated - code: MAP contains the induction variables renaming mapping, and is - used to translate the names of induction variables. */ - -static tree -expand_scalar_variables_expr (tree type, tree op0, enum tree_code code, - tree op1, basic_block bb, scop_p scop, - htab_t map, gimple_stmt_iterator *gsi) -{ - if (TREE_CODE_CLASS (code) == tcc_constant - || TREE_CODE_CLASS (code) == tcc_declaration) - return op0; - - /* For data references we have to duplicate also its memory - indexing. */ - if (TREE_CODE_CLASS (code) == tcc_reference) - { - switch (code) - { - case INDIRECT_REF: - { - tree old_name = TREE_OPERAND (op0, 0); - tree expr = expand_scalar_variables_ssa_name - (old_name, bb, scop, map, gsi); - tree new_name = force_gimple_operand_gsi (gsi, expr, true, NULL, - true, GSI_SAME_STMT); - - return fold_build1 (code, type, new_name); - } - - case ARRAY_REF: - { - tree op00 = TREE_OPERAND (op0, 0); - tree op01 = TREE_OPERAND (op0, 1); - tree op02 = TREE_OPERAND (op0, 2); - tree op03 = TREE_OPERAND (op0, 3); - tree base = expand_scalar_variables_expr - (TREE_TYPE (op00), op00, TREE_CODE (op00), NULL, bb, scop, - map, gsi); - tree subscript = expand_scalar_variables_expr - (TREE_TYPE (op01), op01, TREE_CODE (op01), NULL, bb, scop, - map, gsi); - - return build4 (ARRAY_REF, type, base, subscript, op02, op03); - } - - default: - /* The above cases should catch everything. */ - gcc_unreachable (); - } - } - - if (TREE_CODE_CLASS (code) == tcc_unary) - { - tree op0_type = TREE_TYPE (op0); - enum tree_code op0_code = TREE_CODE (op0); - tree op0_expr = expand_scalar_variables_expr (op0_type, op0, op0_code, - NULL, bb, scop, map, gsi); - - return fold_build1 (code, type, op0_expr); - } - - if (TREE_CODE_CLASS (code) == tcc_binary) - { - tree op0_type = TREE_TYPE (op0); - enum tree_code op0_code = TREE_CODE (op0); - tree op0_expr = expand_scalar_variables_expr (op0_type, op0, op0_code, - NULL, bb, scop, map, gsi); - tree op1_type = TREE_TYPE (op1); - enum tree_code op1_code = TREE_CODE (op1); - tree op1_expr = expand_scalar_variables_expr (op1_type, op1, op1_code, - NULL, bb, scop, map, gsi); - - return fold_build2 (code, type, op0_expr, op1_expr); - } - - if (code == SSA_NAME) - return expand_scalar_variables_ssa_name (op0, bb, scop, map, gsi); - - gcc_unreachable (); - return NULL; -} - -/* Copies at the beginning of BB all the scalar computations on which - STMT depends on in the SCOP: these are all the scalar variables used - in STMT, defined outside BB and still defined in the SCOP, i.e. not a - parameter of the SCOP. The expression that is returned contains - only induction variables from the generated code: MAP contains the - induction variables renaming mapping, and is used to translate the - names of induction variables. */ - -static void -expand_scalar_variables_stmt (gimple stmt, basic_block bb, scop_p scop, - htab_t map) -{ - ssa_op_iter iter; - use_operand_p use_p; - gimple_stmt_iterator gsi = gsi_after_labels (bb); - - FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE) - { - tree use = USE_FROM_PTR (use_p); - tree type = TREE_TYPE (use); - enum tree_code code = TREE_CODE (use); - tree use_expr = expand_scalar_variables_expr (type, use, code, NULL, bb, - scop, map, &gsi); - if (use_expr != use) - { - tree new_use = - force_gimple_operand_gsi (&gsi, use_expr, true, NULL, - true, GSI_NEW_STMT); - replace_exp (use_p, new_use); - } - } - - update_stmt (stmt); -} - -/* Copies at the beginning of BB all the scalar computations on which - BB depends on in the SCOP: these are all the scalar variables used - in BB, defined outside BB and still defined in the SCOP, i.e. not a - parameter of the SCOP. The expression that is returned contains - only induction variables from the generated code: MAP contains the - induction variables renaming mapping, and is used to translate the - names of induction variables. */ - -static void -expand_scalar_variables (basic_block bb, scop_p scop, htab_t map) -{ - gimple_stmt_iterator gsi; - - for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);) - { - gimple stmt = gsi_stmt (gsi); - expand_scalar_variables_stmt (stmt, bb, scop, map); - gsi_next (&gsi); - } -} - -/* Rename all the SSA_NAMEs from block BB according to the MAP. */ - -static void -rename_variables (basic_block bb, htab_t map) -{ - gimple_stmt_iterator gsi; - - for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - rename_variables_in_stmt (gsi_stmt (gsi), map); -} - -/* Remove condition from BB. */ - -static void -remove_condition (basic_block bb) -{ - gimple last = last_stmt (bb); - - if (last && gimple_code (last) == GIMPLE_COND) - { - gimple_stmt_iterator gsi = gsi_last_bb (bb); - gsi_remove (&gsi, true); - } -} - -/* Returns the first successor edge of BB with EDGE_TRUE_VALUE flag set. */ - -static edge -get_true_edge_from_guard_bb (basic_block bb) -{ - edge e; - edge_iterator ei; - - FOR_EACH_EDGE (e, ei, bb->succs) - if (e->flags & EDGE_TRUE_VALUE) - return e; - - gcc_unreachable (); - return NULL; -} - -/* Returns the first successor edge of BB with EDGE_TRUE_VALUE flag cleared. */ - -static edge -get_false_edge_from_guard_bb (basic_block bb) -{ - edge e; - edge_iterator ei; - - FOR_EACH_EDGE (e, ei, bb->succs) - if (!(e->flags & EDGE_TRUE_VALUE)) - return e; - - gcc_unreachable (); - return NULL; -} - -/* Inserts in MAP a tuple (OLD_NAME, NEW_NAME) for the induction - variables of the loops around GBB in SCOP, i.e. GBB_LOOPS. - NEW_NAME is obtained from IVSTACK. IVSTACK has the same stack - ordering as GBB_LOOPS. */ - -static void -build_iv_mapping (loop_iv_stack ivstack, htab_t map, gbb_p gbb, scop_p scop) -{ - int i; - name_tree iv; - PTR *slot; - - for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, iv); i++) - { - struct rename_map_elt_d tmp; - - if (!flow_bb_inside_loop_p (iv->loop, GBB_BB (gbb))) - continue; - - tmp.old_name = iv->t; - slot = htab_find_slot (map, &tmp, INSERT); - - if (!*slot) - { - tree new_name = loop_iv_stack_get_iv (ivstack, - gbb_loop_index (gbb, iv->loop)); - *slot = new_rename_map_elt (iv->t, new_name); - } - } -} - -/* Register in MAP the tuple (old_name, new_name). */ - -static void -register_old_and_new_names (htab_t map, tree old_name, tree new_name) -{ - struct rename_map_elt_d tmp; - PTR *slot; - - tmp.old_name = old_name; - slot = htab_find_slot (map, &tmp, INSERT); - - if (!*slot) - *slot = new_rename_map_elt (old_name, new_name); -} - -/* Create a duplicate of the basic block BB. NOTE: This does not - preserve SSA form. */ - -static void -graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb, htab_t map) -{ - gimple_stmt_iterator gsi, gsi_tgt; - - gsi_tgt = gsi_start_bb (new_bb); - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - def_operand_p def_p; - ssa_op_iter op_iter; - int region; - gimple stmt = gsi_stmt (gsi); - gimple copy; - - if (gimple_code (stmt) == GIMPLE_LABEL) - continue; - - /* Create a new copy of STMT and duplicate STMT's virtual - operands. */ - copy = gimple_copy (stmt); - gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT); - mark_sym_for_renaming (gimple_vop (cfun)); - - region = lookup_stmt_eh_region (stmt); - if (region >= 0) - add_stmt_to_eh_region (copy, region); - gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt); - - /* Create new names for all the definitions created by COPY and - add replacement mappings for each new name. */ - FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_ALL_DEFS) - { - tree old_name = DEF_FROM_PTR (def_p); - tree new_name = create_new_def_for (old_name, copy, def_p); - register_old_and_new_names (map, old_name, new_name); - } - } -} - -/* Records in SCOP_LIVEOUT_RENAMES the names that are live out of - the SCOP and that appear in the RENAME_MAP. */ - -static void -register_scop_liveout_renames (scop_p scop, htab_t rename_map) -{ - int i; - sese region = SCOP_REGION (scop); - - for (i = 0; i < SESE_NUM_VER (region); i++) - if (bitmap_bit_p (SESE_LIVEOUT (region), i) - && is_gimple_reg (ssa_name (i))) - { - tree old_name = ssa_name (i); - tree new_name = get_new_name_from_old_name (rename_map, old_name); - - register_old_and_new_names (SCOP_LIVEOUT_RENAMES (scop), - old_name, new_name); - } -} - -/* Copies BB and includes in the copied BB all the statements that can - be reached following the use-def chains from the memory accesses, - and returns the next edge following this new block. */ - -static edge -copy_bb_and_scalar_dependences (basic_block bb, scop_p scop, - edge next_e, htab_t map) -{ - basic_block new_bb = split_edge (next_e); - - next_e = single_succ_edge (new_bb); - graphite_copy_stmts_from_block (bb, new_bb, map); - remove_condition (new_bb); - rename_variables (new_bb, map); - remove_phi_nodes (new_bb); - expand_scalar_variables (new_bb, scop, map); - register_scop_liveout_renames (scop, map); - - return next_e; -} - -/* Helper function for htab_traverse in insert_loop_close_phis. */ - -static int -add_loop_exit_phis (void **slot, void *s) -{ - struct rename_map_elt_d *entry = (struct rename_map_elt_d *) *slot; - tree new_name = entry->new_name; - basic_block bb = (basic_block) s; - gimple phi = create_phi_node (new_name, bb); - tree res = create_new_def_for (gimple_phi_result (phi), phi, - gimple_phi_result_ptr (phi)); - - add_phi_arg (phi, new_name, single_pred_edge (bb)); - - entry->new_name = res; - *slot = entry; - return 1; -} - -/* Iterate over the SCOP_LIVEOUT_RENAMES (SCOP) and get tuples of the - form (OLD_NAME, NEW_NAME). Insert in BB "RES = phi (NEW_NAME)", - and finally register in SCOP_LIVEOUT_RENAMES (scop) the tuple - (OLD_NAME, RES). */ - -static void -insert_loop_close_phis (scop_p scop, basic_block bb) -{ - update_ssa (TODO_update_ssa); - htab_traverse (SCOP_LIVEOUT_RENAMES (scop), add_loop_exit_phis, bb); - update_ssa (TODO_update_ssa); -} - -/* Helper structure for htab_traverse in insert_guard_phis. */ - -struct igp { - basic_block bb; - edge true_edge, false_edge; - htab_t liveout_before_guard; -}; - -/* Return the default name that is before the guard. */ - -static tree -default_liveout_before_guard (htab_t liveout_before_guard, tree old_name) -{ - tree res = get_new_name_from_old_name (liveout_before_guard, old_name); - - if (res == old_name) - { - if (is_gimple_reg (res)) - return fold_convert (TREE_TYPE (res), integer_zero_node); - return gimple_default_def (cfun, res); - } - - return res; -} - -/* Helper function for htab_traverse in insert_guard_phis. */ - -static int -add_guard_exit_phis (void **slot, void *s) -{ - struct rename_map_elt_d *entry = (struct rename_map_elt_d *) *slot; - struct igp *i = (struct igp *) s; - basic_block bb = i->bb; - edge true_edge = i->true_edge; - edge false_edge = i->false_edge; - tree name1 = entry->new_name; - tree name2 = default_liveout_before_guard (i->liveout_before_guard, - entry->old_name); - gimple phi = create_phi_node (name1, bb); - tree res = create_new_def_for (gimple_phi_result (phi), phi, - gimple_phi_result_ptr (phi)); - - add_phi_arg (phi, name1, true_edge); - add_phi_arg (phi, name2, false_edge); - - entry->new_name = res; - *slot = entry; - return 1; -} - -/* Iterate over the SCOP_LIVEOUT_RENAMES (SCOP) and get tuples of the - form (OLD_NAME, NAME1). If there is a correspondent tuple of - OLD_NAME in LIVEOUT_BEFORE_GUARD, i.e. (OLD_NAME, NAME2) then - insert in BB - - | RES = phi (NAME1 (on TRUE_EDGE), NAME2 (on FALSE_EDGE))" - - if there is no tuple for OLD_NAME in LIVEOUT_BEFORE_GUARD, insert - - | RES = phi (NAME1 (on TRUE_EDGE), - | DEFAULT_DEFINITION of NAME1 (on FALSE_EDGE))". - - Finally register in SCOP_LIVEOUT_RENAMES (scop) the tuple - (OLD_NAME, RES). */ - -static void -insert_guard_phis (scop_p scop, basic_block bb, edge true_edge, - edge false_edge, htab_t liveout_before_guard) -{ - struct igp i; - i.bb = bb; - i.true_edge = true_edge; - i.false_edge = false_edge; - i.liveout_before_guard = liveout_before_guard; - - update_ssa (TODO_update_ssa); - htab_traverse (SCOP_LIVEOUT_RENAMES (scop), add_guard_exit_phis, &i); - update_ssa (TODO_update_ssa); -} - -/* Helper function for htab_traverse. */ - -static int -copy_renames (void **slot, void *s) -{ - struct rename_map_elt_d *entry = (struct rename_map_elt_d *) *slot; - htab_t res = (htab_t) s; - tree old_name = entry->old_name; - tree new_name = entry->new_name; - struct rename_map_elt_d tmp; - PTR *x; - - tmp.old_name = old_name; - x = htab_find_slot (res, &tmp, INSERT); - - if (!*x) - *x = new_rename_map_elt (old_name, new_name); - - return 1; -} - -/* Translates a CLAST statement STMT to GCC representation in the - context of a SCOP. - - - NEXT_E is the edge where new generated code should be attached. - - CONTEXT_LOOP is the loop in which the generated code will be placed - (might be NULL). - - IVSTACK contains the surrounding loops around the statement to be - translated. -*/ - -static edge -translate_clast (scop_p scop, struct loop *context_loop, - struct clast_stmt *stmt, edge next_e, loop_iv_stack ivstack) -{ - if (!stmt) - return next_e; - - if (CLAST_STMT_IS_A (stmt, stmt_root)) - return translate_clast (scop, context_loop, stmt->next, next_e, ivstack); - - if (CLAST_STMT_IS_A (stmt, stmt_user)) - { - htab_t map; - CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement; - graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs); - - if (GBB_BB (gbb) == ENTRY_BLOCK_PTR) - return next_e; - - map = htab_create (10, rename_map_elt_info, eq_rename_map_elts, free); - loop_iv_stack_patch_for_consts (ivstack, (struct clast_user_stmt *) stmt); - build_iv_mapping (ivstack, map, gbb, scop); - next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), scop, - next_e, map); - htab_delete (map); - loop_iv_stack_remove_constants (ivstack); - recompute_all_dominators (); - update_ssa (TODO_update_ssa); - graphite_verify (); - return translate_clast (scop, context_loop, stmt->next, next_e, ivstack); - } - - if (CLAST_STMT_IS_A (stmt, stmt_for)) - { - struct loop *loop - = graphite_create_new_loop (scop, next_e, (struct clast_for *) stmt, - ivstack, context_loop ? context_loop - : get_loop (0)); - edge last_e = single_exit (loop); - - next_e = translate_clast (scop, loop, ((struct clast_for *) stmt)->body, - single_pred_edge (loop->latch), ivstack); - redirect_edge_succ_nodup (next_e, loop->latch); - - set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src); - loop_iv_stack_pop (ivstack); - last_e = single_succ_edge (split_edge (last_e)); - insert_loop_close_phis (scop, last_e->src); - - recompute_all_dominators (); - graphite_verify (); - return translate_clast (scop, context_loop, stmt->next, last_e, ivstack); - } - - if (CLAST_STMT_IS_A (stmt, stmt_guard)) - { - htab_t liveout_before_guard = htab_create (10, rename_map_elt_info, - eq_rename_map_elts, free); - edge last_e = graphite_create_new_guard (scop, next_e, - ((struct clast_guard *) stmt), - ivstack); - edge true_e = get_true_edge_from_guard_bb (next_e->dest); - edge false_e = get_false_edge_from_guard_bb (next_e->dest); - edge exit_true_e = single_succ_edge (true_e->dest); - edge exit_false_e = single_succ_edge (false_e->dest); - - htab_traverse (SCOP_LIVEOUT_RENAMES (scop), copy_renames, - liveout_before_guard); - - next_e = translate_clast (scop, context_loop, - ((struct clast_guard *) stmt)->then, - true_e, ivstack); - insert_guard_phis (scop, last_e->src, exit_true_e, exit_false_e, - liveout_before_guard); - htab_delete (liveout_before_guard); - recompute_all_dominators (); - graphite_verify (); - - return translate_clast (scop, context_loop, stmt->next, last_e, ivstack); - } - - if (CLAST_STMT_IS_A (stmt, stmt_block)) - { - next_e = translate_clast (scop, context_loop, - ((struct clast_block *) stmt)->body, - next_e, ivstack); - recompute_all_dominators (); - graphite_verify (); - return translate_clast (scop, context_loop, stmt->next, next_e, ivstack); - } - - gcc_unreachable (); -} - -/* Free the SCATTERING domain list. */ - -static void -free_scattering (CloogDomainList *scattering) -{ - while (scattering) - { - CloogDomain *dom = cloog_domain (scattering); - CloogDomainList *next = cloog_next_domain (scattering); - - cloog_domain_free (dom); - free (scattering); - scattering = next; - } -} - -/* Build cloog program for SCoP. */ - -static void -build_cloog_prog (scop_p scop) -{ - int i; - int max_nb_loops = scop_max_loop_depth (scop); - graphite_bb_p gbb; - CloogLoop *loop_list = NULL; - CloogBlockList *block_list = NULL; - CloogDomainList *scattering = NULL; - CloogProgram *prog = SCOP_PROG (scop); - int nbs = 2 * max_nb_loops + 1; - int *scaldims = (int *) xmalloc (nbs * (sizeof (int))); - - cloog_program_set_nb_scattdims (prog, nbs); - initialize_cloog_names (scop); - - for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++) - { - /* Build new block. */ - CloogMatrix *domain = GBB_DOMAIN (gbb); - CloogStatement *stmt = cloog_statement_alloc (GBB_BB (gbb)->index); - CloogBlock *block = cloog_block_alloc (stmt, 0, NULL, - nb_loops_around_gb (gbb)); - cloog_statement_set_usr (stmt, gbb); - - /* Add empty domain to all bbs, which do not yet have a domain, as they - are not part of any loop. */ - if (domain == NULL) - { - domain = cloog_matrix_alloc (0, scop_nb_params (scop) + 2); - GBB_DOMAIN (gbb) = domain; - } - - /* Build loop list. */ - { - CloogLoop *new_loop_list = cloog_loop_malloc (); - cloog_loop_set_next (new_loop_list, loop_list); - cloog_loop_set_domain (new_loop_list, - cloog_domain_matrix2domain (domain)); - cloog_loop_set_block (new_loop_list, block); - loop_list = new_loop_list; - } - - /* Build block list. */ - { - CloogBlockList *new_block_list = cloog_block_list_malloc (); - - cloog_block_list_set_next (new_block_list, block_list); - cloog_block_list_set_block (new_block_list, block); - block_list = new_block_list; - } - - /* Build scattering list. */ - { - /* XXX: Replace with cloog_domain_list_alloc(), when available. */ - CloogDomainList *new_scattering - = (CloogDomainList *) xmalloc (sizeof (CloogDomainList)); - CloogMatrix *scat_mat = schedule_to_scattering (gbb, nbs); - - cloog_set_next_domain (new_scattering, scattering); - cloog_set_domain (new_scattering, - cloog_domain_matrix2domain (scat_mat)); - scattering = new_scattering; - cloog_matrix_free (scat_mat); - } - } - - cloog_program_set_loop (prog, loop_list); - cloog_program_set_blocklist (prog, block_list); - - for (i = 0; i < nbs; i++) - scaldims[i] = 0 ; - - cloog_program_set_scaldims (prog, scaldims); - - /* Extract scalar dimensions to simplify the code generation problem. */ - cloog_program_extract_scalars (prog, scattering); - - /* Apply scattering. */ - cloog_program_scatter (prog, scattering); - free_scattering (scattering); - - /* Iterators corresponding to scalar dimensions have to be extracted. */ - cloog_names_scalarize (cloog_program_names (prog), nbs, - cloog_program_scaldims (prog)); - - /* Free blocklist. */ - { - CloogBlockList *next = cloog_program_blocklist (prog); - - while (next) - { - CloogBlockList *toDelete = next; - next = cloog_block_list_next (next); - cloog_block_list_set_next (toDelete, NULL); - cloog_block_list_set_block (toDelete, NULL); - cloog_block_list_free (toDelete); - } - cloog_program_set_blocklist (prog, NULL); - } -} - -/* Return the options that will be used in GLOOG. */ - -static CloogOptions * -set_cloog_options (void) -{ - CloogOptions *options = cloog_options_malloc (); - - /* Change cloog output language to C. If we do use FORTRAN instead, cloog - will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if - we pass an incomplete program to cloog. */ - options->language = LANGUAGE_C; - - /* Enable complex equality spreading: removes dummy statements - (assignments) in the generated code which repeats the - substitution equations for statements. This is useless for - GLooG. */ - options->esp = 1; - - /* Enable C pretty-printing mode: normalizes the substitution - equations for statements. */ - options->cpp = 1; - - /* Allow cloog to build strides with a stride width different to one. - This example has stride = 4: - - for (i = 0; i < 20; i += 4) - A */ - options->strides = 1; - - /* Disable optimizations and make cloog generate source code closer to the - input. This is useful for debugging, but later we want the optimized - code. - - XXX: We can not disable optimizations, as loop blocking is not working - without them. */ - if (0) - { - options->f = -1; - options->l = INT_MAX; - } - - return options; -} - -/* Prints STMT to STDERR. */ - -void -debug_clast_stmt (struct clast_stmt *stmt) -{ - CloogOptions *options = set_cloog_options (); - - pprint (stderr, stmt, 0, options); -} - -/* Find the right transform for the SCOP, and return a Cloog AST - representing the new form of the program. */ - -static struct clast_stmt * -find_transform (scop_p scop) -{ - struct clast_stmt *stmt; - CloogOptions *options = set_cloog_options (); - - /* Connect new cloog prog generation to graphite. */ - build_cloog_prog (scop); - - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Cloog Input [\n"); - cloog_program_print (dump_file, SCOP_PROG(scop)); - fprintf (dump_file, "]\n"); - } - - SCOP_PROG (scop) = cloog_program_generate (SCOP_PROG (scop), options); - stmt = cloog_clast_create (SCOP_PROG (scop), options); - - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Cloog Output[\n"); - pprint (dump_file, stmt, 0, options); - cloog_program_dump_cloog (dump_file, SCOP_PROG (scop)); - fprintf (dump_file, "]\n"); - } - - cloog_options_free (options); - return stmt; -} - -/* Remove from the CFG the REGION. */ - -static inline void -remove_sese_region (sese region) -{ - VEC (basic_block, heap) *bbs = NULL; - basic_block entry_bb = SESE_ENTRY (region)->dest; - basic_block exit_bb = SESE_EXIT (region)->dest; - basic_block bb; - int i; - VEC_safe_push (basic_block, heap, bbs, entry_bb); - gather_blocks_in_sese_region (entry_bb, exit_bb, &bbs); - - for (i = 0; VEC_iterate (basic_block, bbs, i, bb); i++) - delete_basic_block (bb); - - VEC_free (basic_block, heap, bbs); -} - -typedef struct ifsese_d -{ - sese region; - sese true_region; - sese false_region; -} *ifsese; - -static inline edge -if_region_entry (ifsese if_region) -{ - return SESE_ENTRY (if_region->region); -} - -static inline edge -if_region_exit (ifsese if_region) -{ - return SESE_EXIT (if_region->region); -} - -static inline basic_block -if_region_get_condition_block (ifsese if_region) -{ - return if_region_entry (if_region)->dest; -} - -static inline void -if_region_set_false_region (ifsese if_region, sese region) -{ - basic_block condition = if_region_get_condition_block (if_region); - edge false_edge = get_false_edge_from_guard_bb (condition); - basic_block dummy = false_edge->dest; - edge entry_region = SESE_ENTRY (region); - edge exit_region = SESE_EXIT (region); - basic_block before_region = entry_region->src; - basic_block last_in_region = exit_region->src; - void **slot = htab_find_slot_with_hash (current_loops->exits, exit_region, - htab_hash_pointer (exit_region), - NO_INSERT); - - entry_region->flags = false_edge->flags; - false_edge->flags = exit_region->flags; - - redirect_edge_pred (entry_region, condition); - redirect_edge_pred (exit_region, before_region); - redirect_edge_pred (false_edge, last_in_region); - redirect_edge_succ (false_edge, single_succ (dummy)); - delete_basic_block (dummy); - - exit_region->flags = EDGE_FALLTHRU; recompute_all_dominators (); + initialize_original_copy_tables (); + cloog_initialize (); - SESE_EXIT (region) = false_edge; - if_region->false_region = region; - - if (slot) - { - struct loop_exit *loop_exit = GGC_CNEW (struct loop_exit); - - memcpy (loop_exit, *((struct loop_exit **) slot), sizeof (struct loop_exit)); - htab_clear_slot (current_loops->exits, slot); - - slot = htab_find_slot_with_hash (current_loops->exits, false_edge, - htab_hash_pointer (false_edge), - INSERT); - loop_exit->e = false_edge; - *slot = loop_exit; - false_edge->src->loop_father->exits->next = loop_exit; - } -} - -static ifsese -create_if_region_on_edge (edge entry, tree condition) -{ - edge e; - edge_iterator ei; - sese sese_region = GGC_NEW (struct sese_d); - sese true_region = GGC_NEW (struct sese_d); - sese false_region = GGC_NEW (struct sese_d); - ifsese if_region = GGC_NEW (struct ifsese_d); - edge exit = create_empty_if_region_on_edge (entry, condition); - - if_region->region = sese_region; - if_region->region->entry = entry; - if_region->region->exit = exit; - - FOR_EACH_EDGE (e, ei, entry->dest->succs) - { - if (e->flags & EDGE_TRUE_VALUE) - { - true_region->entry = e; - true_region->exit = single_succ_edge (e->dest); - if_region->true_region = true_region; - } - else if (e->flags & EDGE_FALSE_VALUE) - { - false_region->entry = e; - false_region->exit = single_succ_edge (e->dest); - if_region->false_region = false_region; - } - } - - return if_region; -} - -/* Moves REGION in a condition expression: - | if (1) - | ; - | else - | REGION; -*/ - -static ifsese -move_sese_in_condition (sese region) -{ - basic_block pred_block = split_edge (SESE_ENTRY (region)); - ifsese if_region = NULL; - - SESE_ENTRY (region) = single_succ_edge (pred_block); - if_region = create_if_region_on_edge (single_pred_edge (pred_block), integer_one_node); - if_region_set_false_region (if_region, region); - - return if_region; -} - -/* Add exit phis for USE on EXIT. */ - -static void -scop_add_exit_phis_edge (basic_block exit, tree use, edge false_e, edge true_e) -{ - gimple phi = create_phi_node (use, exit); - - create_new_def_for (gimple_phi_result (phi), phi, - gimple_phi_result_ptr (phi)); - add_phi_arg (phi, use, false_e); - add_phi_arg (phi, use, true_e); -} - -/* Add phi nodes for VAR that is used in LIVEIN. Phi nodes are - inserted in block BB. */ - -static void -scop_add_exit_phis_var (basic_block bb, tree var, bitmap livein, - edge false_e, edge true_e) -{ - bitmap def; - basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (var)); - - if (is_gimple_reg (var)) - bitmap_clear_bit (livein, def_bb->index); - else - bitmap_set_bit (livein, def_bb->index); - - def = BITMAP_ALLOC (NULL); - bitmap_set_bit (def, def_bb->index); - compute_global_livein (livein, def); - BITMAP_FREE (def); - - scop_add_exit_phis_edge (bb, var, false_e, true_e); -} - -/* Insert in the block BB phi nodes for variables defined in REGION - and used outside the REGION. The code generation moves REGION in - the else clause of an "if (1)" and generates code in the then - clause that is at this point empty: - - | if (1) - | empty; - | else - | REGION; -*/ - -static void -scop_insert_phis_for_liveouts (sese region, basic_block bb, - edge false_e, edge true_e) -{ - unsigned i; - bitmap_iterator bi; - - update_ssa (TODO_update_ssa); - - EXECUTE_IF_SET_IN_BITMAP (SESE_LIVEOUT (region), 0, i, bi) - scop_add_exit_phis_var (bb, ssa_name (i), SESE_LIVEIN_VER (region, i), - false_e, true_e); - - update_ssa (TODO_update_ssa); -} - -/* Get the definition of NAME before the SCOP. Keep track of the - basic blocks that have been VISITED in a bitmap. */ - -static tree -get_vdef_before_scop (scop_p scop, tree name, sbitmap visited) -{ - unsigned i; - gimple def_stmt = SSA_NAME_DEF_STMT (name); - basic_block def_bb = gimple_bb (def_stmt); - - if (!def_bb - || !bb_in_sese_p (def_bb, SCOP_REGION (scop))) - return name; - - if (TEST_BIT (visited, def_bb->index)) - return NULL_TREE; - - SET_BIT (visited, def_bb->index); - - switch (gimple_code (def_stmt)) - { - case GIMPLE_PHI: - for (i = 0; i < gimple_phi_num_args (def_stmt); i++) - { - tree arg = gimple_phi_arg_def (def_stmt, i); - tree res = get_vdef_before_scop (scop, arg, visited); - if (res) - return res; - } - return NULL_TREE; - - default: - return NULL_TREE; - } -} - -/* Adjust a virtual phi node PHI that is placed at the end of the - generated code for SCOP: - - | if (1) - | generated code from REGION; - | else - | REGION; - - The FALSE_E edge comes from the original code, TRUE_E edge comes - from the code generated for the SCOP. */ - -static void -scop_adjust_vphi (scop_p scop, gimple phi, edge true_e) -{ - unsigned i; - - gcc_assert (gimple_phi_num_args (phi) == 2); - - for (i = 0; i < gimple_phi_num_args (phi); i++) - if (gimple_phi_arg_edge (phi, i) == true_e) - { - tree true_arg, false_arg, before_scop_arg; - sbitmap visited; - - true_arg = gimple_phi_arg_def (phi, i); - if (!SSA_NAME_IS_DEFAULT_DEF (true_arg)) - return; - - false_arg = gimple_phi_arg_def (phi, i == 0 ? 1 : 0); - if (SSA_NAME_IS_DEFAULT_DEF (false_arg)) - return; - - visited = sbitmap_alloc (last_basic_block); - sbitmap_zero (visited); - before_scop_arg = get_vdef_before_scop (scop, false_arg, visited); - gcc_assert (before_scop_arg != NULL_TREE); - SET_PHI_ARG_DEF (phi, i, before_scop_arg); - sbitmap_free (visited); - } -} - -/* Adjusts the phi nodes in the block BB for variables defined in - SCOP_REGION and used outside the SCOP_REGION. The code generation - moves SCOP_REGION in the else clause of an "if (1)" and generates - code in the then clause: - - | if (1) - | generated code from REGION; - | else - | REGION; - - To adjust the phi nodes after the condition, SCOP_LIVEOUT_RENAMES - hash table is used: this stores for a name that is part of the - LIVEOUT of SCOP_REGION its new name in the generated code. */ - -static void -scop_adjust_phis_for_liveouts (scop_p scop, basic_block bb, edge false_e, - edge true_e) -{ - gimple_stmt_iterator si; - - for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si)) - { - unsigned i; - unsigned false_i = 0; - gimple phi = gsi_stmt (si); - - if (!is_gimple_reg (PHI_RESULT (phi))) - { - scop_adjust_vphi (scop, phi, true_e); - continue; - } - - for (i = 0; i < gimple_phi_num_args (phi); i++) - if (gimple_phi_arg_edge (phi, i) == false_e) - { - false_i = i; - break; - } - - for (i = 0; i < gimple_phi_num_args (phi); i++) - if (gimple_phi_arg_edge (phi, i) == true_e) - { - tree old_name = gimple_phi_arg_def (phi, false_i); - tree new_name = get_new_name_from_old_name - (SCOP_LIVEOUT_RENAMES (scop), old_name); - - gcc_assert (old_name != new_name); - SET_PHI_ARG_DEF (phi, i, new_name); - } - } -} - -/* Returns the first cloog name used in EXPR. */ - -static const char * -find_cloog_iv_in_expr (struct clast_expr *expr) -{ - struct clast_term *term = (struct clast_term *) expr; - - if (expr->type == expr_term - && !term->var) - return NULL; - - if (expr->type == expr_term) - return term->var; - - if (expr->type == expr_red) - { - int i; - struct clast_reduction *red = (struct clast_reduction *) expr; - - for (i = 0; i < red->n; i++) - { - const char *res = find_cloog_iv_in_expr ((red)->elts[i]); - - if (res) - return res; - } - } - - return NULL; -} - -/* Build for a clast_user_stmt USER_STMT a map between the CLAST - induction variables and the corresponding GCC old induction - variables. This information is stored on each GRAPHITE_BB. */ - -static void -compute_cloog_iv_types_1 (graphite_bb_p gbb, - struct clast_user_stmt *user_stmt) -{ - struct clast_stmt *t; - int index = 0; - - for (t = user_stmt->substitutions; t; t = t->next, index++) - { - PTR *slot; - struct ivtype_map_elt_d tmp; - struct clast_expr *expr = (struct clast_expr *) - ((struct clast_assignment *)t)->RHS; - - /* Create an entry (clast_var, type). */ - tmp.cloog_iv = find_cloog_iv_in_expr (expr); - if (!tmp.cloog_iv) - continue; - - slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, INSERT); - - if (!*slot) - { - loop_p loop = gbb_loop_at_index (gbb, index); - tree oldiv = oldiv_for_loop (GBB_SCOP (gbb), loop); - tree type = oldiv ? TREE_TYPE (oldiv) : integer_type_node; - *slot = new_ivtype_map_elt (tmp.cloog_iv, type); - } - } -} - -/* Walk the CLAST tree starting from STMT and build for each - clast_user_stmt a map between the CLAST induction variables and the - corresponding GCC old induction variables. This information is - stored on each GRAPHITE_BB. */ - -static void -compute_cloog_iv_types (struct clast_stmt *stmt) -{ - if (!stmt) - return; - - if (CLAST_STMT_IS_A (stmt, stmt_root)) - goto next; - - if (CLAST_STMT_IS_A (stmt, stmt_user)) - { - CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement; - graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs); - GBB_CLOOG_IV_TYPES (gbb) = htab_create (10, ivtype_map_elt_info, - eq_ivtype_map_elts, free); - compute_cloog_iv_types_1 (gbb, (struct clast_user_stmt *) stmt); - goto next; - } - - if (CLAST_STMT_IS_A (stmt, stmt_for)) - { - struct clast_stmt *s = ((struct clast_for *) stmt)->body; - compute_cloog_iv_types (s); - goto next; - } - - if (CLAST_STMT_IS_A (stmt, stmt_guard)) - { - struct clast_stmt *s = ((struct clast_guard *) stmt)->then; - compute_cloog_iv_types (s); - goto next; - } - - if (CLAST_STMT_IS_A (stmt, stmt_block)) - { - struct clast_stmt *s = ((struct clast_block *) stmt)->body; - compute_cloog_iv_types (s); - goto next; - } - - gcc_unreachable (); - - next: - compute_cloog_iv_types (stmt->next); -} - -/* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for - the given SCOP. Return true if code generation succeeded. */ - -static bool -gloog (scop_p scop, struct clast_stmt *stmt) -{ - edge new_scop_exit_edge = NULL; - VEC (iv_stack_entry_p, heap) *ivstack = VEC_alloc (iv_stack_entry_p, heap, - 10); - loop_p context_loop; - ifsese if_region = NULL; - - recompute_all_dominators (); - graphite_verify (); - if_region = move_sese_in_condition (SCOP_REGION (scop)); - sese_build_livein_liveouts (SCOP_REGION (scop)); - scop_insert_phis_for_liveouts (SCOP_REGION (scop), - if_region->region->exit->src, - if_region->false_region->exit, - if_region->true_region->exit); - recompute_all_dominators (); - graphite_verify (); - context_loop = SESE_ENTRY (SCOP_REGION (scop))->src->loop_father; - compute_cloog_iv_types (stmt); - - new_scop_exit_edge = translate_clast (scop, context_loop, stmt, - if_region->true_region->entry, - &ivstack); - free_loop_iv_stack (&ivstack); - cloog_clast_free (stmt); - - graphite_verify (); - scop_adjust_phis_for_liveouts (scop, - if_region->region->exit->src, - if_region->false_region->exit, - if_region->true_region->exit); - - recompute_all_dominators (); - graphite_verify (); - return true; -} - -/* Returns the number of data references in SCOP. */ - -static int -nb_data_refs_in_scop (scop_p scop) -{ - int i; - graphite_bb_p gbb; - int res = 0; - - for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++) - res += VEC_length (data_reference_p, GBB_DATA_REFS (gbb)); - - return res; -} - -/* Move the loop at index LOOP and insert it before index NEW_LOOP_POS. - This transformartion is only valid, if the loop nest between i and k is - perfectly nested. Therefore we do not need to change the static schedule. - - Example: - - for (i = 0; i < 50; i++) - for (j ...) - for (k = 5; k < 100; k++) - A - - To move k before i use: - - graphite_trans_bb_move_loop (A, 2, 0) - - for (k = 5; k < 100; k++) - for (i = 0; i < 50; i++) - for (j ...) - A - - And to move k back: - - graphite_trans_bb_move_loop (A, 0, 2) - - This function does not check the validity of interchanging loops. - This should be checked before calling this function. */ - -static void -graphite_trans_bb_move_loop (graphite_bb_p gb, int loop, - int new_loop_pos) -{ - CloogMatrix *domain = GBB_DOMAIN (gb); - int row, j; - loop_p tmp_loop_p; - - gcc_assert (loop < gbb_nb_loops (gb) - && new_loop_pos < gbb_nb_loops (gb)); - - /* Update LOOPS vector. */ - tmp_loop_p = VEC_index (loop_p, GBB_LOOPS (gb), loop); - VEC_ordered_remove (loop_p, GBB_LOOPS (gb), loop); - VEC_safe_insert (loop_p, heap, GBB_LOOPS (gb), new_loop_pos, tmp_loop_p); - - /* Move the domain columns. */ - if (loop < new_loop_pos) - for (row = 0; row < domain->NbRows; row++) - { - Value tmp; - value_init (tmp); - value_assign (tmp, domain->p[row][loop + 1]); - - for (j = loop ; j < new_loop_pos - 1; j++) - value_assign (domain->p[row][j + 1], domain->p[row][j + 2]); - - value_assign (domain->p[row][new_loop_pos], tmp); - value_clear (tmp); - } - else - for (row = 0; row < domain->NbRows; row++) - { - Value tmp; - value_init (tmp); - value_assign (tmp, domain->p[row][loop + 1]); - - for (j = loop ; j > new_loop_pos; j--) - value_assign (domain->p[row][j + 1], domain->p[row][j]); - - value_assign (domain->p[row][new_loop_pos + 1], tmp); - value_clear (tmp); - } -} - -/* Get the index of the column representing constants in the DOMAIN - matrix. */ - -static int -const_column_index (CloogMatrix *domain) -{ - return domain->NbColumns - 1; -} - - -/* Get the first index that is positive or negative, determined - following the value of POSITIVE, in matrix DOMAIN in COLUMN. */ - -static int -get_first_matching_sign_row_index (CloogMatrix *domain, int column, - bool positive) -{ - int row; - - for (row = 0; row < domain->NbRows; row++) - { - int val = value_get_si (domain->p[row][column]); - - if (val > 0 && positive) - return row; - - else if (val < 0 && !positive) - return row; - } - - gcc_unreachable (); -} - -/* Get the lower bound of COLUMN in matrix DOMAIN. */ - -static int -get_lower_bound_row (CloogMatrix *domain, int column) -{ - return get_first_matching_sign_row_index (domain, column, true); -} - -/* Get the upper bound of COLUMN in matrix DOMAIN. */ - -static int -get_upper_bound_row (CloogMatrix *domain, int column) -{ - return get_first_matching_sign_row_index (domain, column, false); -} - -/* Copies the OLD_ROW constraint from OLD_DOMAIN to the NEW_DOMAIN at - row NEW_ROW. */ - -static void -copy_constraint (CloogMatrix *old_domain, CloogMatrix *new_domain, - int old_row, int new_row) -{ - int i; - - gcc_assert (old_domain->NbColumns == new_domain->NbColumns - && old_row < old_domain->NbRows - && new_row < new_domain->NbRows); - - for (i = 0; i < old_domain->NbColumns; i++) - value_assign (new_domain->p[new_row][i], old_domain->p[old_row][i]); -} - -/* Swap coefficients of variables X and Y on row R. */ - -static void -swap_constraint_variables (CloogMatrix *domain, - int r, int x, int y) -{ - value_swap (domain->p[r][x], domain->p[r][y]); -} - -/* Scale by X the coefficient C of constraint at row R in DOMAIN. */ - -static void -scale_constraint_variable (CloogMatrix *domain, - int r, int c, int x) -{ - Value strip_size_value; - value_init (strip_size_value); - value_set_si (strip_size_value, x); - value_multiply (domain->p[r][c], domain->p[r][c], strip_size_value); - value_clear (strip_size_value); -} - -/* Strip mines the loop of BB at the position LOOP_DEPTH with STRIDE. - Always valid, but not always a performance improvement. */ - -static void -graphite_trans_bb_strip_mine (graphite_bb_p gb, int loop_depth, int stride) -{ - int row, col; - - CloogMatrix *domain = GBB_DOMAIN (gb); - CloogMatrix *new_domain = cloog_matrix_alloc (domain->NbRows + 3, - domain->NbColumns + 1); - - int col_loop_old = loop_depth + 2; - int col_loop_strip = col_loop_old - 1; - - gcc_assert (loop_depth <= gbb_nb_loops (gb) - 1); - - VEC_safe_insert (loop_p, heap, GBB_LOOPS (gb), loop_depth, NULL); - - GBB_DOMAIN (gb) = new_domain; - - for (row = 0; row < domain->NbRows; row++) - for (col = 0; col < domain->NbColumns; col++) - if (col <= loop_depth) - value_assign (new_domain->p[row][col], domain->p[row][col]); - else - value_assign (new_domain->p[row][col + 1], domain->p[row][col]); - - row = domain->NbRows; - - /* Lower bound of the outer stripped loop. */ - copy_constraint (new_domain, new_domain, - get_lower_bound_row (new_domain, col_loop_old), row); - swap_constraint_variables (new_domain, row, col_loop_old, col_loop_strip); - row++; - - /* Upper bound of the outer stripped loop. */ - copy_constraint (new_domain, new_domain, - get_upper_bound_row (new_domain, col_loop_old), row); - swap_constraint_variables (new_domain, row, col_loop_old, col_loop_strip); - scale_constraint_variable (new_domain, row, col_loop_strip, stride); - row++; - - /* Lower bound of a tile starts at "stride * outer_iv". */ - row = get_lower_bound_row (new_domain, col_loop_old); - value_set_si (new_domain->p[row][0], 1); - value_set_si (new_domain->p[row][const_column_index (new_domain)], 0); - value_set_si (new_domain->p[row][col_loop_old], 1); - value_set_si (new_domain->p[row][col_loop_strip], -1 * stride); - - /* Upper bound of a tile stops at "stride * outer_iv + stride - 1", - or at the old upper bound that is not modified. */ - row = new_domain->NbRows - 1; - value_set_si (new_domain->p[row][0], 1); - value_set_si (new_domain->p[row][col_loop_old], -1); - value_set_si (new_domain->p[row][col_loop_strip], stride); - value_set_si (new_domain->p[row][const_column_index (new_domain)], - stride - 1); - - cloog_matrix_free (domain); - - /* Update static schedule. */ - { - int i; - int nb_loops = gbb_nb_loops (gb); - lambda_vector new_schedule = lambda_vector_new (nb_loops + 1); - - for (i = 0; i <= loop_depth; i++) - new_schedule[i] = GBB_STATIC_SCHEDULE (gb)[i]; - - for (i = loop_depth + 1; i <= nb_loops - 2; i++) - new_schedule[i + 2] = GBB_STATIC_SCHEDULE (gb)[i]; - - GBB_STATIC_SCHEDULE (gb) = new_schedule; - } -} - -/* Returns true when the strip mining of LOOP_INDEX by STRIDE is - profitable or undecidable. GB is the statement around which the - loops will be strip mined. */ - -static bool -strip_mine_profitable_p (graphite_bb_p gb, int stride, - int loop_index) -{ - bool res = true; - edge exit = NULL; - tree niter; - loop_p loop; - long niter_val; - - loop = VEC_index (loop_p, GBB_LOOPS (gb), loop_index); - exit = single_exit (loop); - - niter = find_loop_niter (loop, &exit); - if (niter == chrec_dont_know - || TREE_CODE (niter) != INTEGER_CST) - return true; - - niter_val = int_cst_value (niter); - - if (niter_val < stride) - { - res = false; - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "\nStrip Mining is not profitable for loop %d:", - loop->num); - fprintf (dump_file, "number of iterations is too low.\n"); - } - } - - return res; -} - -/* Determines when the interchange of LOOP_A and LOOP_B belonging to - SCOP is legal. DEPTH is the number of loops around. */ - -static bool -is_interchange_valid (scop_p scop, int loop_a, int loop_b, int depth) -{ - bool res; - VEC (ddr_p, heap) *dependence_relations; - VEC (data_reference_p, heap) *datarefs; - - struct loop *nest = VEC_index (loop_p, SCOP_LOOP_NEST (scop), loop_a); - lambda_trans_matrix trans; - - gcc_assert (loop_a < loop_b); - - dependence_relations = VEC_alloc (ddr_p, heap, 10 * 10); - datarefs = VEC_alloc (data_reference_p, heap, 10); - - if (!compute_data_dependences_for_loop (nest, true, &datarefs, - &dependence_relations)) - return false; - - if (dump_file && (dump_flags & TDF_DETAILS)) - dump_ddrs (dump_file, dependence_relations); - - trans = lambda_trans_matrix_new (depth, depth); - lambda_matrix_id (LTM_MATRIX (trans), depth); - - lambda_matrix_row_exchange (LTM_MATRIX (trans), 0, loop_b - loop_a); - - if (!lambda_transform_legal_p (trans, depth, dependence_relations)) - { - lambda_matrix_row_exchange (LTM_MATRIX (trans), 0, loop_b - loop_a); - res = false; - } - else - res = true; - - free_dependence_relations (dependence_relations); - free_data_refs (datarefs); - return res; -} - -/* Loop block the LOOPS innermost loops of GB with stride size STRIDE. - - Example - - for (i = 0; i <= 50; i++=4) - for (k = 0; k <= 100; k++=4) - for (l = 0; l <= 200; l++=4) - A - - To strip mine the two inner most loops with stride = 4 call: - - graphite_trans_bb_block (A, 4, 2) - - for (i = 0; i <= 50; i++) - for (kk = 0; kk <= 100; kk+=4) - for (ll = 0; ll <= 200; ll+=4) - for (k = kk; k <= min (100, kk + 3); k++) - for (l = ll; l <= min (200, ll + 3); l++) - A -*/ - -static bool -graphite_trans_bb_block (graphite_bb_p gb, int stride, int loops) -{ - int i, j; - int nb_loops = gbb_nb_loops (gb); - int start = nb_loops - loops; - scop_p scop = GBB_SCOP (gb); - - gcc_assert (scop_contains_loop (scop, gbb_loop (gb))); - - for (i = start ; i < nb_loops; i++) - for (j = i + 1; j < nb_loops; j++) - if (!is_interchange_valid (scop, i, j, nb_loops)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - "\nInterchange not valid for loops %d and %d:\n", i, j); - return false; - } - else if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - "\nInterchange valid for loops %d and %d:\n", i, j); - - /* Check if strip mining is profitable for every loop. */ - for (i = 0; i < nb_loops - start; i++) - if (!strip_mine_profitable_p (gb, stride, start + i)) - return false; - - /* Strip mine loops. */ - for (i = 0; i < nb_loops - start; i++) - graphite_trans_bb_strip_mine (gb, start + 2 * i, stride); - - /* Interchange loops. */ - for (i = 1; i < nb_loops - start; i++) - graphite_trans_bb_move_loop (gb, start + 2 * i, start + i); - - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "\nLoops containing BB %d will be loop blocked.\n", - GBB_BB (gb)->index); + if (dump_file && dump_flags) + dump_function_to_file (current_function_decl, dump_file, dump_flags); return true; } -/* Loop block LOOPS innermost loops of a loop nest. BBS represent the - basic blocks that belong to the loop nest to be blocked. */ - -static bool -graphite_trans_loop_block (VEC (graphite_bb_p, heap) *bbs, int loops) -{ - graphite_bb_p gb; - int i; - bool transform_done = false; - - /* TODO: - Calculate the stride size automatically. */ - int stride_size = 51; - - for (i = 0; VEC_iterate (graphite_bb_p, bbs, i, gb); i++) - transform_done |= graphite_trans_bb_block (gb, stride_size, loops); - - return transform_done; -} - -/* Loop block all basic blocks of SCOP. Return false when the - transform is not performed. */ - -static bool -graphite_trans_scop_block (scop_p scop) -{ - graphite_bb_p gb; - int i, j; - int last_nb_loops; - int nb_loops; - bool perfect = true; - bool transform_done = false; - - VEC (graphite_bb_p, heap) *bbs = VEC_alloc (graphite_bb_p, heap, 3); - int max_schedule = scop_max_loop_depth (scop) + 1; - lambda_vector last_schedule = lambda_vector_new (max_schedule); - - if (VEC_length (graphite_bb_p, SCOP_BBS (scop)) == 0) - return false; - - /* Get the data of the first bb. */ - gb = VEC_index (graphite_bb_p, SCOP_BBS (scop), 0); - last_nb_loops = gbb_nb_loops (gb); - lambda_vector_copy (GBB_STATIC_SCHEDULE (gb), last_schedule, - last_nb_loops + 1); - VEC_safe_push (graphite_bb_p, heap, bbs, gb); - - for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++) - { - /* We did the first bb before. */ - if (i == 0) - continue; - - nb_loops = gbb_nb_loops (gb); - - /* If the number of loops is unchanged and only the last element of the - schedule changes, we stay in the loop nest. */ - if (nb_loops == last_nb_loops - && (last_schedule [nb_loops + 1] - != GBB_STATIC_SCHEDULE (gb)[nb_loops + 1])) - { - VEC_safe_push (graphite_bb_p, heap, bbs, gb); - continue; - } - - /* Otherwise, we left the innermost loop. So check, if the last bb was in - a perfect loop nest and how many loops are contained in this perfect - loop nest. - - Count the number of zeros from the end of the schedule. They are the - number of surrounding loops. - - Example: - last_bb 2 3 2 0 0 0 0 3 - bb 2 4 0 - <------ j = 4 - - last_bb 2 3 2 0 0 0 0 3 - bb 2 3 2 0 1 - <-- j = 2 - - If there is no zero, there were other bbs in outer loops and the loop - nest is not perfect. */ - for (j = last_nb_loops - 1; j >= 0; j--) - { - if (last_schedule [j] != 0 - || (j <= nb_loops && GBB_STATIC_SCHEDULE (gb)[j] == 1)) - { - j--; - break; - } - } - - j++; - - /* Found perfect loop nest. */ - if (perfect && last_nb_loops - j >= 2) - transform_done |= graphite_trans_loop_block (bbs, last_nb_loops - j); - - /* Check if we start with a new loop. - - Example: - - last_bb 2 3 2 0 0 0 0 3 - bb 2 3 2 0 0 1 0 - - Here we start with the loop "2 3 2 0 0 1" - - last_bb 2 3 2 0 0 0 0 3 - bb 2 3 2 0 0 1 - - But here not, so the loop nest can never be perfect. */ - - perfect = (GBB_STATIC_SCHEDULE (gb)[nb_loops] == 0); - - /* Update the last_bb infos. We do not do that for the bbs in the same - loop, as the data we use is not changed. */ - last_nb_loops = nb_loops; - lambda_vector_copy (GBB_STATIC_SCHEDULE (gb), last_schedule, - nb_loops + 1); - VEC_truncate (graphite_bb_p, bbs, 0); - VEC_safe_push (graphite_bb_p, heap, bbs, gb); - } - - /* Check if the last loop nest was perfect. It is the same check as above, - but the comparison with the next bb is missing. */ - for (j = last_nb_loops - 1; j >= 0; j--) - if (last_schedule [j] != 0) - { - j--; - break; - } - - j++; - - /* Found perfect loop nest. */ - if (last_nb_loops - j >= 2) - transform_done |= graphite_trans_loop_block (bbs, last_nb_loops - j); - VEC_free (graphite_bb_p, heap, bbs); - - return transform_done; -} - -/* Apply graphite transformations to all the basic blocks of SCOP. */ - -static bool -graphite_apply_transformations (scop_p scop) -{ - bool transform_done = false; - - /* Sort the list of bbs. Keep them always sorted. */ - graphite_sort_gbbs (scop); - - if (flag_loop_block) - transform_done = graphite_trans_scop_block (scop); - - /* Generate code even if we did not apply any real transformation. - This also allows to check the performance for the identity - transformation: GIMPLE -> GRAPHITE -> GIMPLE - Keep in mind that CLooG optimizes in control, so the loop structure - may change, even if we only use -fgraphite-identity. */ - if (flag_graphite_identity) - transform_done = true; - - return transform_done; -} - -/* We limit all SCoPs to SCoPs, that are completely surrounded by a loop. - - Example: - - for (i | - { | - for (j | SCoP 1 - for (k | - } | - - * SCoP frontier, as this line is not surrounded by any loop. * - - for (l | SCoP 2 - - This is necessary as scalar evolution and parameter detection need a - outermost loop to initialize parameters correctly. - - TODO: FIX scalar evolution and parameter detection to allow more flexible - SCoP frontiers. */ +/* Finalize graphite: perform CFG cleanup when NEED_CFG_CLEANUP_P is + true. */ static void -limit_scops (void) +graphite_finalize (bool need_cfg_cleanup_p) { - VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap, 3); - - int i; - scop_p scop; - - for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++) - { - int j; - loop_p loop; - build_scop_bbs (scop); - - if (!build_scop_loop_nests (scop)) - continue; - - for (j = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), j, loop); j++) - if (!loop_in_sese_p (loop_outer (loop), SCOP_REGION (scop))) - { - sd_region open_scop; - open_scop.entry = loop->header; - open_scop.exit = single_exit (loop)->dest; - VEC_safe_push (sd_region, heap, tmp_scops, &open_scop); - } - } + if (need_cfg_cleanup_p) + cleanup_tree_cfg (); - free_scops (current_scops); - current_scops = VEC_alloc (scop_p, heap, 3); + cloog_finalize (); + free_original_copy_tables (); + free_aux_in_new_loops (); - create_sese_edges (tmp_scops); - build_graphite_scops (tmp_scops); - VEC_free (sd_region, heap, tmp_scops); + if (dump_file && dump_flags) + print_loops (dump_file, 3); } /* Perform a set of linear transforms on the loops of the current @@ -6109,82 +247,48 @@ graphite_transform_loops (void) { int i; scop_p scop; - bool transform_done = false; + bool need_cfg_cleanup_p = false; + VEC (scop_p, heap) *scops = NULL; + htab_t bb_pbb_mapping; - if (number_of_loops () <= 1) + if (!graphite_initialize ()) return; - current_scops = VEC_alloc (scop_p, heap, 3); - recompute_all_dominators (); - - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Graphite loop transformations \n"); - - initialize_original_copy_tables (); - cloog_initialize (); - build_scops (); - limit_scops (); + build_scops (&scops); if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "\nnumber of SCoPs: %d\n", - VEC_length (scop_p, current_scops)); - - for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++) { - build_scop_bbs (scop); - if (!build_scop_loop_nests (scop)) - continue; - - build_bb_loops (scop); - - if (!build_scop_conditions (scop)) - continue; + print_graphite_statistics (dump_file, scops); + print_global_statistics (dump_file); + } - find_scop_parameters (scop); - build_scop_context (scop); + bb_pbb_mapping = htab_create (10, bb_pbb_map_hash, eq_bb_pbb_map, free); - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "\n(In SCoP %d:\n", i); - fprintf (dump_file, "\nnumber of bbs: %d\n", - VEC_length (graphite_bb_p, SCOP_BBS (scop))); - fprintf (dump_file, "\nnumber of loops: %d)\n", - VEC_length (loop_p, SCOP_LOOP_NEST (scop))); - } + for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++) + { + bool transform_done = false; - if (!build_scop_iteration_domain (scop)) + if (!build_poly_scop (scop)) continue; - add_conditions_to_constraints (scop); - build_scop_canonical_schedules (scop); - - build_scop_data_accesses (scop); - build_scop_dynamic_schedules (scop); - - if (dump_file && (dump_flags & TDF_DETAILS)) - { - int nbrefs = nb_data_refs_in_scop (scop); - fprintf (dump_file, "\nnumber of data refs: %d\n", nbrefs); - } - - if (graphite_apply_transformations (scop)) - transform_done = gloog (scop, find_transform (scop)); -#ifdef ENABLE_CHECKING + if (apply_poly_transforms (scop)) + transform_done = gloog (scop, bb_pbb_mapping); else + check_poly_representation (scop); + + if (transform_done) { - struct clast_stmt *stmt = find_transform (scop); - cloog_clast_free (stmt); + scev_reset (); + need_cfg_cleanup_p = true; } -#endif } - /* Cleanup. */ - if (transform_done) - cleanup_tree_cfg (); + if (flag_loop_parallelize_all) + mark_loops_parallel (bb_pbb_mapping); - free_scops (current_scops); - cloog_finalize (); - free_original_copy_tables (); + htab_delete (bb_pbb_mapping); + free_scops (scops); + graphite_finalize (need_cfg_cleanup_p); } #else /* If Cloog is not available: #ifndef HAVE_cloog. */ diff --git a/gcc/graphite.h b/gcc/graphite.h index e663c2d0fe5..1007e9af410 100644 --- a/gcc/graphite.h +++ b/gcc/graphite.h @@ -21,556 +21,4 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_GRAPHITE_H #define GCC_GRAPHITE_H -#include "tree-data-ref.h" - -int ref_nb_loops (data_reference_p); - -typedef struct graphite_bb *graphite_bb_p; -DEF_VEC_P(graphite_bb_p); -DEF_VEC_ALLOC_P (graphite_bb_p, heap); - -DEF_VEC_P(scop_p); -DEF_VEC_ALLOC_P (scop_p, heap); - -static inline int scop_nb_loops (scop_p scop); -static inline unsigned scop_nb_params (scop_p scop); -static inline bool scop_contains_loop (scop_p scop, struct loop *loop); - -typedef struct graphite_bb -{ - basic_block bb; - scop_p scop; - - /* The static schedule contains the textual order for every loop layer. - - Example: - - S0 - for (i ...) - { - S1 - for (j ...) - { - S2 - S3 - } - S4 - } - S5 - for (k ...) - { - S6 - S7 - for (l ...) - { - S8 - } - S9 - } - S10 - - Schedules: - - | Depth - BB | 0 1 2 - ------------ - S0 | 0 - S1 | 1, 0 - S2 | 1, 1, 0 - S3 | 1, 1, 1 - S4 | 1, 2 - S5 | 2 - S6 | 3, 0 - S7 | 3, 1 - S8 | 3, 2, 0 - S9 | 3, 3 - S10| 4 - - Normalization rules: - - One SCoP can never contain two bbs with the same schedule timestamp. - - All bbs at the same loop depth have a consecutive ordering (no gaps). */ - lambda_vector static_schedule; - - /* The iteration domain of this bb. It contains this columns: - - In/Eq: If this line is a equation or inequation. - - For every loop iterator one column. - - One column for every parameter in this SCoP. - - The constant column to add integers to the (in)equations. - - Example: - - for (i = a - 7*b + 8; i <= 3*a + 13*b + 20; i++) - for (j = 2; j <= 2*i + 5; j++) - for (k = 0; k <= 5; k++) - S (i,j,k) - - Loop iterators: i, j, k - Parameters: a, b - - (I)eq i j k a b 1 - - 1 1 0 0 -1 7 -8 # i >= a - 7b + 8 - 1 -1 0 0 3 13 20 # i <= 3a + 13b + 20 - 1 0 1 0 0 0 -2 # j >= 2 - 1 2 -1 0 0 0 5 # j <= 2i + 5 - 1 0 0 1 0 0 0 # k >= 0 - 1 0 0 -1 0 0 5 # k <= 5 - - The number of loop iterators may change and is not connected to the - number of loops, that surrounded this bb in the gimple code. */ - CloogMatrix *domain; - - /* Lists containing the restrictions of the conditional statements - dominating this bb. This bb can only be executed, if all conditions - are true. - - Example: - - for (i = 0; i <= 20; i++) - { - A - - if (2i <= 8) - B - } - - So for B there is an additional condition (2i <= 8). - - TODO: Add these restrictions to the domain matrix. - - List of COND_EXPR and SWITCH_EXPR. A COND_EXPR is true only if the - corresponding element in CONDITION_CASES is not NULL_TREE. For a - SWITCH_EXPR the corresponding element in CONDITION_CASES is a - CASE_LABEL_EXPR. */ - VEC (gimple, heap) *conditions; - VEC (gimple, heap) *condition_cases; - - /* LOOPS contains for every column in the graphite domain the corresponding - gimple loop. If there exists no corresponding gimple loop LOOPS contains - NULL. - - Example: - - Original code: - - for (i = 0; i <= 20; i++) - for (j = 5; j <= 10; j++) - A - - Original domain: - - (I)eq i j 1 - 1 1 0 0 # i >= 0 - 1 -1 0 20 # i <= 20 - 1 0 1 0 # j >= 0 - 1 0 -1 10 # j <= 10 - - Original loops vector: - 0 1 - Loop i Loop j - - After some changes (Exchange i and j, strip-mine i): - - Domain: - - (I)eq j ii i k 1 - 1 0 0 1 0 0 # i >= 0 - 1 0 0 -1 0 20 # i <= 20 - 1 1 0 0 0 0 # j >= 0 - 1 -1 0 0 0 10 # j <= 10 - 1 0 -1 1 0 0 # ii <= i - 1 0 1 -1 0 1 # ii + 1 >= i - 1 0 -1 0 2 0 # ii <= 2k - 1 0 1 0 -2 0 # ii >= 2k - - Iterator vector: - 0 1 2 3 - Loop j NULL Loop i NULL - - Means the original loop i is now at column two of the domain and - loop j in the original loop nest is now at column 0. Column 1 and - 3 are emtpy. */ - VEC (loop_p, heap) *loops; - - lambda_vector compressed_alpha_matrix; - CloogMatrix *dynamic_schedule; - VEC (data_reference_p, heap) *data_refs; - htab_t cloog_iv_types; -} *gbb_p; - -#define GBB_BB(GBB) GBB->bb -#define GBB_SCOP(GBB) GBB->scop -#define GBB_STATIC_SCHEDULE(GBB) GBB->static_schedule -#define GBB_DATA_REFS(GBB) GBB->data_refs -#define GBB_ALPHA(GBB) GBB->compressed_alpha_matrix -#define GBB_DYNAMIC_SCHEDULE(GBB) GBB->dynamic_schedule -#define GBB_DOMAIN(GBB) GBB->domain -#define GBB_CONDITIONS(GBB) GBB->conditions -#define GBB_CONDITION_CASES(GBB) GBB->condition_cases -#define GBB_LOOPS(GBB) GBB->loops -#define GBB_CLOOG_IV_TYPES(GBB) GBB->cloog_iv_types - -/* Return the loop that contains the basic block GBB. */ - -static inline struct loop * -gbb_loop (struct graphite_bb *gbb) -{ - return GBB_BB (gbb)->loop_father; -} - -int nb_loops_around_gb (graphite_bb_p); - -/* Calculate the number of loops around GB in the current SCOP. Only - works if GBB_DOMAIN is built. */ - -static inline int -gbb_nb_loops (const struct graphite_bb *gb) -{ - scop_p scop = GBB_SCOP (gb); - - if (GBB_DOMAIN (gb) == NULL) - return 0; - - return GBB_DOMAIN (gb)->NbColumns - scop_nb_params (scop) - 2; -} - -/* Returns the gimple loop, that corresponds to the loop_iterator_INDEX. - If there is no corresponding gimple loop, we return NULL. */ - -static inline loop_p -gbb_loop_at_index (graphite_bb_p gb, int index) -{ - return VEC_index (loop_p, GBB_LOOPS (gb), index); -} - -/* Returns the index of LOOP in the loop nest around GB. */ - -static inline int -gbb_loop_index (graphite_bb_p gb, loop_p loop) -{ - int i; - loop_p l; - - for (i = 0; VEC_iterate (loop_p, GBB_LOOPS (gb), i, l); i++) - if (loop == l) - return i; - - gcc_unreachable(); -} - -struct loop_to_cloog_loop_str -{ - unsigned int loop_num; - unsigned int loop_position; /* The column that represents this loop. */ - CloogLoop *cloog_loop; -}; - -typedef struct name_tree_d -{ - tree t; - const char *name; - struct loop *loop; -} *name_tree; - -DEF_VEC_P(name_tree); -DEF_VEC_ALLOC_P (name_tree, heap); - -/* A Single Entry, Single Exit region is a part of the CFG delimited - by two edges. */ -typedef struct sese_d -{ - /* Single ENTRY and single EXIT from the SESE region. */ - edge entry, exit; - - /* REGION_BASIC_BLOCKS contains the set of all the basic blocks - belonging to the SESE region. */ - struct pointer_set_t *region_basic_blocks; - - /* An SSA_NAME version is flagged in the LIVEOUT bitmap if the - SSA_NAME is defined inside and used outside the SESE region. */ - bitmap liveout; - - /* The overall number of SSA_NAME versions used to index LIVEIN. */ - int num_ver; - - /* For each SSA_NAME version VER in LIVEOUT, LIVEIN[VER] contains - the set of basic blocks indices that contain a use of VER. */ - bitmap *livein; -} *sese; - -#define SESE_ENTRY(S) (S->entry) -#define SESE_EXIT(S) (S->exit) -#define SESE_REGION_BBS(S) (S->region_basic_blocks) -#define SESE_LIVEOUT(S) (S->liveout) -#define SESE_LIVEIN(S) (S->livein) -#define SESE_LIVEIN_VER(S, I) (S->livein[I]) -#define SESE_NUM_VER(S) (S->num_ver) - -extern sese new_sese (edge, edge); -extern void free_sese (sese); -extern void sese_build_livein_liveouts (sese); - -/* A SCOP is a Static Control Part of the program, simple enough to be - represented in polyhedral form. */ -struct scop -{ - /* A SCOP is defined as a SESE region. */ - sese region; - - /* All the basic blocks in this scop that contain memory references - and that will be represented as statements in the polyhedral - representation. */ - VEC (graphite_bb_p, heap) *bbs; - - lambda_vector static_schedule; - - /* Parameters used within the SCOP. */ - VEC (name_tree, heap) *params; - - /* A collection of old induction variables*/ - VEC (name_tree, heap) *old_ivs; - - /* Loops completely contained in the SCOP. */ - bitmap loops; - VEC (loop_p, heap) *loop_nest; - - /* ??? It looks like a global mapping loop_id -> cloog_loop would work. */ - htab_t loop2cloog_loop; - - /* Cloog representation of this scop. */ - CloogProgram *program; - - /* Are we allowed to add more params? This is for debugging purpose. We - can only add new params before generating the bb domains, otherwise they - become invalid. */ - bool add_params; - - /* LIVEOUT_RENAMES registers the rename mapping that has to be - applied after code generation. */ - htab_t liveout_renames; -}; - -#define SCOP_BBS(S) S->bbs -#define SCOP_REGION(S) S->region -/* SCOP_ENTRY bb dominates all the bbs of the scop. SCOP_EXIT bb - post-dominates all the bbs of the scop. SCOP_EXIT potentially - contains non affine data accesses, side effect statements or - difficult constructs, and thus is not considered part of the scop, - but just a boundary. SCOP_ENTRY is considered part of the scop. */ -#define SCOP_ENTRY(S) (SESE_ENTRY (SCOP_REGION (S))->dest) -#define SCOP_EXIT(S) (SESE_EXIT (SCOP_REGION (S))->dest) -#define SCOP_REGION_BBS(S) (SESE_REGION_BBS (SCOP_REGION (S))) -#define SCOP_STATIC_SCHEDULE(S) S->static_schedule -#define SCOP_LOOPS(S) S->loops -#define SCOP_LOOP_NEST(S) S->loop_nest -#define SCOP_ADD_PARAMS(S) S->add_params -#define SCOP_PARAMS(S) S->params -#define SCOP_OLDIVS(S) S->old_ivs -#define SCOP_PROG(S) S->program -#define SCOP_LOOP2CLOOG_LOOP(S) S->loop2cloog_loop -#define SCOP_LOOPS_MAPPING(S) S->loops_mapping -#define SCOP_LIVEOUT_RENAMES(S) S->liveout_renames - -extern void debug_scop (scop_p, int); -extern void debug_scops (int); -extern void print_graphite_bb (FILE *, graphite_bb_p, int, int); -extern void debug_gbb (graphite_bb_p, int); -extern void dot_scop (scop_p); -extern void dot_all_scops (void); -extern void debug_clast_stmt (struct clast_stmt *); -extern void debug_rename_map (htab_t); -extern void debug_ivtype_map (htab_t); -extern void debug_loop_vec (graphite_bb_p); -extern void debug_oldivs (scop_p); - -/* Describes the type of an iv stack entry. */ -typedef enum { - iv_stack_entry_unknown = 0, - iv_stack_entry_iv, - iv_stack_entry_const -} iv_stack_entry_kind; - -/* Data contained in an iv stack entry. */ -typedef union iv_stack_entry_data_union -{ - name_tree iv; - tree constant; -} iv_stack_entry_data; - -/* Datatype for loop iv stack entry. */ -typedef struct iv_stack_entry_struct -{ - iv_stack_entry_kind kind; - iv_stack_entry_data data; -} iv_stack_entry; - -typedef iv_stack_entry *iv_stack_entry_p; - -DEF_VEC_P(iv_stack_entry_p); -DEF_VEC_ALLOC_P(iv_stack_entry_p,heap); - -typedef VEC(iv_stack_entry_p, heap) **loop_iv_stack; -extern void debug_loop_iv_stack (loop_iv_stack); - -/* Return the old induction variable of the LOOP that is in normal - form in SCOP. */ - -static inline tree -oldiv_for_loop (scop_p scop, loop_p loop) -{ - int i; - name_tree iv; - - if (!loop) - return NULL_TREE; - - for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, iv); i++) - if (iv->loop == loop) - return iv->t; - - return NULL_TREE; -} - -/* Return the number of gimple loops contained in SCOP. */ - -static inline int -scop_nb_loops (scop_p scop) -{ - return VEC_length (loop_p, SCOP_LOOP_NEST (scop)); -} - -/* Returns the number of parameters for SCOP. */ - -static inline unsigned -scop_nb_params (scop_p scop) -{ - return VEC_length (name_tree, SCOP_PARAMS (scop)); -} - -/* Return the dimension of the domains for SCOP. */ - -static inline int -scop_dim_domain (scop_p scop) -{ - return scop_nb_loops (scop) + scop_nb_params (scop) + 1; -} - -/* Return the dimension of the domains for GB. */ - -static inline int -gbb_dim_domain (graphite_bb_p gb) -{ - return scop_dim_domain (GBB_SCOP (gb)); -} - -/* Returns the dimensionality of a loop iteration domain for a given - loop, identified by LOOP_NUM, with respect to SCOP. */ - -static inline int -loop_domain_dim (unsigned int loop_num, scop_p scop) -{ - struct loop_to_cloog_loop_str tmp, *slot; - htab_t tab = SCOP_LOOP2CLOOG_LOOP (scop); - - tmp.loop_num = loop_num; - slot = (struct loop_to_cloog_loop_str *) htab_find (tab, &tmp); - - /* The loop containing the entry of the scop is not always part of - the SCoP, and it is not registered in SCOP_LOOP2CLOOG_LOOP. */ - if (!slot) - return scop_nb_params (scop) + 2; - - return cloog_domain_dim (cloog_loop_domain (slot->cloog_loop)) + 2; -} - -/* Returns the dimensionality of a loop iteration vector in a loop - iteration domain for a given loop (identified by LOOP_NUM) with - respect to SCOP. */ - -static inline int -loop_iteration_vector_dim (unsigned int loop_num, scop_p scop) -{ - return loop_domain_dim (loop_num, scop) - 2 - scop_nb_params (scop); -} - -/* Checks, if SCOP contains LOOP. */ - -static inline bool -scop_contains_loop (scop_p scop, struct loop *loop) -{ - return bitmap_bit_p (SCOP_LOOPS (scop), loop->num); -} - -/* Returns the index of LOOP in the domain matrix for the SCOP. */ - -static inline int -scop_loop_index (scop_p scop, struct loop *loop) -{ - unsigned i; - struct loop *l; - - gcc_assert (scop_contains_loop (scop, loop)); - - for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, l); i++) - if (l == loop) - return i; - - gcc_unreachable(); -} - -/* Return the index of innermost loop that contains the basic block - GBB. */ - -static inline int -gbb_inner_most_loop_index (scop_p scop, graphite_bb_p gb) -{ - return scop_loop_index(scop, gbb_loop (gb)); -} - -/* Return the outermost loop that contains the loop LOOP. The outer - loops are searched until a sibling for the outer loop is found. */ - -static struct loop * -outer_most_loop_1 (scop_p scop, struct loop* loop, struct loop* current_outer) -{ - return (!scop_contains_loop (scop, loop)) ? current_outer : - (loop->next != NULL) ? loop : - outer_most_loop_1 (scop, loop_outer (loop), loop); -} - -/* Return the outermost loop that contains the loop LOOP. */ - -static struct loop * -outer_most_loop (scop_p scop, struct loop *loop) -{ - return outer_most_loop_1 (scop, loop, NULL); -} - -/* Return the index of the outermost loop that contains the basic - block BB. */ - -static inline int -gbb_outer_most_loop_index (scop_p scop, graphite_bb_p gb) -{ - return scop_loop_index (scop, outer_most_loop (scop, gbb_loop (gb))); -} - -/* Return the loop depth of LOOP in SCOP. */ - -static inline unsigned int -scop_gimple_loop_depth (scop_p scop, loop_p loop) -{ - unsigned int depth = 0; - - loop = loop_outer (loop); - - while (scop_contains_loop (scop, loop)) - { - depth++; - loop = loop_outer (loop); - } - - return depth; -} - #endif /* GCC_GRAPHITE_H */ diff --git a/gcc/gthr-dce.h b/gcc/gthr-dce.h index be92813dc23..4226359f0a0 100644 --- a/gcc/gthr-dce.h +++ b/gcc/gthr-dce.h @@ -37,6 +37,15 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see DCE threads are based on POSIX threads draft 4, and many things have changed since then. */ +/* Make sure CONST_CAST2 (original in system.h) is defined. */ +#ifndef CONST_CAST2 +#ifdef __cplusplus +#define CONST_CAST2(TOTYPE,FROMTYPE,X) (const_cast<TOTYPE> (X)) +#else +#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((__extension__(union {FROMTYPE _q; TOTYPE _nq;})(X))._nq) +#endif +#endif + #define __GTHREADS 1 #include <pthread.h> @@ -462,7 +471,8 @@ __gthread_getspecific (__gthread_key_t __key) static inline int __gthread_setspecific (__gthread_key_t __key, const void *__ptr) { - return __gthrw_(pthread_setspecific) (__key, (void *) __ptr); + return __gthrw_(pthread_setspecific) + (__key, CONST_CAST2(void *, const void *, __ptr)); } static inline void diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 040096fa0d1..dde8181c86c 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1227,6 +1227,8 @@ cgraph_decide_inlining (void) && !node->needed && node->local.inlinable && node->callers->inline_failed + && node->callers->caller != node + && node->callers->caller->global.inlined_to != node && !gimple_call_cannot_inline_p (node->callers->call_stmt) && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl)) diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 1a7003295a2..8308aa36f8f 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -585,25 +585,28 @@ ipa_compute_jump_functions (struct cgraph_edge *cs) compute_cst_member_ptr_arguments (arguments->jump_functions, call); } -/* If RHS looks like a rhs of a statement loading pfn from a member pointer - formal parameter, return the parameter, otherwise return NULL. */ +/* If RHS looks like a rhs of a statement loading pfn from a member + pointer formal parameter, return the parameter, otherwise return + NULL. If USE_DELTA, then we look for a use of the delta field + rather than the pfn. */ static tree -ipa_get_member_ptr_load_param (tree rhs) +ipa_get_member_ptr_load_param (tree rhs, bool use_delta) { tree rec, fld; tree ptr_field; + tree delta_field; if (TREE_CODE (rhs) != COMPONENT_REF) return NULL_TREE; rec = TREE_OPERAND (rhs, 0); if (TREE_CODE (rec) != PARM_DECL - || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, NULL)) + || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, &delta_field)) return NULL_TREE; fld = TREE_OPERAND (rhs, 1); - if (fld == ptr_field) + if (use_delta ? (fld == delta_field) : (fld == ptr_field)) return rec; else return NULL_TREE; @@ -613,7 +616,7 @@ ipa_get_member_ptr_load_param (tree rhs) parameter, this function returns that parameter. */ static tree -ipa_get_stmt_member_ptr_load_param (gimple stmt) +ipa_get_stmt_member_ptr_load_param (gimple stmt, bool use_delta) { tree rhs; @@ -621,7 +624,7 @@ ipa_get_stmt_member_ptr_load_param (gimple stmt) return NULL_TREE; rhs = gimple_assign_rhs1 (stmt); - return ipa_get_member_ptr_load_param (rhs); + return ipa_get_member_ptr_load_param (rhs, use_delta); } /* Returns true iff T is an SSA_NAME defined by a statement. */ @@ -756,15 +759,15 @@ ipa_analyze_call_uses (struct ipa_node_params *info, gimple call) d1 = SSA_NAME_DEF_STMT (n1); d2 = SSA_NAME_DEF_STMT (n2); - if ((rec = ipa_get_stmt_member_ptr_load_param (d1))) + if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false))) { - if (ipa_get_stmt_member_ptr_load_param (d2)) + if (ipa_get_stmt_member_ptr_load_param (d2, false)) return; bb = gimple_bb (d1); virt_bb = gimple_bb (d2); } - else if ((rec = ipa_get_stmt_member_ptr_load_param (d2))) + else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false))) { bb = gimple_bb (d2); virt_bb = gimple_bb (d1); @@ -817,7 +820,10 @@ ipa_analyze_call_uses (struct ipa_node_params *info, gimple call) def = SSA_NAME_DEF_STMT (cond); } - rec2 = ipa_get_stmt_member_ptr_load_param (def); + rec2 = ipa_get_stmt_member_ptr_load_param (def, + (TARGET_PTRMEMFUNC_VBIT_LOCATION + == ptrmemfunc_vbit_in_delta)); + if (rec != rec2) return; diff --git a/gcc/ipa-struct-reorg.c b/gcc/ipa-struct-reorg.c index 199c5855e2e..bc84eee372b 100644 --- a/gcc/ipa-struct-reorg.c +++ b/gcc/ipa-struct-reorg.c @@ -658,7 +658,7 @@ make_edge_and_fix_phis_of_dest (basic_block bb, edge e) { gimple phi = gsi_stmt (si); arg = PHI_ARG_DEF_FROM_EDGE (phi, e); - add_phi_arg (phi, arg, new_e); + add_phi_arg (phi, arg, new_e, gimple_phi_arg_location_from_edge (phi, e)); } return new_e; diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index d6c87f45a10..d78ff733818 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,16 @@ +2009-07-31 Andrew Haley <aph@redhat.com> + + PR java/40867 + * decl.c (java_replace_references): Set EXPR_LOCATION on all + generated expressions. + (binding_level.loc): new field. + (clear_binding_level): Initialize loc. + (set_input_location): New function. + (pushlevel): Set new binding_level.loc. + (poplevel): Set EXPR_LOCATION on the new BIND_EXPR_BODY. + (start_java_method): Set DECL_SOURCE_LOCATION of this new method. + (java_add_stmt): Set the EXPR_LOCATION on all subtrees of new_stmt. + 2009-07-17 Richard Guenther <rguenther@suse.de> PR c/40401 diff --git a/gcc/java/decl.c b/gcc/java/decl.c index 8c327fa97d3..4ab67d6cf51 100644 --- a/gcc/java/decl.c +++ b/gcc/java/decl.c @@ -349,6 +349,7 @@ java_replace_references (tree *tp, int *walk_subtrees, { if (TREE_CODE (*tp) == MODIFY_EXPR) { + source_location loc = EXPR_LOCATION (*tp); tree lhs = TREE_OPERAND (*tp, 0); /* This is specific to the bytecode compiler. If a variable has LOCAL_SLOT_P set, replace an assignment to it with an assignment @@ -361,9 +362,12 @@ java_replace_references (tree *tp, int *walk_subtrees, tree new_lhs = java_replace_reference (lhs, /* want_lvalue */ true); tree new_rhs = build1 (NOP_EXPR, TREE_TYPE (new_lhs), TREE_OPERAND (*tp, 1)); - *tp = build2 (MODIFY_EXPR, TREE_TYPE (new_lhs), - new_lhs, new_rhs); - *tp = build1 (NOP_EXPR, TREE_TYPE (lhs), *tp); + tree tem = build2 (MODIFY_EXPR, TREE_TYPE (new_lhs), + new_lhs, new_rhs); + *tp = build1 (NOP_EXPR, TREE_TYPE (lhs), tem); + SET_EXPR_LOCATION (tem, loc); + SET_EXPR_LOCATION (new_rhs, loc); + SET_EXPR_LOCATION (*tp, loc); } } if (TREE_CODE (*tp) == VAR_DECL) @@ -418,6 +422,9 @@ struct GTY(()) /* Binding depth at which this level began. Used only for debugging. */ unsigned binding_depth; + + /* The location at which this level began. */ + source_location loc; }; #define NULL_BINDING_LEVEL (struct binding_level *) NULL @@ -458,10 +465,11 @@ static const struct binding_level clear_binding_level NULL, /* stmts */ NULL, /* exception_range */ 0, /* binding_depth */ + 0, /* loc */ }; tree java_global_trees[JTI_MAX]; - + /* Build (and pushdecl) a "promoted type" for all standard types shorter than int. */ @@ -1394,7 +1402,8 @@ pushlevel (int unused ATTRIBUTE_UNUSED) *newlevel = clear_binding_level; newlevel->level_chain = current_binding_level; - current_binding_level = newlevel; + newlevel->loc = input_location; + current_binding_level = newlevel; #if defined(DEBUG_JAVA_BINDING_LEVELS) newlevel->binding_depth = binding_depth; indent (); @@ -1509,6 +1518,8 @@ poplevel (int keep, int reverse, int functionbody) if (BIND_EXPR_BODY (bind) == NULL) BIND_EXPR_BODY (bind) = build_java_empty_stmt (); + SET_EXPR_LOCATION (bind, current_binding_level->loc); + current_binding_level->stmts = NULL; } else @@ -1876,6 +1887,7 @@ start_java_method (tree fndecl) type_map[i++] = NULL_TREE; build_result_decl (fndecl); + DECL_SOURCE_LOCATION (fndecl) = input_location; /* Push local variables. */ pushlevel (2); @@ -2037,6 +2049,26 @@ add_stmt_to_compound (tree existing, tree type, tree stmt) return stmt; } +/* If this node is an expr, mark its input location. Called from + walk_tree(). */ + +static tree +set_input_location (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED) +{ + tree t = *tp; + + if (CAN_HAVE_LOCATION_P (t)) + { + if (EXPR_HAS_LOCATION(t)) + return t; /* Don't walk any further into this expr. */ + else + SET_EXPR_LOCATION (t, input_location); + } + + return NULL_TREE; /* Continue walking this expr. */ +} + /* Add a statement to the statement_list currently being constructed. If the statement_list is null, we don't create a singleton list. This is necessary because poplevel() assumes that adding a @@ -2049,8 +2081,8 @@ java_add_stmt (tree new_stmt) tree_stmt_iterator i; if (input_filename) - SET_EXPR_LOCATION (new_stmt, input_location); - + walk_tree (&new_stmt, set_input_location, NULL, NULL); + if (stmts == NULL) return current_binding_level->stmts = new_stmt; diff --git a/gcc/lambda-code.c b/gcc/lambda-code.c index 852be11153c..e7a49951a67 100644 --- a/gcc/lambda-code.c +++ b/gcc/lambda-code.c @@ -2343,6 +2343,10 @@ can_convert_to_perfect_nest (struct loop *loop) return false; } + +DEF_VEC_I(source_location); +DEF_VEC_ALLOC_I(source_location,heap); + /* Transform the loop nest into a perfect nest, if possible. LOOP is the loop nest to transform into a perfect nest LBOUNDS are the lower bounds for the loops to transform @@ -2400,6 +2404,7 @@ perfect_nestify (struct loop *loop, gimple stmt; tree oldivvar, ivvar, ivvarinced; VEC(tree,heap) *phis = NULL; + VEC(source_location,heap) *locations = NULL; htab_t replacements = NULL; /* Create the new loop. */ @@ -2412,8 +2417,11 @@ perfect_nestify (struct loop *loop, { phi = gsi_stmt (bsi); VEC_reserve (tree, heap, phis, 2); + VEC_reserve (source_location, heap, locations, 1); VEC_quick_push (tree, phis, PHI_RESULT (phi)); VEC_quick_push (tree, phis, PHI_ARG_DEF (phi, 0)); + VEC_quick_push (source_location, locations, + gimple_phi_arg_location (phi, 0)); } e = redirect_edge_and_branch (single_succ_edge (preheaderbb), headerbb); @@ -2426,10 +2434,12 @@ perfect_nestify (struct loop *loop, { tree def; tree phiname; + source_location locus; def = VEC_pop (tree, phis); phiname = VEC_pop (tree, phis); + locus = VEC_pop (source_location, locations); phi = create_phi_node (phiname, preheaderbb); - add_phi_arg (phi, def, single_pred_edge (preheaderbb)); + add_phi_arg (phi, def, single_pred_edge (preheaderbb), locus); } flush_pending_stmts (e); VEC_free (tree, heap, phis); diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 82827bf762a..087f6fc42f4 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -3013,8 +3013,8 @@ expand_parallel_call (struct omp_region *region, basic_block bb, { gimple phi = create_phi_node (tmp_join, bb); SSA_NAME_DEF_STMT (tmp_join) = phi; - add_phi_arg (phi, tmp_then, e_then); - add_phi_arg (phi, tmp_else, e_else); + add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION); + add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION); } val = tmp_join; @@ -4508,6 +4508,7 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd) gsi_next (&psi), ++i) { gimple nphi; + source_location locus; phi = gsi_stmt (psi); t = gimple_phi_result (phi); @@ -4516,12 +4517,15 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd) SSA_NAME_DEF_STMT (t) = nphi; t = PHI_ARG_DEF_FROM_EDGE (phi, se); + locus = gimple_phi_arg_location_from_edge (phi, se); + /* A special case -- fd->loop.v is not yet computed in iter_part_bb, we need to use v_extra instead. */ if (t == fd->loop.v) t = v_extra; - add_phi_arg (nphi, t, ene); - add_phi_arg (nphi, redirect_edge_var_map_def (vm), re); + add_phi_arg (nphi, t, ene, locus); + locus = redirect_edge_var_map_location (vm); + add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus); } gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head)); redirect_edge_var_map_clear (re); @@ -4536,8 +4540,10 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd) /* Make phi node for trip. */ phi = create_phi_node (trip_main, iter_part_bb); SSA_NAME_DEF_STMT (trip_main) = phi; - add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb)); - add_phi_arg (phi, trip_init, single_succ_edge (entry_bb)); + add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb), + UNKNOWN_LOCATION); + add_phi_arg (phi, trip_init, single_succ_edge (entry_bb), + UNKNOWN_LOCATION); } set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb); @@ -6925,7 +6931,7 @@ struct gimple_opt_pass pass_diagnose_omp_blocks = { { GIMPLE_PASS, - "diagnose_omp_blocks", /* name */ + "*diagnose_omp_blocks", /* name */ gate_diagnose_omp_blocks, /* gate */ diagnose_omp_structured_block_errors, /* execute */ NULL, /* sub */ diff --git a/gcc/passes.c b/gcc/passes.c index 9ad672c477a..8d5ec3eeb7c 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -658,6 +658,11 @@ init_optimization_passes (void) NEXT_PASS (pass_loop_distribution); NEXT_PASS (pass_linear_transform); NEXT_PASS (pass_graphite_transforms); + { + struct opt_pass **p = &pass_graphite_transforms.pass.sub; + NEXT_PASS (pass_dce_loop); + NEXT_PASS (pass_lim); + } NEXT_PASS (pass_iv_canon); NEXT_PASS (pass_if_conversion); NEXT_PASS (pass_vectorize); diff --git a/gcc/sese.c b/gcc/sese.c new file mode 100644 index 00000000000..25c5703ec71 --- /dev/null +++ b/gcc/sese.c @@ -0,0 +1,1386 @@ +/* Single entry single exit control flow regions. + Copyright (C) 2008, 2009 Free Software Foundation, Inc. + Contributed by Jan Sjodin <jan.sjodin@amd.com> and + Sebastian Pop <sebastian.pop@amd.com>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "ggc.h" +#include "tree.h" +#include "rtl.h" +#include "basic-block.h" +#include "diagnostic.h" +#include "tree-flow.h" +#include "toplev.h" +#include "tree-dump.h" +#include "timevar.h" +#include "cfgloop.h" +#include "tree-chrec.h" +#include "tree-data-ref.h" +#include "tree-scalar-evolution.h" +#include "tree-pass.h" +#include "domwalk.h" +#include "value-prof.h" +#include "pointer-set.h" +#include "gimple.h" +#include "sese.h" + +/* Print to stderr the element ELT. */ + +static void +debug_rename_elt (rename_map_elt elt) +{ + fprintf (stderr, "("); + print_generic_expr (stderr, elt->old_name, 0); + fprintf (stderr, ", "); + print_generic_expr (stderr, elt->expr, 0); + fprintf (stderr, ")\n"); +} + +/* Helper function for debug_rename_map. */ + +static int +debug_rename_map_1 (void **slot, void *s ATTRIBUTE_UNUSED) +{ + struct rename_map_elt_s *entry = (struct rename_map_elt_s *) *slot; + debug_rename_elt (entry); + return 1; +} + +/* Print to stderr all the elements of MAP. */ + +void +debug_rename_map (htab_t map) +{ + htab_traverse (map, debug_rename_map_1, NULL); +} + +/* Computes a hash function for database element ELT. */ + +hashval_t +rename_map_elt_info (const void *elt) +{ + return htab_hash_pointer (((const struct rename_map_elt_s *) elt)->old_name); +} + +/* Compares database elements E1 and E2. */ + +int +eq_rename_map_elts (const void *e1, const void *e2) +{ + const struct rename_map_elt_s *elt1 = (const struct rename_map_elt_s *) e1; + const struct rename_map_elt_s *elt2 = (const struct rename_map_elt_s *) e2; + + return (elt1->old_name == elt2->old_name); +} + + + +/* Print to stderr the element ELT. */ + +static void +debug_ivtype_elt (ivtype_map_elt elt) +{ + fprintf (stderr, "(%s, ", elt->cloog_iv); + print_generic_expr (stderr, elt->type, 0); + fprintf (stderr, ")\n"); +} + +/* Helper function for debug_ivtype_map. */ + +static int +debug_ivtype_map_1 (void **slot, void *s ATTRIBUTE_UNUSED) +{ + struct ivtype_map_elt_s *entry = (struct ivtype_map_elt_s *) *slot; + debug_ivtype_elt (entry); + return 1; +} + +/* Print to stderr all the elements of MAP. */ + +void +debug_ivtype_map (htab_t map) +{ + htab_traverse (map, debug_ivtype_map_1, NULL); +} + +/* Computes a hash function for database element ELT. */ + +hashval_t +ivtype_map_elt_info (const void *elt) +{ + return htab_hash_pointer (((const struct ivtype_map_elt_s *) elt)->cloog_iv); +} + +/* Compares database elements E1 and E2. */ + +int +eq_ivtype_map_elts (const void *e1, const void *e2) +{ + const struct ivtype_map_elt_s *elt1 = (const struct ivtype_map_elt_s *) e1; + const struct ivtype_map_elt_s *elt2 = (const struct ivtype_map_elt_s *) e2; + + return (elt1->cloog_iv == elt2->cloog_iv); +} + + + +/* Record LOOP as occuring in REGION. */ + +static void +sese_record_loop (sese region, loop_p loop) +{ + if (sese_contains_loop (region, loop)) + return; + + bitmap_set_bit (SESE_LOOPS (region), loop->num); + VEC_safe_push (loop_p, heap, SESE_LOOP_NEST (region), loop); +} + +/* Build the loop nests contained in REGION. Returns true when the + operation was successful. */ + +void +build_sese_loop_nests (sese region) +{ + unsigned i; + basic_block bb; + struct loop *loop0, *loop1; + + FOR_EACH_BB (bb) + if (bb_in_sese_p (bb, region)) + { + struct loop *loop = bb->loop_father; + + /* Only add loops if they are completely contained in the SCoP. */ + if (loop->header == bb + && bb_in_sese_p (loop->latch, region)) + sese_record_loop (region, loop); + } + + /* Make sure that the loops in the SESE_LOOP_NEST are ordered. It + can be the case that an inner loop is inserted before an outer + loop. To avoid this, semi-sort once. */ + for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop0); i++) + { + if (VEC_length (loop_p, SESE_LOOP_NEST (region)) == i + 1) + break; + + loop1 = VEC_index (loop_p, SESE_LOOP_NEST (region), i + 1); + if (loop0->num > loop1->num) + { + VEC_replace (loop_p, SESE_LOOP_NEST (region), i, loop1); + VEC_replace (loop_p, SESE_LOOP_NEST (region), i + 1, loop0); + } + } +} + +/* For a USE in BB, if BB is outside REGION, mark the USE in the + LIVEOUTS set. */ + +static void +sese_build_liveouts_use (sese region, bitmap liveouts, basic_block bb, + tree use) +{ + unsigned ver; + basic_block def_bb; + + if (TREE_CODE (use) != SSA_NAME) + return; + + ver = SSA_NAME_VERSION (use); + def_bb = gimple_bb (SSA_NAME_DEF_STMT (use)); + + if (!def_bb + || !bb_in_sese_p (def_bb, region) + || bb_in_sese_p (bb, region)) + return; + + bitmap_set_bit (liveouts, ver); +} + +/* Marks for rewrite all the SSA_NAMES defined in REGION and that are + used in BB that is outside of the REGION. */ + +static void +sese_build_liveouts_bb (sese region, bitmap liveouts, basic_block bb) +{ + gimple_stmt_iterator bsi; + edge e; + edge_iterator ei; + ssa_op_iter iter; + use_operand_p use_p; + + FOR_EACH_EDGE (e, ei, bb->succs) + for (bsi = gsi_start_phis (e->dest); !gsi_end_p (bsi); gsi_next (&bsi)) + sese_build_liveouts_use (region, liveouts, bb, + PHI_ARG_DEF_FROM_EDGE (gsi_stmt (bsi), e)); + + for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) + FOR_EACH_SSA_USE_OPERAND (use_p, gsi_stmt (bsi), iter, SSA_OP_ALL_USES) + sese_build_liveouts_use (region, liveouts, bb, USE_FROM_PTR (use_p)); +} + +/* Build the LIVEOUTS of REGION: the set of variables defined inside + and used outside the REGION. */ + +static void +sese_build_liveouts (sese region, bitmap liveouts) +{ + basic_block bb; + + FOR_EACH_BB (bb) + sese_build_liveouts_bb (region, liveouts, bb); +} + +/* Builds a new SESE region from edges ENTRY and EXIT. */ + +sese +new_sese (edge entry, edge exit) +{ + sese region = XNEW (struct sese_s); + + SESE_ENTRY (region) = entry; + SESE_EXIT (region) = exit; + SESE_LOOPS (region) = BITMAP_ALLOC (NULL); + SESE_LOOP_NEST (region) = VEC_alloc (loop_p, heap, 3); + SESE_ADD_PARAMS (region) = true; + SESE_PARAMS (region) = VEC_alloc (tree, heap, 3); + SESE_PARAMS_INDEX (region) = htab_create (10, clast_name_index_elt_info, + eq_clast_name_indexes, free); + SESE_PARAMS_NAMES (region) = XNEWVEC (char *, num_ssa_names); + + return region; +} + +/* Deletes REGION. */ + +void +free_sese (sese region) +{ + if (SESE_LOOPS (region)) + SESE_LOOPS (region) = BITMAP_ALLOC (NULL); + + VEC_free (tree, heap, SESE_PARAMS (region)); + VEC_free (loop_p, heap, SESE_LOOP_NEST (region)); + + if (SESE_PARAMS_INDEX (region)) + htab_delete (SESE_PARAMS_INDEX (region)); + + /* Do not free SESE_PARAMS_NAMES: CLooG does that. */ + + XDELETE (region); +} + +/* Add exit phis for USE on EXIT. */ + +static void +sese_add_exit_phis_edge (basic_block exit, tree use, edge false_e, edge true_e) +{ + gimple phi = create_phi_node (use, exit); + + create_new_def_for (gimple_phi_result (phi), phi, + gimple_phi_result_ptr (phi)); + add_phi_arg (phi, use, false_e, UNKNOWN_LOCATION); + add_phi_arg (phi, use, true_e, UNKNOWN_LOCATION); +} + +/* Insert in the block BB phi nodes for variables defined in REGION + and used outside the REGION. The code generation moves REGION in + the else clause of an "if (1)" and generates code in the then + clause that is at this point empty: + + | if (1) + | empty; + | else + | REGION; +*/ + +void +sese_insert_phis_for_liveouts (sese region, basic_block bb, + edge false_e, edge true_e) +{ + unsigned i; + bitmap_iterator bi; + bitmap liveouts = BITMAP_ALLOC (NULL); + + update_ssa (TODO_update_ssa); + + sese_build_liveouts (region, liveouts); + EXECUTE_IF_SET_IN_BITMAP (liveouts, 0, i, bi) + sese_add_exit_phis_edge (bb, ssa_name (i), false_e, true_e); + BITMAP_FREE (liveouts); + + update_ssa (TODO_update_ssa); +} + +/* Get the definition of NAME before the SESE. Keep track of the + basic blocks that have been VISITED in a bitmap. */ + +static tree +get_vdef_before_sese (sese region, tree name, sbitmap visited) +{ + unsigned i; + gimple def_stmt = SSA_NAME_DEF_STMT (name); + basic_block def_bb = gimple_bb (def_stmt); + + if (!def_bb || !bb_in_sese_p (def_bb, region)) + return name; + + if (TEST_BIT (visited, def_bb->index)) + return NULL_TREE; + + SET_BIT (visited, def_bb->index); + + switch (gimple_code (def_stmt)) + { + case GIMPLE_PHI: + for (i = 0; i < gimple_phi_num_args (def_stmt); i++) + { + tree arg = gimple_phi_arg_def (def_stmt, i); + tree res = get_vdef_before_sese (region, arg, visited); + if (res) + return res; + } + return NULL_TREE; + + default: + return NULL_TREE; + } +} + +/* Adjust a virtual phi node PHI that is placed at the end of the + generated code for SCOP: + + | if (1) + | generated code from REGION; + | else + | REGION; + + The FALSE_E edge comes from the original code, TRUE_E edge comes + from the code generated for the SCOP. */ + +static void +sese_adjust_vphi (sese region, gimple phi, edge true_e) +{ + unsigned i; + + gcc_assert (gimple_phi_num_args (phi) == 2); + + for (i = 0; i < gimple_phi_num_args (phi); i++) + if (gimple_phi_arg_edge (phi, i) == true_e) + { + tree true_arg, false_arg, before_scop_arg; + sbitmap visited; + + true_arg = gimple_phi_arg_def (phi, i); + if (!SSA_NAME_IS_DEFAULT_DEF (true_arg)) + return; + + false_arg = gimple_phi_arg_def (phi, i == 0 ? 1 : 0); + if (SSA_NAME_IS_DEFAULT_DEF (false_arg)) + return; + + visited = sbitmap_alloc (last_basic_block); + sbitmap_zero (visited); + before_scop_arg = get_vdef_before_sese (region, false_arg, visited); + gcc_assert (before_scop_arg != NULL_TREE); + SET_PHI_ARG_DEF (phi, i, before_scop_arg); + sbitmap_free (visited); + } +} + +/* Returns the name associated to OLD_NAME in MAP. */ + +static tree +get_rename (htab_t map, tree old_name) +{ + struct rename_map_elt_s tmp; + PTR *slot; + + tmp.old_name = old_name; + slot = htab_find_slot (map, &tmp, NO_INSERT); + + if (slot && *slot) + return ((rename_map_elt) *slot)->expr; + + return old_name; +} + +/* Register in MAP the rename tuple (old_name, expr). */ + +void +set_rename (htab_t map, tree old_name, tree expr) +{ + struct rename_map_elt_s tmp; + PTR *slot; + + if (old_name == expr) + return; + + tmp.old_name = old_name; + slot = htab_find_slot (map, &tmp, INSERT); + + if (!slot) + return; + + if (*slot) + free (*slot); + + *slot = new_rename_map_elt (old_name, expr); +} + +/* Adjusts the phi nodes in the block BB for variables defined in + SCOP_REGION and used outside the SCOP_REGION. The code generation + moves SCOP_REGION in the else clause of an "if (1)" and generates + code in the then clause: + + | if (1) + | generated code from REGION; + | else + | REGION; + + To adjust the phi nodes after the condition, the RENAME_MAP is + used. */ + +void +sese_adjust_liveout_phis (sese region, htab_t rename_map, basic_block bb, + edge false_e, edge true_e) +{ + gimple_stmt_iterator si; + + for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si)) + { + unsigned i; + unsigned false_i = 0; + gimple phi = gsi_stmt (si); + + if (!is_gimple_reg (PHI_RESULT (phi))) + { + sese_adjust_vphi (region, phi, true_e); + continue; + } + + for (i = 0; i < gimple_phi_num_args (phi); i++) + if (gimple_phi_arg_edge (phi, i) == false_e) + { + false_i = i; + break; + } + + for (i = 0; i < gimple_phi_num_args (phi); i++) + if (gimple_phi_arg_edge (phi, i) == true_e) + { + tree old_name = gimple_phi_arg_def (phi, false_i); + tree expr = get_rename (rename_map, old_name); + gimple_seq stmts; + + gcc_assert (old_name != expr); + + if (TREE_CODE (expr) != SSA_NAME + && is_gimple_reg (old_name)) + { + tree type = TREE_TYPE (old_name); + tree var = create_tmp_var (type, "var"); + + expr = build2 (MODIFY_EXPR, type, var, expr); + expr = force_gimple_operand (expr, &stmts, true, NULL); + gsi_insert_seq_on_edge_immediate (true_e, stmts); + } + + SET_PHI_ARG_DEF (phi, i, expr); + } + } +} + +/* Rename the SSA_NAMEs used in STMT and that appear in MAP. */ + +static void +rename_variables_in_stmt (gimple stmt, htab_t map, gimple_stmt_iterator *insert_gsi) +{ + ssa_op_iter iter; + use_operand_p use_p; + + FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES) + { + tree use = USE_FROM_PTR (use_p); + tree expr = get_rename (map, use); + tree type_use = TREE_TYPE (use); + tree type_expr = TREE_TYPE (expr); + gimple_seq stmts; + + if (use == expr) + continue; + + if (type_use != type_expr + || (TREE_CODE (expr) != SSA_NAME + && is_gimple_reg (use))) + { + tree var = create_tmp_var (type_use, "var"); + + if (type_use != type_expr) + expr = fold_convert (type_use, expr); + + expr = build2 (MODIFY_EXPR, type_use, var, expr); + expr = force_gimple_operand (expr, &stmts, true, NULL); + gsi_insert_seq_before (insert_gsi, stmts, GSI_SAME_STMT); + } + + replace_exp (use_p, expr); + } + + update_stmt (stmt); +} + +/* Returns true if NAME is a parameter of SESE. */ + +static bool +is_parameter (sese region, tree name) +{ + int i; + tree p; + + for (i = 0; VEC_iterate (tree, SESE_PARAMS (region), i, p); i++) + if (p == name) + return true; + + return false; +} + +/* Returns true if NAME is an induction variable. */ + +static bool +is_iv (tree name) +{ + return gimple_code (SSA_NAME_DEF_STMT (name)) == GIMPLE_PHI; +} + +static void expand_scalar_variables_stmt (gimple, basic_block, sese, + htab_t, gimple_stmt_iterator *); +static tree +expand_scalar_variables_expr (tree, tree, enum tree_code, tree, basic_block, + sese, htab_t, gimple_stmt_iterator *); + +static tree +expand_scalar_variables_call (gimple stmt, basic_block bb, sese region, + htab_t map, gimple_stmt_iterator *gsi) +{ + int i, nargs = gimple_call_num_args (stmt); + VEC (tree, gc) *args = VEC_alloc (tree, gc, nargs); + tree fn_type = TREE_TYPE (gimple_call_fn (stmt)); + tree fn = gimple_call_fndecl (stmt); + tree call_expr, var, lhs; + gimple call; + + for (i = 0; i < nargs; i++) + { + tree arg = gimple_call_arg (stmt, i); + tree t = TREE_TYPE (arg); + + var = create_tmp_var (t, "var"); + arg = expand_scalar_variables_expr (t, arg, TREE_CODE (arg), NULL, + bb, region, map, gsi); + arg = build2 (MODIFY_EXPR, t, var, arg); + arg = force_gimple_operand_gsi (gsi, arg, true, NULL, + true, GSI_SAME_STMT); + VEC_quick_push (tree, args, arg); + } + + lhs = gimple_call_lhs (stmt); + var = create_tmp_var (TREE_TYPE (lhs), "var"); + call_expr = build_call_vec (fn_type, fn, args); + call = gimple_build_call_from_tree (call_expr); + var = make_ssa_name (var, call); + gimple_call_set_lhs (call, var); + gsi_insert_before (gsi, call, GSI_SAME_STMT); + + return var; +} + +/* Copies at GSI all the scalar computations on which the ssa_name OP0 + depends on in the SESE: these are all the scalar variables used in + the definition of OP0, that are defined outside BB and still in the + SESE, i.e. not a parameter of the SESE. The expression that is + returned contains only induction variables from the generated code: + MAP contains the induction variables renaming mapping, and is used + to translate the names of induction variables. */ + +static tree +expand_scalar_variables_ssa_name (tree op0, basic_block bb, + sese region, htab_t map, + gimple_stmt_iterator *gsi) +{ + gimple def_stmt; + tree new_op; + + if (is_parameter (region, op0) + || is_iv (op0)) + return get_rename (map, op0); + + def_stmt = SSA_NAME_DEF_STMT (op0); + + /* Check whether we already have a rename for OP0. */ + new_op = get_rename (map, op0); + + if (new_op != op0 + && gimple_bb (SSA_NAME_DEF_STMT (new_op)) == bb) + return new_op; + + if (gimple_bb (def_stmt) == bb) + { + /* If the defining statement is in the basic block already + we do not need to create a new expression for it, we + only need to ensure its operands are expanded. */ + expand_scalar_variables_stmt (def_stmt, bb, region, map, gsi); + return new_op; + } + else + { + if (!gimple_bb (def_stmt) + || !bb_in_sese_p (gimple_bb (def_stmt), region)) + return new_op; + + switch (gimple_code (def_stmt)) + { + case GIMPLE_ASSIGN: + { + tree var0 = gimple_assign_rhs1 (def_stmt); + enum tree_code subcode = gimple_assign_rhs_code (def_stmt); + tree var1 = gimple_assign_rhs2 (def_stmt); + tree type = gimple_expr_type (def_stmt); + + return expand_scalar_variables_expr (type, var0, subcode, var1, bb, + region, map, gsi); + } + + case GIMPLE_CALL: + return expand_scalar_variables_call (def_stmt, bb, region, map, gsi); + + default: + gcc_unreachable (); + return new_op; + } + } +} + +/* Copies at GSI all the scalar computations on which the expression + OP0 CODE OP1 depends on in the SESE: these are all the scalar + variables used in OP0 and OP1, defined outside BB and still defined + in the SESE, i.e. not a parameter of the SESE. The expression that + is returned contains only induction variables from the generated + code: MAP contains the induction variables renaming mapping, and is + used to translate the names of induction variables. */ + +static tree +expand_scalar_variables_expr (tree type, tree op0, enum tree_code code, + tree op1, basic_block bb, sese region, + htab_t map, gimple_stmt_iterator *gsi) +{ + if (TREE_CODE_CLASS (code) == tcc_constant + || TREE_CODE_CLASS (code) == tcc_declaration) + return op0; + + /* For data references we have to duplicate also its memory + indexing. */ + if (TREE_CODE_CLASS (code) == tcc_reference) + { + switch (code) + { + case REALPART_EXPR: + case IMAGPART_EXPR: + { + tree op = TREE_OPERAND (op0, 0); + tree res = expand_scalar_variables_expr + (type, op, TREE_CODE (op), NULL, bb, region, map, gsi); + return build1 (code, type, res); + } + + case INDIRECT_REF: + { + tree old_name = TREE_OPERAND (op0, 0); + tree expr = expand_scalar_variables_ssa_name + (old_name, bb, region, map, gsi); + + if (TREE_CODE (expr) != SSA_NAME + && is_gimple_reg (old_name)) + { + tree type = TREE_TYPE (old_name); + tree var = create_tmp_var (type, "var"); + + expr = build2 (MODIFY_EXPR, type, var, expr); + expr = force_gimple_operand_gsi (gsi, expr, true, NULL, + true, GSI_SAME_STMT); + } + + return fold_build1 (code, type, expr); + } + + case ARRAY_REF: + { + tree op00 = TREE_OPERAND (op0, 0); + tree op01 = TREE_OPERAND (op0, 1); + tree op02 = TREE_OPERAND (op0, 2); + tree op03 = TREE_OPERAND (op0, 3); + tree base = expand_scalar_variables_expr + (TREE_TYPE (op00), op00, TREE_CODE (op00), NULL, bb, region, + map, gsi); + tree subscript = expand_scalar_variables_expr + (TREE_TYPE (op01), op01, TREE_CODE (op01), NULL, bb, region, + map, gsi); + + return build4 (ARRAY_REF, type, base, subscript, op02, op03); + } + + default: + /* The above cases should catch everything. */ + gcc_unreachable (); + } + } + + if (TREE_CODE_CLASS (code) == tcc_unary) + { + tree op0_type = TREE_TYPE (op0); + enum tree_code op0_code = TREE_CODE (op0); + tree op0_expr = expand_scalar_variables_expr (op0_type, op0, op0_code, + NULL, bb, region, map, gsi); + + return fold_build1 (code, type, op0_expr); + } + + if (TREE_CODE_CLASS (code) == tcc_binary + || TREE_CODE_CLASS (code) == tcc_comparison) + { + tree op0_type = TREE_TYPE (op0); + enum tree_code op0_code = TREE_CODE (op0); + tree op0_expr = expand_scalar_variables_expr (op0_type, op0, op0_code, + NULL, bb, region, map, gsi); + tree op1_type = TREE_TYPE (op1); + enum tree_code op1_code = TREE_CODE (op1); + tree op1_expr = expand_scalar_variables_expr (op1_type, op1, op1_code, + NULL, bb, region, map, gsi); + + return fold_build2 (code, type, op0_expr, op1_expr); + } + + if (code == SSA_NAME) + return expand_scalar_variables_ssa_name (op0, bb, region, map, gsi); + + if (code == ADDR_EXPR) + return op0; + + gcc_unreachable (); + return NULL; +} + +/* Copies at the beginning of BB all the scalar computations on which + STMT depends on in the SESE: these are all the scalar variables used + in STMT, defined outside BB and still defined in the SESE, i.e. not a + parameter of the SESE. The expression that is returned contains + only induction variables from the generated code: MAP contains the + induction variables renaming mapping, and is used to translate the + names of induction variables. */ + +static void +expand_scalar_variables_stmt (gimple stmt, basic_block bb, sese region, + htab_t map, gimple_stmt_iterator *gsi) +{ + ssa_op_iter iter; + use_operand_p use_p; + + FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES) + { + tree use = USE_FROM_PTR (use_p); + tree type = TREE_TYPE (use); + enum tree_code code = TREE_CODE (use); + tree use_expr; + + if (!is_gimple_reg (use)) + continue; + + /* Don't expand USE if we already have a rename for it. */ + use_expr = get_rename (map, use); + if (use_expr != use) + continue; + + use_expr = expand_scalar_variables_expr (type, use, code, NULL, bb, + region, map, gsi); + use_expr = fold_convert (type, use_expr); + + if (use_expr == use) + continue; + + if (TREE_CODE (use_expr) != SSA_NAME) + { + tree var = create_tmp_var (type, "var"); + + use_expr = build2 (MODIFY_EXPR, type, var, use_expr); + use_expr = force_gimple_operand_gsi (gsi, use_expr, true, NULL, + true, GSI_SAME_STMT); + } + + replace_exp (use_p, use_expr); + } + + update_stmt (stmt); +} + +/* Copies at the beginning of BB all the scalar computations on which + BB depends on in the SESE: these are all the scalar variables used + in BB, defined outside BB and still defined in the SESE, i.e. not a + parameter of the SESE. The expression that is returned contains + only induction variables from the generated code: MAP contains the + induction variables renaming mapping, and is used to translate the + names of induction variables. */ + +static void +expand_scalar_variables (basic_block bb, sese region, htab_t map) +{ + gimple_stmt_iterator gsi; + + for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);) + { + gimple stmt = gsi_stmt (gsi); + expand_scalar_variables_stmt (stmt, bb, region, map, &gsi); + gsi_next (&gsi); + } +} + +/* Rename all the SSA_NAMEs from block BB according to the MAP. */ + +static void +rename_variables (basic_block bb, htab_t map) +{ + gimple_stmt_iterator gsi; + gimple_stmt_iterator insert_gsi = gsi_start_bb (bb); + + for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + rename_variables_in_stmt (gsi_stmt (gsi), map, &insert_gsi); +} + +/* Remove condition from BB. */ + +static void +remove_condition (basic_block bb) +{ + gimple last = last_stmt (bb); + + if (last && gimple_code (last) == GIMPLE_COND) + { + gimple_stmt_iterator gsi = gsi_last_bb (bb); + gsi_remove (&gsi, true); + } +} + +/* Returns the first successor edge of BB with EDGE_TRUE_VALUE flag set. */ + +edge +get_true_edge_from_guard_bb (basic_block bb) +{ + edge e; + edge_iterator ei; + + FOR_EACH_EDGE (e, ei, bb->succs) + if (e->flags & EDGE_TRUE_VALUE) + return e; + + gcc_unreachable (); + return NULL; +} + +/* Returns the first successor edge of BB with EDGE_TRUE_VALUE flag cleared. */ + +edge +get_false_edge_from_guard_bb (basic_block bb) +{ + edge e; + edge_iterator ei; + + FOR_EACH_EDGE (e, ei, bb->succs) + if (!(e->flags & EDGE_TRUE_VALUE)) + return e; + + gcc_unreachable (); + return NULL; +} + +/* Returns true when NAME is defined in LOOP. */ + +static bool +defined_in_loop_p (tree name, loop_p loop) +{ + gimple stmt = SSA_NAME_DEF_STMT (name); + + return (gimple_bb (stmt)->loop_father == loop); +} + +/* Returns the gimple statement that uses NAME outside the loop it is + defined in, returns NULL if there is no such loop close phi node. + An invariant of the loop closed SSA form is that the only use of a + variable, outside the loop it is defined in, is in the loop close + phi node that just follows the loop. */ + +static gimple +alive_after_loop (tree name) +{ + use_operand_p use_p; + imm_use_iterator imm_iter; + loop_p loop = gimple_bb (SSA_NAME_DEF_STMT (name))->loop_father; + + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, name) + { + gimple stmt = USE_STMT (use_p); + + if (gimple_code (stmt) == GIMPLE_PHI + && gimple_bb (stmt)->loop_father != loop) + return stmt; + } + + return NULL; +} + +/* Return true if a close phi has not yet been inserted for the use of + variable NAME on the single exit of LOOP. */ + +static bool +close_phi_not_yet_inserted_p (loop_p loop, tree name) +{ + gimple_stmt_iterator psi; + basic_block bb = single_exit (loop)->dest; + + for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi)) + if (gimple_phi_arg_def (gsi_stmt (psi), 0) == name) + return false; + + return true; +} + +/* A structure for passing parameters to add_loop_exit_phis. */ + +typedef struct alep { + loop_p loop; + VEC (rename_map_elt, heap) *new_renames; +} *alep_p; + +/* Helper function for htab_traverse in insert_loop_close_phis. */ + +static int +add_loop_exit_phis (void **slot, void *data) +{ + struct rename_map_elt_s *entry; + alep_p a; + loop_p loop; + tree expr, new_name; + bool def_in_loop_p, used_outside_p, need_close_phi_p; + gimple old_close_phi; + + if (!slot || !data) + return 1; + + entry = (struct rename_map_elt_s *) *slot; + a = (alep_p) data; + loop = a->loop; + expr = entry->expr; + + if (TREE_CODE (expr) != SSA_NAME) + return 1; + + new_name = expr; + def_in_loop_p = defined_in_loop_p (new_name, loop); + old_close_phi = alive_after_loop (entry->old_name); + used_outside_p = (old_close_phi != NULL); + need_close_phi_p = (def_in_loop_p && used_outside_p + && close_phi_not_yet_inserted_p (loop, new_name)); + + /* Insert a loop close phi node. */ + if (need_close_phi_p) + { + basic_block bb = single_exit (loop)->dest; + gimple phi = create_phi_node (new_name, bb); + tree new_res = create_new_def_for (gimple_phi_result (phi), phi, + gimple_phi_result_ptr (phi)); + + add_phi_arg (phi, new_name, single_pred_edge (bb), UNKNOWN_LOCATION); + VEC_safe_push (rename_map_elt, heap, a->new_renames, + new_rename_map_elt (gimple_phi_result (old_close_phi), + new_res)); + } + + /* Remove the old rename from the map. */ + if (def_in_loop_p && *slot) + { + free (*slot); + *slot = NULL; + } + + return 1; +} + +/* Traverses MAP and removes from it all the tuples (OLD, NEW) where + NEW is defined in LOOP. Inserts on the exit of LOOP the close phi + node "RES = phi (NEW)" corresponding to "OLD_RES = phi (OLD)" in + the original code. Inserts in MAP the tuple (OLD_RES, RES). */ + +void +insert_loop_close_phis (htab_t map, loop_p loop) +{ + int i; + struct alep a; + rename_map_elt elt; + + a.loop = loop; + a.new_renames = VEC_alloc (rename_map_elt, heap, 3); + update_ssa (TODO_update_ssa); + htab_traverse (map, add_loop_exit_phis, &a); + update_ssa (TODO_update_ssa); + + for (i = 0; VEC_iterate (rename_map_elt, a.new_renames, i, elt); i++) + { + set_rename (map, elt->old_name, elt->expr); + free (elt); + } + + VEC_free (rename_map_elt, heap, a.new_renames); +} + +/* Helper structure for htab_traverse in insert_guard_phis. */ + +struct igp { + basic_block bb; + edge true_edge, false_edge; + htab_t before_guard; +}; + +/* Return the default name that is before the guard. */ + +static tree +default_before_guard (htab_t before_guard, tree old_name) +{ + tree res = get_rename (before_guard, old_name); + + if (res == old_name) + { + if (is_gimple_reg (res)) + return fold_convert (TREE_TYPE (res), integer_zero_node); + return gimple_default_def (cfun, SSA_NAME_VAR (res)); + } + + return res; +} + +/* Helper function for htab_traverse in insert_guard_phis. */ + +static int +add_guard_exit_phis (void **slot, void *s) +{ + struct rename_map_elt_s *entry = (struct rename_map_elt_s *) *slot; + struct igp *i = (struct igp *) s; + basic_block bb = i->bb; + edge true_edge = i->true_edge; + edge false_edge = i->false_edge; + tree name1 = entry->expr; + tree name2 = default_before_guard (i->before_guard, entry->old_name); + gimple phi; + tree res; + gimple_seq stmts; + + /* Nothing to be merged if the name before the guard is the same as + the one after. */ + if (name1 == name2) + return 1; + + if (TREE_TYPE (name1) != TREE_TYPE (name2)) + name1 = fold_convert (TREE_TYPE (name2), name1); + + if (TREE_CODE (name1) != SSA_NAME + && (TREE_CODE (name2) != SSA_NAME + || is_gimple_reg (name2))) + { + tree type = TREE_TYPE (name2); + tree var = create_tmp_var (type, "var"); + + name1 = build2 (MODIFY_EXPR, type, var, name1); + name1 = force_gimple_operand (name1, &stmts, true, NULL); + gsi_insert_seq_on_edge_immediate (true_edge, stmts); + } + + phi = create_phi_node (entry->old_name, bb); + res = create_new_def_for (gimple_phi_result (phi), phi, + gimple_phi_result_ptr (phi)); + + add_phi_arg (phi, name1, true_edge, UNKNOWN_LOCATION); + add_phi_arg (phi, name2, false_edge, UNKNOWN_LOCATION); + + entry->expr = res; + *slot = entry; + return 1; +} + +/* Iterate over RENAME_MAP and get tuples of the form (OLD, NAME1). + If there is a correspondent tuple (OLD, NAME2) in BEFORE_GUARD, + with NAME1 different than NAME2, then insert in BB the phi node: + + | RES = phi (NAME1 (on TRUE_EDGE), NAME2 (on FALSE_EDGE))" + + if there is no tuple for OLD in BEFORE_GUARD, insert + + | RES = phi (NAME1 (on TRUE_EDGE), + | DEFAULT_DEFINITION of NAME1 (on FALSE_EDGE))". + + Finally register in RENAME_MAP the tuple (OLD, RES). */ + +void +insert_guard_phis (basic_block bb, edge true_edge, edge false_edge, + htab_t before_guard, htab_t rename_map) +{ + struct igp i; + i.bb = bb; + i.true_edge = true_edge; + i.false_edge = false_edge; + i.before_guard = before_guard; + + update_ssa (TODO_update_ssa); + htab_traverse (rename_map, add_guard_exit_phis, &i); + update_ssa (TODO_update_ssa); +} + +/* Create a duplicate of the basic block BB. NOTE: This does not + preserve SSA form. */ + +static void +graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb, htab_t map) +{ + gimple_stmt_iterator gsi, gsi_tgt; + + gsi_tgt = gsi_start_bb (new_bb); + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + def_operand_p def_p; + ssa_op_iter op_iter; + int region; + gimple stmt = gsi_stmt (gsi); + gimple copy; + + if (gimple_code (stmt) == GIMPLE_LABEL) + continue; + + /* Create a new copy of STMT and duplicate STMT's virtual + operands. */ + copy = gimple_copy (stmt); + gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT); + mark_sym_for_renaming (gimple_vop (cfun)); + + region = lookup_stmt_eh_region (stmt); + if (region >= 0) + add_stmt_to_eh_region (copy, region); + gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt); + + /* Create new names for all the definitions created by COPY and + add replacement mappings for each new name. */ + FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_ALL_DEFS) + { + tree old_name = DEF_FROM_PTR (def_p); + tree new_name = create_new_def_for (old_name, copy, def_p); + set_rename (map, old_name, new_name); + } + } +} + +/* Copies BB and includes in the copied BB all the statements that can + be reached following the use-def chains from the memory accesses, + and returns the next edge following this new block. */ + +edge +copy_bb_and_scalar_dependences (basic_block bb, sese region, + edge next_e, htab_t map) +{ + basic_block new_bb = split_edge (next_e); + + next_e = single_succ_edge (new_bb); + graphite_copy_stmts_from_block (bb, new_bb, map); + remove_condition (new_bb); + remove_phi_nodes (new_bb); + expand_scalar_variables (new_bb, region, map); + rename_variables (new_bb, map); + + return next_e; +} + +/* Returns the outermost loop in SCOP that contains BB. */ + +struct loop * +outermost_loop_in_sese (sese region, basic_block bb) +{ + struct loop *nest; + + nest = bb->loop_father; + while (loop_outer (nest) + && loop_in_sese_p (loop_outer (nest), region)) + nest = loop_outer (nest); + + return nest; +} + +/* Sets the false region of an IF_REGION to REGION. */ + +void +if_region_set_false_region (ifsese if_region, sese region) +{ + basic_block condition = if_region_get_condition_block (if_region); + edge false_edge = get_false_edge_from_guard_bb (condition); + basic_block dummy = false_edge->dest; + edge entry_region = SESE_ENTRY (region); + edge exit_region = SESE_EXIT (region); + basic_block before_region = entry_region->src; + basic_block last_in_region = exit_region->src; + void **slot = htab_find_slot_with_hash (current_loops->exits, exit_region, + htab_hash_pointer (exit_region), + NO_INSERT); + + entry_region->flags = false_edge->flags; + false_edge->flags = exit_region->flags; + + redirect_edge_pred (entry_region, condition); + redirect_edge_pred (exit_region, before_region); + redirect_edge_pred (false_edge, last_in_region); + redirect_edge_succ (false_edge, single_succ (dummy)); + delete_basic_block (dummy); + + exit_region->flags = EDGE_FALLTHRU; + recompute_all_dominators (); + + SESE_EXIT (region) = false_edge; + if_region->false_region = region; + + if (slot) + { + struct loop_exit *loop_exit = GGC_CNEW (struct loop_exit); + + memcpy (loop_exit, *((struct loop_exit **) slot), sizeof (struct loop_exit)); + htab_clear_slot (current_loops->exits, slot); + + slot = htab_find_slot_with_hash (current_loops->exits, false_edge, + htab_hash_pointer (false_edge), + INSERT); + loop_exit->e = false_edge; + *slot = loop_exit; + false_edge->src->loop_father->exits->next = loop_exit; + } +} + +/* Creates an IFSESE with CONDITION on edge ENTRY. */ + +ifsese +create_if_region_on_edge (edge entry, tree condition) +{ + edge e; + edge_iterator ei; + sese sese_region = GGC_NEW (struct sese_s); + sese true_region = GGC_NEW (struct sese_s); + sese false_region = GGC_NEW (struct sese_s); + ifsese if_region = GGC_NEW (struct ifsese_s); + edge exit = create_empty_if_region_on_edge (entry, condition); + + if_region->region = sese_region; + if_region->region->entry = entry; + if_region->region->exit = exit; + + FOR_EACH_EDGE (e, ei, entry->dest->succs) + { + if (e->flags & EDGE_TRUE_VALUE) + { + true_region->entry = e; + true_region->exit = single_succ_edge (e->dest); + if_region->true_region = true_region; + } + else if (e->flags & EDGE_FALSE_VALUE) + { + false_region->entry = e; + false_region->exit = single_succ_edge (e->dest); + if_region->false_region = false_region; + } + } + + return if_region; +} + +/* Moves REGION in a condition expression: + | if (1) + | ; + | else + | REGION; +*/ + +ifsese +move_sese_in_condition (sese region) +{ + basic_block pred_block = split_edge (SESE_ENTRY (region)); + ifsese if_region = NULL; + + SESE_ENTRY (region) = single_succ_edge (pred_block); + if_region = create_if_region_on_edge (single_pred_edge (pred_block), integer_one_node); + if_region_set_false_region (if_region, region); + + return if_region; +} + +/* Reset the loop->aux pointer for all loops in REGION. */ + +void +sese_reset_aux_in_loops (sese region) +{ + int i; + loop_p loop; + + for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++) + loop->aux = NULL; +} + +/* Returns the scalar evolution of T in REGION. Every variable that + is not defined in the REGION is considered a parameter. */ + +tree +scalar_evolution_in_region (sese region, loop_p loop, tree t) +{ + gimple def; + struct loop *def_loop; + basic_block before = block_before_sese (region); + + if (TREE_CODE (t) != SSA_NAME + || loop_in_sese_p (loop, region)) + return instantiate_scev (before, loop, + analyze_scalar_evolution (loop, t)); + + if (!defined_in_sese_p (t, region)) + return t; + + def = SSA_NAME_DEF_STMT (t); + def_loop = loop_containing_stmt (def); + + if (loop_in_sese_p (def_loop, region)) + { + t = analyze_scalar_evolution (def_loop, t); + def_loop = superloop_at_depth (def_loop, loop_depth (loop) + 1); + t = compute_overall_effect_of_inner_loop (def_loop, t); + return t; + } + else + return instantiate_scev (before, loop, t); +} diff --git a/gcc/sese.h b/gcc/sese.h new file mode 100644 index 00000000000..ace63ba6719 --- /dev/null +++ b/gcc/sese.h @@ -0,0 +1,475 @@ +/* Single entry single exit control flow regions. + Copyright (C) 2008, 2009 Free Software Foundation, Inc. + Contributed by Jan Sjodin <jan.sjodin@amd.com> and + Sebastian Pop <sebastian.pop@amd.com>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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/>. */ + +#ifndef GCC_SESE_H +#define GCC_SESE_H + +/* A Single Entry, Single Exit region is a part of the CFG delimited + by two edges. */ +typedef struct sese_s +{ + /* Single ENTRY and single EXIT from the SESE region. */ + edge entry, exit; + + /* Parameters used within the SCOP. */ + VEC (tree, heap) *params; + + /* Used to quickly retrieve the index of a parameter in PARAMS. */ + htab_t params_index; + + /* Store the names of the parameters that are passed to CLooG. */ + char **params_names; + + /* Loops completely contained in the SCOP. */ + bitmap loops; + VEC (loop_p, heap) *loop_nest; + + /* Are we allowed to add more params? This is for debugging purpose. We + can only add new params before generating the bb domains, otherwise they + become invalid. */ + bool add_params; +} *sese; + +#define SESE_ENTRY(S) (S->entry) +#define SESE_ENTRY_BB(S) (S->entry->dest) +#define SESE_EXIT(S) (S->exit) +#define SESE_EXIT_BB(S) (S->exit->dest) +#define SESE_PARAMS(S) (S->params) +#define SESE_PARAMS_INDEX(S) (S->params_index) +#define SESE_PARAMS_NAMES(S) (S->params_names) +#define SESE_LOOPS(S) (S->loops) +#define SESE_LOOP_NEST(S) (S->loop_nest) +#define SESE_ADD_PARAMS(S) (S->add_params) + +extern sese new_sese (edge, edge); +extern void free_sese (sese); +extern void sese_insert_phis_for_liveouts (sese, basic_block, edge, edge); +extern void sese_adjust_liveout_phis (sese, htab_t, basic_block, edge, edge); +extern void build_sese_loop_nests (sese); +extern edge copy_bb_and_scalar_dependences (basic_block, sese, edge, htab_t); +extern struct loop *outermost_loop_in_sese (sese, basic_block); +extern void insert_loop_close_phis (htab_t, loop_p); +extern void insert_guard_phis (basic_block, edge, edge, htab_t, htab_t); +extern void sese_reset_aux_in_loops (sese); +extern tree scalar_evolution_in_region (sese, loop_p, tree); + +/* Check that SESE contains LOOP. */ + +static inline bool +sese_contains_loop (sese sese, struct loop *loop) +{ + return bitmap_bit_p (SESE_LOOPS (sese), loop->num); +} + +/* The number of parameters in REGION. */ + +static inline unsigned +sese_nb_params (sese region) +{ + return VEC_length (tree, SESE_PARAMS (region)); +} + +/* Checks whether BB is contained in the region delimited by ENTRY and + EXIT blocks. */ + +static inline bool +bb_in_region (basic_block bb, basic_block entry, basic_block exit) +{ +#ifdef ENABLE_CHECKING + { + edge e; + edge_iterator ei; + + /* Check that there are no edges coming in the region: all the + predecessors of EXIT are dominated by ENTRY. */ + FOR_EACH_EDGE (e, ei, exit->preds) + dominated_by_p (CDI_DOMINATORS, e->src, entry); + + /* Check that there are no edges going out of the region: the + entry is post-dominated by the exit. FIXME: This cannot be + checked right now as the CDI_POST_DOMINATORS are needed. */ + } +#endif + + return dominated_by_p (CDI_DOMINATORS, bb, entry) + && !(dominated_by_p (CDI_DOMINATORS, bb, exit) + && !dominated_by_p (CDI_DOMINATORS, entry, exit)); +} + +/* Checks whether BB is contained in the region delimited by ENTRY and + EXIT blocks. */ + +static inline bool +bb_in_sese_p (basic_block bb, sese region) +{ + basic_block entry = SESE_ENTRY_BB (region); + basic_block exit = SESE_EXIT_BB (region); + + return bb_in_region (bb, entry, exit); +} + +/* Returns true when NAME is defined in REGION. */ + +static inline bool +defined_in_sese_p (tree name, sese region) +{ + gimple stmt = SSA_NAME_DEF_STMT (name); + basic_block bb = gimple_bb (stmt); + + return bb && bb_in_sese_p (bb, region); +} + +/* Returns true when LOOP is in REGION. */ + +static inline bool +loop_in_sese_p (struct loop *loop, sese region) +{ + return (bb_in_sese_p (loop->header, region) + && bb_in_sese_p (loop->latch, region)); +} + +/* Returns the loop depth of LOOP in REGION. The loop depth + is the same as the normal loop depth, but limited by a region. + + Example: + + loop_0 + loop_1 + { + S0 + <- region start + S1 + + loop_2 + S2 + + S3 + <- region end + } + + loop_0 does not exist in the region -> invalid + loop_1 exists, but is not completely contained in the region -> depth 0 + loop_2 is completely contained -> depth 1 */ + +static inline unsigned int +sese_loop_depth (sese region, loop_p loop) +{ + unsigned int depth = 0; + + gcc_assert ((!loop_in_sese_p (loop, region) + && (SESE_ENTRY_BB (region)->loop_father == loop + || SESE_EXIT (region)->src->loop_father == loop)) + || loop_in_sese_p (loop, region)); + + while (loop_in_sese_p (loop, region)) + { + depth++; + loop = loop_outer (loop); + } + + return depth; +} + +/* Returns the block preceding the entry of a SESE. */ + +static inline basic_block +block_before_sese (sese sese) +{ + return SESE_ENTRY (sese)->src; +} + +/* Stores the INDEX in a vector for a given clast NAME. */ + +typedef struct clast_name_index { + int index; + const char *name; +} *clast_name_index_p; + +/* Returns a pointer to a new element of type clast_name_index_p built + from NAME and INDEX. */ + +static inline clast_name_index_p +new_clast_name_index (const char *name, int index) +{ + clast_name_index_p res = XNEW (struct clast_name_index); + + res->name = name; + res->index = index; + return res; +} + +/* For a given clast NAME, returns -1 if it does not correspond to any + parameter, or otherwise, returns the index in the PARAMS or + SCATTERING_DIMENSIONS vector. */ + +static inline int +clast_name_to_index (const char *name, htab_t index_table) +{ + struct clast_name_index tmp; + PTR *slot; + + tmp.name = name; + slot = htab_find_slot (index_table, &tmp, NO_INSERT); + + if (slot && *slot) + return ((struct clast_name_index *) *slot)->index; + + return -1; +} + +/* Records in INDEX_TABLE the INDEX for NAME. */ + +static inline void +save_clast_name_index (htab_t index_table, const char *name, int index) +{ + struct clast_name_index tmp; + PTR *slot; + + tmp.name = name; + slot = htab_find_slot (index_table, &tmp, INSERT); + + if (slot) + *slot = new_clast_name_index (name, index); +} + +/* Print to stderr the element ELT. */ + +static inline void +debug_clast_name_index (clast_name_index_p elt) +{ + fprintf (stderr, "(index = %d, name = %s)\n", elt->index, elt->name); +} + +/* Helper function for debug_rename_map. */ + +static inline int +debug_clast_name_indexes_1 (void **slot, void *s ATTRIBUTE_UNUSED) +{ + struct clast_name_index *entry = (struct clast_name_index *) *slot; + debug_clast_name_index (entry); + return 1; +} + +/* Print to stderr all the elements of MAP. */ + +static inline void +debug_clast_name_indexes (htab_t map) +{ + htab_traverse (map, debug_clast_name_indexes_1, NULL); +} + +/* Computes a hash function for database element ELT. */ + +static inline hashval_t +clast_name_index_elt_info (const void *elt) +{ + return htab_hash_pointer (((const struct clast_name_index *) elt)->name); +} + +/* Compares database elements E1 and E2. */ + +static inline int +eq_clast_name_indexes (const void *e1, const void *e2) +{ + const struct clast_name_index *elt1 = (const struct clast_name_index *) e1; + const struct clast_name_index *elt2 = (const struct clast_name_index *) e2; + + return (elt1->name == elt2->name); +} + + + +/* A single entry single exit specialized for conditions. */ + +typedef struct ifsese_s { + sese region; + sese true_region; + sese false_region; +} *ifsese; + +extern void if_region_set_false_region (ifsese, sese); +extern ifsese create_if_region_on_edge (edge, tree); +extern ifsese move_sese_in_condition (sese); +extern edge get_true_edge_from_guard_bb (basic_block); +extern edge get_false_edge_from_guard_bb (basic_block); + +static inline edge +if_region_entry (ifsese if_region) +{ + return SESE_ENTRY (if_region->region); +} + +static inline edge +if_region_exit (ifsese if_region) +{ + return SESE_EXIT (if_region->region); +} + +static inline basic_block +if_region_get_condition_block (ifsese if_region) +{ + return if_region_entry (if_region)->dest; +} + +/* Structure containing the mapping between the old names and the new + names used after block copy in the new loop context. */ +typedef struct rename_map_elt_s +{ + tree old_name, expr; +} *rename_map_elt; + +DEF_VEC_P(rename_map_elt); +DEF_VEC_ALLOC_P (rename_map_elt, heap); + +extern void debug_rename_map (htab_t); +extern hashval_t rename_map_elt_info (const void *); +extern int eq_rename_map_elts (const void *, const void *); +extern void set_rename (htab_t, tree, tree); + +/* Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW. */ + +static inline rename_map_elt +new_rename_map_elt (tree old_name, tree expr) +{ + rename_map_elt res; + + res = XNEW (struct rename_map_elt_s); + res->old_name = old_name; + res->expr = expr; + + return res; +} + +/* Structure containing the mapping between the CLooG's induction + variable and the type of the old induction variable. */ +typedef struct ivtype_map_elt_s +{ + tree type; + const char *cloog_iv; +} *ivtype_map_elt; + +extern void debug_ivtype_map (htab_t); +extern hashval_t ivtype_map_elt_info (const void *); +extern int eq_ivtype_map_elts (const void *, const void *); + +/* Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW. */ + +static inline ivtype_map_elt +new_ivtype_map_elt (const char *cloog_iv, tree type) +{ + ivtype_map_elt res; + + res = XNEW (struct ivtype_map_elt_s); + res->cloog_iv = cloog_iv; + res->type = type; + + return res; +} + +/* Free and compute again all the dominators information. */ + +static inline void +recompute_all_dominators (void) +{ + mark_irreducible_loops (); + free_dominance_info (CDI_DOMINATORS); + free_dominance_info (CDI_POST_DOMINATORS); + calculate_dominance_info (CDI_DOMINATORS); + calculate_dominance_info (CDI_POST_DOMINATORS); +} + +typedef struct gimple_bb +{ + basic_block bb; + + /* Lists containing the restrictions of the conditional statements + dominating this bb. This bb can only be executed, if all conditions + are true. + + Example: + + for (i = 0; i <= 20; i++) + { + A + + if (2i <= 8) + B + } + + So for B there is an additional condition (2i <= 8). + + List of COND_EXPR and SWITCH_EXPR. A COND_EXPR is true only if the + corresponding element in CONDITION_CASES is not NULL_TREE. For a + SWITCH_EXPR the corresponding element in CONDITION_CASES is a + CASE_LABEL_EXPR. */ + VEC (gimple, heap) *conditions; + VEC (gimple, heap) *condition_cases; + VEC (data_reference_p, heap) *data_refs; + htab_t cloog_iv_types; +} *gimple_bb_p; + +#define GBB_BB(GBB) GBB->bb +#define GBB_DATA_REFS(GBB) GBB->data_refs +#define GBB_CONDITIONS(GBB) GBB->conditions +#define GBB_CONDITION_CASES(GBB) GBB->condition_cases +#define GBB_CLOOG_IV_TYPES(GBB) GBB->cloog_iv_types + +/* Return the innermost loop that contains the basic block GBB. */ + +static inline struct loop * +gbb_loop (struct gimple_bb *gbb) +{ + return GBB_BB (gbb)->loop_father; +} + +/* Returns the gimple loop, that corresponds to the loop_iterator_INDEX. + If there is no corresponding gimple loop, we return NULL. */ + +static inline loop_p +gbb_loop_at_index (gimple_bb_p gbb, sese region, int index) +{ + loop_p loop = gbb_loop (gbb); + int depth = sese_loop_depth (region, loop); + + while (--depth > index) + loop = loop_outer (loop); + + gcc_assert (sese_contains_loop (region, loop)); + + return loop; +} + +/* The number of common loops in REGION for GBB1 and GBB2. */ + +static inline int +nb_common_loops (sese region, gimple_bb_p gbb1, gimple_bb_p gbb2) +{ + loop_p l1 = gbb_loop (gbb1); + loop_p l2 = gbb_loop (gbb2); + loop_p common = find_common_loop (l1, l2); + + return sese_loop_depth (region, common); +} + +extern void print_gimple_bb (FILE *, gimple_bb_p, int, int); +extern void debug_gbb (gimple_bb_p, int); + +#endif diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index ff690684ee6..e3809a85000 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -1997,6 +1997,7 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, /* x*2 is x+x and x*(-1) is -x */ if (GET_CODE (trueop1) == CONST_DOUBLE && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1)) + && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1)) && GET_MODE (op0) == mode) { REAL_VALUE_TYPE d; diff --git a/gcc/stmt.c b/gcc/stmt.c index d03140c2da3..0e1d74463fe 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -1514,23 +1514,22 @@ expand_value_return (rtx val) /* Copy the value to the return location unless it's already there. */ - rtx return_reg = DECL_RTL (DECL_RESULT (current_function_decl)); + tree decl = DECL_RESULT (current_function_decl); + rtx return_reg = DECL_RTL (decl); if (return_reg != val) { - tree type = TREE_TYPE (DECL_RESULT (current_function_decl)); - if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl))) - { - int unsignedp = TYPE_UNSIGNED (type); - enum machine_mode old_mode - = DECL_MODE (DECL_RESULT (current_function_decl)); - enum machine_mode mode - = promote_mode (type, old_mode, &unsignedp, 1); - - if (mode != old_mode) - val = convert_modes (mode, old_mode, val, unsignedp); - } + int unsignedp; + enum machine_mode old_mode = DECL_MODE (decl); + enum machine_mode mode = promote_decl_mode (decl, &unsignedp); + + if (mode != old_mode) + val = convert_modes (mode, old_mode, val, unsignedp); + if (GET_CODE (return_reg) == PARALLEL) - emit_group_load (return_reg, val, type, int_size_in_bytes (type)); + { + tree type = TREE_TYPE (decl); + emit_group_load (return_reg, val, type, int_size_in_bytes (type)); + } else emit_move_insn (return_reg, val); } @@ -1848,9 +1847,7 @@ expand_decl (tree decl) else if (use_register_for_decl (decl)) { /* Automatic variable that can go in a register. */ - int unsignedp = TYPE_UNSIGNED (type); - enum machine_mode reg_mode - = promote_mode (type, DECL_MODE (decl), &unsignedp, 0); + enum machine_mode reg_mode = promote_decl_mode (decl, NULL); SET_DECL_RTL (decl, gen_reg_rtx (reg_mode)); diff --git a/gcc/system.h b/gcc/system.h index 7a9ca816693..5d47f2e1839 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -684,7 +684,7 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; DIVDI3_LIBCALL UDIVSI3_LIBCALL UDIVDI3_LIBCALL MODSI3_LIBCALL \ MODDI3_LIBCALL UMODSI3_LIBCALL UMODDI3_LIBCALL BUILD_VA_LIST_TYPE \ PRETEND_OUTGOING_VARARGS_NAMED STRUCT_VALUE_INCOMING_REGNUM \ - ASM_OUTPUT_SECTION_NAME PROMOTE_FUNCTION_ARGS \ + ASM_OUTPUT_SECTION_NAME PROMOTE_FUNCTION_ARGS PROMOTE_FUNCTION_MODE \ STRUCT_VALUE_INCOMING STRICT_ARGUMENT_NAMING \ PROMOTE_FUNCTION_RETURN PROMOTE_PROTOTYPES STRUCT_VALUE_REGNUM \ SETUP_INCOMING_VARARGS EXPAND_BUILTIN_SAVEREGS \ @@ -754,7 +754,8 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS \ LANG_HOOKS_PUSHLEVEL LANG_HOOKS_SET_BLOCK \ LANG_HOOKS_MAYBE_BUILD_CLEANUP LANG_HOOKS_UPDATE_DECL_AFTER_SAVING \ - LANG_HOOKS_POPLEVEL LANG_HOOKS_TRUTHVALUE_CONVERSION + LANG_HOOKS_POPLEVEL LANG_HOOKS_TRUTHVALUE_CONVERSION \ + TARGET_PROMOTE_FUNCTION_ARGS TARGET_PROMOTE_FUNCTION_RETURN /* Miscellaneous macros that are no longer used. */ #pragma GCC poison USE_MAPPED_LOCATION diff --git a/gcc/target-def.h b/gcc/target-def.h index 54060f5395c..26464ed4472 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -574,8 +574,7 @@ #define TARGET_ARM_EABI_UNWINDER false -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_false -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_false +#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false #define TARGET_STRUCT_VALUE_RTX hook_rtx_tree_int_null @@ -605,8 +604,7 @@ #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS hook_bool_void_true #define TARGET_CALLS { \ - TARGET_PROMOTE_FUNCTION_ARGS, \ - TARGET_PROMOTE_FUNCTION_RETURN, \ + TARGET_PROMOTE_FUNCTION_MODE, \ TARGET_PROMOTE_PROTOTYPES, \ TARGET_STRUCT_VALUE_RTX, \ TARGET_RETURN_IN_MEMORY, \ diff --git a/gcc/target.h b/gcc/target.h index bd107179498..27fd77b7779 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -832,8 +832,11 @@ struct gcc_target /* Functions relating to calls - argument passing, returns, etc. */ struct calls { - bool (*promote_function_args) (const_tree fntype); - bool (*promote_function_return) (const_tree fntype); + enum machine_mode (*promote_function_mode) (const_tree type, + enum machine_mode mode, + int *punsignedp, + const_tree fntype, + int for_return); bool (*promote_prototypes) (const_tree fntype); rtx (*struct_value_rtx) (tree fndecl, int incoming); bool (*return_in_memory) (const_tree type, const_tree fndecl); diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 7d5a09233c7..8c3c2ab1e24 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -113,6 +113,27 @@ default_unspec_may_trap_p (const_rtx x, unsigned flags) } enum machine_mode +default_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, + enum machine_mode mode, + int *punsignedp ATTRIBUTE_UNUSED, + const_tree funtype ATTRIBUTE_UNUSED, + int for_return ATTRIBUTE_UNUSED) +{ + return mode; +} + +enum machine_mode +default_promote_function_mode_always_promote (const_tree type, + enum machine_mode mode, + int *punsignedp, + const_tree funtype ATTRIBUTE_UNUSED, + int for_return ATTRIBUTE_UNUSED) +{ + return promote_mode (type, mode, punsignedp); +} + + +enum machine_mode default_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2) { if (m1 == m2) diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 839f1c32360..5564a7983cf 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -24,6 +24,10 @@ extern void default_external_libcall (rtx); extern rtx default_legitimize_address (rtx, rtx, enum machine_mode); extern int default_unspec_may_trap_p (const_rtx, unsigned); +extern enum machine_mode default_promote_function_mode (const_tree, enum machine_mode, + int *, const_tree, int); +extern enum machine_mode default_promote_function_mode_always_promote + (const_tree, enum machine_mode, int *, const_tree, int); extern enum machine_mode default_cc_modes_compatible (enum machine_mode, enum machine_mode); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e3b61034dc9..0d4378cfc0a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,469 @@ +2009-08-04 Dodji Seketeli <dodji@redhat.com> + + PR c++/39987 + * g++.dg/overload/defarg4.C: New test. + +2009-08-04 Manuel López-Ibáñez <manu@gcc.gnu.org> + + PR c++/16696 + * g++.dg/parse/pr16696.C: New. + * g++.dg/parse/pr16696-permissive.C: New. + +2009-08-04 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/40875 + * gfortran.dg/initialization_23.f90 : New test. + +2009-08-04 Dodji Seketeli <dodji@redhat.com> + + PR debug/39706 + * g++.dg/debug/dwarf2/pubnames-1.C: New test. + +2009-08-03 Jason Merrill <jason@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + PR c++/40948 + * g++.dg/ext/complit12.C: New. + +2009-08-03 Janis Johnson <janis187@us.ibm.com> + + PR c/39902 + * gcc.target/powerpc/pr39902-2.c: New test. + +2009-08-03 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/40943 + * gcc.dg/uninit-6.c: Re-add XFAIL. + * gcc.dg/uninit-6-O0.c: Likewise. + * gcc.dg/uninit-pr40943.c: New test. + +2009-08-03 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> + + PR testsuite/40858 + * g++.dg/debug/dwarf2/typedef1.C: Also match assembler string used with + .ascii. + +2009-08-02 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + PR libfortran/40853 + * gfortran.dg/namelist_40.f90: Update error output. + * gfortran.dg/namelist_47.f90: Update error output. + * gfortran.dg/namelist_58.f90: New test. + +2009-08-02 Janus Weil <janus@gcc.gnu.org> + + PR fortran/40881 + * gfortran.dg/aliasing_dummy_1.f90: Add -std=legacy. + * gfortran.dg/altreturn_3.f90: Ditto. + * gfortran.dg/altreturn_5.f90: Ditto. + * gfortran.dg/altreturn_6.f90: Ditto. + * gfortran.dg/altreturn_7.f90: Ditto. + * gfortran.dg/array_constructor_13.f90: Ditto. + * gfortran.dg/arrayio_7.f90: Ditto. + * gfortran.dg/arrayio_8.f90: Ditto. + * gfortran.dg/assumed_charlen_function_3.f90: Modified warning message. + * gfortran.dg/assumed_charlen_function_4.f90: Add -std=legacy. + * gfortran.dg/assumed_charlen_function_5.f90: Modified warning message. + * gfortran.dg/backspace_8.f: Add -std=legacy. + * gfortran.dg/backspace_9.f: Ditto. + * gfortran.dg/char_comparison_1.f: Ditto. + * gfortran.dg/char_decl_1.f90: Ditto. + * gfortran.dg/char_initialiser_actual.f90: Ditto. + * gfortran.dg/char_pointer_assign.f90: Ditto. + * gfortran.dg/char_pointer_dependency.f90: Ditto. + * gfortran.dg/char_pointer_dummy.f90: Ditto. + * gfortran.dg/char_pointer_func.f90: Ditto. + * gfortran.dg/common_8.f90: Ditto. + * gfortran.dg/constant_substring.f: Ditto. + * gfortran.dg/data_char_2.f90: Ditto. + * gfortran.dg/der_array_io_1.f90: Ditto. + * gfortran.dg/der_array_io_2.f90: Ditto. + * gfortran.dg/der_array_io_3.f90: Ditto. + * gfortran.dg/der_io_3.f90: Ditto. + * gfortran.dg/dev_null.F90: Ditto. + * gfortran.dg/direct_io_2.f90: Ditto. + * gfortran.dg/do_iterator_2.f90: Ditto. + * gfortran.dg/e_d_fmt.f90: Ditto. + * gfortran.dg/empty_format_1.f90: Ditto. + * gfortran.dg/entry_17.f90: Modified warning message. + * gfortran.dg/entry_7.f90: Add -std=legacy. + * gfortran.dg/eor_1.f90: Ditto. + * gfortran.dg/equiv_2.f90: Ditto. + * gfortran.dg/equiv_constraint_2.f90: Use new-style character length. + * gfortran.dg/equiv_substr.f90: Add -std=legacy. + * gfortran.dg/extended_char_comparison_1.f: Ditto. + * gfortran.dg/fmt_bz_bn_err.f: Ditto. + * gfortran.dg/fmt_error_2.f90: Ditto. + * gfortran.dg/fmt_read_bz_bn.f90: Ditto. + * gfortran.dg/fmt_tl.f: Ditto. + * gfortran.dg/fmt_white.f: Ditto. + * gfortran.dg/func_derived_1.f90: Ditto. + * gfortran.dg/g77_intrinsics_funcs.f: Ditto. + * gfortran.dg/g77_intrinsics_sub.f: Ditto. + * gfortran.dg/global_references_2.f90: Ditto. + * gfortran.dg/hollerith_1.f90: Ditto. + * gfortran.dg/hollerith.f90: Use new-style character length. + * gfortran.dg/hollerith_f95.f90: Ditto. + * gfortran.dg/ichar_1.f90: Add -std=legacy. + * gfortran.dg/implicit_6.f90: Ditto. + * gfortran.dg/implicit_9.f90: Ditto. + * gfortran.dg/inquire_13.f90: Ditto. + * gfortran.dg/inquire_5.f90: Ditto. + * gfortran.dg/inquire_6.f90: Ditto. + * gfortran.dg/inquire.f90: Ditto. + * gfortran.dg/io_constraints_1.f90: Use new-style character length. + * gfortran.dg/io_constraints_2.f90: Ditto. + * gfortran.dg/list_read_2.f90: Add -std=legacy. + * gfortran.dg/loc_2.f90: Ditto. + * gfortran.dg/logical_1.f90: Ditto. + * gfortran.dg/longline.f: Ditto. + * gfortran.dg/merge_char_1.f90: Ditto. + * gfortran.dg/namelist_12.f: Ditto. + * gfortran.dg/namelist_14.f90: Ditto. + * gfortran.dg/namelist_18.f90: Ditto. + * gfortran.dg/namelist_19.f90: Ditto. + * gfortran.dg/namelist_21.f90: Ditto. + * gfortran.dg/namelist_22.f90: Ditto. + * gfortran.dg/namelist_37.f90: Ditto. + * gfortran.dg/namelist_54.f90: Ditto. + * gfortran.dg/namelist_55.f90: Ditto. + * gfortran.dg/namelist_empty.f90: Ditto. + * gfortran.dg/namelist_use.f90: Use new-style character length. + * gfortran.dg/namelist_use_only.f90: Add -std=legacy. + * gfortran.dg/nested_modules_4.f90: Ditto. + * gfortran.dg/nested_modules_5.f90: Ditto. + * gfortran.dg/open-options-blanks.f: Ditto. + * gfortran.dg/output_exponents_1.f90: Ditto. + * gfortran.dg/parens_5.f90: Ditto. + * gfortran.dg/parens_6.f90: Ditto. + * gfortran.dg/parent_result_ref_2.f90: Modified warning message. + * gfortran.dg/pointer_function_actual_1.f90: Add -std=legacy. + * gfortran.dg/pr15129.f90: Ditto. + * gfortran.dg/pr15332.f: Ditto. + * gfortran.dg/pr16597.f90: Ditto. + * gfortran.dg/pr17143.f90: Ditto. + * gfortran.dg/pr17164.f90: Ditto. + * gfortran.dg/pr17229.f: Modified warning message. + * gfortran.dg/pr18210.f90: Add -std=legacy. + * gfortran.dg/pr19155.f: Ditto. + * gfortran.dg/pr20086.f90: Ditto. + * gfortran.dg/pr20124.f90: Ditto. + * gfortran.dg/pr20755.f: Ditto. + * gfortran.dg/pr20865.f90: Ditto. + * gfortran.dg/pr20950.f: Ditto. + * gfortran.dg/pr21730.f: Ditto. + * gfortran.dg/pr22491.f: Ditto. + * gfortran.dg/pr29713.f90: Ditto. + * gfortran.dg/print_parentheses_1.f: Ditto. + * gfortran.dg/print_parentheses_2.f90: Ditto. + * gfortran.dg/proc_assign_1.f90: Ditto. + * gfortran.dg/proc_decl_1.f90: Ditto. + * gfortran.dg/proc_ptr_17.f90: Add dg-warning. + * gfortran.dg/read_eor.f90: : Add -std=legacy. + * gfortran.dg/read_float_1.f90: Ditto. + * gfortran.dg/read_logical.f90: Ditto. + * gfortran.dg/recursive_statement_functions.f90: Ditto. + * gfortran.dg/return_1.f90: Ditto. + * gfortran.dg/rewind_1.f90: Ditto. + * gfortran.dg/runtime_warning_1.f90: Use new-style character length. + * gfortran.dg/scalar_return_1.f90: Add -std=legacy. + * gfortran.dg/stfunc_1.f90: Ditto. + * gfortran.dg/stfunc_3.f90: Ditto. + * gfortran.dg/stfunc_4.f90: Ditto. + * gfortran.dg/stfunc_6.f90: Ditto. + * gfortran.dg/streamio_2.f90: Ditto. + * gfortran.dg/string_ctor_1.f90: Ditto. + * gfortran.dg/string_null_compare_1.f: Ditto. + * gfortran.dg/substr_6.f90: Ditto. + * gfortran.dg/tl_editing.f90: Ditto. + * gfortran.dg/unf_io_convert_1.f90: Use new-style character length. + * gfortran.dg/warnings_are_errors_1.f90: Modified warning message. + * gfortran.dg/x_slash_1.f: Add -std=legacy. + * gfortran.dg/g77/1832.f: Ditto. + * gfortran.dg/g77/19981216-0.f Ditto. + * gfortran.dg/g77/19990525-0.f: Ditto. + * gfortran.dg/g77/19990826-2.f: Ditto. + * gfortran.dg/g77/20000630-2.f: Ditto. + * gfortran.dg/g77/20010116.f: Ditto. + * gfortran.dg/g77/20010519-1.f: Use new-style character length. + * gfortran.dg/g77/980419-2.f: Add -std=legacy. + * gfortran.dg/g77/980520-1.f: Ditto. + * gfortran.dg/g77/check0.f: Ditto. + * gfortran.dg/g77/cpp3.F: Ditto. + * gfortran.dg/g77/cpp4.F: Use new-style character length. + * gfortran.dg/g77/f77-edit-i-in.f: Add -std=legacy. + * gfortran.dg/g77/f77-edit-t-in.f: Ditto. + * gfortran.dg/g77/short.f: Ditto. + +2009-08-01 Adam Nemet <anemet@caviumnetworks.com> + + * gcc.target/mips/ext-3.c: Add NOMIPS16. + * gcc.target/mips/ext-4.c: Likewise. + * gcc.target/mips/interrupt_handler.c: Likewise. + * gcc.target/mips/truncate-4.c: Likewise. + * gcc.target/mips/truncate-5.c: Likewise. + +2009-08-01 Sebastian Pop <sebastian.pop@amd.com> + + * gcc.dg/graphite/graphite_autopar/graphite_autopar.exp: Rename + -fgraphite-force-parallel to -floop-parallelize-all. + +2009-08-01 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/40011 + * gfortran.dg/whole_file_7.f90: New test. + * gfortran.dg/whole_file_8.f90: New test. + * gfortran.dg/whole_file_9.f90: New test. + * gfortran.dg/whole_file_10.f90: New test. + * gfortran.dg/whole_file_11.f90: New test. + * gfortran.dg/whole_file_12.f90: New test. + * gfortran.dg/whole_file_13.f90: New test. + * gfortran.dg/whole_file_14.f90: New test. + +2009-07-31 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp0x/initlist22.C: Adjust for new rvalue reference + binding semantics. + * g++.dg/cpp0x/named.C: Likewise. + * g++.dg/cpp0x/overload.C: Likewise. + * g++.dg/cpp0x/rv1n.C: Likewise. + * g++.dg/cpp0x/rv1p.C: Likewise. + * g++.dg/cpp0x/rv2n.C: Likewise. + * g++.dg/cpp0x/rv2p.C: Likewise. + * g++.dg/cpp0x/rv3n.C: Likewise. + * g++.dg/cpp0x/rv3p.C: Likewise. + * g++.dg/cpp0x/rv4n.C: Likewise. + * g++.dg/cpp0x/rv4p.C: Likewise. + * g++.dg/cpp0x/rv5n.C: Likewise. + * g++.dg/cpp0x/rv5p.C: Likewise. + * g++.dg/cpp0x/rv6n.C: Likewise. + * g++.dg/cpp0x/rv6p.C: Likewise. + * g++.dg/cpp0x/rv7n.C: Likewise. + * g++.dg/cpp0x/rv7p.C: Likewise. + * g++.dg/cpp0x/template_deduction.C: Likewise. + * g++.dg/cpp0x/unnamed_refs.C: Likewise. + * g++.dg/cpp0x/overloadn.C: New. + * g++.dg/cpp0x/rv-cast.C: New. + +2009-07-31 Adam Nemet <anemet@caviumnetworks.com> + + * gcc.target/mips/ext-4.c: New test. + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * g++.dg/tree-ssa/pr33615.C: Fix pattern for lim. + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * gcc.dg/tree-ssa/20050314-1.c: Fix patterns for lim and dceloop. + * gcc.dg/tree-ssa/loop-32.c: Same. + * gcc.dg/tree-ssa/loop-33.c: Same. + * gcc.dg/tree-ssa/loop-34.c: Same. + * gcc.dg/tree-ssa/loop-35.c: Same. + * gcc.dg/tree-ssa/loop-7.c: Same. + * gcc.dg/tree-ssa/pr23109.c: Same. + * gcc.dg/tree-ssa/restrict-2.c: Same. + * gcc.dg/tree-ssa/restrict-3.c: Same. + * gcc.dg/tree-ssa/ssa-lim-1.c: Same. + * gcc.dg/tree-ssa/ssa-lim-2.c: Same. + * gcc.dg/tree-ssa/ssa-lim-3.c: Same. + * gcc.dg/tree-ssa/ssa-lim-6.c: Same. + * gcc.dg/tree-ssa/structopt-1.c: Same. + * gcc.dg/vect/dump-tree-dceloop-pr26359.c: Same. + * gfortran.dg/pr32921.f: Same. + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * gcc.dg/graphite/graphite_autopar/force-parallel-1.c: New. + * gcc.dg/graphite/graphite_autopar/force-parallel-2.c: New. + * gcc.dg/graphite/graphite_autopar/force-parallel-3.c: New. + * gcc.dg/graphite/graphite_autopar/force-parallel-4.c: New. + * gcc.dg/graphite/graphite_autopar/force-parallel-5.c: New. + * gcc.dg/graphite/graphite_autopar/force-parallel-6.c: New. + * gcc.dg/graphite/graphite_autopar/force-parallel-7.c: New. + * gcc.dg/graphite/graphite_autopar/force-parallel-8.c: New. + * gcc.dg/graphite/graphite_autopar/force-parallel-9.c: New. + * gcc.dg/graphite/graphite_autopar/graphite_autopar.exp: New. + * gcc.dg/graphite/id-1.c: New. + * gcc.dg/graphite/id-10.c: New. + * gcc.dg/graphite/id-11.c: New. + * gcc.dg/graphite/id-12.c: New. + * gcc.dg/graphite/id-13.c: New. + * gcc.dg/graphite/id-14.c: New. + * gcc.dg/graphite/id-15.c: New. + * gcc.dg/graphite/id-2.c: New. + * gcc.dg/graphite/id-3.c: New. + * gcc.dg/graphite/id-4.c: New. + * gcc.dg/graphite/id-5.c: New. + * gcc.dg/graphite/id-6.c: New. + * gcc.dg/graphite/id-7.c: New. + * gcc.dg/graphite/id-8.c: New. + * gcc.dg/graphite/id-9.c: New. + * gcc.dg/graphite/interchange-0.c: New. + * gcc.dg/graphite/interchange-1.c: New. + * gcc.dg/graphite/interchange-2.c: New. + * gcc.dg/graphite/interchange-3.c: New. + * gcc.dg/graphite/interchange-4.c: New. + * gcc.dg/graphite/interchange-5.c: New. + * gcc.dg/graphite/interchange-6.c: New. + * gcc.dg/graphite/interchange-7.c: New. + * gcc.dg/graphite/interchange-8.c: New. + * gcc.dg/graphite/pr35356-1.c: New. + * gcc.dg/graphite/pr35356-2.c: New. + * gcc.dg/graphite/pr35356-3.c: New. + * gcc.dg/graphite/pr40157.c: New. + * gcc.dg/graphite/run-id-1.c: New. + * gcc.dg/graphite/scop-20.c: New. + * gcc.dg/graphite/scop-21.c: New. + * gfortran.dg/graphite/id-1.f90: New. + * gfortran.dg/graphite/id-10.f90: New. + * gfortran.dg/graphite/id-11.f: New. + * gfortran.dg/graphite/id-12.f: New. + * gfortran.dg/graphite/id-13.f: New. + * gfortran.dg/graphite/id-14.f: New. + * gfortran.dg/graphite/id-15.f: New. + * gfortran.dg/graphite/id-16.f: New. + * gfortran.dg/graphite/id-5.f: New. + * gfortran.dg/graphite/id-6.f: New. + * gfortran.dg/graphite/id-7.f: New. + * gfortran.dg/graphite/id-8.f: New. + * gfortran.dg/graphite/id-9.f: New. + * gfortran.dg/graphite/interchange-1.f: New. + * gfortran.dg/graphite/interchange-2.f: New. + +2009-07-30 Sebastian Pop <sebastian.pop@amd.com> + + * gcc.dg/graphite/graphite.exp: Implement an automatic selection of + flags based on the name of the testcase. + * gfortran.dg/graphite/graphite.exp: Same. + + * gcc.dg/graphite/block-0.c: Adjusted. + * gcc.dg/graphite/block-1.c: Adjusted. + * gcc.dg/graphite/block-2.c: Adjusted. + * gcc.dg/graphite/block-3.c: Adjusted. + * gcc.dg/graphite/block-4.c: Adjusted. + * gcc.dg/graphite/block-5.c: Adjusted. + * gcc.dg/graphite/block-6.c: Adjusted. + * gcc.dg/graphite/pr37485.c: Adjusted. + * gcc.dg/graphite/pr37684.c: Adjusted. + * gcc.dg/graphite/pr37828.c: Adjusted. + * gcc.dg/graphite/pr37883.c: Adjusted. + * gcc.dg/graphite/pr37928.c: Adjusted. + * gcc.dg/graphite/pr37943.c: Adjusted. + * gcc.dg/graphite/pr38409.c: Adjusted. + * gcc.dg/graphite/pr38498.c: Adjusted. + * gcc.dg/graphite/pr38559.c: Adjusted. + * gcc.dg/graphite/pr39335.c: Adjusted. + * gcc.dg/graphite/pr39335_1.c: Adjusted. + * gcc.dg/graphite/scop-0.c: Adjusted. + * gcc.dg/graphite/scop-1.c: Adjusted. + * gcc.dg/graphite/scop-10.c: Adjusted. + * gcc.dg/graphite/scop-11.c: Adjusted. + * gcc.dg/graphite/scop-12.c: Adjusted. + * gcc.dg/graphite/scop-13.c: Adjusted. + * gcc.dg/graphite/scop-14.c: Adjusted. + * gcc.dg/graphite/scop-15.c: Adjusted. + * gcc.dg/graphite/scop-16.c: Adjusted. + * gcc.dg/graphite/scop-17.c: Adjusted. + * gcc.dg/graphite/scop-18.c: Adjusted. + * gcc.dg/graphite/scop-19.c: Adjusted. + * gcc.dg/graphite/scop-2.c: Adjusted. + * gcc.dg/graphite/scop-3.c: Adjusted.- + * gcc.dg/graphite/scop-4.c: Adjusted. + * gcc.dg/graphite/scop-5.c: Adjusted. + * gcc.dg/graphite/scop-6.c: Adjusted. + * gcc.dg/graphite/scop-7.c: Adjusted. + * gcc.dg/graphite/scop-8.c: Adjusted. + * gcc.dg/graphite/scop-9.c: Adjusted. + * gcc.dg/graphite/scop-matmult.c: Adjusted. + * gfortran.dg/graphite/block-1.f90: Adjusted. + * gfortran.dg/graphite/block-2.f: Adjusted. + * gfortran.dg/graphite/block-3.f90: Adjusted. + * gfortran.dg/graphite/block-4.f90: Adjusted. + * gfortran.dg/graphite/id-2.f90: Adjusted. + * gfortran.dg/graphite/id-3.f90: Adjusted. + * gfortran.dg/graphite/id-4.f90: Adjusted. + * gfortran.dg/graphite/pr37852.f90: Adjusted. + * gfortran.dg/graphite/pr37857.f90: Adjusted. + * gfortran.dg/graphite/pr37980.f90: Adjusted. + * gfortran.dg/graphite/pr38083.f90: Adjusted. + * gfortran.dg/graphite/pr38953.f90: Adjusted. + * gfortran.dg/graphite/scop-1.f: Adjusted. + +2009-07-30 Doug Kwan <dougkwan@google.com> + + * gcc.target/arm/neon/polytypes.c: Adjust test for new notes + in warnings added in rev 141298. + +2009-07-30 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> + + * lib/options.exp: Use "!=" instead of "ne". + + * gcc.dg/vector-4.c: Add -fno-common option on hppa*-*-hpux* (32-bit). + + * gcc.dg/ucnid-11.c: Skip on hppa*-*-hpux* (32-bit). + * gcc.dg/ucnid-12.c: Likewise. + +2009-07-30 Michael Meissner <meissner@linux.vnet.ibm.com> + Pat Haugen <pthaugen@us.ibm.com> + Revital Eres <ERES@il.ibm.com> + + * testsuite/gcc.target/powerpc/altivec-32.c: New file to test + Altivec simple math function vectorization. + + * testsuite/gcc.target/powerpc/bswap-run.c: New file to test swap + builtins. + * testsuite/gcc.target/powerpc/bswap16.c: Ditto. + * testsuite/gcc.target/powerpc/bswap32.c: Ditto. + * testsuite/gcc.target/powerpc/bswap64-1.c: Ditto. + * testsuite/gcc.target/powerpc/bswap64-2.c: Ditto. + * testsuite/gcc.target/powerpc/bswap64-3.c: Ditto. + * testsuite/gcc.target/powerpc/optimize-bswapdi-2.c: Ditto. + * testsuite/gcc.target/powerpc/optimize-bswapdi-3.c: Ditto. + * testsuite/gcc.target/powerpc/optimize-bswapsi-2.c: Ditto. + + * testsuite/gcc.target/powerpc/popcount-2.c: New file to test + power7 popcntd instructions. + * testsuite/gcc.target/powerpc/popcount-3.c: Ditto. + + * testsuite/gcc.target/powerpc/pr39457.c: New VSX test. + * testsuite/gcc.target/powerpc/vsx-builtin-1.c: Ditto. + * testsuite/gcc.target/powerpc/vsx-builtin-2.c: Ditto. + * testsuite/gcc.target/powerpc/vsx-builtin-3.c: Ditto. + * testsuite/gcc.target/powerpc/vsx-builtin-4.c: Ditto. + * testsuite/gcc.target/powerpc/vsx-builtin-5.c: Ditto. + * testsuite/gcc.target/powerpc/vsx-builtin-6.c: Ditto. + * testsuite/gcc.target/powerpc/vsx-vector-1.c: Ditto. + * testsuite/gcc.target/powerpc/vsx-vector-2.c: Ditto. + * testsuite/gcc.target/powerpc/vsx-vector-3.c: Ditto. + * testsuite/gcc.target/powerpc/vsx-vector-4.c: Ditto. + * testsuite/gcc.target/powerpc/vsx-vector-5.c: Ditto. + * testsuite/gcc.target/powerpc/vsx-vector-6.c: Ditto. + + * testsuite/gcc.target/powerpc/altivec-6.c: Store the result of + vec_add, so the optimizer doesn't remove it. + + * testsuite/gcc.dg/optimize-bswapdi-1.c: Add powerpc 64-bit to + systems that support bswap64. + + * testsuite/gcc.dg/vmx/vmx.exp: Explicitly add -mno-vsx to + prevent VSX code generation. + + * testsuite/lib/target-supports.exp (check_vsx_hw_available): New + function to test if VSX available. + (check_effective_target_powerpc_vsx_ok): Ditto. + (check_vmx_hw_available): Add explicit -mno-vsx. + +2009-07-30 Janis Johnson <janis187@us.ibm.com> + + PR c/39902 + * gcc.dg/dfp/pr39902.c: Fix typos in constant suffixes. + +2009-07-30 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/40570 + * gcc.c-torture/compile/pr40570.c: New test. + 2009-07-29 Jason Merrill <jason@redhat.com> PR c++/14912 diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist22.C b/gcc/testsuite/g++.dg/cpp0x/initlist22.C index bf1c554f5fc..0855b59d5d5 100644 --- a/gcc/testsuite/g++.dg/cpp0x/initlist22.C +++ b/gcc/testsuite/g++.dg/cpp0x/initlist22.C @@ -4,7 +4,7 @@ int i; int& r1{ i }; // OK, direct binding -int&& r2{ i }; // OK, direct binding +int&& r2{ i }; // { dg-error "" } binding && to lvalue int& r3{ }; // { dg-error "" } reference to temporary int&& r4{ }; // OK, reference to temporary diff --git a/gcc/testsuite/g++.dg/cpp0x/named.C b/gcc/testsuite/g++.dg/cpp0x/named.C index b91e6989425..ef1a2fb6f7d 100644 --- a/gcc/testsuite/g++.dg/cpp0x/named.C +++ b/gcc/testsuite/g++.dg/cpp0x/named.C @@ -1,12 +1,17 @@ // { dg-options "--std=c++0x" } // { dg-do link } +template<typename _Tp> +inline _Tp&& +movel(_Tp& __t) +{ return static_cast<_Tp&&>(__t); } + struct S {}; struct T { - T(S && s_) : s(s_) {} - S && get() { return s; } - operator S&&() { return s; } + T(S && s_) : s(movel(s_)) {} + S && get() { return movel(s); } + operator S&&() { return movel(s); } S && s; }; @@ -18,8 +23,8 @@ void unnamed(S&&) {} void f(S && p) { - S && s(p); - T t(s); + S && s(movel(p)); + T t(movel(s)); named(s); // variable reference named(p); // parameter reference diff --git a/gcc/testsuite/g++.dg/cpp0x/overload.C b/gcc/testsuite/g++.dg/cpp0x/overload.C index 945860cddb1..3782d4a208e 100644 --- a/gcc/testsuite/g++.dg/cpp0x/overload.C +++ b/gcc/testsuite/g++.dg/cpp0x/overload.C @@ -2,6 +2,11 @@ // { dg-do link } // Generated by overload.py +template<typename _Tp> +inline _Tp&& +movel(_Tp& __t) +{ return static_cast<_Tp&&>(__t); } + struct S{}; S l; // lvalue (l) @@ -10,12 +15,12 @@ S r() { return l; } // rvalue (r) S const cr() { return l; } // const rvalue (cr) S & nl = l; // named lvalue reference (nl) S const & ncl = l; // named const lvalue reference (ncl) -S && nr = l; // named rvalue reference (nr) -S const && ncr = l; // named const rvalue reference (ncr) +S && nr = movel(l); // named rvalue reference (nr) +S const && ncr = movel(l); // named const rvalue reference (ncr) S & ul() { return l; } // unnamed lvalue reference (ul) S const & ucl() { return l; } // unnamed const lvalue reference (ucl) -S && ur() { return l; } // unnamed rvalue reference (ur) -S const && ucr() { return l; } // unnamed const rvalue reference (ucr) +S && ur() { return movel(l); } // unnamed rvalue reference (ur) +S const && ucr() { return movel(l); } // unnamed const rvalue reference (ucr) void l0001(const S&&) {} @@ -538,9 +543,9 @@ void ucr1111(const S&&) {} int main() { - l0001(l); - l0010(l); - l0011(l); + //l0001(l); + //l0010(l); + //l0011(l); l0100(l); l0101(l); l0110(l); @@ -553,14 +558,14 @@ int main() l1101(l); l1110(l); l1111(l); - cl0001(cl); - cl0011(cl); + //cl0001(cl); + //cl0011(cl); cl0100(cl); cl0101(cl); cl0110(cl); cl0111(cl); - cl1001(cl); - cl1011(cl); + //cl1001(cl); + //cl1011(cl); cl1100(cl); cl1101(cl); cl1110(cl); @@ -591,9 +596,9 @@ int main() cr1101(cr()); cr1110(cr()); cr1111(cr()); - nl0001(nl); - nl0010(nl); - nl0011(nl); + //nl0001(nl); + //nl0010(nl); + //nl0011(nl); nl0100(nl); nl0101(nl); nl0110(nl); @@ -606,21 +611,21 @@ int main() nl1101(nl); nl1110(nl); nl1111(nl); - ncl0001(ncl); - ncl0011(ncl); + //ncl0001(ncl); + //ncl0011(ncl); ncl0100(ncl); ncl0101(ncl); ncl0110(ncl); ncl0111(ncl); - ncl1001(ncl); - ncl1011(ncl); + //ncl1001(ncl); + //ncl1011(ncl); ncl1100(ncl); ncl1101(ncl); ncl1110(ncl); ncl1111(ncl); - nr0001(nr); - nr0010(nr); - nr0011(nr); + //nr0001(nr); + //nr0010(nr); + //nr0011(nr); nr0100(nr); nr0101(nr); nr0110(nr); @@ -633,21 +638,21 @@ int main() nr1101(nr); nr1110(nr); nr1111(nr); - ncr0001(ncr); - ncr0011(ncr); + //ncr0001(ncr); + //ncr0011(ncr); ncr0100(ncr); ncr0101(ncr); ncr0110(ncr); ncr0111(ncr); - ncr1001(ncr); - ncr1011(ncr); + //ncr1001(ncr); + //ncr1011(ncr); ncr1100(ncr); ncr1101(ncr); ncr1110(ncr); ncr1111(ncr); - ul0001(ul()); - ul0010(ul()); - ul0011(ul()); + //ul0001(ul()); + //ul0010(ul()); + //ul0011(ul()); ul0100(ul()); ul0101(ul()); ul0110(ul()); @@ -660,14 +665,14 @@ int main() ul1101(ul()); ul1110(ul()); ul1111(ul()); - ucl0001(ucl()); - ucl0011(ucl()); + //ucl0001(ucl()); + //ucl0011(ucl()); ucl0100(ucl()); ucl0101(ucl()); ucl0110(ucl()); ucl0111(ucl()); - ucl1001(ucl()); - ucl1011(ucl()); + //ucl1001(ucl()); + //ucl1011(ucl()); ucl1100(ucl()); ucl1101(ucl()); ucl1110(ucl()); diff --git a/gcc/testsuite/g++.dg/cpp0x/overloadn.C b/gcc/testsuite/g++.dg/cpp0x/overloadn.C new file mode 100644 index 00000000000..a42707fe4f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/overloadn.C @@ -0,0 +1,708 @@ +// { dg-options "--std=c++0x" } +// { dg-do link } +// Generated by overload.py + +template<typename _Tp> +inline _Tp&& +movel(_Tp& __t) +{ return static_cast<_Tp&&>(__t); } + +struct S{}; + +S l; // lvalue (l) +S const cl = l; // const lvalue (cl) +S r() { return l; } // rvalue (r) +S const cr() { return l; } // const rvalue (cr) +S & nl = l; // named lvalue reference (nl) +S const & ncl = l; // named const lvalue reference (ncl) +S && nr = movel(l); // named rvalue reference (nr) +S const && ncr = movel(l); // named const rvalue reference (ncr) +S & ul() { return l; } // unnamed lvalue reference (ul) +S const & ucl() { return l; } // unnamed const lvalue reference (ucl) +S && ur() { return movel(l); } // unnamed rvalue reference (ur) +S const && ucr() { return movel(l); } // unnamed const rvalue reference (ucr) + +void l0001(const S&&) {} // { dg-message "" } + +void l0010(S&&) {} // { dg-message "" } + +void l0011(S&&) {} // { dg-message "" } +void l0011(const S&&); + +void l0100(const S&) {} + +void l0101(const S&) {} +void l0101(const S&&); + +void l0110(const S&) {} +void l0110(S&&); + +void l0111(const S&) {} +void l0111(S&&); +void l0111(const S&&); + +void l1000(S&) {} + +void l1001(S&) {} +void l1001(const S&&); + +void l1010(S&) {} +void l1010(S&&); + +void l1011(S&) {} +void l1011(S&&); +void l1011(const S&&); + +void l1100(S&) {} +void l1100(const S&); + +void l1101(S&) {} +void l1101(const S&); +void l1101(const S&&); + +void l1110(S&) {} +void l1110(const S&); +void l1110(S&&); + +void l1111(S&) {} +void l1111(const S&); +void l1111(S&&); +void l1111(const S&&); + +void cl0001(const S&&) {} // { dg-message "" } + +void cl0011(S&&); +void cl0011(const S&&) {} // { dg-message "" } + +void cl0100(const S&) {} + +void cl0101(const S&) {} +void cl0101(const S&&); + +void cl0110(const S&) {} +void cl0110(S&&); + +void cl0111(const S&) {} +void cl0111(S&&); +void cl0111(const S&&); + +void cl1001(S&); +void cl1001(const S&&) {} // { dg-message "" } + +void cl1011(S&); +void cl1011(S&&); +void cl1011(const S&&) {} // { dg-message "" } + +void cl1100(S&); +void cl1100(const S&) {} + +void cl1101(S&); +void cl1101(const S&) {} +void cl1101(const S&&); + +void cl1110(S&); +void cl1110(const S&) {} +void cl1110(S&&); + +void cl1111(S&); +void cl1111(const S&) {} +void cl1111(S&&); +void cl1111(const S&&); + +void r0001(const S&&) {} + +void r0010(S&&) {} + +void r0011(S&&) {} +void r0011(const S&&); + +void r0100(const S&) {} + +void r0101(const S&); +void r0101(const S&&) {} + +void r0110(const S&); +void r0110(S&&) {} + +void r0111(const S&); +void r0111(S&&) {} +void r0111(const S&&); + +void r1001(S&); +void r1001(const S&&) {} + +void r1010(S&); +void r1010(S&&) {} + +void r1011(S&); +void r1011(S&&) {} +void r1011(const S&&); + +void r1100(S&); +void r1100(const S&) {} + +void r1101(S&); +void r1101(const S&); +void r1101(const S&&) {} + +void r1110(S&); +void r1110(const S&); +void r1110(S&&) {} + +void r1111(S&); +void r1111(const S&); +void r1111(S&&) {} +void r1111(const S&&); + +void cr0001(const S&&) {} + +void cr0011(S&&); +void cr0011(const S&&) {} + +void cr0100(const S&) {} + +void cr0101(const S&); +void cr0101(const S&&) {} + +void cr0110(const S&) {} +void cr0110(S&&); + +void cr0111(const S&); +void cr0111(S&&); +void cr0111(const S&&) {} + +void cr1001(S&); +void cr1001(const S&&) {} + +void cr1011(S&); +void cr1011(S&&); +void cr1011(const S&&) {} + +void cr1100(S&); +void cr1100(const S&) {} + +void cr1101(S&); +void cr1101(const S&); +void cr1101(const S&&) {} + +void cr1110(S&); +void cr1110(const S&) {} +void cr1110(S&&); + +void cr1111(S&); +void cr1111(const S&); +void cr1111(S&&); +void cr1111(const S&&) {} + +void nl0001(const S&&) {} // { dg-message "" } + +void nl0010(S&&) {} // { dg-message "" } + +void nl0011(S&&) {} // { dg-message "" } +void nl0011(const S&&); + +void nl0100(const S&) {} + +void nl0101(const S&) {} +void nl0101(const S&&); + +void nl0110(const S&) {} +void nl0110(S&&); + +void nl0111(const S&) {} +void nl0111(S&&); +void nl0111(const S&&); + +void nl1000(S&) {} + +void nl1001(S&) {} +void nl1001(const S&&); + +void nl1010(S&) {} +void nl1010(S&&); + +void nl1011(S&) {} +void nl1011(S&&); +void nl1011(const S&&); + +void nl1100(S&) {} +void nl1100(const S&); + +void nl1101(S&) {} +void nl1101(const S&); +void nl1101(const S&&); + +void nl1110(S&) {} +void nl1110(const S&); +void nl1110(S&&); + +void nl1111(S&) {} +void nl1111(const S&); +void nl1111(S&&); +void nl1111(const S&&); + +void ncl0001(const S&&) {} // { dg-message "" } + +void ncl0011(S&&); +void ncl0011(const S&&) {} // { dg-message "" } + +void ncl0100(const S&) {} + +void ncl0101(const S&) {} +void ncl0101(const S&&); + +void ncl0110(const S&) {} +void ncl0110(S&&); + +void ncl0111(const S&) {} +void ncl0111(S&&); +void ncl0111(const S&&); + +void ncl1001(S&); +void ncl1001(const S&&) {} // { dg-message "" } + +void ncl1011(S&); +void ncl1011(S&&); +void ncl1011(const S&&) {} // { dg-message "" } + +void ncl1100(S&); +void ncl1100(const S&) {} + +void ncl1101(S&); +void ncl1101(const S&) {} +void ncl1101(const S&&); + +void ncl1110(S&); +void ncl1110(const S&) {} +void ncl1110(S&&); + +void ncl1111(S&); +void ncl1111(const S&) {} +void ncl1111(S&&); +void ncl1111(const S&&); + +void nr0001(const S&&) {} // { dg-message "" } + +void nr0010(S&&) {} // { dg-message "" } + +void nr0011(S&&) {} // { dg-message "" } +void nr0011(const S&&); + +void nr0100(const S&) {} + +void nr0101(const S&) {} +void nr0101(const S&&); + +void nr0110(const S&) {} +void nr0110(S&&); + +void nr0111(const S&) {} +void nr0111(S&&); +void nr0111(const S&&); + +void nr1000(S&) {} + +void nr1001(S&) {} +void nr1001(const S&&); + +void nr1010(S&) {} +void nr1010(S&&); + +void nr1011(S&) {} +void nr1011(S&&); +void nr1011(const S&&); + +void nr1100(S&) {} +void nr1100(const S&); + +void nr1101(S&) {} +void nr1101(const S&); +void nr1101(const S&&); + +void nr1110(S&) {} +void nr1110(const S&); +void nr1110(S&&); + +void nr1111(S&) {} +void nr1111(const S&); +void nr1111(S&&); +void nr1111(const S&&); + +void ncr0001(const S&&) {} // { dg-message "" } + +void ncr0011(S&&); +void ncr0011(const S&&) {} // { dg-message "" } + +void ncr0100(const S&) {} + +void ncr0101(const S&) {} +void ncr0101(const S&&); + +void ncr0110(const S&) {} +void ncr0110(S&&); + +void ncr0111(const S&) {} +void ncr0111(S&&); +void ncr0111(const S&&); + +void ncr1001(S&); +void ncr1001(const S&&) {} // { dg-message "" } + +void ncr1011(S&); +void ncr1011(S&&); +void ncr1011(const S&&) {} // { dg-message "" } + +void ncr1100(S&); +void ncr1100(const S&) {} + +void ncr1101(S&); +void ncr1101(const S&) {} +void ncr1101(const S&&); + +void ncr1110(S&); +void ncr1110(const S&) {} +void ncr1110(S&&); + +void ncr1111(S&); +void ncr1111(const S&) {} +void ncr1111(S&&); +void ncr1111(const S&&); + +void ul0001(const S&&) {} // { dg-message "" } + +void ul0010(S&&) {} // { dg-message "" } + +void ul0011(S&&) {} // { dg-message "" } +void ul0011(const S&&); + +void ul0100(const S&) {} + +void ul0101(const S&) {} +void ul0101(const S&&); + +void ul0110(const S&) {} +void ul0110(S&&); + +void ul0111(const S&) {} +void ul0111(S&&); +void ul0111(const S&&); + +void ul1000(S&) {} + +void ul1001(S&) {} +void ul1001(const S&&); + +void ul1010(S&) {} +void ul1010(S&&); + +void ul1011(S&) {} +void ul1011(S&&); +void ul1011(const S&&); + +void ul1100(S&) {} +void ul1100(const S&); + +void ul1101(S&) {} +void ul1101(const S&); +void ul1101(const S&&); + +void ul1110(S&) {} +void ul1110(const S&); +void ul1110(S&&); + +void ul1111(S&) {} +void ul1111(const S&); +void ul1111(S&&); +void ul1111(const S&&); + +void ucl0001(const S&&) {} // { dg-message "" } + +void ucl0011(S&&); +void ucl0011(const S&&) {} // { dg-message "" } + +void ucl0100(const S&) {} + +void ucl0101(const S&) {} +void ucl0101(const S&&); + +void ucl0110(const S&) {} +void ucl0110(S&&); + +void ucl0111(const S&) {} +void ucl0111(S&&); +void ucl0111(const S&&); + +void ucl1001(S&); +void ucl1001(const S&&) {} // { dg-message "" } + +void ucl1011(S&); +void ucl1011(S&&); +void ucl1011(const S&&) {} // { dg-message "" } + +void ucl1100(S&); +void ucl1100(const S&) {} + +void ucl1101(S&); +void ucl1101(const S&) {} +void ucl1101(const S&&); + +void ucl1110(S&); +void ucl1110(const S&) {} +void ucl1110(S&&); + +void ucl1111(S&); +void ucl1111(const S&) {} +void ucl1111(S&&); +void ucl1111(const S&&); + +void ur0001(const S&&) {} + +void ur0010(S&&) {} + +void ur0011(S&&) {} +void ur0011(const S&&); + +void ur0100(const S&) {} + +void ur0101(const S&); +void ur0101(const S&&) {} + +void ur0110(const S&); +void ur0110(S&&) {} + +void ur0111(const S&); +void ur0111(S&&) {} +void ur0111(const S&&); + +void ur1001(S&); +void ur1001(const S&&) {} + +void ur1010(S&); +void ur1010(S&&) {} + +void ur1011(S&); +void ur1011(S&&) {} +void ur1011(const S&&); + +void ur1100(S&); +void ur1100(const S&) {} + +void ur1101(S&); +void ur1101(const S&); +void ur1101(const S&&) {} + +void ur1110(S&); +void ur1110(const S&); +void ur1110(S&&) {} + +void ur1111(S&); +void ur1111(const S&); +void ur1111(S&&) {} +void ur1111(const S&&); + +void ucr0001(const S&&) {} + +void ucr0011(S&&); +void ucr0011(const S&&) {} + +void ucr0100(const S&) {} + +void ucr0101(const S&); +void ucr0101(const S&&) {} + +void ucr0110(const S&) {} +void ucr0110(S&&); + +void ucr0111(const S&); +void ucr0111(S&&); +void ucr0111(const S&&) {} + +void ucr1001(S&); +void ucr1001(const S&&) {} + +void ucr1011(S&); +void ucr1011(S&&); +void ucr1011(const S&&) {} + +void ucr1100(S&); +void ucr1100(const S&) {} + +void ucr1101(S&); +void ucr1101(const S&); +void ucr1101(const S&&) {} + +void ucr1110(S&); +void ucr1110(const S&) {} +void ucr1110(S&&); + +void ucr1111(S&); +void ucr1111(const S&); +void ucr1111(S&&); +void ucr1111(const S&&) {} + + +int main() +{ + l0001(l); // { dg-error "lvalue" } + l0010(l); // { dg-error "lvalue" } + l0011(l); // { dg-error "lvalue" } + l0100(l); + l0101(l); + l0110(l); + l0111(l); + l1000(l); + l1001(l); + l1010(l); + l1011(l); + l1100(l); + l1101(l); + l1110(l); + l1111(l); + cl0001(cl); // { dg-error "lvalue" } + cl0011(cl); // { dg-error "lvalue" } + cl0100(cl); + cl0101(cl); + cl0110(cl); + cl0111(cl); + cl1001(cl); // { dg-error "lvalue" } + cl1011(cl); // { dg-error "lvalue" } + cl1100(cl); + cl1101(cl); + cl1110(cl); + cl1111(cl); + r0001(r()); + r0010(r()); + r0011(r()); + r0100(r()); + r0101(r()); + r0110(r()); + r0111(r()); + r1001(r()); + r1010(r()); + r1011(r()); + r1100(r()); + r1101(r()); + r1110(r()); + r1111(r()); + cr0001(cr()); + cr0011(cr()); + cr0100(cr()); + cr0101(cr()); + cr0110(cr()); + cr0111(cr()); + cr1001(cr()); + cr1011(cr()); + cr1100(cr()); + cr1101(cr()); + cr1110(cr()); + cr1111(cr()); + nl0001(nl); // { dg-error "lvalue" } + nl0010(nl); // { dg-error "lvalue" } + nl0011(nl); // { dg-error "lvalue" } + nl0100(nl); + nl0101(nl); + nl0110(nl); + nl0111(nl); + nl1000(nl); + nl1001(nl); + nl1010(nl); + nl1011(nl); + nl1100(nl); + nl1101(nl); + nl1110(nl); + nl1111(nl); + ncl0001(ncl); // { dg-error "lvalue" } + ncl0011(ncl); // { dg-error "lvalue" } + ncl0100(ncl); + ncl0101(ncl); + ncl0110(ncl); + ncl0111(ncl); + ncl1001(ncl); // { dg-error "lvalue" } + ncl1011(ncl); // { dg-error "lvalue" } + ncl1100(ncl); + ncl1101(ncl); + ncl1110(ncl); + ncl1111(ncl); + nr0001(nr); // { dg-error "lvalue" } + nr0010(nr); // { dg-error "lvalue" } + nr0011(nr); // { dg-error "lvalue" } + nr0100(nr); + nr0101(nr); + nr0110(nr); + nr0111(nr); + nr1000(nr); + nr1001(nr); + nr1010(nr); + nr1011(nr); + nr1100(nr); + nr1101(nr); + nr1110(nr); + nr1111(nr); + ncr0001(ncr); // { dg-error "lvalue" } + ncr0011(ncr); // { dg-error "lvalue" } + ncr0100(ncr); + ncr0101(ncr); + ncr0110(ncr); + ncr0111(ncr); + ncr1001(ncr); // { dg-error "lvalue" } + ncr1011(ncr); // { dg-error "lvalue" } + ncr1100(ncr); + ncr1101(ncr); + ncr1110(ncr); + ncr1111(ncr); + ul0001(ul()); // { dg-error "lvalue" } + ul0010(ul()); // { dg-error "lvalue" } + ul0011(ul()); // { dg-error "lvalue" } + ul0100(ul()); + ul0101(ul()); + ul0110(ul()); + ul0111(ul()); + ul1000(ul()); + ul1001(ul()); + ul1010(ul()); + ul1011(ul()); + ul1100(ul()); + ul1101(ul()); + ul1110(ul()); + ul1111(ul()); + ucl0001(ucl()); // { dg-error "lvalue" } + ucl0011(ucl()); // { dg-error "lvalue" } + ucl0100(ucl()); + ucl0101(ucl()); + ucl0110(ucl()); + ucl0111(ucl()); + ucl1001(ucl()); // { dg-error "lvalue" } + ucl1011(ucl()); // { dg-error "lvalue" } + ucl1100(ucl()); + ucl1101(ucl()); + ucl1110(ucl()); + ucl1111(ucl()); + ur0001(ur()); + ur0010(ur()); + ur0011(ur()); + ur0100(ur()); + ur0101(ur()); + ur0110(ur()); + ur0111(ur()); + ur1001(ur()); + ur1010(ur()); + ur1011(ur()); + ur1100(ur()); + ur1101(ur()); + ur1110(ur()); + ur1111(ur()); + ucr0001(ucr()); + ucr0011(ucr()); + ucr0100(ucr()); + ucr0101(ucr()); + ucr0110(ucr()); + ucr0111(ucr()); + ucr1001(ucr()); + ucr1011(ucr()); + ucr1100(ucr()); + ucr1101(ucr()); + ucr1110(ucr()); + ucr1111(ucr()); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-cast.C b/gcc/testsuite/g++.dg/cpp0x/rv-cast.C new file mode 100644 index 00000000000..48b7c13ba59 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/rv-cast.C @@ -0,0 +1,6 @@ +// { dg-options "-std=c++0x" } + +void f(int i) +{ + int&& r = static_cast<int&&>(i); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/rv1n.C b/gcc/testsuite/g++.dg/cpp0x/rv1n.C index 10b5dc256b4..b7b9b6e25ce 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv1n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv1n.C @@ -1,6 +1,6 @@ // I, Howard Hinnant, hereby place this code in the public domain. -// Test overlaod resolution among referece types +// Test overload resolution among reference types // { dg-do compile } // { dg-options "-std=c++0x" } @@ -103,6 +103,7 @@ int test1_5() const A ca = a; volatile A va; const volatile A cva = a; + sink_1_5(a); // { dg-error "lvalue" } sink_1_5(ca); // { dg-error "invalid initialization" } sink_1_5(va); // { dg-error "invalid initialization" } sink_1_5(cva); // { dg-error "invalid initialization" } @@ -120,6 +121,8 @@ int test1_6() const A ca = a; volatile A va; const volatile A cva = a; + sink_1_6(a); // { dg-error "lvalue" } + sink_1_6(ca); // { dg-error "lvalue" } sink_1_6(va); // { dg-error "invalid initialization" } sink_1_6(cva); // { dg-error "invalid initialization" } sink_1_6(v_source()); // { dg-error "invalid initialization" } @@ -135,13 +138,30 @@ int test1_7() const A ca = a; volatile A va; const volatile A cva = a; + sink_1_7(a); // { dg-error "lvalue" } sink_1_7(ca); // { dg-error "invalid initialization" } + sink_1_7(va); // { dg-error "lvalue" } sink_1_7(cva); // { dg-error "invalid initialization" } sink_1_7(c_source()); // { dg-error "invalid initialization" } sink_1_7(cv_source()); // { dg-error "invalid initialization" } return 0; } +eight sink_1_8(const volatile A&&); // { dg-error "" } + +int test1_8() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_1_8(a); // { dg-error "lvalue" } + sink_1_8(ca); // { dg-error "lvalue" } + sink_1_8(va); // { dg-error "lvalue" } + sink_1_8(cva); // { dg-error "lvalue" } + return 0; +} + int main() { return test1_1() + test1_2() + test1_3() + test1_5() + diff --git a/gcc/testsuite/g++.dg/cpp0x/rv1p.C b/gcc/testsuite/g++.dg/cpp0x/rv1p.C index 6241885654e..b2770ef33d5 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv1p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv1p.C @@ -1,6 +1,6 @@ // I, Howard Hinnant, hereby place this code in the public domain. -// Test overlaod resolution among referece types +// Test overload resolution among reference types // { dg-do compile } // { dg-options "-std=c++0x" } @@ -93,7 +93,6 @@ int test1_5() const A ca = a; volatile A va; const volatile A cva = a; - sa<sizeof(sink_1_5(a)) == 5> t1; sa<sizeof(sink_1_5(source())) == 5> t5; return 0; } @@ -106,8 +105,6 @@ int test1_6() const A ca = a; volatile A va; const volatile A cva = a; - sa<sizeof(sink_1_6(a)) == 6> t1; - sa<sizeof(sink_1_6(ca)) == 6> t2; sa<sizeof(sink_1_6(source())) == 6> t5; sa<sizeof(sink_1_6(c_source())) == 6> t6; return 0; @@ -121,8 +118,6 @@ int test1_7() const A ca = a; volatile A va; const volatile A cva = a; - sa<sizeof(sink_1_7(a)) == 7> t1; - sa<sizeof(sink_1_7(va)) == 7> t3; sa<sizeof(sink_1_7(source())) == 7> t5; sa<sizeof(sink_1_7(v_source())) == 7> t7; return 0; @@ -136,10 +131,6 @@ int test1_8() const A ca = a; volatile A va; const volatile A cva = a; - sa<sizeof(sink_1_8(a)) == 8> t1; - sa<sizeof(sink_1_8(ca)) == 8> t2; - sa<sizeof(sink_1_8(va)) == 8> t3; - sa<sizeof(sink_1_8(cva)) == 8> t4; sa<sizeof(sink_1_8(source())) == 8> t5; sa<sizeof(sink_1_8(c_source())) == 8> t6; sa<sizeof(sink_1_8(v_source())) == 8> t7; diff --git a/gcc/testsuite/g++.dg/cpp0x/rv2n.C b/gcc/testsuite/g++.dg/cpp0x/rv2n.C index a4c11c60e2d..5eee82c4bcf 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv2n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv2n.C @@ -1,6 +1,6 @@ // I, Howard Hinnant, hereby place this code in the public domain. -// Test overlaod resolution among referece types +// Test overload resolution among reference types // { dg-do compile } // { dg-options "-std=c++0x" } @@ -30,8 +30,8 @@ const volatile A cv_source(); // 2 at a time -one sink_2_12( A&); // { dg-message "candidates" } -two sink_2_12(const A&); // { dg-message "note" } +one sink_2_12( A&); // { dg-message "candidates|argument" } +two sink_2_12(const A&); // { dg-message "note|argument" } int test2_12() { @@ -46,8 +46,8 @@ int test2_12() return 0; } -one sink_2_13( A&); // { dg-message "candidates" } -three sink_2_13(volatile A&); // { dg-message "note" } +one sink_2_13( A&); // { dg-message "candidates|argument" } +three sink_2_13(volatile A&); // { dg-message "note|argument" } int test2_13() { @@ -64,8 +64,8 @@ int test2_13() return 0; } -one sink_2_14( A&); // { dg-message "candidates" } -four sink_2_14(const volatile A&); // { dg-message "note" } +one sink_2_14( A&); // { dg-message "candidates|argument" } +four sink_2_14(const volatile A&); // { dg-message "note|argument" } int test2_14() { @@ -80,8 +80,8 @@ int test2_14() return 0; } -one sink_2_15( A&); // { dg-message "candidates" } -five sink_2_15( A&&); // { dg-message "note" } +one sink_2_15( A&); // { dg-message "candidates|argument" } +five sink_2_15( A&&); // { dg-message "note|argument" } int test2_15() { @@ -98,8 +98,8 @@ int test2_15() return 0; } -one sink_2_16( A&); // { dg-message "candidates" } -six sink_2_16(const A&&); // { dg-message "note" } +one sink_2_16( A&); // { dg-message "candidates|argument" } +six sink_2_16(const A&&); // { dg-message "note|argument" } int test2_16() { @@ -107,6 +107,7 @@ int test2_16() const A ca = a; volatile A va; const volatile A cva = a; + sink_2_16(ca); // { dg-error "lvalue" } sink_2_16(va); // { dg-error "no match" } sink_2_16(cva); // { dg-error "no match" } sink_2_16(v_source()); // { dg-error "no match" } @@ -114,8 +115,8 @@ int test2_16() return 0; } -one sink_2_17( A&); // { dg-message "candidates" } -seven sink_2_17(volatile A&&); // { dg-message "note" } +one sink_2_17( A&); // { dg-message "candidates|argument" } +seven sink_2_17(volatile A&&); // { dg-message "note|argument" } int test2_17() { @@ -124,14 +125,29 @@ int test2_17() volatile A va; const volatile A cva = a; sink_2_17(ca); // { dg-error "no match" } + sink_2_17(va); // { dg-error "lvalue" } sink_2_17(cva); // { dg-error "no match" } sink_2_17(c_source()); // { dg-error "no match" } sink_2_17(cv_source()); // { dg-error "no match" } return 0; } -two sink_2_23(const A&); // { dg-message "candidates" } -three sink_2_23(volatile A&); // { dg-message "note" } +one sink_2_18( A&); +eight sink_2_18(const volatile A&&); // { dg-error "argument" } + +int test2_18() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_2_18(ca); // { dg-error "lvalue" } + sink_2_18(va); // { dg-error "lvalue" } + sink_2_18(cva); // { dg-error "lvalue" } +} + +two sink_2_23(const A&); // { dg-message "candidates|argument" } +three sink_2_23(volatile A&); // { dg-message "note|argument" } int test2_23() { @@ -146,8 +162,8 @@ int test2_23() return 0; } -two sink_2_24(const A&); // { dg-message "candidates" } -four sink_2_24(const volatile A&); // { dg-message "note" } +two sink_2_24(const A&); // { dg-message "candidates|argument" } +four sink_2_24(const volatile A&); // { dg-message "note|argument" } int test2_24() { @@ -161,7 +177,7 @@ int test2_24() } three sink_2_34(volatile A&); // { dg-message "candidate" } -four sink_2_34(const volatile A&); // { dg-message "note" } +four sink_2_34(const volatile A&); // { dg-message "note|argument" } int test2_34() { @@ -177,7 +193,7 @@ int test2_34() } two sink_2_25(const A&); // { dg-message "candidate" } -five sink_2_25( A&&); // { dg-message "note" } +five sink_2_25( A&&); // { dg-message "note|argument" } int test2_25() { @@ -193,7 +209,7 @@ int test2_25() } two sink_2_26(const A&); // { dg-message "candidate" } -six sink_2_26(const A&&); // { dg-message "note" } +six sink_2_26(const A&&); // { dg-message "note|argument" } int test2_26() { @@ -209,7 +225,7 @@ int test2_26() } two sink_2_27(const A&); // { dg-message "candidate" } -seven sink_2_27(volatile A&&); // { dg-message "note" } +seven sink_2_27(volatile A&&); // { dg-message "note|argument" } int test2_27() { @@ -217,13 +233,27 @@ int test2_27() const A ca = a; volatile A va; const volatile A cva = a; + sink_2_27(va); // { dg-error "lvalue" } sink_2_27(cva); // { dg-error "no match" } sink_2_27(cv_source()); // { dg-error "no match" } return 0; } +two sink_2_28(const A&); +eight sink_2_28(const volatile A&&); // { dg-error "argument" } + +int test2_28() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_2_28(va); // { dg-error "lvalue" } + sink_2_28(cva); // { dg-error "lvalue" } +} + three sink_2_35(volatile A&); // { dg-message "candidate" } -five sink_2_35( A&&); // { dg-message "note" } +five sink_2_35( A&&); // { dg-message "note|argument" } int test2_35() { @@ -240,7 +270,7 @@ int test2_35() } three sink_2_36(volatile A&); // { dg-message "candidate" } -six sink_2_36(const A&&); // { dg-message "note" } +six sink_2_36(const A&&); // { dg-message "note|argument" } int test2_36() { @@ -248,6 +278,7 @@ int test2_36() const A ca = a; volatile A va; const volatile A cva = a; + sink_2_36(ca); // { dg-error "lvalue" } sink_2_36(cva); // { dg-error "no match" } sink_2_36(v_source()); // { dg-error "no match" } sink_2_36(cv_source()); // { dg-error "no match" } @@ -255,7 +286,7 @@ int test2_36() } three sink_2_37(volatile A&); // { dg-message "candidate" } -seven sink_2_37(volatile A&&); // { dg-message "note" } +seven sink_2_37(volatile A&&); // { dg-message "note|argument" } int test2_37() { @@ -270,8 +301,21 @@ int test2_37() return 0; } +three sink_2_38(volatile A&); +eight sink_2_38(const volatile A&&); // { dg-error "argument" } + +int test2_38() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_2_38(ca); // { dg-error "lvalue" } + sink_2_38(cva); // { dg-error "lvalue" } +} + four sink_2_45(const volatile A&); // { dg-message "candidate" } -five sink_2_45( A&&); // { dg-message "note" } +five sink_2_45( A&&); // { dg-message "note|argument" } int test2_45() { @@ -286,7 +330,7 @@ int test2_45() } four sink_2_46(const volatile A&); // { dg-message "candidate" } -six sink_2_46(const A&&); // { dg-message "note" } +six sink_2_46(const A&&); // { dg-message "note|argument" } int test2_46() { @@ -300,7 +344,7 @@ int test2_46() } four sink_2_47(const volatile A&); // { dg-message "candidate" } -seven sink_2_47(volatile A&&); // { dg-message "note" } +seven sink_2_47(volatile A&&); // { dg-message "note|argument" } int test2_47() { @@ -313,8 +357,8 @@ int test2_47() return 0; } -five sink_2_56( A&&); // { dg-message "candidate" } -six sink_2_56(const A&&); // { dg-message "note" } +five sink_2_56( A&&); // { dg-message "candidate|argument" } +six sink_2_56(const A&&); // { dg-message "note|argument" } int test2_56() { @@ -322,6 +366,8 @@ int test2_56() const A ca = a; volatile A va; const volatile A cva = a; + sink_2_56(a); // { dg-error "lvalue" } + sink_2_56(ca); // { dg-error "lvalue" } sink_2_56(va); // { dg-error "no match" } sink_2_56(cva); // { dg-error "no match" } sink_2_56(v_source()); // { dg-error "no match" } @@ -329,8 +375,8 @@ int test2_56() return 0; } -five sink_2_57( A&&); // { dg-message "candidate" } -seven sink_2_57(volatile A&&); // { dg-message "note" } +five sink_2_57( A&&); // { dg-message "candidate|argument" } +seven sink_2_57(volatile A&&); // { dg-message "note|argument" } int test2_57() { @@ -338,6 +384,8 @@ int test2_57() const A ca = a; volatile A va; const volatile A cva = a; + sink_2_57(a); // { dg-error "lvalue" } + sink_2_57(va); // { dg-error "lvalue" } sink_2_57(ca); // { dg-error "no match" } sink_2_57(cva); // { dg-error "no match" } sink_2_57(c_source()); // { dg-error "no match" } @@ -345,8 +393,23 @@ int test2_57() return 0; } -six sink_2_67(const A&&); // { dg-message "candidate" } -seven sink_2_67(volatile A&&); // { dg-message "note" } +five sink_2_58( A&&); // { dg-error "argument" } +eight sink_2_58(const volatile A&&); // { dg-error "argument" } + +int test2_58() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_2_58(a); // { dg-error "lvalue" } + sink_2_58(ca); // { dg-error "lvalue" } + sink_2_58(va); // { dg-error "lvalue" } + sink_2_58(cva); // { dg-error "lvalue" } +} + +six sink_2_67(const A&&); // { dg-message "candidate|argument" } +seven sink_2_67(volatile A&&); // { dg-message "note|argument" } int test2_67() { @@ -355,12 +418,44 @@ int test2_67() volatile A va; const volatile A cva = a; sink_2_67(a); // { dg-error "ambiguous" } + sink_2_67(ca); // { dg-error "lvalue" } + sink_2_67(va); // { dg-error "lvalue" } sink_2_67(cva); // { dg-error "no match" } sink_2_67(source()); // { dg-error "ambiguous" } sink_2_67(cv_source()); // { dg-error "no match" } return 0; } +six sink_2_68(const A&&); // { dg-error "argument" } +eight sink_2_68(const volatile A&&); // { dg-error "argument" } + +int test2_68() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_2_68(a); // { dg-error "lvalue" } + sink_2_68(ca); // { dg-error "lvalue" } + sink_2_68(va); // { dg-error "lvalue" } + sink_2_68(cva); // { dg-error "lvalue" } +} + +seven sink_2_78(volatile A&&); // { dg-error "argument" } +eight sink_2_78(const volatile A&&); // { dg-error "argument" } + +int test2_78() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_2_78(a); // { dg-error "lvalue" } + sink_2_78(ca); // { dg-error "lvalue" } + sink_2_78(va); // { dg-error "lvalue" } + sink_2_78(cva); // { dg-error "lvalue" } +} + int main() { return test2_12() + test2_13() + test2_15() + test2_16() + diff --git a/gcc/testsuite/g++.dg/cpp0x/rv2p.C b/gcc/testsuite/g++.dg/cpp0x/rv2p.C index 0d12aac75e1..61c4fb046b6 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv2p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv2p.C @@ -1,6 +1,6 @@ // I, Howard Hinnant, hereby place this code in the public domain. -// Test overlaod resolution among referece types +// Test overload resolution among reference types // { dg-do compile } // { dg-options "-std=c++0x" } @@ -100,7 +100,6 @@ int test2_16() volatile A va; const volatile A cva = a; sa<sizeof(sink_2_16(a)) == 1> t1; - sa<sizeof(sink_2_16(ca)) == 6> t2; sa<sizeof(sink_2_16(source())) == 6> t5; sa<sizeof(sink_2_16(c_source())) == 6> t6; return 0; @@ -116,7 +115,6 @@ int test2_17() volatile A va; const volatile A cva = a; sa<sizeof(sink_2_17(a)) == 1> t1; - sa<sizeof(sink_2_17(va)) == 7> t3; sa<sizeof(sink_2_17(source())) == 7> t5; sa<sizeof(sink_2_17(v_source())) == 7> t7; return 0; @@ -132,9 +130,6 @@ int test2_18() volatile A va; const volatile A cva = a; sa<sizeof(sink_2_18(a)) == 1> t1; - sa<sizeof(sink_2_18(ca)) == 8> t2; - sa<sizeof(sink_2_18(va)) == 8> t3; - sa<sizeof(sink_2_18(cva)) == 8> t4; sa<sizeof(sink_2_18(source())) == 8> t5; sa<sizeof(sink_2_18(c_source())) == 8> t6; sa<sizeof(sink_2_18(v_source())) == 8> t7; @@ -221,7 +216,6 @@ int test2_27() const volatile A cva = a; sa<sizeof(sink_2_27(a)) == 2> t1; sa<sizeof(sink_2_27(ca)) == 2> t2; - sa<sizeof(sink_2_27(va)) == 7> t3; sa<sizeof(sink_2_27(source())) == 7> t5; sa<sizeof(sink_2_27(c_source())) == 2> t6; sa<sizeof(sink_2_27(v_source())) == 7> t7; @@ -239,8 +233,6 @@ int test2_28() const volatile A cva = a; sa<sizeof(sink_2_28(a)) == 2> t1; sa<sizeof(sink_2_28(ca)) == 2> t2; - sa<sizeof(sink_2_28(va)) == 8> t3; - sa<sizeof(sink_2_28(cva)) == 8> t4; sa<sizeof(sink_2_28(source())) == 8> t5; sa<sizeof(sink_2_28(c_source())) == 8> t6; sa<sizeof(sink_2_28(v_source())) == 8> t7; @@ -293,7 +285,6 @@ int test2_36() volatile A va; const volatile A cva = a; sa<sizeof(sink_2_36(a)) == 3> t1; - sa<sizeof(sink_2_36(ca)) == 6> t2; sa<sizeof(sink_2_36(va)) == 3> t3; sa<sizeof(sink_2_36(source())) == 6> t5; sa<sizeof(sink_2_36(c_source())) == 6> t6; @@ -326,9 +317,7 @@ int test2_38() volatile A va; const volatile A cva = a; sa<sizeof(sink_2_38(a)) == 3> t1; - sa<sizeof(sink_2_38(ca)) == 8> t2; sa<sizeof(sink_2_38(va)) == 3> t3; - sa<sizeof(sink_2_38(cva)) == 8> t4; sa<sizeof(sink_2_38(source())) == 8> t5; sa<sizeof(sink_2_38(c_source())) == 8> t6; sa<sizeof(sink_2_38(v_source())) == 8> t7; @@ -425,8 +414,6 @@ int test2_56() const A ca = a; volatile A va; const volatile A cva = a; - sa<sizeof(sink_2_56(a)) == 5> t1; - sa<sizeof(sink_2_56(ca)) == 6> t2; sa<sizeof(sink_2_56(source())) == 5> t5; sa<sizeof(sink_2_56(c_source())) == 6> t6; return 0; @@ -441,8 +428,6 @@ int test2_57() const A ca = a; volatile A va; const volatile A cva = a; - sa<sizeof(sink_2_57(a)) == 5> t1; - sa<sizeof(sink_2_57(va)) == 7> t3; sa<sizeof(sink_2_57(source())) == 5> t5; sa<sizeof(sink_2_57(v_source())) == 7> t7; return 0; @@ -457,10 +442,6 @@ int test2_58() const A ca = a; volatile A va; const volatile A cva = a; - sa<sizeof(sink_2_58(a)) == 5> t1; - sa<sizeof(sink_2_58(ca)) == 8> t2; - sa<sizeof(sink_2_58(va)) == 8> t3; - sa<sizeof(sink_2_58(cva)) == 8> t4; sa<sizeof(sink_2_58(source())) == 5> t5; sa<sizeof(sink_2_58(c_source())) == 8> t6; sa<sizeof(sink_2_58(v_source())) == 8> t7; @@ -477,8 +458,6 @@ int test2_67() const A ca = a; volatile A va; const volatile A cva = a; - sa<sizeof(sink_2_67(ca)) == 6> t2; - sa<sizeof(sink_2_67(va)) == 7> t3; sa<sizeof(sink_2_67(c_source())) == 6> t6; sa<sizeof(sink_2_67(v_source())) == 7> t7; return 0; @@ -493,10 +472,6 @@ int test2_68() const A ca = a; volatile A va; const volatile A cva = a; - sa<sizeof(sink_2_68(a)) == 6> t1; - sa<sizeof(sink_2_68(ca)) == 6> t2; - sa<sizeof(sink_2_68(va)) == 8> t3; - sa<sizeof(sink_2_68(cva)) == 8> t4; sa<sizeof(sink_2_68(source())) == 6> t5; sa<sizeof(sink_2_68(c_source())) == 6> t6; sa<sizeof(sink_2_68(v_source())) == 8> t7; @@ -513,10 +488,6 @@ int test2_78() const A ca = a; volatile A va; const volatile A cva = a; - sa<sizeof(sink_2_78(a)) == 7> t1; - sa<sizeof(sink_2_78(ca)) == 8> t2; - sa<sizeof(sink_2_78(va)) == 7> t3; - sa<sizeof(sink_2_78(cva)) == 8> t4; sa<sizeof(sink_2_78(source())) == 7> t5; sa<sizeof(sink_2_78(c_source())) == 8> t6; sa<sizeof(sink_2_78(v_source())) == 7> t7; diff --git a/gcc/testsuite/g++.dg/cpp0x/rv3n.C b/gcc/testsuite/g++.dg/cpp0x/rv3n.C index 84675b37fee..0c208ab6ed0 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv3n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv3n.C @@ -1,6 +1,6 @@ // I, Howard Hinnant, hereby place this code in the public domain. -// Test overlaod resolution among referece types +// Test overload resolution among reference types // { dg-do compile } // { dg-options "-std=c++0x" } @@ -97,7 +97,7 @@ int test3_126() one sink_3_127( A&); // { dg-message "candidates" } two sink_3_127(const A&); // { dg-message "note" } -seven sink_3_127(volatile A&&); // { dg-message "note" } +seven sink_3_127(volatile A&&); // { dg-message "" } int test3_127() { @@ -105,11 +105,27 @@ int test3_127() const A ca = a; volatile A va; const volatile A cva = a; + sink_3_127(va); // { dg-error "lvalue" } sink_3_127(cva); // { dg-error "no match" } sink_3_127(cv_source()); // { dg-error "no match" } return 0; } +one sink_3_128( A&); +two sink_3_128(const A&); +eight sink_3_128(const volatile A&&); // { dg-message "" } + +int test3_128() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + + sink_3_128(va); // { dg-error "lvalue" } + sink_3_128(cva); // { dg-error "lvalue" } +} + one sink_3_134( A&); // { dg-message "candidates" } three sink_3_134(volatile A&); // { dg-message "note" } four sink_3_134(const volatile A&); // { dg-message "note" } @@ -147,7 +163,7 @@ int test3_135() one sink_3_136( A&); // { dg-message "candidates" } three sink_3_136(volatile A&); // { dg-message "note" } -six sink_3_136(const A&&); // { dg-message "note" } +six sink_3_136(const A&&); // { dg-message "" } int test3_136() { @@ -155,6 +171,7 @@ int test3_136() const A ca = a; volatile A va; const volatile A cva = a; + sink_3_136(ca); // { dg-error "lvalue" } sink_3_136(cva); // { dg-error "no match" } sink_3_136(v_source()); // { dg-error "no match" } sink_3_136(cv_source()); // { dg-error "no match" } @@ -178,6 +195,21 @@ int test3_137() return 0; } +one sink_3_138( A&); +three sink_3_138(volatile A&); +eight sink_3_138(const volatile A&&); // { dg-message "" } + +int test3_138() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_3_138(ca); // { dg-error "lvalue" } + sink_3_138(cva); // { dg-error "lvalue" } + return 0; +} + one sink_3_145( A&); // { dg-message "candidates" } four sink_3_145(const volatile A&); // { dg-message "note" } five sink_3_145( A&&); // { dg-message "note" } @@ -226,7 +258,7 @@ int test3_147() one sink_3_156( A&); // { dg-message "candidates" } five sink_3_156( A&&); // { dg-message "note" } -six sink_3_156(const A&&); // { dg-message "note" } +six sink_3_156(const A&&); // { dg-message "" } int test3_156() { @@ -234,6 +266,7 @@ int test3_156() const A ca = a; volatile A va; const volatile A cva = a; + sink_3_156(ca); // { dg-error "lvalue" } sink_3_156(va); // { dg-error "no match" } sink_3_156(cva); // { dg-error "no match" } sink_3_156(v_source()); // { dg-error "no match" } @@ -243,7 +276,7 @@ int test3_156() one sink_3_157( A&); // { dg-message "candidates" } five sink_3_157( A&&); // { dg-message "note" } -seven sink_3_157(volatile A&&); // { dg-message "note" } +seven sink_3_157(volatile A&&); // { dg-message "" } int test3_157() { @@ -252,15 +285,32 @@ int test3_157() volatile A va; const volatile A cva = a; sink_3_157(ca); // { dg-error "no match" } + sink_3_157(va); // { dg-error "lvalue" } sink_3_157(cva); // { dg-error "no match" } sink_3_157(c_source()); // { dg-error "no match" } sink_3_157(cv_source()); // { dg-error "no match" } return 0; } +one sink_3_158( A&); +five sink_3_158( A&&); +eight sink_3_158(const volatile A&&); // { dg-message "" } + +int test3_158() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_3_158(ca); // { dg-error "lvalue" } + sink_3_158(va); // { dg-error "lvalue" } + sink_3_158(cva); // { dg-error "lvalue" } + return 0; +} + one sink_3_167( A&); // { dg-message "candidates" } -six sink_3_167(const A&&); // { dg-message "note" } -seven sink_3_167(volatile A&&); // { dg-message "note" } +six sink_3_167(const A&&); // { dg-message "" } +seven sink_3_167(volatile A&&); // { dg-message "" } int test3_167() { @@ -268,12 +318,46 @@ int test3_167() const A ca = a; volatile A va; const volatile A cva = a; + sink_3_167(ca); // { dg-error "lvalue" } + sink_3_167(va); // { dg-error "lvalue" } sink_3_167(cva); // { dg-error "no match" } sink_3_167(source()); // { dg-error "ambiguous" } sink_3_167(cv_source()); // { dg-error "no match" } return 0; } +one sink_3_168( A&); +six sink_3_168(const A&&); // { dg-message "" } +eight sink_3_168(const volatile A&&); // { dg-message "" } + +int test3_168() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_3_168(ca); // { dg-error "lvalue" } + sink_3_168(va); // { dg-error "lvalue" } + sink_3_168(cva); // { dg-error "lvalue" } + return 0; +} + +one sink_3_178( A&); +seven sink_3_178(volatile A&&); // { dg-message "" } +eight sink_3_178(const volatile A&&); // { dg-message "" } + +int test3_178() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_3_178(ca); // { dg-error "lvalue" } + sink_3_178(va); // { dg-error "lvalue" } + sink_3_178(cva); // { dg-error "lvalue" } + return 0; +} + two sink_3_234(const A&); // { dg-message "candidates" } three sink_3_234(volatile A&); // { dg-message "note" } four sink_3_234(const volatile A&); // { dg-message "note" } @@ -342,7 +426,7 @@ int test3_237() two sink_3_238(const A&); // { dg-message "candidates" } three sink_3_238(volatile A&); // { dg-message "note" } -eight sink_3_238(const volatile A&&); // { dg-message "note" } +eight sink_3_238(const volatile A&&); // { dg-message "" } int test3_238() { @@ -351,6 +435,7 @@ int test3_238() volatile A va; const volatile A cva = a; sink_3_238(a); // { dg-error "ambiguous" } + sink_3_238(cva); // { dg-error "lvalue" } return 0; } @@ -417,7 +502,7 @@ int test3_256() two sink_3_257(const A&); // { dg-message "candidates" } five sink_3_257( A&&); // { dg-message "note" } -seven sink_3_257(volatile A&&); // { dg-message "note" } +seven sink_3_257(volatile A&&); // { dg-message "" } int test3_257() { @@ -425,14 +510,30 @@ int test3_257() const A ca = a; volatile A va; const volatile A cva = a; + sink_3_257(va); // { dg-error "lvalue" } sink_3_257(cva); // { dg-error "no match" } sink_3_257(cv_source()); // { dg-error "no match" } return 0; } +two sink_3_258(const A&); +five sink_3_258( A&&); +eight sink_3_258(const volatile A&&); // { dg-message "" } + +int test3_258() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_3_258(va); // { dg-error "lvalue" } + sink_3_258(cva); // { dg-error "lvalue" } + return 0; +} + two sink_3_267(const A&); // { dg-message "candidates" } six sink_3_267(const A&&); // { dg-message "note" } -seven sink_3_267(volatile A&&); // { dg-message "note" } +seven sink_3_267(volatile A&&); // { dg-message "" } int test3_267() { @@ -440,12 +541,43 @@ int test3_267() const A ca = a; volatile A va; const volatile A cva = a; + sink_3_267(va); // { dg-error "lvalue" } sink_3_267(cva); // { dg-error "no match" } sink_3_267(source()); // { dg-error "ambiguous" } sink_3_267(cv_source()); // { dg-error "no match" } return 0; } +two sink_3_268(const A&); +six sink_3_268(const A&&); +eight sink_3_268(const volatile A&&); // { dg-message "" } + +int test3_268() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_3_268(va); // { dg-error "lvalue" } + sink_3_268(cva); // { dg-error "lvalue" } + return 0; +} + +two sink_3_278(const A&); +seven sink_3_278(volatile A&&); // { dg-message "" } +eight sink_3_278(const volatile A&&); // { dg-message "" } + +int test3_278() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_3_278(va); // { dg-error "lvalue" } + sink_3_278(cva); // { dg-error "lvalue" } + return 0; +} + three sink_3_345(volatile A&); // { dg-message "candidates" } four sink_3_345(const volatile A&); // { dg-message "note" } five sink_3_345( A&&); // { dg-message "note" } @@ -494,7 +626,7 @@ int test3_347() three sink_3_356(volatile A&); // { dg-message "candidates" } five sink_3_356( A&&); // { dg-message "note" } -six sink_3_356(const A&&); // { dg-message "note" } +six sink_3_356(const A&&); // { dg-message "" } int test3_356() { @@ -502,6 +634,7 @@ int test3_356() const A ca = a; volatile A va; const volatile A cva = a; + sink_3_356(ca); // { dg-error "lvalue" } sink_3_356(cva); // { dg-error "no match" } sink_3_356(v_source()); // { dg-error "no match" } sink_3_356(cv_source()); // { dg-error "no match" } @@ -525,8 +658,23 @@ int test3_357() return 0; } +three sink_3_358(volatile A&); +five sink_3_358( A&&); +eight sink_3_358(const volatile A&&); // { dg-message "" } + +int test3_358() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_3_358(ca); // { dg-error "lvalue" } + sink_3_358(cva); // { dg-error "lvalue" } + return 0; +} + three sink_3_367(volatile A&); // { dg-message "candidates" } -six sink_3_367(const A&&); // { dg-message "note" } +six sink_3_367(const A&&); // { dg-message "" } seven sink_3_367(volatile A&&); // { dg-message "note" } int test3_367() @@ -535,12 +683,43 @@ int test3_367() const A ca = a; volatile A va; const volatile A cva = a; + sink_3_367(ca); // { dg-error "lvalue" } sink_3_367(cva); // { dg-error "no match" } sink_3_367(source()); // { dg-error "ambiguous" } sink_3_367(cv_source()); // { dg-error "no match" } return 0; } +three sink_3_368(volatile A&); +six sink_3_368(const A&&); // { dg-message "" } +eight sink_3_368(const volatile A&&); // { dg-message "" } + +int test3_368() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_3_368(ca); // { dg-error "lvalue" } + sink_3_368(cva); // { dg-error "lvalue" } + return 0; +} + +three sink_3_378(volatile A&); +seven sink_3_378(volatile A&&); +eight sink_3_378(const volatile A&&); // { dg-message "" } + +int test3_378() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_3_378(ca); // { dg-error "lvalue" } + sink_3_378(cva); // { dg-error "lvalue" } + return 0; +} + four sink_3_456(const volatile A&); // { dg-message "candidates" } five sink_3_456( A&&); // { dg-message "note" } six sink_3_456(const A&&); // { dg-message "note" } @@ -586,9 +765,9 @@ int test3_467() return 0; } -five sink_3_567( A&&); // { dg-message "candidates" } -six sink_3_567(const A&&); // { dg-message "note" } -seven sink_3_567(volatile A&&); // { dg-message "note" } +five sink_3_567( A&&); // { dg-message "" } +six sink_3_567(const A&&); // { dg-message "" } +seven sink_3_567(volatile A&&); // { dg-message "" } int test3_567() { @@ -596,14 +775,51 @@ int test3_567() const A ca = a; volatile A va; const volatile A cva = a; + sink_3_567(a); // { dg-error "lvalue" } + sink_3_567(ca); // { dg-error "lvalue" } + sink_3_567(va); // { dg-error "lvalue" } sink_3_567(cva); // { dg-error "no match" } sink_3_567(cv_source()); // { dg-error "no match" } return 0; } -six sink_3_678(const A&&); // { dg-message "candidates" } -seven sink_3_678(volatile A&&); // { dg-message "note" } -eight sink_3_678(const volatile A&&); // { dg-message "note" } +five sink_3_568( A&&); // { dg-message "" } +six sink_3_568(const A&&); // { dg-message "" } +eight sink_3_568(const volatile A&&); // { dg-message "" } + +int test3_568() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_3_568(a); // { dg-error "lvalue" } + sink_3_568(ca); // { dg-error "lvalue" } + sink_3_568(va); // { dg-error "lvalue" } + sink_3_568(cva); // { dg-error "lvalue" } + return 0; +} + +five sink_3_578( A&&); // { dg-message "" } +seven sink_3_578(volatile A&&); // { dg-message "" } +eight sink_3_578(const volatile A&&); // { dg-message "" } + +int test3_578() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_3_578(a); // { dg-error "lvalue" } + sink_3_578(ca); // { dg-error "lvalue" } + sink_3_578(va); // { dg-error "lvalue" } + sink_3_578(cva); // { dg-error "lvalue" } + return 0; +} + +six sink_3_678(const A&&); // { dg-message "" } +seven sink_3_678(volatile A&&); // { dg-message "" } +eight sink_3_678(const volatile A&&); // { dg-message "" } int test3_678() { @@ -612,6 +828,9 @@ int test3_678() volatile A va; const volatile A cva = a; sink_3_678(a); // { dg-error "ambiguous" } + sink_3_678(ca); // { dg-error "lvalue" } + sink_3_678(va); // { dg-error "lvalue" } + sink_3_678(cva); // { dg-error "lvalue" } sink_3_678(source()); // { dg-error "ambiguous" } return 0; } diff --git a/gcc/testsuite/g++.dg/cpp0x/rv3p.C b/gcc/testsuite/g++.dg/cpp0x/rv3p.C index c688b11e236..5ab171f2655 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv3p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv3p.C @@ -1,6 +1,6 @@ // I, Howard Hinnant, hereby place this code in the public domain. -// Test overlaod resolution among referece types +// Test overload resolution among reference types // { dg-do compile } // { dg-options "-std=c++0x" } @@ -113,7 +113,6 @@ int test3_127() const volatile A cva = a; sa<sizeof(sink_3_127(a)) == 1> t1; sa<sizeof(sink_3_127(ca)) == 2> t2; - sa<sizeof(sink_3_127(va)) == 7> t3; sa<sizeof(sink_3_127(source())) == 7> t5; sa<sizeof(sink_3_127(c_source())) == 2> t6; sa<sizeof(sink_3_127(v_source())) == 7> t7; @@ -132,8 +131,6 @@ int test3_128() const volatile A cva = a; sa<sizeof(sink_3_128(a)) == 1> t1; sa<sizeof(sink_3_128(ca)) == 2> t2; - sa<sizeof(sink_3_128(va)) == 8> t3; - sa<sizeof(sink_3_128(cva)) == 8> t4; sa<sizeof(sink_3_128(source())) == 8> t5; sa<sizeof(sink_3_128(c_source())) == 8> t6; sa<sizeof(sink_3_128(v_source())) == 8> t7; @@ -185,7 +182,6 @@ int test3_136() volatile A va; const volatile A cva = a; sa<sizeof(sink_3_136(a)) == 1> t1; - sa<sizeof(sink_3_136(ca)) == 6> t2; sa<sizeof(sink_3_136(va)) == 3> t3; sa<sizeof(sink_3_136(source())) == 6> t5; sa<sizeof(sink_3_136(c_source())) == 6> t6; @@ -220,9 +216,7 @@ int test3_138() volatile A va; const volatile A cva = a; sa<sizeof(sink_3_138(a)) == 1> t1; - sa<sizeof(sink_3_138(ca)) == 8> t2; sa<sizeof(sink_3_138(va)) == 3> t3; - sa<sizeof(sink_3_138(cva)) == 8> t4; sa<sizeof(sink_3_138(source())) == 8> t5; sa<sizeof(sink_3_138(c_source())) == 8> t6; sa<sizeof(sink_3_138(v_source())) == 8> t7; @@ -318,7 +312,6 @@ int test3_156() volatile A va; const volatile A cva = a; sa<sizeof(sink_3_156(a)) == 1> t1; - sa<sizeof(sink_3_156(ca)) == 6> t2; sa<sizeof(sink_3_156(source())) == 5> t5; sa<sizeof(sink_3_156(c_source())) == 6> t6; return 0; @@ -335,7 +328,6 @@ int test3_157() volatile A va; const volatile A cva = a; sa<sizeof(sink_3_157(a)) == 1> t1; - sa<sizeof(sink_3_157(va)) == 7> t3; sa<sizeof(sink_3_157(source())) == 5> t5; sa<sizeof(sink_3_157(v_source())) == 7> t7; return 0; @@ -352,9 +344,6 @@ int test3_158() volatile A va; const volatile A cva = a; sa<sizeof(sink_3_158(a)) == 1> t1; - sa<sizeof(sink_3_158(ca)) == 8> t2; - sa<sizeof(sink_3_158(va)) == 8> t3; - sa<sizeof(sink_3_158(cva)) == 8> t4; sa<sizeof(sink_3_158(source())) == 5> t5; sa<sizeof(sink_3_158(c_source())) == 8> t6; sa<sizeof(sink_3_158(v_source())) == 8> t7; @@ -373,8 +362,6 @@ int test3_167() volatile A va; const volatile A cva = a; sa<sizeof(sink_3_167(a)) == 1> t1; - sa<sizeof(sink_3_167(ca)) == 6> t2; - sa<sizeof(sink_3_167(va)) == 7> t3; sa<sizeof(sink_3_167(c_source())) == 6> t6; sa<sizeof(sink_3_167(v_source())) == 7> t7; return 0; @@ -391,9 +378,6 @@ int test3_168() volatile A va; const volatile A cva = a; sa<sizeof(sink_3_168(a)) == 1> t1; - sa<sizeof(sink_3_168(ca)) == 6> t2; - sa<sizeof(sink_3_168(va)) == 8> t3; - sa<sizeof(sink_3_168(cva)) == 8> t4; sa<sizeof(sink_3_168(source())) == 6> t5; sa<sizeof(sink_3_168(c_source())) == 6> t6; sa<sizeof(sink_3_168(v_source())) == 8> t7; @@ -412,9 +396,6 @@ int test3_178() volatile A va; const volatile A cva = a; sa<sizeof(sink_3_178(a)) == 1> t1; - sa<sizeof(sink_3_178(ca)) == 8> t2; - sa<sizeof(sink_3_178(va)) == 7> t3; - sa<sizeof(sink_3_178(cva)) == 8> t4; sa<sizeof(sink_3_178(source())) == 7> t5; sa<sizeof(sink_3_178(c_source())) == 8> t6; sa<sizeof(sink_3_178(v_source())) == 7> t7; @@ -504,7 +485,6 @@ int test3_238() const volatile A cva = a; sa<sizeof(sink_3_238(ca)) == 2> t2; sa<sizeof(sink_3_238(va)) == 3> t3; - sa<sizeof(sink_3_238(cva)) == 8> t4; sa<sizeof(sink_3_238(source())) == 8> t5; sa<sizeof(sink_3_238(c_source())) == 8> t6; sa<sizeof(sink_3_238(v_source())) == 8> t7; @@ -620,7 +600,6 @@ int test3_257() const volatile A cva = a; sa<sizeof(sink_3_257(a)) == 2> t1; sa<sizeof(sink_3_257(ca)) == 2> t2; - sa<sizeof(sink_3_257(va)) == 7> t3; sa<sizeof(sink_3_257(source())) == 5> t5; sa<sizeof(sink_3_257(c_source())) == 2> t6; sa<sizeof(sink_3_257(v_source())) == 7> t7; @@ -639,8 +618,6 @@ int test3_258() const volatile A cva = a; sa<sizeof(sink_3_258(a)) == 2> t1; sa<sizeof(sink_3_258(ca)) == 2> t2; - sa<sizeof(sink_3_258(va)) == 8> t3; - sa<sizeof(sink_3_258(cva)) == 8> t4; sa<sizeof(sink_3_258(source())) == 5> t5; sa<sizeof(sink_3_258(c_source())) == 8> t6; sa<sizeof(sink_3_258(v_source())) == 8> t7; @@ -660,7 +637,6 @@ int test3_267() const volatile A cva = a; sa<sizeof(sink_3_267(a)) == 2> t1; sa<sizeof(sink_3_267(ca)) == 2> t2; - sa<sizeof(sink_3_267(va)) == 7> t3; sa<sizeof(sink_3_267(c_source())) == 6> t6; sa<sizeof(sink_3_267(v_source())) == 7> t7; return 0; @@ -678,8 +654,6 @@ int test3_268() const volatile A cva = a; sa<sizeof(sink_3_268(a)) == 2> t1; sa<sizeof(sink_3_268(ca)) == 2> t2; - sa<sizeof(sink_3_268(va)) == 8> t3; - sa<sizeof(sink_3_268(cva)) == 8> t4; sa<sizeof(sink_3_268(source())) == 6> t5; sa<sizeof(sink_3_268(c_source())) == 6> t6; sa<sizeof(sink_3_268(v_source())) == 8> t7; @@ -699,8 +673,6 @@ int test3_278() const volatile A cva = a; sa<sizeof(sink_3_278(a)) == 2> t1; sa<sizeof(sink_3_278(ca)) == 2> t2; - sa<sizeof(sink_3_278(va)) == 7> t3; - sa<sizeof(sink_3_278(cva)) == 8> t4; sa<sizeof(sink_3_278(source())) == 7> t5; sa<sizeof(sink_3_278(c_source())) == 8> t6; sa<sizeof(sink_3_278(v_source())) == 7> t7; @@ -796,7 +768,6 @@ int test3_356() volatile A va; const volatile A cva = a; sa<sizeof(sink_3_356(a)) == 3> t1; - sa<sizeof(sink_3_356(ca)) == 6> t2; sa<sizeof(sink_3_356(va)) == 3> t3; sa<sizeof(sink_3_356(source())) == 5> t5; sa<sizeof(sink_3_356(c_source())) == 6> t6; @@ -831,9 +802,7 @@ int test3_358() volatile A va; const volatile A cva = a; sa<sizeof(sink_3_358(a)) == 3> t1; - sa<sizeof(sink_3_358(ca)) == 8> t2; sa<sizeof(sink_3_358(va)) == 3> t3; - sa<sizeof(sink_3_358(cva)) == 8> t4; sa<sizeof(sink_3_358(source())) == 5> t5; sa<sizeof(sink_3_358(c_source())) == 8> t6; sa<sizeof(sink_3_358(v_source())) == 8> t7; @@ -852,7 +821,6 @@ int test3_367() volatile A va; const volatile A cva = a; sa<sizeof(sink_3_367(a)) == 3> t1; - sa<sizeof(sink_3_367(ca)) == 6> t2; sa<sizeof(sink_3_367(va)) == 3> t3; sa<sizeof(sink_3_367(c_source())) == 6> t6; sa<sizeof(sink_3_367(v_source())) == 7> t7; @@ -870,9 +838,7 @@ int test3_368() volatile A va; const volatile A cva = a; sa<sizeof(sink_3_368(a)) == 3> t1; - sa<sizeof(sink_3_368(ca)) == 6> t2; sa<sizeof(sink_3_368(va)) == 3> t3; - sa<sizeof(sink_3_368(cva)) == 8> t4; sa<sizeof(sink_3_368(source())) == 6> t5; sa<sizeof(sink_3_368(c_source())) == 6> t6; sa<sizeof(sink_3_368(v_source())) == 8> t7; @@ -891,9 +857,7 @@ int test3_378() volatile A va; const volatile A cva = a; sa<sizeof(sink_3_378(a)) == 3> t1; - sa<sizeof(sink_3_378(ca)) == 8> t2; sa<sizeof(sink_3_378(va)) == 3> t3; - sa<sizeof(sink_3_378(cva)) == 8> t4; sa<sizeof(sink_3_378(source())) == 7> t5; sa<sizeof(sink_3_378(c_source())) == 8> t6; sa<sizeof(sink_3_378(v_source())) == 7> t7; @@ -1031,9 +995,6 @@ int test3_567() const A ca = a; volatile A va; const volatile A cva = a; - sa<sizeof(sink_3_567(a)) == 5> t1; - sa<sizeof(sink_3_567(ca)) == 6> t2; - sa<sizeof(sink_3_567(va)) == 7> t3; sa<sizeof(sink_3_567(source())) == 5> t5; sa<sizeof(sink_3_567(c_source())) == 6> t6; sa<sizeof(sink_3_567(v_source())) == 7> t7; @@ -1050,10 +1011,6 @@ int test3_568() const A ca = a; volatile A va; const volatile A cva = a; - sa<sizeof(sink_3_568(a)) == 5> t1; - sa<sizeof(sink_3_568(ca)) == 6> t2; - sa<sizeof(sink_3_568(va)) == 8> t3; - sa<sizeof(sink_3_568(cva)) == 8> t4; sa<sizeof(sink_3_568(source())) == 5> t5; sa<sizeof(sink_3_568(c_source())) == 6> t6; sa<sizeof(sink_3_568(v_source())) == 8> t7; @@ -1071,10 +1028,6 @@ int test3_578() const A ca = a; volatile A va; const volatile A cva = a; - sa<sizeof(sink_3_578(a)) == 5> t1; - sa<sizeof(sink_3_578(ca)) == 8> t2; - sa<sizeof(sink_3_578(va)) == 7> t3; - sa<sizeof(sink_3_578(cva)) == 8> t4; sa<sizeof(sink_3_578(source())) == 5> t5; sa<sizeof(sink_3_578(c_source())) == 8> t6; sa<sizeof(sink_3_578(v_source())) == 7> t7; @@ -1092,9 +1045,6 @@ int test3_678() const A ca = a; volatile A va; const volatile A cva = a; - sa<sizeof(sink_3_678(ca)) == 6> t2; - sa<sizeof(sink_3_678(va)) == 7> t3; - sa<sizeof(sink_3_678(cva)) == 8> t4; sa<sizeof(sink_3_678(c_source())) == 6> t6; sa<sizeof(sink_3_678(v_source())) == 7> t7; sa<sizeof(sink_3_678(cv_source())) == 8> t8; diff --git a/gcc/testsuite/g++.dg/cpp0x/rv4n.C b/gcc/testsuite/g++.dg/cpp0x/rv4n.C index b88e3f77061..cf627aed3f0 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv4n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv4n.C @@ -1,6 +1,6 @@ // I, Howard Hinnant, hereby place this code in the public domain. -// Test overlaod resolution among referece types +// Test overload resolution among reference types // { dg-do compile } // { dg-options "-std=c++0x" } @@ -96,6 +96,21 @@ int test4_1237() return 0; } +one sink_4_1238( A&); +two sink_4_1238(const A&); +three sink_4_1238(volatile A&); +eight sink_4_1238(const volatile A&&); // { dg-message "" } + +int test4_1238() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_4_1238(cva); // { dg-error "lvalue" } + return 0; +} + one sink_4_1245( A&); // { dg-message "candidates" } two sink_4_1245(const A&); // { dg-message "note" } four sink_4_1245(const volatile A&); // { dg-message "note" } @@ -164,7 +179,7 @@ int test4_1256() one sink_4_1257( A&); // { dg-message "candidates" } two sink_4_1257(const A&); // { dg-message "note" } five sink_4_1257( A&&); // { dg-message "note" } -seven sink_4_1257(volatile A&&); // { dg-message "note" } +seven sink_4_1257(volatile A&&); // { dg-message "" } int test4_1257() { @@ -172,15 +187,32 @@ int test4_1257() const A ca = a; volatile A va; const volatile A cva = a; + sink_4_1257(va); // { dg-error "lvalue" } sink_4_1257(cva); // { dg-error "no match" } sink_4_1257(cv_source()); // { dg-error "no match" } return 0; } +one sink_4_1258( A&); +two sink_4_1258(const A&); +five sink_4_1258( A&&); +eight sink_4_1258(const volatile A&&); // { dg-message "" } + +int test4_1258() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_4_1258(va); // { dg-error "lvalue" } + sink_4_1258(cva); // { dg-error "lvalue" } + return 0; +} + one sink_4_1267( A&); // { dg-message "candidates" } two sink_4_1267(const A&); // { dg-message "note" } six sink_4_1267(const A&&); // { dg-message "note" } -seven sink_4_1267(volatile A&&); // { dg-message "note" } +seven sink_4_1267(volatile A&&); // { dg-message "" } int test4_1267() { @@ -188,12 +220,45 @@ int test4_1267() const A ca = a; volatile A va; const volatile A cva = a; + sink_4_1267(va); // { dg-error "lvalue" } sink_4_1267(cva); // { dg-error "no match" } sink_4_1267(source()); // { dg-error "ambiguous" } sink_4_1267(cv_source()); // { dg-error "no match" } return 0; } +one sink_4_1268( A&); +two sink_4_1268(const A&); +six sink_4_1268(const A&&); +eight sink_4_1268(const volatile A&&); // { dg-message "" } + +int test4_1268() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_4_1268(va); // { dg-error "lvalue" } + sink_4_1268(cva); // { dg-error "lvalue" } + return 0; +} + +one sink_4_1278( A&); +two sink_4_1278(const A&); +seven sink_4_1278(volatile A&&); // { dg-message "" } +eight sink_4_1278(const volatile A&&); // { dg-message "" } + +int test4_1278() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_4_1278(va); // { dg-error "lvalue" } + sink_4_1278(cva); // { dg-error "lvalue" } + return 0; +} + one sink_4_1345( A&); // { dg-message "candidates" } three sink_4_1345(volatile A&); // { dg-message "note" } four sink_4_1345(const volatile A&); // { dg-message "note" } @@ -246,7 +311,7 @@ int test4_1347() one sink_4_1356( A&); // { dg-message "candidates" } three sink_4_1356(volatile A&); // { dg-message "note" } five sink_4_1356( A&&); // { dg-message "note" } -six sink_4_1356(const A&&); // { dg-message "note" } +six sink_4_1356(const A&&); // { dg-message "" } int test4_1356() { @@ -254,6 +319,7 @@ int test4_1356() const A ca = a; volatile A va; const volatile A cva = a; + sink_4_1356(ca); // { dg-error "lvalue" } sink_4_1356(cva); // { dg-error "no match" } sink_4_1356(v_source()); // { dg-error "no match" } sink_4_1356(cv_source()); // { dg-error "no match" } @@ -278,9 +344,25 @@ int test4_1357() return 0; } +one sink_4_1358( A&); +three sink_4_1358(volatile A&); +five sink_4_1358( A&&); +eight sink_4_1358(const volatile A&&); // { dg-message "" } + +int test4_1358() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_4_1358(ca); // { dg-error "lvalue" } + sink_4_1358(cva); // { dg-error "lvalue" } + return 0; +} + one sink_4_1367( A&); // { dg-message "candidates" } three sink_4_1367(volatile A&); // { dg-message "note" } -six sink_4_1367(const A&&); // { dg-message "note" } +six sink_4_1367(const A&&); // { dg-message "" } seven sink_4_1367(volatile A&&); // { dg-message "note" } int test4_1367() @@ -289,12 +371,45 @@ int test4_1367() const A ca = a; volatile A va; const volatile A cva = a; + sink_4_1367(ca); // { dg-error "lvalue" } sink_4_1367(cva); // { dg-error "no match" } sink_4_1367(source()); // { dg-error "ambiguous" } sink_4_1367(cv_source()); // { dg-error "no match" } return 0; } +one sink_4_1368( A&); +three sink_4_1368(volatile A&); +six sink_4_1368(const A&&); // { dg-message "" } +eight sink_4_1368(const volatile A&&); // { dg-message "" } + +int test4_1368() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_4_1368(ca); // { dg-error "lvalue" } + sink_4_1368(cva); // { dg-error "lvalue" } + return 0; +} + +one sink_4_1378( A&); +three sink_4_1378(volatile A&); +seven sink_4_1378(volatile A&&); +eight sink_4_1378(const volatile A&&); // { dg-message "" } + +int test4_1378() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_4_1378(ca); // { dg-error "lvalue" } + sink_4_1378(cva); // { dg-error "lvalue" } + return 0; +} + one sink_4_1456( A&); // { dg-message "candidates" } four sink_4_1456(const volatile A&); // { dg-message "note" } five sink_4_1456( A&&); // { dg-message "note" } @@ -345,8 +460,8 @@ int test4_1467() one sink_4_1567( A&); // { dg-message "candidates" } five sink_4_1567( A&&); // { dg-message "note" } -six sink_4_1567(const A&&); // { dg-message "note" } -seven sink_4_1567(volatile A&&); // { dg-message "note" } +six sink_4_1567(const A&&); // { dg-message "" } +seven sink_4_1567(volatile A&&); // { dg-message "" } int test4_1567() { @@ -354,15 +469,51 @@ int test4_1567() const A ca = a; volatile A va; const volatile A cva = a; + sink_4_1567(ca); // { dg-error "lvalue" } + sink_4_1567(va); // { dg-error "lvalue" } sink_4_1567(cva); // { dg-error "no match" } sink_4_1567(cv_source()); // { dg-error "no match" } return 0; } +one sink_4_1568( A&); +five sink_4_1568( A&&); +six sink_4_1568(const A&&); // { dg-message "" } +eight sink_4_1568(const volatile A&&); // { dg-message "" } + +int test4_1568() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_4_1568(ca); // { dg-error "lvalue" } + sink_4_1568(va); // { dg-error "lvalue" } + sink_4_1568(cva); // { dg-error "lvalue" } + return 0; +} + +one sink_4_1578( A&); +five sink_4_1578( A&&); +seven sink_4_1578(volatile A&&); // { dg-message "" } +eight sink_4_1578(const volatile A&&); // { dg-message "" } + +int test4_1578() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_4_1578(ca); // { dg-error "lvalue" } + sink_4_1578(va); // { dg-error "lvalue" } + sink_4_1578(cva); // { dg-error "lvalue" } + return 0; +} + one sink_4_1678( A&); -six sink_4_1678(const A&&); // { dg-message "candidates" } -seven sink_4_1678(volatile A&&); // { dg-message "note" } -eight sink_4_1678(const volatile A&&); // { dg-message "note" } +six sink_4_1678(const A&&); // { dg-message "" } +seven sink_4_1678(volatile A&&); // { dg-message "" } +eight sink_4_1678(const volatile A&&); // { dg-message "" } int test4_1678() { @@ -370,6 +521,9 @@ int test4_1678() const A ca = a; volatile A va; const volatile A cva = a; + sink_4_1678(ca); // { dg-error "lvalue" } + sink_4_1678(va); // { dg-error "lvalue" } + sink_4_1678(cva); // { dg-error "lvalue" } sink_4_1678(source()); // { dg-error "ambiguous" } return 0; } @@ -477,7 +631,7 @@ int test4_2357() two sink_4_2358(const A&); // { dg-message "candidates" } three sink_4_2358(volatile A&); // { dg-message "note" } five sink_4_2358( A&&); // { dg-message "note" } -eight sink_4_2358(const volatile A&&); // { dg-message "note" } +eight sink_4_2358(const volatile A&&); // { dg-message "" } int test4_2358() { @@ -486,6 +640,7 @@ int test4_2358() volatile A va; const volatile A cva = a; sink_4_2358(a); // { dg-error "ambiguous" } + sink_4_2358(cva); // { dg-error "lvalue" } return 0; } @@ -510,7 +665,7 @@ int test4_2367() two sink_4_2368(const A&); // { dg-message "candidates" } three sink_4_2368(volatile A&); // { dg-message "note" } six sink_4_2368(const A&&); // { dg-message "note" } -eight sink_4_2368(const volatile A&&); // { dg-message "note" } +eight sink_4_2368(const volatile A&&); // { dg-message "" } int test4_2368() { @@ -519,13 +674,14 @@ int test4_2368() volatile A va; const volatile A cva = a; sink_4_2368(a); // { dg-error "ambiguous" } + sink_4_2368(cva); // { dg-error "lvalue" } return 0; } two sink_4_2378(const A&); // { dg-message "candidates" } three sink_4_2378(volatile A&); // { dg-message "note" } seven sink_4_2378(volatile A&&); // { dg-message "note" } -eight sink_4_2378(const volatile A&&); // { dg-message "note" } +eight sink_4_2378(const volatile A&&); // { dg-message "" } int test4_2378() { @@ -534,6 +690,7 @@ int test4_2378() volatile A va; const volatile A cva = a; sink_4_2378(a); // { dg-error "ambiguous" } + sink_4_2378(cva); // { dg-error "lvalue" } return 0; } @@ -587,7 +744,7 @@ int test4_2467() two sink_4_2567(const A&); // { dg-message "candidates" } five sink_4_2567( A&&); // { dg-message "note" } six sink_4_2567(const A&&); // { dg-message "note" } -seven sink_4_2567(volatile A&&); // { dg-message "note" } +seven sink_4_2567(volatile A&&); // { dg-message "" } int test4_2567() { @@ -595,15 +752,48 @@ int test4_2567() const A ca = a; volatile A va; const volatile A cva = a; + sink_4_2567(va); // { dg-error "lvalue" } sink_4_2567(cva); // { dg-error "no match" } sink_4_2567(cv_source()); // { dg-error "no match" } return 0; } +two sink_4_2568(const A&); +five sink_4_2568( A&&); +six sink_4_2568(const A&&); +eight sink_4_2568(const volatile A&&); // { dg-message "" } + +int test4_2568() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_4_2568(va); // { dg-error "lvalue" } + sink_4_2568(cva); // { dg-error "lvalue" } + return 0; +} + +two sink_4_2578(const A&); +five sink_4_2578( A&&); +seven sink_4_2578(volatile A&&); // { dg-message "" } +eight sink_4_2578(const volatile A&&); // { dg-message "" } + +int test4_2578() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_4_2578(va); // { dg-error "lvalue" } + sink_4_2578(cva); // { dg-error "lvalue" } + return 0; +} + two sink_4_2678(const A&); // { dg-message "candidates" } six sink_4_2678(const A&&); // { dg-message "note" } -seven sink_4_2678(volatile A&&); // { dg-message "note" } -eight sink_4_2678(const volatile A&&); // { dg-message "note" } +seven sink_4_2678(volatile A&&); // { dg-message "" } +eight sink_4_2678(const volatile A&&); // { dg-message "" } int test4_2678() { @@ -611,6 +801,8 @@ int test4_2678() const A ca = a; volatile A va; const volatile A cva = a; + sink_4_2678(va); // { dg-error "lvalue" } + sink_4_2678(cva); // { dg-error "lvalue" } sink_4_2678(source()); // { dg-error "ambiguous" } return 0; } @@ -665,7 +857,7 @@ int test4_3467() three sink_4_3567(volatile A&); // { dg-message "candidates" } five sink_4_3567( A&&); // { dg-message "note" } -six sink_4_3567(const A&&); // { dg-message "note" } +six sink_4_3567(const A&&); // { dg-message "" } seven sink_4_3567(volatile A&&); // { dg-message "note" } int test4_3567() @@ -674,15 +866,48 @@ int test4_3567() const A ca = a; volatile A va; const volatile A cva = a; + sink_4_3567(ca); // { dg-error "lvalue" } sink_4_3567(cva); // { dg-error "no match" } sink_4_3567(cv_source()); // { dg-error "no match" } return 0; } +three sink_4_3568(volatile A&); +five sink_4_3568( A&&); +six sink_4_3568(const A&&); // { dg-message "" } +eight sink_4_3568(const volatile A&&); // { dg-message "" } + +int test4_3568() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_4_3568(ca); // { dg-error "lvalue" } + sink_4_3568(cva); // { dg-error "lvalue" } + return 0; +} + +three sink_4_3578(volatile A&); +five sink_4_3578( A&&); +seven sink_4_3578(volatile A&&); +eight sink_4_3578(const volatile A&&); // { dg-message "" } + +int test4_3578() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_4_3578(ca); // { dg-error "lvalue" } + sink_4_3578(cva); // { dg-error "lvalue" } + return 0; +} + three sink_4_3678(volatile A&); -six sink_4_3678(const A&&); // { dg-message "candidates" } +six sink_4_3678(const A&&); // { dg-message "" } seven sink_4_3678(volatile A&&); // { dg-message "note" } -eight sink_4_3678(const volatile A&&); // { dg-message "note" } +eight sink_4_3678(const volatile A&&); // { dg-message "" } int test4_3678() { @@ -690,6 +915,8 @@ int test4_3678() const A ca = a; volatile A va; const volatile A cva = a; + sink_4_3678(ca); // { dg-error "lvalue" } + sink_4_3678(cva); // { dg-error "lvalue" } sink_4_3678(source()); // { dg-error "ambiguous" } return 0; } @@ -724,6 +951,24 @@ int test4_4678() return 0; } +five sink_4_5678( A&&); // { dg-message "" } +six sink_4_5678(const A&&); // { dg-message "" } +seven sink_4_5678(volatile A&&); // { dg-message "" } +eight sink_4_5678(const volatile A&&); // { dg-message "" } + +int test4_5678() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_4_5678(a); // { dg-error "lvalue" } + sink_4_5678(ca); // { dg-error "lvalue" } + sink_4_5678(va); // { dg-error "lvalue" } + sink_4_5678(cva); // { dg-error "lvalue" } + return 0; +} + int main() { return test4_1235() + test4_1236() + test4_1237() + test4_1256() + test4_1257() + diff --git a/gcc/testsuite/g++.dg/cpp0x/rv4p.C b/gcc/testsuite/g++.dg/cpp0x/rv4p.C index a486e75e2e3..03ad9734614 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv4p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv4p.C @@ -1,6 +1,6 @@ // I, Howard Hinnant, hereby place this code in the public domain. -// Test overlaod resolution among referece types +// Test overload resolution among reference types // { dg-do compile } // { dg-options "-std=c++0x" } @@ -122,7 +122,6 @@ int test4_1238() sa<sizeof(sink_4_1238(a)) == 1> t1; sa<sizeof(sink_4_1238(ca)) == 2> t2; sa<sizeof(sink_4_1238(va)) == 3> t3; - sa<sizeof(sink_4_1238(cva)) == 8> t4; sa<sizeof(sink_4_1238(source())) == 8> t5; sa<sizeof(sink_4_1238(c_source())) == 8> t6; sa<sizeof(sink_4_1238(v_source())) == 8> t7; @@ -244,7 +243,6 @@ int test4_1257() const volatile A cva = a; sa<sizeof(sink_4_1257(a)) == 1> t1; sa<sizeof(sink_4_1257(ca)) == 2> t2; - sa<sizeof(sink_4_1257(va)) == 7> t3; sa<sizeof(sink_4_1257(source())) == 5> t5; sa<sizeof(sink_4_1257(c_source())) == 2> t6; sa<sizeof(sink_4_1257(v_source())) == 7> t7; @@ -264,8 +262,6 @@ int test4_1258() const volatile A cva = a; sa<sizeof(sink_4_1258(a)) == 1> t1; sa<sizeof(sink_4_1258(ca)) == 2> t2; - sa<sizeof(sink_4_1258(va)) == 8> t3; - sa<sizeof(sink_4_1258(cva)) == 8> t4; sa<sizeof(sink_4_1258(source())) == 5> t5; sa<sizeof(sink_4_1258(c_source())) == 8> t6; sa<sizeof(sink_4_1258(v_source())) == 8> t7; @@ -286,7 +282,6 @@ int test4_1267() const volatile A cva = a; sa<sizeof(sink_4_1267(a)) == 1> t1; sa<sizeof(sink_4_1267(ca)) == 2> t2; - sa<sizeof(sink_4_1267(va)) == 7> t3; sa<sizeof(sink_4_1267(c_source())) == 6> t6; sa<sizeof(sink_4_1267(v_source())) == 7> t7; return 0; @@ -305,8 +300,6 @@ int test4_1268() const volatile A cva = a; sa<sizeof(sink_4_1268(a)) == 1> t1; sa<sizeof(sink_4_1268(ca)) == 2> t2; - sa<sizeof(sink_4_1268(va)) == 8> t3; - sa<sizeof(sink_4_1268(cva)) == 8> t4; sa<sizeof(sink_4_1268(source())) == 6> t5; sa<sizeof(sink_4_1268(c_source())) == 6> t6; sa<sizeof(sink_4_1268(v_source())) == 8> t7; @@ -327,8 +320,6 @@ int test4_1278() const volatile A cva = a; sa<sizeof(sink_4_1278(a)) == 1> t1; sa<sizeof(sink_4_1278(ca)) == 2> t2; - sa<sizeof(sink_4_1278(va)) == 7> t3; - sa<sizeof(sink_4_1278(cva)) == 8> t4; sa<sizeof(sink_4_1278(source())) == 7> t5; sa<sizeof(sink_4_1278(c_source())) == 8> t6; sa<sizeof(sink_4_1278(v_source())) == 7> t7; @@ -429,7 +420,6 @@ int test4_1356() volatile A va; const volatile A cva = a; sa<sizeof(sink_4_1356(a)) == 1> t1; - sa<sizeof(sink_4_1356(ca)) == 6> t2; sa<sizeof(sink_4_1356(va)) == 3> t3; sa<sizeof(sink_4_1356(source())) == 5> t5; sa<sizeof(sink_4_1356(c_source())) == 6> t6; @@ -466,9 +456,7 @@ int test4_1358() volatile A va; const volatile A cva = a; sa<sizeof(sink_4_1358(a)) == 1> t1; - sa<sizeof(sink_4_1358(ca)) == 8> t2; sa<sizeof(sink_4_1358(va)) == 3> t3; - sa<sizeof(sink_4_1358(cva)) == 8> t4; sa<sizeof(sink_4_1358(source())) == 5> t5; sa<sizeof(sink_4_1358(c_source())) == 8> t6; sa<sizeof(sink_4_1358(v_source())) == 8> t7; @@ -488,7 +476,6 @@ int test4_1367() volatile A va; const volatile A cva = a; sa<sizeof(sink_4_1367(a)) == 1> t1; - sa<sizeof(sink_4_1367(ca)) == 6> t2; sa<sizeof(sink_4_1367(va)) == 3> t3; sa<sizeof(sink_4_1367(c_source())) == 6> t6; sa<sizeof(sink_4_1367(v_source())) == 7> t7; @@ -507,9 +494,7 @@ int test4_1368() volatile A va; const volatile A cva = a; sa<sizeof(sink_4_1368(a)) == 1> t1; - sa<sizeof(sink_4_1368(ca)) == 6> t2; sa<sizeof(sink_4_1368(va)) == 3> t3; - sa<sizeof(sink_4_1368(cva)) == 8> t4; sa<sizeof(sink_4_1368(source())) == 6> t5; sa<sizeof(sink_4_1368(c_source())) == 6> t6; sa<sizeof(sink_4_1368(v_source())) == 8> t7; @@ -529,9 +514,7 @@ int test4_1378() volatile A va; const volatile A cva = a; sa<sizeof(sink_4_1378(a)) == 1> t1; - sa<sizeof(sink_4_1378(ca)) == 8> t2; sa<sizeof(sink_4_1378(va)) == 3> t3; - sa<sizeof(sink_4_1378(cva)) == 8> t4; sa<sizeof(sink_4_1378(source())) == 7> t5; sa<sizeof(sink_4_1378(c_source())) == 8> t6; sa<sizeof(sink_4_1378(v_source())) == 7> t7; @@ -677,8 +660,6 @@ int test4_1567() volatile A va; const volatile A cva = a; sa<sizeof(sink_4_1567(a)) == 1> t1; - sa<sizeof(sink_4_1567(ca)) == 6> t2; - sa<sizeof(sink_4_1567(va)) == 7> t3; sa<sizeof(sink_4_1567(source())) == 5> t5; sa<sizeof(sink_4_1567(c_source())) == 6> t6; sa<sizeof(sink_4_1567(v_source())) == 7> t7; @@ -697,9 +678,6 @@ int test4_1568() volatile A va; const volatile A cva = a; sa<sizeof(sink_4_1568(a)) == 1> t1; - sa<sizeof(sink_4_1568(ca)) == 6> t2; - sa<sizeof(sink_4_1568(va)) == 8> t3; - sa<sizeof(sink_4_1568(cva)) == 8> t4; sa<sizeof(sink_4_1568(source())) == 5> t5; sa<sizeof(sink_4_1568(c_source())) == 6> t6; sa<sizeof(sink_4_1568(v_source())) == 8> t7; @@ -719,9 +697,6 @@ int test4_1578() volatile A va; const volatile A cva = a; sa<sizeof(sink_4_1578(a)) == 1> t1; - sa<sizeof(sink_4_1578(ca)) == 8> t2; - sa<sizeof(sink_4_1578(va)) == 7> t3; - sa<sizeof(sink_4_1578(cva)) == 8> t4; sa<sizeof(sink_4_1578(source())) == 5> t5; sa<sizeof(sink_4_1578(c_source())) == 8> t6; sa<sizeof(sink_4_1578(v_source())) == 7> t7; @@ -741,9 +716,6 @@ int test4_1678() volatile A va; const volatile A cva = a; sa<sizeof(sink_4_1678(a)) == 1> t1; - sa<sizeof(sink_4_1678(ca)) == 6> t2; - sa<sizeof(sink_4_1678(va)) == 7> t3; - sa<sizeof(sink_4_1678(cva)) == 8> t4; sa<sizeof(sink_4_1678(c_source())) == 6> t6; sa<sizeof(sink_4_1678(v_source())) == 7> t7; sa<sizeof(sink_4_1678(cv_source())) == 8> t8; @@ -879,7 +851,6 @@ int test4_2358() const volatile A cva = a; sa<sizeof(sink_4_2358(ca)) == 2> t2; sa<sizeof(sink_4_2358(va)) == 3> t3; - sa<sizeof(sink_4_2358(cva)) == 8> t4; sa<sizeof(sink_4_2358(source())) == 5> t5; sa<sizeof(sink_4_2358(c_source())) == 8> t6; sa<sizeof(sink_4_2358(v_source())) == 8> t7; @@ -918,7 +889,6 @@ int test4_2368() const volatile A cva = a; sa<sizeof(sink_4_2368(ca)) == 2> t2; sa<sizeof(sink_4_2368(va)) == 3> t3; - sa<sizeof(sink_4_2368(cva)) == 8> t4; sa<sizeof(sink_4_2368(source())) == 6> t5; sa<sizeof(sink_4_2368(c_source())) == 6> t6; sa<sizeof(sink_4_2368(v_source())) == 8> t7; @@ -939,7 +909,6 @@ int test4_2378() const volatile A cva = a; sa<sizeof(sink_4_2378(ca)) == 2> t2; sa<sizeof(sink_4_2378(va)) == 3> t3; - sa<sizeof(sink_4_2378(cva)) == 8> t4; sa<sizeof(sink_4_2378(source())) == 7> t5; sa<sizeof(sink_4_2378(c_source())) == 8> t6; sa<sizeof(sink_4_2378(v_source())) == 7> t7; @@ -1087,7 +1056,6 @@ int test4_2567() const volatile A cva = a; sa<sizeof(sink_4_2567(a)) == 2> t1; sa<sizeof(sink_4_2567(ca)) == 2> t2; - sa<sizeof(sink_4_2567(va)) == 7> t3; sa<sizeof(sink_4_2567(source())) == 5> t5; sa<sizeof(sink_4_2567(c_source())) == 6> t6; sa<sizeof(sink_4_2567(v_source())) == 7> t7; @@ -1107,8 +1075,6 @@ int test4_2568() const volatile A cva = a; sa<sizeof(sink_4_2568(a)) == 2> t1; sa<sizeof(sink_4_2568(ca)) == 2> t2; - sa<sizeof(sink_4_2568(va)) == 8> t3; - sa<sizeof(sink_4_2568(cva)) == 8> t4; sa<sizeof(sink_4_2568(source())) == 5> t5; sa<sizeof(sink_4_2568(c_source())) == 6> t6; sa<sizeof(sink_4_2568(v_source())) == 8> t7; @@ -1129,8 +1095,6 @@ int test4_2578() const volatile A cva = a; sa<sizeof(sink_4_2578(a)) == 2> t1; sa<sizeof(sink_4_2578(ca)) == 2> t2; - sa<sizeof(sink_4_2578(va)) == 7> t3; - sa<sizeof(sink_4_2578(cva)) == 8> t4; sa<sizeof(sink_4_2578(source())) == 5> t5; sa<sizeof(sink_4_2578(c_source())) == 8> t6; sa<sizeof(sink_4_2578(v_source())) == 7> t7; @@ -1151,8 +1115,6 @@ int test4_2678() const volatile A cva = a; sa<sizeof(sink_4_2678(a)) == 2> t1; sa<sizeof(sink_4_2678(ca)) == 2> t2; - sa<sizeof(sink_4_2678(va)) == 7> t3; - sa<sizeof(sink_4_2678(cva)) == 8> t4; sa<sizeof(sink_4_2678(c_source())) == 6> t6; sa<sizeof(sink_4_2678(v_source())) == 7> t7; sa<sizeof(sink_4_2678(cv_source())) == 8> t8; @@ -1297,7 +1259,6 @@ int test4_3567() volatile A va; const volatile A cva = a; sa<sizeof(sink_4_3567(a)) == 3> t1; - sa<sizeof(sink_4_3567(ca)) == 6> t2; sa<sizeof(sink_4_3567(va)) == 3> t3; sa<sizeof(sink_4_3567(source())) == 5> t5; sa<sizeof(sink_4_3567(c_source())) == 6> t6; @@ -1317,9 +1278,7 @@ int test4_3568() volatile A va; const volatile A cva = a; sa<sizeof(sink_4_3568(a)) == 3> t1; - sa<sizeof(sink_4_3568(ca)) == 6> t2; sa<sizeof(sink_4_3568(va)) == 3> t3; - sa<sizeof(sink_4_3568(cva)) == 8> t4; sa<sizeof(sink_4_3568(source())) == 5> t5; sa<sizeof(sink_4_3568(c_source())) == 6> t6; sa<sizeof(sink_4_3568(v_source())) == 8> t7; @@ -1339,9 +1298,7 @@ int test4_3578() volatile A va; const volatile A cva = a; sa<sizeof(sink_4_3578(a)) == 3> t1; - sa<sizeof(sink_4_3578(ca)) == 8> t2; sa<sizeof(sink_4_3578(va)) == 3> t3; - sa<sizeof(sink_4_3578(cva)) == 8> t4; sa<sizeof(sink_4_3578(source())) == 5> t5; sa<sizeof(sink_4_3578(c_source())) == 8> t6; sa<sizeof(sink_4_3578(v_source())) == 7> t7; @@ -1361,9 +1318,7 @@ int test4_3678() volatile A va; const volatile A cva = a; sa<sizeof(sink_4_3678(a)) == 3> t1; - sa<sizeof(sink_4_3678(ca)) == 6> t2; sa<sizeof(sink_4_3678(va)) == 3> t3; - sa<sizeof(sink_4_3678(cva)) == 8> t4; sa<sizeof(sink_4_3678(c_source())) == 6> t6; sa<sizeof(sink_4_3678(v_source())) == 7> t7; sa<sizeof(sink_4_3678(cv_source())) == 8> t8; @@ -1467,10 +1422,6 @@ int test4_5678() const A ca = a; volatile A va; const volatile A cva = a; - sa<sizeof(sink_4_5678(a)) == 5> t1; - sa<sizeof(sink_4_5678(ca)) == 6> t2; - sa<sizeof(sink_4_5678(va)) == 7> t3; - sa<sizeof(sink_4_5678(cva)) == 8> t4; sa<sizeof(sink_4_5678(source())) == 5> t5; sa<sizeof(sink_4_5678(c_source())) == 6> t6; sa<sizeof(sink_4_5678(v_source())) == 7> t7; diff --git a/gcc/testsuite/g++.dg/cpp0x/rv5n.C b/gcc/testsuite/g++.dg/cpp0x/rv5n.C index 14128b2aa36..c31a30b2d6f 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv5n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv5n.C @@ -1,6 +1,6 @@ // I, Howard Hinnant, hereby place this code in the public domain. -// Test overlaod resolution among referece types +// Test overload resolution among reference types // { dg-do compile } // { dg-options "-std=c++0x" } @@ -115,6 +115,22 @@ int test5_12357() return 0; } +one sink_5_12358( A&); +two sink_5_12358(const A&); +three sink_5_12358(volatile A&); +five sink_5_12358( A&&); +eight sink_5_12358(const volatile A&&); // { dg-message "" } + +int test5_12358() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_5_12358(cva); // { dg-error "lvalue" } + return 0; +} + one sink_5_12367( A&); // { dg-message "candidates" } two sink_5_12367(const A&); // { dg-message "note" } three sink_5_12367(volatile A&); // { dg-message "note" } @@ -133,6 +149,38 @@ int test5_12367() return 0; } +one sink_5_12368( A&); +two sink_5_12368(const A&); +three sink_5_12368(volatile A&); +six sink_5_12368(const A&&); +eight sink_5_12368(const volatile A&&); // { dg-message "" } + +int test5_12368() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_5_12368(cva); // { dg-error "lvalue" } + return 0; +} + +one sink_5_12378( A&); +two sink_5_12378(const A&); +three sink_5_12378(volatile A&); +seven sink_5_12378(volatile A&&); +eight sink_5_12378(const volatile A&&); // { dg-message "" } + +int test5_12378() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_5_12378(cva); // { dg-error "lvalue" } + return 0; +} + one sink_5_12456( A&); // { dg-message "candidates" } two sink_5_12456(const A&); // { dg-message "note" } four sink_5_12456(const volatile A&); // { dg-message "note" } @@ -187,7 +235,7 @@ one sink_5_12567( A&); // { dg-message "candidates" } two sink_5_12567(const A&); // { dg-message "note" } five sink_5_12567( A&&); // { dg-message "note" } six sink_5_12567(const A&&); // { dg-message "note" } -seven sink_5_12567(volatile A&&); // { dg-message "note" } +seven sink_5_12567(volatile A&&); // { dg-message "" } int test5_12567() { @@ -195,16 +243,51 @@ int test5_12567() const A ca = a; volatile A va; const volatile A cva = a; + sink_5_12567(va); // { dg-error "lvalue" } sink_5_12567(cva); // { dg-error "no match" } sink_5_12567(cv_source()); // { dg-error "no match" } return 0; } +one sink_5_12568( A&); +two sink_5_12568(const A&); +five sink_5_12568( A&&); +six sink_5_12568(const A&&); +eight sink_5_12568(const volatile A&&); // { dg-message "" } + +int test5_12568() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_5_12568(va); // { dg-error "lvalue" } + sink_5_12568(cva); // { dg-error "lvalue" } + return 0; +} + +one sink_5_12578( A&); +two sink_5_12578(const A&); +five sink_5_12578( A&&); +seven sink_5_12578(volatile A&&); // { dg-message "" } +eight sink_5_12578(const volatile A&&); // { dg-message "" } + +int test5_12578() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_5_12578(va); // { dg-error "lvalue" } + sink_5_12578(cva); // { dg-error "lvalue" } + return 0; +} + one sink_5_12678( A&); two sink_5_12678(const A&); // { dg-message "candidates" } six sink_5_12678(const A&&); // { dg-message "note" } -seven sink_5_12678(volatile A&&); // { dg-message "note" } -eight sink_5_12678(const volatile A&&); // { dg-message "note" } +seven sink_5_12678(volatile A&&); // { dg-message "" } +eight sink_5_12678(const volatile A&&); // { dg-message "" } int test5_12678() { @@ -212,6 +295,8 @@ int test5_12678() const A ca = a; volatile A va; const volatile A cva = a; + sink_5_12678(va); // { dg-error "lvalue" } + sink_5_12678(cva); // { dg-error "lvalue" } sink_5_12678(source()); // { dg-error "ambiguous" } return 0; } @@ -270,7 +355,7 @@ int test5_13467() one sink_5_13567( A&); // { dg-message "candidates" } three sink_5_13567(volatile A&); // { dg-message "note" } five sink_5_13567( A&&); // { dg-message "note" } -six sink_5_13567(const A&&); // { dg-message "note" } +six sink_5_13567(const A&&); // { dg-message "" } seven sink_5_13567(volatile A&&); // { dg-message "note" } int test5_13567() @@ -279,16 +364,51 @@ int test5_13567() const A ca = a; volatile A va; const volatile A cva = a; + sink_5_13567(ca); // { dg-error "lvalue" } sink_5_13567(cva); // { dg-error "no match" } sink_5_13567(cv_source()); // { dg-error "no match" } return 0; } +one sink_5_13568( A&); +three sink_5_13568(volatile A&); +five sink_5_13568( A&&); +six sink_5_13568(const A&&); // { dg-message "" } +eight sink_5_13568(const volatile A&&); // { dg-message "" } + +int test5_13568() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_5_13568(ca); // { dg-error "lvalue" } + sink_5_13568(cva); // { dg-error "lvalue" } + return 0; +} + +one sink_5_13578( A&); +three sink_5_13578(volatile A&); +five sink_5_13578( A&&); +seven sink_5_13578(volatile A&&); +eight sink_5_13578(const volatile A&&); // { dg-message "" } + +int test5_13578() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_5_13578(ca); // { dg-error "lvalue" } + sink_5_13578(cva); // { dg-error "lvalue" } + return 0; +} + one sink_5_13678( A&); three sink_5_13678(volatile A&); -six sink_5_13678(const A&&); // { dg-message "candidates" } +six sink_5_13678(const A&&); // { dg-message "" } seven sink_5_13678(volatile A&&); // { dg-message "note" } -eight sink_5_13678(const volatile A&&); // { dg-message "note" } +eight sink_5_13678(const volatile A&&); // { dg-message "" } int test5_13678() { @@ -296,6 +416,8 @@ int test5_13678() const A ca = a; volatile A va; const volatile A cva = a; + sink_5_13678(ca); // { dg-error "lvalue" } + sink_5_13678(cva); // { dg-error "lvalue" } sink_5_13678(source()); // { dg-error "ambiguous" } return 0; } @@ -332,6 +454,24 @@ int test5_14678() return 0; } +one sink_5_15678( A&); +five sink_5_15678( A&&); +six sink_5_15678(const A&&); // { dg-message "" } +seven sink_5_15678(volatile A&&); // { dg-message "" } +eight sink_5_15678(const volatile A&&); // { dg-message "" } + +int test5_15678() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_5_15678(ca); // { dg-error "lvalue" } + sink_5_15678(va); // { dg-error "lvalue" } + sink_5_15678(cva); // { dg-error "lvalue" } + return 0; +} + two sink_5_23456(const A&); // { dg-message "candidates" } three sink_5_23456(volatile A&); // { dg-message "note" } four sink_5_23456(const volatile A&); // { dg-message "note" } @@ -455,7 +595,7 @@ two sink_5_23568(const A&); // { dg-message "candidates" } three sink_5_23568(volatile A&); // { dg-message "note" } five sink_5_23568( A&&); // { dg-message "note" } six sink_5_23568(const A&&); // { dg-message "note" } -eight sink_5_23568(const volatile A&&); // { dg-message "note" } +eight sink_5_23568(const volatile A&&); // { dg-message "" } int test5_23568() { @@ -463,6 +603,7 @@ int test5_23568() const A ca = a; volatile A va; const volatile A cva = a; + sink_5_23568(cva); // { dg-error "lvalue" } sink_5_23568(a); // { dg-error "ambiguous" } return 0; } @@ -471,7 +612,7 @@ two sink_5_23578(const A&); // { dg-message "candidates" } three sink_5_23578(volatile A&); // { dg-message "note" } five sink_5_23578( A&&); // { dg-message "note" } seven sink_5_23578(volatile A&&); // { dg-message "note" } -eight sink_5_23578(const volatile A&&); // { dg-message "note" } +eight sink_5_23578(const volatile A&&); // { dg-message "" } int test5_23578() { @@ -479,6 +620,7 @@ int test5_23578() const A ca = a; volatile A va; const volatile A cva = a; + sink_5_23578(cva); // { dg-error "lvalue" } sink_5_23578(a); // { dg-error "ambiguous" } return 0; } @@ -487,7 +629,7 @@ two sink_5_23678(const A&); // { dg-message "candidates" } three sink_5_23678(volatile A&); // { dg-message "note" } six sink_5_23678(const A&&); // { dg-message "note" } seven sink_5_23678(volatile A&&); // { dg-message "note" } -eight sink_5_23678(const volatile A&&); // { dg-message "note" } +eight sink_5_23678(const volatile A&&); // { dg-message "" } int test5_23678() { @@ -496,6 +638,7 @@ int test5_23678() volatile A va; const volatile A cva = a; sink_5_23678(a); // { dg-error "ambiguous" } + sink_5_23678(cva); // { dg-error "lvalue" } sink_5_23678(source()); // { dg-error "ambiguous" } return 0; } @@ -532,6 +675,23 @@ int test5_24678() return 0; } +two sink_5_25678(const A&); +five sink_5_25678( A&&); +six sink_5_25678(const A&&); +seven sink_5_25678(volatile A&&); // { dg-message "" } +eight sink_5_25678(const volatile A&&); // { dg-message "" } + +int test5_25678() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_5_25678(va); // { dg-error "lvalue" } + sink_5_25678(cva); // { dg-error "lvalue" } + return 0; +} + three sink_5_34567(volatile A&); // { dg-message "candidates" } four sink_5_34567(const volatile A&); // { dg-message "note" } five sink_5_34567( A&&); // { dg-message "note" } @@ -564,6 +724,23 @@ int test5_34678() return 0; } +three sink_5_35678(volatile A&); +five sink_5_35678( A&&); +six sink_5_35678(const A&&); // { dg-message "" } +seven sink_5_35678(volatile A&&); +eight sink_5_35678(const volatile A&&); // { dg-message "" } + +int test5_35678() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_5_35678(ca); // { dg-error "lvalue" } + sink_5_35678(cva); // { dg-error "lvalue" } + return 0; +} + int main() { return test5_12356() + test5_12357() + test5_12367() + test5_12467() + diff --git a/gcc/testsuite/g++.dg/cpp0x/rv5p.C b/gcc/testsuite/g++.dg/cpp0x/rv5p.C index a4d916714c3..7555867f709 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv5p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv5p.C @@ -1,6 +1,6 @@ // I, Howard Hinnant, hereby place this code in the public domain. -// Test overlaod resolution among referece types +// Test overload resolution among reference types // { dg-do compile } // { dg-options "-std=c++0x" } @@ -173,7 +173,6 @@ int test5_12358() sa<sizeof(sink_5_12358(a)) == 1> t1; sa<sizeof(sink_5_12358(ca)) == 2> t2; sa<sizeof(sink_5_12358(va)) == 3> t3; - sa<sizeof(sink_5_12358(cva)) == 8> t4; sa<sizeof(sink_5_12358(source())) == 5> t5; sa<sizeof(sink_5_12358(c_source())) == 8> t6; sa<sizeof(sink_5_12358(v_source())) == 8> t7; @@ -216,7 +215,6 @@ int test5_12368() sa<sizeof(sink_5_12368(a)) == 1> t1; sa<sizeof(sink_5_12368(ca)) == 2> t2; sa<sizeof(sink_5_12368(va)) == 3> t3; - sa<sizeof(sink_5_12368(cva)) == 8> t4; sa<sizeof(sink_5_12368(source())) == 6> t5; sa<sizeof(sink_5_12368(c_source())) == 6> t6; sa<sizeof(sink_5_12368(v_source())) == 8> t7; @@ -239,7 +237,6 @@ int test5_12378() sa<sizeof(sink_5_12378(a)) == 1> t1; sa<sizeof(sink_5_12378(ca)) == 2> t2; sa<sizeof(sink_5_12378(va)) == 3> t3; - sa<sizeof(sink_5_12378(cva)) == 8> t4; sa<sizeof(sink_5_12378(source())) == 7> t5; sa<sizeof(sink_5_12378(c_source())) == 8> t6; sa<sizeof(sink_5_12378(v_source())) == 7> t7; @@ -394,7 +391,6 @@ int test5_12567() const volatile A cva = a; sa<sizeof(sink_5_12567(a)) == 1> t1; sa<sizeof(sink_5_12567(ca)) == 2> t2; - sa<sizeof(sink_5_12567(va)) == 7> t3; sa<sizeof(sink_5_12567(source())) == 5> t5; sa<sizeof(sink_5_12567(c_source())) == 6> t6; sa<sizeof(sink_5_12567(v_source())) == 7> t7; @@ -415,8 +411,6 @@ int test5_12568() const volatile A cva = a; sa<sizeof(sink_5_12568(a)) == 1> t1; sa<sizeof(sink_5_12568(ca)) == 2> t2; - sa<sizeof(sink_5_12568(va)) == 8> t3; - sa<sizeof(sink_5_12568(cva)) == 8> t4; sa<sizeof(sink_5_12568(source())) == 5> t5; sa<sizeof(sink_5_12568(c_source())) == 6> t6; sa<sizeof(sink_5_12568(v_source())) == 8> t7; @@ -438,8 +432,6 @@ int test5_12578() const volatile A cva = a; sa<sizeof(sink_5_12578(a)) == 1> t1; sa<sizeof(sink_5_12578(ca)) == 2> t2; - sa<sizeof(sink_5_12578(va)) == 7> t3; - sa<sizeof(sink_5_12578(cva)) == 8> t4; sa<sizeof(sink_5_12578(source())) == 5> t5; sa<sizeof(sink_5_12578(c_source())) == 8> t6; sa<sizeof(sink_5_12578(v_source())) == 7> t7; @@ -461,8 +453,6 @@ int test5_12678() const volatile A cva = a; sa<sizeof(sink_5_12678(a)) == 1> t1; sa<sizeof(sink_5_12678(ca)) == 2> t2; - sa<sizeof(sink_5_12678(va)) == 7> t3; - sa<sizeof(sink_5_12678(cva)) == 8> t4; sa<sizeof(sink_5_12678(c_source())) == 6> t6; sa<sizeof(sink_5_12678(v_source())) == 7> t7; sa<sizeof(sink_5_12678(cv_source())) == 8> t8; @@ -614,7 +604,6 @@ int test5_13567() volatile A va; const volatile A cva = a; sa<sizeof(sink_5_13567(a)) == 1> t1; - sa<sizeof(sink_5_13567(ca)) == 6> t2; sa<sizeof(sink_5_13567(va)) == 3> t3; sa<sizeof(sink_5_13567(source())) == 5> t5; sa<sizeof(sink_5_13567(c_source())) == 6> t6; @@ -635,9 +624,7 @@ int test5_13568() volatile A va; const volatile A cva = a; sa<sizeof(sink_5_13568(a)) == 1> t1; - sa<sizeof(sink_5_13568(ca)) == 6> t2; sa<sizeof(sink_5_13568(va)) == 3> t3; - sa<sizeof(sink_5_13568(cva)) == 8> t4; sa<sizeof(sink_5_13568(source())) == 5> t5; sa<sizeof(sink_5_13568(c_source())) == 6> t6; sa<sizeof(sink_5_13568(v_source())) == 8> t7; @@ -658,9 +645,7 @@ int test5_13578() volatile A va; const volatile A cva = a; sa<sizeof(sink_5_13578(a)) == 1> t1; - sa<sizeof(sink_5_13578(ca)) == 8> t2; sa<sizeof(sink_5_13578(va)) == 3> t3; - sa<sizeof(sink_5_13578(cva)) == 8> t4; sa<sizeof(sink_5_13578(source())) == 5> t5; sa<sizeof(sink_5_13578(c_source())) == 8> t6; sa<sizeof(sink_5_13578(v_source())) == 7> t7; @@ -681,9 +666,7 @@ int test5_13678() volatile A va; const volatile A cva = a; sa<sizeof(sink_5_13678(a)) == 1> t1; - sa<sizeof(sink_5_13678(ca)) == 6> t2; sa<sizeof(sink_5_13678(va)) == 3> t3; - sa<sizeof(sink_5_13678(cva)) == 8> t4; sa<sizeof(sink_5_13678(c_source())) == 6> t6; sa<sizeof(sink_5_13678(v_source())) == 7> t7; sa<sizeof(sink_5_13678(cv_source())) == 8> t8; @@ -793,9 +776,6 @@ int test5_15678() volatile A va; const volatile A cva = a; sa<sizeof(sink_5_15678(a)) == 1> t1; - sa<sizeof(sink_5_15678(ca)) == 6> t2; - sa<sizeof(sink_5_15678(va)) == 7> t3; - sa<sizeof(sink_5_15678(cva)) == 8> t4; sa<sizeof(sink_5_15678(source())) == 5> t5; sa<sizeof(sink_5_15678(c_source())) == 6> t6; sa<sizeof(sink_5_15678(v_source())) == 7> t7; @@ -964,7 +944,6 @@ int test5_23568() const volatile A cva = a; sa<sizeof(sink_5_23568(ca)) == 2> t2; sa<sizeof(sink_5_23568(va)) == 3> t3; - sa<sizeof(sink_5_23568(cva)) == 8> t4; sa<sizeof(sink_5_23568(source())) == 5> t5; sa<sizeof(sink_5_23568(c_source())) == 6> t6; sa<sizeof(sink_5_23568(v_source())) == 8> t7; @@ -986,7 +965,6 @@ int test5_23578() const volatile A cva = a; sa<sizeof(sink_5_23578(ca)) == 2> t2; sa<sizeof(sink_5_23578(va)) == 3> t3; - sa<sizeof(sink_5_23578(cva)) == 8> t4; sa<sizeof(sink_5_23578(source())) == 5> t5; sa<sizeof(sink_5_23578(c_source())) == 8> t6; sa<sizeof(sink_5_23578(v_source())) == 7> t7; @@ -1008,7 +986,6 @@ int test5_23678() const volatile A cva = a; sa<sizeof(sink_5_23678(ca)) == 2> t2; sa<sizeof(sink_5_23678(va)) == 3> t3; - sa<sizeof(sink_5_23678(cva)) == 8> t4; sa<sizeof(sink_5_23678(c_source())) == 6> t6; sa<sizeof(sink_5_23678(v_source())) == 7> t7; sa<sizeof(sink_5_23678(cv_source())) == 8> t8; @@ -1119,8 +1096,6 @@ int test5_25678() const volatile A cva = a; sa<sizeof(sink_5_25678(a)) == 2> t1; sa<sizeof(sink_5_25678(ca)) == 2> t2; - sa<sizeof(sink_5_25678(va)) == 7> t3; - sa<sizeof(sink_5_25678(cva)) == 8> t4; sa<sizeof(sink_5_25678(source())) == 5> t5; sa<sizeof(sink_5_25678(c_source())) == 6> t6; sa<sizeof(sink_5_25678(v_source())) == 7> t7; @@ -1231,9 +1206,7 @@ int test5_35678() volatile A va; const volatile A cva = a; sa<sizeof(sink_5_35678(a)) == 3> t1; - sa<sizeof(sink_5_35678(ca)) == 6> t2; sa<sizeof(sink_5_35678(va)) == 3> t3; - sa<sizeof(sink_5_35678(cva)) == 8> t4; sa<sizeof(sink_5_35678(source())) == 5> t5; sa<sizeof(sink_5_35678(c_source())) == 6> t6; sa<sizeof(sink_5_35678(v_source())) == 7> t7; diff --git a/gcc/testsuite/g++.dg/cpp0x/rv6n.C b/gcc/testsuite/g++.dg/cpp0x/rv6n.C index 040c0f6c3e8..2a2520c7599 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv6n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv6n.C @@ -1,6 +1,6 @@ // I, Howard Hinnant, hereby place this code in the public domain. -// Test overlaod resolution among referece types +// Test overload resolution among reference types // { dg-do compile } // { dg-options "-std=c++0x" } @@ -70,7 +70,7 @@ three sink_6_235678(volatile A&); // { dg-message "note" } five sink_6_235678( A&&); // { dg-message "note" } six sink_6_235678(const A&&); // { dg-message "note" } seven sink_6_235678(volatile A&&); // { dg-message "note" } -eight sink_6_235678(const volatile A&&); // { dg-message "note" } +eight sink_6_235678(const volatile A&&); // { dg-message "" } int test6_235678() { @@ -79,6 +79,7 @@ int test6_235678() volatile A va; const volatile A cva = a; sink_6_235678(a); // { dg-error "ambiguous" } + sink_6_235678(cva); // { dg-error "lvalue" } return 0; } @@ -191,7 +192,7 @@ two sink_6_123678(const A&); // { dg-message "candidates" } three sink_6_123678(volatile A&); six sink_6_123678(const A&&); // { dg-message "note" } seven sink_6_123678(volatile A&&); // { dg-message "note" } -eight sink_6_123678(const volatile A&&); // { dg-message "note" } +eight sink_6_123678(const volatile A&&); // { dg-message "" } int test6_123678() { @@ -199,6 +200,7 @@ int test6_123678() const A ca = a; volatile A va; const volatile A cva = a; + sink_6_123678(cva); // { dg-error "lvalue" } sink_6_123678(source()); // { dg-error "ambiguous" } return 0; } @@ -221,6 +223,40 @@ int test6_123567() return 0; } +one sink_6_123568( A&); +two sink_6_123568(const A&); +three sink_6_123568(volatile A&); +five sink_6_123568( A&&); +six sink_6_123568(const A&&); +eight sink_6_123568(const volatile A&&); // { dg-message "" } + +int test6_123568() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_6_123568(cva); // { dg-error "lvalue" } + return 0; +} + +one sink_6_123578( A&); +two sink_6_123578(const A&); +three sink_6_123578(volatile A&); +five sink_6_123578( A&&); +seven sink_6_123578(volatile A&&); +eight sink_6_123578(const volatile A&&); // { dg-message "" } + +int test6_123578() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_6_123578(cva); // { dg-error "lvalue" } + return 0; +} + one sink_6_123467( A&); // { dg-message "candidates" } two sink_6_123467(const A&); // { dg-message "note" } three sink_6_123467(volatile A&); // { dg-message "note" } @@ -256,6 +292,24 @@ int test6_124567() return 0; } +one sink_6_125678( A&); +two sink_6_125678(const A&); +five sink_6_125678( A&&); +six sink_6_125678(const A&&); +seven sink_6_125678(volatile A&&); // { dg-message "" } +eight sink_6_125678(const volatile A&&); // { dg-message "" } + +int test6_125678() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_6_125678(va); // { dg-error "lvalue" } + sink_6_125678(cva); // { dg-error "lvalue" } + return 0; +} + one sink_6_134567( A&); // { dg-message "candidates" } three sink_6_134567(volatile A&); // { dg-message "note" } four sink_6_134567(const volatile A&); // { dg-message "note" } @@ -273,6 +327,24 @@ int test6_134567() return 0; } +one sink_6_135678( A&); +three sink_6_135678(volatile A&); +five sink_6_135678( A&&); +six sink_6_135678(const A&&); // { dg-message "" } +seven sink_6_135678(volatile A&&); +eight sink_6_135678(const volatile A&&); // { dg-message "" } + +int test6_135678() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_6_135678(ca); // { dg-error "lvalue" } + sink_6_135678(cva); // { dg-error "lvalue" } + return 0; +} + int main() { return test6_235678() + test6_234678() + test6_234578() + test6_234568() + diff --git a/gcc/testsuite/g++.dg/cpp0x/rv6p.C b/gcc/testsuite/g++.dg/cpp0x/rv6p.C index a59958e37ef..0e5352bf8b1 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv6p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv6p.C @@ -1,6 +1,6 @@ // I, Howard Hinnant, hereby place this code in the public domain. -// Test overlaod resolution among referece types +// Test overload resolution among reference types // { dg-do compile } // { dg-options "-std=c++0x" } @@ -207,7 +207,6 @@ int test6_123568() sa<sizeof(sink_6_123568(a)) == 1> t1; sa<sizeof(sink_6_123568(ca)) == 2> t2; sa<sizeof(sink_6_123568(va)) == 3> t3; - sa<sizeof(sink_6_123568(cva)) == 8> t4; sa<sizeof(sink_6_123568(source())) == 5> t5; sa<sizeof(sink_6_123568(c_source())) == 6> t6; sa<sizeof(sink_6_123568(v_source())) == 8> t7; @@ -231,7 +230,6 @@ int test6_123578() sa<sizeof(sink_6_123578(a)) == 1> t1; sa<sizeof(sink_6_123578(ca)) == 2> t2; sa<sizeof(sink_6_123578(va)) == 3> t3; - sa<sizeof(sink_6_123578(cva)) == 8> t4; sa<sizeof(sink_6_123578(source())) == 5> t5; sa<sizeof(sink_6_123578(c_source())) == 8> t6; sa<sizeof(sink_6_123578(v_source())) == 7> t7; @@ -255,7 +253,6 @@ int test6_123678() sa<sizeof(sink_6_123678(a)) == 1> t1; sa<sizeof(sink_6_123678(ca)) == 2> t2; sa<sizeof(sink_6_123678(va)) == 3> t3; - sa<sizeof(sink_6_123678(cva)) == 8> t4; sa<sizeof(sink_6_123678(c_source())) == 6> t6; sa<sizeof(sink_6_123678(v_source())) == 7> t7; sa<sizeof(sink_6_123678(cv_source())) == 8> t8; @@ -371,8 +368,6 @@ int test6_125678() const volatile A cva = a; sa<sizeof(sink_6_125678(a)) == 1> t1; sa<sizeof(sink_6_125678(ca)) == 2> t2; - sa<sizeof(sink_6_125678(va)) == 7> t3; - sa<sizeof(sink_6_125678(cva)) == 8> t4; sa<sizeof(sink_6_125678(source())) == 5> t5; sa<sizeof(sink_6_125678(c_source())) == 6> t6; sa<sizeof(sink_6_125678(v_source())) == 7> t7; @@ -488,9 +483,7 @@ int test6_135678() volatile A va; const volatile A cva = a; sa<sizeof(sink_6_135678(a)) == 1> t1; - sa<sizeof(sink_6_135678(ca)) == 6> t2; sa<sizeof(sink_6_135678(va)) == 3> t3; - sa<sizeof(sink_6_135678(cva)) == 8> t4; sa<sizeof(sink_6_135678(source())) == 5> t5; sa<sizeof(sink_6_135678(c_source())) == 6> t6; sa<sizeof(sink_6_135678(v_source())) == 7> t7; @@ -627,7 +620,6 @@ int test6_235678() const volatile A cva = a; sa<sizeof(sink_6_235678(ca)) == 2> t2; sa<sizeof(sink_6_235678(va)) == 3> t3; - sa<sizeof(sink_6_235678(cva)) == 8> t4; sa<sizeof(sink_6_235678(source())) == 5> t5; sa<sizeof(sink_6_235678(c_source())) == 6> t6; sa<sizeof(sink_6_235678(v_source())) == 7> t7; diff --git a/gcc/testsuite/g++.dg/cpp0x/rv7n.C b/gcc/testsuite/g++.dg/cpp0x/rv7n.C index 9d81bd5d722..102730bc7f0 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv7n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv7n.C @@ -48,6 +48,24 @@ int test7_1234567() return 0; } +one sink_7_1235678( A&); +two sink_7_1235678(const A&); +three sink_7_1235678(volatile A&); +five sink_7_1235678( A&&); +six sink_7_1235678(const A&&); +seven sink_7_1235678(volatile A&&); +eight sink_7_1235678(const volatile A&&); // { dg-message "" } + +int test7_1235678() +{ + A a; + const A ca = a; + volatile A va; + const volatile A cva = a; + sink_7_1235678(cva); // { dg-error "lvalue" } + return 0; +} + two sink_7_2345678(const A&); // { dg-message "candidates" } three sink_7_2345678(volatile A&); // { dg-message "note" } four sink_7_2345678(const volatile A&); // { dg-message "note" } diff --git a/gcc/testsuite/g++.dg/cpp0x/rv7p.C b/gcc/testsuite/g++.dg/cpp0x/rv7p.C index d3e1474ff10..d25488f94f1 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv7p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv7p.C @@ -1,6 +1,6 @@ // I, Howard Hinnant, hereby place this code in the public domain. -// Test overlaod resolution among referece types +// Test overload resolution among reference types // { dg-do compile } // { dg-options "-std=c++0x" } @@ -145,7 +145,6 @@ int test7_1235678() sa<sizeof(sink_7_1235678(a)) == 1> t1; sa<sizeof(sink_7_1235678(ca)) == 2> t2; sa<sizeof(sink_7_1235678(va)) == 3> t3; - sa<sizeof(sink_7_1235678(cva)) == 8> t4; sa<sizeof(sink_7_1235678(source())) == 5> t5; sa<sizeof(sink_7_1235678(c_source())) == 6> t6; sa<sizeof(sink_7_1235678(v_source())) == 7> t7; diff --git a/gcc/testsuite/g++.dg/cpp0x/rv8p.C b/gcc/testsuite/g++.dg/cpp0x/rv8p.C index 95a72d5105b..cc7ff8a6ef3 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv8p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv8p.C @@ -1,6 +1,6 @@ // I, Howard Hinnant, hereby place this code in the public domain. -// Test overlaod resolution among referece types +// Test overload resolution among reference types // { dg-do compile } // { dg-options "-std=c++0x" } diff --git a/gcc/testsuite/g++.dg/cpp0x/template_deduction.C b/gcc/testsuite/g++.dg/cpp0x/template_deduction.C index ee48fb305d0..c1eace6fa0b 100644 --- a/gcc/testsuite/g++.dg/cpp0x/template_deduction.C +++ b/gcc/testsuite/g++.dg/cpp0x/template_deduction.C @@ -35,7 +35,7 @@ test1(T&&) template <bool is_lvalue_ref, bool is_rvalue_ref, class T> void -test2(const T&&) +test2(const T&&) // { dg-error "argument" } { sa<is_lvalue_reference<const T&&>::value == is_lvalue_ref> t1; sa<is_rvalue_reference<const T&&>::value == is_rvalue_ref> t2; @@ -60,7 +60,7 @@ int main() { test1<true, false>(a); test1<false, true>(source()); - test2<false, true>(a); + test2<false, true>(a); // { dg-error "lvalue" } test2<false, true>(source()); test3<false, true>(&a); test3<false, true>(sourcep()); diff --git a/gcc/testsuite/g++.dg/cpp0x/unnamed_refs.C b/gcc/testsuite/g++.dg/cpp0x/unnamed_refs.C index 06311856d69..57d635961ba 100644 --- a/gcc/testsuite/g++.dg/cpp0x/unnamed_refs.C +++ b/gcc/testsuite/g++.dg/cpp0x/unnamed_refs.C @@ -16,7 +16,12 @@ struct A {}; one foo(const A&) {return one();} two foo(A&&) {return two();} -A&& source() {static A a; return a;} +template<typename _Tp> +inline _Tp&& +movel(_Tp& __t) +{ return static_cast<_Tp&&>(__t); } + +A&& source() {static A a; return movel(a);} int test1() { diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-1.C b/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-1.C new file mode 100644 index 00000000000..b2f67036e24 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-1.C @@ -0,0 +1,13 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR debug/39706 +// { dg-options "-g -dA" } +// { dg-do compile } +// { dg-final { scan-assembler-times ".debug_pubnames" 1 } } +// { dg-final { scan-assembler-times "\"main\".*external name" 1 } } +// { dg-final { scan-assembler-times "\"ns::ns_x.*external name" 1 } } +// { dg-final { scan-assembler-times "\"y::y_x.*external name" 1 } } + +namespace ns { int ns_x; } +class y { public: static int y_x; }; +int y::y_x; +int main() { return ns::ns_x; } diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/typedef1.C b/gcc/testsuite/g++.dg/debug/dwarf2/typedef1.C index f325ac54ad2..b3a0f937338 100644 --- a/gcc/testsuite/g++.dg/debug/dwarf2/typedef1.C +++ b/gcc/testsuite/g++.dg/debug/dwarf2/typedef1.C @@ -3,9 +3,9 @@ // { dg-options "-g -dA" } // { dg-do compile } // { dg-final { scan-assembler-times "DW_TAG_structure_type" 2 } } -// { dg-final { scan-assembler-times "DW_AT_name: \"foo<1u>\"" 1 } } +// { dg-final { scan-assembler-times "DW_AT_name: \"foo<1u>\"|\"foo<1u>..\".*DW_AT_name" 1 } } // { dg-final { scan-assembler-times "DW_TAG_enumeration_type" 2 } } -// { dg-final { scan-assembler-times "DW_AT_name: \"typedef foo<1u>::type type\"" 1 } } +// { dg-final { scan-assembler-times "DW_AT_name: \"typedef foo<1u>::type type\"|\"typedef foo<1u>::type type..\".*DW_AT_name" 1 } } // { dg-final { scan-assembler-times "DIE (.*) DW_TAG_enumeration_type" 2 } } // { dg-final { scan-assembler-times "\"e0..\".*DW_AT_name" 1 } } // { dg-final { scan-assembler-times "\"e1..\".*DW_AT_name" 1 } } diff --git a/gcc/testsuite/g++.dg/ext/complit12.C b/gcc/testsuite/g++.dg/ext/complit12.C new file mode 100644 index 00000000000..81056214483 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit12.C @@ -0,0 +1,54 @@ +// PR c++/40948 +// { dg-do run } +// { dg-options "" } + +int c; +struct M +{ + M () { ++c; } + M (const M&) { ++c; } + ~M () { --c; } +}; + +struct S +{ + S (); + M m[1]; +}; + +S::S () : m ((M[1]) { M () }) +{ +} + +struct T +{ + T (); + M m[4]; +}; + +T::T () : m ((M[4]) { M (), M (), M (), M () }) +{ +} + +int main () +{ + { + M m[1] = (M[1]) { M () }; + if (c != 1) + return 1; + M n = (M) { M () }; + if (c != 2) + return 2; + M o[4] = (M[4]) { M (), M (), M (), M () }; + if (c != 6) + return 3; + S s; + if (c != 7) + return 4; + T t; + if (c != 11) + return 5; + } + if (c != 0) + return 6; +} diff --git a/gcc/testsuite/g++.dg/parse/pr16696-permissive.C b/gcc/testsuite/g++.dg/parse/pr16696-permissive.C new file mode 100644 index 00000000000..1d8a920ad25 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pr16696-permissive.C @@ -0,0 +1,17 @@ +// PR 16696 Strange message when operator++ not found +// { dg-do compile } +// { dg-options "-fdiagnostics-show-option -fpermissive" } + + +struct X { void operator++(); }; +struct Y { }; + +int main () { + X x; + Y y; + x++; // { dg-warning "trying prefix operator" } + + y++; // { dg-warning "trying prefix operator" } + // { dg-error "no match" "" { target *-*-* } 14 } +} + diff --git a/gcc/testsuite/g++.dg/parse/pr16696.C b/gcc/testsuite/g++.dg/parse/pr16696.C new file mode 100644 index 00000000000..902e2a1a90b --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pr16696.C @@ -0,0 +1,17 @@ +// PR 16696 Strange message when operator++ not found +// { dg-do compile } +// { dg-options "-fdiagnostics-show-option" } + + +struct X { void operator++(); }; +struct Y { }; + +int main () { + X x; + Y y; + x++; // { dg-bogus "trying prefix operator" } + // { dg-error "fpermissive" "" { target *-*-* } 12 } + y++; // { dg-bogus "trying prefix operator" } + // { dg-error "fpermissive" "" { target *-*-* } 14 } +} + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr33615.C b/gcc/testsuite/g++.dg/tree-ssa/pr33615.C index e8a536935b7..4b075428290 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/pr33615.C +++ b/gcc/testsuite/g++.dg/tree-ssa/pr33615.C @@ -16,5 +16,5 @@ foo (double a, int x) // The expression 1.0 / 0.0 should not be treated as a loop invariant // if it may throw an exception. -// { dg-final { scan-tree-dump-times "invariant up to" 0 "lim" } } -// { dg-final { cleanup-tree-dump "lim" } } +// { dg-final { scan-tree-dump-times "invariant up to" 0 "lim1" } } +// { dg-final { cleanup-tree-dump "lim\[1-2\]" } } diff --git a/gcc/testsuite/gcc.c-torture/compile/pr40570.c b/gcc/testsuite/gcc.c-torture/compile/pr40570.c new file mode 100644 index 00000000000..7c3f4d83b2e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr40570.c @@ -0,0 +1,22 @@ +extern void anything(int); + +static int foo(int i); + +static int bar(int i) { foo(i); } + +extern int j; + +static int foo(int i) +{ + if (j) + anything(j); + return bar(i); +} + +int baz() +{ + foo(0); + if (baz()) + return 1; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/dfp/pr39902.c b/gcc/testsuite/gcc.dg/dfp/pr39902.c index 8c4e7b24380..120610c3779 100644 --- a/gcc/testsuite/gcc.dg/dfp/pr39902.c +++ b/gcc/testsuite/gcc.dg/dfp/pr39902.c @@ -189,7 +189,7 @@ doit128 (void) if (COMPARE128 (a128, p128_2_0)) FAILURE - a128.d = p128_2_0.d * 1.0DD; + a128.d = p128_2_0.d * 1.0DL; if (COMPARE128 (a128, p128_2_0)) FAILURE @@ -197,7 +197,7 @@ doit128 (void) if (COMPARE128 (a128, m128_2_0)) FAILURE - a128.d = p128_2_0.d * -1.0DD; + a128.d = p128_2_0.d * -1.0DL; if (COMPARE128 (a128, m128_2_0)) FAILURE @@ -208,7 +208,7 @@ doit128 (void) if (! (COMPARE128 (a128, p128_2_0))) FAILURE - a128.d = p128_2_0.d * 1.DD; + a128.d = p128_2_0.d * 1.DL; if (! (COMPARE128 (a128, p128_2_0))) FAILURE @@ -216,7 +216,7 @@ doit128 (void) if (! (COMPARE128 (a128, m128_2_0))) FAILURE - a128.d = p128_2_0.d * -1.DD; + a128.d = p128_2_0.d * -1.DL; if (! (COMPARE128 (a128, m128_2_0))) FAILURE } diff --git a/gcc/testsuite/gcc.dg/graphite/block-0.c b/gcc/testsuite/gcc.dg/graphite/block-0.c index 627f044fc14..55b903650e2 100644 --- a/gcc/testsuite/gcc.dg/graphite/block-0.c +++ b/gcc/testsuite/gcc.dg/graphite/block-0.c @@ -1,5 +1,3 @@ -/* { dg-options "-O -floop-block -fdump-tree-graphite-all" } */ - #define N 1000 int toto() @@ -21,5 +19,5 @@ main() return toto(); } -/* { dg-final { scan-tree-dump-times "will be loop blocked" 1 "graphite"} } */ +/* { dg-final { scan-tree-dump-times "will be loop blocked" 1 "graphite" { xfail *-*-* } } } */ /* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/block-1.c b/gcc/testsuite/gcc.dg/graphite/block-1.c index 0a70e9e10a4..ba772b3f952 100644 --- a/gcc/testsuite/gcc.dg/graphite/block-1.c +++ b/gcc/testsuite/gcc.dg/graphite/block-1.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } */ - #define MAX 8192 void bar (void); @@ -36,5 +34,5 @@ int main() return sum; } -/* { dg-final { scan-tree-dump-times "will be loop blocked" 2 "graphite"} } */ +/* { dg-final { scan-tree-dump-times "will be loop blocked" 2 "graphite" { xfail *-*-* } } } */ /* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/block-2.c b/gcc/testsuite/gcc.dg/graphite/block-2.c index fc4e889e791..210ea342776 100644 --- a/gcc/testsuite/gcc.dg/graphite/block-2.c +++ b/gcc/testsuite/gcc.dg/graphite/block-2.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } */ - typedef unsigned char UChar; typedef int Int32; typedef unsigned int UInt32; diff --git a/gcc/testsuite/gcc.dg/graphite/block-3.c b/gcc/testsuite/gcc.dg/graphite/block-3.c index 1d2ca40dbac..6358bce1e24 100644 --- a/gcc/testsuite/gcc.dg/graphite/block-3.c +++ b/gcc/testsuite/gcc.dg/graphite/block-3.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } */ - #define N 24 #define M 100 diff --git a/gcc/testsuite/gcc.dg/graphite/block-4.c b/gcc/testsuite/gcc.dg/graphite/block-4.c index e3649f01d2d..773dfef5df6 100644 --- a/gcc/testsuite/gcc.dg/graphite/block-4.c +++ b/gcc/testsuite/gcc.dg/graphite/block-4.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } */ - #define N 24 #define M 1000 diff --git a/gcc/testsuite/gcc.dg/graphite/block-5.c b/gcc/testsuite/gcc.dg/graphite/block-5.c index e0bd4688d39..7864f32e1fc 100644 --- a/gcc/testsuite/gcc.dg/graphite/block-5.c +++ b/gcc/testsuite/gcc.dg/graphite/block-5.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } */ - #define N 10000 void foo (int); int test () @@ -22,5 +20,5 @@ int test () } /* Interchange is legal for loops 0 and 1 of the first two SCoPs */ -/* { dg-final { scan-tree-dump-times "Interchange valid for loops 0 and 1:" 2 "graphite"} } */ +/* { dg-final { scan-tree-dump-times "Interchange valid for loops 0 and 1:" 2 "graphite" { xfail *-*-* } } } */ /* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/block-6.c b/gcc/testsuite/gcc.dg/graphite/block-6.c index 77429f1cb83..5545ec9fc91 100644 --- a/gcc/testsuite/gcc.dg/graphite/block-6.c +++ b/gcc/testsuite/gcc.dg/graphite/block-6.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } */ - #define N 10000 void foo (int); int test () @@ -21,5 +19,5 @@ int test () } /* Interchange is not legal for loops 0 and 1 of SCoP 2. */ -/* { dg-final { scan-tree-dump-times "Interchange not valid for loops 0 and 1:" 1 "graphite"} } */ +/* { dg-final { scan-tree-dump-times "Interchange not valid for loops 0 and 1:" 1 "graphite" { xfail *-*-* } } } */ /* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/graphite.exp b/gcc/testsuite/gcc.dg/graphite/graphite.exp index a1257177f55..57fb74c8d90 100644 --- a/gcc/testsuite/gcc.dg/graphite/graphite.exp +++ b/gcc/testsuite/gcc.dg/graphite/graphite.exp @@ -23,23 +23,66 @@ if ![check_effective_target_fgraphite] { return } +# Remove VALUE from LIST_VARIABLE. +proc lremove {list_variable value} { + upvar 1 $list_variable var + set idx [lsearch -exact $var $value] + set var [lreplace $var $idx $idx] +} + # The default action for a test is 'compile'. Save current default. global dg-do-what-default set save-dg-do-what-default ${dg-do-what-default} set dg-do-what-default compile -# If a testcase doesn't have special options, use these. -global DEFAULT_CFLAGS -if ![info exists DEFAULT_CFLAGS] then { - set DEFAULT_CFLAGS " -ansi -pedantic-errors" -} - # Initialize `dg'. dg-init # Main loop. -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ - "" $DEFAULT_CFLAGS + +set wait_to_run_files [lsort [glob -nocomplain $srcdir/$subdir/*.c ] ] + +# Flags using for block-* files. +set DEFAULT_CFLAGS_GRAPHITE_BLOCK "-O2 -fdump-tree-graphite-all" +set block_files [lsort [glob -nocomplain $srcdir/$subdir/block-*.c ] ] +dg-runtest $block_files "" $DEFAULT_CFLAGS_GRAPHITE_BLOCK +foreach block_file $block_files {lremove wait_to_run_files $block_file} + +# Flags using for id-* files. +set DEFAULT_CFLAGS_GRAPHITE_IDENTITY "-O2 -fgraphite-identity" +set id_files [lsort [glob -nocomplain $srcdir/$subdir/id-*.c ] ] +dg-runtest $id_files "" $DEFAULT_CFLAGS_GRAPHITE_IDENTITY +foreach id_file $id_files {lremove wait_to_run_files $id_file} + +# Flags using for interchange-* files. +set DEFAULT_CFLAGS_GRAPHITE_BLOCK "-O2 -fdump-tree-graphite-all -floop-interchange" +set interchange_files [lsort [glob -nocomplain $srcdir/$subdir/interchange-*.c ] ] +dg-runtest $interchange_files "" $DEFAULT_CFLAGS_GRAPHITE_BLOCK +foreach interchange_file $interchange_files {lremove wait_to_run_files $interchange_file} + +# Flags using for scop-* files. +set DEFAULT_CFLAGS_GRAPHITE_SCOP "-O2 -fgraphite -fdump-tree-graphite-all" +set scop_files [lsort [glob -nocomplain $srcdir/$subdir/scop-*.c ] ] +dg-runtest $scop_files "" $DEFAULT_CFLAGS_GRAPHITE_SCOP +foreach scop_file $scop_files {lremove wait_to_run_files $scop_file} + + +# Schedule now the tests to be run. +set dg-do-what-default run + +# Flags using for run-id-* files. +set DEFAULT_CFLAGS_RUN_ID "-O2 -fgraphite-identity" +set run_id_files [lsort [glob -nocomplain $srcdir/$subdir/run-id-*.c ] ] +dg-runtest $run_id_files "" $DEFAULT_CFLAGS_RUN_ID +foreach run_id_file $run_id_files {lremove wait_to_run_files $run_id_file} + + +# The default action for the rest of the files is 'compile'. +set dg-do-what-default compile + +# Flags using for other files. +set DEFAULT_CFLAGS_GRAPHITE "-ansi -pedantic-errors" +dg-runtest $wait_to_run_files "" $DEFAULT_CFLAGS_GRAPHITE # Clean up. set dg-do-what-default ${save-dg-do-what-default} diff --git a/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-1.c b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-1.c new file mode 100644 index 00000000000..7f043d83d8b --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-1.c @@ -0,0 +1,30 @@ +void abort (void); + +void parloop (int N) +{ + int i; + int x[10000000]; + + for (i = 0; i < N; i++) + x[i] = i + 3; + + for (i = 0; i < N; i++) + { + if (x[i] != i + 3) + abort (); + } +} + +int main(void) +{ + parloop(10000000); + + return 0; +} + +/* Check that parallel code generation part make the right answer. */ +/* { dg-final { scan-tree-dump-times "1 loops carried no dependency" 2 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ +/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "parloops" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-2.c b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-2.c new file mode 100644 index 00000000000..a198fed658a --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-2.c @@ -0,0 +1,30 @@ +void abort (void); + +void parloop (int N) +{ + int i, j; + int x[10000][10000]; + + for (i = 0; i < N; i++) + for (j = 0; j < N; j++) + x[i][j] = i + j + 3; + + for (i = 0; i < N; i++) + for (j = 0; j < N; j++) + if (x[i][j] != i + j + 3) + abort (); +} + +int main(void) +{ + parloop(10000); + + return 0; +} + +/* Check that parallel code generation part make the right answer. */ +/* { dg-final { scan-tree-dump-times "2 loops carried no dependency" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ +/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "parloops" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-3.c b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-3.c new file mode 100644 index 00000000000..81b356d5c24 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-3.c @@ -0,0 +1,38 @@ +void abort (void); + +#define N 500 + +void foo(void) +{ + int i,j; + + int Z[2*N+2][2*N+2], B[2*N+2][2*N+2]; + + for (i = 0; i < 2*N+2; i++) + for (j = 0; j < 2*N+2; j++) + B[i][j] = Z[i][j] = i + j; + + for (i = 0; i <= N; i++) + for (j = 0; j <= N; j++) + Z[i][j] = Z[j+N][i+N+1]; + + for (i = 0; i <= N; i++) + for (j = 0; j <=N; j++) + if (Z[i][j] != B[j+N][i+N+1]) + abort(); +} + +int main(void) +{ + foo(); + + return 0; +} + +/* Check that parallel code generation part make the right answer. */ +/* { dg-final { scan-tree-dump-times "4 loops carried no dependency" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ +/* { dg-final { scan-tree-dump-times "loopfn.0" 5 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "loopfn.1" 5 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "parloops" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-4.c b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-4.c new file mode 100644 index 00000000000..c0c6b1c6e55 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-4.c @@ -0,0 +1,55 @@ +/* Autopar with IF conditions. */ + +void abort(); + +#define N 10000 +#define T 1000 + +void foo(void) +{ + int i; + int A[2*N], B[2*N]; + + /* Initialize array: carried no dependency. */ + for (i = 0; i < 2*N; i++) + B[i] = A[i] = i; + + for (i = 0; i < N; i++) + { + if (i < T) + /* loop i1: carried no dependency. */ + A[i] = A[i+T]; + else + /* loop i2: carried dependency. */ + A[i] = A[i+T+1]; + } + + /* If it runs a wrong answer, abort. */ + for (i = 0; i < N; i++) + { + if (i < T) + { + if (A[i] != B[i+T]) + abort(); + } + else + { + if (A[i] != B[i+T+1]) + abort(); + } + } +} + +int main(void) +{ + foo(); + return 0; +} + +/* Check that parallel code generation part make the right answer. */ +/* { dg-final { scan-tree-dump-times "2 loops carried no dependency" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ +/* { dg-final { scan-tree-dump-times "loopfn.0" 5 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "loopfn.1" 5 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "parloops" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-5.c b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-5.c new file mode 100644 index 00000000000..e5392b1b8ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-5.c @@ -0,0 +1,39 @@ +/* Triangle loops. */ +void abort (void); + +#define N 500 + +void foo(void) +{ + int i,j; + int A[3*N], B[3*N]; + + for (i = 0; i < 3*N; i++) + B[i] = A[i] = i; + + for (i = 1; i < N; i++) + for (j = 1; j < i; j++) + /* This loop carried no dependency, it fails + at code generation part.*/ + A[j+N] = A[j] + j; + + for (i = 1; i < N; i++) + for (j = 1; j < i; j++) + if (A[j+N] != B[j] + j) + abort(); +} + +int main(void) +{ + foo(); + + return 0; +} + +/* Check that parallel code generation part make the right answer. */ +/* { dg-final { scan-tree-dump-times "2 loops carried no dependency" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ +/* { dg-final { scan-tree-dump-times "loopfn.0" 5 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "loopfn.1" 5 "optimized" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "parloops" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-6.c b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-6.c new file mode 100644 index 00000000000..e961fc0baa5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-6.c @@ -0,0 +1,38 @@ +#define N 500 + +int foo(void) +{ + int i, j, k; + int X[2*N], Y[2*N], B[2*N]; + int A[2*N][2*N], C[2*N][2*N]; + + for (i = 1; i <= N; i++) + { + X[i] = Y[i] + 10; + for (j = 1; j <= N; j++) + { + B[j] = A[j][N]; + for (k = 1; k <= N; k++) + { + A[j+1][k] = B[j] + C[j][k]; + } + Y[i+j] = A[j+1][N]; + } + } + + return A[1][5]*B[6]; +} + +int main(void) +{ + foo(); + + return 0; +} + +/* Check that parallel code generation part make the right answer. */ +/* { dg-final { scan-tree-dump-times "1 loops carried no dependency" 2 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ +/* { dg-final { scan-tree-dump-times "loopfn.0" 5 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "parloops" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-7.c b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-7.c new file mode 100644 index 00000000000..9ba9007fe31 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-7.c @@ -0,0 +1,36 @@ +#define N 500 + +int foo(void) +{ + int i, j, k; + int A[N+5][N+5][N+5]; + + /* Loop i: carried no dependency. */ + for (i = 0; i < N; i++) + for (j = 0; j < N; j++) + for (k = 0; k < N; k++) + A[k+1][j+2][i+1] = A[k][j][i+1]; + + for (i = 0; i < N; i++) + /* Loop j: carried no dependency. */ + for (j = 0; j < N; j++) + /* Loop k: carreid no dependency. */ + for (k = 0; k < N; k++) + A[i+1][j][k] = A[i][j][k+1]; + + return A[1][5][2]; +} + +int main(void) +{ + foo(); + + return 0; +} + +/* Check that parallel code generation part make the right answer. */ +/* { dg-final { scan-tree-dump-times "3 loops carried no dependency" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ +/* { dg-final { scan-tree-dump-times "loopfn.0" 5 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "parloops" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-8.c b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-8.c new file mode 100644 index 00000000000..28b9a2a06b9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-8.c @@ -0,0 +1,40 @@ +#define N 1500 + +int foo(void) +{ + int i, j; + int x[N][N], y[N]; + + for (i = 0; i < N; i++) + { + y[i] = i; + + for (j = 0; j < N; j++) + { + if (j > 500) + { + x[i][j] = i + j + 3; + y[j] = i*j + 10; + } + else + x[i][j] = x[i][j]*3; + } + } + + return x[2][5]*y[8]; +} + +int main(void) +{ + foo(); + + return 0; +} + +/* Check that parallel code generation part make the right answer. */ +/* { dg-final { scan-tree-dump-times "2 loops carried no dependency" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ +/* { dg-final { scan-tree-dump-times "loopfn.0" 5 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "loopfn.1" 5 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "parloops" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-9.c b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-9.c new file mode 100644 index 00000000000..36551905f0c --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/force-parallel-9.c @@ -0,0 +1,37 @@ +void abort (void); + +#define N 500 + +void foo(void) +{ + int i,j; + + int Z[2*N+2][2*N+2], B[2*N+2][2*N+2]; + + for (i = 0; i < 2*N+2; i++) + for (j = 0; j < 2*N+2; j++) + B[i][j] = Z[i][j] = i + j; + + for (i = 0; i <= N; i++) + for (j = 0; j <= N; j++) + Z[i][j] = Z[j+N][i+N+1]; + + for (i = 0; i <= N; i++) + for (j = 0; j <=N; j++) + if (Z[i][j] != B[j+N][i+N+1]) + abort(); +} + +int main(void) +{ + foo(); + return 0; +} + +/* Check that parallel code generation part make the right answer. */ +/* { dg-final { scan-tree-dump-times "4 loops carried no dependency" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ +/* { dg-final { scan-tree-dump-times "loopfn.0" 5 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "loopfn.1" 5 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "parloops" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/graphite_autopar/graphite_autopar.exp b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/graphite_autopar.exp new file mode 100644 index 00000000000..11d19a8d9fe --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/graphite_autopar/graphite_autopar.exp @@ -0,0 +1,68 @@ +# Copyright (C) 2008 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# 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/>. + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp + +if ![check_effective_target_pthread] { + return +} + +if ![check_effective_target_fgraphite] { + return +} + +# Remove VALUE from LIST_VARIABLE. +proc lremove {list_variable value} { + upvar 1 $list_variable var + set idx [lsearch -exact $var $value] + set var [lreplace $var $idx $idx] +} + +# Set default action for these tests is 'run'. Save current default. +global dg-do-what-default +set save-dg-do-what-default ${dg-do-what-default} +set dg-do-what-default run + +# Initialize `dg'. +dg-init + +# Main loop. + +set wait_to_run_files [lsort [glob -nocomplain $srcdir/$subdir/*.c]] + +# Flags using for force-parallel-*.c files. +set DEFAULT_CFLAGS_FORCE_PARALLEL " -ansi -pedantic-errors -O2 \ +-ftree-parallelize-loops=4 -floop-parallelize-all \ +-fdump-tree-parloops-details -fdump-tree-optimized \ +-fno-loop-strip-mine -fdump-tree-graphite-all" +set force_parallel_files \ + [lsort [glob -nocomplain $srcdir/$subdir/force-parallel-*.c]] +dg-runtest $force_parallel_files "" $DEFAULT_CFLAGS_FORCE_PARALLEL +foreach force_parallel_file $force_parallel_files \ + {lremove wait_to_run_files $force_parallel_file} + +# Flags using for other files. +set DEFAULT_CFLAGS_GRAPHITE "-ansi -pedantic-errors" +dg-runtest $wait_to_run_files "" $DEFAULT_CFLAGS_GRAPHITE + +# Clean up. +set dg-do-what-default ${save-dg-do-what-default} + +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.dg/graphite/id-1.c b/gcc/testsuite/gcc.dg/graphite/id-1.c new file mode 100644 index 00000000000..70b477a07b1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-1.c @@ -0,0 +1,18 @@ +typedef int *lambda_vector; +typedef lambda_vector *lambda_matrix; +lambda_vector_add_mc (lambda_vector vec1, int const1, + lambda_vector vec2, int const2, + lambda_vector vec3, int size) +{ + int i; + for (i = 0; i < size; i++) + vec3[i] = const1 * vec1[i] + const2 * vec2[i]; +} +lambda_matrix_add_mc (lambda_matrix mat1, int const1, + lambda_matrix mat2, int const2, + lambda_matrix mat3, int m, int n) +{ + int i; + for (i = 0; i < m; i++) + lambda_vector_add_mc (mat1[i], const1, mat2[i], const2, mat3[i], n); +} diff --git a/gcc/testsuite/gcc.dg/graphite/id-10.c b/gcc/testsuite/gcc.dg/graphite/id-10.c new file mode 100644 index 00000000000..8c2b88982b1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-10.c @@ -0,0 +1,15 @@ +int bar[100][100]; + +int +foo (int N, unsigned int J) +{ + int i, k; + + for (k = 0; k < N; k++) + if (k != J) + for (i = 0; i < N; i++) + if (i != J) + bar[k][i] = 20; + + return bar[N][J]; +} diff --git a/gcc/testsuite/gcc.dg/graphite/id-11.c b/gcc/testsuite/gcc.dg/graphite/id-11.c new file mode 100644 index 00000000000..387512c3c4c --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-11.c @@ -0,0 +1,14 @@ +double +foo (double x, double *cof) +{ + int i; + double tmp, value; + + for (i = 10; i >= 0; i--) + { + value += cof[i] / tmp; + tmp -= 1.0; + } + + return value; +} diff --git a/gcc/testsuite/gcc.dg/graphite/id-12.c b/gcc/testsuite/gcc.dg/graphite/id-12.c new file mode 100644 index 00000000000..57857d1d20c --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-12.c @@ -0,0 +1,10 @@ +void +foo (unsigned short x[]) +{ + int i; + unsigned short *p = &x[2]; + if (*p) + x += 2; + for (i = 2; i < 9; i++, ++x) + *x >>= 8; +} diff --git a/gcc/testsuite/gcc.dg/graphite/id-13.c b/gcc/testsuite/gcc.dg/graphite/id-13.c new file mode 100644 index 00000000000..e921cd4e9d6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-13.c @@ -0,0 +1,11 @@ +void +foo (int N, int k, int *fb) +{ + int i, j; + for (i = 1; i <= N; i++) + { + for (j = 1; j < i; j++) + k %= N; + bar (k); + } +} diff --git a/gcc/testsuite/gcc.dg/graphite/id-14.c b/gcc/testsuite/gcc.dg/graphite/id-14.c new file mode 100644 index 00000000000..51ac4c1bbe5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-14.c @@ -0,0 +1,19 @@ +typedef struct { + int n; + float *a; +} bar; + +float +foo (bar *b) +{ + float c, d; + int j; + + for (j = 0; (j < b->n); j++) + d += b->a[j]; + + for (j = 0; (j < b->n); j++) + c += b->a[j]; + + return d; +} diff --git a/gcc/testsuite/gcc.dg/graphite/id-15.c b/gcc/testsuite/gcc.dg/graphite/id-15.c new file mode 100644 index 00000000000..109d5bbdb01 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-15.c @@ -0,0 +1,118 @@ +typedef long unsigned int size_t; +extern void *memset (void *__s, int __c, size_t __n) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1))); + +static void +encode (words, low, hi) + long *words; + unsigned long low; + long hi; +{ + words[0] = ((low) & (((unsigned long) 1 << ((8 * 8) / 2)) - 1)); + words[1] = ((unsigned long) (low) >> (8 * 8) / 2); + words[2] = ((hi) & (((unsigned long) 1 << ((8 * 8) / 2)) - 1)); + words[3] = ((unsigned long) (hi) >> (8 * 8) / 2); +} + +static void +decode (words, low, hi) + long *words; + unsigned long *low; + long *hi; +{ + *low = words[0] + words[1] * ((unsigned long) 1 << (8 * 8) / 2); + *hi = words[2] + words[3] * ((unsigned long) 1 << (8 * 8) / 2); +} + +int +neg_double (l1, h1, lv, hv) + unsigned long l1; + long h1; + unsigned long *lv; + long *hv; +{ + if (l1 == 0) + { + *lv = 0; + *hv = - h1; + return (*hv & h1) < 0; + } + else + { + *lv = -l1; + *hv = ~h1; + return 0; + } +} + +int +add_double (l1, h1, l2, h2, lv, hv) + unsigned long l1, l2; + long h1, h2; + unsigned long *lv; + long *hv; +{ + unsigned long l; + long h; + + l = l1 + l2; + h = h1 + h2 + (l < l1); + + *lv = l; + *hv = h; + return ((~((h1) ^ (h2)) & ((h1) ^ (h))) < 0); +} + +int +mul_double (l1, h1, l2, h2, lv, hv) + unsigned long l1, l2; + long h1, h2; + unsigned long *lv; + long *hv; +{ + long arg1[4]; + long arg2[4]; + long prod[4 * 2]; + unsigned long carry; + int i, j, k; + unsigned long toplow, neglow; + long tophigh, neghigh; + + encode (arg1, l1, h1); + encode (arg2, l2, h2); + + memset ((char *) prod, 0, sizeof prod); + + for (i = 0; i < 4; i++) + { + carry = 0; + for (j = 0; j < 4; j++) + { + k = i + j; + + carry += arg1[i] * arg2[j]; + + carry += prod[k]; + prod[k] = ((carry) & (((unsigned long) 1 << ((8 * 8) / 2)) - 1)); + carry = ((unsigned long) (carry) >> (8 * 8) / 2); + } + prod[i + 4] = carry; + } + + decode (prod, lv, hv); + + + + decode (prod + 4, &toplow, &tophigh); + if (h1 < 0) + { + neg_double (l2, h2, &neglow, &neghigh); + add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh); + } + if (h2 < 0) + { + neg_double (l1, h1, &neglow, &neghigh); + add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh); + } + return (*hv < 0 ? ~(toplow & tophigh) : toplow | tophigh) != 0; +} + diff --git a/gcc/testsuite/gcc.dg/graphite/id-2.c b/gcc/testsuite/gcc.dg/graphite/id-2.c new file mode 100644 index 00000000000..c11f6a283a8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-2.c @@ -0,0 +1,16 @@ +typedef _Complex float GFC_COMPLEX_4; +matmul_c4 () +{ + int x, n, count; + GFC_COMPLEX_4 * bbase_y; + GFC_COMPLEX_4 * dest_y; + GFC_COMPLEX_4 * abase_n; + GFC_COMPLEX_4 bbase_yn; + + for (n = 0; n < count; n++) + { + bbase_yn = bbase_y[n]; + for (x = 0; x < count; x++) + dest_y[x] += abase_n[x] * bbase_yn; + } +} diff --git a/gcc/testsuite/gcc.dg/graphite/id-3.c b/gcc/testsuite/gcc.dg/graphite/id-3.c new file mode 100644 index 00000000000..608c1c37cea --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-3.c @@ -0,0 +1,11 @@ +struct { +} +mmaxloc0_4_i1 () +{ + int dstride; + int *dest; + int rank; + int n; + for (n = 0; n < rank; n++) + dest[n * dstride] = 0; +} diff --git a/gcc/testsuite/gcc.dg/graphite/id-4.c b/gcc/testsuite/gcc.dg/graphite/id-4.c new file mode 100644 index 00000000000..38f6738d706 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-4.c @@ -0,0 +1,7 @@ +extern a[]; +g () +{ + int i, b; + for (i = 0; i < 10; i++) + a[i] = (b == 0); +} diff --git a/gcc/testsuite/gcc.dg/graphite/id-5.c b/gcc/testsuite/gcc.dg/graphite/id-5.c new file mode 100644 index 00000000000..93972d79ed7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-5.c @@ -0,0 +1,15 @@ +void matmul_i1 () +{ + int *abase; + int aystride; + int x, n, count, xcount; + int *dest_y; + int *abase_n; + for (n = 0; n < count; n++) + { + abase_n = abase + n * aystride; + for (x = 0; x < xcount; x++) + dest_y[x] += abase_n[x]; + } +} + diff --git a/gcc/testsuite/gcc.dg/graphite/id-6.c b/gcc/testsuite/gcc.dg/graphite/id-6.c new file mode 100644 index 00000000000..c3aab432a59 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-6.c @@ -0,0 +1,29 @@ +#define N 10000 +void foo (int); +int test () +{ + int a[N]; + unsigned i; + + for (i = 0; i < N; i++) + { + a[i] = i + 12; + + if (i == 40) + a[i] = i; + else + a[i] = i+1; + + + a[i] = i + 12; + a[i] = a[i+1]; + a[i] += a[i+2]; + a[i] += a[i+3]; + a[i] += a[i+4]; + a[i] += a[i+5]; + a[i] += a[i+6]; + + } + + return a[20]; +} diff --git a/gcc/testsuite/gcc.dg/graphite/id-7.c b/gcc/testsuite/gcc.dg/graphite/id-7.c new file mode 100644 index 00000000000..9fa811d6ece --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-7.c @@ -0,0 +1,16 @@ +void foo (int *BM_tab) +{ + int *BM_tab_base; + + BM_tab_base = BM_tab; + BM_tab += 0400; + while (BM_tab_base != BM_tab) + *--BM_tab = 6; +} + +int main () +{ + int BM_tab[0400]; + foo (BM_tab); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/graphite/id-8.c b/gcc/testsuite/gcc.dg/graphite/id-8.c new file mode 100644 index 00000000000..1a278c16426 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-8.c @@ -0,0 +1,14 @@ +int blah; +foo() +{ + int i; + + for (i=0 ; i< 7 ; i++) + { + if (i == 7 - 1) + blah = 0xfcc; + else + blah = 0xfee; + } + return blah; +} diff --git a/gcc/testsuite/gcc.dg/graphite/id-9.c b/gcc/testsuite/gcc.dg/graphite/id-9.c new file mode 100644 index 00000000000..2199538697b --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-9.c @@ -0,0 +1,26 @@ +typedef enum +{ + no_op, + jump +} +re_opcode_t; +struct +{ +} +byte_register_info_type () +{ + char *p; + for (;;) + switch ((re_opcode_t) p++) + { + case no_op: + { + for (; (p);) + ; + for (;;) + ; + } + case jump: + (p) += 2; + } +} diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-0.c b/gcc/testsuite/gcc.dg/graphite/interchange-0.c new file mode 100644 index 00000000000..bfbbb20800a --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/interchange-0.c @@ -0,0 +1,17 @@ +int a[1000][1000]; + +int +foo (int N) +{ + int j; + int i; + + for (i = 0; i < N; i++) + for (j = 0; j < N; j++) + a[j][i] = a[j][i] + 1; + + return a[N][123]; +} + +/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-1.c b/gcc/testsuite/gcc.dg/graphite/interchange-1.c new file mode 100644 index 00000000000..011d98e2cfc --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/interchange-1.c @@ -0,0 +1,20 @@ +/* Formerly known as ltrans-1.c */ + +double u[1782225]; +int foo(int N, int *res) +{ + int i, j; + double sum = 0.0; + + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + sum = sum + u[i + 1335 * j]; + + u[1336 * i] *= 2; + } + *res = sum + N; +} + +/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-2.c b/gcc/testsuite/gcc.dg/graphite/interchange-2.c new file mode 100644 index 00000000000..5a64f9a6f47 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/interchange-2.c @@ -0,0 +1,24 @@ +/* Formerly known as ltrans-2.c */ + +double u[1782225]; +int foo(int N, int *res) +{ + unsigned int i, j; + double sum = 0; + + /* This loop should be converted to a perfect nest and + interchanged. */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + sum = sum + u[i + 1335 * j]; + if (j == N - 1) + u[1336 * i] *= 2; + } + } + *res = sum + N; +} + +/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-3.c b/gcc/testsuite/gcc.dg/graphite/interchange-3.c new file mode 100644 index 00000000000..d081d9e33d5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/interchange-3.c @@ -0,0 +1,19 @@ +/* Formerly known as ltrans-3.c */ + +double u[1782225]; +int foo(int N, int *res) +{ + unsigned int i, j; + double sum = 0; + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + sum = sum + u[i + 1335 * j]; + } + } + *res = sum + N; +} + +/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-4.c b/gcc/testsuite/gcc.dg/graphite/interchange-4.c new file mode 100644 index 00000000000..52fc1709dd1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/interchange-4.c @@ -0,0 +1,18 @@ +/* Formerly known as ltrans-4.c */ + +double u[1782225]; +int foo(int N, int *res) +{ + int i, j; + double sum = 0; + for (i = 0; i < N; i++) + for (j = 0; j < N; j++) + sum = sum + u[i + 1335 * j]; + + for (i = 0; i < N; i++) + u[1336 * i] *= 2; + *res = sum + N; +} + +/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-5.c b/gcc/testsuite/gcc.dg/graphite/interchange-5.c new file mode 100644 index 00000000000..2aec56758cc --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/interchange-5.c @@ -0,0 +1,16 @@ +/* Formerly known as ltrans-5.c */ + +int foo () +{ + int A[100][1111]; + int i, j; + + for( i = 0; i < 1111; i++) + for( j = 0; j < 100; j++) + A[j][i] = 5 * A[j][i]; + + return A[10][10]; +} + +/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-6.c b/gcc/testsuite/gcc.dg/graphite/interchange-6.c new file mode 100644 index 00000000000..64a18653f90 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/interchange-6.c @@ -0,0 +1,17 @@ +/* Formerly known as ltrans-6.c */ + +int medium_loop_interchange(int A[100][200]) +{ + int i,j; + + /* This loop should be interchanged. */ + + for(j = 0; j < 200; j++) + for(i = 0; i < 100; i++) + A[i][j] = A[i][j] + A[i][j]; + + return A[1][1]; +} + +/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-7.c b/gcc/testsuite/gcc.dg/graphite/interchange-7.c new file mode 100644 index 00000000000..7627830586a --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/interchange-7.c @@ -0,0 +1,14 @@ +/* Formerly known as ltrans-8.c */ + +double foo(double *a) +{ + int i,j; + double r = 0.0; + for (i=0; i<100; ++i) + for (j=0; j<1000; ++j) + r += a[j*100+i]; + return r; +} + +/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-8.c b/gcc/testsuite/gcc.dg/graphite/interchange-8.c new file mode 100644 index 00000000000..6a1e201087d --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/interchange-8.c @@ -0,0 +1,45 @@ +int +foo (void) +{ + int i, j, k, l; + int B[4]; + int A[4][4][4][4]; + + for (l = 0; l < 4; l++) + { + for (k = 0; k < 4; k++) + { + for (j = 0; j < 4; j++) + { + for (i = 0; i < 2; i++) + { + B[i] = A[i][k][j][l] + A[3 - i][k][j][l]; + B[3 - i] = A[i][k][j][l] - A[3 - i][k][j][l]; + } + A[0][k][j][l] = B[0] + B[1]; + A[2][k][j][l] = B[0] - B[1]; + A[1][k][j][l] = B[3] + B[2]; + A[3][k][j][l] = B[3] - B[2]; + } + + for (i = 0; i < 4; i++) + { + for (j = 0; j < 2; j++) + { + B[j] = A[i][k][j][l] + A[i][k][3 - j][l]; + B[3 - j] = A[i][k][j][l] - A[i][k][3 - j][l]; + } + A[i][k][0][l] = B[0] + B[1]; + A[i][k][2][l] = B[0] - B[1]; + A[i][k][1][l] = B[3] + B[2]; + A[i][k][3][l] = B[3] - B[2]; + } + } + } + + return A[0][1][0][2]; +} + +/* This should not be interchanged. */ +/* { dg-final { scan-tree-dump-times "will be interchanged" 0 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/pr35356-1.c b/gcc/testsuite/gcc.dg/graphite/pr35356-1.c new file mode 100644 index 00000000000..2ba0c1b0f5e --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/pr35356-1.c @@ -0,0 +1,26 @@ +/* { dg-options "-O2 -fgraphite-identity -fdump-tree-graphite-all" } */ + +int a[100]; + +int +foo (int bar, int n, int k) +{ + int i; + + for (i = 0; i < n; i++) + if (i == k) + a[i] = bar; + + return a[bar]; +} + +/* There should be no loops generated for this testcase, instead we + should generate the following: + + | if (k >= 0 && k < n) + | a[k] = bar; + +*/ + +/* { dg-final { scan-tree-dump-times "loop_1" 0 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/pr35356-2.c b/gcc/testsuite/gcc.dg/graphite/pr35356-2.c new file mode 100644 index 00000000000..5432deec61d --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/pr35356-2.c @@ -0,0 +1,32 @@ +/* { dg-options "-O2 -fgraphite-identity -fdump-tree-graphite-all" } */ + +int a[100]; + +int +foo (int bar, int n, int k) +{ + int i; + + for (i = 0; i < n; i++) + if (i == k) + a[i] = 1; + else + a[i] = i; + + return a[bar]; +} + +/* We should generate the following: + + | for (i = 0; i < min (n, k); i++) + | a[i] = i; + | if (k >= 0 && k < n) + | a[k] = 1; + | for (i = max(k+1,0); i < n; i++) + | a[i] = i; + +*/ + +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "graphite" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR" 1 "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/pr35356-3.c b/gcc/testsuite/gcc.dg/graphite/pr35356-3.c new file mode 100644 index 00000000000..55a771aff94 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/pr35356-3.c @@ -0,0 +1,40 @@ +/* { dg-options "-O2 -fgraphite-identity -fdump-tree-graphite-all" } */ + + +int winner, numf2s; +double **tds; +double d, tsum; + +typedef struct { + double y; +} xyz; + +xyz *Y; +int ti; + +double +match (void) +{ + int tj, tresult; + + for (tj = 0; tj < numf2s; tj++) + if (tj == winner + && Y[tj].y > 0) + tsum += tds[ti][tj] * d; + + return tsum; +} + +/* There should be no loops generated for this testcase, instead we + should generate the following: + + | if (winner >= 0 && winner < numf2s && Y[winner].y > 0) + | tsum += tds[ti][winner] * d; + + For the moment this is XFAILed as this loop is not detected as a + SCoP by graphite: we depend on data in one of the conditions, + "Y[winner].y > 0". This could be fixed when we will use predicates + for such cases. */ + +/* { dg-final { scan-tree-dump-times "loop_1" 0 "graphite" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/pr37485.c b/gcc/testsuite/gcc.dg/graphite/pr37485.c index cf0969bac1d..ce2507b3d6c 100644 --- a/gcc/testsuite/gcc.dg/graphite/pr37485.c +++ b/gcc/testsuite/gcc.dg/graphite/pr37485.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } */ +/* { dg-options "-O2 -fdump-tree-graphite-all" } */ typedef unsigned char UChar; typedef int Int32; diff --git a/gcc/testsuite/gcc.dg/graphite/pr37684.c b/gcc/testsuite/gcc.dg/graphite/pr37684.c index a9e6f5a4a59..ab5a6853316 100644 --- a/gcc/testsuite/gcc.dg/graphite/pr37684.c +++ b/gcc/testsuite/gcc.dg/graphite/pr37684.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } */ +/* { dg-options "-O2 -fdump-tree-graphite-all" } */ typedef struct _IO_FILE FILE; struct _IO_marker { diff --git a/gcc/testsuite/gcc.dg/graphite/pr37828.c b/gcc/testsuite/gcc.dg/graphite/pr37828.c index 0a0412d8045..df0ef7c0aa7 100644 --- a/gcc/testsuite/gcc.dg/graphite/pr37828.c +++ b/gcc/testsuite/gcc.dg/graphite/pr37828.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -floop-block" } */ +/* { dg-options "-O2" } */ typedef struct foo { diff --git a/gcc/testsuite/gcc.dg/graphite/pr37883.c b/gcc/testsuite/gcc.dg/graphite/pr37883.c index 2ab043adce1..9b386561c33 100644 --- a/gcc/testsuite/gcc.dg/graphite/pr37883.c +++ b/gcc/testsuite/gcc.dg/graphite/pr37883.c @@ -1,4 +1,4 @@ -/* { dg-options "-O3 -floop-block" } */ +/* { dg-options "-O3" } */ void test_sort() { diff --git a/gcc/testsuite/gcc.dg/graphite/pr37928.c b/gcc/testsuite/gcc.dg/graphite/pr37928.c index 47ad5bce0bd..3c33f3a4637 100644 --- a/gcc/testsuite/gcc.dg/graphite/pr37928.c +++ b/gcc/testsuite/gcc.dg/graphite/pr37928.c @@ -1,4 +1,4 @@ -/* { dg-options "-O3 -floop-block" } */ +/* { dg-options "-O3" } */ int get_state(int size, int *node, int *hash) { diff --git a/gcc/testsuite/gcc.dg/graphite/pr37943.c b/gcc/testsuite/gcc.dg/graphite/pr37943.c index a4b4fe5658f..4513d12c0b7 100644 --- a/gcc/testsuite/gcc.dg/graphite/pr37943.c +++ b/gcc/testsuite/gcc.dg/graphite/pr37943.c @@ -31,4 +31,3 @@ unsigned char compress(test *in) } /* { dg-final { cleanup-tree-dump "graphite" } } */ - diff --git a/gcc/testsuite/gcc.dg/graphite/pr38409.c b/gcc/testsuite/gcc.dg/graphite/pr38409.c index 41c67753426..5cdb4725dbf 100644 --- a/gcc/testsuite/gcc.dg/graphite/pr38409.c +++ b/gcc/testsuite/gcc.dg/graphite/pr38409.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -floop-block" } */ +/* { dg-options "-O2" } */ typedef struct test input ; struct test diff --git a/gcc/testsuite/gcc.dg/graphite/pr38498.c b/gcc/testsuite/gcc.dg/graphite/pr38498.c index c79bbad554d..d20b4ae165a 100644 --- a/gcc/testsuite/gcc.dg/graphite/pr38498.c +++ b/gcc/testsuite/gcc.dg/graphite/pr38498.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -floop-block" } */ +/* { dg-options "-O2" } */ double test_vector (float **data, int rows, int cols, int vqrows,double epsilon, int maxiter,int **mean, int *map) { diff --git a/gcc/testsuite/gcc.dg/graphite/pr38559.c b/gcc/testsuite/gcc.dg/graphite/pr38559.c index 1e2ef0a4ff3..7f90a50acd0 100644 --- a/gcc/testsuite/gcc.dg/graphite/pr38559.c +++ b/gcc/testsuite/gcc.dg/graphite/pr38559.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -floop-block" } */ +/* { dg-options "-O2" } */ int test() { diff --git a/gcc/testsuite/gcc.dg/graphite/pr39335.c b/gcc/testsuite/gcc.dg/graphite/pr39335.c index c86e03ab73a..5b8fb543855 100644 --- a/gcc/testsuite/gcc.dg/graphite/pr39335.c +++ b/gcc/testsuite/gcc.dg/graphite/pr39335.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -floop-interchange" } */ +/* { dg-options "-O2" } */ typedef unsigned char byte; typedef struct gx_device_s gx_device; diff --git a/gcc/testsuite/gcc.dg/graphite/pr39335_1.c b/gcc/testsuite/gcc.dg/graphite/pr39335_1.c index 257c2c99436..dfa2465e34d 100644 --- a/gcc/testsuite/gcc.dg/graphite/pr39335_1.c +++ b/gcc/testsuite/gcc.dg/graphite/pr39335_1.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -floop-interchange" } */ +/* { dg-options "-O2" } */ void crash_me(int num1, int num2, char * in, char * out) { diff --git a/gcc/testsuite/gcc.dg/graphite/pr40157.c b/gcc/testsuite/gcc.dg/graphite/pr40157.c new file mode 100644 index 00000000000..8b3d7298613 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/pr40157.c @@ -0,0 +1,12 @@ +/* { dg-options "-O2 -fgraphite-identity" } */ + +int buffer[256*256]; +int main(void) +{ + int *dest = buffer; + int x, y; + for(x = 0; x < 256; x++) + for(y = 0; y < 256; y++) + *dest++ = 0; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/graphite/run-id-1.c b/gcc/testsuite/gcc.dg/graphite/run-id-1.c new file mode 100644 index 00000000000..0a0ff6ab801 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/run-id-1.c @@ -0,0 +1,24 @@ +void abort (void); + +void foo (int N) +{ + int i, j; + int x[10000][10000]; + + for (i = 0; i < N; i++) + for (j = 0; j < N; j++) + x[i][j] = i + j + 3; + + for (i = 0; i < N; i++) + for (j = 0; j < N; j++) + if (x[i][j] != i + j + 3) + abort (); +} + +int main(void) +{ + foo (10000); + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/graphite/scop-0.c b/gcc/testsuite/gcc.dg/graphite/scop-0.c index ea3ae065a0b..067e7bcffe0 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-0.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-0.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - int foo (void); void bar (void); diff --git a/gcc/testsuite/gcc.dg/graphite/scop-1.c b/gcc/testsuite/gcc.dg/graphite/scop-1.c index ed6159fb365..ba2590c1102 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-1.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-1.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - void bar (void); int toto() diff --git a/gcc/testsuite/gcc.dg/graphite/scop-10.c b/gcc/testsuite/gcc.dg/graphite/scop-10.c index 8aff2c74302..139f4c11494 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-10.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-10.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - void bar (void); int toto() diff --git a/gcc/testsuite/gcc.dg/graphite/scop-11.c b/gcc/testsuite/gcc.dg/graphite/scop-11.c index e5a0fdb3904..544b36bd744 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-11.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-11.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - void bar (); int toto() diff --git a/gcc/testsuite/gcc.dg/graphite/scop-12.c b/gcc/testsuite/gcc.dg/graphite/scop-12.c index 0c130330ccd..71d34b1db07 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-12.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-12.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - void bar (); int toto() diff --git a/gcc/testsuite/gcc.dg/graphite/scop-13.c b/gcc/testsuite/gcc.dg/graphite/scop-13.c index aa55e10f3f4..b2ca5b4008f 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-13.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-13.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - void bar (); int toto() diff --git a/gcc/testsuite/gcc.dg/graphite/scop-14.c b/gcc/testsuite/gcc.dg/graphite/scop-14.c index a707b01d450..867e293d649 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-14.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-14.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - void bar (); int toto() diff --git a/gcc/testsuite/gcc.dg/graphite/scop-15.c b/gcc/testsuite/gcc.dg/graphite/scop-15.c index 9324631e2fd..6b2c2bdc88f 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-15.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-15.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - # define EXTERN(type, array) extern type array[] typedef unsigned char uch; typedef unsigned short ush; diff --git a/gcc/testsuite/gcc.dg/graphite/scop-16.c b/gcc/testsuite/gcc.dg/graphite/scop-16.c index d0b32f63973..d465d953b26 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-16.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-16.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - #define N 10000 void foo (int); int test () diff --git a/gcc/testsuite/gcc.dg/graphite/scop-17.c b/gcc/testsuite/gcc.dg/graphite/scop-17.c index c2fec3fccaf..dd7bdadc4e8 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-17.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-17.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - #define N 10000 void foo (int); int test () diff --git a/gcc/testsuite/gcc.dg/graphite/scop-18.c b/gcc/testsuite/gcc.dg/graphite/scop-18.c index 6264116e114..7d56cb74279 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-18.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-18.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - #define N 24 #define M 1000 diff --git a/gcc/testsuite/gcc.dg/graphite/scop-19.c b/gcc/testsuite/gcc.dg/graphite/scop-19.c index 3ad49971bc0..cfbf401642e 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-19.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-19.c @@ -1,4 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ typedef unsigned int __uint32_t; typedef __uint32_t __size_t; typedef __size_t size_t; diff --git a/gcc/testsuite/gcc.dg/graphite/scop-2.c b/gcc/testsuite/gcc.dg/graphite/scop-2.c index cf25dcdaf09..9e494f4d006 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-2.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-2.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - void bar (void); int toto() diff --git a/gcc/testsuite/gcc.dg/graphite/scop-20.c b/gcc/testsuite/gcc.dg/graphite/scop-20.c new file mode 100644 index 00000000000..6e71df3f0db --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/scop-20.c @@ -0,0 +1,27 @@ +void bar (void); + +int toto() +{ + int i, j, k; + int a[100][100]; + int b[100]; + + for (i = 1; i < 100; i++) + { + for (j = 1; j < 100; j += i) + for (k = 1; k < 100; k++) + a[j][k] = a[j+1][i-1] + 2; + + b[i] = b[i-1] + 2; + + for (j = 1; j < 100; j++) + a[j][i] = a[j+1][i-1] + 2; + + b[i] = b[i-1] + 2; + } + + return a[3][5] + b[1]; +} + +/* { dg-final { scan-tree-dump-times "number of SCoPs: 2" 1 "graphite"} } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/scop-21.c b/gcc/testsuite/gcc.dg/graphite/scop-21.c new file mode 100644 index 00000000000..5e3bce2da32 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/scop-21.c @@ -0,0 +1,31 @@ +#define N 10000 +void foo (int); +int test () +{ + int a[N]; + unsigned i; + + for (i = 0; i < N; i++) + { + a[i] = i + 12; + + if (i == 40) + a[i] = i; + else + a[i] = i+1; + + + a[i] = i + 12; + a[i] = a[i+1]; + a[i] += a[i+2]; + a[i] += a[i+3]; + a[i] += a[i+4]; + a[i] += a[i+5]; + a[i] += a[i+6]; + + } + + return a[20]; +} +/* { dg-final { scan-tree-dump-times "number of SCoPs: 1" 1 "graphite"} } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/scop-3.c b/gcc/testsuite/gcc.dg/graphite/scop-3.c index 1789e6b6c5a..e20bfdcb34b 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-3.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-3.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - int toto() { int i, j, k; @@ -26,5 +24,5 @@ int toto() return a[3][5] + b[1]; } -/* { dg-final { scan-tree-dump-times "number of SCoPs: 3" 1 "graphite"} } */ +/* { dg-final { scan-tree-dump-times "number of SCoPs: 1" 1 "graphite"} } */ /* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/scop-4.c b/gcc/testsuite/gcc.dg/graphite/scop-4.c index 515c53ad592..4ab2d07f48d 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-4.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-4.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - void bar (); int toto() diff --git a/gcc/testsuite/gcc.dg/graphite/scop-5.c b/gcc/testsuite/gcc.dg/graphite/scop-5.c index 697a28ea168..4f4b45b4914 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-5.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-5.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - void bar (); int toto() diff --git a/gcc/testsuite/gcc.dg/graphite/scop-6.c b/gcc/testsuite/gcc.dg/graphite/scop-6.c index d2623204735..df208acb201 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-6.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-6.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - void bar (void); int toto() diff --git a/gcc/testsuite/gcc.dg/graphite/scop-7.c b/gcc/testsuite/gcc.dg/graphite/scop-7.c index 1187ce104ec..c02748fa71a 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-7.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-7.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - void bar (void); int toto() diff --git a/gcc/testsuite/gcc.dg/graphite/scop-8.c b/gcc/testsuite/gcc.dg/graphite/scop-8.c index 491ad372feb..3f14e347a51 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-8.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-8.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - int bar (void); int toto() diff --git a/gcc/testsuite/gcc.dg/graphite/scop-9.c b/gcc/testsuite/gcc.dg/graphite/scop-9.c index 871b86b8bd4..a803d921790 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-9.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-9.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - void bar (void); int toto() diff --git a/gcc/testsuite/gcc.dg/graphite/scop-matmult.c b/gcc/testsuite/gcc.dg/graphite/scop-matmult.c index 61a5be1fd21..2d2dce3c160 100644 --- a/gcc/testsuite/gcc.dg/graphite/scop-matmult.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-matmult.c @@ -1,5 +1,3 @@ -/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */ - float A[1000][1000], B[1000][1000], C[1000][1000]; /* Multiply two n x n matrices A and B and store the result in C. */ @@ -16,5 +14,5 @@ void matmult (int n) /* This one fails because the number of iterations cannot be determined anymore for the outermost loop. */ -/* { dg-final { scan-tree-dump-times "number of SCoPs: 1" 1 "graphite" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "number of SCoPs: 1" 1 "graphite" } } */ /* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/optimize-bswapdi-1.c b/gcc/testsuite/gcc.dg/optimize-bswapdi-1.c index 449dc19f765..a6aea4a7846 100644 --- a/gcc/testsuite/gcc.dg/optimize-bswapdi-1.c +++ b/gcc/testsuite/gcc.dg/optimize-bswapdi-1.c @@ -1,4 +1,4 @@ -/* { dg-do compile { target alpha*-*-* ia64*-*-* x86_64-*-* s390x-*-* } } */ +/* { dg-do compile { target alpha*-*-* ia64*-*-* x86_64-*-* s390x-*-* powerpc*-*-* rs6000-*-* } } */ /* { dg-require-effective-target stdint_types } */ /* { dg-require-effective-target lp64 } */ /* { dg-options "-O2 -fdump-tree-bswap" } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c index 04f202835df..2ba1ee047f1 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c @@ -17,5 +17,5 @@ void xxx (void) /* Store motion may be applied to the assignment to a[k], since sinf cannot read nor write the memory. */ -/* { dg-final { scan-tree-dump-times "Moving statement" 1 "lim" } } */ -/* { dg-final { cleanup-tree-dump "lim" } } */ +/* { dg-final { scan-tree-dump-times "Moving statement" 1 "lim1" } } */ +/* { dg-final { cleanup-tree-dump "lim\[1-2\]" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-32.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-32.c index 945ee2fcb8e..3a92a08f8da 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-32.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-32.c @@ -42,5 +42,5 @@ void test3(struct a *A) } } -/* { dg-final { scan-tree-dump-times "Executing store motion of" 3 "lim" } } */ -/* { dg-final { cleanup-tree-dump "lim" } } */ +/* { dg-final { scan-tree-dump-times "Executing store motion of" 3 "lim1" } } */ +/* { dg-final { cleanup-tree-dump "lim\[1-2\]" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-33.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-33.c index 6b9b67f3e33..3ee4e3ce04d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-33.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-33.c @@ -36,5 +36,5 @@ void test5(struct a *A, unsigned b) } } -/* { dg-final { scan-tree-dump-times "Executing store motion of" 4 "lim" { xfail lp64 } } } */ -/* { dg-final { cleanup-tree-dump "lim" } } */ +/* { dg-final { scan-tree-dump-times "Executing store motion of" 4 "lim1" { xfail lp64 } } } */ +/* { dg-final { cleanup-tree-dump "lim\[1-2\]" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-34.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-34.c index 4a0d1eaad56..5da804f8b89 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-34.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-34.c @@ -17,5 +17,5 @@ void f (int n) } -/* { dg-final { scan-tree-dump-times "Executing store motion of r" 6 "lim" } } */ -/* { dg-final { cleanup-tree-dump "lim" } } */ +/* { dg-final { scan-tree-dump-times "Executing store motion of r" 6 "lim1" } } */ +/* { dg-final { cleanup-tree-dump "lim\[1-2\]" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-35.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-35.c index e1bdde24049..4716e962586 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-35.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-35.c @@ -60,6 +60,6 @@ void test4(struct a *A, unsigned long b) } } /* long index not hoisted for avr target PR 36561 */ -/* { dg-final { scan-tree-dump-times "Executing store motion of" 8 "lim" { xfail { "avr-*-*" } } } } */ -/* { dg-final { scan-tree-dump-times "Executing store motion of" 6 "lim" { target { "avr-*-*" } } } } */ -/* { dg-final { cleanup-tree-dump "lim" } } */ +/* { dg-final { scan-tree-dump-times "Executing store motion of" 8 "lim1" { xfail { "avr-*-*" } } } } */ +/* { dg-final { scan-tree-dump-times "Executing store motion of" 6 "lim1" { target { "avr-*-*" } } } } */ +/* { dg-final { cleanup-tree-dump "lim\[1-2\]" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-7.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-7.c index a4597b196d7..e9e8d7d23ac 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-7.c @@ -31,5 +31,5 @@ int xxx (void) Calls to cst_fun2 and pure_fun2 should not be, since calling with k = 0 may be invalid. */ -/* { dg-final { scan-tree-dump-times "Moving statement" 3 "lim" } } */ -/* { dg-final { cleanup-tree-dump "lim" } } */ +/* { dg-final { scan-tree-dump-times "Moving statement" 3 "lim1" } } */ +/* { dg-final { cleanup-tree-dump "lim\[1-2\]" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23109.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23109.c index e60b2f09f10..39add724e89 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr23109.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23109.c @@ -29,8 +29,8 @@ int main() /* LIM only performs the transformation in the no-trapping-math case. In the future we will do it for trapping-math as well in recip, check that this is not wrongly optimized. */ -/* { dg-final { scan-tree-dump-not "reciptmp" "lim" } } */ +/* { dg-final { scan-tree-dump-not "reciptmp" "lim1" } } */ /* { dg-final { scan-tree-dump-not "reciptmp" "recip" } } */ /* { dg-final { cleanup-tree-dump "recip" } } */ -/* { dg-final { cleanup-tree-dump "lim" } } */ +/* { dg-final { cleanup-tree-dump "lim\[1-2\]" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/restrict-2.c b/gcc/testsuite/gcc.dg/tree-ssa/restrict-2.c index b76ad98fa88..ec824653d5f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/restrict-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/restrict-2.c @@ -10,5 +10,5 @@ void foo (float * __restrict__ a, float * __restrict__ b, int n, int j) /* We should move the RHS of the store out of the loop. */ -/* { dg-final { scan-tree-dump-times "Moving statement" 11 "lim" } } */ -/* { dg-final { cleanup-tree-dump "lim" } } */ +/* { dg-final { scan-tree-dump-times "Moving statement" 11 "lim1" } } */ +/* { dg-final { cleanup-tree-dump "lim\[1-2\]" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/restrict-3.c b/gcc/testsuite/gcc.dg/tree-ssa/restrict-3.c index 08faafada25..90f62aa4dfc 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/restrict-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/restrict-3.c @@ -14,5 +14,5 @@ void f(int * __restrict__ r, /* We should apply store motion to the store to *r. */ -/* { dg-final { scan-tree-dump "Executing store motion of \\\*r" "lim" } } */ -/* { dg-final { cleanup-tree-dump "lim" } } */ +/* { dg-final { scan-tree-dump "Executing store motion of \\\*r" "lim1" } } */ +/* { dg-final { cleanup-tree-dump "lim\[1-2\]" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-1.c index db36ff02cb2..aa40d443bc7 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-1.c @@ -18,5 +18,5 @@ quantum_toffoli (int control1, int control2, int target, } } -/* { dg-final { scan-tree-dump-times "1 <<" 3 "lim" } } */ -/* { dg-final { cleanup-tree-dump "lim" } } */ +/* { dg-final { scan-tree-dump-times "1 <<" 3 "lim1" } } */ +/* { dg-final { cleanup-tree-dump "lim\[1-2\]" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-2.c index 7b18b1c0550..9274261cb21 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-2.c @@ -18,5 +18,5 @@ int size) } } -/* { dg-final { scan-tree-dump-times "1 <<" 3 "lim" } } */ -/* { dg-final { cleanup-tree-dump "lim" } } */ +/* { dg-final { scan-tree-dump-times "1 <<" 3 "lim1" } } */ +/* { dg-final { cleanup-tree-dump "lim\[1-2\]" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-3.c index 91956017898..85800588dc2 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-3.c @@ -9,6 +9,6 @@ void foo(int n) global.y += global.x*global.x; } -/* { dg-final { scan-tree-dump "Executing store motion of global.y" "lim" } } */ -/* { dg-final { scan-tree-dump "Moving statement.*global.x.*out of loop 1" "lim" } } */ -/* { dg-final { cleanup-tree-dump "lim" } } */ +/* { dg-final { scan-tree-dump "Executing store motion of global.y" "lim1" } } */ +/* { dg-final { scan-tree-dump "Moving statement.*global.x.*out of loop 1" "lim1" } } */ +/* { dg-final { cleanup-tree-dump "lim\[1-2\]" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-6.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-6.c index 0da57aa087d..e29f50c7117 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-6.c @@ -10,5 +10,5 @@ void foo(void) y[j] = y[j] + a[i][j] * x[i]; } -/* { dg-final { scan-tree-dump "Executing store motion of y" "lim" } } */ -/* { dg-final { cleanup-tree-dump "lim" } } */ +/* { dg-final { scan-tree-dump "Executing store motion of y" "lim1" } } */ +/* { dg-final { cleanup-tree-dump "lim\[1-2\]" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/structopt-1.c b/gcc/testsuite/gcc.dg/tree-ssa/structopt-1.c index bc69c4fe0d7..75183052e4b 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/structopt-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/structopt-1.c @@ -10,6 +10,6 @@ int foo() { global.y += global.x*global.x; } -/* { dg-final { scan-tree-dump-times "Executing store motion of global.y" 1 "lim" } } */ +/* { dg-final { scan-tree-dump-times "Executing store motion of global.y" 1 "lim1" } } */ /* XXX: We should also check for the load motion of global.x, but there is no easy way to do this. */ -/* { dg-final { cleanup-tree-dump "lim" } } */ +/* { dg-final { cleanup-tree-dump "lim\[1-2\]" } } */ diff --git a/gcc/testsuite/gcc.dg/ucnid-11.c b/gcc/testsuite/gcc.dg/ucnid-11.c index b4063306857..056017ee988 100644 --- a/gcc/testsuite/gcc.dg/ucnid-11.c +++ b/gcc/testsuite/gcc.dg/ucnid-11.c @@ -1,5 +1,6 @@ /* { dg-do run } */ /* { dg-xfail-if "" { powerpc-ibm-aix* *-*-solaris2.* } { "*" } { "" } } */ +/* { dg-skip-if "-fdata-sections not supported" { { hppa*-*-hpux* } && { ! hppa*64*-*-* } } { "*" } { "" } } */ /* { dg-options "-std=c99 -fextended-identifiers -fdata-sections" } */ #include "ucnid-3.c" diff --git a/gcc/testsuite/gcc.dg/ucnid-12.c b/gcc/testsuite/gcc.dg/ucnid-12.c index 6c8789236b0..3d84ad0d3e0 100644 --- a/gcc/testsuite/gcc.dg/ucnid-12.c +++ b/gcc/testsuite/gcc.dg/ucnid-12.c @@ -1,5 +1,6 @@ /* { dg-do run } */ /* { dg-xfail-if "" { powerpc-ibm-aix* *-*-solaris2.* } { "*" } { "" } } */ +/* { dg-skip-if "-ffunction-sections not supported" { { hppa*-*-hpux* } && { ! hppa*64*-*-* } } { "*" } { "" } } */ /* { dg-options "-std=c99 -fextended-identifiers -ffunction-sections" } */ #include "ucnid-4.c" diff --git a/gcc/testsuite/gcc.dg/uninit-6-O0.c b/gcc/testsuite/gcc.dg/uninit-6-O0.c index f4588305ffa..e3fefe5e1c5 100644 --- a/gcc/testsuite/gcc.dg/uninit-6-O0.c +++ b/gcc/testsuite/gcc.dg/uninit-6-O0.c @@ -39,7 +39,7 @@ make_something(int a, int b, int c) rv = malloc (sizeof (struct tree)); rv->car = 0; - APPEND(rv, field, INTEGER_T, a); /* { dg-bogus "field" "uninitialized variable warning" } */ + APPEND(rv, field, INTEGER_T, a); /* { dg-bogus "field" "uninitialized variable warning" { xfail *-*-* } } */ APPEND(rv, field, PTR_T, b); APPEND(rv, field, INTEGER_T, c); diff --git a/gcc/testsuite/gcc.dg/uninit-6.c b/gcc/testsuite/gcc.dg/uninit-6.c index 009e124fccf..b0f2083ab4b 100644 --- a/gcc/testsuite/gcc.dg/uninit-6.c +++ b/gcc/testsuite/gcc.dg/uninit-6.c @@ -39,7 +39,7 @@ make_something(int a, int b, int c) rv = malloc (sizeof (struct tree)); rv->car = 0; - APPEND(rv, field, INTEGER_T, a); /* { dg-bogus "field" "uninitialized variable warning" } */ + APPEND(rv, field, INTEGER_T, a); /* { dg-bogus "field" "uninitialized variable warning" { xfail *-*-* } } */ APPEND(rv, field, PTR_T, b); APPEND(rv, field, INTEGER_T, c); diff --git a/gcc/testsuite/gcc.dg/uninit-pr40943.c b/gcc/testsuite/gcc.dg/uninit-pr40943.c new file mode 100644 index 00000000000..2b6e9131cb1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr40943.c @@ -0,0 +1,10 @@ +/* PR middle-end/40943 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wuninitialized" } */ + +void +foo (void) +{ + int *p; + *p = 3; /* { dg-warning "is used uninitialized" } */ +} diff --git a/gcc/testsuite/gcc.dg/vect/dump-tree-dceloop-pr26359.c b/gcc/testsuite/gcc.dg/vect/dump-tree-dceloop-pr26359.c index ea9b3837c90..ae7aea25ebd 100644 --- a/gcc/testsuite/gcc.dg/vect/dump-tree-dceloop-pr26359.c +++ b/gcc/testsuite/gcc.dg/vect/dump-tree-dceloop-pr26359.c @@ -11,6 +11,6 @@ foo () { } } -/* { dg-final { scan-tree-dump-times "Deleting : vect_" 0 "dceloop2" } } */ -/* { dg-final { cleanup-tree-dump "dceloop\[1-2\]" } } */ +/* { dg-final { scan-tree-dump-times "Deleting : vect_" 0 "dceloop3" } } */ +/* { dg-final { cleanup-tree-dump "dceloop\[1-3\]" } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vector-4.c b/gcc/testsuite/gcc.dg/vector-4.c index 7964a881f4a..9fa60ded8d1 100644 --- a/gcc/testsuite/gcc.dg/vector-4.c +++ b/gcc/testsuite/gcc.dg/vector-4.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-options "-fno-common" { target { { hppa*-*-hpux* } && { ! hppa*64*-*-* } } } } */ #define vector __attribute__((vector_size(4*sizeof(int)) )) vector int a, b, c; diff --git a/gcc/testsuite/gcc.dg/vmx/vmx.exp b/gcc/testsuite/gcc.dg/vmx/vmx.exp index 8a842e12f5d..85c88d8a392 100644 --- a/gcc/testsuite/gcc.dg/vmx/vmx.exp +++ b/gcc/testsuite/gcc.dg/vmx/vmx.exp @@ -31,7 +31,7 @@ if {![istarget powerpc*-*-*] # nothing but extensions. global DEFAULT_VMXCFLAGS if ![info exists DEFAULT_VMXCFLAGS] then { - set DEFAULT_VMXCFLAGS "-maltivec -mabi=altivec -std=gnu99" + set DEFAULT_VMXCFLAGS "-maltivec -mabi=altivec -std=gnu99 -mno-vsx" } # If the target system supports AltiVec instructions, the default action diff --git a/gcc/testsuite/gcc.target/arm/neon/polytypes.c b/gcc/testsuite/gcc.target/arm/neon/polytypes.c index 12e9b0a7f6a..4fa3eac086c 100644 --- a/gcc/testsuite/gcc.target/arm/neon/polytypes.c +++ b/gcc/testsuite/gcc.target/arm/neon/polytypes.c @@ -45,4 +45,4 @@ void foo () u128_16 (v128_16); /* { dg-error "incompatible type for argument 1 of 'u128_16'" } */ p128_16 (v128_16); } - +/* { dg-message "note: expected '\[^'\n\]*' but argument is of type '\[^'\n\]*'" "note: expected" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.target/mips/ext-3.c b/gcc/testsuite/gcc.target/mips/ext-3.c index 557a8bc574e..acdbbc9a413 100644 --- a/gcc/testsuite/gcc.target/mips/ext-3.c +++ b/gcc/testsuite/gcc.target/mips/ext-3.c @@ -4,7 +4,7 @@ /* { dg-final { scan-assembler "\tdext\t" } } */ /* { dg-final { scan-assembler-not "sll" } } */ -unsigned long long +NOMIPS16 unsigned long long f (unsigned *i) { unsigned j = *i; diff --git a/gcc/testsuite/gcc.target/mips/ext-4.c b/gcc/testsuite/gcc.target/mips/ext-4.c new file mode 100644 index 00000000000..f3d2ad92aa3 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/ext-4.c @@ -0,0 +1,11 @@ +/* For MIPS64r2 use DEXT rather than DSLL/DSRL for clear_upper32. */ +/* { dg-do compile } */ +/* { dg-options "-O isa_rev>=2 -mgp64" } */ +/* { dg-final { scan-assembler "\tdext\t" } } */ +/* { dg-final { scan-assembler-not "sll" } } */ + +NOMIPS16 unsigned long long +f (unsigned long long i) +{ + return i & 0xffffffffull; +} diff --git a/gcc/testsuite/gcc.target/mips/interrupt_handler.c b/gcc/testsuite/gcc.target/mips/interrupt_handler.c index 35ee1d20614..073c772ae40 100644 --- a/gcc/testsuite/gcc.target/mips/interrupt_handler.c +++ b/gcc/testsuite/gcc.target/mips/interrupt_handler.c @@ -4,20 +4,20 @@ void f () { } -void __attribute__ ((interrupt)) v0 () { } -void __attribute__ ((interrupt, use_shadow_register_set)) v1 () { } -void __attribute__ ((interrupt, keep_interrupts_masked)) v2 () { } -void __attribute__ ((interrupt, use_debug_exception_return)) v3 () { } -void __attribute__ ((interrupt, use_shadow_register_set, keep_interrupts_masked)) v4 () { } -void __attribute__ ((interrupt, use_shadow_register_set, use_debug_exception_return)) v5 () { } -void __attribute__ ((interrupt, keep_interrupts_masked, use_debug_exception_return)) v6 () { } -void __attribute__ ((interrupt, use_shadow_register_set, keep_interrupts_masked, use_debug_exception_return)) v7 () { } +NOMIPS16 void __attribute__ ((interrupt)) v0 () { } +NOMIPS16 void __attribute__ ((interrupt, use_shadow_register_set)) v1 () { } +NOMIPS16 void __attribute__ ((interrupt, keep_interrupts_masked)) v2 () { } +NOMIPS16 void __attribute__ ((interrupt, use_debug_exception_return)) v3 () { } +NOMIPS16 void __attribute__ ((interrupt, use_shadow_register_set, keep_interrupts_masked)) v4 () { } +NOMIPS16 void __attribute__ ((interrupt, use_shadow_register_set, use_debug_exception_return)) v5 () { } +NOMIPS16 void __attribute__ ((interrupt, keep_interrupts_masked, use_debug_exception_return)) v6 () { } +NOMIPS16 void __attribute__ ((interrupt, use_shadow_register_set, keep_interrupts_masked, use_debug_exception_return)) v7 () { } -void __attribute__ ((interrupt)) w0 () { t(); } -void __attribute__ ((interrupt, use_shadow_register_set)) w1 () { t(); } -void __attribute__ ((interrupt, keep_interrupts_masked)) w2 () { t(); } -void __attribute__ ((interrupt, use_debug_exception_return)) w3 () { t(); } -void __attribute__ ((interrupt, use_shadow_register_set, keep_interrupts_masked)) w4 () { t(); } -void __attribute__ ((interrupt, use_shadow_register_set, use_debug_exception_return)) w5 () { t(); } -void __attribute__ ((interrupt, keep_interrupts_masked, use_debug_exception_return)) w6 () { t(); } -void __attribute__ ((interrupt, use_shadow_register_set, keep_interrupts_masked, use_debug_exception_return)) w7 () { t(); } +NOMIPS16 void __attribute__ ((interrupt)) w0 () { t(); } +NOMIPS16 void __attribute__ ((interrupt, use_shadow_register_set)) w1 () { t(); } +NOMIPS16 void __attribute__ ((interrupt, keep_interrupts_masked)) w2 () { t(); } +NOMIPS16 void __attribute__ ((interrupt, use_debug_exception_return)) w3 () { t(); } +NOMIPS16 void __attribute__ ((interrupt, use_shadow_register_set, keep_interrupts_masked)) w4 () { t(); } +NOMIPS16 void __attribute__ ((interrupt, use_shadow_register_set, use_debug_exception_return)) w5 () { t(); } +NOMIPS16 void __attribute__ ((interrupt, keep_interrupts_masked, use_debug_exception_return)) w6 () { t(); } +NOMIPS16 void __attribute__ ((interrupt, use_shadow_register_set, keep_interrupts_masked, use_debug_exception_return)) w7 () { t(); } diff --git a/gcc/testsuite/gcc.target/mips/truncate-4.c b/gcc/testsuite/gcc.target/mips/truncate-4.c index 2958be8de1e..4c783681ab2 100644 --- a/gcc/testsuite/gcc.target/mips/truncate-4.c +++ b/gcc/testsuite/gcc.target/mips/truncate-4.c @@ -2,7 +2,7 @@ /* { dg-options "-O -mgp64" } */ /* { dg-final { scan-assembler-not "\tsll\t" } } */ -unsigned long long +NOMIPS16 unsigned long long f (unsigned long long s) { unsigned u = s & 0xfff; diff --git a/gcc/testsuite/gcc.target/mips/truncate-5.c b/gcc/testsuite/gcc.target/mips/truncate-5.c index 046ef80c453..6cdb7f71e7f 100644 --- a/gcc/testsuite/gcc.target/mips/truncate-5.c +++ b/gcc/testsuite/gcc.target/mips/truncate-5.c @@ -8,6 +8,7 @@ struct s unsigned a:5; }; +NOMIPS16 void f (struct s *s, unsigned long long a) { s->a = a & 0x3; diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-32.c b/gcc/testsuite/gcc.target/powerpc/altivec-32.c new file mode 100644 index 00000000000..83105f89a50 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/altivec-32.c @@ -0,0 +1,59 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-O2 -ftree-vectorize -mcpu=power6 -m64 -maltivec" } */ +/* { dg-final { scan-assembler "vsel" } } */ +/* { dg-final { scan-assembler "vrfim" } } */ +/* { dg-final { scan-assembler "vrfip" } } */ +/* { dg-final { scan-assembler "vrfiz" } } */ + +#ifndef SIZE +#define SIZE 1024 +#endif + +float a[SIZE] __attribute__((__aligned__(32))); +float b[SIZE] __attribute__((__aligned__(32))); +float c[SIZE] __attribute__((__aligned__(32))); +float d[SIZE] __attribute__((__aligned__(32))); +float e[SIZE] __attribute__((__aligned__(32))); + +extern float floorf (float); +extern float ceilf (float); +extern float truncf (float); +extern float copysignf (float, float); + +void +vector_floor (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = floorf (b[i]); +} + +void +vector_ceil (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = ceilf (b[i]); +} + +void +vector_trunc (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = truncf (b[i]); +} + +void +vector_copysign (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = copysignf (b[i], c[i]); +} diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-6.c b/gcc/testsuite/gcc.target/powerpc/altivec-6.c index dc115f9422d..51d411688fb 100644 --- a/gcc/testsuite/gcc.target/powerpc/altivec-6.c +++ b/gcc/testsuite/gcc.target/powerpc/altivec-6.c @@ -5,7 +5,7 @@ #include <altivec.h> /* These denote "generic" GCC vectors. */ -static int __attribute__((vector_size(16))) x, y; +static int __attribute__((vector_size(16))) x, y, z; static vector signed int i,j; static vector signed short s,t; @@ -21,7 +21,7 @@ static int int1, int2; void b() { - vec_add (x, y); + z = vec_add (x, y); /* Make sure the predicates accept correct argument types. */ diff --git a/gcc/testsuite/gcc.target/powerpc/bswap-run.c b/gcc/testsuite/gcc.target/powerpc/bswap-run.c new file mode 100644 index 00000000000..484908a8167 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/bswap-run.c @@ -0,0 +1,102 @@ +/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-options "-O2 -std=gnu99" } */ + +extern void abort (void); + +static unsigned char bytes[] = { 0, 1, 2, 0x80, 0xff }; + +unsigned short b16a (unsigned short *p) { return __builtin_bswap16 (*p); } +void b16b (unsigned short *p, unsigned short a) { *p = __builtin_bswap16 (a); } +int b16c (unsigned short a) { return __builtin_bswap16 (a); } + +unsigned int b32a (unsigned int *p) { return __builtin_bswap32 (*p); } +void b32b (unsigned int *p, unsigned int a) { *p = __builtin_bswap32 (a); } +static unsigned int b32c (unsigned int a) { return __builtin_bswap32 (a); } + +unsigned long long b64a (unsigned long long *p) { return __builtin_bswap64 (*p); } +void b64b (unsigned long long *p, unsigned long long a) { *p = __builtin_bswap64 (a); } +unsigned long long b64c (unsigned long long a) { return __builtin_bswap64 (a); } + +int +main (void) +{ + unsigned i1, i2, i3, i4, i5; + unsigned b1, b2, b3, b4, b5; + unsigned short b16_inp, b16_exp, b16_var; + unsigned int b32_inp, b32_exp, b32_var; + unsigned long long b64_inp, b64_exp, b64_var; + + for (i1 = 0; i1 < sizeof (bytes); i1++) + { + b1 = bytes[i1]; + for (i2 = 0; i2 < sizeof (bytes); i2++) + { + b2 = bytes[i2]; + b16_inp = (b1 << 8) | b2; + b16_exp = (b2 << 8) | b1; + + if (b16a (&b16_inp) != b16_exp) + abort (); + + b16b (&b16_var, b16_inp); + if (b16_var != b16_exp) + abort (); + + if (b16c (b16_inp) != b16_exp) + abort (); + + for (i3 = 0; i3 < sizeof (bytes); i3++) + { + b3 = bytes[i3]; + for (i4 = 0; i4 < sizeof (bytes); i4++) + { + b4 = bytes[i4]; + b32_inp = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; + b32_exp = (b4 << 24) | (b3 << 16) | (b2 << 8) | b1; + + if (b32a (&b32_inp) != b32_exp) + abort (); + + b32b (&b32_var, b32_inp); + if (b32_var != b32_exp) + abort (); + + if (b32c (b32_inp) != b32_exp) + abort (); + + for (i5 = 0; i5 < sizeof (bytes); i5++) + { + b5 = bytes[i5]; + b64_inp = (((unsigned long long)b32_inp) << 32) | b5; + b64_exp = (((unsigned long long)b5) << 56) | b32_exp; + + if (b64a (&b64_inp) != b64_exp) + abort (); + + b64b (&b64_var, b64_inp); + if (b64_var != b64_exp) + abort (); + + if (b64c (b64_inp) != b64_exp) + abort (); + + b64_inp = (((unsigned long long)b5) << 56) | b32_inp; + b64_exp = (((unsigned long long)b32_exp) << 32) | b5; + + if (b64a (&b64_inp) != b64_exp) + abort (); + + b64b (&b64_var, b64_inp); + if (b64_var != b64_exp) + abort (); + + if (b64c (b64_inp) != b64_exp) + abort (); + } + } + } + } + } + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/bswap16.c b/gcc/testsuite/gcc.target/powerpc/bswap16.c new file mode 100644 index 00000000000..5eea4f77491 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/bswap16.c @@ -0,0 +1,8 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler "lhbrx" } } */ +/* { dg-final { scan-assembler "sthbrx" } } */ + +unsigned short us; +unsigned int load_bswap16 (unsigned short *p) { return __builtin_bswap16 (*p); } +void store_bswap16 (unsigned int a) { us = __builtin_bswap16 (a); } diff --git a/gcc/testsuite/gcc.target/powerpc/bswap32.c b/gcc/testsuite/gcc.target/powerpc/bswap32.c new file mode 100644 index 00000000000..1b1e189aafa --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/bswap32.c @@ -0,0 +1,8 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler "lwbrx" } } */ +/* { dg-final { scan-assembler "stwbrx" } } */ + +unsigned int ui; +unsigned int load_bswap32 (unsigned int *p) { return __builtin_bswap32 (*p); } +void store_bswap32 (unsigned int a) { ui = __builtin_bswap32 (a); } diff --git a/gcc/testsuite/gcc.target/powerpc/bswap64-1.c b/gcc/testsuite/gcc.target/powerpc/bswap64-1.c new file mode 100644 index 00000000000..480e1cd7cfc --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/bswap64-1.c @@ -0,0 +1,9 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-options "-O2 -mno-popcntd -mcpu=power5" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-final { scan-assembler "lwbrx" } } */ +/* { dg-final { scan-assembler "stwbrx" } } */ + +unsigned long ul; +unsigned long load_bswap64 (unsigned long *p) { return __builtin_bswap64 (*p); } +void store_bswap64 (unsigned long a) { ul = __builtin_bswap64 (a); } diff --git a/gcc/testsuite/gcc.target/powerpc/bswap64-2.c b/gcc/testsuite/gcc.target/powerpc/bswap64-2.c new file mode 100644 index 00000000000..6c3d8ca0528 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/bswap64-2.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-options "-O2 -mpopcntd" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-final { scan-assembler "ldbrx" } } */ +/* { dg-final { scan-assembler "stdbrx" } } */ + +unsigned long ul; +unsigned long load_bswap64 (unsigned long *p) { return __builtin_bswap64 (*p); } +void store_bswap64 (unsigned long a) { ul = __builtin_bswap64 (a); } diff --git a/gcc/testsuite/gcc.target/powerpc/bswap64-3.c b/gcc/testsuite/gcc.target/powerpc/bswap64-3.c new file mode 100644 index 00000000000..7f1138cf94f --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/bswap64-3.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-options "-O2 -mcpu=cell" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target powerpc_ppu_ok } */ +/* { dg-final { scan-assembler "ldbrx" } } */ +/* { dg-final { scan-assembler "stdbrx" } } */ + +unsigned long ul; +unsigned long load_bswap64 (unsigned long *p) { return __builtin_bswap64 (*p); } +void store_bswap64 (unsigned long a) { ul = __builtin_bswap64 (a); } diff --git a/gcc/testsuite/gcc.target/powerpc/optimize-bswapdi-2.c b/gcc/testsuite/gcc.target/powerpc/optimize-bswapdi-2.c new file mode 100644 index 00000000000..7337e99b1b3 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/optimize-bswapdi-2.c @@ -0,0 +1,36 @@ +/* { dg-require-effective-target stdint_types } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O2 -mcpu=power5" } */ + +/* This is a clone of gcc-dg/optimize-bswapdi-1.c, redone to use load and stores + to test whether lwbrx/stwbrx is generated for normal power systems. */ + +#include <stdint.h> +#define __const_swab64(x) ((uint64_t)( \ + (((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \ + (((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \ + (((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \ + (((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \ + (((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \ + (((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \ + (((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \ + (((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56))) + + +/* This byte swap implementation is used by the Linux kernel and the + GNU C library. */ + +uint64_t +swap64_load (uint64_t *in) +{ + return __const_swab64 (*in); +} + +void +swap64_store (uint64_t *out, uint64_t in) +{ + *out = __const_swab64 (in); +} + +/* { dg-final { scan-assembler-times "lwbrx" 2 } } */ +/* { dg-final { scan-assembler-times "stwbrx" 2 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/optimize-bswapdi-3.c b/gcc/testsuite/gcc.target/powerpc/optimize-bswapdi-3.c new file mode 100644 index 00000000000..9dcd824c6ed --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/optimize-bswapdi-3.c @@ -0,0 +1,36 @@ +/* { dg-require-effective-target stdint_types } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O2 -mcpu=power7" } */ + +/* This is a clone of gcc-dg/optimize-bswapdi-1.c, redone to use load and stores + to test whether ldbrx/stdbrx is generated for power7. */ + +#include <stdint.h> +#define __const_swab64(x) ((uint64_t)( \ + (((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \ + (((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \ + (((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \ + (((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \ + (((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \ + (((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \ + (((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \ + (((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56))) + + +/* This byte swap implementation is used by the Linux kernel and the + GNU C library. */ + +uint64_t +swap64_load (uint64_t *in) +{ + return __const_swab64 (*in); +} + +void +swap64_store (uint64_t *out, uint64_t in) +{ + *out = __const_swab64 (in); +} + +/* { dg-final { scan-assembler "ldbrx" } } */ +/* { dg-final { scan-assembler "stdbrx" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/optimize-bswapsi-2.c b/gcc/testsuite/gcc.target/powerpc/optimize-bswapsi-2.c new file mode 100644 index 00000000000..34cc8236fbc --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/optimize-bswapsi-2.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target stdint_types } */ +/* { dg-options "-O2 -mcpu=power5" } */ + +#include <stdint.h> + +/* This is a clone of gcc-dg/optimize-bswapsi-1.c, redone to use load and stores + to test whether lwbrx/stwbrx is generated for normal power systems. */ + +#define __const_swab32(x) ((uint32_t)( \ + (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ + (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ + (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ + (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24))) + +/* This byte swap implementation is used by the Linux kernel and the + GNU C library. */ + +uint32_t +swap32_a_load (uint32_t *in) +{ + return __const_swab32 (*in); +} + +/* The OpenSSH byte swap implementation. */ +uint32_t +swap32_b_load (uint32_t *in) +{ + uint32_t a; + + a = (*in << 16) | (*in >> 16); + a = ((a & 0x00ff00ff) << 8) | ((a & 0xff00ff00) >> 8); + + return a; +} + +void +swap32_a_store (uint32_t *out, uint32_t in) +{ + *out = __const_swab32 (in); +} + +/* The OpenSSH byte swap implementation. */ +void +swap32_b_store (uint32_t *out, uint32_t in) +{ + uint32_t a; + + a = (in << 16) | (in >> 16); + a = ((a & 0x00ff00ff) << 8) | ((a & 0xff00ff00) >> 8); + + *out = a; +} + +/* { dg-final { scan-assembler-times "lwbrx" 2 } } */ +/* { dg-final { scan-assembler-times "stwbrx" 2 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/popcount-2.c b/gcc/testsuite/gcc.target/powerpc/popcount-2.c new file mode 100644 index 00000000000..7546a3bdf1e --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/popcount-2.c @@ -0,0 +1,9 @@ +/* { dg-do compile { target { ilp32 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-options "-O2 -mcpu=power7 -m32" } */ +/* { dg-final { scan-assembler "popcntw" } } */ + +int foo(int x) +{ + return __builtin_popcount(x); +} diff --git a/gcc/testsuite/gcc.target/powerpc/popcount-3.c b/gcc/testsuite/gcc.target/powerpc/popcount-3.c new file mode 100644 index 00000000000..c803532e6db --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/popcount-3.c @@ -0,0 +1,9 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-options "-O2 -mcpu=power7 -m64" } */ +/* { dg-final { scan-assembler "popcntd" } } */ + +long foo(int x) +{ + return __builtin_popcountl(x); +} diff --git a/gcc/testsuite/gcc.target/powerpc/pr39457.c b/gcc/testsuite/gcc.target/powerpc/pr39457.c new file mode 100644 index 00000000000..22057e51f59 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr39457.c @@ -0,0 +1,56 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-options "-m64 -O2 -mminimal-toc" } */ + +/* PR 39457 -- fix breakage because the compiler ran out of registers and + wanted to stash a floating point value to the LR/CTR register. */ + +/* -O2 -m64 -mminimal-toc */ +typedef struct { void *s; } S; +typedef void (*T1) (void); +typedef void (*T2) (void *, void *, int, void *); +char *fn1 (const char *, ...); +void *fn2 (void); +int fn3 (char *, int); +int fn4 (const void *); +int fn5 (const void *); +long fn6 (void) __attribute__ ((__const__)); +int fn7 (void *, void *, void *); +void *fn8 (void *, long); +void *fn9 (void *, long, const char *, ...); +void *fn10 (void *); +long fn11 (void) __attribute__ ((__const__)); +long fn12 (void *, const char *, T1, T2, void *); +void *fn13 (void *); +long fn14 (void) __attribute__ ((__const__)); +extern void *v1; +extern char *v2; +extern int v3; + +void +foo (void *x, char *z) +{ + void *i1, *i2; + int y; + if (v1) + return; + v1 = fn9 (fn10 (fn2 ()), fn6 (), "x", 0., "y", 0., 0); + y = 520 - (520 - fn4 (x)) / 2; + fn9 (fn8 (v1, fn6 ()), fn6 (), "wig", fn8 (v1, fn14 ()), "x", 18.0, + "y", 16.0, "wid", 80.0, "hi", 500.0, 0); + fn9 (fn10 (v1), fn6 (), "x1", 0., "y1", 0., "x2", 80.0, "y2", + 500.0, "f", fn3 ("fff", 0x0D0DFA00), 0); + fn13 (((S *) fn8 (v1, fn6 ()))->s); + fn12 (fn8 (v1, fn11 ()), "ev", (T1) fn7, 0, fn8 (v1, fn6 ())); + fn9 (fn8 (v1, fn6 ()), fn6 (), "wig", + fn8 (v1, fn14 ()), "x", 111.0, "y", 14.0, "wid", 774.0, "hi", + 500.0, 0); + v1 = fn9 (fn10 (v1), fn6 (), "x1", 0., "y1", 0., "x2", 774.0, "y2", + 500.0, "f", fn3 ("gc", 0x0D0DFA00), 0); + fn1 (z, 0); + i1 = fn9 (fn8 (v1, fn6 ()), fn6 (), "pixbuf", x, "x", + 800 - fn5 (x) / 2, "y", y - fn4 (x), 0); + fn12 (fn8 (i1, fn11 ()), "ev", (T1) fn7, 0, "/ok/"); + fn12 (fn8 (i1, fn11 ()), "ev", (T1) fn7, 0, 0); + i2 = fn9 (fn8 (v1, fn6 ()), fn6 (), "txt", "OK", "fnt", v2, "x", + 800, "y", y - fn4 (x) + 15, "ar", 0, "f", v3, 0); +} diff --git a/gcc/testsuite/gcc.target/powerpc/pr39902-2.c b/gcc/testsuite/gcc.target/powerpc/pr39902-2.c new file mode 100644 index 00000000000..463a36c1bee --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr39902-2.c @@ -0,0 +1,28 @@ +/* Check that simplification "x*(-1)" -> "-x" is not performed for decimal + float types. */ + +/* { dg-do compile { target { powerpc*-*-linux* && powerpc_fprs } } } */ +/* { dg-options "-std=gnu99 -O -mcpu=power6" } */ +/* { dg-final { scan-assembler-not "fneg" } } */ + +extern _Decimal32 a32, b32; +extern _Decimal64 a64, b64; +extern _Decimal128 a128, b128; + +void +foo32 (void) +{ + b32 = a32 * -1.0DF; +} + +void +foo64 (void) +{ + b64 = a64 * -1.0DD; +} + +void +foo128 (void) +{ + b128 = a128 * -1.0DL; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-1.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-1.c new file mode 100644 index 00000000000..42d5b605641 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-1.c @@ -0,0 +1,38 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mcpu=power7" } */ +/* { dg-final { scan-assembler "xvadddp" } } */ +/* { dg-final { scan-assembler "xvsubdp" } } */ +/* { dg-final { scan-assembler "xvmuldp" } } */ +/* { dg-final { scan-assembler "xvmadd" } } */ +/* { dg-final { scan-assembler "xvmsub" } } */ +/* { dg-final { scan-assembler "xvnmadd" } } */ +/* { dg-final { scan-assembler "xvnmsub" } } */ +/* { dg-final { scan-assembler "xvdivdp" } } */ +/* { dg-final { scan-assembler "xvmaxdp" } } */ +/* { dg-final { scan-assembler "xvmindp" } } */ +/* { dg-final { scan-assembler "xvsqrtdp" } } */ +/* { dg-final { scan-assembler "xvrsqrtedp" } } */ +/* { dg-final { scan-assembler "xvabsdp" } } */ +/* { dg-final { scan-assembler "xvnabsdp" } } */ +/* { dg-final { scan-assembler "xvredp" } } */ + +void use_builtins (__vector double *p, __vector double *q, __vector double *r, __vector double *s) +{ + p[0] = __builtin_vsx_xvadddp (q[0], r[0]); + p[1] = __builtin_vsx_xvsubdp (q[1], r[1]); + p[2] = __builtin_vsx_xvmuldp (q[2], r[2]); + p[3] = __builtin_vsx_xvdivdp (q[3], r[3]); + p[4] = __builtin_vsx_xvmaxdp (q[4], r[4]); + p[5] = __builtin_vsx_xvmindp (q[5], r[5]); + p[6] = __builtin_vsx_xvabsdp (q[6]); + p[7] = __builtin_vsx_xvnabsdp (q[7]); + p[8] = __builtin_vsx_xvsqrtdp (q[8]); + p[9] = __builtin_vsx_xvmadddp (q[9], r[9], s[9]); + p[10] = __builtin_vsx_xvmsubdp (q[10], r[10], s[10]); + p[11] = __builtin_vsx_xvnmadddp (q[11], r[11], s[11]); + p[12] = __builtin_vsx_xvnmsubdp (q[12], r[12], s[12]); + p[13] = __builtin_vsx_xvredp (q[13]); + p[14] = __builtin_vsx_xvrsqrtedp (q[14]); +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-2.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-2.c new file mode 100644 index 00000000000..6d883dc90f1 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-2.c @@ -0,0 +1,38 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mcpu=power7" } */ +/* { dg-final { scan-assembler "xvaddsp" } } */ +/* { dg-final { scan-assembler "xvsubsp" } } */ +/* { dg-final { scan-assembler "xvmulsp" } } */ +/* { dg-final { scan-assembler "xvmadd" } } */ +/* { dg-final { scan-assembler "xvmsub" } } */ +/* { dg-final { scan-assembler "xvnmadd" } } */ +/* { dg-final { scan-assembler "xvnmsub" } } */ +/* { dg-final { scan-assembler "xvdivsp" } } */ +/* { dg-final { scan-assembler "xvmaxsp" } } */ +/* { dg-final { scan-assembler "xvminsp" } } */ +/* { dg-final { scan-assembler "xvsqrtsp" } } */ +/* { dg-final { scan-assembler "xvabssp" } } */ +/* { dg-final { scan-assembler "xvnabssp" } } */ +/* { dg-final { scan-assembler "xvresp" } } */ +/* { dg-final { scan-assembler "xvrsqrtesp" } } */ + +void use_builtins (__vector float *p, __vector float *q, __vector float *r, __vector float *s) +{ + p[0] = __builtin_vsx_xvaddsp (q[0], r[0]); + p[1] = __builtin_vsx_xvsubsp (q[1], r[1]); + p[2] = __builtin_vsx_xvmulsp (q[2], r[2]); + p[3] = __builtin_vsx_xvdivsp (q[3], r[3]); + p[4] = __builtin_vsx_xvmaxsp (q[4], r[4]); + p[5] = __builtin_vsx_xvminsp (q[5], r[5]); + p[6] = __builtin_vsx_xvabssp (q[6]); + p[7] = __builtin_vsx_xvnabssp (q[7]); + p[8] = __builtin_vsx_xvsqrtsp (q[8]); + p[9] = __builtin_vsx_xvmaddsp (q[9], r[9], s[9]); + p[10] = __builtin_vsx_xvmsubsp (q[10], r[10], s[10]); + p[11] = __builtin_vsx_xvnmaddsp (q[11], r[11], s[11]); + p[12] = __builtin_vsx_xvnmsubsp (q[12], r[12], s[12]); + p[13] = __builtin_vsx_xvresp (q[13]); + p[14] = __builtin_vsx_xvrsqrtesp (q[14]); +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-3.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-3.c new file mode 100644 index 00000000000..8450920ec0c --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-3.c @@ -0,0 +1,212 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mcpu=power7" } */ +/* { dg-final { scan-assembler "xxsel" } } */ +/* { dg-final { scan-assembler "vperm" } } */ +/* { dg-final { scan-assembler "xvrdpi" } } */ +/* { dg-final { scan-assembler "xvrdpic" } } */ +/* { dg-final { scan-assembler "xvrdpim" } } */ +/* { dg-final { scan-assembler "xvrdpip" } } */ +/* { dg-final { scan-assembler "xvrdpiz" } } */ +/* { dg-final { scan-assembler "xvrspi" } } */ +/* { dg-final { scan-assembler "xvrspic" } } */ +/* { dg-final { scan-assembler "xvrspim" } } */ +/* { dg-final { scan-assembler "xvrspip" } } */ +/* { dg-final { scan-assembler "xvrspiz" } } */ +/* { dg-final { scan-assembler "xsrdpi" } } */ +/* { dg-final { scan-assembler "xsrdpic" } } */ +/* { dg-final { scan-assembler "xsrdpim" } } */ +/* { dg-final { scan-assembler "xsrdpip" } } */ +/* { dg-final { scan-assembler "xsrdpiz" } } */ +/* { dg-final { scan-assembler "xsmaxdp" } } */ +/* { dg-final { scan-assembler "xsmindp" } } */ +/* { dg-final { scan-assembler "xxland" } } */ +/* { dg-final { scan-assembler "xxlandc" } } */ +/* { dg-final { scan-assembler "xxlnor" } } */ +/* { dg-final { scan-assembler "xxlor" } } */ +/* { dg-final { scan-assembler "xxlxor" } } */ +/* { dg-final { scan-assembler "xvcmpeqdp" } } */ +/* { dg-final { scan-assembler "xvcmpgtdp" } } */ +/* { dg-final { scan-assembler "xvcmpgedp" } } */ +/* { dg-final { scan-assembler "xvcmpeqsp" } } */ +/* { dg-final { scan-assembler "xvcmpgtsp" } } */ +/* { dg-final { scan-assembler "xvcmpgesp" } } */ +/* { dg-final { scan-assembler "xxsldwi" } } */ +/* { dg-final { scan-assembler-not "call" } } */ + +extern __vector int si[][4]; +extern __vector short ss[][4]; +extern __vector signed char sc[][4]; +extern __vector float f[][4]; +extern __vector unsigned int ui[][4]; +extern __vector unsigned short us[][4]; +extern __vector unsigned char uc[][4]; +extern __vector __bool int bi[][4]; +extern __vector __bool short bs[][4]; +extern __vector __bool char bc[][4]; +extern __vector __pixel p[][4]; +#ifdef __VSX__ +extern __vector double d[][4]; +extern __vector long sl[][4]; +extern __vector unsigned long ul[][4]; +extern __vector __bool long bl[][4]; +#endif + +int do_sel(void) +{ + int i = 0; + + si[i][0] = __builtin_vsx_xxsel_4si (si[i][1], si[i][2], si[i][3]); i++; + ss[i][0] = __builtin_vsx_xxsel_8hi (ss[i][1], ss[i][2], ss[i][3]); i++; + sc[i][0] = __builtin_vsx_xxsel_16qi (sc[i][1], sc[i][2], sc[i][3]); i++; + f[i][0] = __builtin_vsx_xxsel_4sf (f[i][1], f[i][2], f[i][3]); i++; + d[i][0] = __builtin_vsx_xxsel_2df (d[i][1], d[i][2], d[i][3]); i++; + + si[i][0] = __builtin_vsx_xxsel (si[i][1], si[i][2], bi[i][3]); i++; + ss[i][0] = __builtin_vsx_xxsel (ss[i][1], ss[i][2], bs[i][3]); i++; + sc[i][0] = __builtin_vsx_xxsel (sc[i][1], sc[i][2], bc[i][3]); i++; + f[i][0] = __builtin_vsx_xxsel (f[i][1], f[i][2], bi[i][3]); i++; + d[i][0] = __builtin_vsx_xxsel (d[i][1], d[i][2], bl[i][3]); i++; + + si[i][0] = __builtin_vsx_xxsel (si[i][1], si[i][2], ui[i][3]); i++; + ss[i][0] = __builtin_vsx_xxsel (ss[i][1], ss[i][2], us[i][3]); i++; + sc[i][0] = __builtin_vsx_xxsel (sc[i][1], sc[i][2], uc[i][3]); i++; + f[i][0] = __builtin_vsx_xxsel (f[i][1], f[i][2], ui[i][3]); i++; + d[i][0] = __builtin_vsx_xxsel (d[i][1], d[i][2], ul[i][3]); i++; + + return i; +} + +int do_perm(void) +{ + int i = 0; + + si[i][0] = __builtin_vsx_vperm_4si (si[i][1], si[i][2], uc[i][3]); i++; + ss[i][0] = __builtin_vsx_vperm_8hi (ss[i][1], ss[i][2], uc[i][3]); i++; + sc[i][0] = __builtin_vsx_vperm_16qi (sc[i][1], sc[i][2], uc[i][3]); i++; + f[i][0] = __builtin_vsx_vperm_4sf (f[i][1], f[i][2], uc[i][3]); i++; + d[i][0] = __builtin_vsx_vperm_2df (d[i][1], d[i][2], uc[i][3]); i++; + + si[i][0] = __builtin_vsx_vperm (si[i][1], si[i][2], uc[i][3]); i++; + ss[i][0] = __builtin_vsx_vperm (ss[i][1], ss[i][2], uc[i][3]); i++; + sc[i][0] = __builtin_vsx_vperm (sc[i][1], sc[i][2], uc[i][3]); i++; + f[i][0] = __builtin_vsx_vperm (f[i][1], f[i][2], uc[i][3]); i++; + d[i][0] = __builtin_vsx_vperm (d[i][1], d[i][2], uc[i][3]); i++; + + return i; +} + +int do_xxperm (void) +{ + int i = 0; + + d[i][0] = __builtin_vsx_xxpermdi_2df (d[i][1], d[i][2], 0); i++; + d[i][0] = __builtin_vsx_xxpermdi (d[i][1], d[i][2], 1); i++; + return i; +} + +double x, y; +void do_concat (void) +{ + d[0][0] = __builtin_vsx_concat_2df (x, y); +} + +void do_set (void) +{ + d[0][0] = __builtin_vsx_set_2df (d[0][1], x, 0); + d[1][0] = __builtin_vsx_set_2df (d[1][1], y, 1); +} + +extern double z[][4]; + +int do_math (void) +{ + int i = 0; + + d[i][0] = __builtin_vsx_xvrdpi (d[i][1]); i++; + d[i][0] = __builtin_vsx_xvrdpic (d[i][1]); i++; + d[i][0] = __builtin_vsx_xvrdpim (d[i][1]); i++; + d[i][0] = __builtin_vsx_xvrdpip (d[i][1]); i++; + d[i][0] = __builtin_vsx_xvrdpiz (d[i][1]); i++; + + f[i][0] = __builtin_vsx_xvrspi (f[i][1]); i++; + f[i][0] = __builtin_vsx_xvrspic (f[i][1]); i++; + f[i][0] = __builtin_vsx_xvrspim (f[i][1]); i++; + f[i][0] = __builtin_vsx_xvrspip (f[i][1]); i++; + f[i][0] = __builtin_vsx_xvrspiz (f[i][1]); i++; + + z[i][0] = __builtin_vsx_xsrdpi (z[i][1]); i++; + z[i][0] = __builtin_vsx_xsrdpic (z[i][1]); i++; + z[i][0] = __builtin_vsx_xsrdpim (z[i][1]); i++; + z[i][0] = __builtin_vsx_xsrdpip (z[i][1]); i++; + z[i][0] = __builtin_vsx_xsrdpiz (z[i][1]); i++; + z[i][0] = __builtin_vsx_xsmaxdp (z[i][1], z[i][0]); i++; + z[i][0] = __builtin_vsx_xsmindp (z[i][1], z[i][0]); i++; + return i; +} + +int do_cmp (void) +{ + int i = 0; + + d[i][0] = __builtin_vsx_xvcmpeqdp (d[i][1], d[i][2]); i++; + d[i][0] = __builtin_vsx_xvcmpgtdp (d[i][1], d[i][2]); i++; + d[i][0] = __builtin_vsx_xvcmpgedp (d[i][1], d[i][2]); i++; + + f[i][0] = __builtin_vsx_xvcmpeqsp (f[i][1], f[i][2]); i++; + f[i][0] = __builtin_vsx_xvcmpgtsp (f[i][1], f[i][2]); i++; + f[i][0] = __builtin_vsx_xvcmpgesp (f[i][1], f[i][2]); i++; + return i; +} + +int do_logical (void) +{ + int i = 0; + + si[i][0] = __builtin_vsx_xxland (si[i][1], si[i][2]); i++; + si[i][0] = __builtin_vsx_xxlandc (si[i][1], si[i][2]); i++; + si[i][0] = __builtin_vsx_xxlnor (si[i][1], si[i][2]); i++; + si[i][0] = __builtin_vsx_xxlor (si[i][1], si[i][2]); i++; + si[i][0] = __builtin_vsx_xxlxor (si[i][1], si[i][2]); i++; + + ss[i][0] = __builtin_vsx_xxland (ss[i][1], ss[i][2]); i++; + ss[i][0] = __builtin_vsx_xxlandc (ss[i][1], ss[i][2]); i++; + ss[i][0] = __builtin_vsx_xxlnor (ss[i][1], ss[i][2]); i++; + ss[i][0] = __builtin_vsx_xxlor (ss[i][1], ss[i][2]); i++; + ss[i][0] = __builtin_vsx_xxlxor (ss[i][1], ss[i][2]); i++; + + sc[i][0] = __builtin_vsx_xxland (sc[i][1], sc[i][2]); i++; + sc[i][0] = __builtin_vsx_xxlandc (sc[i][1], sc[i][2]); i++; + sc[i][0] = __builtin_vsx_xxlnor (sc[i][1], sc[i][2]); i++; + sc[i][0] = __builtin_vsx_xxlor (sc[i][1], sc[i][2]); i++; + sc[i][0] = __builtin_vsx_xxlxor (sc[i][1], sc[i][2]); i++; + + d[i][0] = __builtin_vsx_xxland (d[i][1], d[i][2]); i++; + d[i][0] = __builtin_vsx_xxlandc (d[i][1], d[i][2]); i++; + d[i][0] = __builtin_vsx_xxlnor (d[i][1], d[i][2]); i++; + d[i][0] = __builtin_vsx_xxlor (d[i][1], d[i][2]); i++; + d[i][0] = __builtin_vsx_xxlxor (d[i][1], d[i][2]); i++; + + f[i][0] = __builtin_vsx_xxland (f[i][1], f[i][2]); i++; + f[i][0] = __builtin_vsx_xxlandc (f[i][1], f[i][2]); i++; + f[i][0] = __builtin_vsx_xxlnor (f[i][1], f[i][2]); i++; + f[i][0] = __builtin_vsx_xxlor (f[i][1], f[i][2]); i++; + f[i][0] = __builtin_vsx_xxlxor (f[i][1], f[i][2]); i++; + return i; +} + +int do_xxsldwi (void) +{ + int i = 0; + + si[i][0] = __builtin_vsx_xxsldwi (si[i][1], si[i][2], 0); i++; + ss[i][0] = __builtin_vsx_xxsldwi (ss[i][1], ss[i][2], 1); i++; + sc[i][0] = __builtin_vsx_xxsldwi (sc[i][1], sc[i][2], 2); i++; + ui[i][0] = __builtin_vsx_xxsldwi (ui[i][1], ui[i][2], 3); i++; + us[i][0] = __builtin_vsx_xxsldwi (us[i][1], us[i][2], 0); i++; + uc[i][0] = __builtin_vsx_xxsldwi (uc[i][1], uc[i][2], 1); i++; + f[i][0] = __builtin_vsx_xxsldwi (f[i][1], f[i][2], 2); i++; + d[i][0] = __builtin_vsx_xxsldwi (d[i][1], d[i][2], 3); i++; + return i; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-4.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-4.c new file mode 100644 index 00000000000..bcf486377e8 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-4.c @@ -0,0 +1,142 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mcpu=power7" } */ +/* { dg-final { scan-assembler "xvcmpeqdp." } } */ +/* { dg-final { scan-assembler "xvcmpgtdp." } } */ +/* { dg-final { scan-assembler "xvcmpgedp." } } */ +/* { dg-final { scan-assembler "xvcmpeqsp." } } */ +/* { dg-final { scan-assembler "xvcmpgtsp." } } */ +/* { dg-final { scan-assembler "xvcmpgesp." } } */ +/* { dg-final { scan-assembler "vcmpbfp." } } */ +/* { dg-final { scan-assembler "vcmpequb." } } */ +/* { dg-final { scan-assembler "vcmpequh." } } */ +/* { dg-final { scan-assembler "vcmpequw." } } */ +/* { dg-final { scan-assembler "vcmpgtub." } } */ +/* { dg-final { scan-assembler "vcmpgtuh." } } */ +/* { dg-final { scan-assembler "vcmpgtuw." } } */ +/* { dg-final { scan-assembler "vcmpgtsb." } } */ +/* { dg-final { scan-assembler "vcmpgtsh." } } */ +/* { dg-final { scan-assembler "vcmpgtsw." } } */ +/* { dg-final { scan-assembler-not "vcmpeqfp" } } */ +/* { dg-final { scan-assembler-not "vcmpgtfp" } } */ +/* { dg-final { scan-assembler-not "vcmpgefp" } } */ + +/* check that Altivec builtins generate VSX if -mvsx. */ + +#include <altivec.h> + +int *v16qi_s (vector signed char *a, vector signed char *b, int *p) +{ + if (vec_all_eq (*a, *b)) + *p++ = 1; + + if (vec_all_gt (*a, *b)) + *p++ = 2; + + if (vec_all_ge (*a, *b)) + *p++ = 2; + + return p; +} + +int *v16qi_u (vector unsigned char *a, vector unsigned char *b, int *p) +{ + if (vec_all_eq (*a, *b)) + *p++ = 1; + + if (vec_all_gt (*a, *b)) + *p++ = 2; + + if (vec_all_ge (*a, *b)) + *p++ = 2; + + return p; +} + +int *v8hi_s (vector short *a, vector short *b, int *p) +{ + if (vec_all_eq (*a, *b)) + *p++ = 1; + + if (vec_all_gt (*a, *b)) + *p++ = 2; + + if (vec_all_ge (*a, *b)) + *p++ = 2; + + return p; +} + +int *v8hi_u (vector unsigned short *a, vector unsigned short *b, int *p) +{ + if (vec_all_eq (*a, *b)) + *p++ = 1; + + if (vec_all_gt (*a, *b)) + *p++ = 2; + + if (vec_all_ge (*a, *b)) + *p++ = 2; + + return p; +} + +int *v4si_s (vector int *a, vector int *b, int *p) +{ + if (vec_all_eq (*a, *b)) + *p++ = 1; + + if (vec_all_gt (*a, *b)) + *p++ = 2; + + if (vec_all_ge (*a, *b)) + *p++ = 2; + + return p; +} + +int *v4si_u (vector unsigned int *a, vector unsigned int *b, int *p) +{ + if (vec_all_eq (*a, *b)) + *p++ = 1; + + if (vec_all_gt (*a, *b)) + *p++ = 2; + + if (vec_all_ge (*a, *b)) + *p++ = 2; + + return p; +} + +int *v4sf (vector float *a, vector float *b, int *p) +{ + if (vec_all_eq (*a, *b)) + *p++ = 1; + + if (vec_all_gt (*a, *b)) + *p++ = 2; + + if (vec_all_ge (*a, *b)) + *p++ = 3; + + if (vec_all_in (*a, *b)) /* veccmpbfp. */ + *p++ = 4; + + return p; +} + +int *v2df (vector double *a, vector double *b, int *p) +{ + if (vec_all_eq (*a, *b)) + *p++ = 1; + + if (vec_all_gt (*a, *b)) + *p++ = 2; + + if (vec_all_ge (*a, *b)) + *p++ = 3; + + return p; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-5.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-5.c new file mode 100644 index 00000000000..5c24dc618ce --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-5.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mcpu=power7" } */ +/* { dg-final { scan-assembler "xxpermdi" } } */ +/* { dg-final { scan-assembler-not "stxvd2x" } } */ + +/* Make sure double extract doesn't use a store instruction. */ + +double d0(__vector double v){ return __builtin_vec_extract (v, 0); } +double d1(__vector double v){ return __builtin_vec_extract (v, 1); } + +double e0(vector double v){ return __builtin_vec_ext_v2df (v, 0); } +double e1(vector double v){ return __builtin_vec_ext_v2df (v, 1); } diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-6.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-6.c new file mode 100644 index 00000000000..a722b83b976 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-6.c @@ -0,0 +1,146 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mcpu=power7" } */ + +/* Check whether tdiv and tsqrt instructions generate the correct code. */ +/* Each of the *tdiv* and *tsqrt* instructions should be generated exactly 3 + times (the two calls in the _1 function should be combined). */ +/* { dg-final { scan-assembler-times "xstdivdp" 3 } } */ +/* { dg-final { scan-assembler-times "xvtdivdp" 3 } } */ +/* { dg-final { scan-assembler-times "xvtdivsp" 3 } } */ +/* { dg-final { scan-assembler-times "xstsqrtdp" 3 } } */ +/* { dg-final { scan-assembler-times "xvtsqrtdp" 3 } } */ +/* { dg-final { scan-assembler-times "xvtsqrtsp" 3 } } */ + +void test_div_df_1 (double a, double b, int *p) +{ + p[0] = __builtin_vsx_xstdivdp_fe (a, b); + p[1] = __builtin_vsx_xstdivdp_fg (a, b); +} + +int *test_div_df_2 (double a, double b, int *p) +{ + if (__builtin_vsx_xstdivdp_fe (a, b)) + *p++ = 1; + + return p; +} + +int *test_div_df_3 (double a, double b, int *p) +{ + if (__builtin_vsx_xstdivdp_fg (a, b)) + *p++ = 1; + + return p; +} + +void test_sqrt_df_1 (double a, int *p) +{ + p[0] = __builtin_vsx_xstsqrtdp_fe (a); + p[1] = __builtin_vsx_xstsqrtdp_fg (a); +} + +int *test_sqrt_df_2 (double a, int *p) +{ + if (__builtin_vsx_xstsqrtdp_fe (a)) + *p++ = 1; + + return p; +} + +int *test_sqrt_df_3 (double a, int *p) +{ + if (__builtin_vsx_xstsqrtdp_fg (a)) + *p++ = 1; + + return p; +} + +void test_div_v2df_1 (__vector double *a, __vector double *b, int *p) +{ + p[0] = __builtin_vsx_xvtdivdp_fe (*a, *b); + p[1] = __builtin_vsx_xvtdivdp_fg (*a, *b); +} + +int *test_div_v2df_2 (__vector double *a, __vector double *b, int *p) +{ + if (__builtin_vsx_xvtdivdp_fe (*a, *b)) + *p++ = 1; + + return p; +} + +int *test_div_v2df_3 (__vector double *a, __vector double *b, int *p) +{ + if (__builtin_vsx_xvtdivdp_fg (*a, *b)) + *p++ = 1; + + return p; +} + +void test_sqrt_v2df_1 (__vector double *a, int *p) +{ + p[0] = __builtin_vsx_xvtsqrtdp_fe (*a); + p[1] = __builtin_vsx_xvtsqrtdp_fg (*a); +} + +int *test_sqrt_v2df_2 (__vector double *a, int *p) +{ + if (__builtin_vsx_xvtsqrtdp_fe (*a)) + *p++ = 1; + + return p; +} + +int *test_sqrt_v2df_3 (__vector double *a, int *p) +{ + if (__builtin_vsx_xvtsqrtdp_fg (*a)) + *p++ = 1; + + return p; +} + +void test_div_v4sf_1 (__vector float *a, __vector float *b, int *p) +{ + p[0] = __builtin_vsx_xvtdivsp_fe (*a, *b); + p[1] = __builtin_vsx_xvtdivsp_fg (*a, *b); +} + +int *test_div_v4sf_2 (__vector float *a, __vector float *b, int *p) +{ + if (__builtin_vsx_xvtdivsp_fe (*a, *b)) + *p++ = 1; + + return p; +} + +int *test_div_v4sf_3 (__vector float *a, __vector float *b, int *p) +{ + if (__builtin_vsx_xvtdivsp_fg (*a, *b)) + *p++ = 1; + + return p; +} + +void test_sqrt_v4sf_1 (__vector float *a, int *p) +{ + p[0] = __builtin_vsx_xvtsqrtsp_fe (*a); + p[1] = __builtin_vsx_xvtsqrtsp_fg (*a); +} + +int *test_sqrt_v4sf_2 (__vector float *a, int *p) +{ + if (__builtin_vsx_xvtsqrtsp_fe (*a)) + *p++ = 1; + + return p; +} + +int *test_sqrt_v4sf_3 (__vector float *a, int *p) +{ + if (__builtin_vsx_xvtsqrtsp_fg (*a)) + *p++ = 1; + + return p; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-7.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-7.c new file mode 100644 index 00000000000..55e999d3851 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-7.c @@ -0,0 +1,150 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mcpu=power7" } */ + +/* Test simple extract/insert/slat operations. Make sure all types are + supported with various options. */ + +#include <altivec.h> + +double extract_df_0_reg (vector double p) { return vec_extract (p, 0); } +double extract_df_1_reg (vector double p) { return vec_extract (p, 1); } +double extract_df_n_reg (vector double p, int n) { return vec_extract (p, n); } + +double extract_df_0_mem (vector double *p) { return vec_extract (*p, 0); } +double extract_df_1_mem (vector double *p) { return vec_extract (*p, 1); } +double extract_df_n_mem (vector double *p, int n) { return vec_extract (*p, n); } + +vector double insert_df_0 (vector double p, double x) { return vec_insert (x, p, 0); } +vector double insert_df_1 (vector double p, double x) { return vec_insert (x, p, 1); } +vector double insert_df_n (vector double p, double x, int n) { return vec_insert (x, p, n); } + +vector double splat_df_reg (double x) { return vec_splats (x); } +vector double splat_df_mem (double *x) { return vec_splats (*x); } + +#ifdef _ARCH_PPC64 +#define ll long +#else +#define ll long long +#endif + +ll extract_di_0_reg (vector ll p) { return vec_extract (p, 0); } +ll extract_di_1_reg (vector ll p) { return vec_extract (p, 1); } +ll extract_di_n_reg (vector ll p, int n) { return vec_extract (p, n); } + +ll extract_di_0_mem (vector ll *p) { return vec_extract (*p, 0); } +ll extract_di_1_mem (vector ll *p) { return vec_extract (*p, 1); } +ll extract_di_n_mem (vector ll *p, int n) { return vec_extract (*p, n); } + +vector ll insert_di_0 (vector ll p, ll x) { return vec_insert (x, p, 0); } +vector ll insert_di_1 (vector ll p, ll x) { return vec_insert (x, p, 1); } +vector ll insert_di_n (vector ll p, ll x, int n) { return vec_insert (x, p, n); } + +vector ll splat_di_reg (ll x) { return vec_splats (x); } +vector ll splat_di_mem (ll *x) { return vec_splats (*x); } + +float extract_sf_0_reg (vector float p) { return vec_extract (p, 0); } +float extract_sf_3_reg (vector float p) { return vec_extract (p, 3); } +float extract_sf_n_reg (vector float p, int n) { return vec_extract (p, n); } + +float extract_sf_0_mem (vector float *p) { return vec_extract (*p, 0); } +float extract_sf_3_mem (vector float *p) { return vec_extract (*p, 3); } +float extract_sf_n_mem (vector float *p, int n) { return vec_extract (*p, n); } + +vector float insert_sf_0 (vector float p, float x) { return vec_insert (x, p, 0); } +vector float insert_sf_3 (vector float p, float x) { return vec_insert (x, p, 3); } +vector float insert_sf_n (vector float p, float x, int n) { return vec_insert (x, p, n); } + +vector float splat_sf_reg (float x) { return vec_splats (x); } +vector float splat_sf_mem (float *x) { return vec_splats (*x); } + +int extract_si_0_reg (vector int p) { return vec_extract (p, 0); } +int extract_si_3_reg (vector int p) { return vec_extract (p, 3); } +int extract_si_n_reg (vector int p, int n) { return vec_extract (p, n); } + +int extract_si_0_mem (vector int *p) { return vec_extract (*p, 0); } +int extract_si_3_mem (vector int *p) { return vec_extract (*p, 3); } +int extract_si_n_mem (vector int *p, int n) { return vec_extract (*p, n); } + +vector int insert_si_0 (vector int p, int x) { return vec_insert (x, p, 0); } +vector int insert_si_3 (vector int p, int x) { return vec_insert (x, p, 3); } +vector int insert_si_n (vector int p, int x, int n) { return vec_insert (x, p, n); } + +vector int splat_si_reg (int x) { return vec_splats (x); } +vector int splat_si_mem (int *x) { return vec_splats (*x); } + +unsigned int extract_usi_0_reg (vector unsigned int p) { return vec_extract (p, 0); } +unsigned int extract_usi_3_reg (vector unsigned int p) { return vec_extract (p, 3); } +unsigned int extract_usi_n_reg (vector unsigned int p, int n) { return vec_extract (p, n); } + +unsigned int extract_usi_0_mem (vector unsigned int *p) { return vec_extract (*p, 0); } +unsigned int extract_usi_3_mem (vector unsigned int *p) { return vec_extract (*p, 3); } +unsigned int extract_usi_n_mem (vector unsigned int *p, int n) { return vec_extract (*p, n); } + +vector unsigned int insert_usi_0 (vector unsigned int p, unsigned int x) { return vec_insert (x, p, 0); } +vector unsigned int insert_usi_3 (vector unsigned int p, unsigned int x) { return vec_insert (x, p, 3); } +vector unsigned int insert_usi_n (vector unsigned int p, unsigned int x, int n) { return vec_insert (x, p, n); } + +vector unsigned int splat_usi_reg (unsigned int x) { return vec_splats (x); } +vector unsigned int splat_usi_mem (unsigned int *x) { return vec_splats (*x); } + +short extract_hi_0_reg (vector short p) { return vec_extract (p, 0); } +short extract_hi_7_reg (vector short p) { return vec_extract (p, 7); } +short extract_hi_n_reg (vector short p, int n) { return vec_extract (p, n); } + +short extract_hi_0_mem (vector short *p) { return vec_extract (*p, 0); } +short extract_hi_7_mem (vector short *p) { return vec_extract (*p, 7); } +short extract_hi_n_mem (vector short *p, int n) { return vec_extract (*p, n); } + +vector short insert_hi_0 (vector short p, short x) { return vec_insert (x, p, 0); } +vector short insert_hi_7 (vector short p, short x) { return vec_insert (x, p, 7); } +vector short insert_hi_n (vector short p, short x, int n) { return vec_insert (x, p, n); } + +vector short splat_hi_reg (short x) { return vec_splats (x); } +vector short splat_hi_mem (short *x) { return vec_splats (*x); } + +unsigned short extract_uhi_0_reg (vector unsigned short p) { return vec_extract (p, 0); } +unsigned short extract_uhi_7_reg (vector unsigned short p) { return vec_extract (p, 7); } +unsigned short extract_uhi_n_reg (vector unsigned short p, int n) { return vec_extract (p, n); } + +unsigned short extract_uhi_0_mem (vector unsigned short *p) { return vec_extract (*p, 0); } +unsigned short extract_uhi_7_mem (vector unsigned short *p) { return vec_extract (*p, 7); } +unsigned short extract_uhi_n_mem (vector unsigned short *p, int n) { return vec_extract (*p, n); } + +vector unsigned short insert_uhi_0 (vector unsigned short p, unsigned short x) { return vec_insert (x, p, 0); } +vector unsigned short insert_uhi_7 (vector unsigned short p, unsigned short x) { return vec_insert (x, p, 7); } +vector unsigned short insert_uhi_n (vector unsigned short p, unsigned short x, int n) { return vec_insert (x, p, n); } + +vector unsigned short splat_uhi_reg (unsigned short x) { return vec_splats (x); } +vector unsigned short splat_uhi_mem (unsigned short *x) { return vec_splats (*x); } + +signed char extract_qi_0_reg (vector signed char p) { return vec_extract (p, 0); } +signed char extract_qi_1_reg5 (vector signed char p) { return vec_extract (p, 15); } +signed char extract_qi_n_reg (vector signed char p, int n) { return vec_extract (p, n); } + +signed char extract_qi_0_mem (vector signed char *p) { return vec_extract (*p, 0); } +signed char extract_qi_1_mem5 (vector signed char *p) { return vec_extract (*p, 15); } +signed char extract_qi_n_mem (vector signed char *p, int n) { return vec_extract (*p, n); } + +vector signed char insert_qi_0 (vector signed char p, signed char x) { return vec_insert (x, p, 0); } +vector signed char insert_qi_15 (vector signed char p, signed char x) { return vec_insert (x, p, 15); } +vector signed char insert_qi_n (vector signed char p, signed char x, int n) { return vec_insert (x, p, n); } + +vector signed char splat_qi_reg (signed char x) { return vec_splats (x); } +vector signed char splat_qi_mem (signed char *x) { return vec_splats (*x); } + +unsigned char extract_uqi_0_reg (vector unsigned char p) { return vec_extract (p, 0); } +unsigned char extract_uqi_1_reg5 (vector unsigned char p) { return vec_extract (p, 15); } +unsigned char extract_uqi_n_reg (vector unsigned char p, int n) { return vec_extract (p, n); } + +unsigned char extract_uqi_0_mem (vector unsigned char *p) { return vec_extract (*p, 0); } +unsigned char extract_uqi_1_mem5 (vector unsigned char *p) { return vec_extract (*p, 15); } +unsigned char extract_uqi_n_mem (vector unsigned char *p, int n) { return vec_extract (*p, n); } + +vector unsigned char insert_uqi_0 (vector unsigned char p, unsigned char x) { return vec_insert (x, p, 0); } +vector unsigned char insert_uqi_15 (vector unsigned char p, unsigned char x) { return vec_insert (x, p, 15); } +vector unsigned char insert_uqi_n (vector unsigned char p, unsigned char x, int n) { return vec_insert (x, p, n); } + +vector unsigned char splat_uqi_reg (unsigned char x) { return vec_splats (x); } +vector unsigned char splat_uqi_mem (unsigned char *x) { return vec_splats (*x); } diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-1.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-1.c new file mode 100644 index 00000000000..0bf3a7f53a9 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-1.c @@ -0,0 +1,152 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -ftree-vectorize -mcpu=power7 -m64 -ffast-math" } */ +/* { dg-final { scan-assembler "xvadddp" } } */ +/* { dg-final { scan-assembler "xvsubdp" } } */ +/* { dg-final { scan-assembler "xvmuldp" } } */ +/* { dg-final { scan-assembler "xvdivdp" } } */ +/* { dg-final { scan-assembler "xvmadd" } } */ +/* { dg-final { scan-assembler "xvmsub" } } */ +/* { dg-final { scan-assembler "xvsqrtdp" } } */ +/* { dg-final { scan-assembler "xvcpsgndp" } } */ +/* { dg-final { scan-assembler "xvrdpim" } } */ +/* { dg-final { scan-assembler "xvrdpip" } } */ +/* { dg-final { scan-assembler "xvrdpiz" } } */ +/* { dg-final { scan-assembler "xvrdpic" } } */ +/* { dg-final { scan-assembler "xvrdpi " } } */ + +#ifndef SIZE +#define SIZE 1024 +#endif + +double a[SIZE] __attribute__((__aligned__(32))); +double b[SIZE] __attribute__((__aligned__(32))); +double c[SIZE] __attribute__((__aligned__(32))); +double d[SIZE] __attribute__((__aligned__(32))); +double e[SIZE] __attribute__((__aligned__(32))); + +void +vector_add (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = b[i] + c[i]; +} + +void +vector_subtract (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = b[i] - c[i]; +} + +void +vector_multiply (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = b[i] * c[i]; +} + +void +vector_multiply_add (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = (b[i] * c[i]) + d[i]; +} + +void +vector_multiply_subtract (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = (b[i] * c[i]) - d[i]; +} + +void +vector_divide (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = b[i] / c[i]; +} + +extern double sqrt (double); +extern double floor (double); +extern double ceil (double); +extern double trunc (double); +extern double nearbyint (double); +extern double rint (double); +extern double copysign (double, double); + +void +vector_sqrt (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = sqrt (b[i]); +} + +void +vector_floor (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = floor (b[i]); +} + +void +vector_ceil (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = ceil (b[i]); +} + +void +vector_trunc (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = trunc (b[i]); +} + +void +vector_nearbyint (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = nearbyint (b[i]); +} + +void +vector_rint (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = rint (b[i]); +} + +void +vector_copysign (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = copysign (b[i], c[i]); +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-2.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-2.c new file mode 100644 index 00000000000..ba27b46fb27 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-2.c @@ -0,0 +1,152 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -ftree-vectorize -mcpu=power7 -m64 -ffast-math" } */ +/* { dg-final { scan-assembler "xvaddsp" } } */ +/* { dg-final { scan-assembler "xvsubsp" } } */ +/* { dg-final { scan-assembler "xvmulsp" } } */ +/* { dg-final { scan-assembler "xvdivsp" } } */ +/* { dg-final { scan-assembler "xvmadd" } } */ +/* { dg-final { scan-assembler "xvmsub" } } */ +/* { dg-final { scan-assembler "xvsqrtsp" } } */ +/* { dg-final { scan-assembler "xvcpsgnsp" } } */ +/* { dg-final { scan-assembler "xvrspim" } } */ +/* { dg-final { scan-assembler "xvrspip" } } */ +/* { dg-final { scan-assembler "xvrspiz" } } */ +/* { dg-final { scan-assembler "xvrspic" } } */ +/* { dg-final { scan-assembler "xvrspi " } } */ + +#ifndef SIZE +#define SIZE 1024 +#endif + +float a[SIZE] __attribute__((__aligned__(32))); +float b[SIZE] __attribute__((__aligned__(32))); +float c[SIZE] __attribute__((__aligned__(32))); +float d[SIZE] __attribute__((__aligned__(32))); +float e[SIZE] __attribute__((__aligned__(32))); + +void +vector_add (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = b[i] + c[i]; +} + +void +vector_subtract (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = b[i] - c[i]; +} + +void +vector_multiply (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = b[i] * c[i]; +} + +void +vector_multiply_add (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = (b[i] * c[i]) + d[i]; +} + +void +vector_multiply_subtract (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = (b[i] * c[i]) - d[i]; +} + +void +vector_divide (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = b[i] / c[i]; +} + +extern float sqrtf (float); +extern float floorf (float); +extern float ceilf (float); +extern float truncf (float); +extern float nearbyintf (float); +extern float rintf (float); +extern float copysignf (float, float); + +void +vector_sqrt (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = sqrtf (b[i]); +} + +void +vector_floor (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = floorf (b[i]); +} + +void +vector_ceil (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = ceilf (b[i]); +} + +void +vector_trunc (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = truncf (b[i]); +} + +void +vector_nearbyint (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = nearbyintf (b[i]); +} + +void +vector_rint (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = rintf (b[i]); +} + +void +vector_copysign (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a[i] = copysignf (b[i], c[i]); +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-3.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-3.c new file mode 100644 index 00000000000..5f3bf5b4b2c --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-3.c @@ -0,0 +1,48 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -ftree-vectorize -mcpu=power7 -m64" } */ +/* { dg-final { scan-assembler "xvadddp" } } */ +/* { dg-final { scan-assembler "xvsubdp" } } */ +/* { dg-final { scan-assembler "xvmuldp" } } */ +/* { dg-final { scan-assembler "xvdivdp" } } */ +/* { dg-final { scan-assembler "xvmadd" } } */ +/* { dg-final { scan-assembler "xvmsub" } } */ + +__vector double a, b, c, d; + +void +vector_add (void) +{ + a = b + c; +} + +void +vector_subtract (void) +{ + a = b - c; +} + +void +vector_multiply (void) +{ + a = b * c; +} + +void +vector_multiply_add (void) +{ + a = (b * c) + d; +} + +void +vector_multiply_subtract (void) +{ + a = (b * c) - d; +} + +void +vector_divide (void) +{ + a = b / c; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-4.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-4.c new file mode 100644 index 00000000000..a34ba8f7de3 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-4.c @@ -0,0 +1,48 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -ftree-vectorize -mcpu=power7 -m64" } */ +/* { dg-final { scan-assembler "xvaddsp" } } */ +/* { dg-final { scan-assembler "xvsubsp" } } */ +/* { dg-final { scan-assembler "xvmulsp" } } */ +/* { dg-final { scan-assembler "xvdivsp" } } */ +/* { dg-final { scan-assembler "xvmadd" } } */ +/* { dg-final { scan-assembler "xvmsub" } } */ + +__vector float a, b, c, d; + +void +vector_add (void) +{ + a = b + c; +} + +void +vector_subtract (void) +{ + a = b - c; +} + +void +vector_multiply (void) +{ + a = b * c; +} + +void +vector_multiply_add (void) +{ + a = (b * c) + d; +} + +void +vector_multiply_subtract (void) +{ + a = (b * c) - d; +} + +void +vector_divide (void) +{ + a = b / c; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-5.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-5.c new file mode 100644 index 00000000000..65843e93fbd --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-5.c @@ -0,0 +1,392 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-mvsx -O2" } */ + +/* This will run, and someday we should add the support to test whether we are + running on VSX hardware. */ + +#include <altivec.h> +#include <stdlib.h> + +#ifdef DEBUG +#include <stdio.h> + +static int errors = 0; +#endif + +union args { + double scalar[2]; + vector double vect; +}; + +union largs { + unsigned long scalar[2]; + vector bool long vect; +}; + +static void +do_test (union args *expected, union args *got, const char *name) +{ + if (expected->scalar[0] != got->scalar[0] + || expected->scalar[1] != got->scalar[1]) + { +#ifdef DEBUG + printf ("%s failed!\n", name); + errors++; +#else + abort (); +#endif + } +} + +static void +do_ltest (union largs *expected, union largs *got, const char *name) +{ + if (expected->scalar[0] != got->scalar[0] + || expected->scalar[1] != got->scalar[1]) + { +#ifdef DEBUG + printf ("%s failed!\n", name); + errors++; +#else + abort (); +#endif + } +} + + +/* Vec functions taking a single argument. */ +static vector double +vabs (vector double arg) +{ + return vec_abs (arg); +} + +static vector double +vceil (vector double arg) +{ + return vec_ceil (arg); +} + +static vector double +vfloor (vector double arg) +{ + return vec_floor (arg); +} + +static vector double +vnearbyint (vector double arg) +{ + return vec_nearbyint (arg); +} + +static vector double +vrint (vector double arg) +{ + return vec_rint (arg); +} + +static vector double +vsqrt (vector double arg) +{ + return vec_sqrt (arg); +} + +/* Single argument tests. */ +static struct +{ + union args result; + union args input; + vector double (*func) (vector double); + const char *name; +} arg1_tests[] = { + /* result input function name */ + { { 1.0, 2.0 }, { -1.0, 2.0 }, vabs, "vabs" }, + { { 1.0, 2.0 }, { 1.0, -2.0 }, vabs, "vabs" }, + { { 2.0, 2.0 }, { 1.1, 1.7 }, vceil, "vceil" }, + { { -1.0, -1.0 }, { -1.1, -1.7 }, vceil, "vceil" }, + { { -1.0, 2.0 }, { -1.5, 1.5 }, vceil, "vceil" }, + { { 1.0, 1.0 }, { 1.1, 1.7 }, vfloor, "vfloor" }, + { { -2.0, -2.0 }, { -1.1, -1.7 }, vfloor, "vfloor" }, + { { -2.0, 1.0 }, { -1.5, 1.5 }, vfloor, "vfloor" }, + { { 1.0, 2.0 }, { 1.1, 1.7 }, vnearbyint, "vnearbyint" }, + { { -1.0, -2.0 }, { -1.1, -1.7 }, vnearbyint, "vnearbyint" }, + { { -2.0, 2.0 }, { -1.5, 1.5 }, vnearbyint, "vnearbyint" }, + { { 1.0, 2.0 }, { 1.1, 1.7 }, vrint, "vrint" }, + { { -1.0, -2.0 }, { -1.1, -1.7 }, vrint, "vrint" }, + { { -2.0, 2.0 }, { -1.5, 1.5 }, vrint, "vrint" }, + { { 2.0, 4.0 }, { 4.0, 16.0 }, vsqrt, "vsqrt" }, +}; + +static void +test_arg1 (void) +{ + unsigned i; + +#ifdef DEBUG + printf ("Single argument tests:\n"); +#endif + + for (i = 0; i < sizeof (arg1_tests) / sizeof (arg1_tests[0]); i++) + { + union args u; + u.vect = arg1_tests[i].func (arg1_tests[i].input.vect); + +#ifdef DEBUG + printf ("test %-16s: expected { %4g, %4g }, got { %4g, %4g }, input { %4g, %4g }\n", + arg1_tests[i].name, + arg1_tests[i].result.scalar[0], + arg1_tests[i].result.scalar[1], + u.scalar[0], + u.scalar[1], + arg1_tests[i].input.scalar[0], + arg1_tests[i].input.scalar[1]); +#endif + + do_test (&arg1_tests[i].result, &u, arg1_tests[i].name); + } + + return; +} + + +/* Vect functions taking 2 arguments. */ +static vector double +vadd (vector double arg1, vector double arg2) +{ + return vec_add (arg1, arg2); +} + +static vector double +vadd2 (vector double arg1, vector double arg2) +{ + return arg1 + arg2; +} + +static vector double +vsub (vector double arg1, vector double arg2) +{ + return vec_sub (arg1, arg2); +} + +static vector double +vsub2 (vector double arg1, vector double arg2) +{ + return arg1 - arg2; +} + +static vector double +vmul (vector double arg1, vector double arg2) +{ + return vec_mul (arg1, arg2); +} + +static vector double +vmul2 (vector double arg1, vector double arg2) +{ + return arg1 * arg2; +} + +static vector double +vdiv (vector double arg1, vector double arg2) +{ + return vec_div (arg1, arg2); +} + +static vector double +vdiv2 (vector double arg1, vector double arg2) +{ + return arg1 / arg2; +} + +static vector double +vmax (vector double arg1, vector double arg2) +{ + return vec_max (arg1, arg2); +} + +static vector double +vmin (vector double arg1, vector double arg2) +{ + return vec_min (arg1, arg2); +} + +/* 2 argument tests. */ +static struct +{ + union args result; + union args input[2]; + vector double (*func) (vector double, vector double); + const char *name; +} arg2_tests[] = { + /* result */ + { { 4.0, 6.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vadd, "vadd" }, + { { 4.0, -6.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vadd, "vadd" }, + { { 4.0, 6.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vadd2, "vadd2" }, + { { 4.0, -6.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vadd2, "vadd2" }, + { { -2.0, -2.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vsub, "vsub" }, + { { -2.0, 2.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vsub, "vsub" }, + { { -2.0, -2.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vsub2, "vsub2" }, + { { -2.0, 2.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vsub2, "vsub2" }, + { { 6.0, 4.0 }, { { 2.0, 8.0 }, { 3.0, 0.5 } }, vmul, "vmul" }, + { { 6.0, 4.0 }, { { 2.0, 8.0 }, { 3.0, 0.5 } }, vmul2, "vmul2" }, + { { 2.0, 0.5 }, { { 6.0, 4.0 }, { 3.0, 8.0 } }, vdiv, "vdiv" }, + { { 2.0, 0.5 }, { { 6.0, 4.0 }, { 3.0, 8.0 } }, vdiv2, "vdiv2" }, + { { 3.0, 4.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vmax, "vmax" }, + { { 1.0, 4.0 }, { { 1.0, -2.0 }, { -3.0, 4.0 } }, vmax, "vmax" }, + { { 1.0, 2.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vmin, "vmin" }, + { { -3.0, -2.0 }, { { 1.0, -2.0 }, { -3.0, 4.0 } }, vmin, "vmin" }, +}; + +static void +test_arg2 (void) +{ + unsigned i; + +#ifdef DEBUG + printf ("\nTwo argument tests:\n"); +#endif + + for (i = 0; i < sizeof (arg2_tests) / sizeof (arg2_tests[0]); i++) + { + union args u; + u.vect = arg2_tests[i].func (arg2_tests[i].input[0].vect, + arg2_tests[i].input[1].vect); + +#ifdef DEBUG + printf ("test %-16s: expected { %4g, %4g }, got { %4g, %4g }, input { %4g, %4g }, { %4g, %4g }\n", + arg2_tests[i].name, + arg2_tests[i].result.scalar[0], + arg2_tests[i].result.scalar[1], + u.scalar[0], + u.scalar[1], + arg2_tests[i].input[0].scalar[0], + arg2_tests[i].input[0].scalar[1], + arg2_tests[i].input[1].scalar[0], + arg2_tests[i].input[1].scalar[1]); +#endif + + do_test (&arg2_tests[i].result, &u, arg2_tests[i].name); + } + + return; +} + + +/* Comparisons, returnning a boolean vector. */ +static vector bool long +vcmpeq (vector double arg1, vector double arg2) +{ + return vec_cmpeq (arg1, arg2); +} + +static vector bool long +vcmplt (vector double arg1, vector double arg2) +{ + return vec_cmplt (arg1, arg2); +} + +static vector bool long +vcmple (vector double arg1, vector double arg2) +{ + return vec_cmple (arg1, arg2); +} + +static vector bool long +vcmpgt (vector double arg1, vector double arg2) +{ + return vec_cmpgt (arg1, arg2); +} + +static vector bool long +vcmpge (vector double arg1, vector double arg2) +{ + return vec_cmpge (arg1, arg2); +} + +#define ONE 0xffffffffffffffffUL +#define ZERO 0x0000000000000000UL + +/* comparison tests. */ +static struct +{ + union largs result; + union args input[2]; + vector bool long (*func) (vector double, vector double); + const char *name; +} argcmp_tests[] = { + { { ONE, ZERO }, { { 1.0, 2.0 }, { 1.0, -2.0 } }, vcmpeq, "vcmpeq" }, + { { ZERO, ONE }, { { -1.0, 2.0 }, { 1.0, 2.0 } }, vcmpeq, "vcmpeq" }, + + { { ONE, ONE }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmple, "vcmple" }, + { { ONE, ONE }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmple, "vcmple" }, + { { ZERO, ZERO }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmple, "vcmple" }, + + { { ZERO, ZERO }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmplt, "vcmplt" }, + { { ONE, ONE }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmplt, "vcmplt" }, + { { ZERO, ZERO }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmplt, "vcmplt" }, + + { { ZERO, ZERO }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmpgt, "vcmpgt" }, + { { ZERO, ZERO }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmpgt, "vcmpgt" }, + { { ONE, ONE }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmpgt, "vcmpgt" }, + + { { ONE, ONE }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmpge, "vcmpge" }, + { { ZERO, ZERO }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmpge, "vcmpge" }, + { { ONE, ONE }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmpge, "vcmpge" }, +}; + +static void +test_argcmp (void) +{ + unsigned i; + +#ifdef DEBUG + printf ("\nComparison tests:\n"); +#endif + + for (i = 0; i < sizeof (argcmp_tests) / sizeof (argcmp_tests[0]); i++) + { + union largs u; + u.vect = argcmp_tests[i].func (argcmp_tests[i].input[0].vect, + argcmp_tests[i].input[1].vect); + +#ifdef DEBUG + printf ("test %-16s: expected { 0x%016lx, 0x%016lx }, got { 0x%016lx, 0x%016lx }, input { %4g, %4g }, { %4g, %4g }\n", + argcmp_tests[i].name, + argcmp_tests[i].result.scalar[0], + argcmp_tests[i].result.scalar[1], + u.scalar[0], + u.scalar[1], + argcmp_tests[i].input[0].scalar[0], + argcmp_tests[i].input[0].scalar[1], + argcmp_tests[i].input[1].scalar[0], + argcmp_tests[i].input[1].scalar[1]); +#endif + + do_ltest (&argcmp_tests[i].result, &u, argcmp_tests[i].name); + } + + return; +} + + +int +main (int argc, char *argv[]) +{ + test_arg1 (); + test_arg2 (); + test_argcmp (); + +#ifdef DEBUG + if (errors) + { + printf ("There were %d error(s)\n", errors); + return errors; + } + else + printf ("There were no errors\n"); +#endif + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6.c new file mode 100644 index 00000000000..f8e644bb532 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6.c @@ -0,0 +1,81 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-mvsx -O2" } */ + +#include <altivec.h> + +void foo (vector double *out, vector double *in, vector long *p_l, vector bool long *p_b, vector unsigned char *p_uc, int *i) +{ + vector double in0 = in[0]; + vector double in1 = in[1]; + vector double in2 = in[2]; + vector long inl = *p_l; + vector bool long inb = *p_b; + vector unsigned char uc = *p_uc; + + *out++ = vec_abs (in0); + *out++ = vec_add (in0, in1); + *out++ = vec_and (in0, in1); + *out++ = vec_and (in0, inb); + *out++ = vec_and (inb, in0); + *out++ = vec_andc (in0, in1); + *out++ = vec_andc (in0, inb); + *out++ = vec_andc (inb, in0); + *out++ = vec_ceil (in0); + *p_b++ = vec_cmpeq (in0, in1); + *p_b++ = vec_cmpgt (in0, in1); + *p_b++ = vec_cmpge (in0, in1); + *p_b++ = vec_cmplt (in0, in1); + *p_b++ = vec_cmple (in0, in1); + *out++ = vec_div (in0, in1); + *out++ = vec_floor (in0); + *out++ = vec_madd (in0, in1, in2); + *out++ = vec_msub (in0, in1, in2); + *out++ = vec_max (in0, in1); + *out++ = vec_min (in0, in1); + *out++ = vec_msub (in0, in1, in2); + *out++ = vec_mul (in0, in1); + *out++ = vec_nearbyint (in0); + *out++ = vec_nmadd (in0, in1, in2); + *out++ = vec_nmsub (in0, in1, in2); + *out++ = vec_nor (in0, in1); + *out++ = vec_or (in0, in1); + *out++ = vec_or (in0, inb); + *out++ = vec_or (inb, in0); + *out++ = vec_perm (in0, in1, uc); + *out++ = vec_rint (in0); + *out++ = vec_sel (in0, in1, inl); + *out++ = vec_sel (in0, in1, inb); + *out++ = vec_sub (in0, in1); + *out++ = vec_sqrt (in0); + *out++ = vec_trunc (in0); + *out++ = vec_xor (in0, in1); + *out++ = vec_xor (in0, inb); + *out++ = vec_xor (inb, in0); + + *i++ = vec_all_eq (in0, in1); + *i++ = vec_all_ge (in0, in1); + *i++ = vec_all_gt (in0, in1); + *i++ = vec_all_le (in0, in1); + *i++ = vec_all_lt (in0, in1); + *i++ = vec_all_nan (in0); + *i++ = vec_all_ne (in0, in1); + *i++ = vec_all_nge (in0, in1); + *i++ = vec_all_ngt (in0, in1); + *i++ = vec_all_nle (in0, in1); + *i++ = vec_all_nlt (in0, in1); + *i++ = vec_all_numeric (in0); + *i++ = vec_any_eq (in0, in1); + *i++ = vec_any_ge (in0, in1); + *i++ = vec_any_gt (in0, in1); + *i++ = vec_any_le (in0, in1); + *i++ = vec_any_lt (in0, in1); + *i++ = vec_any_nan (in0); + *i++ = vec_any_ne (in0, in1); + *i++ = vec_any_nge (in0, in1); + *i++ = vec_any_ngt (in0, in1); + *i++ = vec_any_nle (in0, in1); + *i++ = vec_any_nlt (in0, in1); + *i++ = vec_any_numeric (in0); +} diff --git a/gcc/testsuite/gfortran.dg/aliasing_dummy_1.f90 b/gcc/testsuite/gfortran.dg/aliasing_dummy_1.f90 index 0d0b588fc10..686853a1c08 100644 --- a/gcc/testsuite/gfortran.dg/aliasing_dummy_1.f90 +++ b/gcc/testsuite/gfortran.dg/aliasing_dummy_1.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! This tests the fix for PR24276, which originated from the Loren P. Meissner example, ! Array_List. The PR concerns dummy argument aliassing of components of arrays of derived ! types as arrays of the type of the component. gfortran would compile and run this @@ -61,4 +63,5 @@ contains write (slist(1,1), '(2hi=,i3)') i end subroutine foo3 -end program test_lex
\ No newline at end of file +end program test_lex + diff --git a/gcc/testsuite/gfortran.dg/altreturn_3.f90 b/gcc/testsuite/gfortran.dg/altreturn_3.f90 index 999ada87a07..daa09017859 100644 --- a/gcc/testsuite/gfortran.dg/altreturn_3.f90 +++ b/gcc/testsuite/gfortran.dg/altreturn_3.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Tests the fix for PR30236, which was due to alternate returns ! in generic interfaces causing a segfault. They now work ! correctly. diff --git a/gcc/testsuite/gfortran.dg/altreturn_5.f90 b/gcc/testsuite/gfortran.dg/altreturn_5.f90 index ff1b82289f6..a8b6ff83cd1 100644 --- a/gcc/testsuite/gfortran.dg/altreturn_5.f90 +++ b/gcc/testsuite/gfortran.dg/altreturn_5.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Tests the fix for PR31483, in which dummy argument procedures ! produced an ICE if they had an alternate return. ! diff --git a/gcc/testsuite/gfortran.dg/altreturn_6.f90 b/gcc/testsuite/gfortran.dg/altreturn_6.f90 index 61f5f605990..19c851e5092 100644 --- a/gcc/testsuite/gfortran.dg/altreturn_6.f90 +++ b/gcc/testsuite/gfortran.dg/altreturn_6.f90 @@ -1,3 +1,6 @@ +! { dg-do compile } +! { dg-options "-std=legacy" } +! ! PR 32938 subroutine r (*) integer(kind=8) :: i diff --git a/gcc/testsuite/gfortran.dg/altreturn_7.f90 b/gcc/testsuite/gfortran.dg/altreturn_7.f90 index 6eb0c78bde7..d1786d038c8 100644 --- a/gcc/testsuite/gfortran.dg/altreturn_7.f90 +++ b/gcc/testsuite/gfortran.dg/altreturn_7.f90 @@ -1,4 +1,5 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } ! ! PR 40848: [4.5 Regression] ICE with alternate returns ! diff --git a/gcc/testsuite/gfortran.dg/array_constructor_13.f90 b/gcc/testsuite/gfortran.dg/array_constructor_13.f90 index bacc6fffc38..74f3d497a75 100644 --- a/gcc/testsuite/gfortran.dg/array_constructor_13.f90 +++ b/gcc/testsuite/gfortran.dg/array_constructor_13.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! Tests patch for PR29431, which arose from PR29373. ! ! Contributed by Tobias Schlueter <tobi@gcc.gnu.org> diff --git a/gcc/testsuite/gfortran.dg/arrayio_7.f90 b/gcc/testsuite/gfortran.dg/arrayio_7.f90 index 69581763a64..68d1fbf97e6 100644 --- a/gcc/testsuite/gfortran.dg/arrayio_7.f90 +++ b/gcc/testsuite/gfortran.dg/arrayio_7.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR24224 Test formatted input/output to/from character arrays with strides ! other than 1. Test that reading stops at the end of the current record. ! Contributed by Jerry DeLisle <jvdelisle@verizon.net>. diff --git a/gcc/testsuite/gfortran.dg/arrayio_8.f90 b/gcc/testsuite/gfortran.dg/arrayio_8.f90 index 9dc81f82da1..7b609bd061c 100644 --- a/gcc/testsuite/gfortran.dg/arrayio_8.f90 +++ b/gcc/testsuite/gfortran.dg/arrayio_8.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR28339, This test checks that internal unit array I/O handles a full record ! and advances to the next record properly. Test case derived from PR ! Submitted by Jerry DeLisle <jvdelisle@gcc.gnu.org> diff --git a/gcc/testsuite/gfortran.dg/assumed_charlen_function_3.f90 b/gcc/testsuite/gfortran.dg/assumed_charlen_function_3.f90 index 09c9be97c03..912126fe72a 100644 --- a/gcc/testsuite/gfortran.dg/assumed_charlen_function_3.f90 +++ b/gcc/testsuite/gfortran.dg/assumed_charlen_function_3.f90 @@ -5,13 +5,13 @@ !
! Contributed by Paul Thomas <pault@gcc.gnu.org>
!
-function is_OK (ch) ! { dg-warning "is obsolescent in fortran 95" }
+function is_OK (ch) ! { dg-warning "Obsolescent feature" }
character(*) is_OK, ch ! OK in an external function
is_OK = ch
end function is_OK
! The warning occurs twice for the next line; for 'more_OK' and for 'fcn';
-function more_OK (ch, fcn) ! { dg-warning "is obsolescent in fortran 95" }
+function more_OK (ch, fcn) ! { dg-warning "Obsolescent feature" }
character(*) more_OK, ch
character (*), external :: fcn ! OK as a dummy argument
more_OK = fcn (ch)
diff --git a/gcc/testsuite/gfortran.dg/assumed_charlen_function_4.f90 b/gcc/testsuite/gfortran.dg/assumed_charlen_function_4.f90 index 9c96ba4d69f..c8f804465b7 100644 --- a/gcc/testsuite/gfortran.dg/assumed_charlen_function_4.f90 +++ b/gcc/testsuite/gfortran.dg/assumed_charlen_function_4.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! Tests the fix for PR28600 in which the declaration for the ! character length n, would be given the DECL_CONTEXT of 'gee' ! thus causing an ICE. diff --git a/gcc/testsuite/gfortran.dg/assumed_charlen_function_5.f90 b/gcc/testsuite/gfortran.dg/assumed_charlen_function_5.f90 index cc7e0108db9..8a0788978af 100644 --- a/gcc/testsuite/gfortran.dg/assumed_charlen_function_5.f90 +++ b/gcc/testsuite/gfortran.dg/assumed_charlen_function_5.f90 @@ -5,14 +5,14 @@ ! ! Contributed by Paul Thomas <pault@gcc.gnu.org> ! -character(*) function charrext (n) ! { dg-warning "is obsolescent in fortran 95" } +character(*) function charrext (n) ! { dg-warning "Obsolescent feature" } character(26) :: alpha ="abcdefghijklmnopqrstuvwxyz" charrext = alpha (1:n) end function charrext character(26), external :: charrext interface - integer(4) function test(charr, i) ! { dg-warning "is obsolescent in fortran 95" } + integer(4) function test(charr, i) ! { dg-warning "Obsolescent feature" } character(*), external :: charr integer :: i end function test @@ -23,7 +23,7 @@ end function charrext m = ctest (charrext, 27 - j) end do contains - integer(4) function ctest(charr, i) ! { dg-warning "is obsolescent in fortran 95" } + integer(4) function ctest(charr, i) ! { dg-warning "Obsolescent feature" } character(*) :: charr integer :: i print *, charr(i) @@ -31,7 +31,7 @@ contains end function ctest end -integer(4) function test(charr, i) ! { dg-warning "is obsolescent in fortran 95" } +integer(4) function test(charr, i) ! { dg-warning "Obsolescent feature" } character(*) :: charr integer :: i print *, charr(i) diff --git a/gcc/testsuite/gfortran.dg/backspace_8.f b/gcc/testsuite/gfortran.dg/backspace_8.f index 8c8c96aacec..2dd6b72e9d9 100644 --- a/gcc/testsuite/gfortran.dg/backspace_8.f +++ b/gcc/testsuite/gfortran.dg/backspace_8.f @@ -1,4 +1,6 @@ C { dg-do run } +C { dg-options "-std=legacy" } +C C PR libfortran/31618 - backspace after an error didn't work. program main character*78 msg diff --git a/gcc/testsuite/gfortran.dg/backspace_9.f b/gcc/testsuite/gfortran.dg/backspace_9.f index fe62ea5a6e0..851f518a2a9 100644 --- a/gcc/testsuite/gfortran.dg/backspace_9.f +++ b/gcc/testsuite/gfortran.dg/backspace_9.f @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR32235 incorrectly position text file after backspace ! Test case from PR, prepared by Jerry DeLisle <jvdelisle@gcc.gnu.org> program main diff --git a/gcc/testsuite/gfortran.dg/char_comparison_1.f b/gcc/testsuite/gfortran.dg/char_comparison_1.f index 9a316b74f7d..02f69e07661 100644 --- a/gcc/testsuite/gfortran.dg/char_comparison_1.f +++ b/gcc/testsuite/gfortran.dg/char_comparison_1.f @@ -1,4 +1,6 @@ C { dg-do run } +C { dg-options "-std=legacy" } +C C PR 30525 - comparisons with padded spaces were done C signed. program main diff --git a/gcc/testsuite/gfortran.dg/char_decl_1.f90 b/gcc/testsuite/gfortran.dg/char_decl_1.f90 index 7ce6974f688..3bef08342ee 100644 --- a/gcc/testsuite/gfortran.dg/char_decl_1.f90 +++ b/gcc/testsuite/gfortran.dg/char_decl_1.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! PR32644 "CHARACTER*1, c" produces "Unclassifiable statement" program f character*1, c diff --git a/gcc/testsuite/gfortran.dg/char_initialiser_actual.f90 b/gcc/testsuite/gfortran.dg/char_initialiser_actual.f90 index 920e1066014..d123aca136d 100644 --- a/gcc/testsuite/gfortran.dg/char_initialiser_actual.f90 +++ b/gcc/testsuite/gfortran.dg/char_initialiser_actual.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Tests passing of character array initialiser as actual argument. ! Fixes PR18109. ! Contributed by Paul Thomas pault@gcc.gnu.org diff --git a/gcc/testsuite/gfortran.dg/char_pointer_assign.f90 b/gcc/testsuite/gfortran.dg/char_pointer_assign.f90 index ee3da524528..62fcf0360a3 100644 --- a/gcc/testsuite/gfortran.dg/char_pointer_assign.f90 +++ b/gcc/testsuite/gfortran.dg/char_pointer_assign.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! program char_pointer_assign
! Test character pointer assignments, required
! to fix PR18890 and PR21297
@@ -38,4 +40,5 @@ program char_pointer_assign if (any (t2 /= "lnmo")) call abort ()
if (any (c2 /= "onml")) call abort ()
deallocate (c3, c4)
-end program char_pointer_assign
\ No newline at end of file +end program char_pointer_assign + diff --git a/gcc/testsuite/gfortran.dg/char_pointer_dependency.f90 b/gcc/testsuite/gfortran.dg/char_pointer_dependency.f90 index 94976cbb33c..ef2d783e1ff 100644 --- a/gcc/testsuite/gfortran.dg/char_pointer_dependency.f90 +++ b/gcc/testsuite/gfortran.dg/char_pointer_dependency.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Test assignments from character pointer functions with dependencies ! are correctly resolved. ! Provided by Paul Thomas pault@gcc.gnu.org diff --git a/gcc/testsuite/gfortran.dg/char_pointer_dummy.f90 b/gcc/testsuite/gfortran.dg/char_pointer_dummy.f90 index 1935de51113..b533a1cb98c 100644 --- a/gcc/testsuite/gfortran.dg/char_pointer_dummy.f90 +++ b/gcc/testsuite/gfortran.dg/char_pointer_dummy.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! program char_pointer_dummy
! Test character pointer dummy arguments, required
! to fix PR16939 and PR18689
@@ -30,4 +32,5 @@ contains character*4, pointer :: ac1(:)
if (ac1(1) /= "wxyz") call abort ()
end subroutine afoo
-end program char_pointer_dummy
\ No newline at end of file +end program char_pointer_dummy + diff --git a/gcc/testsuite/gfortran.dg/char_pointer_func.f90 b/gcc/testsuite/gfortran.dg/char_pointer_func.f90 index ddca76f40b2..23f867eeb45 100644 --- a/gcc/testsuite/gfortran.dg/char_pointer_func.f90 +++ b/gcc/testsuite/gfortran.dg/char_pointer_func.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! program char_pointer_func ! Test assignments from character pointer functions, required ! to fix PR17192 and PR17202 diff --git a/gcc/testsuite/gfortran.dg/common_8.f90 b/gcc/testsuite/gfortran.dg/common_8.f90 index 5d08fcdee22..ada4408f5d6 100644 --- a/gcc/testsuite/gfortran.dg/common_8.f90 +++ b/gcc/testsuite/gfortran.dg/common_8.f90 @@ -1,4 +1,5 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } ! ! PR fortran/25062 ! diff --git a/gcc/testsuite/gfortran.dg/constant_substring.f b/gcc/testsuite/gfortran.dg/constant_substring.f index c3aff4848e1..4ca11bc160a 100644 --- a/gcc/testsuite/gfortran.dg/constant_substring.f +++ b/gcc/testsuite/gfortran.dg/constant_substring.f @@ -1,5 +1,7 @@ ! Simplify constant substring ! { dg-do run } +! { dg-options "-std=legacy" } +! character*2 a character*4 b character*6 c diff --git a/gcc/testsuite/gfortran.dg/data_char_2.f90 b/gcc/testsuite/gfortran.dg/data_char_2.f90 index 3e021b165f7..26e31a14f08 100644 --- a/gcc/testsuite/gfortran.dg/data_char_2.f90 +++ b/gcc/testsuite/gfortran.dg/data_char_2.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Test that getting a character from a ! string data works. diff --git a/gcc/testsuite/gfortran.dg/der_array_io_1.f90 b/gcc/testsuite/gfortran.dg/der_array_io_1.f90 index b43864d6e14..244b600746c 100644 --- a/gcc/testsuite/gfortran.dg/der_array_io_1.f90 +++ b/gcc/testsuite/gfortran.dg/der_array_io_1.f90 @@ -1,5 +1,7 @@ ! Test IO of arrays of integers in derived types ! { dg-do run } +! { dg-options "-std=legacy" } +! program main character* 10000 :: buf1, buf2 diff --git a/gcc/testsuite/gfortran.dg/der_array_io_2.f90 b/gcc/testsuite/gfortran.dg/der_array_io_2.f90 index c62fd1eb1a0..21e10d21306 100644 --- a/gcc/testsuite/gfortran.dg/der_array_io_2.f90 +++ b/gcc/testsuite/gfortran.dg/der_array_io_2.f90 @@ -1,5 +1,7 @@ ! Test IO of arrays in derived type arrays ! { dg-do run } +! { dg-options "-std=legacy" } +! program main character *1000 buf1, buf2 diff --git a/gcc/testsuite/gfortran.dg/der_array_io_3.f90 b/gcc/testsuite/gfortran.dg/der_array_io_3.f90 index ae89b3dce78..de562152c49 100644 --- a/gcc/testsuite/gfortran.dg/der_array_io_3.f90 +++ b/gcc/testsuite/gfortran.dg/der_array_io_3.f90 @@ -1,5 +1,7 @@ ! Test IO of character arrays in derived types. ! { dg-do run } +! { dg-options "-std=legacy" } +! program main character*1000 buf1, buf2 type :: foo_type diff --git a/gcc/testsuite/gfortran.dg/der_io_3.f90 b/gcc/testsuite/gfortran.dg/der_io_3.f90 index 01066cf56e4..1cb370ce17c 100644 --- a/gcc/testsuite/gfortran.dg/der_io_3.f90 +++ b/gcc/testsuite/gfortran.dg/der_io_3.f90 @@ -1,3 +1,6 @@ +! { dg-do compile } +! { dg-options "-std=legacy" } +! ! PR23843 ! Make sure derived type I/O with PRIVATE components works where it's allowed module m1 diff --git a/gcc/testsuite/gfortran.dg/dev_null.F90 b/gcc/testsuite/gfortran.dg/dev_null.F90 index 2385e19ee6c..b8ba5748593 100644 --- a/gcc/testsuite/gfortran.dg/dev_null.F90 +++ b/gcc/testsuite/gfortran.dg/dev_null.F90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! pr19478 read from /dev/null ! Thomas.Koenig@online.de #if defined _WIN32 diff --git a/gcc/testsuite/gfortran.dg/direct_io_2.f90 b/gcc/testsuite/gfortran.dg/direct_io_2.f90 index cc20f96eedd..8e18052ff01 100644 --- a/gcc/testsuite/gfortran.dg/direct_io_2.f90 +++ b/gcc/testsuite/gfortran.dg/direct_io_2.f90 @@ -1,4 +1,5 @@ ! { dg-do run } +! { dg-options "-std=legacy" } ! ! this testcase derived from NIST test FM413.FOR ! tests writing direct access files in ascending and descending diff --git a/gcc/testsuite/gfortran.dg/do_iterator_2.f90 b/gcc/testsuite/gfortran.dg/do_iterator_2.f90 index 38f59b5e034..7422b9eb575 100644 --- a/gcc/testsuite/gfortran.dg/do_iterator_2.f90 +++ b/gcc/testsuite/gfortran.dg/do_iterator_2.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Tests the fix for pr32613 - see: ! http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/495c154ee188d7f1/ea292134fe68b1d0#ea292134fe68b1d0 ! diff --git a/gcc/testsuite/gfortran.dg/e_d_fmt.f90 b/gcc/testsuite/gfortran.dg/e_d_fmt.f90 index d463d89d6f1..f2a3a5fc553 100644 --- a/gcc/testsuite/gfortran.dg/e_d_fmt.f90 +++ b/gcc/testsuite/gfortran.dg/e_d_fmt.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Verify that the D format uses 'D' as the exponent character. ! " " " E " " 'E' " " " " CHARACTER*10 c1, c2 diff --git a/gcc/testsuite/gfortran.dg/empty_format_1.f90 b/gcc/testsuite/gfortran.dg/empty_format_1.f90 index 79a2d0c17d7..ad60afa3f47 100644 --- a/gcc/testsuite/gfortran.dg/empty_format_1.f90 +++ b/gcc/testsuite/gfortran.dg/empty_format_1.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR 17709 ! We weren't resetting the internal EOR flag correctly, so the second read ! wasn't advancing to the next line. diff --git a/gcc/testsuite/gfortran.dg/entry_17.f90 b/gcc/testsuite/gfortran.dg/entry_17.f90 index d466266cec3..22aabb3a88f 100644 --- a/gcc/testsuite/gfortran.dg/entry_17.f90 +++ b/gcc/testsuite/gfortran.dg/entry_17.f90 @@ -17,19 +17,19 @@ entry bar2() bar2 = "" end function test2 -function test3() ! { dg-warning "is obsolescent" } +function test3() ! { dg-warning "Obsolescent feature" } character(*) :: test3 - character(*) :: bar3 ! { dg-warning "is obsolescent" } + character(*) :: bar3 ! { dg-warning "Obsolescent feature" } test3 = "" return entry bar3() bar3 = "" -end function test3 ! { dg-warning "is obsolescent" } +end function test3 ! { dg-warning "Obsolescent feature" } function test4(n) ! { dg-error "returning variables of different string lengths" } integer :: n character(n) :: test4 - character(*) :: bar4 ! { dg-warning "is obsolescent" } + character(*) :: bar4 ! { dg-warning "Obsolescent feature" } test4 = "" return entry bar4() @@ -45,11 +45,11 @@ entry bar5() bar5 = "" end function test5 -function test6() ! { dg-warning "is obsolescent|returning variables of different string lengths" } +function test6() ! { dg-warning "Obsolescent feature|returning variables of different string lengths" } character(*) :: test6 character(2) :: bar6 test6 = "" return entry bar6() bar6 = "" -end function test6 ! { dg-warning "is obsolescent" } +end function test6 ! { dg-warning "Obsolescent feature" } diff --git a/gcc/testsuite/gfortran.dg/entry_7.f90 b/gcc/testsuite/gfortran.dg/entry_7.f90 index 52940984551..b011fe63bfd 100644 --- a/gcc/testsuite/gfortran.dg/entry_7.f90 +++ b/gcc/testsuite/gfortran.dg/entry_7.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! Check that PR20877 and PR25047 are fixed by the patch for ! PR24558. Both modules would emit the error: ! insert_bbt(): Duplicate key found! diff --git a/gcc/testsuite/gfortran.dg/eor_1.f90 b/gcc/testsuite/gfortran.dg/eor_1.f90 index dd3b5e98f70..cd0004bb2a7 100644 --- a/gcc/testsuite/gfortran.dg/eor_1.f90 +++ b/gcc/testsuite/gfortran.dg/eor_1.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR 19451: The test for advance='NO' with eor used to be reversed. program main character*2 c diff --git a/gcc/testsuite/gfortran.dg/equiv_2.f90 b/gcc/testsuite/gfortran.dg/equiv_2.f90 index 8bc7fb14ac7..ee671f964fd 100644 --- a/gcc/testsuite/gfortran.dg/equiv_2.f90 +++ b/gcc/testsuite/gfortran.dg/equiv_2.f90 @@ -1,3 +1,6 @@ +! { dg-do compile } +! { dg-options "-std=legacy" } +! subroutine broken_equiv1 character*4 h character*3 i diff --git a/gcc/testsuite/gfortran.dg/equiv_constraint_2.f90 b/gcc/testsuite/gfortran.dg/equiv_constraint_2.f90 index d721f967137..8a4e0b5ff85 100644 --- a/gcc/testsuite/gfortran.dg/equiv_constraint_2.f90 +++ b/gcc/testsuite/gfortran.dg/equiv_constraint_2.f90 @@ -30,8 +30,8 @@ type :: char_type sequence - character*4 :: ch - character*4 :: cha (6) + character(4) :: ch + character(4) :: cha (6) end type char_type type (char_type) :: my_char @@ -39,7 +39,7 @@ type :: mixed_type sequence integer :: i(4) - character*4 :: cha (6) + character(4) :: cha (6) end type mixed_type type (mixed_type) :: my_mixed, thy_mixed diff --git a/gcc/testsuite/gfortran.dg/equiv_substr.f90 b/gcc/testsuite/gfortran.dg/equiv_substr.f90 index cd186cf0015..bad3a3a20e8 100644 --- a/gcc/testsuite/gfortran.dg/equiv_substr.f90 +++ b/gcc/testsuite/gfortran.dg/equiv_substr.f90 @@ -1,4 +1,5 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } ! ! PR fortran/34557 ! diff --git a/gcc/testsuite/gfortran.dg/extended_char_comparison_1.f b/gcc/testsuite/gfortran.dg/extended_char_comparison_1.f index 311567dceb0..b3d7c045620 100644 --- a/gcc/testsuite/gfortran.dg/extended_char_comparison_1.f +++ b/gcc/testsuite/gfortran.dg/extended_char_comparison_1.f @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR 27715 - the front end and the library used to have different ideas ! about ordering for characters whose encoding is above 127. diff --git a/gcc/testsuite/gfortran.dg/fmt_bz_bn_err.f b/gcc/testsuite/gfortran.dg/fmt_bz_bn_err.f index 36881f85dc7..579ab26f4d9 100644 --- a/gcc/testsuite/gfortran.dg/fmt_bz_bn_err.f +++ b/gcc/testsuite/gfortran.dg/fmt_bz_bn_err.f @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR38772 r143102 reveals missed error checking on floating point reads. ! Test case contributed by Jack Howarth. program badread diff --git a/gcc/testsuite/gfortran.dg/fmt_error_2.f90 b/gcc/testsuite/gfortran.dg/fmt_error_2.f90 index 8fdaf9e3f21..ae818da7f04 100644 --- a/gcc/testsuite/gfortran.dg/fmt_error_2.f90 +++ b/gcc/testsuite/gfortran.dg/fmt_error_2.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! PR 33269: we used to not simplify format strings before checking if ! they were valid, leading to a missed error. diff --git a/gcc/testsuite/gfortran.dg/fmt_read_bz_bn.f90 b/gcc/testsuite/gfortran.dg/fmt_read_bz_bn.f90 index d0d01937ea2..5eea29a6c14 100644 --- a/gcc/testsuite/gfortran.dg/fmt_read_bz_bn.f90 +++ b/gcc/testsuite/gfortran.dg/fmt_read_bz_bn.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Test various uses of BZ and BN format specifiers. ! Portions inspired by NIST F77 testsuite FM711.f ! Contributed by jvdelisle@verizon.net diff --git a/gcc/testsuite/gfortran.dg/fmt_tl.f b/gcc/testsuite/gfortran.dg/fmt_tl.f index d79146ff02f..656499ed05e 100644 --- a/gcc/testsuite/gfortran.dg/fmt_tl.f +++ b/gcc/testsuite/gfortran.dg/fmt_tl.f @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR25631 Check that TL editing works for special case of no bytes written yet. ! Contributed by Jerry DeLisle <jvdelisle@gcc.gnu.org> real x diff --git a/gcc/testsuite/gfortran.dg/fmt_white.f b/gcc/testsuite/gfortran.dg/fmt_white.f index bcd056f7fb9..6921a722f6a 100644 --- a/gcc/testsuite/gfortran.dg/fmt_white.f +++ b/gcc/testsuite/gfortran.dg/fmt_white.f @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR24268 Test case derived from example given by Iwan Kawrakow ! Embedded spaces in format strings should be ignored. ! Prepared by Jerry DeLisle <jvdelisle@gcc.gnu.org> diff --git a/gcc/testsuite/gfortran.dg/func_derived_1.f90 b/gcc/testsuite/gfortran.dg/func_derived_1.f90 index 496d2905c39..2cf8e449c7e 100644 --- a/gcc/testsuite/gfortran.dg/func_derived_1.f90 +++ b/gcc/testsuite/gfortran.dg/func_derived_1.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR 17244 ! verifies that functions returning derived type work module m diff --git a/gcc/testsuite/gfortran.dg/g77/1832.f b/gcc/testsuite/gfortran.dg/g77/1832.f index 1d2ad92add4..6b7617d62e0 100644 --- a/gcc/testsuite/gfortran.dg/g77/1832.f +++ b/gcc/testsuite/gfortran.dg/g77/1832.f @@ -1,4 +1,6 @@ c { dg-do run } +! { dg-options "-std=legacy" } +! character*5 string write(string, *) "a " if (string .ne. ' a') call abort diff --git a/gcc/testsuite/gfortran.dg/g77/19981216-0.f b/gcc/testsuite/gfortran.dg/g77/19981216-0.f index 1e5db3c3b5c..82d259d3cb5 100644 --- a/gcc/testsuite/gfortran.dg/g77/19981216-0.f +++ b/gcc/testsuite/gfortran.dg/g77/19981216-0.f @@ -1,4 +1,6 @@ c { dg-do compile } +c { dg-options "-std=legacy" } +c * Resent-From: Craig Burley <burley@gnu.org> * Resent-To: craig@jcb-sc.com * X-Delivered: at request of burley on mescaline.gnu.org diff --git a/gcc/testsuite/gfortran.dg/g77/19990525-0.f b/gcc/testsuite/gfortran.dg/g77/19990525-0.f index 589fb8ebfd1..4eb104cdbe2 100644 --- a/gcc/testsuite/gfortran.dg/g77/19990525-0.f +++ b/gcc/testsuite/gfortran.dg/g77/19990525-0.f @@ -1,4 +1,6 @@ c { dg-do compile } +c { dg-options "-std=legacy" } +c * Mailing-List: contact egcs-bugs-help@egcs.cygnus.com; run by ezmlm * Precedence: bulk * Sender: owner-egcs-bugs@egcs.cygnus.com diff --git a/gcc/testsuite/gfortran.dg/g77/19990826-2.f b/gcc/testsuite/gfortran.dg/g77/19990826-2.f index b8384f8d25a..8870c2588d4 100644 --- a/gcc/testsuite/gfortran.dg/g77/19990826-2.f +++ b/gcc/testsuite/gfortran.dg/g77/19990826-2.f @@ -1,4 +1,6 @@ c { dg-do run } +c { dg-options "-std=legacy" } +c * From: "Billinghurst, David (RTD)" <David.Billinghurst@riotinto.com.au> * Subject: RE: single precision complex bug in g77 - was Testing g77 with LA * PACK 3.0 diff --git a/gcc/testsuite/gfortran.dg/g77/20000630-2.f b/gcc/testsuite/gfortran.dg/g77/20000630-2.f index b2776bf6bed..4948c49e494 100644 --- a/gcc/testsuite/gfortran.dg/g77/20000630-2.f +++ b/gcc/testsuite/gfortran.dg/g77/20000630-2.f @@ -1,4 +1,6 @@ c { dg-do compile } +c { dg-options "-std=legacy" } +c SUBROUTINE CHOUT(CHR,ICNT) C ICE: failed assertion `expr != NULL' C Reduced version of GNATS PR fortran/329 from trond.bo@dnmi.no diff --git a/gcc/testsuite/gfortran.dg/g77/20010116.f b/gcc/testsuite/gfortran.dg/g77/20010116.f index dd8ee931297..ca7375d0f68 100644 --- a/gcc/testsuite/gfortran.dg/g77/20010116.f +++ b/gcc/testsuite/gfortran.dg/g77/20010116.f @@ -1,4 +1,6 @@ c { dg-do run } +c { dg-options "-std=legacy" } +c * * Derived from LAPACK 3.0 routine CHGEQZ * Fails on i686-pc-cygwin with gcc-2.97 snapshots at -O2 and higher diff --git a/gcc/testsuite/gfortran.dg/g77/20010519-1.f b/gcc/testsuite/gfortran.dg/g77/20010519-1.f index beead98c7b9..c268bf03eb5 100644 --- a/gcc/testsuite/gfortran.dg/g77/20010519-1.f +++ b/gcc/testsuite/gfortran.dg/g77/20010519-1.f @@ -340,10 +340,10 @@ C..##IF ACE C..##ENDIF C..##IF ADUMB C..##ENDIF - CHARACTER*4 GTRMA, NEXTA4, CURRA4 - CHARACTER*6 NEXTA6 - CHARACTER*8 NEXTA8 - CHARACTER*20 NEXT20 + CHARACTER(4) GTRMA, NEXTA4, CURRA4 + CHARACTER(6) NEXTA6 + CHARACTER(8) NEXTA8 + CHARACTER(20) NEXT20 INTEGER ALLCHR, ALLSTK, ALLHP, DECODI, FIND52, * GETATN, GETRES, GETRSN, GETSEG, GTRMI, I4VAL, * ICHAR4, ICMP16, ILOGI4, INDX, INDXA, INDXAF, @@ -390,11 +390,11 @@ C..##ENDIF C..##IF MMFF INTEGER LEN_TRIM EXTERNAL LEN_TRIM - CHARACTER*4 AtName + CHARACTER(4) AtName external AtName - CHARACTER*8 ElementName + CHARACTER(8) ElementName external ElementName - CHARACTER*10 QNAME + CHARACTER(10) QNAME external QNAME integer IATTCH, IBORDR, CONN12, CONN13, CONN14 integer LEQUIV, LPATH @@ -576,7 +576,7 @@ C..##ENDIF & PIXX = 28, PIXY = 29, PIXZ = 30, PIYX = 31, & PIYY = 32, PIYZ = 33, PIZX = 34, PIZY = 35, & PIZZ = 36) - CHARACTER*4 CEPROP, CETERM, CEPRSS + CHARACTER(4) CEPROP, CETERM, CEPRSS COMMON /ANER/ CEPROP(LENENP), CETERM(LENENT), CEPRSS(LENENV) LOGICAL QEPROP, QETERM, QEPRSS COMMON /QENER/ QEPROP(LENENP), QETERM(LENENT), QEPRSS(LENENV) @@ -653,7 +653,7 @@ C:::##INCLUDE '~/charmm_fcm/ctitla.fcm' INTEGER MAXTIT PARAMETER (MAXTIT=32) INTEGER NTITLA,NTITLB - CHARACTER*80 TITLEA,TITLEB + CHARACTER(80) TITLEA,TITLEB COMMON /NTITLA/ NTITLA,NTITLB COMMON /CTITLA/ TITLEA(MAXTIT),TITLEB(MAXTIT) C..##IF SAVEFCM diff --git a/gcc/testsuite/gfortran.dg/g77/980419-2.f b/gcc/testsuite/gfortran.dg/g77/980419-2.f index defda413eb7..bb02862e30c 100644 --- a/gcc/testsuite/gfortran.dg/g77/980419-2.f +++ b/gcc/testsuite/gfortran.dg/g77/980419-2.f @@ -1,4 +1,6 @@ c { dg-do compile } +c { dg-options "-std=legacy" } +c c SEGVs in loop.c with -O2. character*80 function nxtlin(lun,ierr,itok) diff --git a/gcc/testsuite/gfortran.dg/g77/980520-1.f b/gcc/testsuite/gfortran.dg/g77/980520-1.f index edf7241b997..855b9a442d7 100644 --- a/gcc/testsuite/gfortran.dg/g77/980520-1.f +++ b/gcc/testsuite/gfortran.dg/g77/980520-1.f @@ -1,4 +1,6 @@ c { dg-do run } +c { dg-options "-std=legacy" } +c c Produced a link error through not eliminating the unused statement c function after 1998-05-15 change to gcc/toplev.c. It's in c `execute' since it needs to link. diff --git a/gcc/testsuite/gfortran.dg/g77/check0.f b/gcc/testsuite/gfortran.dg/g77/check0.f index 3febba9d02a..f0a14f826cf 100644 --- a/gcc/testsuite/gfortran.dg/g77/check0.f +++ b/gcc/testsuite/gfortran.dg/g77/check0.f @@ -1,4 +1,6 @@ c { dg-do compile } +c { dg-options "-std=legacy" } +c CCC Abort fixed by: CCC1998-04-21 Jim Wilson <wilson@cygnus.com> CCC diff --git a/gcc/testsuite/gfortran.dg/g77/cpp3.F b/gcc/testsuite/gfortran.dg/g77/cpp3.F index 38387737092..ab25b532945 100644 --- a/gcc/testsuite/gfortran.dg/g77/cpp3.F +++ b/gcc/testsuite/gfortran.dg/g77/cpp3.F @@ -1,4 +1,6 @@ c { dg-do run } +c { dg-options "-std=legacy" } +c ! Some versions of cpp will delete "//'World' as a C++ comment. character*40 title title = 'Hello '//'World' diff --git a/gcc/testsuite/gfortran.dg/g77/cpp4.F b/gcc/testsuite/gfortran.dg/g77/cpp4.F index 0dd5c99edc2..bc14e0469ea 100644 --- a/gcc/testsuite/gfortran.dg/g77/cpp4.F +++ b/gcc/testsuite/gfortran.dg/g77/cpp4.F @@ -1,8 +1,8 @@ - ! { dg-do run } +c { dg-do run } C The preprocessor must not mangle Hollerith constants C which contain apostrophes. integer i - character*4 j + character(4) j data i /4hbla'/ write (j, '(4a)') i if (j .ne. "bla'") call abort diff --git a/gcc/testsuite/gfortran.dg/g77/f77-edit-i-in.f b/gcc/testsuite/gfortran.dg/g77/f77-edit-i-in.f index 49eb41608bb..0369b79db33 100644 --- a/gcc/testsuite/gfortran.dg/g77/f77-edit-i-in.f +++ b/gcc/testsuite/gfortran.dg/g77/f77-edit-i-in.f @@ -4,6 +4,8 @@ C C Origin: David Billinghurst <David.Billinghurst@riotinto.com> C C { dg-do run } +C { dg-options "-std=legacy" } +C integer i,j character*10 buf diff --git a/gcc/testsuite/gfortran.dg/g77/f77-edit-t-in.f b/gcc/testsuite/gfortran.dg/g77/f77-edit-t-in.f index 2314080d708..524b18e3179 100644 --- a/gcc/testsuite/gfortran.dg/g77/f77-edit-t-in.f +++ b/gcc/testsuite/gfortran.dg/g77/f77-edit-t-in.f @@ -4,6 +4,8 @@ C C Origin: David Billinghurst <David.Billinghurst@riotinto.com> C C { dg-do run } +C { dg-options "-std=legacy" } +C integer i,j real a,b,c,d,e character*32 in diff --git a/gcc/testsuite/gfortran.dg/g77/short.f b/gcc/testsuite/gfortran.dg/g77/short.f index e9a18a1315b..330f0ac52b1 100644 --- a/gcc/testsuite/gfortran.dg/g77/short.f +++ b/gcc/testsuite/gfortran.dg/g77/short.f @@ -1,4 +1,6 @@ c { dg-do run } +c { dg-options "-std=legacy" } +c program short parameter ( N=2 ) diff --git a/gcc/testsuite/gfortran.dg/g77_intrinsics_funcs.f b/gcc/testsuite/gfortran.dg/g77_intrinsics_funcs.f index 551bd61cd65..f9e0195bcdb 100644 --- a/gcc/testsuite/gfortran.dg/g77_intrinsics_funcs.f +++ b/gcc/testsuite/gfortran.dg/g77_intrinsics_funcs.f @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! Testing g77 intrinsics as subroutines integer(kind=8) i8 integer i4 diff --git a/gcc/testsuite/gfortran.dg/g77_intrinsics_sub.f b/gcc/testsuite/gfortran.dg/g77_intrinsics_sub.f index d1591e04bef..6ee5f837cc4 100644 --- a/gcc/testsuite/gfortran.dg/g77_intrinsics_sub.f +++ b/gcc/testsuite/gfortran.dg/g77_intrinsics_sub.f @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! Testing g77 intrinsics as subroutines integer(kind=8) i8, j8 integer i4, j4 diff --git a/gcc/testsuite/gfortran.dg/global_references_2.f90 b/gcc/testsuite/gfortran.dg/global_references_2.f90 index 95666981ac0..bf2528006a0 100644 --- a/gcc/testsuite/gfortran.dg/global_references_2.f90 +++ b/gcc/testsuite/gfortran.dg/global_references_2.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! This program tests the patch for PR25964. This is a ! regression that would not allow a common block and a statement ! to share the same name. @@ -7,4 +9,5 @@ common /foo/ a, b, c foo (x) = x + 1.0 print *, foo (0.0) - end
\ No newline at end of file + end + diff --git a/gcc/testsuite/gfortran.dg/graphite/block-1.f90 b/gcc/testsuite/gfortran.dg/graphite/block-1.f90 index 124f06d16eb..8125853b937 100644 --- a/gcc/testsuite/gfortran.dg/graphite/block-1.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/block-1.f90 @@ -1,5 +1,3 @@ -! { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } - subroutine matrix_multiply(a,b,c,n) real(8), dimension(n,n) :: a,b,c diff --git a/gcc/testsuite/gfortran.dg/graphite/block-2.f b/gcc/testsuite/gfortran.dg/graphite/block-2.f index af966ec5f97..6c7ee6fe951 100644 --- a/gcc/testsuite/gfortran.dg/graphite/block-2.f +++ b/gcc/testsuite/gfortran.dg/graphite/block-2.f @@ -1,5 +1,3 @@ -! { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } - SUBROUTINE MATRIX_MUL_UNROLLED (A, B, C, L, M, N) DIMENSION A(L,M), B(M,N), C(L,N) diff --git a/gcc/testsuite/gfortran.dg/graphite/block-3.f90 b/gcc/testsuite/gfortran.dg/graphite/block-3.f90 index c7809d3431b..1579e66e411 100644 --- a/gcc/testsuite/gfortran.dg/graphite/block-3.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/block-3.f90 @@ -1,5 +1,3 @@ -! { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } - subroutine matrix_multiply(a,b,c,n) real(8), dimension(n,n) :: a,b,c diff --git a/gcc/testsuite/gfortran.dg/graphite/block-4.f90 b/gcc/testsuite/gfortran.dg/graphite/block-4.f90 index 586a7772512..f37d70aec3f 100644 --- a/gcc/testsuite/gfortran.dg/graphite/block-4.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/block-4.f90 @@ -1,5 +1,3 @@ -! { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } - subroutine matrix_multiply(a,b,c,n) real(8), dimension(n,n) :: a,b,c diff --git a/gcc/testsuite/gfortran.dg/graphite/graphite.exp b/gcc/testsuite/gfortran.dg/graphite/graphite.exp index a9fdb2c508f..717413e63ce 100644 --- a/gcc/testsuite/gfortran.dg/graphite/graphite.exp +++ b/gcc/testsuite/gfortran.dg/graphite/graphite.exp @@ -23,23 +23,64 @@ if ![check_effective_target_fgraphite] { return } +# Remove VALUE from LIST_VARIABLE. +proc lremove {list_variable value} { + upvar 1 $list_variable var + set idx [lsearch -exact $var $value] + set var [lreplace $var $idx $idx] +} + # The default action for a test is 'compile'. Save current default. global dg-do-what-default set save-dg-do-what-default ${dg-do-what-default} set dg-do-what-default compile -# If a testcase doesn't have special options, use these. -set DEFAULT_GRAPHITE_FLAGS "" - # Initialize `dg'. dg-init # Main loop. -gfortran-dg-runtest [lsort \ - [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ] ] $DEFAULT_GRAPHITE_FLAGS +set wait_to_run_files [lsort [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ] ] + +# Flags using for block-* files. +set DEFAULT_FLAGS_GRAPHITE_BLOCK "-O2 -fdump-tree-graphite-all" +set block_files [lsort [glob -nocomplain $srcdir/$subdir/block-*.\[fF\]{,90,95,03,08} ] ] +gfortran-dg-runtest $block_files $DEFAULT_FLAGS_GRAPHITE_BLOCK +foreach block_file $block_files {lremove wait_to_run_files $block_file} + +# Flags using for id-* files. +set DEFAULT_FLAGS_GRAPHITE_IDENTITY "-O2 -fgraphite-identity -fdump-tree-graphite-all" +set id_files [lsort [glob -nocomplain $srcdir/$subdir/id-*.\[fF\]{,90,95,03,08} ] ] +gfortran-dg-runtest $id_files $DEFAULT_FLAGS_GRAPHITE_IDENTITY +foreach id_file $id_files {lremove wait_to_run_files $id_file} + +# Flags using for interchange-* files. +set DEFAULT_FLAGS_GRAPHITE_BLOCK "-O2 -fdump-tree-graphite-all -floop-interchange" +set interchange_files [lsort [glob -nocomplain $srcdir/$subdir/interchange-*.\[fF\]{,90,95,03,08} ] ] +gfortran-dg-runtest $interchange_files $DEFAULT_FLAGS_GRAPHITE_BLOCK +foreach interchange_file $interchange_files {lremove wait_to_run_files $interchange_file} -gfortran-dg-runtest [lsort \ - [glob -nocomplain $srcdir/$subdir/g77/*.\[fF\] ] ] $DEFAULT_GRAPHITE_FLAGS +# Flags using for scop-* files. +set DEFAULT_FLAGS_GRAPHITE_SCOP "-O2 -fgraphite -fdump-tree-graphite-all" +set scop_files [lsort [glob -nocomplain $srcdir/$subdir/scop-*.\[fF\]{,90,95,03,08} ] ] +gfortran-dg-runtest $scop_files $DEFAULT_FLAGS_GRAPHITE_SCOP +foreach scop_file $scop_files {lremove wait_to_run_files $scop_file} + +# Schedule now the tests to be run. +set dg-do-what-default run + +# Flags using for run-id-* files. +set DEFAULT_FLAGS_RUN_ID "-O2 -fgraphite-identity" +set run_id_files [lsort [glob -nocomplain $srcdir/$subdir/run-id-*.\[fF\]{,90,95,03,08} ] ] +gfortran-dg-runtest $run_id_files $DEFAULT_FLAGS_RUN_ID +foreach run_id_file $run_id_files {lremove wait_to_run_files $run_id_file} + + +# The default action for the rest of the files is 'compile'. +set dg-do-what-default compile + +# Flags using for other files. +set DEFAULT_GRAPHITE_FLAGS "" +gfortran-dg-runtest $wait_to_run_files $DEFAULT_GRAPHITE_FLAGS # Clean up. set dg-do-what-default ${save-dg-do-what-default} diff --git a/gcc/testsuite/gfortran.dg/graphite/id-1.f90 b/gcc/testsuite/gfortran.dg/graphite/id-1.f90 new file mode 100644 index 00000000000..5fe709bfb07 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/id-1.f90 @@ -0,0 +1,11 @@ +program NF +end program NF +subroutine mattest(nx,ny,nz,band1,band2,band3,stiffness,maxiter,targrms,method) + integer,parameter :: dpkind=kind(1.0D0) + character(*) :: method + real(dpkind),allocatable,dimension(:) :: ad,au1,au2,au3,x,b + allocate(ad(nxyz),au1(nxyz),au2(nxyz),au3(nxyz),x(nxyz),b(nxyz)) + au1(nx:nxyz:nx) = 0.0 + if ( method=='NFCG' ) then + endif +end subroutine mattest diff --git a/gcc/testsuite/gfortran.dg/graphite/id-10.f90 b/gcc/testsuite/gfortran.dg/graphite/id-10.f90 new file mode 100644 index 00000000000..0e016f25319 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/id-10.f90 @@ -0,0 +1,11 @@ +subroutine foo ( uplo, ap, y ) + character*1 uplo + complex(kind((1.0d0,1.0d0))) ap( * ), y( * ) + if ( .not. scan( uplo, 'uu' )>0.and. & + .not. scan( uplo, 'll' )>0 )then + do 60, j = 1, n + y( j ) = y( j ) + dble( ap( kk ) ) + kk = kk + j + 60 continue + end if + end diff --git a/gcc/testsuite/gfortran.dg/graphite/id-11.f b/gcc/testsuite/gfortran.dg/graphite/id-11.f new file mode 100644 index 00000000000..872e12f359e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/id-11.f @@ -0,0 +1,14 @@ + subroutine foo(bar) + dimension bar(100) + common l_ + 50 continue + do i=1,20 + bar(i)=0 + enddo + do 100 j=1,l_ + if(sum.gt.r) then + bar(n2)=j + end if + 100 continue + if(bar(4).ne.0) go to 50 + end diff --git a/gcc/testsuite/gfortran.dg/graphite/id-12.f b/gcc/testsuite/gfortran.dg/graphite/id-12.f new file mode 100644 index 00000000000..5b7415ca0ec --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/id-12.f @@ -0,0 +1,19 @@ + subroutine foo(a) + logical bar + dimension a(12,2) + dimension b(12,8) + if(cd .eq. 1) then + if (bar) write(iw,*) norb + if(ef.ne.1) then + do i=1,norb + end do + end if + end if + do 400 j = 1,8 + b(i,j) = 0 + 400 continue + do 410 j=1,norb + a(i,j) = 0 + 410 continue + call rdrsym(b) + end diff --git a/gcc/testsuite/gfortran.dg/graphite/id-13.f b/gcc/testsuite/gfortran.dg/graphite/id-13.f new file mode 100644 index 00000000000..9aec1fa6ba9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/id-13.f @@ -0,0 +1,12 @@ + DIMENSION FF(19) + COMMON UF(9) + CALL RYSNOD(K) + DO 150 K=2,N + JMAX=K-1 + DUM = ONE/FF(1) + DO 110 J=1,JMAX + DUM=DUM+POLY*POLY + 110 CONTINUE + 150 CONTINUE + UF(K)=DUM/(ONE-DUM) + END diff --git a/gcc/testsuite/gfortran.dg/graphite/id-14.f b/gcc/testsuite/gfortran.dg/graphite/id-14.f new file mode 100644 index 00000000000..cdc3d101c95 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/id-14.f @@ -0,0 +1,20 @@ + SUBROUTINE ORDORB(IORBTP,IORBCD) + LOGICAL MASWRK + DIMENSION IORBTP(12,12) + DIMENSION IORBCD(12) + DIMENSION NSYMTP(12,8) + IF (MASWRK) WRITE(IW) K,NORB + DO 280 I=1,NFZV + IORBCD(K+I) = 3 + 280 CONTINUE + DO 420 I = 1,NTPS + DO 400 J = 1,8 + NSYMTP(I,J) = 0 + 400 CONTINUE + DO 410 J=1,NORB + IORBTP(I,J) = 0 + 410 CONTINUE + 420 CONTINUE + CALL RDRSYM(ICODE,NSYMTP,NSYM) + 9055 FORMAT(I5) + END diff --git a/gcc/testsuite/gfortran.dg/graphite/id-15.f b/gcc/testsuite/gfortran.dg/graphite/id-15.f new file mode 100644 index 00000000000..bf60d856913 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/id-15.f @@ -0,0 +1,16 @@ + SUBROUTINE ORDORB(IORBTP) + LOGICAL MASWRK + DIMENSION IORBTP(12,12) + DIMENSION NSYMTP(12,8) + IF (MASWRK) WRITE(IW) K,NORB + DO 420 I = 1,NTPS + DO 400 J = 1,8 + NSYMTP(I,J) = 0 + 400 CONTINUE + DO 410 J=1,NORB + IORBTP(I,J) = 0 + 410 CONTINUE + 420 CONTINUE + CALL RDRSYM(ICODE,NSYMTP,NSYM) + 9055 FORMAT(I5) + END diff --git a/gcc/testsuite/gfortran.dg/graphite/id-16.f b/gcc/testsuite/gfortran.dg/graphite/id-16.f new file mode 100644 index 00000000000..323d6c958f0 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/id-16.f @@ -0,0 +1,10 @@ + SUBROUTINE BFN(X,BF) + DIMENSION BF(13) + DIMENSION FACT(17) + DO 70 M=0,LAST + XF = 1 + IF(M.NE.0) XF = FACT(M) + Y = Y + XF + 70 CONTINUE + BF(1)=Y + END diff --git a/gcc/testsuite/gfortran.dg/graphite/id-2.f90 b/gcc/testsuite/gfortran.dg/graphite/id-2.f90 index 0c9f54bb979..720fff8dd02 100644 --- a/gcc/testsuite/gfortran.dg/graphite/id-2.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/id-2.f90 @@ -1,5 +1,3 @@ -! { dg-options "-O2 -fgraphite-identity" } - module solv_cap integer, parameter, public :: dp = selected_real_kind(5) contains diff --git a/gcc/testsuite/gfortran.dg/graphite/id-3.f90 b/gcc/testsuite/gfortran.dg/graphite/id-3.f90 index 394bdf7ac16..7f0efc7bc8e 100644 --- a/gcc/testsuite/gfortran.dg/graphite/id-3.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/id-3.f90 @@ -1,5 +1,3 @@ -! { dg-options "-O2 -fgraphite-identity" } - subroutine gentrs (ptrst, ncls, xmin, dcls, xdont, ndon) do icls1 = 1, ncls prec: do diff --git a/gcc/testsuite/gfortran.dg/graphite/id-4.f90 b/gcc/testsuite/gfortran.dg/graphite/id-4.f90 index 896d608777e..b2c6cb04edc 100644 --- a/gcc/testsuite/gfortran.dg/graphite/id-4.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/id-4.f90 @@ -1,5 +1,3 @@ -! { dg-options "-O2 -fgraphite-identity" } - MODULE Vcimage CHARACTER (LEN=80), SAVE :: CARD, FIELD END MODULE Vcimage diff --git a/gcc/testsuite/gfortran.dg/graphite/id-5.f b/gcc/testsuite/gfortran.dg/graphite/id-5.f new file mode 100644 index 00000000000..b9e93e39c1c --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/id-5.f @@ -0,0 +1,19 @@ + subroutine shell(Re,Pr,nx,ny,nz, + $nuim,nuex2,nuex4,cfl,scheme,conf,ni,maxit) + real*8 q(5,nx,ny,nz),dq(5,nx,ny,nz),rhs(5,nx,ny,nz),e(5,nx,ny,nz), + 1 f(5,nx,ny,nz),g(5,nx,ny,nz),ev(5,nx,ny,nz),fv(5,nx,ny,nz), + 2 gv(5,nx,ny,nz),diss(5,nx,ny,nz) + do k=1,nz + do j=1,ny + do i=1,nx + do l=1,5 + t1= -0.5d0*dt*( + 3 (g(l,i,j,kp1)-g(l,i,j,km1))/dz) + + 4 dt/Re*((ev(l,i,j,k)-ev(l,im1,j,k))/dx + + 6 (gv(l,i,j,k)-gv(l,i,j,km1))/dz) + rhs(l,i,j,k)=t1+t2 + enddo + enddo + enddo + enddo + end diff --git a/gcc/testsuite/gfortran.dg/graphite/id-6.f b/gcc/testsuite/gfortran.dg/graphite/id-6.f new file mode 100644 index 00000000000..2ccb4632afe --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/id-6.f @@ -0,0 +1,22 @@ + SUBROUTINE EIJDEN(EPS,V,E,IA,WRK,L1,L2,L3,L0,ECI) + DIMENSION V(L1,L0),EPS(L2),E(*),IA(L1),WRK(L1),ECI(L0,L0) + IF(SCFTYP.EQ.RHF .AND. MPLEVL.EQ.0 .AND. + * CITYP.NE.GUGA .AND. CITYP.NE.CIS) THEN + CALL DCOPY(NORB,E(IADDE),1,E(IADD),1) + END IF + IF (CITYP.NE.GUGA) THEN + DO 500 I = 1,L1 + DO 430 L = 1,NORB + DO 420 K = 1,NORB + IF(K.LE.L) THEN + WRK(L) = WRK(L) - V(I,K)*ECI(K,L) + ELSE + WRK(L) = WRK(L) - V(I,K)*ECI(L,K) + END IF + 420 CONTINUE + 430 CONTINUE + DO 440 L = 1,NORB + 440 CONTINUE + 500 CONTINUE + END IF + END diff --git a/gcc/testsuite/gfortran.dg/graphite/id-7.f b/gcc/testsuite/gfortran.dg/graphite/id-7.f new file mode 100644 index 00000000000..dbbbe37a484 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/id-7.f @@ -0,0 +1,14 @@ + subroutine dasol(al,au,ad,b,jp,neq,energy) + real*8 al(*),au(*),ad(*),b(*),zero,energy,bd,dot + do 100 is=1,neq + if(b(is).ne.zero) go to 200 + 100 continue + return + 200 if(is.lt.neq) then + endif + do 400 j = is,neq + energy=energy+bd*b(j) + 400 continue + if(neq.gt.1)then + endif + end diff --git a/gcc/testsuite/gfortran.dg/graphite/id-8.f b/gcc/testsuite/gfortran.dg/graphite/id-8.f new file mode 100644 index 00000000000..6594dda24a9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/id-8.f @@ -0,0 +1,17 @@ + subroutine foo(mxgtot,mxsh) + logical b + dimension ex(mxgtot),cs(mxgtot) + do 500 jg = k1,ig + u = ex(ig)+ex(jg) + z = u*sqrt(u) + x = cs(ig)*cs(jg)/z + if (ig .eq. jg) go to 480 + x = x+x + 480 continue + y = y+x + 500 continue + if(y.gt.t) z=1/sqrt(y) + if (b) then + write(9) z + endif + end diff --git a/gcc/testsuite/gfortran.dg/graphite/id-9.f b/gcc/testsuite/gfortran.dg/graphite/id-9.f new file mode 100644 index 00000000000..c9393708897 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/id-9.f @@ -0,0 +1,20 @@ + subroutine foo(bar) + real*8 bar(3,3),coefm + do ii=istart,iend + do i=1,21 + bar(k,l)=4 + enddo + do m=1,ne + do l=1,3 + do k=1,l + enddo + bar(k,l)=bar(k,l)+(v3b-1.d0) + enddo + enddo + do m=1,ne + do k=1,l + l = l*(v3b**(-coefm)) + enddo + enddo + enddo + end diff --git a/gcc/testsuite/gfortran.dg/graphite/interchange-1.f b/gcc/testsuite/gfortran.dg/graphite/interchange-1.f new file mode 100644 index 00000000000..a73bb131ff4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/interchange-1.f @@ -0,0 +1,38 @@ + subroutine foo(f1,f2,f3,f4,f5,f6,f7,f8,f9,f0,g1,g2,g3) + implicit none + integer f4,f3,f2,f1 + integer g4,g5,g6,g7,g8,g9 + integer i1,i2,i3,i4,i5 + + real*8 g1(5,f3,f2,f1),g2(5,5,f3,f2,f1),g3(5,f3,f2,f1) + real*8 f0(5,5,f3,f2,f1),f9(5,5,f3,f2,f1),f8(5,5,f3,f2,f1) + real*8 f7(5,5,f3,f2,f1),f6(5,5,f3,f2,f1),f5(5,5,f3,f2,f1) + + do i3=1,f1 + g8=mod(i3+f1-2,f1)+1 + g9=mod(i3,f1)+1 + do i4=1,f2 + g6=mod(i4+f2-2,f2)+1 + g7=mod(i4,f2)+1 + do i5=1,f3 + g4=mod(i5+f3-2,f3)+1 + g5=mod(i5,f3)+1 + do i1=1,5 + g3(i1,i5,i4,i3)=0.0d0 + do i2=1,5 + g3(i1,i5,i4,i3)=g3(i1,i5,i4,i3)+ + 1 g2(i1,i2,i5,i4,i3)*g1(i2,i5,i4,i3)+ + 2 f0(i1,i2,i5,i4,i3)*g1(i2,g5,i4,i3)+ + 3 f9(i1,i2,i5,i4,i3)*g1(i2,i5,g7,i3)+ + 4 f8(i1,i2,i5,i4,i3)*g1(i2,i5,i4,g9)+ + 5 f7(i1,i2,i5,i4,i3)*g1(i2,g4,i4,i3)+ + 6 f6(i1,i2,i5,i4,i3)*g1(i2,i5,g6,i3)+ + 7 f5(i1,i2,i5,i4,i3)*g1(i2,i5,i4,g8) + enddo + enddo + enddo + enddo + enddo + return + end + diff --git a/gcc/testsuite/gfortran.dg/graphite/interchange-2.f b/gcc/testsuite/gfortran.dg/graphite/interchange-2.f new file mode 100644 index 00000000000..6418c0c89e6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/interchange-2.f @@ -0,0 +1,38 @@ + subroutine foo(f1,f2,f3,f4,f5,f6,f7,f8,f9,f0,g1,g2,g3) + implicit none + integer f4,f3,f2,f1 + integer g4,g5,g6,g7,g8,g9 + integer i1,i2,i3,i4,i5 + + real*8 g1(f4,f3,f2,f1),g2(f4,f4,f3,f2,f1),g3(f4,f3,f2,f1) + real*8 f0(f4,f4,f3,f2,f1),f9(f4,f4,f3,f2,f1),f8(f4,f4,f3,f2,f1) + real*8 f7(f4,f4,f3,f2,f1),f6(f4,f4,f3,f2,f1),f5(f4,f4,f3,f2,f1) + + do i3=1,f1 + g8=mod(i3+f1-2,f1)+1 + g9=mod(i3,f1)+1 + do i4=1,f2 + g6=mod(i4+f2-2,f2)+1 + g7=mod(i4,f2)+1 + do i5=1,f3 + g4=mod(i5+f3-2,f3)+1 + g5=mod(i5,f3)+1 + do i1=1,f4 + g3(i1,i5,i4,i3)=0.0d0 + do i2=1,f4 + g3(i1,i5,i4,i3)=g3(i1,i5,i4,i3)+ + 1 g2(i1,i2,i5,i4,i3)*g1(i2,i5,i4,i3)+ + 2 f0(i1,i2,i5,i4,i3)*g1(i2,g5,i4,i3)+ + 3 f9(i1,i2,i5,i4,i3)*g1(i2,i5,g7,i3)+ + 4 f8(i1,i2,i5,i4,i3)*g1(i2,i5,i4,g9)+ + 5 f7(i1,i2,i5,i4,i3)*g1(i2,g4,i4,i3)+ + 6 f6(i1,i2,i5,i4,i3)*g1(i2,i5,g6,i3)+ + 7 f5(i1,i2,i5,i4,i3)*g1(i2,i5,i4,g8) + enddo + enddo + enddo + enddo + enddo + return + end + diff --git a/gcc/testsuite/gfortran.dg/graphite/pr37852.f90 b/gcc/testsuite/gfortran.dg/graphite/pr37852.f90 index 50e23428f82..a5d48b7124a 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr37852.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr37852.f90 @@ -1,4 +1,4 @@ -! { dg-options "-O2 -floop-block" } +! { dg-options "-O2 " } PROGRAM TEST_FPU CHARACTER (LEN=36) :: invert_id(1) = & diff --git a/gcc/testsuite/gfortran.dg/graphite/pr37857.f90 b/gcc/testsuite/gfortran.dg/graphite/pr37857.f90 index de2d3a124ee..c2cccb775da 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr37857.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr37857.f90 @@ -1,4 +1,4 @@ -! { dg-options "-O2 -floop-block" } +! { dg-options "-O2 " } program superficie_proteina integer, parameter :: LONGreal = selected_real_kind(12,90) diff --git a/gcc/testsuite/gfortran.dg/graphite/pr37980.f90 b/gcc/testsuite/gfortran.dg/graphite/pr37980.f90 index 5306aa84c92..62eccf35ff1 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr37980.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr37980.f90 @@ -1,4 +1,4 @@ -! { dg-options "-O2 -floop-block" } +! { dg-options "-O2 " } module INT_MODULE contains diff --git a/gcc/testsuite/gfortran.dg/graphite/pr38083.f90 b/gcc/testsuite/gfortran.dg/graphite/pr38083.f90 index 834d33ab833..da8c3cc7914 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr38083.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr38083.f90 @@ -1,4 +1,4 @@ -! { dg-options "-O3 -floop-block" } +! { dg-options "-O3 " } SUBROUTINE IVSORT (IL,IH,NSEGS,IOUNIT) INTEGER IOUNIT diff --git a/gcc/testsuite/gfortran.dg/graphite/pr38953.f90 b/gcc/testsuite/gfortran.dg/graphite/pr38953.f90 index 245db0dfe28..73224764f16 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr38953.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr38953.f90 @@ -1,4 +1,4 @@ -! { dg-options "-O3 -floop-block -fgraphite-identity" } +! { dg-options "-O3 -fgraphite-identity" } MODULE MAIN1 INTEGER , PARAMETER :: IFMAX = 40 , IKN = 85 , ISTRG = 132 , & diff --git a/gcc/testsuite/gfortran.dg/graphite/scop-1.f b/gcc/testsuite/gfortran.dg/graphite/scop-1.f index a279abaf9c2..5bd463c4e9c 100644 --- a/gcc/testsuite/gfortran.dg/graphite/scop-1.f +++ b/gcc/testsuite/gfortran.dg/graphite/scop-1.f @@ -1,5 +1,3 @@ -C { dg-options "-O2 -fgraphite" } - dimension p1(2),t(6,4),b1(2),b2(2),al1(2),al2(2),g1(2),g2(2) save if(nlin.eq.0) then @@ -11,3 +9,5 @@ C { dg-options "-O2 -fgraphite" } endif end +! { dg-final { scan-tree-dump-times "number of SCoPs: 1" 1 "graphite" { xfail *-*-* } } } +! { dg-final { cleanup-tree-dump "graphite" } } diff --git a/gcc/testsuite/gfortran.dg/hollerith.f90 b/gcc/testsuite/gfortran.dg/hollerith.f90 index 21cbf66bdf6..697ed22d892 100644 --- a/gcc/testsuite/gfortran.dg/hollerith.f90 +++ b/gcc/testsuite/gfortran.dg/hollerith.f90 @@ -3,14 +3,14 @@ implicit none complex(kind=8) x(2) complex a(2,2) -character*4 z +character(4) z character z1(4) -character*4 z2(2,2) -character*80 line +character(4) z2(2,2) +character(80) line integer i integer j real r -character*8 c +character(8) c data x /16Habcdefghijklmnop, 16Hqrstuvwxyz012345/ data a /8H(i3),abc, 0, 4H(i4), 8H (i9)/ @@ -53,7 +53,7 @@ end subroutine test (h) integer(kind=8) h -character*80 line +character(80) line write (line, '(8a)') h if (line .ne. ' hello') call abort diff --git a/gcc/testsuite/gfortran.dg/hollerith_1.f90 b/gcc/testsuite/gfortran.dg/hollerith_1.f90 index d6732d40b69..829ca7f99c2 100644 --- a/gcc/testsuite/gfortran.dg/hollerith_1.f90 +++ b/gcc/testsuite/gfortran.dg/hollerith_1.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR 21260 ! We wrongly interpreted the '!' as the beginning of a comment. ! Also verifies the functioning of hollerith formatting. diff --git a/gcc/testsuite/gfortran.dg/hollerith_f95.f90 b/gcc/testsuite/gfortran.dg/hollerith_f95.f90 index 4d7fda8c72e..dc52187adb9 100644 --- a/gcc/testsuite/gfortran.dg/hollerith_f95.f90 +++ b/gcc/testsuite/gfortran.dg/hollerith_f95.f90 @@ -4,14 +4,14 @@ implicit none complex(kind=8) x(2) complex a(2,2) -character*4 z +character(4) z character z1(4) -character*4 z2(2,2) -character*80 line +character(4) z2(2,2) +character(80) line integer i logical l real r -character*8 c +character(8) c data x /16Habcdefghijklmnop, 16Hqrstuvwxyz012345/ data a /8H(i3),abc, 0, 4H(i4), 8H (i9)/ @@ -54,7 +54,7 @@ end subroutine test (h) integer(kind=8) h -character*80 line +character(80) line write (line, '(8a)') h if (line .ne. ' hello') call abort diff --git a/gcc/testsuite/gfortran.dg/ichar_1.f90 b/gcc/testsuite/gfortran.dg/ichar_1.f90 index 104c5d166af..362cd2f453b 100644 --- a/gcc/testsuite/gfortran.dg/ichar_1.f90 +++ b/gcc/testsuite/gfortran.dg/ichar_1.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! PR20879 ! Check that we reject expressions longer than one character for the ! ICHAR and IACHAR intrinsics. diff --git a/gcc/testsuite/gfortran.dg/implicit_6.f90 b/gcc/testsuite/gfortran.dg/implicit_6.f90 index bb7fe3221ab..a74ecc29ba5 100644 --- a/gcc/testsuite/gfortran.dg/implicit_6.f90 +++ b/gcc/testsuite/gfortran.dg/implicit_6.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! PR 24643 ! substring references on implicitly typed CHARACTER variables didn't work PROGRAM P diff --git a/gcc/testsuite/gfortran.dg/implicit_9.f90 b/gcc/testsuite/gfortran.dg/implicit_9.f90 index 335c85bffb1..04b7afa4ed8 100644 --- a/gcc/testsuite/gfortran.dg/implicit_9.f90 +++ b/gcc/testsuite/gfortran.dg/implicit_9.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! Tests patch for PR29373, in which the implicit character ! statement messes up the function declaration because the ! requisite functions in decl.c were told nothing about diff --git a/gcc/testsuite/gfortran.dg/initialization_23.f90 b/gcc/testsuite/gfortran.dg/initialization_23.f90 new file mode 100644 index 00000000000..cc2aca4e223 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/initialization_23.f90 @@ -0,0 +1,17 @@ +! { dg-do compile } +! +! PR 40875: The error was missed and an ICE ensued. +! +! Contributed by Michael Richmond <michael.a.richmond@nasa.gov> +! + MODULE cdf_aux_mod + PUBLIC + TYPE :: one_parameter + CHARACTER :: name + END TYPE one_parameter + CHARACTER, PARAMETER :: the_alpha = one_parameter('c') ! { dg-error "Can't convert TYPE" } + CHARACTER, PARAMETER :: the_beta = (/one_parameter('c')/) ! { dg-error "Incompatible ranks" } + END MODULE cdf_aux_mod + +! { dg-final { cleanup-modules "cdf_aux_mod" } } + diff --git a/gcc/testsuite/gfortran.dg/inquire.f90 b/gcc/testsuite/gfortran.dg/inquire.f90 index 9f3b72532af..7115913c6c6 100644 --- a/gcc/testsuite/gfortran.dg/inquire.f90 +++ b/gcc/testsuite/gfortran.dg/inquire.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! check to see that you cannot open a direct access file ! for sequential i/o. ! derived from NIST test fm910.for diff --git a/gcc/testsuite/gfortran.dg/inquire_13.f90 b/gcc/testsuite/gfortran.dg/inquire_13.f90 index 366e383327f..d074861a97b 100644 --- a/gcc/testsuite/gfortran.dg/inquire_13.f90 +++ b/gcc/testsuite/gfortran.dg/inquire_13.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR34795 inquire statement , direct= specifier incorrectly returns YES ! Test case from PR, modified by Jerry DeLisle <jvdelisle@gcc.gnu.org program testinquire diff --git a/gcc/testsuite/gfortran.dg/inquire_5.f90 b/gcc/testsuite/gfortran.dg/inquire_5.f90 index b2e07be9319..fe107a19863 100644 --- a/gcc/testsuite/gfortran.dg/inquire_5.f90 +++ b/gcc/testsuite/gfortran.dg/inquire_5.f90 @@ -1,4 +1,6 @@ ! { dg-do run { target fd_truncate } } +! { dg-options "-std=legacy" } +! ! pr19314 inquire(..position=..) segfaults ! test by Thomas.Koenig@online.de ! bdavis9659@comcast.net diff --git a/gcc/testsuite/gfortran.dg/inquire_6.f90 b/gcc/testsuite/gfortran.dg/inquire_6.f90 index 7575b6e67b3..b657df831d9 100644 --- a/gcc/testsuite/gfortran.dg/inquire_6.f90 +++ b/gcc/testsuite/gfortran.dg/inquire_6.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! !pr19313 - inquire(..pad=..) implicit none ! logical debug diff --git a/gcc/testsuite/gfortran.dg/io_constraints_1.f90 b/gcc/testsuite/gfortran.dg/io_constraints_1.f90 index 5f2c776b128..db1e949e7a5 100644 --- a/gcc/testsuite/gfortran.dg/io_constraints_1.f90 +++ b/gcc/testsuite/gfortran.dg/io_constraints_1.f90 @@ -29,7 +29,7 @@ end module global use global integer :: a,b, c(20) integer(8) :: ierr - character*80 :: buffer(3) + character(80) :: buffer(3) ! Appending to a USE associated namelist is an extension. diff --git a/gcc/testsuite/gfortran.dg/io_constraints_2.f90 b/gcc/testsuite/gfortran.dg/io_constraints_2.f90 index 8bf48d72ff2..8d3ae6b45f4 100644 --- a/gcc/testsuite/gfortran.dg/io_constraints_2.f90 +++ b/gcc/testsuite/gfortran.dg/io_constraints_2.f90 @@ -25,7 +25,7 @@ end module global use global integer :: a,b, c(20) integer(8) :: ierr - character*80 :: buffer(3) + character(80) :: buffer(3) ! Appending to a USE associated namelist is an extension. diff --git a/gcc/testsuite/gfortran.dg/list_read_2.f90 b/gcc/testsuite/gfortran.dg/list_read_2.f90 index e757f613e44..3e6c233c09a 100644 --- a/gcc/testsuite/gfortran.dg/list_read_2.f90 +++ b/gcc/testsuite/gfortran.dg/list_read_2.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR16805 ! Test list directed reads from character substrings ! The IO library was reporting an error rather the end-of-record when it diff --git a/gcc/testsuite/gfortran.dg/loc_2.f90 b/gcc/testsuite/gfortran.dg/loc_2.f90 index 196dcc6db74..d905fc0f74b 100644 --- a/gcc/testsuite/gfortran.dg/loc_2.f90 +++ b/gcc/testsuite/gfortran.dg/loc_2.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Series of routines for testing a loc() implementation program test common /errors/errors(12) diff --git a/gcc/testsuite/gfortran.dg/logical_1.f90 b/gcc/testsuite/gfortran.dg/logical_1.f90 index 3edc74441b2..69d9e6a437e 100644 --- a/gcc/testsuite/gfortran.dg/logical_1.f90 +++ b/gcc/testsuite/gfortran.dg/logical_1.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR middle-end/19543 program logical_1 implicit none diff --git a/gcc/testsuite/gfortran.dg/longline.f b/gcc/testsuite/gfortran.dg/longline.f index ffd5a4bb2af..c2a5f5afd70 100644 --- a/gcc/testsuite/gfortran.dg/longline.f +++ b/gcc/testsuite/gfortran.dg/longline.f @@ -1,5 +1,6 @@ # 1 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.f" ! { dg-do compile } +! { dg-options "-std=legacy" } subroutine foo character*10 cpnam diff --git a/gcc/testsuite/gfortran.dg/merge_char_1.f90 b/gcc/testsuite/gfortran.dg/merge_char_1.f90 index 0a8036d62df..5974e8c06c3 100644 --- a/gcc/testsuite/gfortran.dg/merge_char_1.f90 +++ b/gcc/testsuite/gfortran.dg/merge_char_1.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR 15327 ! The merge intrinsic didn't work for strings character*2 :: c(2) diff --git a/gcc/testsuite/gfortran.dg/namelist_12.f b/gcc/testsuite/gfortran.dg/namelist_12.f index dca96452e21..1752bfa07df 100644 --- a/gcc/testsuite/gfortran.dg/namelist_12.f +++ b/gcc/testsuite/gfortran.dg/namelist_12.f @@ -1,4 +1,6 @@ c{ dg-do run { target fd_truncate } } +c{ dg-options "-std=legacy" } +c c This program repeats many of the same tests as test_nml_1 but for integer c instead of real. It also tests repeat nulls, comma delimited character read, c a triplet qualifier, a range with an assumed start, a quote delimited string, diff --git a/gcc/testsuite/gfortran.dg/namelist_14.f90 b/gcc/testsuite/gfortran.dg/namelist_14.f90 index 729f1b2d5c4..478e07fe67f 100644 --- a/gcc/testsuite/gfortran.dg/namelist_14.f90 +++ b/gcc/testsuite/gfortran.dg/namelist_14.f90 @@ -1,4 +1,6 @@ !{ dg-do run } +!{ dg-options "-std=legacy" } +! ! Tests various combinations of intrinsic types, derived types, arrays, ! dummy arguments and common to check nml_get_addr_expr in trans-io.c. ! See comments below for selection. diff --git a/gcc/testsuite/gfortran.dg/namelist_18.f90 b/gcc/testsuite/gfortran.dg/namelist_18.f90 index d54d91f9a05..87b66012d4c 100644 --- a/gcc/testsuite/gfortran.dg/namelist_18.f90 +++ b/gcc/testsuite/gfortran.dg/namelist_18.f90 @@ -1,4 +1,6 @@ !{ dg-do run } +!{ dg-options "-std=legacy" } +! ! Tests character delimiters for namelist write ! provided by Paul Thomas - pault@gcc.gnu.org diff --git a/gcc/testsuite/gfortran.dg/namelist_19.f90 b/gcc/testsuite/gfortran.dg/namelist_19.f90 index c06abf5295b..4821033ecd7 100644 --- a/gcc/testsuite/gfortran.dg/namelist_19.f90 +++ b/gcc/testsuite/gfortran.dg/namelist_19.f90 @@ -1,4 +1,6 @@ !{ dg-do run } +!{ dg-options "-std=legacy" } +! ! Test namelist error trapping. ! provided by Paul Thomas - pault@gcc.gnu.org diff --git a/gcc/testsuite/gfortran.dg/namelist_21.f90 b/gcc/testsuite/gfortran.dg/namelist_21.f90 index 8d2852d2cca..de88200c167 100644 --- a/gcc/testsuite/gfortran.dg/namelist_21.f90 +++ b/gcc/testsuite/gfortran.dg/namelist_21.f90 @@ -1,4 +1,6 @@ !{ dg-do run { target fd_truncate } } +!{ dg-options "-std=legacy" } +! ! Tests filling arrays from a namelist read when object list is not complete. ! Developed from a test case provided by Christoph Jacob. ! Contributed by Jerry DeLisle <jvdelisle@gcc.gnu.org>. diff --git a/gcc/testsuite/gfortran.dg/namelist_22.f90 b/gcc/testsuite/gfortran.dg/namelist_22.f90 index 3119e808640..e877b5beeae 100644 --- a/gcc/testsuite/gfortran.dg/namelist_22.f90 +++ b/gcc/testsuite/gfortran.dg/namelist_22.f90 @@ -1,4 +1,6 @@ !{ dg-do run { target fd_truncate } } +!{ dg-options "-std=legacy" } +! ! Tests filling arrays from a namelist read when object list is not complete. ! This is the same as namelist_21.f90 except using spaces as seperators instead ! of commas. Developed from a test case provided by Christoph Jacob. diff --git a/gcc/testsuite/gfortran.dg/namelist_37.f90 b/gcc/testsuite/gfortran.dg/namelist_37.f90 index 9ff62977710..4a46b534f67 100644 --- a/gcc/testsuite/gfortran.dg/namelist_37.f90 +++ b/gcc/testsuite/gfortran.dg/namelist_37.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR33039 Read NAMELIST: reads wrong namelist name ! Test case from PR modified by Jerry DeLisle <jvdelisle@gcc.gnu.org>
PROGRAM namelist
diff --git a/gcc/testsuite/gfortran.dg/namelist_40.f90 b/gcc/testsuite/gfortran.dg/namelist_40.f90 index 3c9d813343a..d6f896a3956 100644 --- a/gcc/testsuite/gfortran.dg/namelist_40.f90 +++ b/gcc/testsuite/gfortran.dg/namelist_40.f90 @@ -47,7 +47,7 @@ subroutine writenml (astring) end subroutine writenml end program namelist_40 -! { dg-output "Multiple sub-objects with non-zero rank in namelist object x(\n|\r\n|\r)" } +! { dg-output "Multiple sub-objects with non-zero rank in namelist object x%m%ch(\n|\r\n|\r)" } ! { dg-output "Missing colon in substring qualifier for namelist variable x%m%ch(\n|\r\n|\r)" } ! { dg-output "Substring out of range for namelist variable x%m%ch(\n|\r\n|\r)" } ! { dg-output "Bad character in substring qualifier for namelist variable x%m%ch(\n|\r\n|\r)" } diff --git a/gcc/testsuite/gfortran.dg/namelist_47.f90 b/gcc/testsuite/gfortran.dg/namelist_47.f90 index bc9110fa3cd..581924720bd 100644 --- a/gcc/testsuite/gfortran.dg/namelist_47.f90 +++ b/gcc/testsuite/gfortran.dg/namelist_47.f90 @@ -45,7 +45,7 @@ subroutine writenml (astring) end subroutine writenml end program namelist_47 -! { dg-output "Multiple sub-objects with non-zero rank in namelist object x(\n|\r\n|\r)" } +! { dg-output "Multiple sub-objects with non-zero rank in namelist object x%m%c012345678901234567890123456789012345678901234567890123456789h(\n|\r\n|\r)" } ! { dg-output "Missing colon in substring qualifier for namelist variable x%m%c012345678901234567890123456789012345678901234567890123456789h(\n|\r\n|\r)" } ! { dg-output "Substring out of range for namelist variable x%m%c012345678901234567890123456789012345678901234567890123456789h(\n|\r\n|\r)" } ! { dg-output "Bad character in substring qualifier for namelist variable x%m%c012345678901234567890123456789012345678901234567890123456789h(\n|\r\n|\r)" } diff --git a/gcc/testsuite/gfortran.dg/namelist_54.f90 b/gcc/testsuite/gfortran.dg/namelist_54.f90 index 25061c48fc5..01332689340 100644 --- a/gcc/testsuite/gfortran.dg/namelist_54.f90 +++ b/gcc/testsuite/gfortran.dg/namelist_54.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR37707 Namelist read of array of derived type incorrect. type s integer m diff --git a/gcc/testsuite/gfortran.dg/namelist_55.f90 b/gcc/testsuite/gfortran.dg/namelist_55.f90 index 20c7a219cd6..9690d858d07 100644 --- a/gcc/testsuite/gfortran.dg/namelist_55.f90 +++ b/gcc/testsuite/gfortran.dg/namelist_55.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR37707 Namelist read of array of derived type incorrect ! Test case from PR, prepared by Jerry DeLisle <jvdelisle@gcc.gnu.org> TYPE geometry diff --git a/gcc/testsuite/gfortran.dg/namelist_58.f90 b/gcc/testsuite/gfortran.dg/namelist_58.f90 new file mode 100644 index 00000000000..fcce01653a4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/namelist_58.f90 @@ -0,0 +1,25 @@ +! { dg-do run } +! PR40853 Error in namelist IO. +! Test case derived from example given in PR. < jvdelisle@gcc.gnu.org > +program test + implicit none + type tao_title_struct + character(2) justify + end type + type tao_plot_page_struct + real shape_height_max + type (tao_title_struct) title ! Comment this line out and the bug goes away. + real size(2) + end type + type (tao_plot_page_struct) plot_page + namelist / params / plot_page + open (10, status="scratch") + write(10,'(a)')" ¶ms" + write(10,'(a)')" plot_page%size=5 , 2," + write(10,'(a)')"/" + rewind(10) + read (10, nml = params) + if (any(plot_page%size .ne. (/ 5, 2 /))) call abort + close (10) +end program + diff --git a/gcc/testsuite/gfortran.dg/namelist_empty.f90 b/gcc/testsuite/gfortran.dg/namelist_empty.f90 index 12e72ae7e4d..89493a84b34 100644 --- a/gcc/testsuite/gfortran.dg/namelist_empty.f90 +++ b/gcc/testsuite/gfortran.dg/namelist_empty.f90 @@ -1,3 +1,6 @@ +! { dg-do compile } +! { dg-options "-std=legacy" } +! ! pr24584, segfault on namelist reading an empty string ! Contributed by Jerry DeLisle <jvdelisle@verizon.net> implicit none diff --git a/gcc/testsuite/gfortran.dg/namelist_use.f90 b/gcc/testsuite/gfortran.dg/namelist_use.f90 index 0460630dd33..d550e00aa6d 100644 --- a/gcc/testsuite/gfortran.dg/namelist_use.f90 +++ b/gcc/testsuite/gfortran.dg/namelist_use.f90 @@ -6,7 +6,7 @@ ! Contributed by Paul Thomas pault@gcc.gnu.org ! module global - character*4 :: aa + character(4) :: aa integer :: ii real :: rr namelist /nml1/ aa, ii, rr diff --git a/gcc/testsuite/gfortran.dg/namelist_use_only.f90 b/gcc/testsuite/gfortran.dg/namelist_use_only.f90 index a9adf015ded..d9a28a8567b 100644 --- a/gcc/testsuite/gfortran.dg/namelist_use_only.f90 +++ b/gcc/testsuite/gfortran.dg/namelist_use_only.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! This tests the fix for PR22010, where namelists were not being written to ! and read back from modules. It checks that namelists from modules that are ! selected by an ONLY declaration work correctly, even when the variables in diff --git a/gcc/testsuite/gfortran.dg/nested_modules_4.f90 b/gcc/testsuite/gfortran.dg/nested_modules_4.f90 index dde171c7ed9..6be77b36760 100644 --- a/gcc/testsuite/gfortran.dg/nested_modules_4.f90 +++ b/gcc/testsuite/gfortran.dg/nested_modules_4.f90 @@ -1,4 +1,5 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } ! ! Test for the fix to PR24409 - the name clash between the module ! name and the interface formal argument would cause an ICE. diff --git a/gcc/testsuite/gfortran.dg/nested_modules_5.f90 b/gcc/testsuite/gfortran.dg/nested_modules_5.f90 index 86b43fd7b36..2ed68244ede 100644 --- a/gcc/testsuite/gfortran.dg/nested_modules_5.f90 +++ b/gcc/testsuite/gfortran.dg/nested_modules_5.f90 @@ -1,4 +1,5 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } ! ! Test for supplementary fix to PR24409 - the name clash between the module ! variable and the interface formal argument would cause an ICE. diff --git a/gcc/testsuite/gfortran.dg/open-options-blanks.f b/gcc/testsuite/gfortran.dg/open-options-blanks.f index 8f5faa41629..4db31b9e31a 100644 --- a/gcc/testsuite/gfortran.dg/open-options-blanks.f +++ b/gcc/testsuite/gfortran.dg/open-options-blanks.f @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR 20163, first half: Trailing blanks on an option to ! open used to cause an error CHARACTER*8 ST diff --git a/gcc/testsuite/gfortran.dg/output_exponents_1.f90 b/gcc/testsuite/gfortran.dg/output_exponents_1.f90 index b645e6231a3..db47b0bfc62 100644 --- a/gcc/testsuite/gfortran.dg/output_exponents_1.f90 +++ b/gcc/testsuite/gfortran.dg/output_exponents_1.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR 21376 ! we used to take the logarithm of zero in this special case character*10 c diff --git a/gcc/testsuite/gfortran.dg/parens_5.f90 b/gcc/testsuite/gfortran.dg/parens_5.f90 index a6e64b4112a..ac631ef08af 100644 --- a/gcc/testsuite/gfortran.dg/parens_5.f90 +++ b/gcc/testsuite/gfortran.dg/parens_5.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Another case of fallout from the original patch for PR14771 ! Testcase by Erik Zeek module para diff --git a/gcc/testsuite/gfortran.dg/parens_6.f90 b/gcc/testsuite/gfortran.dg/parens_6.f90 index 5a888a60056..6d5ee3b520f 100644 --- a/gcc/testsuite/gfortran.dg/parens_6.f90 +++ b/gcc/testsuite/gfortran.dg/parens_6.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR fortran/33626 ! Types were not always propagated correctly logical(kind=1) :: i, j diff --git a/gcc/testsuite/gfortran.dg/parent_result_ref_2.f90 b/gcc/testsuite/gfortran.dg/parent_result_ref_2.f90 index 2409cb4685f..38a5fdc7b2c 100644 --- a/gcc/testsuite/gfortran.dg/parent_result_ref_2.f90 +++ b/gcc/testsuite/gfortran.dg/parent_result_ref_2.f90 @@ -16,7 +16,7 @@ contains end subroutine sub end function f -function g() ! { dg-warning "is obsolescent in fortran 95" } +function g() ! { dg-warning "Obsolescent feature" } character(*) :: g g = "efgh" call sub () diff --git a/gcc/testsuite/gfortran.dg/pointer_function_actual_1.f90 b/gcc/testsuite/gfortran.dg/pointer_function_actual_1.f90 index b3cb2727007..0924117080c 100644 --- a/gcc/testsuite/gfortran.dg/pointer_function_actual_1.f90 +++ b/gcc/testsuite/gfortran.dg/pointer_function_actual_1.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Tests the fix for PR31209, in which an ICE would result because ! the reference to the pointer function f would be indirected, as ! if it were the result that is being passed. diff --git a/gcc/testsuite/gfortran.dg/pr15129.f90 b/gcc/testsuite/gfortran.dg/pr15129.f90 index f9a277cb7e8..df3854d7a5f 100644 --- a/gcc/testsuite/gfortran.dg/pr15129.f90 +++ b/gcc/testsuite/gfortran.dg/pr15129.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR 15129: we used to share the character length between A and B in the ! subroutine. CHARACTER*10 A diff --git a/gcc/testsuite/gfortran.dg/pr15332.f b/gcc/testsuite/gfortran.dg/pr15332.f index 309b59eabf0..813e3018839 100644 --- a/gcc/testsuite/gfortran.dg/pr15332.f +++ b/gcc/testsuite/gfortran.dg/pr15332.f @@ -1,5 +1,7 @@ ! PR libfortran/15332 ! { dg-do run } +! { dg-options "-std=legacy" } +! character*12 c write (c,100) 0, 1 diff --git a/gcc/testsuite/gfortran.dg/pr16597.f90 b/gcc/testsuite/gfortran.dg/pr16597.f90 index 071bf86d613..c29147411a8 100644 --- a/gcc/testsuite/gfortran.dg/pr16597.f90 +++ b/gcc/testsuite/gfortran.dg/pr16597.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! pr 16597 ! libgfortran ! reading a direct access record after it was written did diff --git a/gcc/testsuite/gfortran.dg/pr17143.f90 b/gcc/testsuite/gfortran.dg/pr17143.f90 index 1c171a3c902..4423eab7354 100644 --- a/gcc/testsuite/gfortran.dg/pr17143.f90 +++ b/gcc/testsuite/gfortran.dg/pr17143.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! pr17143 ! does not print 2*63 correctly character*25 l diff --git a/gcc/testsuite/gfortran.dg/pr17164.f90 b/gcc/testsuite/gfortran.dg/pr17164.f90 index a0dfff9aa00..c9b4d4537d7 100644 --- a/gcc/testsuite/gfortran.dg/pr17164.f90 +++ b/gcc/testsuite/gfortran.dg/pr17164.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! pr17164 ! index aborts when substring is longer than string implicit none diff --git a/gcc/testsuite/gfortran.dg/pr17229.f b/gcc/testsuite/gfortran.dg/pr17229.f index da780d7feef..65f72b04d10 100644 --- a/gcc/testsuite/gfortran.dg/pr17229.f +++ b/gcc/testsuite/gfortran.dg/pr17229.f @@ -1,22 +1,23 @@ ! PR fortran/17229 ! { dg-do run } + integer i logical l l = .false. i = -1 - if (l) if (i) 999,999,999 ! { dg-warning "Obsolescent: arithmetic IF statement" } + if (l) if (i) 999,999,999 ! { dg-warning "Obsolescent feature" } l = .true. - if (l) if (i) 10,999,999 ! { dg-warning "Obsolescent: arithmetic IF statement" } + if (l) if (i) 10,999,999 ! { dg-warning "Obsolescent feature" } go to 999 10 i = 0 - if (l) if (i) 999,20,999 ! { dg-warning "Obsolescent: arithmetic IF statement" } + if (l) if (i) 999,20,999 ! { dg-warning "Obsolescent feature" } go to 999 20 i = 1 - if (l) if (i) 999,999,30 ! { dg-warning "Obsolescent: arithmetic IF statement" } + if (l) if (i) 999,999,30 ! { dg-warning "Obsolescent feature" } go to 999 999 call abort diff --git a/gcc/testsuite/gfortran.dg/pr18210.f90 b/gcc/testsuite/gfortran.dg/pr18210.f90 index 60959841378..85c5afa3e95 100644 --- a/gcc/testsuite/gfortran.dg/pr18210.f90 +++ b/gcc/testsuite/gfortran.dg/pr18210.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Names in upper case and object names starting column 2 ! Based on example provided by thomas.koenig@online.de diff --git a/gcc/testsuite/gfortran.dg/pr19155.f b/gcc/testsuite/gfortran.dg/pr19155.f index 6387c3f9ce3..770b008f9d9 100644 --- a/gcc/testsuite/gfortran.dg/pr19155.f +++ b/gcc/testsuite/gfortran.dg/pr19155.f @@ -1,4 +1,5 @@ ! { dg-do run } +! { dg-options "-std=legacy" } ! ! PR libfortran/19155 ! We accept 'E+00' as a valid real number. The standard says it is not, diff --git a/gcc/testsuite/gfortran.dg/pr20086.f90 b/gcc/testsuite/gfortran.dg/pr20086.f90 index e5759da3dc1..26b53276dc3 100644 --- a/gcc/testsuite/gfortran.dg/pr20086.f90 +++ b/gcc/testsuite/gfortran.dg/pr20086.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR 20086 - Missing characters in output with hollerith strings implicit none character*80 line diff --git a/gcc/testsuite/gfortran.dg/pr20124.f90 b/gcc/testsuite/gfortran.dg/pr20124.f90 index 69f4f18b29c..5d05abf6eb1 100644 --- a/gcc/testsuite/gfortran.dg/pr20124.f90 +++ b/gcc/testsuite/gfortran.dg/pr20124.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! pr 20124 character*80 line x = -.01 diff --git a/gcc/testsuite/gfortran.dg/pr20755.f b/gcc/testsuite/gfortran.dg/pr20755.f index e2bac5a7dcc..4a9b69cad57 100644 --- a/gcc/testsuite/gfortran.dg/pr20755.f +++ b/gcc/testsuite/gfortran.dg/pr20755.f @@ -1,5 +1,7 @@ ! PR libfortran/20755 ! { dg-do run } +! { dg-options "-std=legacy" } +! character*30 s write (s,2000) 0.0, 0.02 diff --git a/gcc/testsuite/gfortran.dg/pr20865.f90 b/gcc/testsuite/gfortran.dg/pr20865.f90 index 96d0d791cb0..5c26965ccc5 100644 --- a/gcc/testsuite/gfortran.dg/pr20865.f90 +++ b/gcc/testsuite/gfortran.dg/pr20865.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! PR fortran/20865 subroutine tt(j) integer :: j diff --git a/gcc/testsuite/gfortran.dg/pr20950.f b/gcc/testsuite/gfortran.dg/pr20950.f index c132548c829..942696c618f 100644 --- a/gcc/testsuite/gfortran.dg/pr20950.f +++ b/gcc/testsuite/gfortran.dg/pr20950.f @@ -1,6 +1,8 @@ ! PR libfortran/20950 ! Original bug-report by Walt Brainerd, The Fortran Company ! { dg-do run } +! { dg-options "-std=legacy" } +! character*20 c inquire (33, sequential = c) if (c .ne. "UNKNOWN") call abort diff --git a/gcc/testsuite/gfortran.dg/pr21730.f b/gcc/testsuite/gfortran.dg/pr21730.f index 9542c023420..1fe19edfae4 100644 --- a/gcc/testsuite/gfortran.dg/pr21730.f +++ b/gcc/testsuite/gfortran.dg/pr21730.f @@ -1,5 +1,7 @@ ! PR fortran/21730 ! { dg-do run } +! { dg-options "-std=legacy" } +! character*2 a character*4 b character*6 c diff --git a/gcc/testsuite/gfortran.dg/pr22491.f b/gcc/testsuite/gfortran.dg/pr22491.f index 1cd35577022..70210f6b095 100644 --- a/gcc/testsuite/gfortran.dg/pr22491.f +++ b/gcc/testsuite/gfortran.dg/pr22491.f @@ -1,5 +1,7 @@ ! PR fortran/21730 ! { dg-do run } +! { dg-options "-std=legacy" } +! character*2 a (1) character*4 b (1) character*6 c diff --git a/gcc/testsuite/gfortran.dg/pr29713.f90 b/gcc/testsuite/gfortran.dg/pr29713.f90 index be4accd6edd..e60904395ae 100644 --- a/gcc/testsuite/gfortran.dg/pr29713.f90 +++ b/gcc/testsuite/gfortran.dg/pr29713.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! character*2 a character*4 b parameter (a="12") diff --git a/gcc/testsuite/gfortran.dg/pr32921.f b/gcc/testsuite/gfortran.dg/pr32921.f index 42bb986ada0..544665051ac 100644 --- a/gcc/testsuite/gfortran.dg/pr32921.f +++ b/gcc/testsuite/gfortran.dg/pr32921.f @@ -45,6 +45,6 @@ RETURN END -! { dg-final { scan-tree-dump-times "stride" 4 "lim" } } -! { dg-final { cleanup-tree-dump "lim" } } +! { dg-final { scan-tree-dump-times "stride" 4 "lim1" } } +! { dg-final { cleanup-tree-dump "lim\[1-2\]" } } ! { dg-final { cleanup-modules "LES3D_DATA" } } diff --git a/gcc/testsuite/gfortran.dg/print_parentheses_1.f b/gcc/testsuite/gfortran.dg/print_parentheses_1.f index 26041c7f1d6..d644483232a 100644 --- a/gcc/testsuite/gfortran.dg/print_parentheses_1.f +++ b/gcc/testsuite/gfortran.dg/print_parentheses_1.f @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! program main character*80 line print (line,'(A)'), 'hello' ! { dg-error "Syntax error" } diff --git a/gcc/testsuite/gfortran.dg/print_parentheses_2.f90 b/gcc/testsuite/gfortran.dg/print_parentheses_2.f90 index 699f507dafb..520973ed160 100644 --- a/gcc/testsuite/gfortran.dg/print_parentheses_2.f90 +++ b/gcc/testsuite/gfortran.dg/print_parentheses_2.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! program main character*80 line print (line,'(A)'), 'hello' ! { dg-error "Syntax error" } diff --git a/gcc/testsuite/gfortran.dg/proc_assign_1.f90 b/gcc/testsuite/gfortran.dg/proc_assign_1.f90 index 919089acb42..e85df7635de 100644 --- a/gcc/testsuite/gfortran.dg/proc_assign_1.f90 +++ b/gcc/testsuite/gfortran.dg/proc_assign_1.f90 @@ -1,4 +1,6 @@ -! { dg-do compile }
+! { dg-do compile } +! { dg-options "-std=legacy" } +!
! This tests the patch for PR26787 in which it was found that setting
! the result of one module procedure from within another produced an
! ICE rather than an error.
diff --git a/gcc/testsuite/gfortran.dg/proc_decl_1.f90 b/gcc/testsuite/gfortran.dg/proc_decl_1.f90 index c7ec4f2f3fc..de7cb4159c1 100644 --- a/gcc/testsuite/gfortran.dg/proc_decl_1.f90 +++ b/gcc/testsuite/gfortran.dg/proc_decl_1.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! This tests various error messages for PROCEDURE declarations. ! Contributed by Janus Weil <jaydub66@gmail.com> diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_17.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_17.f90 index 20e059fca3a..55b8bce24d9 100644 --- a/gcc/testsuite/gfortran.dg/proc_ptr_17.f90 +++ b/gcc/testsuite/gfortran.dg/proc_ptr_17.f90 @@ -6,7 +6,7 @@ ! Contributed by Tobias Burnus <burnus@net-b.de> procedure(), pointer :: p - f(x) = x**2 + f(x) = x**2 ! { dg-warning "Obsolescent feature" } p => f ! { dg-error "invalid in procedure pointer assignment" } p => sub ! { dg-error "invalid in procedure pointer assignment" } contains diff --git a/gcc/testsuite/gfortran.dg/read_eor.f90 b/gcc/testsuite/gfortran.dg/read_eor.f90 index f3327550297..e6c849eab76 100644 --- a/gcc/testsuite/gfortran.dg/read_eor.f90 +++ b/gcc/testsuite/gfortran.dg/read_eor.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR24489 Assure that read does not go past the end of record. The width of ! the format specifier is 8, but the internal unit record length is 4 so only ! the first 4 characters should be read. diff --git a/gcc/testsuite/gfortran.dg/read_float_1.f90 b/gcc/testsuite/gfortran.dg/read_float_1.f90 index 86589c053b6..0848ee67590 100644 --- a/gcc/testsuite/gfortran.dg/read_float_1.f90 +++ b/gcc/testsuite/gfortran.dg/read_float_1.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR18218 ! The IO library has an algorithm that involved repeated multiplication by 10, ! resulting in introducing large cumulative floating point errors. diff --git a/gcc/testsuite/gfortran.dg/read_logical.f90 b/gcc/testsuite/gfortran.dg/read_logical.f90 index 1e74c8e1a1b..7b7ba8c3a25 100644 --- a/gcc/testsuite/gfortran.dg/read_logical.f90 +++ b/gcc/testsuite/gfortran.dg/read_logical.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR 26554 : Test logical read from string. Test case derived from PR. ! Submitted by Jerry DeLisle <jvdelisle@verizon.net>. program bug @@ -13,4 +15,4 @@ program bug read (strg,*) l if (.not.l) call abort() end -
\ No newline at end of file + diff --git a/gcc/testsuite/gfortran.dg/recursive_statement_functions.f90 b/gcc/testsuite/gfortran.dg/recursive_statement_functions.f90 index 8f9b0918370..bcf51f8d5e9 100644 --- a/gcc/testsuite/gfortran.dg/recursive_statement_functions.f90 +++ b/gcc/testsuite/gfortran.dg/recursive_statement_functions.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! PR20866 - A statement function cannot be recursive. ! Contributed by Joost VandeVondele <jv244@cam.ac.uk> ! diff --git a/gcc/testsuite/gfortran.dg/return_1.f90 b/gcc/testsuite/gfortran.dg/return_1.f90 index a66b4c199ed..a8067b03c08 100644 --- a/gcc/testsuite/gfortran.dg/return_1.f90 +++ b/gcc/testsuite/gfortran.dg/return_1.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! Test cases where no blank is required after RETURN subroutine sub(*) return(1) diff --git a/gcc/testsuite/gfortran.dg/rewind_1.f90 b/gcc/testsuite/gfortran.dg/rewind_1.f90 index cbd2ef17b8f..92edf6dfed9 100644 --- a/gcc/testsuite/gfortran.dg/rewind_1.f90 +++ b/gcc/testsuite/gfortran.dg/rewind_1.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Check that rewind doesn't delete a file. ! Writing to the file truncates it at the end of the current record. Out ! IO library was defering the actual truncation until the file was rewound. diff --git a/gcc/testsuite/gfortran.dg/runtime_warning_1.f90 b/gcc/testsuite/gfortran.dg/runtime_warning_1.f90 index 6af85c344ef..cff9eae7ae7 100644 --- a/gcc/testsuite/gfortran.dg/runtime_warning_1.f90 +++ b/gcc/testsuite/gfortran.dg/runtime_warning_1.f90 @@ -5,7 +5,7 @@ ! { dg-options "-pedantic" } ! { dg-do run } ! - character*5 c + character(5) c open (42,status='scratch') write (42,'(A,$)') 'abc' ! { dg-warning ".*descriptor" "" } write (42,'(A)') 'de' diff --git a/gcc/testsuite/gfortran.dg/scalar_return_1.f90 b/gcc/testsuite/gfortran.dg/scalar_return_1.f90 index d7583bc10b4..df206458e3a 100644 --- a/gcc/testsuite/gfortran.dg/scalar_return_1.f90 +++ b/gcc/testsuite/gfortran.dg/scalar_return_1.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! tests the fix for pr25082 in which the return of an array by a ! subroutine went undremarked. ! diff --git a/gcc/testsuite/gfortran.dg/stfunc_1.f90 b/gcc/testsuite/gfortran.dg/stfunc_1.f90 index e21f34e063b..46dde6286b6 100644 --- a/gcc/testsuite/gfortran.dg/stfunc_1.f90 +++ b/gcc/testsuite/gfortran.dg/stfunc_1.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! this is a problem which disappeared between 2005-01-02 and 2005-03-13 ! PR 18600 logical a, b diff --git a/gcc/testsuite/gfortran.dg/stfunc_3.f90 b/gcc/testsuite/gfortran.dg/stfunc_3.f90 index 42eedf8c830..90980a92448 100644 --- a/gcc/testsuite/gfortran.dg/stfunc_3.f90 +++ b/gcc/testsuite/gfortran.dg/stfunc_3.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! Tests the fix for PR20867 in which implicit typing was not done within ! statement functions and so was not confirmed or not by subsequent ! type delarations. diff --git a/gcc/testsuite/gfortran.dg/stfunc_4.f90 b/gcc/testsuite/gfortran.dg/stfunc_4.f90 index e995fb86bec..2f0efccf326 100644 --- a/gcc/testsuite/gfortran.dg/stfunc_4.f90 +++ b/gcc/testsuite/gfortran.dg/stfunc_4.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Tests the fix for PR29389, in which the statement function would not be ! recognised as PURE within a PURE procedure. diff --git a/gcc/testsuite/gfortran.dg/stfunc_6.f90 b/gcc/testsuite/gfortran.dg/stfunc_6.f90 index c5657833c0f..482d12592f3 100644 --- a/gcc/testsuite/gfortran.dg/stfunc_6.f90 +++ b/gcc/testsuite/gfortran.dg/stfunc_6.f90 @@ -1,4 +1,6 @@ ! { dg-do compile } +! { dg-options "-std=legacy" } +! ! Tests the fix for the second bit of PR29389, in which the ! statement function would not be recognised as not PURE ! when it referenced a procedure that is not PURE. diff --git a/gcc/testsuite/gfortran.dg/streamio_2.f90 b/gcc/testsuite/gfortran.dg/streamio_2.f90 index a7d5d3ccfaa..8260a7481c9 100644 --- a/gcc/testsuite/gfortran.dg/streamio_2.f90 +++ b/gcc/testsuite/gfortran.dg/streamio_2.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR25828 Stream IO test 2 ! Contributed by Jerry DeLisle <jvdelisle@verizon.net>. PROGRAM readUstream @@ -16,4 +18,5 @@ PROGRAM readUstream if (string.ne."rst") call abort() if (n.ne.7) call abort() close(unit=11, status="delete") -END PROGRAM readUstream
\ No newline at end of file +END PROGRAM readUstream + diff --git a/gcc/testsuite/gfortran.dg/string_ctor_1.f90 b/gcc/testsuite/gfortran.dg/string_ctor_1.f90 index 3242ea8f9e3..7e5c2f9f030 100644 --- a/gcc/testsuite/gfortran.dg/string_ctor_1.f90 +++ b/gcc/testsuite/gfortran.dg/string_ctor_1.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Program to test character array constructors. ! PR17144 subroutine test1 (n, t, u) diff --git a/gcc/testsuite/gfortran.dg/string_null_compare_1.f b/gcc/testsuite/gfortran.dg/string_null_compare_1.f index 2e6eb1b2b88..659b3eb3709 100644 --- a/gcc/testsuite/gfortran.dg/string_null_compare_1.f +++ b/gcc/testsuite/gfortran.dg/string_null_compare_1.f @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! PR 27784 - Different strings should compare unequal even if they ! have CHAR(0) in them. diff --git a/gcc/testsuite/gfortran.dg/substr_6.f90 b/gcc/testsuite/gfortran.dg/substr_6.f90 index ee0eae49e0e..813a02521a3 100644 --- a/gcc/testsuite/gfortran.dg/substr_6.f90 +++ b/gcc/testsuite/gfortran.dg/substr_6.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Check that NULs don't mess up constant substring simplification CHARACTER(5), parameter :: c0(1) = (/ "123" // ACHAR(0) // "5" /) CHARACTER*5 c(1) diff --git a/gcc/testsuite/gfortran.dg/tl_editing.f90 b/gcc/testsuite/gfortran.dg/tl_editing.f90 index d2a7ede436f..830c7eb71bd 100644 --- a/gcc/testsuite/gfortran.dg/tl_editing.f90 +++ b/gcc/testsuite/gfortran.dg/tl_editing.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-std=legacy" } +! ! Test of fix to bug triggered by NIST fm908.for. ! Left tabbing, followed by X or T-tabbing to the right would ! cause spaces to be overwritten on output data. diff --git a/gcc/testsuite/gfortran.dg/unf_io_convert_1.f90 b/gcc/testsuite/gfortran.dg/unf_io_convert_1.f90 index 3d35312c92c..31765699750 100644 --- a/gcc/testsuite/gfortran.dg/unf_io_convert_1.f90 +++ b/gcc/testsuite/gfortran.dg/unf_io_convert_1.f90 @@ -16,7 +16,7 @@ program main integer n real r(size) integer i - character*4 str + character(4) str m(1) = Z'11223344' ! { dg-warning "BOZ literal at .1. outside a DATA statement" } m(2) = Z'55667788' ! { dg-warning "BOZ literal at .1. outside a DATA statement" } diff --git a/gcc/testsuite/gfortran.dg/warnings_are_errors_1.f90 b/gcc/testsuite/gfortran.dg/warnings_are_errors_1.f90 index fcbeba5aa51..0a0883c67c3 100644 --- a/gcc/testsuite/gfortran.dg/warnings_are_errors_1.f90 +++ b/gcc/testsuite/gfortran.dg/warnings_are_errors_1.f90 @@ -5,7 +5,7 @@ ! free-form tests ! gfc_notify_std: - function char_ (ch) ! { dg-warning "is obsolescent in fortran 95" } + function char_ (ch) ! { dg-warning "Obsolescent feature" } character(*) :: char_, ch char_ = ch end function char_ diff --git a/gcc/testsuite/gfortran.dg/whole_file_10.f90 b/gcc/testsuite/gfortran.dg/whole_file_10.f90 new file mode 100644 index 00000000000..fb100bb0ed5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/whole_file_10.f90 @@ -0,0 +1,32 @@ +! { dg-do compile } +! { dg-options "-fwhole-file" } +! Test the fix for the fifth problem in PR40011, where the +! entries were not resolved, resulting in a segfault. +! +! Contributed by Dominique d'Humieres <dominiq@lps.ens.fr> +! +recursive function fac(i) result (res) + integer :: i, j, k, res + k = 1 + goto 100 +entry bifac(i,j) result (res) + k = j +100 continue + if (i < k) then + res = 1 + else + res = i * bifac(i-k,k) + end if +end function + +program test + external fac + external bifac + integer :: fac, bifac + print *, fac(5) + print *, bifac(5,2) + print*, fac(6) + print *, bifac(6,2) + print*, fac(0) + print *, bifac(1,2) +end program test diff --git a/gcc/testsuite/gfortran.dg/whole_file_11.f90 b/gcc/testsuite/gfortran.dg/whole_file_11.f90 new file mode 100644 index 00000000000..d01b2100c4b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/whole_file_11.f90 @@ -0,0 +1,37 @@ +! { dg-do compile } +! { dg-options "-fwhole-file" } +! +! Tests the fix PR40011 comment 16 in which the derived type lists in +! different program units were getting mixed up. +! +! Contributed by Daniel Franck <dfranke@gcc.gnu.org> +! +MODULE module_foo + TYPE :: foo_node + TYPE(foo_node_private), POINTER :: p + END TYPE + + TYPE :: foo_node_private + TYPE(foo_node), DIMENSION(-1:1) :: link + END TYPE + + TYPE :: foo + TYPE(foo_node) :: root + END TYPE +END MODULE + +FUNCTION foo_insert() + USE module_foo, ONLY: foo, foo_node + + INTEGER :: foo_insert + TYPE(foo_node) :: parent, current + INTEGER :: cmp + + parent = current + current = current%p%link(cmp) +END FUNCTION + +FUNCTION foo_count() + USE module_foo, ONLY: foo + INTEGER :: foo_count +END FUNCTION diff --git a/gcc/testsuite/gfortran.dg/whole_file_12.f90 b/gcc/testsuite/gfortran.dg/whole_file_12.f90 new file mode 100644 index 00000000000..150ac5f9d5d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/whole_file_12.f90 @@ -0,0 +1,33 @@ +! { dg-do compile } +! { dg-options "-fwhole-file" } +! +! Tests the fix PR40011 comment 17 in which the explicit interface was +! being ignored and the missing argument was not correctly handled, which +! led to an ICE. +! +! Contributed by Dominique d'Humieres <dominiq@lps.ens.fr +! + Implicit None + call sub(1,2) + call sub(1,2,3) + + contains + + subroutine sub(i,j,k) + Implicit None + Integer, Intent( In ) :: i + Integer, Intent( In ) :: j + Integer, Intent( In ), Optional :: k + intrinsic present + write(*,*)' 3 presence flag ',present(k) + write(*,*)' 1st arg ',i + write(*,*)' 2nd arg ',j + if (present(k)) then + write(*,*)' 3rd arg ',k + else + write(*,*)' 3rd arg is absent' + endif + return + end subroutine + + end diff --git a/gcc/testsuite/gfortran.dg/whole_file_13.f90 b/gcc/testsuite/gfortran.dg/whole_file_13.f90 new file mode 100644 index 00000000000..99e3ceecb7d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/whole_file_13.f90 @@ -0,0 +1,28 @@ +! { dg-do run } +! { dg-options "-fwhole-file -O3" } +! Check that the TYPE_CANONICAL is being correctly set +! for the derived types, when whole file compiling. +! (based on import.f90) +! +subroutine test(x) + type myType3 + sequence + integer :: i + end type myType3 + type(myType3) :: x + if(x%i /= 7) call abort() + x%i = 1 +end subroutine test + + +program foo + type myType3 + sequence + integer :: i + end type myType3 + + type(myType3) :: z + z%i = 7 + call test(z) + if(z%i /= 1) call abort +end program foo diff --git a/gcc/testsuite/gfortran.dg/whole_file_14.f90 b/gcc/testsuite/gfortran.dg/whole_file_14.f90 new file mode 100644 index 00000000000..65058960b95 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/whole_file_14.f90 @@ -0,0 +1,28 @@ +! { dg-do run } +! { dg-options "-fwhole-file -O3" } +! Check that the derived types are correctly substituted when +! whole file compiling. +! +! Contributed by Dominique d'Humieres <dominiq@lps.ens.fr +! +module global + type :: mytype + type(mytype),pointer :: this + end type mytype + type(mytype),target :: base +end module global + +program test_equi + use global + call check() + print *, "base%this%this=>base?" , associated(base%this%this,base) + print *, "base%this%this=>?" , associated(base%this%this) + print *, "base%this=>?" , associated(base%this) +contains + subroutine check() + type(mytype),target :: j + base%this => j !have the variables point + j%this => base !to one another + end subroutine check !take j out of scope +end program test_equi +! { dg-final { cleanup-modules "global" } } diff --git a/gcc/testsuite/gfortran.dg/whole_file_7.f90 b/gcc/testsuite/gfortran.dg/whole_file_7.f90 new file mode 100644 index 00000000000..53fed228ae2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/whole_file_7.f90 @@ -0,0 +1,34 @@ +! { dg-do compile } +! { dg-options "-fwhole-file" } +! Test the fixes for the first two problems in PR40011 +! +! Contributed by Dominique d'Humieres <dominiq@lps.ens.fr> +! +! This function would not compile because -fwhole-file would +! try repeatedly to resolve the function because of the self +! reference. +RECURSIVE FUNCTION eval_args(q) result (r) + INTEGER NNODE + PARAMETER (NNODE = 10) + TYPE NODE + SEQUENCE + INTEGER car + INTEGER cdr + END TYPE NODE + TYPE(NODE) heap(NNODE) + INTEGER r, q + r = eval_args(heap(q)%cdr) +END FUNCTION eval_args + +function test(n) + real, dimension(2) :: test + integer :: n + test = n + return +end function test + +program arr ! The error was not picked up causing an ICE + real, dimension(2) :: res + res = test(2) ! { dg-error "needs an explicit INTERFACE" } + print *, res +end program diff --git a/gcc/testsuite/gfortran.dg/whole_file_8.f90 b/gcc/testsuite/gfortran.dg/whole_file_8.f90 new file mode 100644 index 00000000000..6ea319a9d12 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/whole_file_8.f90 @@ -0,0 +1,36 @@ +! { dg-do compile } +! { dg-options "-fwhole-file" } +! Test the fix for the third problem in PR40011, where false +! type/rank mismatches were found in the main program calls. +! +! Contributed by Dominique d'Humieres <dominiq@lps.ens.fr> +! +subroutine test_d(fn, val, res) + double precision fn + double precision val, res + + print *, fn(val), res +end subroutine + +subroutine test_c(fn, val, res) + complex fn + complex val, res + + print *, fn(val), res +end subroutine + +program specifics + + intrinsic dcos + intrinsic dcosh + intrinsic dexp + + intrinsic conjg + + call test_d (dcos, 1d0, dcos(1d0)) + call test_d (dcosh, 1d0, dcosh(1d0)) + call test_d (dexp, 1d0, dexp(1d0)) + + call test_c (conjg, (1.0,1.0) , conjg((1.0,1.0))) + +end program diff --git a/gcc/testsuite/gfortran.dg/whole_file_9.f90 b/gcc/testsuite/gfortran.dg/whole_file_9.f90 new file mode 100644 index 00000000000..64dce42ee21 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/whole_file_9.f90 @@ -0,0 +1,46 @@ +! { dg-do compile } +! { dg-options "-fwhole-file" } +! Test the fix for the fourth problem in PR40011, where the +! entries were not resolved, resulting in a segfault. +! +! Contributed by Dominique d'Humieres <dominiq@lps.ens.fr> +! +program test +interface + function bad_stuff(n) + integer :: bad_stuff (2) + integer :: n(2) + end function bad_stuff + recursive function rec_stuff(n) result (tmp) + integer :: n(2), tmp(2) + end function rec_stuff +end interface + integer :: res(2) + res = bad_stuff((/-19,-30/)) + +end program test + + recursive function bad_stuff(n) + integer :: bad_stuff (2) + integer :: n(2), tmp(2), ent = 0, sent = 0 + save ent, sent + ent = -1 + entry rec_stuff(n) result (tmp) + if (ent == -1) then + sent = ent + ent = 0 + end if + ent = ent + 1 + tmp = 1 + if(maxval (n) < 5) then + tmp = tmp + rec_stuff (n+1) + ent = ent - 1 + endif + if (ent == 1) then + if (sent == -1) then + bad_stuff = tmp + bad_stuff (1) + end if + ent = 0 + sent = 0 + end if + end function bad_stuff diff --git a/gcc/testsuite/gfortran.dg/x_slash_1.f b/gcc/testsuite/gfortran.dg/x_slash_1.f index de576e2e401..435e4612227 100644 --- a/gcc/testsuite/gfortran.dg/x_slash_1.f +++ b/gcc/testsuite/gfortran.dg/x_slash_1.f @@ -1,4 +1,6 @@ c { dg-do run { target fd_truncate } } +c { dg-options "-std=legacy" } +c c This program tests the fixes to PR22570. c c Provided by Paul Thomas - pault@gcc.gnu.org diff --git a/gcc/testsuite/lib/options.exp b/gcc/testsuite/lib/options.exp index c63fd66cc02..18359023228 100644 --- a/gcc/testsuite/lib/options.exp +++ b/gcc/testsuite/lib/options.exp @@ -41,11 +41,11 @@ proc check_for_options {language gcc_options compiler_patterns compiler_non_patt remote_file build delete $filename.c $filename.x $filename.gcno foreach pattern [split $compiler_patterns "\n"] { - if {$pattern ne ""} { + if {$pattern != ""} { if {[regexp -- "$pattern" $gcc_output]} { pass "$test $pattern" } else { - if {$expected_failure ne ""} { + if {$expected_failure != ""} { xfail "$test $pattern" } else { fail "$test $pattern" @@ -54,11 +54,11 @@ proc check_for_options {language gcc_options compiler_patterns compiler_non_patt } } foreach pattern [split $compiler_non_patterns "\n"] { - if {$pattern ne ""} { + if {$pattern != ""} { if {![regexp -- "$pattern" $gcc_output]} { pass "$test $pattern" } else { - if {$expected_failure ne ""} { + if {$expected_failure != ""} { xfail "$test $pattern" } else { fail "$test $pattern" diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index c847de090e7..050292b3feb 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -902,6 +902,32 @@ proc check_sse2_hw_available { } { }] } +# Return 1 if the target supports executing VSX instructions, 0 +# otherwise. Cache the result. + +proc check_vsx_hw_available { } { + return [check_cached_effective_target vsx_hw_available { + # Some simulators are known to not support VSX instructions. + # For now, disable on Darwin + if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mvsx" + check_runtime_nocache vsx_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("xxlor vs0,vs0,vs0"); + #else + asm volatile ("xxlor 0,0,0"); + #endif + return 0; + } + } $options + } + }] +} + # Return 1 if the target supports executing AltiVec instructions, 0 # otherwise. Cache the result. @@ -912,12 +938,13 @@ proc check_vmx_hw_available { } { expr 0 } else { # Most targets don't require special flags for this test case, but - # Darwin does. + # Darwin does. Just to be sure, make sure VSX is not enabled for + # the altivec tests. if { [istarget *-*-darwin*] || [istarget *-*-aix*] } { - set options "-maltivec" + set options "-maltivec -mno-vsx" } else { - set options "" + set options "-mno-vsx" } check_runtime_nocache vmx_hw_available { int main() @@ -1632,6 +1659,33 @@ proc check_effective_target_powerpc_altivec_ok { } { } } +# Return 1 if this is a PowerPC target supporting -mvsx + +proc check_effective_target_powerpc_vsx_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # AltiVec is not supported on AIX before 5.3. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5.1*] + || [istarget powerpc*-*-aix5.2*] } { + return 0 + } + return [check_no_compiler_messages powerpc_vsx_ok object { + int main (void) { +#ifdef __MACH__ + asm volatile ("xxlor vs0,vs0,vs0"); +#else + asm volatile ("xxlor 0,0,0"); +#endif + return 0; + } + } "-mvsx"] + } else { + return 0 + } +} + # Return 1 if this is a PowerPC target supporting -mcpu=cell. proc check_effective_target_powerpc_ppu_ok { } { diff --git a/gcc/toplev.c b/gcc/toplev.c index 81d55f3a5b8..bb7633f09fc 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1034,8 +1034,7 @@ compile_file (void) ggc_protect_identifiers = false; - /* This must also call cgraph_finalize_compilation_unit and - cgraph_optimize. */ + /* This must also call cgraph_finalize_compilation_unit. */ lang_hooks.decls.final_write_globals (); if (errorcount || sorrycount) @@ -1801,7 +1800,8 @@ process_options (void) || flag_loop_block || flag_loop_interchange || flag_loop_strip_mine - || flag_graphite_identity) + || flag_graphite_identity + || flag_loop_parallelize_all) sorry ("Graphite loop optimizations cannot be used"); #endif @@ -2046,7 +2046,7 @@ process_options (void) if (flag_signaling_nans) flag_trapping_math = 1; - /* We cannot reassociate if we want traps or signed zeros. */ + /* We cannot reassociate if we want traps or signed zeros. */ if (flag_associative_math && (flag_trapping_math || flag_signed_zeros)) { warning (0, "-fassociative-math disabled; other options take precedence"); diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index bb29df3c0f6..6057a7d507a 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -2886,7 +2886,7 @@ reinstall_phi_args (edge new_edge, edge old_edge) gcc_assert (result == gimple_phi_result (phi)); - add_phi_arg (phi, arg, new_edge); + add_phi_arg (phi, arg, new_edge, redirect_edge_var_map_location (vm)); } redirect_edge_var_map_clear (old_edge); @@ -4840,7 +4840,8 @@ gimple_make_forwarder_block (edge fallthru) new_phi = create_phi_node (var, bb); SSA_NAME_DEF_STMT (var) = new_phi; gimple_phi_set_result (phi, make_ssa_name (SSA_NAME_VAR (var), phi)); - add_phi_arg (new_phi, gimple_phi_result (phi), fallthru); + add_phi_arg (new_phi, gimple_phi_result (phi), fallthru, + UNKNOWN_LOCATION); } /* Add the arguments we have stored on edges. */ @@ -5239,7 +5240,8 @@ add_phi_args_after_copy_edge (edge e_copy) phi = gsi_stmt (psi); phi_copy = gsi_stmt (psi_copy); def = PHI_ARG_DEF_FROM_EDGE (phi, e); - add_phi_arg (phi_copy, def, e_copy); + add_phi_arg (phi_copy, def, e_copy, + gimple_phi_arg_location_from_edge (phi, e)); } } @@ -7058,7 +7060,7 @@ gimple_lv_adjust_loop_header_phi (basic_block first, basic_block second, phi1 = gsi_stmt (psi1); phi2 = gsi_stmt (psi2); def = PHI_ARG_DEF (phi2, e2->dest_idx); - add_phi_arg (phi1, def, e); + add_phi_arg (phi1, def, e, gimple_phi_arg_location_from_edge (phi2, e2)); } } @@ -7460,7 +7462,7 @@ struct gimple_opt_pass pass_warn_unused_result = { { GIMPLE_PASS, - "warn_unused_result", /* name */ + "*warn_unused_result", /* name */ gate_warn_unused_result, /* gate */ run_warn_unused_result, /* execute */ NULL, /* sub */ diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index fdd7d780ade..34cfc80bbee 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -401,7 +401,8 @@ remove_forwarder_block (basic_block bb) gsi_next (&gsi)) { gimple phi = gsi_stmt (gsi); - add_phi_arg (phi, gimple_phi_arg_def (phi, succ->dest_idx), s); + source_location l = gimple_phi_arg_location_from_edge (phi, succ); + add_phi_arg (phi, gimple_phi_arg_def (phi, succ->dest_idx), s, l); } } } @@ -744,6 +745,7 @@ remove_forwarder_block_with_phi (basic_block bb) { gimple phi = gsi_stmt (gsi); tree def = gimple_phi_arg_def (phi, succ->dest_idx); + source_location locus = gimple_phi_arg_location_from_edge (phi, succ); if (TREE_CODE (def) == SSA_NAME) { @@ -763,12 +765,13 @@ remove_forwarder_block_with_phi (basic_block bb) if (def == old_arg) { def = new_arg; + locus = redirect_edge_var_map_location (vm); break; } } } - add_phi_arg (phi, def, s); + add_phi_arg (phi, def, s, locus); } redirect_edge_var_map_clear (e); diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c index 74935043918..33d9f18c099 100644 --- a/gcc/tree-chrec.c +++ b/gcc/tree-chrec.c @@ -1411,7 +1411,7 @@ for_each_scev_op (tree *scev, bool (*cbck) (tree *, void *), void *data) case 2: for_each_scev_op (&TREE_OPERAND (*scev, 1), cbck, data); - + case 1: for_each_scev_op (&TREE_OPERAND (*scev, 0), cbck, data); @@ -1438,6 +1438,7 @@ operator_is_linear (tree scev) case NEGATE_EXPR: case SSA_NAME: case NON_LVALUE_EXPR: + case BIT_NOT_EXPR: CASE_CONVERT: return true; @@ -1461,6 +1462,10 @@ scev_is_linear_expression (tree scev) return !(tree_contains_chrecs (TREE_OPERAND (scev, 0), NULL) && tree_contains_chrecs (TREE_OPERAND (scev, 1), NULL)); + if (TREE_CODE (scev) == POLYNOMIAL_CHREC + && !evolution_function_is_affine_multivariate_p (scev, CHREC_VARIABLE (scev))) + return false; + switch (TREE_CODE_LENGTH (TREE_CODE (scev))) { case 3: @@ -1471,7 +1476,7 @@ scev_is_linear_expression (tree scev) case 2: return scev_is_linear_expression (TREE_OPERAND (scev, 0)) && scev_is_linear_expression (TREE_OPERAND (scev, 1)); - + case 1: return scev_is_linear_expression (TREE_OPERAND (scev, 0)); @@ -1482,3 +1487,33 @@ scev_is_linear_expression (tree scev) return false; } } + +/* Determines whether the expression CHREC contains only interger consts + in the right parts. */ + +bool +evolution_function_right_is_integer_cst (const_tree chrec) +{ + if (chrec == NULL_TREE) + return false; + + switch (TREE_CODE (chrec)) + { + case INTEGER_CST: + return true; + + case POLYNOMIAL_CHREC: + if (!evolution_function_right_is_integer_cst (CHREC_RIGHT (chrec))) + return false; + + if (TREE_CODE (CHREC_LEFT (chrec)) == POLYNOMIAL_CHREC + && !evolution_function_right_is_integer_cst (CHREC_LEFT (chrec))) + return false; + + return true; + + default: + return false; + } +} + diff --git a/gcc/tree-chrec.h b/gcc/tree-chrec.h index db45eedc595..f21aa74d795 100644 --- a/gcc/tree-chrec.h +++ b/gcc/tree-chrec.h @@ -86,6 +86,7 @@ extern bool evolution_function_is_univariate_p (const_tree); extern unsigned nb_vars_in_chrec (tree); extern bool evolution_function_is_invariant_p (tree, int); extern bool scev_is_linear_expression (tree); +extern bool evolution_function_right_is_integer_cst (const_tree); /* Determines whether CHREC is equal to zero. */ diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index 2181f469ca0..ae0a0681479 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -157,6 +157,14 @@ dump_data_references (FILE *file, VEC (data_reference_p, heap) *datarefs) dump_data_reference (file, dr); } +/* Dump into STDERR all the data references from DATAREFS. */ + +void +debug_data_references (VEC (data_reference_p, heap) *datarefs) +{ + dump_data_references (stderr, datarefs); +} + /* Dump to STDERR all the dependence relations from DDRS. */ void @@ -178,6 +186,14 @@ dump_data_dependence_relations (FILE *file, dump_data_dependence_relation (file, ddr); } +/* Print to STDERR the data_reference DR. */ + +void +debug_data_reference (struct data_reference *dr) +{ + dump_data_reference (stderr, dr); +} + /* Dump function for a DATA_REFERENCE structure. */ void @@ -3334,22 +3350,6 @@ access_functions_are_affine_or_constant_p (const struct data_reference *a, return true; } -/* Return true if we can create an affine data-ref for OP in STMT. */ - -bool -stmt_simple_memref_p (struct loop *loop, gimple stmt, tree op) -{ - data_reference_p dr; - bool res = true; - - dr = create_data_ref (loop, op, stmt, true); - if (!access_functions_are_affine_or_constant_p (dr, loop)) - res = false; - - free_data_ref (dr); - return res; -} - /* Initializes an equation for an OMEGA problem using the information contained in the ACCESS_FUN. Returns true when the operation succeeded. @@ -4158,6 +4158,37 @@ find_data_references_in_stmt (struct loop *nest, gimple stmt, return ret; } +/* Stores the data references in STMT to DATAREFS. If there is an unanalyzable + reference, returns false, otherwise returns true. NEST is the outermost + loop of the loop nest in which the references should be analyzed. */ + +bool +graphite_find_data_references_in_stmt (struct loop *nest, gimple stmt, + VEC (data_reference_p, heap) **datarefs) +{ + unsigned i; + VEC (data_ref_loc, heap) *references; + data_ref_loc *ref; + bool ret = true; + data_reference_p dr; + + if (get_references_in_stmt (stmt, &references)) + { + VEC_free (data_ref_loc, heap, references); + return false; + } + + for (i = 0; VEC_iterate (data_ref_loc, references, i, ref); i++) + { + dr = create_data_ref (nest, *ref->pos, stmt, ref->is_read); + gcc_assert (dr != NULL); + VEC_safe_push (data_reference_p, heap, *datarefs, dr); + } + + VEC_free (data_ref_loc, heap, references); + return ret; +} + /* Search the data references in LOOP, and record the information into DATAREFS. Returns chrec_dont_know when failing to analyze a difficult case, returns NULL_TREE otherwise. */ diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h index dfce23309f5..fe79faea40f 100644 --- a/gcc/tree-data-ref.h +++ b/gcc/tree-data-ref.h @@ -96,8 +96,6 @@ struct dr_alias bitmap vops; }; -typedef struct scop *scop_p; - /* Each vector of the access matrix represents a linear access function for a subscript. First elements correspond to the leftmost indices, ie. for a[i][j] the first vector corresponds to @@ -184,14 +182,10 @@ struct data_reference /* Alias information for the data reference. */ struct dr_alias alias; - /* The SCoP in which the data reference was analyzed. */ - scop_p scop; - /* Matrix representation for the data access functions. */ struct access_matrix *access_matrix; }; -#define DR_SCOP(DR) (DR)->scop #define DR_STMT(DR) (DR)->stmt #define DR_REF(DR) (DR)->ref #define DR_BASE_OBJECT(DR) (DR)->indices.base_object @@ -395,7 +389,9 @@ extern void dump_subscript (FILE *, struct subscript *); extern void dump_ddrs (FILE *, VEC (ddr_p, heap) *); extern void dump_dist_dir_vectors (FILE *, VEC (ddr_p, heap) *); extern void dump_data_reference (FILE *, struct data_reference *); +extern void debug_data_reference (struct data_reference *); extern void dump_data_references (FILE *, VEC (data_reference_p, heap) *); +extern void debug_data_references (VEC (data_reference_p, heap) *); extern void debug_data_dependence_relation (struct data_dependence_relation *); extern void dump_data_dependence_relation (FILE *, struct data_dependence_relation *); @@ -409,6 +405,8 @@ extern void free_data_ref (data_reference_p); extern void free_data_refs (VEC (data_reference_p, heap) *); extern bool find_data_references_in_stmt (struct loop *, gimple, VEC (data_reference_p, heap) **); +extern bool graphite_find_data_references_in_stmt (struct loop *, gimple, + VEC (data_reference_p, heap) **); struct data_reference *create_data_ref (struct loop *, tree, gimple, bool); extern bool find_loop_nest (struct loop *, VEC (loop_p, heap) **); extern void compute_all_dependences (VEC (data_reference_p, heap) *, @@ -418,7 +416,6 @@ extern void compute_all_dependences (VEC (data_reference_p, heap) *, extern void create_rdg_vertices (struct graph *, VEC (gimple, heap) *); extern bool dr_may_alias_p (const struct data_reference *, const struct data_reference *); -extern bool stmt_simple_memref_p (struct loop *, gimple, tree); /* Return true when the DDR contains two data references that have the same access functions. */ diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index e6de3772c3c..f56ecea7db7 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -455,6 +455,39 @@ gimple_phi_arg_edge (gimple gs, size_t i) return EDGE_PRED (gimple_bb (gs), i); } +/* Return the source location of gimple argument I of phi node GS. */ + +static inline source_location +gimple_phi_arg_location (gimple gs, size_t i) +{ + return gimple_phi_arg (gs, i)->locus; +} + +/* Return the source location of the argument on edge E of phi node GS. */ + +static inline source_location +gimple_phi_arg_location_from_edge (gimple gs, edge e) +{ + return gimple_phi_arg (gs, e->dest_idx)->locus; +} + +/* Set the source location of gimple argument I of phi node GS to LOC. */ + +static inline void +gimple_phi_arg_set_location (gimple gs, size_t i, source_location loc) +{ + gimple_phi_arg (gs, i)->locus = loc; +} + +/* Return TRUE if argument I of phi node GS has a location record. */ + +static inline bool +gimple_phi_arg_has_location (gimple gs, size_t i) +{ + return gimple_phi_arg_location (gs, i) != UNKNOWN_LOCATION; +} + + /* Return the PHI nodes for basic block BB, or NULL if there are no PHI nodes. */ static inline gimple_seq @@ -1196,6 +1229,14 @@ redirect_edge_var_map_result (edge_var_map *v) return v->result; } +/* Given an edge_var_map V, return the PHI arg location. */ + +static inline source_location +redirect_edge_var_map_location (edge_var_map *v) +{ + return v->locus; +} + /* Return an SSA_NAME node for variable VAR defined in statement STMT in function cfun. */ diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index f9f0da20025..69dc446b8b8 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -579,7 +579,7 @@ extern void reserve_phi_args_for_new_edge (basic_block); extern void add_phi_node_to_bb (gimple phi, basic_block bb); extern gimple make_phi_node (tree var, int len); extern gimple create_phi_node (tree, basic_block); -extern void add_phi_arg (gimple, tree, edge); +extern void add_phi_arg (gimple, tree, edge, source_location); extern void remove_phi_args (edge); extern void remove_phi_node (gimple_stmt_iterator *, bool); extern void remove_phi_nodes (basic_block); @@ -604,6 +604,7 @@ extern bool gimple_stmt_may_fallthru (gimple); struct GTY(()) _edge_var_map { tree result; /* PHI result. */ tree def; /* PHI arg definition. */ + source_location locus; /* PHI arg location. */ }; typedef struct _edge_var_map edge_var_map; @@ -614,7 +615,7 @@ DEF_VEC_ALLOC_O(edge_var_map, heap); typedef VEC(edge_var_map, heap) *edge_var_map_vector; extern void init_tree_ssa (struct function *); -extern void redirect_edge_var_map_add (edge, tree, tree); +extern void redirect_edge_var_map_add (edge, tree, tree, source_location); extern void redirect_edge_var_map_clear (edge); extern void redirect_edge_var_map_dup (edge, edge); extern edge_var_map_vector redirect_edge_var_map_vector (edge); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index e62c5c1e792..f79ba758088 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1828,7 +1828,8 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id) new_arg = force_gimple_operand (new_arg, &stmts, true, NULL); gsi_insert_seq_on_edge_immediate (new_edge, stmts); } - add_phi_arg (new_phi, new_arg, new_edge); + add_phi_arg (new_phi, new_arg, new_edge, + gimple_phi_arg_location_from_edge (phi, old_edge)); } } } diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index ab827eadc57..bdec08063e4 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -1114,7 +1114,7 @@ insert_phi_nodes_for (tree var, bitmap phi_insertion_points, bool update_p) renamer will use the symbol on the LHS to get its reaching definition. */ FOR_EACH_EDGE (e, ei, bb->preds) - add_phi_arg (phi, var, e); + add_phi_arg (phi, var, e, UNKNOWN_LOCATION); } else { @@ -1320,9 +1320,12 @@ rewrite_add_phi_arguments (basic_block bb) gsi_next (&gsi)) { tree currdef; + gimple stmt; + phi = gsi_stmt (gsi); currdef = get_reaching_def (SSA_NAME_VAR (gimple_phi_result (phi))); - add_phi_arg (phi, currdef, e); + stmt = SSA_NAME_DEF_STMT (currdef); + add_phi_arg (phi, currdef, e, gimple_location (stmt)); } } } @@ -1857,7 +1860,7 @@ rewrite_update_phi_arguments (basic_block bb) phis = VEC_index (gimple_vec, phis_to_rewrite, e->dest->index); for (i = 0; VEC_iterate (gimple, phis, i, phi); i++) { - tree arg, lhs_sym; + tree arg, lhs_sym, reaching_def = NULL; use_operand_p arg_p; gcc_assert (rewrite_uses_p (phi)); @@ -1875,18 +1878,41 @@ rewrite_update_phi_arguments (basic_block bb) /* When updating a PHI node for a recently introduced symbol we may find NULL arguments. That's why we take the symbol from the LHS of the PHI node. */ - SET_USE (arg_p, get_reaching_def (lhs_sym)); + reaching_def = get_reaching_def (lhs_sym); + } else { tree sym = DECL_P (arg) ? arg : SSA_NAME_VAR (arg); if (symbol_marked_for_renaming (sym)) - SET_USE (arg_p, get_reaching_def (sym)); + reaching_def = get_reaching_def (sym); else if (is_old_name (arg)) - SET_USE (arg_p, get_reaching_def (arg)); + reaching_def = get_reaching_def (arg); + } + + /* Update the argument if there is a reaching def. */ + if (reaching_def) + { + gimple stmt; + source_location locus; + int arg_i = PHI_ARG_INDEX_FROM_USE (arg_p); + + SET_USE (arg_p, reaching_def); + stmt = SSA_NAME_DEF_STMT (reaching_def); + + /* Single element PHI nodes behave like copies, so get the + location from the phi argument. */ + if (gimple_code (stmt) == GIMPLE_PHI && + gimple_phi_num_args (stmt) == 1) + locus = gimple_phi_arg_location (stmt, 0); + else + locus = gimple_location (stmt); + + gimple_phi_arg_set_location (phi, arg_i, locus); } + if (e->flags & EDGE_ABNORMAL) SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (arg_p)) = 1; } diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 575025473cb..b9b6ea3cd43 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -97,17 +97,20 @@ update_phis_for_loop_copy (struct loop *orig_loop, struct loop *new_loop) gsi_next (&si_new), gsi_next (&si_orig)) { tree def; + source_location locus; gimple phi_new = gsi_stmt (si_new); gimple phi_orig = gsi_stmt (si_orig); /* Add the first phi argument for the phi in NEW_LOOP (the one associated with the entry of NEW_LOOP) */ def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_entry_e); - add_phi_arg (phi_new, def, new_loop_entry_e); + locus = gimple_phi_arg_location_from_edge (phi_orig, orig_entry_e); + add_phi_arg (phi_new, def, new_loop_entry_e, locus); /* Add the second phi argument for the phi in NEW_LOOP (the one associated with the latch of NEW_LOOP) */ def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch); + locus = gimple_phi_arg_location_from_edge (phi_orig, orig_loop_latch); if (TREE_CODE (def) == SSA_NAME) { @@ -122,7 +125,7 @@ update_phis_for_loop_copy (struct loop *orig_loop, struct loop *new_loop) /* Could be an integer. */ new_ssa_name = def; - add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop)); + add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus); } } diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index 4ed8e9fbdf0..420ee8099b4 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -36,6 +36,9 @@ along with GCC; see the file COPYING3. If not see #include "ssaexpand.h" +DEF_VEC_I(source_location); +DEF_VEC_ALLOC_I(source_location,heap); + /* Used to hold all the components required to do SSA PHI elimination. The node and pred/succ list is a simple linear list of nodes and edges represented as pairs of nodes. @@ -67,6 +70,9 @@ typedef struct _elim_graph { /* The predecessor and successor edge list. */ VEC(int,heap) *edge_list; + /* Source locus on each edge */ + VEC(source_location,heap) *edge_locus; + /* Visited vector. */ sbitmap visited; @@ -82,6 +88,9 @@ typedef struct _elim_graph { /* List of constant copies to emit. These are pushed on in pairs. */ VEC(int,heap) *const_dests; VEC(tree,heap) *const_copies; + + /* Source locations for any constant copies. */ + VEC(source_location,heap) *copy_locus; } *elim_graph; @@ -150,7 +159,7 @@ emit_partition_copy (rtx dest, rtx src, int unsignedsrcp) /* Insert a copy instruction from partition SRC to DEST onto edge E. */ static void -insert_partition_copy_on_edge (edge e, int dest, int src) +insert_partition_copy_on_edge (edge e, int dest, int src, source_location locus) { rtx seq; if (dump_file && (dump_flags & TDF_DETAILS)) @@ -167,6 +176,9 @@ insert_partition_copy_on_edge (edge e, int dest, int src) gcc_assert (SA.partition_to_pseudo[src]); set_location_for_edge (e); + /* If a locus is provided, override the default. */ + if (locus) + set_curr_insn_source_location (locus); seq = emit_partition_copy (SA.partition_to_pseudo[dest], SA.partition_to_pseudo[src], @@ -180,7 +192,7 @@ insert_partition_copy_on_edge (edge e, int dest, int src) onto edge E. */ static void -insert_value_copy_on_edge (edge e, int dest, tree src) +insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus) { rtx seq, x; enum machine_mode mode; @@ -197,6 +209,9 @@ insert_value_copy_on_edge (edge e, int dest, tree src) gcc_assert (SA.partition_to_pseudo[dest]); set_location_for_edge (e); + /* If a locus is provided, override the default. */ + if (locus) + set_curr_insn_source_location (locus); start_sequence (); mode = GET_MODE (SA.partition_to_pseudo[dest]); @@ -219,7 +234,8 @@ insert_value_copy_on_edge (edge e, int dest, tree src) onto edge E. */ static void -insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp) +insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp, + source_location locus) { rtx seq; if (dump_file && (dump_flags & TDF_DETAILS)) @@ -233,7 +249,11 @@ insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp) } gcc_assert (SA.partition_to_pseudo[dest]); + set_location_for_edge (e); + /* If a locus is provided, override the default. */ + if (locus) + set_curr_insn_source_location (locus); seq = emit_partition_copy (SA.partition_to_pseudo[dest], src, @@ -246,7 +266,7 @@ insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp) onto edge E. */ static void -insert_part_to_rtx_on_edge (edge e, rtx dest, int src) +insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus) { rtx seq; if (dump_file && (dump_flags & TDF_DETAILS)) @@ -260,7 +280,11 @@ insert_part_to_rtx_on_edge (edge e, rtx dest, int src) } gcc_assert (SA.partition_to_pseudo[src]); + set_location_for_edge (e); + /* If a locus is provided, override the default. */ + if (locus) + set_curr_insn_source_location (locus); seq = emit_partition_copy (dest, SA.partition_to_pseudo[src], @@ -282,7 +306,9 @@ new_elim_graph (int size) g->nodes = VEC_alloc (int, heap, 30); g->const_dests = VEC_alloc (int, heap, 20); g->const_copies = VEC_alloc (tree, heap, 20); + g->copy_locus = VEC_alloc (source_location, heap, 10); g->edge_list = VEC_alloc (int, heap, 20); + g->edge_locus = VEC_alloc (source_location, heap, 10); g->stack = VEC_alloc (int, heap, 30); g->visited = sbitmap_alloc (size); @@ -298,6 +324,7 @@ clear_elim_graph (elim_graph g) { VEC_truncate (int, g->nodes, 0); VEC_truncate (int, g->edge_list, 0); + VEC_truncate (source_location, g->edge_locus, 0); } @@ -312,6 +339,9 @@ delete_elim_graph (elim_graph g) VEC_free (tree, heap, g->const_copies); VEC_free (int, heap, g->const_dests); VEC_free (int, heap, g->nodes); + VEC_free (source_location, heap, g->copy_locus); + VEC_free (source_location, heap, g->edge_locus); + free (g); } @@ -343,10 +373,11 @@ elim_graph_add_node (elim_graph g, int node) /* Add the edge PRED->SUCC to graph G. */ static inline void -elim_graph_add_edge (elim_graph g, int pred, int succ) +elim_graph_add_edge (elim_graph g, int pred, int succ, source_location locus) { VEC_safe_push (int, heap, g->edge_list, pred); VEC_safe_push (int, heap, g->edge_list, succ); + VEC_safe_push (source_location, heap, g->edge_locus, locus); } @@ -354,7 +385,7 @@ elim_graph_add_edge (elim_graph g, int pred, int succ) return the successor node. -1 is returned if there is no such edge. */ static inline int -elim_graph_remove_succ_edge (elim_graph g, int node) +elim_graph_remove_succ_edge (elim_graph g, int node, source_location *locus) { int y; unsigned x; @@ -364,8 +395,11 @@ elim_graph_remove_succ_edge (elim_graph g, int node) VEC_replace (int, g->edge_list, x, -1); y = VEC_index (int, g->edge_list, x + 1); VEC_replace (int, g->edge_list, x + 1, -1); + *locus = VEC_index (source_location, g->edge_locus, x / 2); + VEC_replace (source_location, g->edge_locus, x / 2, UNKNOWN_LOCATION); return y; } + *locus = UNKNOWN_LOCATION; return -1; } @@ -374,7 +408,7 @@ elim_graph_remove_succ_edge (elim_graph g, int node) edge list. VAR will hold the partition number found. CODE is the code fragment executed for every node found. */ -#define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, CODE) \ +#define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, LOCUS, CODE) \ do { \ unsigned x_; \ int y_; \ @@ -384,6 +418,7 @@ do { \ if (y_ != (NODE)) \ continue; \ (VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1); \ + (LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \ CODE; \ } \ } while (0) @@ -393,7 +428,7 @@ do { \ GRAPH. VAR will hold the partition number found. CODE is the code fragment executed for every node found. */ -#define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, CODE) \ +#define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, LOCUS, CODE) \ do { \ unsigned x_; \ int y_; \ @@ -403,6 +438,7 @@ do { \ if (y_ != (NODE)) \ continue; \ (VAR) = VEC_index (int, (GRAPH)->edge_list, x_); \ + (LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \ CODE; \ } \ } while (0) @@ -432,6 +468,7 @@ eliminate_build (elim_graph g) for (gsi = gsi_start_phis (g->e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple phi = gsi_stmt (gsi); + source_location locus; p0 = var_to_partition (g->map, gimple_phi_result (phi)); /* Ignore results which are not in partitions. */ @@ -439,6 +476,7 @@ eliminate_build (elim_graph g) continue; Ti = PHI_ARG_DEF (phi, g->e->dest_idx); + locus = gimple_phi_arg_location_from_edge (phi, g->e); /* If this argument is a constant, or a SSA_NAME which is being left in SSA form, just queue a copy to be emitted on this @@ -451,6 +489,7 @@ eliminate_build (elim_graph g) on this edge. */ VEC_safe_push (int, heap, g->const_dests, p0); VEC_safe_push (tree, heap, g->const_copies, Ti); + VEC_safe_push (source_location, heap, g->copy_locus, locus); } else { @@ -459,7 +498,7 @@ eliminate_build (elim_graph g) { eliminate_name (g, p0); eliminate_name (g, pi); - elim_graph_add_edge (g, p0, pi); + elim_graph_add_edge (g, p0, pi, locus); } } } @@ -472,8 +511,10 @@ static void elim_forward (elim_graph g, int T) { int S; + source_location locus; + SET_BIT (g->visited, T); - FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, + FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, locus, { if (!TEST_BIT (g->visited, S)) elim_forward (g, S); @@ -488,7 +529,9 @@ static int elim_unvisited_predecessor (elim_graph g, int T) { int P; - FOR_EACH_ELIM_GRAPH_PRED (g, T, P, + source_location locus; + + FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, { if (!TEST_BIT (g->visited, P)) return 1; @@ -502,13 +545,15 @@ static void elim_backward (elim_graph g, int T) { int P; + source_location locus; + SET_BIT (g->visited, T); - FOR_EACH_ELIM_GRAPH_PRED (g, T, P, + FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, { if (!TEST_BIT (g->visited, P)) { elim_backward (g, P); - insert_partition_copy_on_edge (g->e, P, T); + insert_partition_copy_on_edge (g->e, P, T, locus); } }); } @@ -521,9 +566,8 @@ get_temp_reg (tree name) { tree var = TREE_CODE (name) == SSA_NAME ? SSA_NAME_VAR (name) : name; tree type = TREE_TYPE (var); - int unsignedp = TYPE_UNSIGNED (type); - enum machine_mode reg_mode - = promote_mode (type, DECL_MODE (var), &unsignedp, 0); + int unsignedp; + enum machine_mode reg_mode = promote_decl_mode (var, &unsignedp); rtx x = gen_reg_rtx (reg_mode); if (POINTER_TYPE_P (type)) mark_reg_pointer (x, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (var)))); @@ -537,6 +581,7 @@ static void elim_create (elim_graph g, int T) { int P, S; + source_location locus; if (elim_unvisited_predecessor (g, T)) { @@ -544,23 +589,23 @@ elim_create (elim_graph g, int T) rtx U = get_temp_reg (var); int unsignedsrcp = TYPE_UNSIGNED (TREE_TYPE (var)); - insert_part_to_rtx_on_edge (g->e, U, T); - FOR_EACH_ELIM_GRAPH_PRED (g, T, P, + insert_part_to_rtx_on_edge (g->e, U, T, UNKNOWN_LOCATION); + FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, { if (!TEST_BIT (g->visited, P)) { elim_backward (g, P); - insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp); + insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp, locus); } }); } else { - S = elim_graph_remove_succ_edge (g, T); + S = elim_graph_remove_succ_edge (g, T, &locus); if (S != -1) { SET_BIT (g->visited, T); - insert_partition_copy_on_edge (g->e, T, S); + insert_partition_copy_on_edge (g->e, T, S, locus); } } } @@ -574,6 +619,7 @@ eliminate_phi (edge e, elim_graph g) int x; gcc_assert (VEC_length (tree, g->const_copies) == 0); + gcc_assert (VEC_length (source_location, g->copy_locus) == 0); /* Abnormal edges already have everything coalesced. */ if (e->flags & EDGE_ABNORMAL) @@ -610,9 +656,12 @@ eliminate_phi (edge e, elim_graph g) { int dest; tree src; + source_location locus; + src = VEC_pop (tree, g->const_copies); dest = VEC_pop (int, g->const_dests); - insert_value_copy_on_edge (e, dest, src); + locus = VEC_pop (source_location, g->copy_locus); + insert_value_copy_on_edge (e, dest, src, locus); } } @@ -991,6 +1040,11 @@ insert_backedge_copies (void) name = make_ssa_name (result_var, stmt); gimple_assign_set_lhs (stmt, name); + /* copy location if present. */ + if (gimple_phi_arg_has_location (phi, i)) + gimple_set_location (stmt, + gimple_phi_arg_location (phi, i)); + /* Insert the new statement into the block and update the PHI node. */ if (last && stmt_ends_bb_p (last)) diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c index f9a2e40d480..9acf0ff75f0 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -747,6 +747,7 @@ create_phi_for_local_result (void **slot, void *data) gimple new_phi; basic_block store_bb; tree local_res; + source_location locus; /* STORE_BB is the block where the phi should be stored. It is the destination of the loop exit. @@ -765,11 +766,12 @@ create_phi_for_local_result (void **slot, void *data) local_res = make_ssa_name (SSA_NAME_VAR (gimple_assign_lhs (reduc->reduc_stmt)), NULL); + locus = gimple_location (reduc->reduc_stmt); new_phi = create_phi_node (local_res, store_bb); SSA_NAME_DEF_STMT (local_res) = new_phi; - add_phi_arg (new_phi, reduc->init, e); + add_phi_arg (new_phi, reduc->init, e, locus); add_phi_arg (new_phi, gimple_assign_lhs (reduc->reduc_stmt), - FALLTHRU_EDGE (loop->latch)); + FALLTHRU_EDGE (loop->latch), locus); reduc->new_phi = new_phi; return 1; @@ -1219,7 +1221,7 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit nphi = create_phi_node (res, orig_header); SSA_NAME_DEF_STMT (res) = nphi; - add_phi_arg (nphi, t, hpred); + add_phi_arg (nphi, t, hpred, UNKNOWN_LOCATION); if (res == control) { @@ -1370,14 +1372,20 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data, end = make_edge (loop->latch, ex_bb, EDGE_FALLTHRU); for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); gsi_next (&gsi)) { + source_location locus; + tree def; phi = gsi_stmt (gsi); res = PHI_RESULT (phi); stmt = SSA_NAME_DEF_STMT (PHI_ARG_DEF_FROM_EDGE (phi, exit)); - add_phi_arg (phi, - PHI_ARG_DEF_FROM_EDGE (stmt, loop_preheader_edge (loop)), - guard); - add_phi_arg (phi, PHI_ARG_DEF_FROM_EDGE (stmt, loop_latch_edge (loop)), - end); + + def = PHI_ARG_DEF_FROM_EDGE (stmt, loop_preheader_edge (loop)); + locus = gimple_phi_arg_location_from_edge (stmt, + loop_preheader_edge (loop)); + add_phi_arg (phi, def, guard, locus); + + def = PHI_ARG_DEF_FROM_EDGE (stmt, loop_latch_edge (loop)); + locus = gimple_phi_arg_location_from_edge (stmt, loop_latch_edge (loop)); + add_phi_arg (phi, def, end, locus); } e = redirect_edge_and_branch (exit, nexit->dest); PENDING_STMT (e) = NULL; diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c index 2907807690a..a48ae01fe8d 100644 --- a/gcc/tree-phinodes.c +++ b/gcc/tree-phinodes.c @@ -231,6 +231,8 @@ make_phi_node (tree var, int len) for (i = 0; i < capacity; i++) { use_operand_p imm; + + gimple_phi_arg_set_location (phi, i, UNKNOWN_LOCATION); imm = gimple_phi_arg_imm_use_ptr (phi, i); imm->use = gimple_phi_arg_def_ptr (phi, i); imm->prev = NULL; @@ -299,6 +301,8 @@ resize_phi_node (gimple *phi, size_t len) for (i = gimple_phi_num_args (new_phi); i < len; i++) { use_operand_p imm; + + gimple_phi_arg_set_location (new_phi, i, UNKNOWN_LOCATION); imm = gimple_phi_arg_imm_use_ptr (new_phi, i); imm->use = gimple_phi_arg_def_ptr (new_phi, i); imm->prev = NULL; @@ -384,7 +388,7 @@ create_phi_node (tree var, basic_block bb) PHI points to the reallocated phi node when we return. */ void -add_phi_arg (gimple phi, tree def, edge e) +add_phi_arg (gimple phi, tree def, edge e, source_location locus) { basic_block bb = e->dest; @@ -407,6 +411,7 @@ add_phi_arg (gimple phi, tree def, edge e) } SET_PHI_ARG_DEF (phi, e->dest_idx, def); + gimple_phi_arg_set_location (phi, e->dest_idx, locus); } @@ -435,6 +440,9 @@ remove_phi_arg_num (gimple phi, int i) /* Set use on new node, and link into last element's place. */ *(new_p->use) = *(old_p->use); relink_imm_use (new_p, old_p); + /* Move the location as well. */ + gimple_phi_arg_set_location (phi, i, + gimple_phi_arg_location (phi, num_elem - 1)); } /* Shrink the vector and return. Note that we do not have to clear diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index 5d8bf4d2704..0ce35f5de86 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -1512,8 +1512,8 @@ initialize_root_vars (struct loop *loop, chain_p chain, bitmap tmp_vars) phi = create_phi_node (var, loop->header); SSA_NAME_DEF_STMT (var) = phi; - add_phi_arg (phi, init, entry); - add_phi_arg (phi, next, latch); + add_phi_arg (phi, init, entry, UNKNOWN_LOCATION); + add_phi_arg (phi, next, latch, UNKNOWN_LOCATION); } } @@ -1576,8 +1576,8 @@ initialize_root_vars_lm (struct loop *loop, dref root, bool written, next = VEC_index (tree, *vars, 1); phi = create_phi_node (var, loop->header); SSA_NAME_DEF_STMT (var) = phi; - add_phi_arg (phi, init, entry); - add_phi_arg (phi, next, latch); + add_phi_arg (phi, init, entry, UNKNOWN_LOCATION); + add_phi_arg (phi, next, latch, UNKNOWN_LOCATION); } else { diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index bac6e594d8f..02a4eed646e 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -466,7 +466,7 @@ loop_phi_node_p (gimple phi) EVOLUTION_FN = {i_0, +, 2}_1. */ -static tree +tree compute_overall_effect_of_inner_loop (struct loop *loop, tree evolution_fn) { bool val = false; @@ -492,7 +492,10 @@ compute_overall_effect_of_inner_loop (struct loop *loop, tree evolution_fn) /* evolution_fn is the evolution function in LOOP. Get its value in the nb_iter-th iteration. */ res = chrec_apply (inner_loop->num, evolution_fn, nb_iter); - + + if (chrec_contains_symbols_defined_in_loop (res, loop->num)) + res = instantiate_parameters (loop, res); + /* Continue the computation until ending on a parent of LOOP. */ return compute_overall_effect_of_inner_loop (loop, res); } @@ -1890,18 +1893,16 @@ analyze_scalar_evolution_1 (struct loop *loop, tree var, tree res) return res; } -/* Entry point for the scalar evolution analyzer. - Analyzes and returns the scalar evolution of the ssa_name VAR. - LOOP_NB is the identifier number of the loop in which the variable - is used. +/* Analyzes and returns the scalar evolution of the ssa_name VAR in + LOOP. LOOP is the loop in which the variable is used. Example of use: having a pointer VAR to a SSA_NAME node, STMT a pointer to the statement that uses this variable, in order to determine the evolution function of the variable, use the following calls: - unsigned loop_nb = loop_containing_stmt (stmt)->num; - tree chrec_with_symbols = analyze_scalar_evolution (loop_nb, var); + loop_p loop = loop_containing_stmt (stmt); + tree chrec_with_symbols = analyze_scalar_evolution (loop, var); tree chrec_instantiated = instantiate_parameters (loop, chrec_with_symbols); */ @@ -2174,7 +2175,9 @@ instantiate_scev_1 (basic_block instantiate_below, else res = chrec; - if (res == NULL_TREE) + if (res == NULL_TREE + || !dominated_by_p (CDI_DOMINATORS, instantiate_below, + gimple_bb (SSA_NAME_DEF_STMT (res)))) res = chrec_dont_know; } diff --git a/gcc/tree-scalar-evolution.h b/gcc/tree-scalar-evolution.h index 06324972ca5..5caadc57031 100644 --- a/gcc/tree-scalar-evolution.h +++ b/gcc/tree-scalar-evolution.h @@ -1,5 +1,5 @@ /* Scalar evolution detector. - Copyright (C) 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Sebastian Pop <s.pop@laposte.net> This file is part of GCC. @@ -33,10 +33,10 @@ extern tree instantiate_scev (basic_block, struct loop *, tree); extern tree resolve_mixers (struct loop *, tree); extern void gather_stats_on_scev_database (void); extern void scev_analysis (void); -unsigned int scev_const_prop (void); - -bool expression_expensive_p (tree); +extern unsigned int scev_const_prop (void); +extern bool expression_expensive_p (tree); extern bool simple_iv (struct loop *, struct loop *, tree, affine_iv *, bool); +extern tree compute_overall_effect_of_inner_loop (struct loop *, tree); /* Returns the basic block preceding LOOP or ENTRY_BLOCK_PTR when the loop is function's body. */ diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index c1f4e7f647b..2eec3147886 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -951,6 +951,7 @@ forward_edge_to_pdom (edge e, basic_block post_dom_bb) { gimple phi = gsi_stmt (gsi); tree op; + source_location locus; /* Dead PHI do not imply control dependency. */ if (!gimple_plf (phi, STMT_NECESSARY) @@ -975,10 +976,16 @@ forward_edge_to_pdom (edge e, basic_block post_dom_bb) continue; } if (!e2) - op = gimple_phi_arg_def (phi, e->dest_idx == 0 ? 1 : 0); + { + op = gimple_phi_arg_def (phi, e->dest_idx == 0 ? 1 : 0); + locus = gimple_phi_arg_location (phi, e->dest_idx == 0 ? 1 : 0); + } else - op = gimple_phi_arg_def (phi, e2->dest_idx); - add_phi_arg (phi, op, e); + { + op = gimple_phi_arg_def (phi, e2->dest_idx); + locus = gimple_phi_arg_location (phi, e2->dest_idx); + } + add_phi_arg (phi, op, e, locus); gcc_assert (e2 || degenerate_phi_p (phi)); gsi_next (&gsi); } diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c index c4a40b084a6..e43c0bc404a 100644 --- a/gcc/tree-ssa-loop-manip.c +++ b/gcc/tree-ssa-loop-manip.c @@ -125,8 +125,8 @@ create_iv (tree base, tree step, tree var, struct loop *loop, stmt = create_phi_node (vb, loop->header); SSA_NAME_DEF_STMT (vb) = stmt; - add_phi_arg (stmt, initial, loop_preheader_edge (loop)); - add_phi_arg (stmt, va, loop_latch_edge (loop)); + add_phi_arg (stmt, initial, loop_preheader_edge (loop), UNKNOWN_LOCATION); + add_phi_arg (stmt, va, loop_latch_edge (loop), UNKNOWN_LOCATION); } /* Add exit phis for the USE on EXIT. */ @@ -156,7 +156,7 @@ add_exit_phis_edge (basic_block exit, tree use) create_new_def_for (gimple_phi_result (phi), phi, gimple_phi_result_ptr (phi)); FOR_EACH_EDGE (e, ei, exit->preds) - add_phi_arg (phi, use, e); + add_phi_arg (phi, use, e, UNKNOWN_LOCATION); } /* Add exit phis for VAR that is used in LIVEIN. @@ -476,11 +476,13 @@ split_loop_exit_edge (edge exit) tree new_name, name; use_operand_p op_p; gimple_stmt_iterator psi; + source_location locus; for (psi = gsi_start_phis (dest); !gsi_end_p (psi); gsi_next (&psi)) { phi = gsi_stmt (psi); op_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (bb)); + locus = gimple_phi_arg_location_from_edge (phi, single_succ_edge (bb)); name = USE_FROM_PTR (op_p); @@ -494,7 +496,7 @@ split_loop_exit_edge (edge exit) new_name = duplicate_ssa_name (name, NULL); new_phi = create_phi_node (new_name, bb); SSA_NAME_DEF_STMT (new_name) = new_phi; - add_phi_arg (new_phi, name, exit); + add_phi_arg (new_phi, name, exit, locus); SET_USE (op_p, new_name); } @@ -1014,8 +1016,8 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor, phi_rest = create_phi_node (new_init, rest); SSA_NAME_DEF_STMT (new_init) = phi_rest; - add_phi_arg (phi_rest, init, precond_edge); - add_phi_arg (phi_rest, next, new_exit); + add_phi_arg (phi_rest, init, precond_edge, UNKNOWN_LOCATION); + add_phi_arg (phi_rest, next, new_exit, UNKNOWN_LOCATION); SET_USE (op, new_init); } diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c index 0aab6d3a2d3..8f7047f8309 100644 --- a/gcc/tree-ssa-loop.c +++ b/gcc/tree-ssa-loop.c @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "tree-inline.h" #include "tree-scalar-evolution.h" +#include "toplev.h" #include "tree-vectorizer.h" /* The loop superpass. */ @@ -307,9 +308,12 @@ gate_graphite_transforms (void) /* Enable -fgraphite pass if any one of the graphite optimization flags is turned on. */ if (flag_loop_block || flag_loop_interchange || flag_loop_strip_mine - || flag_graphite_identity) + || flag_graphite_identity || flag_loop_parallelize_all) flag_graphite = 1; + if (flag_loop_block) + sorry ("loop blocking not implemented"); + return flag_graphite != 0; } diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 8c3f71d32b6..97847f4c888 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -513,6 +513,8 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb, if (!useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (new_var))) { + source_location locus_0, locus_1; + new_var2 = create_tmp_var (TREE_TYPE (result), NULL); add_referenced_var (new_var2); new_stmt = gimple_build_assign_with_ops (CONVERT_EXPR, new_var2, @@ -521,6 +523,13 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb, gimple_assign_set_lhs (new_stmt, new_var2); gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); new_var = new_var2; + + /* Set the locus to the first argument, unless is doesn't have one. */ + locus_0 = gimple_phi_arg_location (phi, 0); + locus_1 = gimple_phi_arg_location (phi, 1); + if (locus_0 == UNKNOWN_LOCATION) + locus_0 = locus_1; + gimple_set_location (new_stmt, locus_0); } replace_phi_edge_with_variable (cond_bb, e1, phi, new_var); @@ -1177,6 +1186,7 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, tree lhs, rhs, name; gimple newphi, new_stmt; gimple_stmt_iterator gsi; + source_location locus; enum tree_code code; /* Check if middle_bb contains of only one store. */ @@ -1184,6 +1194,7 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, || gimple_code (assign) != GIMPLE_ASSIGN) return false; + locus = gimple_location (assign); lhs = gimple_assign_lhs (assign); rhs = gimple_assign_rhs1 (assign); if (!INDIRECT_REF_P (lhs)) @@ -1224,6 +1235,7 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, new_stmt = gimple_build_assign (condstoretemp, lhs); name = make_ssa_name (condstoretemp, new_stmt); gimple_assign_set_lhs (new_stmt, name); + gimple_set_location (new_stmt, locus); mark_symbols_for_renaming (new_stmt); gsi_insert_on_edge (e1, new_stmt); @@ -1231,8 +1243,8 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, holding the old RHS, and the other holding the temporary where we stored the old memory contents. */ newphi = create_phi_node (condstoretemp, join_bb); - add_phi_arg (newphi, rhs, e0); - add_phi_arg (newphi, name, e1); + add_phi_arg (newphi, rhs, e0, locus); + add_phi_arg (newphi, name, e1, locus); lhs = unshare_expr (lhs); new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi)); diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c index 022e4af9a48..bac2303899f 100644 --- a/gcc/tree-ssa-phiprop.c +++ b/gcc/tree-ssa-phiprop.c @@ -159,14 +159,17 @@ phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt, { tree old_arg, new_var; gimple tmp; + source_location locus; old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e); + locus = gimple_phi_arg_location_from_edge (phi, e); while (TREE_CODE (old_arg) == SSA_NAME && (SSA_NAME_VERSION (old_arg) >= n || phivn[SSA_NAME_VERSION (old_arg)].value == NULL_TREE)) { gimple def_stmt = SSA_NAME_DEF_STMT (old_arg); old_arg = gimple_assign_rhs1 (def_stmt); + locus = gimple_location (def_stmt); } if (TREE_CODE (old_arg) == SSA_NAME) @@ -196,6 +199,7 @@ phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt, add_referenced_var (new_var); new_var = make_ssa_name (new_var, tmp); gimple_assign_set_lhs (tmp, new_var); + gimple_set_location (tmp, locus); gsi_insert_on_edge (e, tmp); update_stmt (tmp); @@ -209,7 +213,7 @@ phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt, } } - add_phi_arg (new_phi, new_var, e); + add_phi_arg (new_phi, new_var, e, locus); } update_stmt (new_phi); diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 9e3754b37fc..237c250a5f0 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -3328,9 +3328,10 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum, gcc_assert (get_expr_type (ae) == type || useless_type_conversion_p (type, get_expr_type (ae))); if (ae->kind == CONSTANT) - add_phi_arg (phi, PRE_EXPR_CONSTANT (ae), pred); + add_phi_arg (phi, PRE_EXPR_CONSTANT (ae), pred, UNKNOWN_LOCATION); else - add_phi_arg (phi, PRE_EXPR_NAME (avail[pred->src->index]), pred); + add_phi_arg (phi, PRE_EXPR_NAME (avail[pred->src->index]), pred, + UNKNOWN_LOCATION); } newphi = get_or_alloc_expr_for_name (gimple_phi_result (phi)); diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index b6d2fafaa0f..71a34957bdf 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -325,9 +325,11 @@ create_edge_and_update_destination_phis (struct redirection_data *rd) for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple phi = gsi_stmt (gsi); - + source_location locus; int indx = rd->outgoing_edge->dest_idx; - add_phi_arg (phi, gimple_phi_arg_def (phi, indx), e); + + locus = gimple_phi_arg_location (phi, indx); + add_phi_arg (phi, gimple_phi_arg_def (phi, indx), e, locus); } } diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 7ec04f70fad..28da94bb21c 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -53,7 +53,7 @@ static struct pointer_map_t *edge_var_maps; /* Add a mapping with PHI RESULT and PHI DEF associated with edge E. */ void -redirect_edge_var_map_add (edge e, tree result, tree def) +redirect_edge_var_map_add (edge e, tree result, tree def, source_location locus) { void **slot; edge_var_map_vector old_head, head; @@ -71,6 +71,7 @@ redirect_edge_var_map_add (edge e, tree result, tree def) } new_node.def = def; new_node.result = result; + new_node.locus = locus; VEC_safe_push (edge_var_map, heap, head, &new_node); if (old_head != head) @@ -193,14 +194,16 @@ ssa_redirect_edge (edge e, basic_block dest) for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) { tree def; + source_location locus ; phi = gsi_stmt (gsi); def = gimple_phi_arg_def (phi, e->dest_idx); + locus = gimple_phi_arg_location (phi, e->dest_idx); if (def == NULL_TREE) continue; - redirect_edge_var_map_add (e, gimple_phi_result (phi), def); + redirect_edge_var_map_add (e, gimple_phi_result (phi), def, locus); } e = redirect_edge_succ_nodup (e, dest); @@ -233,7 +236,7 @@ flush_pending_stmts (edge e) phi = gsi_stmt (gsi); def = redirect_edge_var_map_def (vm); - add_phi_arg (phi, def, e); + add_phi_arg (phi, def, e, redirect_edge_var_map_location (vm)); } redirect_edge_var_map_clear (e); @@ -894,6 +897,11 @@ useless_type_conversion_p_1 (tree outer_type, tree inner_type) && SCALAR_FLOAT_TYPE_P (outer_type)) return true; + /* Fixed point types with the same mode are compatible. */ + else if (FIXED_POINT_TYPE_P (inner_type) + && FIXED_POINT_TYPE_P (outer_type)) + return true; + /* We need to take special care recursing to pointed-to types. */ else if (POINTER_TYPE_P (inner_type) && POINTER_TYPE_P (outer_type)) @@ -997,12 +1005,17 @@ useless_type_conversion_p_1 (tree outer_type, tree inner_type) bool useless_type_conversion_p (tree outer_type, tree inner_type) { - /* If the outer type is (void *), then the conversion is not - necessary. We have to make sure to not apply this while - recursing though. */ + /* If the outer type is (void *) or a pointer to an incomplete record type, + then the conversion is not necessary. + We have to make sure to not apply this while recursing though. */ if (POINTER_TYPE_P (inner_type) && POINTER_TYPE_P (outer_type) - && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE) + && (VOID_TYPE_P (TREE_TYPE (outer_type)) + || (AGGREGATE_TYPE_P (TREE_TYPE (outer_type)) + && TREE_CODE (TREE_TYPE (outer_type)) != ARRAY_TYPE + && (TREE_CODE (TREE_TYPE (outer_type)) + == TREE_CODE (TREE_TYPE (inner_type))) + && !COMPLETE_TYPE_P (TREE_TYPE (outer_type))))) return true; return useless_type_conversion_p_1 (outer_type, inner_type); @@ -1252,7 +1265,12 @@ warn_uninitialized_var (tree *tp, int *walk_subtrees, void *data_) /* We do not care about LHS. */ if (wi->is_lhs) - return NULL_TREE; + { + /* Except for operands of INDIRECT_REF. */ + if (!INDIRECT_REF_P (t)) + return NULL_TREE; + t = TREE_OPERAND (t, 0); + } switch (TREE_CODE (t)) { diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index a5494827b37..1309e822fe2 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -638,8 +638,8 @@ fix_phi_nodes (edge e1f, edge e2f, basic_block bbf) !gsi_end_p (gsi); gsi_next (&gsi), i++) { gimple phi = gsi_stmt (gsi); - add_phi_arg (phi, info.target_inbound_names[i], e1f); - add_phi_arg (phi, info.target_outbound_names[i], e2f); + add_phi_arg (phi, info.target_inbound_names[i], e1f, UNKNOWN_LOCATION); + add_phi_arg (phi, info.target_outbound_names[i], e2f, UNKNOWN_LOCATION); } } diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index f2d58dd6e4a..efd6bc2c029 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -548,7 +548,7 @@ add_successor_phi_arg (edge e, tree var, tree phi_arg) break; gcc_assert (!gsi_end_p (gsi)); - add_phi_arg (gsi_stmt (gsi), phi_arg, e); + add_phi_arg (gsi_stmt (gsi), phi_arg, e, UNKNOWN_LOCATION); } /* Creates a GIMPLE statement which computes the operation specified by @@ -773,7 +773,7 @@ eliminate_tail_call (struct tailcall *t) phi = gsi_stmt (gsi); gcc_assert (param == SSA_NAME_VAR (PHI_RESULT (phi))); - add_phi_arg (phi, arg, e); + add_phi_arg (phi, arg, e, gimple_location (stmt)); gsi_next (&gsi); } @@ -870,7 +870,8 @@ create_tailcall_accumulator (const char *label, basic_block bb, tree init) add_referenced_var (tmp); phi = create_phi_node (tmp, bb); /* RET_TYPE can be a float when -ffast-maths is enabled. */ - add_phi_arg (phi, fold_convert (ret_type, init), single_pred_edge (bb)); + add_phi_arg (phi, fold_convert (ret_type, init), single_pred_edge (bb), + UNKNOWN_LOCATION); return PHI_RESULT (phi); } @@ -933,7 +934,8 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls) set_default_def (param, new_name); phi = create_phi_node (name, first); SSA_NAME_DEF_STMT (name) = phi; - add_phi_arg (phi, new_name, single_pred_edge (first)); + add_phi_arg (phi, new_name, single_pred_edge (first), + EXPR_LOCATION (param)); } phis_constructed = true; } diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 7646cc1ad0f..facde06969e 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -3049,7 +3049,7 @@ vect_setup_realignment (gimple stmt, gimple_stmt_iterator *gsi, msq = make_ssa_name (vec_dest, NULL); phi_stmt = create_phi_node (msq, containing_loop->header); SSA_NAME_DEF_STMT (msq) = phi_stmt; - add_phi_arg (phi_stmt, msq_init, pe); + add_phi_arg (phi_stmt, msq_init, pe, UNKNOWN_LOCATION); return msq; } diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index eaf263c4270..c0b15cd98a5 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -169,15 +169,18 @@ slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop, !gsi_end_p (gsi_new) && !gsi_end_p (gsi_orig); gsi_next (&gsi_new), gsi_next (&gsi_orig)) { + source_location locus; phi_new = gsi_stmt (gsi_new); phi_orig = gsi_stmt (gsi_orig); /* step 1. */ def = PHI_ARG_DEF_FROM_EDGE (phi_orig, entry_arg_e); - add_phi_arg (phi_new, def, new_loop_entry_e); + locus = gimple_phi_arg_location_from_edge (phi_orig, entry_arg_e); + add_phi_arg (phi_new, def, new_loop_entry_e, locus); /* step 2. */ def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch); + locus = gimple_phi_arg_location_from_edge (phi_orig, orig_loop_latch); if (TREE_CODE (def) != SSA_NAME) continue; @@ -190,7 +193,7 @@ slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop, } /* An ordinary ssa name defined in the loop. */ - add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop)); + add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus); /* step 3 (case 1). */ if (!after) @@ -383,6 +386,7 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop, !gsi_end_p (gsi_orig) && !gsi_end_p (gsi_update); gsi_next (&gsi_orig), gsi_next (&gsi_update)) { + source_location loop_locus, guard_locus;; orig_phi = gsi_stmt (gsi_orig); update_phi = gsi_stmt (gsi_update); @@ -395,10 +399,16 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop, /* 1.2. NEW_MERGE_BB has two incoming edges: GUARD_EDGE and the exit-edge of LOOP. Set the two phi args in NEW_PHI for these edges: */ loop_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, EDGE_SUCC (loop->latch, 0)); + loop_locus = gimple_phi_arg_location_from_edge (orig_phi, + EDGE_SUCC (loop->latch, + 0)); guard_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, loop_preheader_edge (loop)); + guard_locus + = gimple_phi_arg_location_from_edge (orig_phi, + loop_preheader_edge (loop)); - add_phi_arg (new_phi, loop_arg, new_exit_e); - add_phi_arg (new_phi, guard_arg, guard_edge); + add_phi_arg (new_phi, loop_arg, new_exit_e, loop_locus); + add_phi_arg (new_phi, guard_arg, guard_edge, guard_locus); /* 1.3. Update phi in successor block. */ gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == loop_arg @@ -417,7 +427,7 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop, *new_exit_bb); /* 2.2. NEW_EXIT_BB has one incoming edge: the exit-edge of the loop. */ - add_phi_arg (new_phi, loop_arg, single_exit (loop)); + add_phi_arg (new_phi, loop_arg, single_exit (loop), loop_locus); /* 2.3. Update phi in successor of NEW_EXIT_BB: */ gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg); @@ -545,8 +555,8 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop, if (new_name2) guard_arg = new_name2; - add_phi_arg (new_phi, loop_arg, new_exit_e); - add_phi_arg (new_phi, guard_arg, guard_edge); + add_phi_arg (new_phi, loop_arg, new_exit_e, UNKNOWN_LOCATION); + add_phi_arg (new_phi, guard_arg, guard_edge, UNKNOWN_LOCATION); /* 1.3. Update phi in successor block. */ gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == orig_def); @@ -561,7 +571,7 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop, *new_exit_bb); /* 2.2. NEW_EXIT_BB has one incoming edge: the exit-edge of the loop. */ - add_phi_arg (new_phi, loop_arg, single_exit (loop)); + add_phi_arg (new_phi, loop_arg, single_exit (loop), UNKNOWN_LOCATION); /* 2.3. Update phi in successor of NEW_EXIT_BB: */ gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg); @@ -596,7 +606,8 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop, /* 3.3. GUARD_BB has one incoming edge: */ gcc_assert (EDGE_COUNT (guard_edge->src->preds) == 1); - add_phi_arg (new_phi, arg, EDGE_PRED (guard_edge->src, 0)); + add_phi_arg (new_phi, arg, EDGE_PRED (guard_edge->src, 0), + UNKNOWN_LOCATION); /* 3.4. Update phi in successor of GUARD_BB: */ gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, guard_edge) @@ -720,13 +731,15 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, edge e) if (phi_arg) { edge new_loop_exit_edge; + source_location locus; + locus = gimple_phi_arg_location_from_edge (phi, single_exit (loop)); if (EDGE_SUCC (new_loop->header, 0)->dest == new_loop->latch) new_loop_exit_edge = EDGE_SUCC (new_loop->header, 1); else new_loop_exit_edge = EDGE_SUCC (new_loop->header, 0); - add_phi_arg (phi, phi_arg, new_loop_exit_edge); + add_phi_arg (phi, phi_arg, new_loop_exit_edge, locus); } } @@ -764,7 +777,8 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, edge e) phi = gsi_stmt (gsi); phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, entry_e); if (phi_arg) - add_phi_arg (phi, phi_arg, new_exit_e); + add_phi_arg (phi, phi_arg, new_exit_e, + gimple_phi_arg_location_from_edge (phi, entry_e)); } redirect_edge_and_branch_force (entry_e, new_loop->header); @@ -954,8 +968,9 @@ set_prologue_iterations (basic_block bb_before_first_loop, gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT); newphi = create_phi_node (var, bb_before_first_loop); - add_phi_arg (newphi, prologue_after_cost_adjust_name, e_fallthru); - add_phi_arg (newphi, first_niters, e_false); + add_phi_arg (newphi, prologue_after_cost_adjust_name, e_fallthru, + UNKNOWN_LOCATION); + add_phi_arg (newphi, first_niters, e_false, UNKNOWN_LOCATION); first_niters = PHI_RESULT (newphi); } @@ -2383,7 +2398,8 @@ vect_loop_versioning (loop_vec_info loop_vinfo, bool do_versioning, new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (orig_phi)), new_exit_bb); arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, e); - add_phi_arg (new_phi, arg, new_exit_e); + add_phi_arg (new_phi, arg, new_exit_e, + gimple_phi_arg_location_from_edge (orig_phi, e)); SET_PHI_ARG_DEF (orig_phi, e->dest_idx, PHI_RESULT (new_phi)); } diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index b7b9d7893e5..113dc0ff0e6 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -2524,8 +2524,9 @@ get_initial_def_for_induction (gimple iv_phi) NULL)); /* Set the arguments of the phi node: */ - add_phi_arg (induction_phi, vec_init, pe); - add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop)); + add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION); + add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop), + UNKNOWN_LOCATION); /* In case that vectorization factor (VF) is bigger than the number @@ -2934,12 +2935,13 @@ vect_create_epilog_for_reduction (tree vect_def, gimple stmt, for (j = 0; j < ncopies; j++) { /* 1.1 set the loop-entry arg of the reduction-phi: */ - add_phi_arg (phi, vec_initial_def, loop_preheader_edge (loop)); + add_phi_arg (phi, vec_initial_def, loop_preheader_edge (loop), + UNKNOWN_LOCATION); /* 1.2 set the loop-latch arg for the reduction-phi: */ if (j > 0) def = vect_get_vec_def_for_stmt_copy (dt, def); - add_phi_arg (phi, def, loop_latch_edge (loop)); + add_phi_arg (phi, def, loop_latch_edge (loop), UNKNOWN_LOCATION); if (vect_print_dump_info (REPORT_DETAILS)) { @@ -3350,9 +3352,9 @@ vect_finalize_reduction: /* Update phi node arguments with vs0 and vs2. */ add_phi_arg (vect_phi, vect_phi_init, - loop_preheader_edge (outer_loop)); + loop_preheader_edge (outer_loop), UNKNOWN_LOCATION); add_phi_arg (vect_phi, PHI_RESULT (epilog_stmt), - loop_latch_edge (outer_loop)); + loop_latch_edge (outer_loop), UNKNOWN_LOCATION); if (vect_print_dump_info (REPORT_DETAILS)) { fprintf (vect_dump, "created double reduction phi node: "); diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 50900775a04..aacf768a4cf 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -3639,7 +3639,8 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { gcc_assert (phi); if (i == vec_num - 1 && j == ncopies - 1) - add_phi_arg (phi, lsq, loop_latch_edge (containing_loop)); + add_phi_arg (phi, lsq, loop_latch_edge (containing_loop), + UNKNOWN_LOCATION); msq = lsq; } } diff --git a/gcc/tree.c b/gcc/tree.c index 44178aff65c..58994b12898 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -7686,21 +7686,10 @@ make_vector_type (tree innertype, int nunits, enum machine_mode mode) tree t; hashval_t hashcode = 0; - /* Build a main variant, based on the main variant of the inner type, then - use it to build the variant we return. */ - if ((TYPE_ATTRIBUTES (innertype) || TYPE_QUALS (innertype)) - && TYPE_MAIN_VARIANT (innertype) != innertype) - return build_type_attribute_qual_variant ( - make_vector_type (TYPE_MAIN_VARIANT (innertype), nunits, mode), - TYPE_ATTRIBUTES (innertype), - TYPE_QUALS (innertype)); - t = make_node (VECTOR_TYPE); TREE_TYPE (t) = TYPE_MAIN_VARIANT (innertype); SET_TYPE_VECTOR_SUBPARTS (t, nunits); SET_TYPE_MODE (t, mode); - TYPE_READONLY (t) = TYPE_READONLY (innertype); - TYPE_VOLATILE (t) = TYPE_VOLATILE (innertype); if (TYPE_STRUCTURAL_EQUALITY_P (innertype)) SET_TYPE_STRUCTURAL_EQUALITY (t); @@ -7730,9 +7719,20 @@ make_vector_type (tree innertype, int nunits, enum machine_mode mode) } hashcode = iterative_hash_host_wide_int (VECTOR_TYPE, hashcode); + hashcode = iterative_hash_host_wide_int (nunits, hashcode); hashcode = iterative_hash_host_wide_int (mode, hashcode); - hashcode = iterative_hash_object (TYPE_HASH (innertype), hashcode); - return type_hash_canon (hashcode, t); + hashcode = iterative_hash_object (TYPE_HASH (TREE_TYPE (t)), hashcode); + t = type_hash_canon (hashcode, t); + + /* We have built a main variant, based on the main variant of the + inner type. Use it to build the variant we return. */ + if ((TYPE_ATTRIBUTES (innertype) || TYPE_QUALS (innertype)) + && TREE_TYPE (t) != innertype) + return build_type_attribute_qual_variant (t, + TYPE_ATTRIBUTES (innertype), + TYPE_QUALS (innertype)); + + return t; } static tree diff --git a/gcc/tree.h b/gcc/tree.h index f4c70df55b8..1a21b751b01 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1888,6 +1888,7 @@ struct GTY(()) phi_arg_d { pointer arithmetic with it. See phi_arg_index_from_use. */ struct ssa_use_operand_d imm_use; tree def; + location_t locus; }; diff --git a/gnattools/ChangeLog b/gnattools/ChangeLog index d8cbe086f4a..ff395ea7783 100644 --- a/gnattools/ChangeLog +++ b/gnattools/ChangeLog @@ -1,3 +1,8 @@ +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * Makefile.in (AUTOCONF, configure_deps): New variables. + ($(srcdir)/configure): Use them. + 2009-05-18 Bechir Zalila <bechir.zalila@gmail.com> PR ada/40166 diff --git a/gnattools/Makefile.in b/gnattools/Makefile.in index 92f4773b3d8..93198967857 100644 --- a/gnattools/Makefile.in +++ b/gnattools/Makefile.in @@ -305,9 +305,14 @@ Makefile: $(srcdir)/Makefile.in config.status config.status: $(srcdir)/configure $(SHELL) ./config.status --recheck -$(srcdir)/configure: @MAINT@ $(srcdir)/configure.ac \ - $(srcdir)/../config/acx.m4 $(srcdir)/../config/override.m4 - cd $(srcdir) && autoconf +AUTOCONF = autoconf +configure_deps = \ + $(srcdir)/configure.ac \ + $(srcdir)/../config/acx.m4 \ + $(srcdir)/../config/override.m4 + +$(srcdir)/configure: @MAINT@ $(configure_deps) + cd $(srcdir) && $(AUTOCONF) # Don't export variables to the environment, in order to not confuse # configure. diff --git a/intl/ChangeLog b/intl/ChangeLog index 74018fb44c0..fda6cc38cd4 100644 --- a/intl/ChangeLog +++ b/intl/ChangeLog @@ -1,3 +1,8 @@ +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * Makefile.in (aclocal_deps): New variable. + ($(srcdir)/aclocal.m4): Use it, for portable makefile syntax. + 2008-06-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> * configure: Regenerate. diff --git a/intl/Makefile.in b/intl/Makefile.in index 96211ffd147..3dd0b7fe8fd 100644 --- a/intl/Makefile.in +++ b/intl/Makefile.in @@ -211,16 +211,28 @@ config.status: $(srcdir)/configure $(srcdir)/configure: @MAINT@ $(srcdir)/aclocal.m4 $(srcdir)/configure.ac cd $(srcdir) && $(AUTOCONF) -$(srcdir)/aclocal.m4: @MAINT@ $(srcdir)/configure.ac \ - $(srcdir)/../config/codeset.m4 $(srcdir)/../config/gettext.m4 \ - $(srcdir)/../config/glibc21.m4 $(srcdir)/../config/iconv.m4 \ - $(srcdir)/../config/intdiv0.m4 $(srcdir)/../config/inttypes-pri.m4 \ - $(srcdir)/../config/inttypes.m4 $(srcdir)/../config/inttypes_h.m4 \ - $(srcdir)/../config/lcmessage.m4 $(srcdir)/../config/lib-ld.m4 \ - $(srcdir)/../config/lib-link.m4 $(srcdir)/../config/lib-prefix.m4 \ - $(srcdir)/../config/nls.m4 $(srcdir)/../config/po.m4 \ - $(srcdir)/../config/progtest.m4 $(srcdir)/../config/stdint_h.m4 \ - $(srcdir)/../config/uintmax_t.m4 $(srcdir)/../config/ulonglong.m4 +aclocal_deps = \ + $(srcdir)/configure.ac \ + $(srcdir)/../config/codeset.m4 \ + $(srcdir)/../config/gettext.m4 \ + $(srcdir)/../config/glibc21.m4 \ + $(srcdir)/../config/iconv.m4 \ + $(srcdir)/../config/intdiv0.m4 \ + $(srcdir)/../config/inttypes-pri.m4 \ + $(srcdir)/../config/inttypes.m4 \ + $(srcdir)/../config/inttypes_h.m4 \ + $(srcdir)/../config/lcmessage.m4 \ + $(srcdir)/../config/lib-ld.m4 \ + $(srcdir)/../config/lib-link.m4 \ + $(srcdir)/../config/lib-prefix.m4 \ + $(srcdir)/../config/nls.m4 \ + $(srcdir)/../config/po.m4 \ + $(srcdir)/../config/progtest.m4 \ + $(srcdir)/../config/stdint_h.m4 \ + $(srcdir)/../config/uintmax_t.m4 \ + $(srcdir)/../config/ulonglong.m4 + +$(srcdir)/aclocal.m4: @MAINT@ $(aclocal_deps) cd $(srcdir) && $(ACLOCAL) -I ../config config.h: stamp-h1 diff --git a/libada/ChangeLog b/libada/ChangeLog index fc48aa148dd..0eddf991d72 100644 --- a/libada/ChangeLog +++ b/libada/ChangeLog @@ -1,3 +1,12 @@ +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * Makefile.in (AUTOCONF, configure_deps): New variables. + ($(srcdir)/configure)): Use them. Also depend on multi.m4. + +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force. + 2009-07-13 Eric Botcazou <ebotcazou@adacore.com> * configure.ac: Include multi.m4 and do not call AC_CANONICAL_SYSTEM. diff --git a/libada/Makefile.in b/libada/Makefile.in index f5057a006e7..db483b50033 100644 --- a/libada/Makefile.in +++ b/libada/Makefile.in @@ -171,9 +171,15 @@ Makefile: $(srcdir)/Makefile.in config.status config.status: $(srcdir)/configure $(SHELL) ./config.status --recheck -$(srcdir)/configure: @MAINT@ $(srcdir)/configure.ac \ - $(srcdir)/../config/acx.m4 $(srcdir)/../config/override.m4 - cd $(srcdir) && autoconf +AUTOCONF = autoconf +configure_deps = \ + $(srcdir)/configure.ac \ + $(srcdir)/../config/acx.m4 \ + $(srcdir)/../config/override.m4 \ + $(srcdir)/../config/multi.m4 + +$(srcdir)/configure: @MAINT@ $(configure_deps) + cd $(srcdir) && $(AUTOCONF) # Don't export variables to the environment, in order to not confuse # configure. diff --git a/libada/configure.ac b/libada/configure.ac index 12de5479e00..ef9e6132c43 100644 --- a/libada/configure.ac +++ b/libada/configure.ac @@ -92,7 +92,7 @@ AC_SUBST(toolexeclibdir) m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) m4_define([_AC_ARG_VAR_PRECIOUS],[]) AC_PROG_CC -m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) +m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) AC_SUBST(CFLAGS) diff --git a/libcpp/po/ChangeLog b/libcpp/po/ChangeLog index 94503a7c4eb..ba4d1e6a1cb 100644 --- a/libcpp/po/ChangeLog +++ b/libcpp/po/ChangeLog @@ -1,3 +1,7 @@ +2009-08-04 Joseph Myers <joseph@codesourcery.com> + + * es.po: Update. + 2009-07-25 Joseph Myers <joseph@codesourcery.com> * nl.po: Update. diff --git a/libcpp/po/es.po b/libcpp/po/es.po index a43c1d3cc47..1ae12e2f7f3 100644 --- a/libcpp/po/es.po +++ b/libcpp/po/es.po @@ -1,14 +1,14 @@ -# Mensajes en español para cpplib-4.4-b20081121 +# Mensajes en español para cpplib-4.4.1 # Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is distributed under the same license as the gcc package. # Cristian Othón Martínez Vera <cfuga@itam.mx>, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009. # msgid "" msgstr "" -"Project-Id-Version: cpplib 4.4-b20081121\n" +"Project-Id-Version: cpplib 4.4.1\n" "Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n" "POT-Creation-Date: 2009-04-22 16:32+0000\n" -"PO-Revision-Date: 2009-03-03 23:45-0600\n" +"PO-Revision-Date: 2009-08-02 21:44-0500\n" "Last-Translator: Cristian Othón Martínez Vera <cfuga@itam.mx>\n" "Language-Team: Spanish <es@li.org>\n" "MIME-Version: 1.0\n" @@ -900,9 +900,9 @@ msgid "while writing precompiled header" msgstr "al escribir el encabezado precompilado" #: pch.c:484 -#, fuzzy, c-format +#, c-format msgid "%s: not used because `%.*s' is poisoned" -msgstr "%s: no se usa porque `%s' está definido" +msgstr "%s: no se usa porque `%.*s' está envenenado" #: pch.c:506 #, c-format diff --git a/libdecnumber/ChangeLog b/libdecnumber/ChangeLog index 74fba5990d6..8cdf161b1d4 100644 --- a/libdecnumber/ChangeLog +++ b/libdecnumber/ChangeLog @@ -1,3 +1,8 @@ +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * Makefile.in (aclocal_deps): New variable. + ($(srcdir)/aclocal.m4): Use it, for portable makefile syntax. + 2009-05-31 Ian Lance Taylor <iant@google.com> * decContext.h: Add extern "C" if compiling with C++. diff --git a/libdecnumber/Makefile.in b/libdecnumber/Makefile.in index 41607959c91..de91f6f614b 100644 --- a/libdecnumber/Makefile.in +++ b/libdecnumber/Makefile.in @@ -94,9 +94,13 @@ config.status: $(srcdir)/configure $(srcdir)/configure: @MAINT@ $(srcdir)/aclocal.m4 cd $(srcdir) && $(AUTOCONF) -$(srcdir)/aclocal.m4: @MAINT@ $(srcdir)/../config/stdint.m4 \ - $(srcdir)/../config/warnings.m4 $(srcdir)/../config/override.m4 \ +aclocal_deps = \ + $(srcdir)/../config/stdint.m4 \ + $(srcdir)/../config/warnings.m4 \ + $(srcdir)/../config/override.m4 \ $(srcdir)/configure.ac + +$(srcdir)/aclocal.m4: @MAINT@ $(aclocal_deps) cd $(srcdir) && $(ACLOCAL) -I ../config config.h: stamp-h1 diff --git a/libffi/ChangeLog b/libffi/ChangeLog index 9af1e445e72..2fc3b1a7487 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,7 @@ +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force. + 2009-07-24 Dave Korn <dave.korn.cygwin@gmail.com> PR libffi/40807 diff --git a/libffi/configure.ac b/libffi/configure.ac index 2ab5902746e..ab693bb5c36 100644 --- a/libffi/configure.ac +++ b/libffi/configure.ac @@ -22,7 +22,7 @@ AM_INIT_AUTOMAKE m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) m4_define([_AC_ARG_VAR_PRECIOUS],[]) AC_PROG_CC -m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) +m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) AC_SUBST(CFLAGS) diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 01c35fc5366..9c2f7aefb81 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,11 @@ +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * configure.ac: Add snippet for maintainer-mode. + * configure: Regenerate. + * Makefile.in (AUTOCONF, configure_deps): New variables. + ($(srcdir)/configure)): New rule, active only with maintainer + mode turned on. + 2009-06-23 DJ Delorie <dj@redhat.com> Add MeP port. diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in index 53dde12b47d..9484e7e6c0e 100644 --- a/libgcc/Makefile.in +++ b/libgcc/Makefile.in @@ -140,6 +140,17 @@ stamp-h: $(srcdir)/config.in config.status Makefile config.status: $(srcdir)/configure $(srcdir)/config.host $(SHELL) ./config.status --recheck +AUTOCONF = autoconf +configure_deps = \ + $(srcdir)/../config/enable.m4 \ + $(srcdir)/../config/tls.m4 \ + $(srcdir)/../config/acx.m4 \ + $(srcdir)/../config/no-executables.m4 \ + $(srcdir)/../config/override.m4 \ + +$(srcdir)/configure: @MAINT@ $(srcdir)/configure.ac $(configure_deps) + cd $(srcdir) && $(AUTOCONF) + include $(gcc_objdir)/libgcc.mvars # Flags to pass to recursive makes. diff --git a/libgcc/configure b/libgcc/configure index 6315ecd5cbc..0230e799fce 100644 --- a/libgcc/configure +++ b/libgcc/configure @@ -272,7 +272,7 @@ PACKAGE_STRING='GNU C Runtime Library 1.0' PACKAGE_BUGREPORT='' ac_unique_file="static-object.mk" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libgcc_topdir enable_shared slibdir INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK build build_cpu build_vendor build_os host host_cpu host_vendor host_os host_noncanonical build_libsubdir build_subdir host_subdir target_subdir AR ac_ct_AR LIPO ac_ct_LIPO NM ac_ct_NM RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP decimal_float enable_decimal_float fixed_point vis_hide set_have_cc_tls tmake_file extra_parts asm_hidden_op LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libgcc_topdir enable_shared slibdir MAINT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK build build_cpu build_vendor build_os host host_cpu host_vendor host_os host_noncanonical build_libsubdir build_subdir host_subdir target_subdir AR ac_ct_AR LIPO ac_ct_LIPO NM ac_ct_NM RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP decimal_float enable_decimal_float fixed_point vis_hide set_have_cc_tls tmake_file extra_parts asm_hidden_op LIBOBJS LTLIBOBJS' ac_subst_files='' ac_pwd=`pwd` @@ -812,6 +812,9 @@ Optional Features: --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-shared don't provide a shared libgcc --enable-version-specific-runtime-libs Specify that runtime libraries should be installed in a compiler-specific directory + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer --enable-decimal-float={no,yes,bid,dpd} enable decimal float extension to C. Selecting 'bid' or 'dpd' choses which decimal floating point format @@ -1419,6 +1422,23 @@ fi fi; +# Command-line options. +# Very limited version of AC_MAINTAINER_MODE. +# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + case ${enable_maintainer_mode} in + yes) MAINT='' ;; + no) MAINT='#' ;; + *) { { echo "$as_me:$LINENO: error: --enable-maintainer-mode must be yes or no" >&5 +echo "$as_me: error: --enable-maintainer-mode must be yes or no" >&2;} + { (exit 1); exit 1; }; } ;; + esac + maintainer_mode=${enableval} +else + MAINT='#' +fi; + # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: @@ -4226,6 +4246,7 @@ s,@LIBS@,$LIBS,;t t s,@libgcc_topdir@,$libgcc_topdir,;t t s,@enable_shared@,$enable_shared,;t t s,@slibdir@,$slibdir,;t t +s,@MAINT@,$MAINT,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t diff --git a/libgcc/configure.ac b/libgcc/configure.ac index d48bccce065..b055dbaca13 100644 --- a/libgcc/configure.ac +++ b/libgcc/configure.ac @@ -78,6 +78,21 @@ else fi) AC_SUBST(slibdir) +# Command-line options. +# Very limited version of AC_MAINTAINER_MODE. +AC_ARG_ENABLE([maintainer-mode], + [AC_HELP_STRING([--enable-maintainer-mode], + [enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer])], + [case ${enable_maintainer_mode} in + yes) MAINT='' ;; + no) MAINT='#' ;; + *) AC_MSG_ERROR([--enable-maintainer-mode must be yes or no]) ;; + esac + maintainer_mode=${enableval}], + [MAINT='#']) +AC_SUBST([MAINT])dnl + AC_PROG_INSTALL AC_PROG_AWK diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index aec14276fbe..846bdfb1738 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,27 @@ +2009-08-02 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + PR libfortran/40853 + * io/list_read.c (nml_get_obj_data): Do not set nl + pointer to first_nl if nl->next is NULL. + +2009-07-31 Kaz Kojima <kkojima@gcc.gnu.org> + + * Makefile.am: Don't set SECTION_FLAGS with @SECTION_FLAGS@. + Don't set IEEE_FLAGS with @IEEE_FLAGS@. + * Makefile.in: Regenerate. + +2009-07-30 Kaz Kojima <kkojima@gcc.gnu.org> + + * configure.host: Define ieee_flags and set it to -mieee for sh. + * configure.ac: Set IEEE_FLAGS with ieee_flags. + * Makefile.am: Add IEEE_FLAGS to AM_CFLAGS. + * configure: Regenerate. + * Makefile.in: Regenerate. + +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force. + 2009-07-27 Tobias Burnus <burnus@net-b.de> PR fortran/40863 diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am index 4a974ba0066..aaecdb4f11a 100644 --- a/libgfortran/Makefile.am +++ b/libgfortran/Makefile.am @@ -34,9 +34,11 @@ AM_CPPFLAGS = -iquote$(srcdir)/io -I$(srcdir)/$(MULTISRCTOP)../gcc \ AM_CFLAGS += -fcx-fortran-rules # Use -ffunction-sections -fdata-sections if supported by the compiler -SECTION_FLAGS = @SECTION_FLAGS@ AM_CFLAGS += $(SECTION_FLAGS) +# Some targets require additional compiler options for IEEE compatibility. +AM_CFLAGS += $(IEEE_FLAGS) + gfor_io_src= \ io/close.c \ io/file_pos.c \ diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in index 7741c324aaf..7ea32c6608b 100644 --- a/libgfortran/Makefile.in +++ b/libgfortran/Makefile.in @@ -815,7 +815,12 @@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ # Fortran rules for complex multiplication and division -AM_CFLAGS = @AM_CFLAGS@ -fcx-fortran-rules $(SECTION_FLAGS) + +# Use -ffunction-sections -fdata-sections if supported by the compiler + +# Some targets require additional compiler options for IEEE compatibility. +AM_CFLAGS = @AM_CFLAGS@ -fcx-fortran-rules $(SECTION_FLAGS) \ + $(IEEE_FLAGS) AM_FCFLAGS = @AM_FCFLAGS@ AR = @AR@ AS = @AS@ @@ -843,6 +848,7 @@ FCFLAGS = @FCFLAGS@ FGREP = @FGREP@ FPU_HOST_HEADER = @FPU_HOST_HEADER@ GREP = @GREP@ +IEEE_FLAGS = @IEEE_FLAGS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ @@ -875,8 +881,6 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ - -# Use -ffunction-sections -fdata-sections if supported by the compiler SECTION_FLAGS = @SECTION_FLAGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ diff --git a/libgfortran/configure b/libgfortran/configure index 043884bad5a..9091071e011 100755 --- a/libgfortran/configure +++ b/libgfortran/configure @@ -457,7 +457,7 @@ ac_includes_default="\ # include <unistd.h> #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os build_libsubdir build_subdir host_subdir target_subdir onestep_TRUE onestep_FALSE onestep host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT multi_basedir toolexecdir toolexeclibdir CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE AM_FCFLAGS AM_CFLAGS CFLAGS LIBGFOR_USE_SYMVER_TRUE LIBGFOR_USE_SYMVER_FALSE SECTION_FLAGS AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB LIBTOOL SED EGREP FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S OBJDUMP ac_ct_OBJDUMP lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 CPP CPPFLAGS enable_shared enable_static FC FCFLAGS LDFLAGS ac_ct_FC extra_ldflags_libgfortran FPU_HOST_HEADER LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os build_libsubdir build_subdir host_subdir target_subdir onestep_TRUE onestep_FALSE onestep host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT multi_basedir toolexecdir toolexeclibdir CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE AM_FCFLAGS AM_CFLAGS CFLAGS LIBGFOR_USE_SYMVER_TRUE LIBGFOR_USE_SYMVER_FALSE SECTION_FLAGS AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB LIBTOOL SED EGREP FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S OBJDUMP ac_ct_OBJDUMP lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 CPP CPPFLAGS enable_shared enable_static FC FCFLAGS LDFLAGS ac_ct_FC extra_ldflags_libgfortran FPU_HOST_HEADER IEEE_FLAGS LIBOBJS LTLIBOBJS' ac_subst_files='' ac_pwd=`pwd` @@ -33816,6 +33816,10 @@ echo "$as_me: FPU dependent file will be ${fpu_host}.h" >&6;} FPU_HOST_HEADER=config/${fpu_host}.h +# Some targets require additional compiler options for IEEE compatibility. +IEEE_FLAGS="${ieee_flags}" + + # Check out attribute support. echo "$as_me:$LINENO: checking whether the target supports hidden visibility" >&5 @@ -35568,6 +35572,7 @@ s,@LDFLAGS@,$LDFLAGS,;t t s,@ac_ct_FC@,$ac_ct_FC,;t t s,@extra_ldflags_libgfortran@,$extra_ldflags_libgfortran,;t t s,@FPU_HOST_HEADER@,$FPU_HOST_HEADER,;t t +s,@IEEE_FLAGS@,$IEEE_FLAGS,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac index b1e5d1e2c35..2d0dff0c68c 100644 --- a/libgfortran/configure.ac +++ b/libgfortran/configure.ac @@ -119,7 +119,7 @@ AC_SUBST(toolexeclibdir) m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) m4_define([_AC_ARG_VAR_PRECIOUS],[]) AC_PROG_CC -m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) +m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) # Add -Wall -fno-repack-arrays -fno-underscoring if we are using GCC. if test "x$GCC" = "xyes"; then @@ -448,6 +448,10 @@ AC_MSG_NOTICE([FPU dependent file will be ${fpu_host}.h]) FPU_HOST_HEADER=config/${fpu_host}.h AC_SUBST(FPU_HOST_HEADER) +# Some targets require additional compiler options for IEEE compatibility. +IEEE_FLAGS="${ieee_flags}" +AC_SUBST(IEEE_FLAGS) + # Check out attribute support. LIBGFOR_CHECK_ATTRIBUTE_VISIBILITY LIBGFOR_CHECK_ATTRIBUTE_DLLEXPORT diff --git a/libgfortran/configure.host b/libgfortran/configure.host index 73da57172d6..eb68c934c39 100644 --- a/libgfortran/configure.host +++ b/libgfortran/configure.host @@ -38,3 +38,10 @@ fi if test "x${have_fp_enable}" = "xyes" && test "x${have_fp_trap}" = "xyes"; then fpu_host='fpu-aix' fi + +# Some targets require additional compiler options for NaN/Inf. +ieee_flags= +case "${host_cpu}" in + sh*) + ieee_flags="-mieee" ;; +esac diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index c39a51d34e2..bcc00e17c26 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -2773,7 +2773,7 @@ get_name: if (nl->type == GFC_DTYPE_DERIVED) nml_touch_nodes (nl); - if (component_flag && nl->var_rank > 0) + if (component_flag && nl->var_rank > 0 && nl->next) nl = first_nl; /* Make sure no extraneous qualifiers are there. */ diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 5ef1785e213..6b9592bda73 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,13 @@ +2009-08-04 David Daney <ddaney@caviumnetworks.com> + + * config/linux/mutex.h (gomp_mutex_unlock): Add comment about + needed memory barrier semantics. + * config/linux/mips/mutex.h: New file. + +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force. + 2009-07-16 Joseph Myers <joseph@codesourcery.com> * configure: Regenerate. diff --git a/libgomp/config/linux/mips/mutex.h b/libgomp/config/linux/mips/mutex.h new file mode 100644 index 00000000000..668cc11b29a --- /dev/null +++ b/libgomp/config/linux/mips/mutex.h @@ -0,0 +1,27 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* MIPS needs the same correct usage of __sync_synchronize and + __sync_lock_test_and_set as ia64. So we just use its mutex.h. */ + +#include "config/linux/ia64/mutex.h" diff --git a/libgomp/config/linux/mutex.h b/libgomp/config/linux/mutex.h index 07a2156a462..1905ce012fd 100644 --- a/libgomp/config/linux/mutex.h +++ b/libgomp/config/linux/mutex.h @@ -48,6 +48,16 @@ static inline void gomp_mutex_lock (gomp_mutex_t *mutex) extern void gomp_mutex_unlock_slow (gomp_mutex_t *mutex); static inline void gomp_mutex_unlock (gomp_mutex_t *mutex) { + /* Warning: By definition __sync_lock_test_and_set() does not have + proper memory barrier semantics for a mutex unlock operation. + However, this default implementation is written assuming that it + does, which is true for some targets. + + Targets that require additional memory barriers before + __sync_lock_test_and_set to achieve the release semantics of + mutex unlock, are encouraged to include + "config/linux/ia64/mutex.h" in a target specific mutex.h instead + of using this file. */ int val = __sync_lock_test_and_set (mutex, 0); if (__builtin_expect (val > 1, 0)) gomp_mutex_unlock_slow (mutex); diff --git a/libgomp/configure.ac b/libgomp/configure.ac index db8e2811a30..9a026a20f87 100644 --- a/libgomp/configure.ac +++ b/libgomp/configure.ac @@ -103,7 +103,7 @@ AC_SUBST(toolexeclibdir) m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) m4_define([_AC_ARG_VAR_PRECIOUS],[]) AC_PROG_CC -m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) +m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) AC_SUBST(CFLAGS) diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 16f541ed275..b2f41208bf8 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,8 @@ +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * Makefile.in (AUTOCONF, configure_deps): New variables. + ($(srcdir)/configure): New rule, active only in maintainer mode. + 2009-07-29 Douglas B Rupp <rupp@gnat.com> * make-temp-file.c (choose_tmpdir): Try standard temp logical on VMS. diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in index 20a7210a1a1..e8f4f4d679a 100644 --- a/libiberty/Makefile.in +++ b/libiberty/Makefile.in @@ -459,6 +459,16 @@ stamp-h: $(srcdir)/config.in config.status Makefile config.status: $(srcdir)/configure $(SHELL) ./config.status --recheck +AUTOCONF = autoconf +configure_deps = $(srcdir)/aclocal.m4 \ + $(srcdir)/../config/acx.m4 \ + $(srcdir)/../config/no-executables.m4 \ + $(srcdir)/../config/override.m4 \ + $(srcdir)/../config/warnings.m4 \ + +$(srcdir)/configure: @MAINT@ $(srcdir)/configure.ac $(configure_deps) + cd $(srcdir) && $(AUTOCONF) + # Depending on config.h makes sure that config.status has been re-run # if needed. This prevents problems with parallel builds, in case # subdirectories need to run config.status also. diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 02fc607e328..a4784e51ffb 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,7 @@ +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force. + 2009-07-28 David Daney <ddaney@caviumnetworks.com> * gnu/gcj/util/natGCInfo.cc (nomem_handler): Use oomDumpName as diff --git a/libjava/configure.ac b/libjava/configure.ac index 3074a0c0fd4..1ab5bec75d6 100644 --- a/libjava/configure.ac +++ b/libjava/configure.ac @@ -159,7 +159,7 @@ CXXFLAGS="$CXXFLAGS -fno-builtin" AC_PROG_CC AC_PROG_CXX CXXFLAGS="$save_CXXFLAGS" -m4_rename([glibcxx_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) +m4_rename_force([glibcxx_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) AC_SUBST(CFLAGS) AC_SUBST(CXXFLAGS) AC_SUBST(LDFLAGS) diff --git a/libmudflap/ChangeLog b/libmudflap/ChangeLog index edb0958cd40..2312b20fc42 100644 --- a/libmudflap/ChangeLog +++ b/libmudflap/ChangeLog @@ -1,3 +1,7 @@ +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force. + 2009-07-16 Joseph Myers <joseph@codesourcery.com> * configure: Regenerate. diff --git a/libmudflap/configure.ac b/libmudflap/configure.ac index 8ce99a10270..c7d69d549c3 100644 --- a/libmudflap/configure.ac +++ b/libmudflap/configure.ac @@ -39,7 +39,7 @@ AC_LANG_C m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) m4_define([_AC_ARG_VAR_PRECIOUS],[]) AC_PROG_CC -m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) +m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) AC_SUBST(CFLAGS) diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog index 88f8b8d64af..a4c963a6e5c 100644 --- a/libobjc/ChangeLog +++ b/libobjc/ChangeLog @@ -1,3 +1,13 @@ +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * Makefile.in (AUTOCONF, ACLOCAL, ACLOCAL_AMFLAGS, aclocal_deps): + New variables. + ($(srcdir)/configure, $(srcdir)/aclocal.m4): New rules. + +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force. + 2009-04-09 Nick Clifton <nickc@redhat.com> * sendmsg.c: Change copyright header to refer to version 3 of diff --git a/libobjc/Makefile.in b/libobjc/Makefile.in index 85550035521..98539cfda41 100644 --- a/libobjc/Makefile.in +++ b/libobjc/Makefile.in @@ -333,9 +333,25 @@ config.status: configure CONFIG_SITE=no-such-file CC='$(CC)' AR='$(AR)' CFLAGS='$(CFLAGS)' \ CPPFLAGS='$(CPPFLAGS)' $(SHELL) config.status --recheck -${srcdir}/configure: @MAINT@ configure.ac +AUTOCONF = autoconf +ACLOCAL = aclocal +ACLOCAL_AMFLAGS = -I ../config -I .. +aclocal_deps = \ + $(srcdir)/../config/multi.m4 \ + $(srcdir)/../config/override.m4 \ + $(srcdir)/../config/proginstall.m4 \ + $(srcdir)/../ltoptions.m4 \ + $(srcdir)/../ltsugar.m4 \ + $(srcdir)/../ltversion.m4 \ + $(srcdir)/../lt~obsolete.m4 \ + $(srcdir)/acinclude.m4 + +$(srcdir)/configure: @MAINT@ configure.ac $(srcdir)/aclocal.m4 rm -f config.cache - cd ${srcdir} && autoconf + cd $(srcdir) && $(AUTOCONF) + +$(srcdir)/aclocal.m4: @MAINT@ $(aclocal_deps) + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) install: install-libs install-headers diff --git a/libobjc/aclocal.m4 b/libobjc/aclocal.m4 index 0b3d8b741f7..69611d54e76 100644 --- a/libobjc/aclocal.m4 +++ b/libobjc/aclocal.m4 @@ -154,11 +154,11 @@ if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then fi ]) -m4_include([../config/multi.m4]) -m4_include([../config/override.m4]) -m4_include([../config/proginstall.m4]) m4_include([../ltoptions.m4]) m4_include([../ltsugar.m4]) m4_include([../ltversion.m4]) m4_include([../lt~obsolete.m4]) +m4_include([../config/multi.m4]) +m4_include([../config/override.m4]) +m4_include([../config/proginstall.m4]) m4_include([acinclude.m4]) diff --git a/libobjc/configure.ac b/libobjc/configure.ac index dd7751eb3cc..036e34c9607 100644 --- a/libobjc/configure.ac +++ b/libobjc/configure.ac @@ -153,7 +153,7 @@ GCC_NO_EXECUTABLES m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) m4_define([_AC_ARG_VAR_PRECIOUS],[]) AC_PROG_CC -m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) +m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) # extra LD Flags which are required for targets case "${host}" in diff --git a/libssp/ChangeLog b/libssp/ChangeLog index d8d3c7410c0..89d23ae6bf3 100644 --- a/libssp/ChangeLog +++ b/libssp/ChangeLog @@ -1,3 +1,7 @@ +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force. + 2009-04-13 Ozkan Sezer <sezeroz@gmail.com> PR target/39062 diff --git a/libssp/configure.ac b/libssp/configure.ac index f3a66ec975a..ff6f2de9799 100644 --- a/libssp/configure.ac +++ b/libssp/configure.ac @@ -41,7 +41,7 @@ AC_LANG_C m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) m4_define([_AC_ARG_VAR_PRECIOUS],[]) AC_PROG_CC -m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) +m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) AC_SUBST(CFLAGS) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 6e7b73d90b3..dafe95f6ce4 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,351 @@ +2009-08-04 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/15523 + * include/debug/safe_iterator.h (_Safe_iterator<>:: + _Safe_iterator(const _Safe_iterator&), _Safe_iterator<>:: + operator=(const _Safe_iterator&)): Implement resolution of DR 408, + do not error out when the source is a value-initialized iterator. + * testsuite/23_containers/vector/15523.cc: New. + * doc/xml/manual/intro.xml: Add an entry for DR 408. + +2009-08-03 Paolo Carlini <paolo.carlini@oracle.com> + + * include/std/istream (operator>>(basic_istream<>&&, _Tp&)): Minor + cosmetic changes, inline. + * include/std/ostream (operator<<(basic_ostream<>&&, const _Tp&)): + Likewise. + * include/bits/move.h: Minor cosmetic changes. + +2009-08-02 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/40912 (final) + * testsuite/26_numerics/random/mt19937.cc: dg-require-cstdint. + * testsuite/26_numerics/random/uniform_real_distribution/cons/ + parms_neg.cc: Likewise. + * testsuite/26_numerics/random/uniform_real_distribution/cons/ + parms.cc: Likewise. + * testsuite/26_numerics/random/uniform_real_distribution/cons/ + default.cc: Likewise. + * testsuite/26_numerics/random/uniform_real_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/piecewise_constant_distribution/ + cons/range.cc: Likewise. + * testsuite/26_numerics/random/piecewise_constant_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/piecewise_constant_distribution/ + cons/num_xbound_fun.cc: Likewise. + * testsuite/26_numerics/random/piecewise_constant_distribution/ + cons/initlist_fun.cc: Likewise. + * testsuite/26_numerics/random/piecewise_constant_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/minstd_rand.cc: Likewise. + * testsuite/26_numerics/random/chi_squared_distribution/cons/ + parms.cc: Likewise. + * testsuite/26_numerics/random/chi_squared_distribution/cons/ + default.cc: Likewise. + * testsuite/26_numerics/random/chi_squared_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/normal_distribution/ + cons/parms.cc: Likewise. + * testsuite/26_numerics/random/normal_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/normal_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/seed_seq/cons/ + range.cc: Likewise. + * testsuite/26_numerics/random/seed_seq/cons/ + initlist.cc: Likewise. + * testsuite/26_numerics/random/seed_seq/cons/ + default.cc: Likewise. + * testsuite/26_numerics/random/seed_seq/requirements/ + typedefs.cc: Likewise. + * testsuite/26_numerics/random/uniform_int_distribution/ + cons/parms_neg.cc: Likewise. + * testsuite/26_numerics/random/uniform_int_distribution/ + cons/parms.cc: Likewise. + * testsuite/26_numerics/random/uniform_int_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/uniform_int_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/poisson_distribution/cons/ + parms.cc: Likewise. + * testsuite/26_numerics/random/poisson_distribution/cons/ + default.cc: Likewise. + * testsuite/26_numerics/random/poisson_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/bernoulli_distribution/ + cons/parms.cc: Likewise. + * testsuite/26_numerics/random/bernoulli_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/bernoulli_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/ranlux24_base.cc: Likewise. + * testsuite/26_numerics/random/ + default_random_engine.cc: Likewise. + * testsuite/26_numerics/random/discrete_distribution/ + cons/range.cc: Likewise. + * testsuite/26_numerics/random/discrete_distribution/ + cons/initlist.cc: Likewise. + * testsuite/26_numerics/random/discrete_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/discrete_distribution/ + cons/num_xbound_fun.cc: Likewise. + * testsuite/26_numerics/random/discrete_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/weibull_distribution/ + cons/parms.cc: Likewise. + * testsuite/26_numerics/random/weibull_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/weibull_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/independent_bits_engine/ + cons/base_move.cc: Likewise. + * testsuite/26_numerics/random/independent_bits_engine/ + cons/seed1.cc: Likewise. + * testsuite/26_numerics/random/independent_bits_engine/ + cons/seed2.cc: Likewise. + * testsuite/26_numerics/random/independent_bits_engine/ + cons/base_copy.cc: Likewise. + * testsuite/26_numerics/random/independent_bits_engine/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/independent_bits_engine/ + cons/seed_seq.cc: Likewise. + * testsuite/26_numerics/random/independent_bits_engine/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/independent_bits_engine/ + operators/equal.cc: Likewise. + * testsuite/26_numerics/random/independent_bits_engine/ + operators/serialize.cc: Likewise. + * testsuite/26_numerics/random/ranlux48_base.cc: Likewise. + * testsuite/26_numerics/random/minstd_rand0.cc: Likewise. + * testsuite/26_numerics/random/subtract_with_carry_engine/ + cons/seed1.cc: Likewise. + * testsuite/26_numerics/random/subtract_with_carry_engine/ + cons/seed2.cc: Likewise. + * testsuite/26_numerics/random/subtract_with_carry_engine/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/subtract_with_carry_engine/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/subtract_with_carry_engine/ + operators/equal.cc: Likewise. + * testsuite/26_numerics/random/subtract_with_carry_engine/ + operators/serialize.cc: Likewise. + * testsuite/26_numerics/random/discard_block_engine/cons/ + base_move.cc: Likewise. + * testsuite/26_numerics/random/discard_block_engine/cons/ + seed1.cc: Likewise. + * testsuite/26_numerics/random/discard_block_engine/cons/ + seed2.cc: Likewise. + * testsuite/26_numerics/random/discard_block_engine/cons/ + base_copy.cc: Likewise. + * testsuite/26_numerics/random/discard_block_engine/cons/ + default.cc: Likewise. + * testsuite/26_numerics/random/discard_block_engine/cons/ + seed_seq.cc: Likewise. + * testsuite/26_numerics/random/discard_block_engine/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/discard_block_engine/ + operators/equal.cc: Likewise. + * testsuite/26_numerics/random/discard_block_engine/ + operators/serialize.cc: Likewise. + * testsuite/26_numerics/random/cauchy_distribution/ + cons/parms.cc: Likewise. + * testsuite/26_numerics/random/cauchy_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/cauchy_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/negative_binomial_distribution/ + cons/parms.cc: Likewise. + * testsuite/26_numerics/random/negative_binomial_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/negative_binomial_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/gamma_distribution/ + cons/parms.cc: Likewise. + * testsuite/26_numerics/random/gamma_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/gamma_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/mersenne_twister_engine/ + cons/seed1.cc: Likewise. + * testsuite/26_numerics/random/mersenne_twister_engine/ + cons/seed2.cc: Likewise. + * testsuite/26_numerics/random/mersenne_twister_engine/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/mersenne_twister_engine/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/mersenne_twister_engine/ + operators/equal.cc: Likewise. + * testsuite/26_numerics/random/mersenne_twister_engine/ + operators/serialize.cc: Likewise. + * testsuite/26_numerics/random/fisher_f_distribution/ + cons/parms.cc: Likewise. + * testsuite/26_numerics/random/fisher_f_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/fisher_f_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/exponential_distribution/ + cons/parms.cc: Likewise. + * testsuite/26_numerics/random/exponential_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/exponential_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/binomial_distribution/ + cons/parms.cc: Likewise. + * testsuite/26_numerics/random/binomial_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/binomial_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/lognormal_distribution/ + cons/parms.cc: Likewise. + * testsuite/26_numerics/random/lognormal_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/lognormal_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/mt19937_64.cc: Likewise. + * testsuite/26_numerics/random/random_device/cons/ + token.cc: Likewise. + * testsuite/26_numerics/random/random_device/cons/ + default.cc: Likewise. + * testsuite/26_numerics/random/random_device/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/ranlux24.cc: Likewise. + * testsuite/26_numerics/random/extreme_value_distribution/ + cons/parms.cc: Likewise. + * testsuite/26_numerics/random/extreme_value_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/extreme_value_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/piecewise_linear_distribution/ + cons/range.cc: Likewise. + * testsuite/26_numerics/random/piecewise_linear_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/piecewise_linear_distribution/ + cons/num_xbound_fun.cc: Likewise. + * testsuite/26_numerics/random/piecewise_linear_distribution/ + cons/initlist_fun.cc: Likewise. + * testsuite/26_numerics/random/piecewise_linear_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/student_t_distribution/ + cons/parms.cc: Likewise. + * testsuite/26_numerics/random/student_t_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/student_t_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/linear_congruential_engine/ + cons/seed1.cc: Likewise. + * testsuite/26_numerics/random/linear_congruential_engine/ + cons/seed2.cc: Likewise. + * testsuite/26_numerics/random/linear_congruential_engine/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/linear_congruential_engine/ + requirements/non_uint_neg.cc: Likewise. + * testsuite/26_numerics/random/linear_congruential_engine/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/linear_congruential_engine/ + operators/equal.cc: Likewise. + * testsuite/26_numerics/random/linear_congruential_engine/ + operators/serialize.cc: Likewise. + * testsuite/26_numerics/random/ranlux48.cc: Likewise. + * testsuite/26_numerics/random/shuffle_order_engine/cons/ + base_move.cc: Likewise. + * testsuite/26_numerics/random/shuffle_order_engine/cons/ + seed1.cc: Likewise. + * testsuite/26_numerics/random/shuffle_order_engine/cons/ + seed2.cc: Likewise. + * testsuite/26_numerics/random/shuffle_order_engine/cons/ + base_copy.cc: Likewise. + * testsuite/26_numerics/random/shuffle_order_engine/cons/ + default.cc: Likewise. + * testsuite/26_numerics/random/shuffle_order_engine/cons/ + seed_seq.cc: Likewise. + * testsuite/26_numerics/random/shuffle_order_engine/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/shuffle_order_engine/ + operators/equal.cc: Likewise. + * testsuite/26_numerics/random/shuffle_order_engine/ + operators/serialize.cc: Likewise. + * testsuite/26_numerics/random/geometric_distribution/ + cons/parms.cc: Likewise. + * testsuite/26_numerics/random/geometric_distribution/ + cons/default.cc: Likewise. + * testsuite/26_numerics/random/geometric_distribution/ + requirements/typedefs.cc: Likewise. + * testsuite/26_numerics/random/knuth_b.cc: Likewise. + +2009-07-31 Jason Merrill <jason@redhat.com> + Douglas Gregor <doug.gregor@gmail.com> + + * include/bits/move.h (forward): Implement as in N2835. + (move): Implement as in N2831. + * include/std/istream (rvalue stream operator>>): New. + * include/std/ostream (rvalue stream operator<<): New. + * testsuite/27_io/rvalue_streams.cc: New. + +2009-07-31 Jason Merrill <jason@redhat.com> + + * include/bits/forward_list.h (splice_after): Use forward. + (merge): Likewise. + * include/bits/stl_iterator.h (move_iterator::operator*): Use move. + (move_iterator::operator[]): Use move. + * include/bits/stl_list.h (insert): Use move. + * include/std/thread (_Callable constructor): Use forward. + * include/std/tuple: Don't specify explicit template args to move. + + * testsuite/20_util/forward/requirements/explicit_instantiation.cc: + Adjust signature. + * testsuite/20_util/tuple/swap.cc: Swap takes lvalue reference. + * testsuite/30_threads/shared_future/cons/copy.cc: Return rvalue + reference. + * testsuite/20_util/shared_ptr/assign/auto_ptr.cc, + testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc, + testsuite/20_util/shared_ptr/cons/auto_ptr.cc, + testsuite/20_util/shared_ptr/cons/auto_ptr_neg.cc, + testsuite/23_containers/forward_list/ext_pointer/operations/1.cc, + testsuite/23_containers/forward_list/ext_pointer/operations/5.cc, + testsuite/23_containers/forward_list/operations/1.cc, + testsuite/23_containers/forward_list/operations/5.cc: Use move. + * testsuite/23_containers/list/requirements/dr438/assign_neg.cc, + testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc, + testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc, + testsuite/23_containers/list/requirements/dr438/insert_neg.cc, + testsuite/30_threads/thread/cons/assign_neg.cc: Adjust line numbers. + +2009-07-31 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/40912 (partial) + * include/std/random: Disable the facility if <stdint.h> is not + available. + +2009-07-30 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> + + PR libstdc++/40919 + * testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc: + xfail on darwin[3-9]*. + +2009-07-30 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/40917 + * testsuite/util/replacement_memory_operators.h: Add missing includes, + tweak qualifications. + +2009-07-30 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/40916 + * testsuite/23_containers/list/modifiers/swap/1.cc: Fix include order. + * testsuite/23_containers/list/modifiers/swap/2.cc: Likewise. + * testsuite/23_containers/list/modifiers/swap/2.cc: Likewise. + +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * acinclude.m4 (GLIBCXX_CONFIGURE): Use m4_rename_force. + +2009-07-30 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/40915 + * testsuite/18_support/headers/exception/synopsis.cc: Fix + std::terminate declaration. + 2009-07-29 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/40908 diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index d7895f5ec7f..b0b6241de5f 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -104,7 +104,7 @@ AC_DEFUN([GLIBCXX_CONFIGURE], [ AC_PROG_CC AC_PROG_CXX CXXFLAGS="$save_CXXFLAGS" - m4_rename([glibcxx_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) + m4_rename_force([glibcxx_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) AC_SUBST(CFLAGS) AC_SUBST(CXXFLAGS) diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml index 560a0b54e9c..2bf4dea28bf 100644 --- a/libstdc++-v3/doc/xml/manual/intro.xml +++ b/libstdc++-v3/doc/xml/manual/intro.xml @@ -604,6 +604,14 @@ requirements of the license of GCC. <listitem><para>Replace "new" with "::new". </para></listitem></varlistentry> + <varlistentry><term><ulink url="../ext/lwg-active.html#408">408</ulink>: + <emphasis> + Is vector<reverse_iterator<char*> > forbidden? + </emphasis> + </term> + <listitem><para>Tweak the debug-mode checks in _Safe_iterator. + </para></listitem></varlistentry> + <varlistentry><term><ulink url="../ext/lwg-defects.html#409">409</ulink>: <emphasis>Closing an fstream should clear the error state</emphasis> </term> diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index 724d87b01b1..5158f2dac64 100644 --- a/libstdc++-v3/include/bits/forward_list.h +++ b/libstdc++-v3/include/bits/forward_list.h @@ -1057,7 +1057,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std) void splice_after(const_iterator __pos, forward_list&& __list, const_iterator __it) - { this->splice_after(__pos, __list, __it, __it._M_next()); } + { + this->splice_after(__pos, std::forward<forward_list>(__list), + __it, __it._M_next()); + } /** * @brief Insert range from another %forward_list. @@ -1146,7 +1149,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) */ void merge(forward_list&& __list) - { this->merge(__list, std::less<_Tp>()); } + { this->merge(std::forward<forward_list>(__list), std::less<_Tp>()); } /** * @brief Merge sorted lists according to comparison function. diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h index 25773e13c48..e52dec81bc7 100644 --- a/libstdc++-v3/include/bits/move.h +++ b/libstdc++-v3/include/bits/move.h @@ -46,12 +46,30 @@ _GLIBCXX_BEGIN_NAMESPACE(std) typedef _Tp type; }; - /// forward + /// forward (as per N2835) + /// Forward lvalues as rvalues. template<typename _Tp> - inline _Tp&& + inline typename enable_if<!is_lvalue_reference<_Tp>::value, _Tp&&>::type + forward(typename std::identity<_Tp>::type& __t) + { return static_cast<_Tp&&>(__t); } + + /// Forward rvalues as rvalues. + template<typename _Tp> + inline typename enable_if<!is_lvalue_reference<_Tp>::value, _Tp&&>::type forward(typename std::identity<_Tp>::type&& __t) + { return static_cast<_Tp&&>(__t); } + + // Forward lvalues as lvalues. + template<typename _Tp> + inline typename enable_if<is_lvalue_reference<_Tp>::value, _Tp>::type + forward(typename std::identity<_Tp>::type __t) { return __t; } + // Prevent forwarding rvalues as const lvalues. + template<typename _Tp> + inline typename enable_if<is_lvalue_reference<_Tp>::value, _Tp>::type + forward(typename std::remove_reference<_Tp>::type&& __t) = delete; + /** * @brief Move a value. * @ingroup mutating_algorithms @@ -61,7 +79,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) template<typename _Tp> inline typename std::remove_reference<_Tp>::type&& move(_Tp&& __t) - { return __t; } + { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); } _GLIBCXX_END_NAMESPACE diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 129552f3705..eb7290053ed 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -913,7 +913,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) reference operator*() const - { return *_M_current; } + { return std::move(*_M_current); } pointer operator->() const @@ -973,7 +973,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) reference operator[](difference_type __n) const - { return _M_current[__n]; } + { return std::move(_M_current[__n]); } }; template<typename _IteratorL, typename _IteratorR> diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index f758baed5c9..2a6e58f798f 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -1027,7 +1027,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) insert(iterator __position, size_type __n, const value_type& __x) { list __tmp(__n, __x, _M_get_Node_allocator()); - splice(__position, __tmp); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + splice(__position, std::move(__tmp)); +#else + splice(__position, __tmp); +#endif } /** @@ -1049,7 +1053,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) _InputIterator __last) { list __tmp(__first, __last, _M_get_Node_allocator()); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + splice(__position, std::move(__tmp)); +#else splice(__position, __tmp); +#endif } /** diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index dbdb32e2299..eb0a3e4ae15 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -115,12 +115,14 @@ namespace __gnu_debug /** * @brief Copy construction. - * @pre @p x is not singular */ _Safe_iterator(const _Safe_iterator& __x) : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current) { - _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 408. Is vector<reverse_iterator<char*> > forbidden? + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() + || __x._M_current == _Iterator(), _M_message(__msg_init_copy_singular) ._M_iterator(*this, "this") ._M_iterator(__x, "other")); @@ -129,8 +131,6 @@ namespace __gnu_debug /** * @brief Converting constructor from a mutable iterator to a * constant iterator. - * - * @pre @p x is not singular */ template<typename _MutableIterator> _Safe_iterator( @@ -140,7 +140,10 @@ namespace __gnu_debug _Sequence>::__type>& __x) : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base()) { - _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 408. Is vector<reverse_iterator<char*> > forbidden? + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() + || __x.base() == _Iterator(), _M_message(__msg_init_const_singular) ._M_iterator(*this, "this") ._M_iterator(__x, "other")); @@ -148,12 +151,14 @@ namespace __gnu_debug /** * @brief Copy assignment. - * @pre @p x is not singular */ _Safe_iterator& operator=(const _Safe_iterator& __x) { - _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 408. Is vector<reverse_iterator<char*> > forbidden? + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() + || __x._M_current == _Iterator(), _M_message(__msg_copy_singular) ._M_iterator(*this, "this") ._M_iterator(__x, "other")); @@ -169,7 +174,6 @@ namespace __gnu_debug reference operator*() const { - _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), _M_message(__msg_bad_deref) ._M_iterator(*this, "this")); diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream index 1979a51327f..2d47b0fd842 100644 --- a/libstdc++-v3/include/std/istream +++ b/libstdc++-v3/include/std/istream @@ -827,6 +827,24 @@ _GLIBCXX_BEGIN_NAMESPACE(std) basic_istream<_CharT, _Traits>& ws(basic_istream<_CharT, _Traits>& __is); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + // [27.7.1.6] Rvalue stream extraction + /** + * @brief Generic extractor for rvalue stream + * @param is An input stream. + * @param x A reference to the extraction target. + * @return is + * + * This is just a forwarding function to allow extraction from + * rvalue streams since they won't bind to the extractor functions + * that take an lvalue reference. + */ + template<typename _CharT, typename _Traits, typename _Tp> + inline basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp& __x) + { return (__is >> __x); } +#endif // __GXX_EXPERIMENTAL_CXX0X__ + _GLIBCXX_END_NAMESPACE #ifndef _GLIBCXX_EXPORT_TEMPLATE diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream index b9ea4a8ce19..9fc693cb3c3 100644 --- a/libstdc++-v3/include/std/ostream +++ b/libstdc++-v3/include/std/ostream @@ -562,6 +562,24 @@ _GLIBCXX_BEGIN_NAMESPACE(std) flush(basic_ostream<_CharT, _Traits>& __os) { return __os.flush(); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + // [27.7.2.9] Rvalue stream insertion + /** + * @brief Generic inserter for rvalue stream + * @param os An input stream. + * @param x A reference to the object being inserted. + * @return os + * + * This is just a forwarding function to allow insertion to + * rvalue streams since they won't bind to the inserter functions + * that take an lvalue reference. + */ + template<typename _CharT, typename _Traits, typename _Tp> + inline basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x) + { return (__os << __x); } +#endif // __GXX_EXPERIMENTAL_CXX0X__ + _GLIBCXX_END_NAMESPACE #ifndef _GLIBCXX_EXPORT_TEMPLATE diff --git a/libstdc++-v3/include/std/random b/libstdc++-v3/include/std/random index 12668583498..b57ef4925d6 100644 --- a/libstdc++-v3/include/std/random +++ b/libstdc++-v3/include/std/random @@ -47,12 +47,18 @@ #include <debug/debug.h> #include <type_traits> +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + +#include <cstdint> // For uint_fast32_t, uint_fast64_t, uint_least32_t + #include <bits/random.h> #ifndef _GLIBCXX_EXPORT_TEMPLATE # include <bits/random.tcc> #endif +#endif // _GLIBCXX_USE_C99_STDINT_TR1 + #endif // __GXX_EXPERIMENTAL_CXX0X__ #endif // _GLIBCXX_RANDOM diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread index bf282cc0365..83b259d7949 100644 --- a/libstdc++-v3/include/std/thread +++ b/libstdc++-v3/include/std/thread @@ -126,7 +126,10 @@ namespace std template<typename _Callable> explicit thread(_Callable __f) - { _M_start_thread(_M_make_routine<_Callable>(__f)); } + { + _M_start_thread(_M_make_routine<_Callable> + (std::forward<_Callable>(__f))); + } template<typename _Callable, typename... _Args> thread(_Callable&& __f, _Args&&... __args) diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 8dc8dcfc064..18cd89bca3b 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -164,7 +164,7 @@ namespace std : _Inherited(__in._M_tail()), _Base(__in._M_head()) { } _Tuple_impl(_Tuple_impl&& __in) - : _Inherited(std::move<_Inherited&&>(__in._M_tail())), + : _Inherited(std::move(__in._M_tail())), _Base(std::forward<_Head>(__in._M_head())) { } template<typename... _UElements> @@ -173,8 +173,7 @@ namespace std template<typename... _UElements> _Tuple_impl(_Tuple_impl<_Idx, _UElements...>&& __in) - : _Inherited(std::move<typename _Tuple_impl<_Idx, _UElements...>:: - _Inherited&&>(__in._M_tail())), + : _Inherited(std::move(__in._M_tail())), _Base(std::forward<typename _Tuple_impl<_Idx, _UElements...>:: _Base>(__in._M_head())) { } @@ -244,7 +243,7 @@ namespace std : _Inherited(static_cast<const _Inherited&>(__in)) { } tuple(tuple&& __in) - : _Inherited(std::move<_Inherited>(__in)) { } + : _Inherited(static_cast<_Inherited&&>(__in)) { } template<typename... _UElements> tuple(const tuple<_UElements...>& __in) @@ -253,7 +252,7 @@ namespace std template<typename... _UElements> tuple(tuple<_UElements...>&& __in) - : _Inherited(std::move<_Tuple_impl<0, _UElements...> >(__in)) { } + : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } // XXX http://gcc.gnu.org/ml/libstdc++/2008-02/msg00047.html template<typename... _UElements> @@ -327,7 +326,7 @@ namespace std : _Inherited(static_cast<const _Inherited&>(__in)) { } tuple(tuple&& __in) - : _Inherited(std::move<_Inherited>(__in)) { } + : _Inherited(static_cast<_Inherited&&>(__in)) { } template<typename _U1, typename _U2> tuple(const tuple<_U1, _U2>& __in) @@ -335,7 +334,7 @@ namespace std template<typename _U1, typename _U2> tuple(tuple<_U1, _U2>&& __in) - : _Inherited(std::move<_Tuple_impl<0, _U1, _U2> >(__in)) { } + : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } template<typename _U1, typename _U2> tuple(const pair<_U1, _U2>& __in) diff --git a/libstdc++-v3/testsuite/18_support/headers/exception/synopsis.cc b/libstdc++-v3/testsuite/18_support/headers/exception/synopsis.cc index a66c0156291..6c64eb29d9f 100644 --- a/libstdc++-v3/testsuite/18_support/headers/exception/synopsis.cc +++ b/libstdc++-v3/testsuite/18_support/headers/exception/synopsis.cc @@ -29,7 +29,7 @@ namespace std { typedef void (*terminate_handler)(); terminate_handler set_terminate(terminate_handler f ) throw(); - void terminate(); + void terminate() throw(); bool uncaught_exception() throw(); } diff --git a/libstdc++-v3/testsuite/20_util/forward/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/forward/requirements/explicit_instantiation.cc index 8b14da23a95..88ba9e548af 100644 --- a/libstdc++-v3/testsuite/20_util/forward/requirements/explicit_instantiation.cc +++ b/libstdc++-v3/testsuite/20_util/forward/requirements/explicit_instantiation.cc @@ -28,5 +28,5 @@ namespace std { typedef short test_type; - template test_type&& forward(std::identity<test_type>::type&&); + template test_type&& forward<test_type>(test_type&&); } diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr.cc index e8c751bba5c..e2ec0786055 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr.cc @@ -66,7 +66,7 @@ test01() std::shared_ptr<A> a(new A); std::auto_ptr<B> b(new B); - a = b; + a = std::move(b); VERIFY( a.get() != 0 ); VERIFY( b.get() == 0 ); VERIFY( A::ctor_count == 2 ); diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc index 155449438cf..b79a25b131c 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc @@ -36,7 +36,7 @@ test01() std::shared_ptr<A> a; std::auto_ptr<B> b; - a = b; // { dg-error "here" } + a = std::move(b); // { dg-error "here" } return 0; } diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr.cc index 9087e518ad9..eb5bb9590df 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr.cc @@ -33,7 +33,7 @@ test01() bool test __attribute__((unused)) = true; std::auto_ptr<A> a(new A); - std::shared_ptr<A> a2(a); + std::shared_ptr<A> a2(std::move(a)); VERIFY( a.get() == 0 ); VERIFY( a2.get() != 0 ); VERIFY( a2.use_count() == 1 ); diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr_neg.cc index 3a946b5872b..e2ef60e3fbb 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr_neg.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr_neg.cc @@ -34,7 +34,7 @@ test01() bool test __attribute__((unused)) = true; const std::auto_ptr<A> a; - std::shared_ptr<A> p(a); // { dg-error "no match" } + std::shared_ptr<A> p(std::move(a)); // { dg-error "no match" } return 0; } diff --git a/libstdc++-v3/testsuite/20_util/tuple/swap.cc b/libstdc++-v3/testsuite/20_util/tuple/swap.cc index 6dab446bfe9..613e9c2ff1c 100644 --- a/libstdc++-v3/testsuite/20_util/tuple/swap.cc +++ b/libstdc++-v3/testsuite/20_util/tuple/swap.cc @@ -41,7 +41,7 @@ struct MoveOnly bool operator==(MoveOnly const& m) { return i == m.i; } - void swap(MoveOnly&& m) + void swap(MoveOnly& m) { std::swap(m.i, i); } int i; diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/ext_pointer/operations/1.cc b/libstdc++-v3/testsuite/23_containers/forward_list/ext_pointer/operations/1.cc index 0d9361a37d0..8b5afdd980b 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/ext_pointer/operations/1.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/ext_pointer/operations/1.cc @@ -39,7 +39,7 @@ test01() fwd_list_type x = {666.0, 777.0, 888.0}; - a.splice_after(posa, x); + a.splice_after(posa, std::move(x)); ++posa; VERIFY(*posa == 666.0); @@ -70,7 +70,7 @@ test02() ++endy; VERIFY(*endy == 14.0); - a.splice_after(posa, y, befy, endy); + a.splice_after(posa, std::move(y), befy, endy); VERIFY(*posa == 0.0); VERIFY(*befy == 10.0); @@ -95,7 +95,7 @@ test03() fwd_list_type::const_iterator posz = z.begin(); VERIFY(*posz == 42.0); - a.splice_after(posa, z, posz); + a.splice_after(posa, std::move(z), posz); VERIFY(*posa == 1.0); ++posa; VERIFY(*posa == 43.0); diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/ext_pointer/operations/5.cc b/libstdc++-v3/testsuite/23_containers/forward_list/ext_pointer/operations/5.cc index 434a9aaac95..13d15b39d12 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/ext_pointer/operations/5.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/ext_pointer/operations/5.cc @@ -37,7 +37,7 @@ test01() fwd_list_type a = {0.0, 1.0, 2.0, 3.0, 4.0}; fwd_list_type b = {1.0, 2.0, 3.0, 4.0, 4.0, 5.0}; - a.merge(b); + a.merge(std::move(b)); fwd_list_type r = {0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 3.0, 4.0, 4.0, 4.0, 5.0}; diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/operations/1.cc b/libstdc++-v3/testsuite/23_containers/forward_list/operations/1.cc index 1f86db9743f..5a996f3411e 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/operations/1.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/operations/1.cc @@ -34,7 +34,7 @@ test01() std::forward_list<double> x = {666.0, 777.0, 888.0}; - a.splice_after(posa, x); + a.splice_after(posa, std::move(x)); ++posa; VERIFY(*posa == 666.0); @@ -63,7 +63,7 @@ test02() ++endy; VERIFY(*endy == 14.0); - a.splice_after(posa, y, befy, endy); + a.splice_after(posa, std::move(y), befy, endy); VERIFY(*posa == 0.0); VERIFY(*befy == 10.0); @@ -86,7 +86,7 @@ test03() std::forward_list<double>::const_iterator posz = z.begin(); VERIFY(*posz == 42.0); - a.splice_after(posa, z, posz); + a.splice_after(posa, std::move(z), posz); VERIFY(*posa == 1.0); ++posa; VERIFY(*posa == 43.0); diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/operations/5.cc b/libstdc++-v3/testsuite/23_containers/forward_list/operations/5.cc index 05e3f844410..1291a269044 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/operations/5.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/operations/5.cc @@ -32,7 +32,7 @@ test01() std::forward_list<double> a = {0.0, 1.0, 2.0, 3.0, 4.0}; std::forward_list<double> b = {1.0, 2.0, 3.0, 4.0, 4.0, 5.0}; - a.merge(b); + a.merge(std::move(b)); std::forward_list<double> r = {0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 3.0, 4.0, 4.0, 4.0, 5.0}; diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/1.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/1.cc index d9bd9a2194e..767640ea996 100644 --- a/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/1.cc +++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/1.cc @@ -15,8 +15,8 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. -#include "1.h" #include <list> +#include "1.h" namespace std { diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/2.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/2.cc index 7bd75a39e3c..d1faf025f2f 100644 --- a/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/2.cc +++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/2.cc @@ -17,8 +17,8 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. -#include "2.h" #include <list> +#include "2.h" int main() { diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/3.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/3.cc index f994e9b4ae1..676466d537a 100644 --- a/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/3.cc +++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/3.cc @@ -17,8 +17,8 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. -#include "3.h" #include <list> +#include "3.h" int main() { diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc index cd2b2994807..c0b6ea46be9 100644 --- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1379 } +// { dg-error "no matching" "" { target *-*-* } 1387 } // { dg-excess-errors "" } #include <list> diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc index cc2b419bd4e..0d27211a5f7 100644 --- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1348 } +// { dg-error "no matching" "" { target *-*-* } 1356 } // { dg-excess-errors "" } #include <list> diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc index d650a9ec102..bbf78080365 100644 --- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1348 } +// { dg-error "no matching" "" { target *-*-* } 1356 } // { dg-excess-errors "" } #include <list> diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc index ae9e63f704e..1e84b97d301 100644 --- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1348 } +// { dg-error "no matching" "" { target *-*-* } 1356 } // { dg-excess-errors "" } #include <list> diff --git a/libstdc++-v3/testsuite/23_containers/vector/15523.cc b/libstdc++-v3/testsuite/23_containers/vector/15523.cc new file mode 100644 index 00000000000..3b8230cd560 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/15523.cc @@ -0,0 +1,39 @@ +// Copyright (C) 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-options "-D_GLIBCXX_DEBUG" } + +#include <vector> + +// libstdc++/15523 +void test01() +{ + using namespace std; + + vector<vector<int>::const_iterator> x(2); + + vector<int>::iterator i2, i3; + vector<int>::const_iterator ci1(i2); + + i2 = i3; +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc index 26c3501f04d..771a5550d43 100644 --- a/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc +++ b/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc @@ -19,8 +19,8 @@ // { dg-do compile } -// { dg-xfail-if "" { { *-*-linux* *-*-darwin[3-7]* } || { uclibc || newlib } } { "*" } { "" } } -// { dg-excess-errors "" { target { { *-*-linux* *-*-darwin[3-7]* } || { uclibc || newlib } } } } +// { dg-xfail-if "" { { *-*-linux* *-*-darwin[3-9]* } || { uclibc || newlib } } { "*" } { "" } } +// { dg-excess-errors "" { target { { *-*-linux* *-*-darwin[3-9]* } || { uclibc || newlib } } } } #include <math.h> diff --git a/libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/cons/default.cc index a9dcd0626be..16e56f80569 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/cons/parms.cc index d4c29e26784..9742e273a9e 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/requirements/typedefs.cc index 20a69ad803e..adea635e962 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/cons/default.cc index 22b854d8a5d..25fe4fbc5e6 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/cons/parms.cc index 077d6a3032c..4381c6ea415 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/requirements/typedefs.cc index cd6eb7d9e7c..e60fac13c75 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/default.cc index a61fcaad3df..85a5c278c39 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/parms.cc index ce936bca62c..54f6f81b3c5 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/requirements/typedefs.cc index 173404138a5..3d80d2ddf0f 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/cons/default.cc index 0135bad215e..88e5ebb4c82 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/cons/parms.cc index 4461b410a56..a720aab5f00 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/requirements/typedefs.cc index 5fa807432bc..271e0fe451a 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/default_random_engine.cc b/libstdc++-v3/testsuite/26_numerics/random/default_random_engine.cc index c766482414d..3fef87d0c8e 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/default_random_engine.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/default_random_engine.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/base_copy.cc b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/base_copy.cc index c69467eb691..328dd71d0bb 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/base_copy.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/base_copy.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/base_move.cc b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/base_move.cc index 86cc46be50b..990dc9b3fe9 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/base_move.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/base_move.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/default.cc index a82623ea564..17fea5bdb47 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed1.cc b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed1.cc index b464e71d5a3..efe194c99f0 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed1.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed1.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed2.cc b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed2.cc index d670c608fee..82f6fdb1c74 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed2.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed2.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed_seq.cc b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed_seq.cc index 098f2bbe04f..58f0f1c392a 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed_seq.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed_seq.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/operators/equal.cc b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/operators/equal.cc index 39560537d5d..db2497540a3 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/operators/equal.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/operators/equal.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/operators/serialize.cc b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/operators/serialize.cc index d2f66125e18..1d39a213f47 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/operators/serialize.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/operators/serialize.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/requirements/typedefs.cc index 0c2c42a1b72..379b3aeb978 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/default.cc index f5292a638c8..9d05b19823f 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-03 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/initlist.cc b/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/initlist.cc index c83da0778a4..3bcb7448e96 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/initlist.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/initlist.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-03 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/num_xbound_fun.cc b/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/num_xbound_fun.cc index 13974837255..12282f0f468 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/num_xbound_fun.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/num_xbound_fun.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-03 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/range.cc b/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/range.cc index b7eb7fcfa77..aa8d9567f45 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/range.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/range.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-03 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/requirements/typedefs.cc index 7d25cad8c95..7c5977b3808 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-03 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/default.cc index ba4dc9cfee4..97168ff029f 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/parms.cc index 753f5c93175..6c2535fa0ac 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/requirements/typedefs.cc index 83eb297fa0b..7c696e25244 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/default.cc index ce9756b3f7b..542909588ee 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/parms.cc index 99315f4fa07..d0374cd5c22 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/requirements/typedefs.cc index f271d663d12..8f5d99da494 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/fisher_f_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/fisher_f_distribution/cons/default.cc index 6fc78d2e066..d3e8ae968fa 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/fisher_f_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/fisher_f_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/fisher_f_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/fisher_f_distribution/cons/parms.cc index 576f88b7b0d..15133aba161 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/fisher_f_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/fisher_f_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/fisher_f_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/fisher_f_distribution/requirements/typedefs.cc index 62b3f3a2a95..a92727d706b 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/fisher_f_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/fisher_f_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/gamma_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/gamma_distribution/cons/default.cc index 0c4745b9172..378eca23b9f 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/gamma_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/gamma_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/gamma_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/gamma_distribution/cons/parms.cc index 2d31e9a4ee8..c400c98df62 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/gamma_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/gamma_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/gamma_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/gamma_distribution/requirements/typedefs.cc index f4b2775a5c0..a1d15575e91 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/gamma_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/gamma_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/cons/default.cc index 4cc05596913..353193bbd9c 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/cons/parms.cc index b0d6e109a43..ddc66767546 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/requirements/typedefs.cc index 6955c516107..cc03ebf0ddb 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/base_copy.cc b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/base_copy.cc index 0c7e7615b2f..2c8d88e4f26 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/base_copy.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/base_copy.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/base_move.cc b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/base_move.cc index 8243d7cbe41..1d2ede72c9b 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/base_move.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/base_move.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/default.cc index 1da18ffca52..7db0cf30ffc 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed1.cc b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed1.cc index fcc274ef908..9ad6164d963 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed1.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed1.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed2.cc b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed2.cc index a2f3869a5a0..3e878773044 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed2.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed2.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed_seq.cc b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed_seq.cc index 42138ab7550..724a324310f 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed_seq.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed_seq.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/operators/equal.cc b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/operators/equal.cc index 15294fbf09f..18d05140db2 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/operators/equal.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/operators/equal.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/operators/serialize.cc b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/operators/serialize.cc index 759e64817c3..332931addfa 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/operators/serialize.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/operators/serialize.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/requirements/typedefs.cc index 367fc94ad72..0402a0966bc 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/knuth_b.cc b/libstdc++-v3/testsuite/26_numerics/random/knuth_b.cc index e1dde6b5241..ba4016eabd2 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/knuth_b.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/knuth_b.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/default.cc index d3f40a057cb..42ca73c73f3 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed1.cc b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed1.cc index 700dc7dde54..75a2e42c56d 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed1.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed1.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed2.cc b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed2.cc index 3da26ccc104..a8819598670 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed2.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed2.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/operators/equal.cc b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/operators/equal.cc index 62a266e23e0..5f555db48d6 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/operators/equal.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/operators/equal.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/operators/serialize.cc b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/operators/serialize.cc index 38c19624c48..8b67e5f3a33 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/operators/serialize.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/operators/serialize.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/requirements/non_uint_neg.cc b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/requirements/non_uint_neg.cc index 390334487a2..f54d76ada07 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/requirements/non_uint_neg.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/requirements/non_uint_neg.cc @@ -20,8 +20,9 @@ // { dg-do compile } // { dg-options "-std=c++0x -D_GLIBCXX_CONCEPT_CHECKS" } -// { dg-error "not a valid type" "" { target *-*-* } 31 } -// { dg-error "invalid type" "" { target *-*-* } 31 } +// { dg-require-cstdint "" } +// { dg-error "not a valid type" "" { target *-*-* } 32 } +// { dg-error "invalid type" "" { target *-*-* } 32 } // 26.4.3.1 class template linear_congruential_engine [rand.eng.lcong] // 26.4.2.2 Concept RandomNumberEngine [rand.concept.eng] diff --git a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/requirements/typedefs.cc index a17c5526a92..993f7935498 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/lognormal_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/lognormal_distribution/cons/default.cc index 62893c0dab8..9607fd3e830 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/lognormal_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/lognormal_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/lognormal_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/lognormal_distribution/cons/parms.cc index ea5b7363977..a18f935087c 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/lognormal_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/lognormal_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/lognormal_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/lognormal_distribution/requirements/typedefs.cc index 035c8c6ce3d..2e3ade699c4 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/lognormal_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/lognormal_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/default.cc index 838d778bd0f..30634e1da30 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed1.cc b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed1.cc index e711a4a1045..b37f9782496 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed1.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed1.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed2.cc b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed2.cc index 9a63769ada6..d840772cd76 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed2.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed2.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/operators/equal.cc b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/operators/equal.cc index c96c54f567f..7e482a8cd09 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/operators/equal.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/operators/equal.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/operators/serialize.cc b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/operators/serialize.cc index 6cfd8951bc9..03fb8b04fa1 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/operators/serialize.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/operators/serialize.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/requirements/typedefs.cc index d533aca5cb5..7ea898a1e84 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/minstd_rand.cc b/libstdc++-v3/testsuite/26_numerics/random/minstd_rand.cc index cef616f2312..33f5c0355da 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/minstd_rand.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/minstd_rand.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/minstd_rand0.cc b/libstdc++-v3/testsuite/26_numerics/random/minstd_rand0.cc index c101ee912aa..51716b3c92d 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/minstd_rand0.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/minstd_rand0.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/mt19937.cc b/libstdc++-v3/testsuite/26_numerics/random/mt19937.cc index a906c1c1e6e..2703ae3e84e 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/mt19937.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/mt19937.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/mt19937_64.cc b/libstdc++-v3/testsuite/26_numerics/random/mt19937_64.cc index cda4546116d..47ef8cfcff3 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/mt19937_64.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/mt19937_64.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/cons/default.cc index db9522712eb..02a7836ef47 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/cons/parms.cc index 5e7d928c5bc..3db9c0bd152 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/requirements/typedefs.cc index 0fa32bf56a8..5b30fda671c 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/default.cc index b5c047d93f8..fca0cc18818 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/parms.cc index 551be3423e2..ea3113dd089 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/requirements/typedefs.cc index d27c6ede9c7..471379d5527 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/default.cc index 0b0ff19e2f0..cdfa3d061e7 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-03 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/initlist_fun.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/initlist_fun.cc index aded49d13da..7ae5d89bed9 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/initlist_fun.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/initlist_fun.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-03 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/num_xbound_fun.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/num_xbound_fun.cc index bc0f1923711..a7c7589fe68 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/num_xbound_fun.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/num_xbound_fun.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-03 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/range.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/range.cc index 9d5e75c7eec..d0f7dbf53b0 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/range.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/range.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-03 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/requirements/typedefs.cc index 150e7fe20f2..c0d458ef6a1 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-03 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/default.cc index 8de114fab29..d2db1765a3c 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-03 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/initlist_fun.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/initlist_fun.cc index a00e41e4f27..564aeeea249 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/initlist_fun.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/initlist_fun.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-03 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/num_xbound_fun.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/num_xbound_fun.cc index f9025183b44..e4eb0e8fe2d 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/num_xbound_fun.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/num_xbound_fun.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-03 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/range.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/range.cc index 8038c33a9eb..56be0ad9bcd 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/range.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/range.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-03 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/requirements/typedefs.cc index c71144341e7..cb1d016dce2 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-03 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/cons/default.cc index f8eb958aced..df396c4c04b 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/cons/parms.cc index 2aecbff80ce..728587bd2dc 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/requirements/typedefs.cc index 40506888d9a..d6a600293da 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default.cc index 3b502b8800a..2e21ab6a9cb 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/token.cc b/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/token.cc index db64e85d2c4..638134cf440 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/token.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/token.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/random_device/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/random_device/requirements/typedefs.cc index 3fb4ae7156e..47a76b613cd 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/random_device/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/random_device/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/ranlux24.cc b/libstdc++-v3/testsuite/26_numerics/random/ranlux24.cc index ab37bc51f85..f7352146d97 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/ranlux24.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/ranlux24.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/ranlux24_base.cc b/libstdc++-v3/testsuite/26_numerics/random/ranlux24_base.cc index a6bb790d144..65cf97560ff 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/ranlux24_base.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/ranlux24_base.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/ranlux48.cc b/libstdc++-v3/testsuite/26_numerics/random/ranlux48.cc index a0856b19ecb..095242c1c48 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/ranlux48.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/ranlux48.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/ranlux48_base.cc b/libstdc++-v3/testsuite/26_numerics/random/ranlux48_base.cc index 21522041d91..42c423c7363 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/ranlux48_base.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/ranlux48_base.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/seed_seq/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/seed_seq/cons/default.cc index 43bfd919281..c68c1b446a3 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/seed_seq/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/seed_seq/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-05 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/seed_seq/cons/initlist.cc b/libstdc++-v3/testsuite/26_numerics/random/seed_seq/cons/initlist.cc index 904c075c4d9..d98b6b2c45b 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/seed_seq/cons/initlist.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/seed_seq/cons/initlist.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2009-02-13 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/seed_seq/cons/range.cc b/libstdc++-v3/testsuite/26_numerics/random/seed_seq/cons/range.cc index 9fc46e18184..69740c8882e 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/seed_seq/cons/range.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/seed_seq/cons/range.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-05 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/seed_seq/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/seed_seq/requirements/typedefs.cc index 694048cbf3b..6c92fa8094f 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/seed_seq/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/seed_seq/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-05 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/base_copy.cc b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/base_copy.cc index 5fb58ae463a..c0087721079 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/base_copy.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/base_copy.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/base_move.cc b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/base_move.cc index a04e119e8fa..caac982e53f 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/base_move.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/base_move.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/default.cc index 021e8eaaec5..5d96933ef9f 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed1.cc b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed1.cc index 0fb92c54279..f6827009c7d 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed1.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed1.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed2.cc b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed2.cc index 69adcb06f53..44ba08896c0 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed2.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed2.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed_seq.cc b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed_seq.cc index 1f1b1e4e23d..b88d7ebb6b7 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed_seq.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed_seq.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-12-07 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/operators/equal.cc b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/operators/equal.cc index 21a36f1a359..57763e851a3 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/operators/equal.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/operators/equal.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/operators/serialize.cc b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/operators/serialize.cc index 5fc25797d7a..578e4959371 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/operators/serialize.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/operators/serialize.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/requirements/typedefs.cc index 010f7ca069c..e2ec4ce1401 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/default.cc index bf62bc7afcb..a875523d98f 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/parms.cc index b57b58d0ed0..19ea7bacdf8 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/requirements/typedefs.cc index bdb211e1c1c..e090b354200 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/default.cc index 44dbdc1ab71..4311439b6e6 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed1.cc b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed1.cc index 1528166c2ba..078392ccbd0 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed1.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed1.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed2.cc b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed2.cc index be251baa7f7..d8618706092 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed2.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed2.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/operators/equal.cc b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/operators/equal.cc index bd6f7c8d2cb..53fdbbefd8a 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/operators/equal.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/operators/equal.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/operators/serialize.cc b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/operators/serialize.cc index c701bd7b74d..e4129fc8df5 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/operators/serialize.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/operators/serialize.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/requirements/typedefs.cc index 24dff43bbf5..5e56a6e25a4 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/cons/default.cc index 0e83565e0de..dae94ccea0f 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/cons/parms.cc index 47c6fdb07fd..70b40b0ade6 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/cons/parms_neg.cc b/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/cons/parms_neg.cc index c566c03b181..e462d686298 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/cons/parms_neg.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/cons/parms_neg.cc @@ -20,6 +20,7 @@ // { dg-do run { xfail *-*-* } } // { dg-options "-std=c++0x -D_GLIBCXX_DEBUG" } +// { dg-require-cstdint "" } // 26.4.8.1.1 Class template uniform_int_distribution [rand.dist_uni] // 26.4.2.4 Concept RandomNumberDistribution [rand.concept.dist] diff --git a/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/requirements/typedefs.cc index c403ff6f131..3d584b525c5 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/uniform_int_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/cons/default.cc index 57fedeb666a..8240736c753 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/cons/parms.cc index d52c664c339..ff1494b7318 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/cons/parms_neg.cc b/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/cons/parms_neg.cc index bd2b88df63e..a5c76d6ec7a 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/cons/parms_neg.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/cons/parms_neg.cc @@ -20,6 +20,7 @@ // { dg-do run { xfail *-*-* } } // { dg-options "-std=c++0x -D_GLIBCXX_DEBUG" } +// { dg-require-cstdint "" } // 26.4.8.1.1 Class template uniform_real_distribution [rand.dist_uni] // 26.4.2.4 Concept RandomNumberDistribution [rand.concept.dist] diff --git a/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/requirements/typedefs.cc index 5e4d5d3a43c..c14182f7230 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/weibull_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/weibull_distribution/cons/default.cc index 49442fe3376..1377c20e37f 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/weibull_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/weibull_distribution/cons/default.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/weibull_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/weibull_distribution/cons/parms.cc index 480a311f14c..91eca51e53d 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/weibull_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/weibull_distribution/cons/parms.cc @@ -1,4 +1,5 @@ // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/26_numerics/random/weibull_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/26_numerics/random/weibull_distribution/requirements/typedefs.cc index 1920ad324a1..5c8d8e0769b 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/weibull_distribution/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/weibull_distribution/requirements/typedefs.cc @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } // // 2008-11-24 Edward M. Smith-Rowland <3dw4rd@verizon.net> // diff --git a/libstdc++-v3/testsuite/27_io/rvalue_streams.cc b/libstdc++-v3/testsuite/27_io/rvalue_streams.cc new file mode 100644 index 00000000000..245633a8fca --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/rvalue_streams.cc @@ -0,0 +1,42 @@ +// Copyright (C) 2008, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-do run } + +#include <sstream> +#include <string> +#include <testsuite_hooks.h> + +void +test01() +{ + int i = 1742; + // This usage isn't supported by the current draft. + // std::string result = (std::ostringstream() << i).str(); + std::ostringstream() << i; + std::string result ("1742"); + int i2; + std::istringstream(result) >> i2; + VERIFY (i == i2); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/cons/copy.cc b/libstdc++-v3/testsuite/30_threads/shared_future/cons/copy.cc index 16954a1d4c1..b1940fae3c7 100644 --- a/libstdc++-v3/testsuite/30_threads/shared_future/cons/copy.cc +++ b/libstdc++-v3/testsuite/30_threads/shared_future/cons/copy.cc @@ -25,7 +25,7 @@ #include <future> #include <testsuite_hooks.h> -extern std::unique_future<int>& get(); +extern std::unique_future<int>&& get(); void test01() { diff --git a/libstdc++-v3/testsuite/30_threads/thread/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/thread/cons/assign_neg.cc index 7857e53bac7..1ea66ec9c81 100644 --- a/libstdc++-v3/testsuite/30_threads/thread/cons/assign_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/thread/cons/assign_neg.cc @@ -32,4 +32,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 31 } -// { dg-error "deleted function" "" { target *-*-* } 141 } +// { dg-error "deleted function" "" { target *-*-* } 144 } diff --git a/libstdc++-v3/testsuite/util/replacement_memory_operators.h b/libstdc++-v3/testsuite/util/replacement_memory_operators.h index 91c8fa3d38a..c7b19edc457 100644 --- a/libstdc++-v3/testsuite/util/replacement_memory_operators.h +++ b/libstdc++-v3/testsuite/util/replacement_memory_operators.h @@ -17,6 +17,9 @@ // <http://www.gnu.org/licenses/>. #include <exception> +#include <stdexcept> +#include <cstdlib> +#include <cstdio> namespace __gnu_test { @@ -24,7 +27,7 @@ namespace __gnu_test struct counter { - size_t _M_count; + std::size_t _M_count; bool _M_throw; counter() : _M_count(0), _M_throw(true) { } @@ -48,7 +51,7 @@ namespace __gnu_test return g; } - static size_t + static std::size_t count() { return get()._M_count; } static void @@ -85,7 +88,7 @@ namespace __gnu_test void* operator new(std::size_t size) throw(std::bad_alloc) { - printf("operator new is called \n"); + std::printf("operator new is called \n"); void* p = std::malloc(size); if (p == NULL) throw std::bad_alloc(); @@ -95,7 +98,7 @@ void* operator new(std::size_t size) throw(std::bad_alloc) void operator delete(void* p) throw() { - printf("operator delete is called \n"); + std::printf("operator delete is called \n"); if (p != NULL) { std::free(p); @@ -103,8 +106,8 @@ void operator delete(void* p) throw() std::size_t count = __gnu_test::counter::count(); if (count == 0) - printf("All memory released \n"); + std::printf("All memory released \n"); else - printf("%lu allocations to be released \n", count); + std::printf("%lu allocations to be released \n", count); } } diff --git a/zlib/ChangeLog.gcj b/zlib/ChangeLog.gcj index eee68cdf60b..2570352b14b 100644 --- a/zlib/ChangeLog.gcj +++ b/zlib/ChangeLog.gcj @@ -1,3 +1,7 @@ +2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force. + 2009-03-01 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> * configure: Regenerate. diff --git a/zlib/configure.ac b/zlib/configure.ac index c85f4d50c81..febe9e39b76 100644 --- a/zlib/configure.ac +++ b/zlib/configure.ac @@ -54,7 +54,7 @@ GCC_NO_EXECUTABLES m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) m4_define([_AC_ARG_VAR_PRECIOUS],[]) AC_PROG_CC -m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) +m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) AC_SUBST(CFLAGS) |