diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-07-31 06:16:50 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-07-31 06:16:50 +0000 |
commit | 80840a5fd2b47202cc9d2266cf9a6b1f5c2e6ce2 (patch) | |
tree | 8e564e5ac627ae476fa0e8d322261e6313f70b07 | |
parent | 6c3f1ba6c0116a23ada0a56e7ef8b55e4eeaffa0 (diff) | |
download | gcc-80840a5fd2b47202cc9d2266cf9a6b1f5c2e6ce2.tar.gz |
2009-07-31 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 150307
added manually libstdc++-v3/include/std/chrono from trunk.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@150308 138bc75d-0d04-0410-961f-82ee72b054a4
496 files changed, 32121 insertions, 11339 deletions
diff --git a/ChangeLog b/ChangeLog index f5845fc2fdf..50a2ec58942 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-07-28 Rask Ingemann Lambertsen <ccc94453@vip.cybercity.dk> + + * MAINTAINERS (Write After Approval): Update my e-mail address. + 2009-07-06 Ian Lance Taylor <iant@google.com> * configure.ac: Add missing comma in AC_ARG_WITH(boot-libs). diff --git a/ChangeLog.MELT b/ChangeLog.MELT index 02461f97f28..4f7374fd97e 100644 --- a/ChangeLog.MELT +++ b/ChangeLog.MELT @@ -1,4 +1,8 @@ +2009-07-31 Basile Starynkevitch <basile@starynkevitch.net> + MELT branch merged with trunk rev 150307 + added manually libstdc++-v3/include/std/chrono from trunk. + 2009-07-27 Basile Starynkevitch <basile@starynkevitch.net> MELT branch merged with trunk rev 150103 diff --git a/MAINTAINERS b/MAINTAINERS index 107111fba20..065948470a4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -371,7 +371,7 @@ Doug Kwan dougkwan@google.com Scott Robert Ladd scott.ladd@coyotegulch.com Razya Ladelsky razya@gcc.gnu.org Aaron W. LaFramboise aaronavay62@aaronwl.com -Rask Ingemann Lambertsen rask@sygehus.dk +Rask Ingemann Lambertsen ccc94453@vip.cybercity.dk Asher Langton langton2@llnl.gov Chris Lattner sabre@nondot.org Terry Laurenzo tlaurenzo@gmail.com 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/fixincludes/ChangeLog b/fixincludes/ChangeLog index 35260caca66..62300af7c25 100644 --- a/fixincludes/ChangeLog +++ b/fixincludes/ChangeLog @@ -1,3 +1,10 @@ +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/gcc/ChangeLog b/gcc/ChangeLog index 99028e8b1e3..bde57bbbfa5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,606 @@ +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. + (rewrite_phi_with_iv): New. + (rewrite_all_phi_nodes_with_iv): New. + (canonicalize_loop_ivs): Move here from tree-parloops.c. + Remove reduction_list argument. Use rewrite_all_phi_nodes_with_iv. + * tree-parloops.c (loop_parallel_p): Move out all conditions + except dependency check. + (canonicalize_loop_ivs): Move to tree-ssa-loop-manip.c. + (gen_parallel_loop): Call canonicalize_loop_ivs without + reduction_list argument. + (build_new_reduction): New. + (gather_scalar_reductions): New. + (try_get_loop_niter): New. + (try_create_reduction_list): New. + (parallleize_loops): Change the parallel conditions check. + * tree-flow.h (canonicalize_loop_ivs): Remove one argument. + * Makefile.in (tree-ssa-loop-manip.o): Add langhooks.h dependency. + +2009-07-30 Dave Korn <dave.korn.cygwin@gmail.com> + + * opt-functions.awk (opt_args): Allow argument to be enclosed in + curly braces. + * doc/options.texi (Option properties): Mention new quoting syntax. + +2009-07-29 Douglas B Rupp <rupp@gnat.com> + + * config/alpha/alpha.c (alpha_start_function): + Handle VMS_DEBUG_MAIN_POINTER + * config/alpha/vms.h (VMS_DEBUG_MAIN_POINTER): Define new macro. + * doc/invoke.texi: Document -mdebug-main switch. + +2009-07-29 Richard Henderson <rth@redhat.com> + + * cgraph.c (cgraph_set_call_stmt_including_clones): Tidy. + (cgraph_create_edge_including_clones): Likewise. + * tree-inline.c (copy_bb): Operate on the correct edges + when updating the callgraph. + +2009-07-29 Douglas B Rupp <rupp@gnat.com> + + * config/alpha/vms-cc.c: Deleted. + * config/alpha/vms-ld.c: Deleted. + * config/alpha/t-vms64: Moved to config/vms + * config/alpha/vms-crt0-64.c: Moved to config/vms + * config/alpha/vms-crt0.c: Moved to config/vms + * config/alpha/vms-psxcrt0-64.c: Moved to config/vms + * config/alpha/vms-psxcrt0.c: Moved to config/vms + * config/alpha/xm-vms.h: Moved to config/vms + * config/alpha/x-vms: Moved to config/vms + * config/alpha/t-vms (vcrt0.o, pcrt0.o): Move rules to new file + config/vms/t-vms. + * config/vms/t-vms: Moved here from config/alpha. Alpha specific + parts removed. (STMP_FIXPROTO, STMP_FIXINC, LIMITS_H_TEST): Set. + (version): Set. + * config/vms/t-vms64: Moved here from config/alpha + * config/vms/vms-crt0-64.c: Moved here from config/alpha. + (argc,argv,envp): Enforce 32bit malloc'ing. + * config/vms/vms-psxcrt0-64.c: Likewise. + * config/vms/vms-crt0.c: Moved here from config/alpha. + * config/vms/vms-psxcrt0.c: Likewise. + * config/vms/vms-crtl-64.h: New file. + * config/vms/vms-crtl.h: New file. + * config/vms/vms.opt: New file. + * config/vms/xm-vms64.h: New file. + * config/vms/xm-vms.h: Moved here from config/alpha. + (STANARD_EXEC_PREFIX, STANDARD_STARTFILE_PREFIX, STANDARD_INCLUDE_DIR): + Set. + * config/vms/x-vms: Moved here from config/alpha. + (version, VMS_EXTRA_PARTS): Moved to t-vms. + (vms-ld.o, vms-cc.o): Removed. + (LN, LN_S, USE_COLLECT2, POD2MAN): Set. + +2009-07-29 Douglas B Rupp <rupp@gnat.com> + + * dwarf2out.c (add_name_and_src_coords_attributes): Push on the + correct stack (obvious VMS fix). + +2009-07-29 Douglas B Rupp <rupp@gnat.com> + + * dwarf2out.c (output_file_names): Output VMS style file name, size, + date, version info if VMS_DEBUGGING_INFO defined. + * vmsdgbout.c (vms_file_stats_name): New functon. VMS style file name, + size, date calculating code moved here. + +2009-07-29 Paul Brook <paul@codesourcery.com> + + * config/arm/lib1funcs.asm (clear_cache): Use ARM_FUNC_START and + do_push/do_pop. + +2009-07-29 Uros Bizjak <ubizjak@gmail.com> + + PR target/40577 + * config/alpha/alpha.c (alpha_expand_unaligned_store): Convert src + to DImode when generating insq_le insn. + +2009-07-28 Douglas B Rupp <rupp@gnat.com> + + * dwarf2out.c (DWARF2_INDIRECT_STRING_SUPPORT_MISSING_ON_TARGET): + New macro set for VMS_DEBUGGGING_INFO. + (AT_string_form): Use it. + +2009-07-28 DJ Delorie <dj@redhat.com> + + * config/mep/mep.c (vtext_section): New. + (vftext_section): New. + (ftext_section): New. + (mep_select_section): Add support for functions. + (mep_unique_section): Likewise. + (mep_asm_init_sections): Likewise. + (mep_encode_section_info): Remove it from here. + + * config/mep/mep.h (USE_SELECT_SECTION_FOR_FUNCTIONS): Define. + +2009-07-28 Paolo Bonzini <bonzinI@gnu.org> + + * tree.h (TREE_DEPRECATED): Document it is used for types too. + (TYPE_VECTOR_OPAQUE): Use default_def_flag + +2009-07-28 Douglas B Rupp <rupp@gnat.com> + + * dwarf2out.c (output_file_names): Test new macro + DWARF2_DIR_SHOULD_END_WITH_SEPARATOR. + (add_comp_dir_attribute): Likewise. + +2009-07-28 Kai Tietz <kai.tietz@onevision.com> + + * config/i386/mingw-w64.h (LINK_SPEC): Add + separating space between commands. + +2009-07-28 Jan Hubicka <jh@suse.cz> + + PR tree-optimization/40759 + * tree-ssa-dce.c (mark_virtual_phi_result_for_renaming): Mark all uses + for renaming. + +2009-07-27 DJ Delorie <dj@redhat.com> + + * config/mep/mep.c (mep_expand_builtin_saveregs): Make sure 64-bit + types are dword-aligned. + (mep_expand_va_start): Likewise. + +2009-07-27 Olivier Hainque <hainque@adacore.com> + Douglas B Rupp <rupp@gnat.com> + + * convert.c (convert_to_pointer): Don't assume the target + pointer type is POINTER_SIZE long. Fetch its precision instead. + +2009-07-27 Douglas B Rupp <rupp@gnat.com> + + * system.h (fopen): Undefine if macro. + +2009-07-27 Jakub Jelinek <jakub@redhat.com> + + * dwarf2out.c (output_cfi_p): Removed. + (output_cfis): New function. + (output_fde): New function, split from output_call_frame_info. + (output_call_frame_info): Use it. + (dwarf2out_switch_text_section): Use output_cfis. + +2009-07-24 Kai Tietz <kai.tietz@onevision.com> + + * config/i386/cygming.h (DWARF2_UNWIND_INFO): Error build when + TARGET_BI_ARCH is specified without enabling SJLJ. + * config/i386/mingw32.h (MD_UNWIND_SUPPORT): Define MD_UNWIND_SUPPORT, + if TARGET_64BIT and TARGET_BI_ARCH aren't defined. + +2009-07-26 Mikael Pettersson <mikpe@it.uu.se> + + * arm.md (negdi2): Use DImode if forcing a value into a register. + 2009-07-26 Ira Rosen <irar@il.ibm.com> PR tree-optimization/40801 @@ -31,8 +634,7 @@ 2009-07-25 David Daney <ddaney@caviumnetworks.com> - * cfgcleanup.c (old_insns_match_p): Handle the case of empty - blocks. + * cfgcleanup.c (old_insns_match_p): Handle the case of empty blocks. 2009-07-25 Martin Jambor <mjambor@suse.cz> 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 45221d3810b..ceb6e65bab9 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20090727 +20090731 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 3af8d54d59e..f88c8ab21e5 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1196,6 +1196,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 \ @@ -1269,6 +1277,7 @@ OBJS-common = \ sel-sched-ir.o \ sel-sched-dump.o \ sel-sched.o \ + sese.o \ simplify-rtx.o \ sparseset.o \ sreal.o \ @@ -1618,9 +1627,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 @@ -1637,9 +1672,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 @@ -2384,7 +2420,7 @@ tree-ssa-loop-manip.o : tree-ssa-loop-manip.c $(TREE_FLOW_H) $(CONFIG_H) \ $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) $(TM_P_H) hard-reg-set.h \ $(BASIC_BLOCK_H) output.h $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) \ $(TIMEVAR_H) $(CFGLOOP_H) $(TREE_PASS_H) $(CFGLAYOUT_H) \ - $(SCEV_H) $(PARAMS_H) $(TREE_INLINE_H) + $(SCEV_H) $(PARAMS_H) $(TREE_INLINE_H) langhooks.h tree-ssa-loop-im.o : tree-ssa-loop-im.c $(TREE_FLOW_H) $(CONFIG_H) \ $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) domwalk.h \ $(PARAMS_H) output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h \ @@ -2451,11 +2487,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..79e11042dac 100644 --- a/gcc/aclocal.m4 +++ b/gcc/aclocal.m4 @@ -1,7 +1,7 @@ -# generated automatically by aclocal 1.9.6 -*- Autoconf -*- +# generated automatically by aclocal 1.10.2 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005 Free Software Foundation, Inc. +# 2005, 2006, 2007, 2008 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. @@ -64,13 +64,14 @@ AC_PREREQ([2.50])dnl am_aux_dir=`cd $ac_aux_dir && pwd` ]) -# Copyright (C) 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# 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. -# serial 3 +# serial 6 # AM_PROG_CC_C_O # -------------- @@ -78,11 +79,13 @@ am_aux_dir=`cd $ac_aux_dir && pwd` AC_DEFUN([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC_C_O])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC -ac_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` -if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then +am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. @@ -90,8 +93,17 @@ if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi +dnl Make sure AC_PROG_CC is never called again, or it will override our +dnl setting of CC. +m4_define([AC_PROG_CC], + [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) ]) +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 +117,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 fba1a74a6c1..35aa5423619 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,4 +1,399 @@ -2009-07-16 Dave Korn <dave.korn.cygwin@gmail.com> +2009-07-30 Ben Brosgol <brosgol@adacore.com> + + * gnat_ugn.texi: Correct minor texi glitch. + +2009-07-30 Ed Schonberg <schonberg@adacore.com> + + * exp_util.adb (Expand_Subtype_From_Expr): If the type of the + expression has an underlying representation that is an unchecked union, + there is no subtype to build. + +2009-07-30 Robert Dewar <dewar@adacore.com> + + * a-teioed.adb, exp_disp.adb, s-linux-hppa.ads, s-linux.ads, + s-tasini.adb, sem_ch13.adb, sem_ch3.adb, sem_ch3.ads, sem_ch6.adb, + sem_ch7.adb, adaint.c: Minor reformatting + +2009-07-29 Javier Miranda <miranda@adacore.com> + + * sem_ch3.ads, sem_ch3.adb (Add_Internal_Interface_Entities): Routine + moved from the expander to the semantic analyzer to allow the + generation of these internal entities when compiling with no code + generation. Required by ASIS. + * sem.adb (Analyze): Add processing for N_Freeze_Entity nodes. + * sem_ch13.ads, sem_ch13.adb (Analyze_Freeze_Entity): New subprogram. + * exp_ch3.adb (Add_Internal_Interface_Entities): Moved to sem_ch3 + (Expand_Freeze_Record_Type): Remove call to + Add_Internal_Interface_Entities because this routine is now called at + early stage --when the freezing node is analyzed. + +2009-07-29 Robert Dewar <dewar@adacore.com> + + * exp_atag.ads, exp_atag.adb, s-tasini.adb, s-soflin.ads, + exp_disp.adb, g-socket.adb: Minor reformatting + +2009-07-29 Ed Schonberg <schonberg@adacore.com> + + * sem_ch7.adb (New_Private_Type): Create class-wide type after other + attributes have been established, so that they are all inherited by the + class-wide type. + * sem_cat.adb (Validate_Remote_Access_Object_Type_Declaration): Handle + properly named subtypes of class-wide types. + +2009-07-29 Ed Schonberg <schonberg@adacore.com> + + * sem_ch6.adb (Check_Overriding_Indicator): Handle properly overriding + indicators on user-defined operators. + +2009-07-29 Vadim Godunko <godunko@adacore.com> + + * g-socket.adb (Receive_Vector): Add comment. + +2009-07-29 Javier Miranda <miranda@adacore.com> + + * frontend.adb (Frontend): Code cleanup. + * exp_atag.ads, exp_atag.adb (Build_Get_Predefined_Prim_Op_Address): + Rewriten as a procedure because it a new out-mode parameters to + keep up-to-date the controlling tag node in the caller. + (Build_Get_Prim_Op_Address): Rewriten as a procedure because it has a + new out-mode parameter to keep up-to-date the controlling tag node in + the caller. + * exp_ch7.adb, sem_ch5.adb, exp_util.adb, sem_util.adb, exp_ch4.adb, + exp_ch6.adb, sem_ch4.adb, exp_ch3.adb: Add new dependency on new + package Sem_SCIL. + * sem_aux.ads, sem_aux.adb (First_Non_SCIL_Node): Removed. Routine + available in new package Sem_SCIL. + (Next_Non_SCIL_Node): Ditto. + * exp_disp.adb (Adjust_SCIL_Node): Removed. Routine available in new + package Sem_SCIL. + (Expand_Dispatching_Call): Update call to modified Exp_Atags routines + plus complete decoration of SCIL dispatching node. + (Find_SCIL_Node): Removed. Routine available in new package Sem_SCIL. + * exp_disp.ads (Adjust_SCIL_Node): Removed. Routine available in new + package Sem_SCIL. + (Find_SCIL_Node): Removed. Routine available in new package Sem_SCIL. + * exp_ch3.adb (Build_Init_Procedure): Fix comment. + * sem_scil.ads, sem_scil.adb: New files. + * gcc-interface/Make-lang.in (GNAT_ADA_OBJS): Addition of sem_scil.o. + Update dependencies. + +2009-07-28 Robert Dewar <dewar@adacore.com> + + * adaint.h, einfo.ads, prj.adb, sem_util.adb, makeutl.ads, + makeutl.adb: Minor reformatting & code reorganization + * sem_ch3.adb: Minor reformatting. + Fix spelling error (constraint for constrain) in error msg. + +2009-07-28 Emmanuel Briot <briot@adacore.com> + + * make.adb, makeutl.adb, makeutl.ads (Project_Tree): Duplicates the + global variable that also exists in makeutl.ads, and that some routines + in that package use already. + (Check): Moved part of the code to makeutl.adb for better sharing with + gprbuild. + +2009-07-28 Arnaud Charlet <charlet@adacore.com> + + * gcc-interface/Make-lang.in: Update dependencies. + +2009-07-28 Emmanuel Briot <briot@adacore.com> + + * prj.adb, prj.ads (Compute_All_Imported_Projects): Make sure the + importing project does not end up in the list, in the case of extending + projects. + * make.adb, makeutl.adb, makeutl.ads (File_Not_A_Source_Of): Moved to + makeutl.ads, for better sharing with gprbuild. + +2009-07-28 Arnaud Charlet <charlet@adacore.com> + + * gnat_ugn.texi: Fix typo. + +2009-07-28 Ed Schonberg <schonberg@adacore.com> + + * sem_ch3.adb (Build_Derived_Concurrent_Type): Handle properly a + derivation that renames some discriminants and constrain others. + * exp_ch9.adb (Build_Protected_Subprogram_Call): If the type of the + prefix is a derived untagged type, convert to the root type to conform + to the signature of the protected operations. + +2009-07-28 Robert Dewar <dewar@adacore.com> + + * sinfo.ads: Update comments. + * exp_attr.adb: Minor reformatting + +2009-07-28 Ed Schonberg <schonberg@adacore.com> + + * sem_aggr.adb (Get_Value): A named association in a record aggregate + should be treated as a modification of the named component, not as a + reference. + +2009-07-28 Quentin Ochem <ochem@adacore.com> + + * prj-tree.ads, prj-tree.adb (Free): Minor editing. + * prj.ads, prj.adb (Image): Ditto. + +2009-07-28 Arnaud Charlet <charlet@adacore.com> + + * frontend.adb: Minor reformatting. + (Frontend): Only call Check_SCIL_Nodes if assertions are enabled, + for efficiency. + +2009-07-28 Bob Duff <duff@adacore.com> + + * exp_attr.adb (Expand_Access_To_Protected_Op): Use 'Access instead of + 'Address to get a pointer to the protected body wrapper. + +2009-07-28 Javier Miranda <miranda@adacore.com> + + * gnat1drv.adb (Adjust_Global_Switches): Disable generation of SCIL + nodes if we are not generating code. + * frontend.adb (Check_SCIL_Node): New subprogram. Used to check + attribute SCIL_Related_Node of SCIL dispatching nodes. + (Check_SCIL_Nodes): New instantiation of Traverse_Proc. + * sinfo.ads (Is_SCIL_Node,Set_Is_SCIL_Node): Removed + (SCIL_Nkind,Set_SCIL_Nkind): Removed. + (SCIL_Entity): Update documentation. + (SCIL_Related_Node): Update documentation. + (SCIL_Controlling_Tag): New attribute. + (SCIL_Target_Prim): Update documentation. + (N_Null_Statement): Remove attributes associated with SCIL nodes. + (N_SCIL_Dispatch_Table_Object_Init): New node. + (N_SCIL_Dispatch_Table_Tag_Init): New node. + (N_SCIL_Dispatching_Call): New node. + (N_SCIL_Tag_Init): New node. + * sinfo.adb (Is_SCIL_Node,Set_Is_SCIL_Node): Removed + (SCIL_Nkind,Set_SCIL_Nkind): Removed. + (SCIL_Controlling_Tag/Set_SCIL_Controlling_Tag): New subprogram. + (SCIL_Entity,Set_SCIL_Entity): Applicable only to SCIL nodes. + (SCIL_Related_Node,Set_SCIL_Related_Node): Applicable only to SCIL nodes + (SCIL_Target_Prim,Set_SCIL_Target_Prim): Applicable only to + N_SCIL_Dispatching_Call nodes. + * sem.adb (Analyze): No need to analyze SCIL nodes. + * sem_aux.ads, sem_aux.adb (First_Non_SCIL_Node): New subprogram + (Next_Non_SCIL_Node): New subprogram + * sem_ch4.adb (Analyze_Type_Conversion): Adjust relocated SCIL + dispatching nodes. + * sem_ch5.adb (Analyze_Iteration_Scheme): Adjust relocated SCIL + dispatching node. + * sem_util.adb (Insert_Explicit_Dereference): Adjust relocated SCIL + dispatching node. + * exp_ch3.adb (Build_Array_Init_Proc): Skip SCIL nodes when processing + null statement nodes. + (Build_Init_Procedure): Generate new SCIL node. + * exp_ch4.adb (Expand_N_And_Then): Adjust relocated SCIL dispatching + node. + * exp_ch6.adb (Is_Null_Procedure): Skip SCIL nodes. Required because + they are currently implemented as special N_Null_Statement nodes. + * exp_ch7.adb (Wrap_Transient_Statement): If the relocated node is a + procedure call then check if some SCIL node references it and needs + readjustment. + * exp_disp.ads (SCIL_Node_Kind): Removed. + (Adjust_SCIL_Node): New subprogram. + (Find_SCIL_Node): New subprogram. + (Get_SCIL_Node_Kind): Removed. + (New_SCIL_Node): Removed. + * exp_disp.adb (Adjust_SCIL_Node): New subprogram + (Expand_Dispatching_Call): Generate new SCIL dispatching node including + decoration of its new controlling_tag attribute. + (Get_SCIL_Node_Kind): Removed. + (Find_SCIL_Node): New subprogram. + (Make_Secondary_DT): Generate new SCIL nodes. + (Make_Tags): Generate new SCIL nodes. + (New_SCIL_Node): Removed. + * exp_util.adb (Insert_Actions): Handle SCIL nodes. + (Remove_Side_Effects): Check if relocated nodes require readjustment + of some SCIL dispatching node. + * gcc-interface/trans.c (gnat_to_gnu): Do nothing with new SCIL nodes. + +2009-07-28 Robert Dewar <dewar@adacore.com> + + * prj-nmsc.adb, g-expect.adb, prj.ads: Minor reformatting + +2009-07-28 Sergey Rybin <rybin@adacore.com> + + * gnat_ugn.texi: Add section about gnatcheck rule exemption. + +2009-07-28 Vadim Godunko <godunko@adacore.com> + + * s-oscons-tmplt.c: Define _XOPEN_SOURCE on Linux, otherwise IOV_MAX is + not defined by limits.h. + + * g-socket.adb (Receive_Vector): Use minimum length from user's vector + length and maximum supported length of data vector. + +2009-07-28 Gary Dismukes <dismukes@adacore.com> + + * usage.adb: Inhibit printing gcc-specific switches for AAMP target. + * make.adb: Call Get_Target_Parameters before calling Usage so that + VM_Target and AAMP_On_Target will be set. + +2009-07-28 Olivier Hainque <hainque@adacore.com> + + * g-ssinty.ads: Remove, pointless and just confusing at this stage. + * gnat_rm.texi: Remove documentation. + * g-sse.ads: Minor reorg along the way. + * gcc-interface/Makefile.in: Remove processing for g-ssinty. + * g-ssvety.ads: Minor comment updates. + +2009-07-28 Sergey Rybin <rybin@adacore.com> + + * gnat_ugn.texi: gnatcheck 'Format of the Report File' section - update + for the new format of the report file. + +2009-07-28 Sergey Rybin <rybin@adacore.com> + + * gnat_ugn.texi: gnatcheck Deeply_Nested_Inlining rule: Update doc. + +2009-07-28 Pascal Obry <obry@adacore.com> + + * g-expect.adb: Record standard handles only on Windows. + +2009-07-27 Emmanuel Briot <briot@adacore.com> + + * prj.ads, prj-nmsc.adb (Override_Kind): add debug trace + Add comments. + +2009-07-27 Sergey Rybin <rybin@adacore.com> + + * gnat_ugn.texi: gnatcheck Unconstrained_Array_Returns rule: Add to the + rule definition the paragraph that explains that generic functions and + functions from generic packages are not checked. + +2009-07-27 Gary Dismukes <dismukes@adacore.com> + + * sem_ch6.adb (New_Overloaded_Entity): Add test for an expanded null + procedure when determining whether to set the Overridden_Operation + field of a subprogram overriding an inherited subprogram. + +2009-07-27 Robert Dewar <dewar@adacore.com> + + * a-except.adb, a-except-2005.ads: Minor reformatting + +2009-07-27 Robert Dewar <dewar@adacore.com> + + * sem_util.adb, sem_util.ads (Kill_Current_Values): Reset Is_Known_Valid + +2009-07-27 Javier Miranda <miranda@adacore.com> + + * exp_disp.adb (Expand_Dispatching_Call): Reverse previous patch and + add some documentation explaining why the SCIL nodes must be generated + at that point. + +2009-07-27 Olivier Hainque <hainque@adacore.com> + + * a-except.adb: Bind to __builtin_longjmp directly. + * a-except-2005.ads: Provide direct binding to __builtin_longjmp + for sjlj variants. + * a-exexpr.adb: Use it. + * a-except-xi.adb: Likewise. + * raise.c (_gnat_builtin_longjmp): Remove and update comments. + * raise.h (_gnat_builtin_longjmp): Remove declaration. + +2009-07-27 Ed Schonberg <schonberg@adacore.com> + + * sem_eval.adb (Compile_Time_Compare): More precise handling of + Known_Valid flag, to prevent spurious range deductions when scalar + variables may be uninitialized. New predicate Is_Known_Valid_Operand. + +2009-07-27 Robert Dewar <dewar@adacore.com> + + * gnatfind.adb, osint.ads, sem.adb, xr_tabls.adb: Minor reformatting + and code clean up. + +2009-07-27 Ed Schonberg <schonberg@adacore.com> + + * exp_ch9.adb (Expand_N_Timed_Entry_Call): Do not attempt expansion in + Ravenscar mode. Error has already been posted on specification. + + * sem.adb: Further code clean ups. + +2009-07-27 Robert Dewar <dewar@adacore.com> + + * g-sse.ads: Minor reformatting + +2009-07-27 Arnaud Charlet <charlet@adacore.com> + + * xref_lib.adb (Add_Xref_File_Internal, Find_ALI_Files): Add support for + alternate ali extension. + * xr_tabls.adb (ALI_File_Name, Get_File, Set_Unvisited): Take into + account Osint.ALI_Suffix. + * osint.ads (ALI_Suffix): Make visible. + * gnatfind.adb (Gnatfind): Add support for --ext= switch. + * gnat_ugn.texi: Document new gnatfind --ext= switch. + +2009-07-27 Ed Schonberg <schonberg@adacore.com> + + * sem.adb (Walk_Library_Items): If main unit is an instance body, do + its spec first. + +2009-07-27 Javier Miranda <miranda@adacore.com> + + * exp_disp.adb (Expand_Dispatching_Call): Generate the SCIL node after + the dispatching call has is expanded. + +2009-07-27 Ed Schonberg <schonberg@adacore.com> + + * exp_attr.adb (Expand_Attribute_Reference, case 'Valid): Reset the + Is_Known_Valid flag on the temporary created for the value whose + validity is being checked. + + * sem.adb (Do_Unit_And_Dependents): Further code reorganization to + handle properly main units that are package specifications. + +2009-07-27 Geert Bosch <bosch@adacore.com> + + * einfo.ads (Checks_May_Be_Suppressed): Fix typo in comment + * sem_aux.ads: Fix typo in comment + * sem_util.ads (Is_LHS): Adjust comment to match body + +2009-07-27 Sergey Rybin <rybin@adacore.com> + + * gnat_ugn.texi (gnatcheck Complex_Inlined_Subprograms rule): Update + rule definition. + +2009-07-27 Olivier Hainque <hainque@adacore.com> + + * g-sse.ads, g-ssvety.ads: Update comments. + +2009-07-27 Sergey Rybin <rybin@adacore.com> + + * gnat_ugn.texi: Update gnatcheck doc. + +2009-07-27 Arnaud Charlet <charlet@adacore.com> + + * lib-xref.ads: Allocate/document 'o' char for use by references to + spark 'own' variables. + +2009-07-27 Gary Dismukes <dismukes@adacore.com> + + * sem_ch6.adb (Analyze_Function_Return): Set Referenced on return + objects, since these are implicitly referenced by the return statement. + * sem_warn.adb (Warn_On_Unreferenced_Entity): No longer a need to test + Is_Return_Object in this procedure, as return objects will never make + it here since they're now marked as Referenced. + +2009-07-27 Robert Dewar <dewar@adacore.com> + + * exp_ch2.adb, sem_util.adb, sem_util.ads: Minor reformnatting + +2009-07-27 Robert Dewar <dewar@adacore.com> + + * exp_ch6.adb (Expand_Call): Reset Is_Known_Valid after call + + * sem_ch3.adb, sem_eval.adb, sem_aux.adb: Minor comment reformatting + +2009-07-27 Geert Bosch <bosch@adacore.com> + + * checks.adb (Find_Check): Minor streamlining of logic. + * gnat1drv.adb(Gnat1drv): Put Check_Rep_Info in its alphabetical order. + * debug.adb: Document -gnatdX debug flag + * exp_ch2.adb(Expand_Entity_Reference): Implement new -gnatdX flag to + list information about reads from scalar entities. + Also slightly simplify condition for Expand_Current_Value. + * sem_util.ads, sem_util.adb (Is_LHS, Is_Actual_Out_Parameter): New + functions. + +2009-07-26 Dave Korn <dave.korn.cygwin@gmail.com> PR bootstrap/40578 * adaint.h (FOPEN, STAT, FSTAT, LSTAT, STRUCT_STAT): Rename from these @@ -360,7 +755,7 @@ * vms_data.ads: Add entry for SCO_OUTPUT (-gnateS) * gnat_ugn.texi: Add documentation for -gnateS switch * ug_words: Add entry for -gnateS /SCO_OUTPUT - * gcc-interface/Make-lang.in: Update dependenciest.3 + * gcc-interface/Make-lang.in: Update dependencies. * get_scos.adb, get_scos.ads, gnat1drv.adb, par_sco.adb, par_sco.ads, put_scos.adb, put_scos.ads, scos.adb, scos.ads: Initial diff --git a/gcc/ada/a-except-2005.ads b/gcc/ada/a-except-2005.ads index 0b248ff9879..033244dcd92 100644 --- a/gcc/ada/a-except-2005.ads +++ b/gcc/ada/a-except-2005.ads @@ -50,6 +50,8 @@ with System.Parameters; with System.Standard_Library; with System.Traceback_Entries; +with Ada.Unchecked_Conversion; + package Ada.Exceptions is pragma Warnings (Off); pragma Preelaborate_05; @@ -113,7 +115,9 @@ package Ada.Exceptions is -- 0xyyyyyyyy 0xyyyyyyyy ... -- -- The lines are separated by a ASCII.LF character - -- The nnnn is the partition Id given as decimal digits. + -- + -- The nnnn is the partition Id given as decimal digits + -- -- The 0x... line represents traceback program counter locations, -- in order with the first one being the exception location. @@ -182,13 +186,13 @@ private pragma Export (Ada, Current_Target_Exception, "__gnat_current_target_exception"); - -- This routine should return the current raised exception on targets - -- which have built-in exception handling such as the Java Virtual - -- Machine. For other targets this routine is simply ignored. Currently, - -- only JGNAT uses this. See 4jexcept.ads for details. The pragma Export - -- allows this routine to be accessed elsewhere in the run-time, even - -- though it is in the private part of this package (it is not allowed - -- to be in the visible part, since this is set by the reference manual). + -- This routine should return the current raised exception on targets which + -- have built-in exception handling such as the Java Virtual Machine. For + -- other targets this routine is simply ignored. Currently, only JGNAT + -- uses this. See 4jexcept.ads for details. The pragma Export allows this + -- routine to be accessed elsewhere in the run-time, even though it is in + -- the private part of this package (it is not allowed to be in the visible + -- part, since this is set by the reference manual). function Exception_Name_Simple (X : Exception_Occurrence) return String; -- Like Exception_Name, but returns the simple non-qualified name of the @@ -228,8 +232,8 @@ private procedure Raise_From_Controlled_Operation (X : Ada.Exceptions.Exception_Occurrence); pragma No_Return (Raise_From_Controlled_Operation); - -- Raise Program_Error, providing information about X (an exception - -- raised during a controlled operation) in the exception message. + -- Raise Program_Error, providing information about X (an exception raised + -- during a controlled operation) in the exception message. procedure Reraise_Occurrence_Always (X : Exception_Occurrence); pragma No_Return (Reraise_Occurrence_Always); @@ -242,8 +246,8 @@ private pragma No_Return (Reraise_Occurrence_No_Defer); -- Exactly like Reraise_Occurrence, except that abort is not deferred -- before the call and the parameter X is known not to be the null - -- occurrence. This is used in generated code when it is known that - -- abort is already deferred. + -- occurrence. This is used in generated code when it is known that abort + -- is already deferred. ----------------------- -- Polling Interface -- @@ -285,6 +289,7 @@ private type Exception_Occurrence is record Id : Exception_Id; -- Exception_Identity for this exception occurrence + -- -- WARNING System.System.Finalization_Implementation.Finalize_List -- relies on the fact that this field is always first in the exception -- occurrence @@ -348,4 +353,18 @@ private Tracebacks => (others => TBE.Null_TB_Entry), Private_Data => System.Null_Address); + -- Common binding to __builtin_longjmp for sjlj variants. + + -- The builtin expects a pointer type for the jmpbuf address argument, and + -- System.Address doesn't work because this is really an integer type. + + type Jmpbuf_Address is access Character; + + function To_Jmpbuf_Address is new + Ada.Unchecked_Conversion (System.Address, Jmpbuf_Address); + + procedure builtin_longjmp (buffer : Jmpbuf_Address; Flag : Integer); + pragma No_Return (builtin_longjmp); + pragma Import (Intrinsic, builtin_longjmp, "__builtin_longjmp"); + end Ada.Exceptions; diff --git a/gcc/ada/a-except.adb b/gcc/ada/a-except.adb index cf04fd46f3e..c9fe38b466e 100644 --- a/gcc/ada/a-except.adb +++ b/gcc/ada/a-except.adb @@ -57,9 +57,9 @@ with System.Soft_Links; use System.Soft_Links; package body Ada.Exceptions is pragma Suppress (All_Checks); - -- We definitely do not want exceptions occurring within this unit, or - -- we are in big trouble. If an exceptional situation does occur, better - -- that it not be raised, since raising it can cause confusing chaos. + -- We definitely do not want exceptions occurring within this unit, or we + -- are in big trouble. If an exceptional situation does occur, better that + -- it not be raised, since raising it can cause confusing chaos. ----------------------- -- Local Subprograms -- @@ -77,14 +77,14 @@ package body Ada.Exceptions is procedure To_Stderr (S : String); pragma Export (Ada, To_Stderr, "__gnat_to_stderr"); - -- Little routine to output string to stderr that is also used - -- in the tasking run time. + -- Little routine to output string to stderr that is also used in the + -- tasking run time. procedure To_Stderr (C : Character); pragma Inline (To_Stderr); pragma Export (Ada, To_Stderr, "__gnat_to_stderr_char"); - -- Little routine to output a character to stderr, used by some of - -- the separate units below. + -- Little routine to output a character to stderr, used by some of the + -- separate units below. package Exception_Data is @@ -109,9 +109,9 @@ package body Ada.Exceptions is (Id : Exception_Id; Message : String); -- This routine is called to setup the exception referenced by the - -- Current_Excep field in the TSD to contain the indicated Id value - -- and message. Message is a string which is generated as the - -- exception message. + -- Current_Excep field in the TSD to contain the indicated Id value and + -- message. Message is a string which is generated as the exception + -- message. -------------------------------------- -- Exception information subprogram -- @@ -126,18 +126,20 @@ package body Ada.Exceptions is -- Call stack traceback locations: (only if at least one location) -- <0xyyyyyyyy 0xyyyyyyyy ...> (is recorded) -- - -- The lines are separated by a ASCII.LF character. - -- The nnnn is the partition Id given as decimal digits. + -- The lines are separated by a ASCII.LF character + -- + -- The nnnn is the partition Id given as decimal digits + -- -- The 0x... line represents traceback program counter locations, in -- execution order with the first one being the exception location. It -- is present only -- - -- The Exception_Name and Message lines are omitted in the abort - -- signal case, since this is not really an exception. + -- The Exception_Name and Message lines are omitted in the abort signal + -- case, since this is not really an exception. - -- !! If the format of the generated string is changed, please note - -- !! that an equivalent modification to the routine String_To_EO must - -- !! be made to preserve proper functioning of the stream attributes. + -- Note: If the format of the generated string is changed, please note + -- that an equivalent modification to the routine String_To_EO must be + -- made to preserve proper functioning of the stream attributes. --------------------------------------- -- Exception backtracing subprograms -- @@ -198,11 +200,11 @@ package body Ada.Exceptions is procedure Unhandled_Exception_Terminate; pragma No_Return (Unhandled_Exception_Terminate); - -- This procedure is called to terminate execution following an - -- unhandled exception. The exception information, including - -- traceback if available is output, and execution is then - -- terminated. Note that at the point where this routine is - -- called, the stack has typically been destroyed. + -- This procedure is called to terminate program execution following an + -- unhandled exception. The exception information, including traceback + -- if available is output, and execution is then terminated. Note that + -- at the point where this routine is called, the stack has typically + -- been destroyed. end Exception_Traces; @@ -253,10 +255,10 @@ package body Ada.Exceptions is procedure Raise_With_Msg (E : Exception_Id); pragma No_Return (Raise_With_Msg); pragma Export (C, Raise_With_Msg, "__gnat_raise_with_msg"); - -- Raises an exception with given exception id value. A message - -- is associated with the raise, and has already been stored in the - -- exception occurrence referenced by the Current_Excep in the TSD. - -- Abort is deferred before the raise call. + -- Raises an exception with given exception id value. A message is + -- associated with the raise, and has already been stored in the exception + -- occurrence referenced by the Current_Excep in the TSD. Abort is deferred + -- before the raise call. procedure Raise_With_Location_And_Msg (E : Exception_Id; @@ -266,8 +268,8 @@ package body Ada.Exceptions is pragma No_Return (Raise_With_Location_And_Msg); -- Raise an exception with given exception id value. A filename and line -- number is associated with the raise and is stored in the exception - -- occurrence and in addition a string message M is appended to - -- this (if M is not null). + -- occurrence and in addition a string message M is appended to this + -- if M is not null. procedure Raise_Constraint_Error (File : System.Address; @@ -344,9 +346,9 @@ package body Ada.Exceptions is procedure Reraise; pragma No_Return (Reraise); pragma Export (C, Reraise, "__gnat_reraise"); - -- Reraises the exception referenced by the Current_Excep field of - -- the TSD (all fields of this exception occurrence are set). Abort - -- is deferred before the reraise operation. + -- Reraises the exception referenced by the Current_Excep field of the TSD + -- (all fields of this exception occurrence are set). Abort is deferred + -- before the reraise operation. -- Save_Occurrence variations: As the management of the private data -- attached to occurrences is delicate, whether or not pointers to such @@ -373,11 +375,10 @@ package body Ada.Exceptions is -- Run-Time Check Routines -- ----------------------------- - -- These routines raise a specific exception with a reason message - -- attached. The parameters are the file name and line number in each - -- case. The names are keyed to the codes defined in types.ads and - -- a-types.h (for example, the name Rcheck_05 refers to the Reason - -- RT_Exception_Code'Val (5)). + -- Routines to a specific exception with a reason message attached. The + -- parameters are the file name and line number in each case. The names are + -- keyed to the codes defined in types.ads and a-types.h (for example, the + -- name Rcheck_05 refers to the Reason RT_Exception_Code'Val (5)). procedure Rcheck_00 (File : System.Address; Line : Integer); procedure Rcheck_01 (File : System.Address; Line : Integer); @@ -546,8 +547,8 @@ package body Ada.Exceptions is -- perform periodic but not systematic operations. procedure Poll is separate; - -- The actual polling routine is separate, so that it can easily - -- be replaced with a target dependent version. + -- The actual polling routine is separate, so that it can easily be + -- replaced with a target dependent version. ------------------------------ -- Current_Target_Exception -- @@ -569,8 +570,8 @@ package body Ada.Exceptions is -- EO_To_String -- ------------------ - -- We use the null string to represent the null occurrence, otherwise - -- we output the Exception_Information string for the occurrence. + -- We use the null string to represent the null occurrence, otherwise we + -- output the Exception_Information string for the occurrence. function EO_To_String (X : Exception_Occurrence) return String renames Stream_Attributes.EO_To_String; @@ -583,9 +584,9 @@ package body Ada.Exceptions is (X : Exception_Occurrence) return Exception_Id is begin - -- Note that the following test used to be here for the original - -- Ada 95 semantics, but these were modified by AI-241 to require - -- returning Null_Id instead of raising Constraint_Error. + -- Note that the following test used to be here for the original Ada 95 + -- semantics, but these were modified by AI-241 to require returning + -- Null_Id instead of raising Constraint_Error. -- if X.Id = Null_Id then -- raise Constraint_Error; @@ -667,8 +668,8 @@ package body Ada.Exceptions is -------------------- package body Exception_Data is separate; - -- This package can be easily dummied out if we do not want the - -- basic support for exception messages (such as in Ada 83). + -- This package can be easily dummied out if we do not want the basic + -- support for exception messages (such as in Ada 83). package body Exception_Propagation is @@ -691,10 +692,10 @@ package body Ada.Exceptions is ---------------------- package body Exception_Traces is separate; - -- Depending on the underlying support for IO the implementation - -- will differ. Moreover we would like to dummy out this package - -- in case we do not want any exception tracing support. This is - -- why this package is separated. + -- Depending on the underlying support for IO the implementation will + -- differ. Moreover we would like to dummy out this package in case we do + -- not want any exception tracing support. This is why this package is + -- separated. ----------------------- -- Stream Attributes -- @@ -720,17 +721,17 @@ package body Ada.Exceptions is pragma Import (C, builtin_longjmp, "_gnat_builtin_longjmp"); begin - -- WARNING: There should be no exception handler for this body - -- because this would cause gigi to prepend a setup for a new - -- jmpbuf to the sequence of statements in case of built-in sjljl. - -- We would then always get this new buf in Jumpbuf_Ptr instead of the - -- one for the exception we are handling, which would completely break - -- the whole design of this procedure. + -- WARNING: There should be no exception handler for this body because + -- this would cause gigi to prepend a setup for a new jmpbuf to the + -- sequence of statements in case of built-in sjljl. We would then + -- always get this new buf in Jumpbuf_Ptr instead of the one for the + -- exception we are handling, which would completely break the whole + -- design of this procedure. - -- If the jump buffer pointer is non-null, transfer control using - -- it. Otherwise announce an unhandled exception (note that this - -- means that we have no finalizations to do other than at the outer - -- level). Perform the necessary notification tasks in both cases. + -- If the jump buffer pointer is non-null, transfer control using it. + -- Otherwise announce an unhandled exception (note that this means that + -- we have no finalizations to do other than at the outer level). + -- Perform the necessary notification tasks in both cases. if Jumpbuf_Ptr /= Null_Address then if not Excep.Exception_Raised then @@ -1251,9 +1252,9 @@ package body Ada.Exceptions is begin -- Setup Target as an exception to be propagated in the calling task -- (rendezvous-wise), taking care not to clobber the associated private - -- data. Target is expected to be a pointer to the calling task's - -- fixed TSD occurrence, which is very different from Get_Current_Excep - -- here because this subprogram is called from the called task. + -- data. Target is expected to be a pointer to the calling task's fixed + -- TSD occurrence, which is very different from Get_Current_Excep here + -- because this subprogram is called from the called task. Save_Occurrence_No_Private (Target.all, Source); end Transfer_Occurrence; @@ -1293,7 +1294,6 @@ package body Ada.Exceptions is --------------- procedure To_Stderr (C : Character) is - type int is new Integer; procedure put_char_stderr (C : int); diff --git a/gcc/ada/a-exexpr.adb b/gcc/ada/a-exexpr.adb index 13b7d798328..e3ae5b01cff 100644 --- a/gcc/ada/a-exexpr.adb +++ b/gcc/ada/a-exexpr.adb @@ -41,10 +41,6 @@ pragma Warnings (Off); separate (Ada.Exceptions) package body Exception_Propagation is - procedure builtin_longjmp (buffer : Address; Flag : Integer); - pragma No_Return (builtin_longjmp); - pragma Import (C, builtin_longjmp, "_gnat_builtin_longjmp"); - --------------------- -- Setup_Exception -- --------------------- @@ -114,7 +110,7 @@ package body Exception_Propagation is Exception_Traces.Notify_Handled_Exception; end if; - builtin_longjmp (Jumpbuf_Ptr, 1); + builtin_longjmp (To_Jmpbuf_Address (Jumpbuf_Ptr), 1); else Exception_Traces.Notify_Unhandled_Exception; diff --git a/gcc/ada/a-teioed.adb b/gcc/ada/a-teioed.adb index e2408a45194..cfe64c3b64e 100644 --- a/gcc/ada/a-teioed.adb +++ b/gcc/ada/a-teioed.adb @@ -71,16 +71,16 @@ package body Ada.Text_IO.Editing is case Picture (Picture_Index) is when '(' => - Int_IO.Get (Picture (Picture_Index + 1 .. Picture'Last), - Count, Last); + Int_IO.Get + (Picture (Picture_Index + 1 .. Picture'Last), Count, Last); if Picture (Last + 1) /= ')' then raise Picture_Error; end if; - -- In what follows note that one copy of the repeated - -- character has already been made, so a count of one is a - -- no-op, and a count of zero erases a character. + -- In what follows note that one copy of the repeated character + -- has already been made, so a count of one is a no-op, and a + -- count of zero erases a character. if Result_Index + Count - 2 > Result'Last then raise Picture_Error; diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c index 19bbf7075ee..c3405daaf44 100644 --- a/gcc/ada/adaint.c +++ b/gcc/ada/adaint.c @@ -3502,7 +3502,7 @@ __gnat_set_close_on_exec (int fd ATTRIBUTE_UNUSED, return -1; if (close_on_exec_p) return ! SetHandleInformation (h, HANDLE_FLAG_INHERIT, 0); - return ! SetHandleInformation (h, HANDLE_FLAG_INHERIT, + return ! SetHandleInformation (h, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); #else /* TODO: Unimplemented. */ diff --git a/gcc/ada/adaint.h b/gcc/ada/adaint.h index 471b5ab6b03..79a1e4eb4bd 100644 --- a/gcc/ada/adaint.h +++ b/gcc/ada/adaint.h @@ -43,10 +43,9 @@ #define Encoding_8bits 1 /* Standard 8bits, CP_ACP on Windows. */ #define Encoding_Unspecified 2 /* Based on GNAT_CODE_PAGE env variable. */ -/* Large file support. It is unclear what portable mechanism we can - use to determine at compile time what support the system offers for - large files. For now we just list the platforms we have manually - tested. */ +/* Large file support. It is unclear what portable mechanism we can use to + determine at compile time what support the system offers for large files. + For now we just list the platforms we have manually tested. */ #if defined (__GLIBC__) || defined (sun) || defined (__sgi) #define GNAT_FOPEN fopen64 diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb index e39e3e079a6..d1a2b460c90 100644 --- a/gcc/ada/checks.adb +++ b/gcc/ada/checks.adb @@ -4254,7 +4254,7 @@ package body Checks is -- Start of processing for Find_Check begin - -- Establish default, to avoid warnings from GCC + -- Establish default, in case no entry is found Check_Num := 0; @@ -4325,7 +4325,6 @@ package body Checks is -- If we fall through entry was not found - Check_Num := 0; return; end Find_Check; diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb index baa04293cd1..f60a67b5b40 100644 --- a/gcc/ada/debug.adb +++ b/gcc/ada/debug.adb @@ -87,7 +87,7 @@ package body Debug is -- dU Enable garbage collection of unreachable entities -- dV Enable viewing of all symbols in debugger -- dW Disable warnings on calls for IN OUT parameters - -- dX + -- dX Display messages on reads of potentially uninitialized scalars -- dY Enable configurable run-time mode -- dZ Generate listing showing the contents of the dispatch tables diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads index 7a17efd9f7a..6330dec57f2 100644 --- a/gcc/ada/einfo.ads +++ b/gcc/ada/einfo.ads @@ -491,7 +491,7 @@ package Einfo is -- Present in all entities. Set if a pragma Suppress or Unsuppress -- mentions the entity specifically in the second argument. If this -- flag is set the Global_Entity_Suppress and Local_Entity_Suppress --- tables must be consulted to determine if the is actually an active +-- tables must be consulted to determine if there actually is an active -- Suppress or Unsuppress pragma that applies to the entity. -- Class_Wide_Type (Node9) @@ -3192,7 +3192,7 @@ package Einfo is -- the case of an appearance of a simple variable that is not a renaming -- as the left side of an assignment in which case Referenced_As_LHS is -- set instead, or a similar appearance as an out parameter actual, in --- which case As_Out_Parameter_Parameter is set. +-- which case Referenced_As_Out_Parameter is set. -- Referenced_As_LHS (Flag36): -- Present in all entities. This flag is set instead of Referenced if a diff --git a/gcc/ada/exp_atag.adb b/gcc/ada/exp_atag.adb index c94b319ecc0..314258c3070 100644 --- a/gcc/ada/exp_atag.adb +++ b/gcc/ada/exp_atag.adb @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2006-2008, Free Software Foundation, Inc. -- +-- Copyright (C) 2006-2009, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -227,12 +227,22 @@ package body Exp_Atag is -- Build_Get_Predefined_Prim_Op_Address -- ------------------------------------------ - function Build_Get_Predefined_Prim_Op_Address + procedure Build_Get_Predefined_Prim_Op_Address (Loc : Source_Ptr; - Tag_Node : Node_Id; - Position : Uint) return Node_Id + Position : Uint; + Tag_Node : in out Node_Id; + New_Node : out Node_Id) is + Ctrl_Tag : Node_Id; + begin + Ctrl_Tag := Unchecked_Convert_To (RTE (RE_Address), Tag_Node); + + -- Unchecked_Convert_To relocates the controlling tag node and therefore + -- we must update it. + + Tag_Node := Expression (Ctrl_Tag); + -- Build code that retrieves the address of the dispatch table -- containing the predefined Ada primitives: -- @@ -240,7 +250,7 @@ package body Exp_Atag is -- To_Predef_Prims_Table_Ptr -- (To_Addr_Ptr (To_Address (Tag) - Predef_Prims_Offset).all); - return + New_Node := Make_Indexed_Component (Loc, Prefix => Unchecked_Convert_To (RTE (RE_Predef_Prims_Table_Ptr), @@ -257,7 +267,7 @@ package body Exp_Atag is Make_Identifier (Loc, Chars => Name_Op_Subtract)), Parameter_Associations => New_List ( - Unchecked_Convert_To (RTE (RE_Address), Tag_Node), + Ctrl_Tag, New_Reference_To (RTE (RE_DT_Predef_Prims_Offset), Loc)))))), Expressions => @@ -337,12 +347,15 @@ package body Exp_Atag is -- Build_Get_Prim_Op_Address -- ------------------------------- - function Build_Get_Prim_Op_Address + procedure Build_Get_Prim_Op_Address (Loc : Source_Ptr; Typ : Entity_Id; - Tag_Node : Node_Id; - Position : Uint) return Node_Id + Position : Uint; + Tag_Node : in out Node_Id; + New_Node : out Node_Id) is + New_Prefix : Node_Id; + begin pragma Assert (Position <= DT_Entry_Count (First_Tag_Component (Typ))); @@ -351,11 +364,18 @@ package body Exp_Atag is -- declaration required to convert the tag into a pointer to -- the prims_ptr table (see Freeze_Record_Type). - return + New_Prefix := + Unchecked_Convert_To + (Node (Last_Elmt (Access_Disp_Table (Typ))), Tag_Node); + + -- Unchecked_Convert_To relocates the controlling tag node and therefore + -- we must update it. + + Tag_Node := Expression (New_Prefix); + + New_Node := Make_Indexed_Component (Loc, - Prefix => - Unchecked_Convert_To - (Node (Last_Elmt (Access_Disp_Table (Typ))), Tag_Node), + Prefix => New_Prefix, Expressions => New_List (Make_Integer_Literal (Loc, Position))); end Build_Get_Prim_Op_Address; @@ -482,11 +502,15 @@ package body Exp_Atag is Position : Uint; Address_Node : Node_Id) return Node_Id is + Ctrl_Tag : Node_Id := Tag_Node; + New_Node : Node_Id; + begin + Build_Get_Prim_Op_Address (Loc, Typ, Position, Ctrl_Tag, New_Node); + return Make_Assignment_Statement (Loc, - Name => Build_Get_Prim_Op_Address - (Loc, Typ, Tag_Node, Position), + Name => New_Node, Expression => Address_Node); end Build_Set_Prim_Op_Address; diff --git a/gcc/ada/exp_atag.ads b/gcc/ada/exp_atag.ads index 2ac42a9d254..42ec4769c38 100644 --- a/gcc/ada/exp_atag.ads +++ b/gcc/ada/exp_atag.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2006-2008, Free Software Foundation, Inc. -- +-- Copyright (C) 2006-2009, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -61,23 +61,26 @@ package Exp_Atag is -- -- Generates: TSD (Tag).Access_Level - function Build_Get_Predefined_Prim_Op_Address + procedure Build_Get_Predefined_Prim_Op_Address (Loc : Source_Ptr; - Tag_Node : Node_Id; - Position : Uint) return Node_Id; + Position : Uint; + Tag_Node : in out Node_Id; + New_Node : out Node_Id); -- Given a pointer to a dispatch table (T) and a position in the DT, build -- code that gets the address of the predefined virtual function stored in - -- it (used for dispatching calls). + -- it (used for dispatching calls). Tag_Node is relocated. -- -- Generates: Predefined_DT (Tag).D (Position); - function Build_Get_Prim_Op_Address + procedure Build_Get_Prim_Op_Address (Loc : Source_Ptr; Typ : Entity_Id; - Tag_Node : Node_Id; - Position : Uint) return Node_Id; + Position : Uint; + Tag_Node : in out Node_Id; + New_Node : out Node_Id); -- Build code that retrieves the address of the virtual function stored in -- a given position of the dispatch table (used for dispatching calls). + -- Tag_Node is relocated. -- -- Generates: To_Tag (Tag).D (Position); diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb index 2df553c4585..d5cce9b43ee 100644 --- a/gcc/ada/exp_attr.adb +++ b/gcc/ada/exp_attr.adb @@ -235,6 +235,7 @@ package body Exp_Attr is Agg : Node_Id; Btyp : constant Entity_Id := Base_Type (Typ); Sub : Entity_Id; + Sub_Ref : Node_Id; E_T : constant Entity_Id := Equivalent_Type (Btyp); Acc : constant Entity_Id := Etype (Next_Component (First_Component (E_T))); @@ -355,23 +356,27 @@ package body Exp_Attr is Attribute_Name => Name_Address); end if; + Sub_Ref := + Make_Attribute_Reference (Loc, + Prefix => Sub, + Attribute_Name => Name_Access); + + -- We set the type of the access reference to the already generated + -- access_to_subprogram type, and declare the reference analyzed, to + -- prevent further expansion when the enclosing aggregate is analyzed. + + Set_Etype (Sub_Ref, Acc); + Set_Analyzed (Sub_Ref); + Agg := Make_Aggregate (Loc, - Expressions => - New_List ( - Obj_Ref, - Unchecked_Convert_To (Acc, - Make_Attribute_Reference (Loc, - Prefix => Sub, - Attribute_Name => Name_Address)))); + Expressions => New_List (Obj_Ref, Sub_Ref)); Rewrite (N, Agg); - Analyze_And_Resolve (N, E_T); - -- For subsequent analysis, the node must retain its type. - -- The backend will replace it with the equivalent type where - -- needed. + -- For subsequent analysis, the node must retain its type. The backend + -- will replace it with the equivalent type where needed. Set_Etype (N, Typ); end Expand_Access_To_Protected_Op; @@ -4682,13 +4687,23 @@ package body Exp_Attr is --------------------- function Make_Range_Test return Node_Id is + Temp : constant Node_Id := Duplicate_Subexpr (Pref); + begin + -- The value whose validity is being checked has been captured in + -- an object declaration. We certainly don't want this object to + -- appear valid because the declaration initializes it! + + if Is_Entity_Name (Temp) then + Set_Is_Known_Valid (Entity (Temp), False); + end if; + return Make_And_Then (Loc, Left_Opnd => Make_Op_Ge (Loc, Left_Opnd => - Unchecked_Convert_To (Btyp, Duplicate_Subexpr (Pref)), + Unchecked_Convert_To (Btyp, Temp), Right_Opnd => Unchecked_Convert_To (Btyp, @@ -4699,8 +4714,7 @@ package body Exp_Attr is Right_Opnd => Make_Op_Le (Loc, Left_Opnd => - Unchecked_Convert_To (Btyp, - Duplicate_Subexpr_No_Checks (Pref)), + Unchecked_Convert_To (Btyp, Temp), Right_Opnd => Unchecked_Convert_To (Btyp, diff --git a/gcc/ada/exp_ch2.adb b/gcc/ada/exp_ch2.adb index 5d1822d1859..e0be4042f11 100644 --- a/gcc/ada/exp_ch2.adb +++ b/gcc/ada/exp_ch2.adb @@ -24,6 +24,7 @@ ------------------------------------------------------------------------------ with Atree; use Atree; +with Debug; use Debug; with Einfo; use Einfo; with Elists; use Elists; with Errout; use Errout; @@ -34,12 +35,14 @@ with Exp_VFpt; use Exp_VFpt; with Namet; use Namet; with Nmake; use Nmake; with Opt; use Opt; +with Output; use Output; with Sem; use Sem; with Sem_Eval; use Sem_Eval; with Sem_Res; use Sem_Res; with Sem_Util; use Sem_Util; with Sem_Warn; use Sem_Warn; with Sinfo; use Sinfo; +with Sinput; use Sinput; with Snames; use Snames; with Tbuild; use Tbuild; with Uintp; use Uintp; @@ -370,13 +373,34 @@ package body Exp_Ch2 is Expand_Shared_Passive_Variable (N); end if; + -- Test code for implementing the pragma Reviewable requirement of + -- classifying reads of scalars as referencing potentially uninitialized + -- objects or not. + + if Debug_Flag_XX + and then Is_Scalar_Type (Etype (N)) + and then (Is_Assignable (E) or else Is_Constant_Object (E)) + and then Comes_From_Source (N) + and then not Is_LHS (N) + and then not Is_Actual_Out_Parameter (N) + and then (Nkind (Parent (N)) /= N_Attribute_Reference + or else Attribute_Name (Parent (N)) /= Name_Valid) + then + Write_Location (Sloc (N)); + Write_Str (": Read from scalar """); + Write_Name (Chars (N)); + Write_Str (""""); + + if Is_Known_Valid (E) then + Write_Str (", Is_Known_Valid"); + end if; + + Write_Eol; + end if; + -- Interpret possible Current_Value for variable case - if (Ekind (E) = E_Variable - or else - Ekind (E) = E_In_Out_Parameter - or else - Ekind (E) = E_Out_Parameter) + if Is_Assignable (E) and then Present (Current_Value (E)) then Expand_Current_Value (N); diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb index e8b46e55e60..c0861e30890 100644 --- a/gcc/ada/exp_ch3.adb +++ b/gcc/ada/exp_ch3.adb @@ -59,6 +59,7 @@ with Sem_Disp; use Sem_Disp; with Sem_Eval; use Sem_Eval; with Sem_Mech; use Sem_Mech; with Sem_Res; use Sem_Res; +with Sem_SCIL; use Sem_SCIL; with Sem_Type; use Sem_Type; with Sem_Util; use Sem_Util; with Sinfo; use Sinfo; @@ -752,7 +753,11 @@ package body Exp_Ch3 is Set_Init_Proc (A_Type, Proc_Id); if List_Length (Body_Stmts) = 1 - and then Nkind (First (Body_Stmts)) = N_Null_Statement + + -- We must skip SCIL nodes because they may have been added to this + -- list by Insert_Actions. + + and then Nkind (First_Non_SCIL_Node (Body_Stmts)) = N_Null_Statement then Set_Is_Null_Init_Proc (Proc_Id); @@ -763,7 +768,7 @@ package body Exp_Ch3 is Set_Static_Initialization (Proc_Id, - Build_Equivalent_Array_Aggregate (First_Subtype (A_Type))); + Build_Equivalent_Array_Aggregate (First_Subtype (A_Type))); end if; end if; end Build_Array_Init_Proc; @@ -1939,6 +1944,7 @@ package body Exp_Ch3 is D := First_Discriminant (Rec_Type); while Present (D) loop + -- Don't generate the assignment for discriminants in derived -- tagged types if the discriminant is a renaming of some -- ancestor discriminant. This initialization will be done @@ -2330,11 +2336,16 @@ package body Exp_Ch3 is -- the tag component. if Generate_SCIL then - Prepend_To (Init_Tags_List, - New_SCIL_Node - (SN_Kind => IP_Tag_Init, - Related_Node => First (Init_Tags_List), - Entity => Rec_Type)); + declare + New_Node : Node_Id; + + begin + New_Node := + Make_SCIL_Tag_Init (Sloc (First (Init_Tags_List))); + Set_SCIL_Related_Node (New_Node, First (Init_Tags_List)); + Set_SCIL_Entity (New_Node, Rec_Type); + Prepend_To (Init_Tags_List, New_Node); + end; end if; -- Ada 2005 (AI-251): Initialize the secondary tags components @@ -2496,7 +2507,11 @@ package body Exp_Ch3 is Set_Init_Proc (Rec_Type, Proc_Id); if List_Length (Body_Stmts) = 1 - and then Nkind (First (Body_Stmts)) = N_Null_Statement + + -- We must skip SCIL nodes because they may have been added to this + -- list by Insert_Actions. + + and then Nkind (First_Non_SCIL_Node (Body_Stmts)) = N_Null_Statement and then VM_Target = No_VM then -- Even though the init proc may be null at this time it might get @@ -5602,105 +5617,6 @@ package body Exp_Ch3 is ------------------------------- procedure Expand_Freeze_Record_Type (N : Node_Id) is - - procedure Add_Internal_Interface_Entities (Tagged_Type : Entity_Id); - -- Add to the list of primitives of Tagged_Types the internal entities - -- associated with interface primitives that are located in secondary - -- dispatch tables. - - ------------------------------------- - -- Add_Internal_Interface_Entities -- - ------------------------------------- - - procedure Add_Internal_Interface_Entities (Tagged_Type : Entity_Id) is - Elmt : Elmt_Id; - Iface : Entity_Id; - Iface_Elmt : Elmt_Id; - Iface_Prim : Entity_Id; - Ifaces_List : Elist_Id; - New_Subp : Entity_Id := Empty; - Prim : Entity_Id; - - begin - pragma Assert (Ada_Version >= Ada_05 - and then Is_Record_Type (Tagged_Type) - and then Is_Tagged_Type (Tagged_Type) - and then Has_Interfaces (Tagged_Type) - and then not Is_Interface (Tagged_Type)); - - Collect_Interfaces (Tagged_Type, Ifaces_List); - - Iface_Elmt := First_Elmt (Ifaces_List); - while Present (Iface_Elmt) loop - Iface := Node (Iface_Elmt); - - -- Exclude from this processing interfaces that are parents - -- of Tagged_Type because their primitives are located in the - -- primary dispatch table (and hence no auxiliary internal - -- entities are required to handle secondary dispatch tables - -- in such case). - - if not Is_Ancestor (Iface, Tagged_Type) then - Elmt := First_Elmt (Primitive_Operations (Iface)); - while Present (Elmt) loop - Iface_Prim := Node (Elmt); - - if not Is_Predefined_Dispatching_Operation (Iface_Prim) then - Prim := - Find_Primitive_Covering_Interface - (Tagged_Type => Tagged_Type, - Iface_Prim => Iface_Prim); - - pragma Assert (Present (Prim)); - - Derive_Subprogram - (New_Subp => New_Subp, - Parent_Subp => Iface_Prim, - Derived_Type => Tagged_Type, - Parent_Type => Iface); - - -- Ada 2005 (AI-251): Decorate internal entity Iface_Subp - -- associated with interface types. These entities are - -- only registered in the list of primitives of its - -- corresponding tagged type because they are only used - -- to fill the contents of the secondary dispatch tables. - -- Therefore they are removed from the homonym chains. - - Set_Is_Hidden (New_Subp); - Set_Is_Internal (New_Subp); - Set_Alias (New_Subp, Prim); - Set_Is_Abstract_Subprogram (New_Subp, - Is_Abstract_Subprogram (Prim)); - Set_Interface_Alias (New_Subp, Iface_Prim); - - -- Internal entities associated with interface types are - -- only registered in the list of primitives of the - -- tagged type. They are only used to fill the contents - -- of the secondary dispatch tables. Therefore they are - -- not needed in the homonym chains. - - Remove_Homonym (New_Subp); - - -- Hidden entities associated with interfaces must have - -- set the Has_Delay_Freeze attribute to ensure that, in - -- case of locally defined tagged types (or compiling - -- with static dispatch tables generation disabled) the - -- corresponding entry of the secondary dispatch table is - -- filled when such entity is frozen. - - Set_Has_Delayed_Freeze (New_Subp); - end if; - - Next_Elmt (Elmt); - end loop; - end if; - - Next_Elmt (Iface_Elmt); - end loop; - end Add_Internal_Interface_Entities; - - -- Local variables - Def_Id : constant Node_Id := Entity (N); Type_Decl : constant Node_Id := Parent (Def_Id); Comp : Entity_Id; @@ -5933,17 +5849,6 @@ package body Exp_Ch3 is Insert_Actions (N, Null_Proc_Decl_List); end if; - -- Ada 2005 (AI-251): Add internal entities associated with - -- secondary dispatch tables to the list of primitives of tagged - -- types that are not interfaces - - if Ada_Version >= Ada_05 - and then not Is_Interface (Def_Id) - and then Has_Interfaces (Def_Id) - then - Add_Internal_Interface_Entities (Def_Id); - end if; - Set_Is_Frozen (Def_Id); Set_All_DT_Position (Def_Id); diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index 258ce3a8266..955d3f6a898 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -58,6 +58,7 @@ with Sem_Ch8; use Sem_Ch8; with Sem_Ch13; use Sem_Ch13; with Sem_Eval; use Sem_Eval; with Sem_Res; use Sem_Res; +with Sem_SCIL; use Sem_SCIL; with Sem_Type; use Sem_Type; with Sem_Util; use Sem_Util; with Sem_Warn; use Sem_Warn; @@ -3965,6 +3966,16 @@ package body Exp_Ch4 is Right, New_Occurrence_Of (Standard_False, Loc)))); + -- If the right part of the expression is a function call then it can + -- be part of the expansion of the predefined equality operator of a + -- tagged type and we may need to adjust its SCIL dispatching node. + + if Generate_SCIL + and then Nkind (Right) = N_Function_Call + then + Adjust_SCIL_Node (N, Right); + end if; + Set_Then_Actions (N, Actlist); Analyze_And_Resolve (N, Standard_Boolean); Adjust_Result_Type (N, Typ); diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb index f6a83bd2f91..44944aecaf9 100644 --- a/gcc/ada/exp_ch6.adb +++ b/gcc/ada/exp_ch6.adb @@ -64,6 +64,7 @@ with Sem_Disp; use Sem_Disp; with Sem_Dist; use Sem_Dist; with Sem_Mech; use Sem_Mech; with Sem_Res; use Sem_Res; +with Sem_SCIL; use Sem_SCIL; with Sem_Util; use Sem_Util; with Sinfo; use Sinfo; with Snames; use Snames; @@ -1125,6 +1126,7 @@ package body Exp_Ch6 is -- created, since we just passed it as an OUT parameter. Kill_Current_Values (Temp); + Set_Is_Known_Valid (Temp, False); -- If type conversion, use reverse conversion on exit @@ -2470,7 +2472,8 @@ package body Exp_Ch6 is -- For an OUT or IN OUT parameter that is an assignable entity, -- we do not want to clobber the Last_Assignment field, since -- if it is set, it was precisely because it is indeed an OUT - -- or IN OUT parameter! + -- or IN OUT parameter! We do reset the Is_Known_Valid flag + -- since the subprogram could have returned in invalid value. if (Ekind (Formal) = E_Out_Parameter or else @@ -2480,6 +2483,7 @@ package body Exp_Ch6 is Sav := Last_Assignment (Ent); Kill_Current_Values (Ent); Set_Last_Assignment (Ent, Sav); + Set_Is_Known_Valid (Ent, False); -- For all other cases, just kill the current values @@ -4969,10 +4973,13 @@ package body Exp_Ch6 is if Nkind (Orig_Bod) /= N_Subprogram_Body then return False; else + -- We must skip SCIL nodes because they are currently + -- implemented as special N_Null_Statement nodes. + Stat := - First + First_Non_SCIL_Node (Statements (Handled_Statement_Sequence (Orig_Bod))); - Stat2 := Next (Stat); + Stat2 := Next_Non_SCIL_Node (Stat); return Is_Empty_List (Declarations (Orig_Bod)) diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb index a8a32fb5114..3e8fc6a7d7a 100644 --- a/gcc/ada/exp_ch7.adb +++ b/gcc/ada/exp_ch7.adb @@ -54,6 +54,7 @@ with Sem_Ch3; use Sem_Ch3; with Sem_Ch7; use Sem_Ch7; with Sem_Ch8; use Sem_Ch8; with Sem_Res; use Sem_Res; +with Sem_SCIL; use Sem_SCIL; with Sem_Type; use Sem_Type; with Sem_Util; use Sem_Util; with Snames; use Snames; @@ -3602,6 +3603,15 @@ package body Exp_Ch7 is New_Statement : constant Node_Id := Relocate_Node (N); begin + -- If the relocated node is a procedure call then check if some SCIL + -- node references it and needs readjustment. + + if Generate_SCIL + and then Nkind (New_Statement) = N_Procedure_Call_Statement + then + Adjust_SCIL_Node (N, New_Statement); + end if; + Rewrite (N, Make_Transient_Block (Loc, New_Statement)); -- With the scope stack back to normal, we can call analyze on the diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb index cc58d9f4fa4..3a7fa25065d 100644 --- a/gcc/ada/exp_ch9.adb +++ b/gcc/ada/exp_ch9.adb @@ -3193,6 +3193,18 @@ package body Exp_Ch9 is Params := New_List; end if; + -- If the type is an untagged derived type, convert to the root type, + -- which is the one on which the operations are defined. + + if Nkind (Rec) = N_Unchecked_Type_Conversion + and then not Is_Tagged_Type (Etype (Rec)) + and then Is_Derived_Type (Etype (Rec)) + then + Set_Etype (Rec, Root_Type (Etype (Rec))); + Set_Subtype_Mark (Rec, + New_Occurrence_Of (Root_Type (Etype (Rec)), Sloc (N))); + end if; + Prepend (Rec, Params); if Ekind (Sub) = E_Procedure then @@ -4358,8 +4370,8 @@ package body Exp_Ch9 is return N; else return - Unchecked_Convert_To (Corresponding_Record_Type (Typ), - New_Copy_Tree (N)); + Unchecked_Convert_To + (Corresponding_Record_Type (Typ), New_Copy_Tree (N)); end if; end Convert_Concurrent; @@ -10324,6 +10336,13 @@ package body Exp_Ch9 is S : Entity_Id; -- Primitive operation slot begin + -- Under the Ravenscar profile, timed entry calls are excluded. An error + -- was already reported on spec, so do not attempt to expand the call. + + if Restriction_Active (No_Select_Statements) then + return; + end if; + -- The arguments in the call may require dynamic allocation, and the -- call statement may have been transformed into a block. The block -- may contain additional declarations for internal entities, and the diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb index df23c891f27..f34b1e9af33 100644 --- a/gcc/ada/exp_disp.adb +++ b/gcc/ada/exp_disp.adb @@ -575,6 +575,11 @@ package body Exp_Disp is end if; end New_Value; + -- Local variables + + New_Node : Node_Id; + SCIL_Node : Node_Id; + -- Start of processing for Expand_Dispatching_Call begin @@ -643,15 +648,17 @@ package body Exp_Disp is Typ := Non_Limited_View (Typ); end if; - -- Generate the SCIL node for this dispatching call + -- Generate the SCIL node for this dispatching call. The SCIL node for a + -- dispatching call is inserted in the tree before the call is rewriten + -- and expanded because the SCIL node must be found by the SCIL backend + -- BEFORE the expanded nodes associated with the call node are found. if Generate_SCIL then - Insert_Action (Call_Node, - New_SCIL_Node - (SN_Kind => Dispatching_Call, - Related_Node => Call_Node, - Entity => Typ, - Target_Prim => Subp)); + SCIL_Node := Make_SCIL_Dispatching_Call (Sloc (Call_Node)); + Set_SCIL_Related_Node (SCIL_Node, Call_Node); + Set_SCIL_Entity (SCIL_Node, Typ); + Set_SCIL_Target_Prim (SCIL_Node, Subp); + Insert_Action (Call_Node, SCIL_Node); end if; if not Is_Limited_Type (Typ) then @@ -804,7 +811,7 @@ package body Exp_Disp is else Controlling_Tag := Make_Selected_Component (Loc, - Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg), + Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg), Selector_Name => New_Reference_To (DTC_Entity (Subp), Loc)); end if; @@ -813,28 +820,100 @@ package body Exp_Disp is if Is_Predefined_Dispatching_Operation (Subp) or else Is_Predefined_Dispatching_Alias (Subp) then - New_Call_Name := - Unchecked_Convert_To (Subp_Ptr_Typ, - Build_Get_Predefined_Prim_Op_Address (Loc, - Tag_Node => Controlling_Tag, - Position => DT_Position (Subp))); + Build_Get_Predefined_Prim_Op_Address (Loc, + Tag_Node => Controlling_Tag, + Position => DT_Position (Subp), + New_Node => New_Node); -- Handle dispatching calls to user-defined primitives else - New_Call_Name := - Unchecked_Convert_To (Subp_Ptr_Typ, - Build_Get_Prim_Op_Address (Loc, - Typ => Find_Dispatching_Type (Subp), - Tag_Node => Controlling_Tag, - Position => DT_Position (Subp))); + Build_Get_Prim_Op_Address (Loc, + Typ => Find_Dispatching_Type (Subp), + Tag_Node => Controlling_Tag, + Position => DT_Position (Subp), + New_Node => New_Node); end if; - if Nkind (Call_Node) = N_Function_Call then + New_Call_Name := + Unchecked_Convert_To (Subp_Ptr_Typ, New_Node); + + -- Complete decoration of SCIL dispatching node. It must be done after + -- the new call name is built to reference the nodes that will see the + -- SCIL backend (because Build_Get_Prim_Op_Address generates an + -- unchecked type conversion which relocates the controlling tag node). + + if Generate_SCIL then + + -- Common case: the controlling tag is the tag of an object + -- (for example, obj.tag) + + if Nkind (Controlling_Tag) = N_Selected_Component then + Set_SCIL_Controlling_Tag (SCIL_Node, Controlling_Tag); + + -- Handle renaming of selected component + + elsif Nkind (Controlling_Tag) = N_Identifier + and then Nkind (Parent (Entity (Controlling_Tag))) = + N_Object_Renaming_Declaration + and then Nkind (Name (Parent (Entity (Controlling_Tag)))) = + N_Selected_Component + then + Set_SCIL_Controlling_Tag (SCIL_Node, + Name (Parent (Entity (Controlling_Tag)))); + + -- If the controlling tag is an identifier, the SCIL node references + -- the corresponding object or parameter declaration + + elsif Nkind (Controlling_Tag) = N_Identifier + and then Nkind_In (Parent (Entity (Controlling_Tag)), + N_Object_Declaration, + N_Parameter_Specification) + then + Set_SCIL_Controlling_Tag (SCIL_Node, + Parent (Entity (Controlling_Tag))); + + -- If the controlling tag is a dereference, the SCIL node references + -- the corresponding object or parameter declaration + + elsif Nkind (Controlling_Tag) = N_Explicit_Dereference + and then Nkind (Prefix (Controlling_Tag)) = N_Identifier + and then Nkind_In (Parent (Entity (Prefix (Controlling_Tag))), + N_Object_Declaration, + N_Parameter_Specification) + then + Set_SCIL_Controlling_Tag (SCIL_Node, + Parent (Entity (Prefix (Controlling_Tag)))); + + -- For a direct reference of the tag of the type the SCIL node + -- references the the internal object declaration containing the tag + -- of the type. + + elsif Nkind (Controlling_Tag) = N_Attribute_Reference + and then Attribute_Name (Controlling_Tag) = Name_Tag + then + Set_SCIL_Controlling_Tag (SCIL_Node, + Parent + (Node + (First_Elmt + (Access_Disp_Table (Entity (Prefix (Controlling_Tag))))))); + + -- Interfaces are not supported. For now we leave the SCIL node + -- decorated with the Controlling_Tag. More work needed here??? + + elsif Is_Interface (Etype (Controlling_Tag)) then + Set_SCIL_Controlling_Tag (SCIL_Node, Controlling_Tag); + + else + pragma Assert (False); + null; + end if; + end if; + if Nkind (Call_Node) = N_Function_Call then New_Call := Make_Function_Call (Loc, - Name => New_Call_Name, + Name => New_Call_Name, Parameter_Associations => New_Params); -- If this is a dispatching "=", we must first compare the tags so @@ -848,26 +927,26 @@ package body Exp_Disp is Make_Op_Eq (Loc, Left_Opnd => Make_Selected_Component (Loc, - Prefix => New_Value (Param), + Prefix => New_Value (Param), Selector_Name => New_Reference_To (First_Tag_Component (Typ), Loc)), Right_Opnd => Make_Selected_Component (Loc, - Prefix => + Prefix => Unchecked_Convert_To (Typ, New_Value (Next_Actual (Param))), Selector_Name => - New_Reference_To (First_Tag_Component (Typ), - Loc))), + New_Reference_To + (First_Tag_Component (Typ), Loc))), Right_Opnd => New_Call); end if; else New_Call := Make_Procedure_Call_Statement (Loc, - Name => New_Call_Name, + Name => New_Call_Name, Parameter_Associations => New_Params); end if; @@ -1607,17 +1686,6 @@ package body Exp_Disp is end if; end Expand_Interface_Thunk; - ------------------------ - -- Get_SCIL_Node_Kind -- - ------------------------ - - function Get_SCIL_Node_Kind (Node : Node_Id) return SCIL_Node_Kind is - begin - pragma Assert - (Nkind (Node) = N_Null_Statement and then Is_SCIL_Node (Node)); - return SCIL_Node_Kind'Val (UI_To_Int (SCIL_Nkind (Node))); - end Get_SCIL_Node_Kind; - ------------ -- Has_DT -- ------------ @@ -4247,11 +4315,11 @@ package body Exp_Disp is -- because it has a null dispatch table. if Generate_SCIL then - Insert_Before (Last (Result), - New_SCIL_Node - (SN_Kind => Dispatch_Table_Object_Init, - Related_Node => Last (Result), - Entity => Typ)); + New_Node := + Make_SCIL_Dispatch_Table_Object_Init (Sloc (Last (Result))); + Set_SCIL_Related_Node (New_Node, Last (Result)); + Set_SCIL_Entity (New_Node, Typ); + Insert_Before (Last (Result), New_Node); end if; Append_To (Result, @@ -4284,11 +4352,11 @@ package body Exp_Disp is -- because it has a tag initialization. if Generate_SCIL then - Insert_Before (Last (Result), - New_SCIL_Node - (SN_Kind => Dispatch_Table_Tag_Init, - Related_Node => Last (Result), - Entity => Typ)); + New_Node := + Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result))); + Set_SCIL_Related_Node (New_Node, Last (Result)); + Set_SCIL_Entity (New_Node, Typ); + Insert_Before (Last (Result), New_Node); end if; -- Generate: @@ -4324,11 +4392,11 @@ package body Exp_Disp is -- because it contains a dispatch table. if Generate_SCIL then - Insert_Before (Last (Result), - New_SCIL_Node - (SN_Kind => Dispatch_Table_Object_Init, - Related_Node => Last (Result), - Entity => Typ)); + New_Node := + Make_SCIL_Dispatch_Table_Object_Init (Sloc (Last (Result))); + Set_SCIL_Related_Node (New_Node, Last (Result)); + Set_SCIL_Entity (New_Node, Typ); + Insert_Before (Last (Result), New_Node); end if; Append_To (Result, @@ -4361,11 +4429,11 @@ package body Exp_Disp is -- because it has a tag initialization. if Generate_SCIL then - Insert_Before (Last (Result), - New_SCIL_Node - (SN_Kind => Dispatch_Table_Tag_Init, - Related_Node => Last (Result), - Entity => Typ)); + New_Node := + Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result))); + Set_SCIL_Related_Node (New_Node, Last (Result)); + Set_SCIL_Entity (New_Node, Typ); + Insert_Before (Last (Result), New_Node); end if; Append_To (Result, @@ -5140,11 +5208,11 @@ package body Exp_Disp is -- because it has a null dispatch table. if Generate_SCIL then - Insert_Before (Last (Result), - New_SCIL_Node - (SN_Kind => Dispatch_Table_Object_Init, - Related_Node => Last (Result), - Entity => Typ)); + New_Node := + Make_SCIL_Dispatch_Table_Object_Init (Sloc (Last (Result))); + Set_SCIL_Related_Node (New_Node, Last (Result)); + Set_SCIL_Entity (New_Node, Typ); + Insert_Before (Last (Result), New_Node); end if; Append_To (Result, @@ -5457,11 +5525,11 @@ package body Exp_Disp is -- because it contains a dispatch table. if Generate_SCIL then - Insert_Before (Last (Result), - New_SCIL_Node - (SN_Kind => Dispatch_Table_Object_Init, - Related_Node => Last (Result), - Entity => Typ)); + New_Node := + Make_SCIL_Dispatch_Table_Object_Init (Sloc (Last (Result))); + Set_SCIL_Related_Node (New_Node, Last (Result)); + Set_SCIL_Entity (New_Node, Typ); + Insert_Before (Last (Result), New_Node); end if; Append_To (Result, @@ -6095,6 +6163,7 @@ package body Exp_Disp is Predef_Prims_Ptr : Node_Id; Iface_DT : Node_Id; Iface_DT_Ptr : Node_Id; + New_Node : Node_Id; Suffix_Index : Int; Typ_Name : Name_Id; Typ_Comps : Elist_Id; @@ -6158,11 +6227,11 @@ package body Exp_Disp is -- because it has a tag initialization. if Generate_SCIL then - Insert_Before (Last (Result), - New_SCIL_Node - (SN_Kind => Dispatch_Table_Tag_Init, - Related_Node => Last (Result), - Entity => Typ)); + New_Node := + Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result))); + Set_SCIL_Related_Node (New_Node, Last (Result)); + Set_SCIL_Entity (New_Node, Typ); + Insert_Before (Last (Result), New_Node); end if; Append_To (Result, @@ -6204,11 +6273,11 @@ package body Exp_Disp is -- because it has a tag initialization. if Generate_SCIL then - Insert_Before (Last (Result), - New_SCIL_Node - (SN_Kind => Dispatch_Table_Tag_Init, - Related_Node => Last (Result), - Entity => Typ)); + New_Node := + Make_SCIL_Dispatch_Table_Object_Init (Sloc (Last (Result))); + Set_SCIL_Related_Node (New_Node, Last (Result)); + Set_SCIL_Entity (New_Node, Typ); + Insert_Before (Last (Result), New_Node); end if; end if; @@ -6433,29 +6502,6 @@ package body Exp_Disp is end if; end New_Value; - ------------------- - -- New_SCIL_Node -- - ------------------- - - function New_SCIL_Node - (SN_Kind : SCIL_Node_Kind; - Related_Node : Node_Id; - Entity : Entity_Id := Empty; - Target_Prim : Entity_Id := Empty) return Node_Id - is - New_N : constant Node_Id := - New_Node (N_Null_Statement, Sloc (Related_Node)); - begin - Set_Is_SCIL_Node (New_N); - - Set_SCIL_Nkind (New_N, UI_From_Int (SCIL_Node_Kind'Pos (SN_Kind))); - Set_SCIL_Related_Node (New_N, Related_Node); - Set_SCIL_Entity (New_N, Entity); - Set_SCIL_Target_Prim (New_N, Target_Prim); - - return New_N; - end New_SCIL_Node; - ----------------------------------- -- Original_View_In_Visible_Part -- ----------------------------------- @@ -6869,13 +6915,12 @@ package body Exp_Disp is begin pragma Assert (Present (First_Tag_Component (Typ))); - -- Set the DT_Position for each primitive operation. Perform some - -- sanity checks to avoid to build completely inconsistent dispatch - -- tables. + -- Set the DT_Position for each primitive operation. Perform some sanity + -- checks to avoid building inconsistent dispatch tables. - -- First stage: Set the DTC entity of all the primitive operations - -- This is required to properly read the DT_Position attribute in - -- the latter stages. + -- First stage: Set the DTC entity of all the primitive operations. This + -- is required to properly read the DT_Position attribute in the latter + -- stages. Prim_Elmt := First_Prim; Count_Prim := 0; @@ -6885,7 +6930,8 @@ package body Exp_Disp is -- Predefined primitives have a separate dispatch table if not (Is_Predefined_Dispatching_Operation (Prim) - or else Is_Predefined_Dispatching_Alias (Prim)) + or else + Is_Predefined_Dispatching_Alias (Prim)) then Count_Prim := Count_Prim + 1; end if; diff --git a/gcc/ada/exp_disp.ads b/gcc/ada/exp_disp.ads index 2b3710e48ca..18f751d978d 100644 --- a/gcc/ada/exp_disp.ads +++ b/gcc/ada/exp_disp.ads @@ -30,34 +30,6 @@ with Types; use Types; package Exp_Disp is - ------------------------------- - -- SCIL Node Type Definition -- - ------------------------------- - - -- SCIL nodes are a special kind of nodes added to the tree when the - -- CodePeer mode is active. They are stored in the tree as special - -- N_Null_Statement nodes that have extra attributes. The information - -- available through these extra attributes relies on the kind of SCIL - -- node. The SCIL node kind is stored in the Scil_Nkind attribute of - -- the N_Null_Statement node, and indicates the type of the SCIL node. - - type SCIL_Node_Kind is - (Unused, - -- What is this for ??? - - IP_Tag_Init, - -- SCIL node for tag component initialization - - Dispatching_Call, - -- SCIL node for dispatching call. Used by the CodePeer backend to - -- locate nodes associated with dispatching calls. - - Dispatch_Table_Object_Init, - -- SCIL node for object declaration containing a dispatch table - - Dispatch_Table_Tag_Init); - -- SCIL node for tag initialization - ------------------------------------- -- Predefined primitive operations -- ------------------------------------- @@ -243,9 +215,6 @@ package Exp_Disp is -- Otherwise they are set to the defining identifier and the subprogram -- body of the generated thunk. - function Get_SCIL_Node_Kind (Node : Node_Id) return SCIL_Node_Kind; - -- Returns the kind of an SCIL node - function Is_Predefined_Dispatching_Operation (E : Entity_Id) return Boolean; -- Ada 2005 (AI-251): Determines if E is a predefined primitive operation @@ -340,15 +309,6 @@ package Exp_Disp is -- tagged types this routine imports the forward declaration of the tag -- entity, that will be declared and exported by Make_DT. - function New_SCIL_Node - (SN_Kind : SCIL_Node_Kind; - Related_Node : Node_Id; - Entity : Entity_Id := Empty; - Target_Prim : Entity_Id := Empty) return Node_Id; - -- Creates a new Scil node. Related_Node is the AST node associated with - -- this Scil node. Entity is the tagged type associated with the Scil node. - -- For Dispatching_Call nodes, Target_Prim is the dispatching primitive. - function Register_Primitive (Loc : Source_Ptr; Prim : Entity_Id) return List_Id; diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb index d139a2bc321..cd05d75f1f3 100644 --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -43,6 +43,7 @@ with Rident; use Rident; with Sem; use Sem; with Sem_Aux; use Sem_Aux; with Sem_Ch8; use Sem_Ch8; +with Sem_SCIL; use Sem_SCIL; with Sem_Eval; use Sem_Eval; with Sem_Res; use Sem_Res; with Sem_Type; use Sem_Type; @@ -1320,12 +1321,14 @@ package body Exp_Util is Rewrite (Subtype_Indic, New_Reference_To (T, Loc)); -- nothing needs to be done for private types with unknown discriminants - -- if the underlying type is not an unconstrained composite type. + -- if the underlying type is not an unconstrained composite type or it + -- is an unchecked union. elsif Is_Private_Type (Unc_Type) and then Has_Unknown_Discriminants (Unc_Type) and then (not Is_Composite_Type (Underlying_Type (Unc_Type)) - or else Is_Constrained (Underlying_Type (Unc_Type))) + or else Is_Constrained (Underlying_Type (Unc_Type)) + or else Is_Unchecked_Union (Underlying_Type (Unc_Type))) then null; @@ -2755,6 +2758,10 @@ package body Exp_Util is N_Real_Range_Specification | N_Record_Definition | N_Reference | + N_SCIL_Dispatch_Table_Object_Init | + N_SCIL_Dispatch_Table_Tag_Init | + N_SCIL_Dispatching_Call | + N_SCIL_Tag_Init | N_Selected_Component | N_Signed_Integer_Type_Definition | N_Single_Protected_Declaration | @@ -4634,6 +4641,15 @@ package body Exp_Util is Constant_Present => True, Expression => Relocate_Node (Exp)); + -- Check if the previous node relocation requires readjustment of + -- some SCIL Dispatching node. + + if Generate_SCIL + and then Nkind (Exp) = N_Function_Call + then + Adjust_SCIL_Node (Exp, Expression (E)); + end if; + Set_Assignment_OK (E); Insert_Action (Exp, E); @@ -4794,6 +4810,16 @@ package body Exp_Util is Defining_Identifier => Obj, Object_Definition => New_Occurrence_Of (Exp_Type, Loc), Expression => Relocate_Node (Exp)); + + -- Check if the previous node relocation requires readjustment + -- of some SCIL Dispatching node. + + if Generate_SCIL + and then Nkind (Exp) = N_Function_Call + then + Adjust_SCIL_Node (Exp, Expression (Decl)); + end if; + Insert_Action (Exp, Decl); Set_Etype (Obj, Exp_Type); Rewrite (Exp, New_Occurrence_Of (Obj, Loc)); @@ -4853,6 +4879,15 @@ package body Exp_Util is Defining_Identifier => Def_Id, Object_Definition => New_Reference_To (Ref_Type, Loc), Expression => New_Exp)); + + -- Check if the previous node relocation requires readjustment + -- of some SCIL Dispatching node. + + if Generate_SCIL + and then Nkind (Exp) = N_Function_Call + then + Adjust_SCIL_Node (Exp, Prefix (New_Exp)); + end if; end if; -- Preserve the Assignment_OK flag in all copies, since at least diff --git a/gcc/ada/frontend.adb b/gcc/ada/frontend.adb index 7109383555f..581d977436a 100644 --- a/gcc/ada/frontend.adb +++ b/gcc/ada/frontend.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2008, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -46,12 +46,13 @@ with Prep; with Prepcomp; with Restrict; use Restrict; with Rident; use Rident; -with Rtsfind; +with Rtsfind; use Rtsfind; with Sprint; with Scn; use Scn; with Sem; use Sem; with Sem_Aux; with Sem_Ch8; use Sem_Ch8; +with Sem_SCIL; with Sem_Elab; use Sem_Elab; with Sem_Prag; use Sem_Prag; with Sem_Warn; use Sem_Warn; @@ -308,7 +309,7 @@ begin -- incorporate subunits at a lower level. if Operating_Mode = Generate_Code - and then Nkind (Unit (Cunit (Main_Unit))) = N_Subunit + and then Nkind (Unit (Cunit (Main_Unit))) = N_Subunit then Operating_Mode := Check_Semantics; end if; @@ -321,8 +322,8 @@ begin -- Cleanup processing after completing main analysis if Operating_Mode = Generate_Code - or else (Operating_Mode = Check_Semantics - and then ASIS_Mode) + or else (Operating_Mode = Check_Semantics + and then ASIS_Mode) then Instantiate_Bodies; end if; @@ -366,6 +367,14 @@ begin Exp_Dbug.Qualify_All_Entity_Names; end if; + -- SCIL backend requirement. Check that SCIL nodes associated with + -- dispatching calls reference subprogram calls. + + if Generate_SCIL then + pragma Debug (Sem_SCIL.Check_SCIL_Nodes (Cunit (Main_Unit))); + null; + end if; + -- Dump the source now. Note that we do this as soon as the analysis -- of the tree is complete, because it is not just a dump in the case -- of -gnatD, where it rewrites all source locations in the tree. diff --git a/gcc/ada/g-expect.adb b/gcc/ada/g-expect.adb index 405b0331275..02bc6cf8a79 100644 --- a/gcc/ada/g-expect.adb +++ b/gcc/ada/g-expect.adb @@ -1195,21 +1195,28 @@ package body GNAT.Expect is pragma Warnings (Off, Pipe2); pragma Warnings (Off, Pipe3); + On_Windows : constant Boolean := Directory_Separator = '\'; + -- This is ugly, we need a better way of doing this test ??? + Input : File_Descriptor; Output : File_Descriptor; Error : File_Descriptor; begin - -- Since Windows does not have a separate fork/exec, we need to - -- perform the following actions: - -- - save stdin, stdout, stderr - -- - replace them by our pipes - -- - create the child with process handle inheritance - -- - revert to the previous stdin, stdout and stderr. + if On_Windows then + + -- Since Windows does not have a separate fork/exec, we need to + -- perform the following actions: + + -- - save stdin, stdout, stderr + -- - replace them by our pipes + -- - create the child with process handle inheritance + -- - revert to the previous stdin, stdout and stderr. - Input := Dup (GNAT.OS_Lib.Standin); - Output := Dup (GNAT.OS_Lib.Standout); - Error := Dup (GNAT.OS_Lib.Standerr); + Input := Dup (GNAT.OS_Lib.Standin); + Output := Dup (GNAT.OS_Lib.Standout); + Error := Dup (GNAT.OS_Lib.Standerr); + end if; -- Since we are still called from the parent process, there is no way -- currently we can cleanly close the unneeded ends of the pipes, but @@ -1223,8 +1230,8 @@ package body GNAT.Expect is Portable_Execvp (Pid.Pid'Access, Cmd & ASCII.NUL, Args); - -- The following commands are not executed on Unix systems, and are - -- only required for Windows systems. We are now in the parent process. + -- The following commands are not executed on Unix systems, and are only + -- required for Windows systems. We are now in the parent process. -- Restore the old descriptors @@ -1277,8 +1284,8 @@ package body GNAT.Expect is -- Reuse the standard output pipe for standard error Pipe3.all := Pipe2.all; - else + else -- Create a separate pipe for standard error if Create_Pipe (Pipe3) /= 0 then diff --git a/gcc/ada/g-socket.adb b/gcc/ada/g-socket.adb index c002054395c..d32ebfc37a8 100644 --- a/gcc/ada/g-socket.adb +++ b/gcc/ada/g-socket.adb @@ -1664,7 +1664,14 @@ package body GNAT.Sockets is (Msg_Name => System.Null_Address, Msg_Namelen => 0, Msg_Iov => Vector'Address, - Msg_Iovlen => SOSC.Msg_Iovlen_T (Vector'Length), + + -- recvmsg(2) returns EMSGSIZE on Linux (and probably on other + -- platforms) when the supplied vector is longer than IOV_MAX, + -- so use minimum of the two lengths. + + Msg_Iovlen => SOSC.Msg_Iovlen_T'Min + (Vector'Length, SOSC.IOV_MAX), + Msg_Control => System.Null_Address, Msg_Controllen => 0, Msg_Flags => 0); diff --git a/gcc/ada/g-sse.ads b/gcc/ada/g-sse.ads index d7b01a991be..706516b9830 100644 --- a/gcc/ada/g-sse.ads +++ b/gcc/ada/g-sse.ads @@ -30,8 +30,8 @@ ------------------------------------------------------------------------------ -- This package is the root of a set aimed at offering Ada bindings to a --- subset of the Intel(r) Streaming SIMD Extensions with GNAT. The purpose is --- to allow access from Ada to the SSE facilities defined in the Intel(r) +-- subset of the Intel(r) Streaming SIMD Extensions with GNAT. The purpose +-- is to allow access from Ada to the SSE facilities defined in the Intel(r) -- compiler manuals, in particular in the Intrinsics Reference of the C++ -- Compiler User's Guide, available from http://www.intel.com. @@ -44,48 +44,74 @@ -- This unit exposes vector _component_ types together with general comments -- on the binding contents. --- As of today, one other unit is offered: GNAT.SSE.Vector__Types, which +-- One other unit is offered as of today: GNAT.SSE.Vector_Types, which -- exposes Ada types corresponding to the reference types (__m128 and the --- like) over which GCC builtins will operate. The exposed Ada types are --- private. Object initializations or value observations may be performed --- with unchecked conversions or address overlays, for example: +-- like) over which a binding to the SSE GCC builtins may operate. + +-- The exposed Ada types are private. Object initializations or value +-- observations may be performed with unchecked conversions or address +-- overlays, for example: -- with Ada.Unchecked_Conversion; --- with GNAT.SSE.Vector_Types; use GNAT.SSE; use GNAT.SSE.Vector_Types; +-- with GNAT.SSE.Vector_Types; use GNAT.SSE, GNAT.SSE.Vector_Types; -- procedure SSE_Base is -- -- Core operations --- function mm_add_ss (A, B : M128) return M128; --- pragma Import (Intrinsic, mm_add_ss, "__builtin_ia32_addss"); +-- function ia32_addps (A, B : m128) return m128; +-- pragma Import (Intrinsic, ia32_addps, "__builtin_ia32_addps"); --- -- User views / conversions or overlays +-- -- User views & conversions --- type Vf32_View is array (1 .. 4) of Float; +-- type Vf32_View is array (1 .. 4) of GNAT.SSE.Float32; -- for Vf32_View'Alignment use VECTOR_ALIGN; --- function To_M128 is new Ada.Unchecked_Conversion (Vf32_View, M128); +-- function To_m128 is new Ada.Unchecked_Conversion (Vf32_View, m128); --- X, Y, Z : M128; +-- Xf32 : constant Vf32_View := (1.0, 1.0, 2.0, 2.0); +-- Yf32 : constant Vf32_View := (2.0, 2.0, 1.0, 1.0); --- Vz : Vf32_View; --- for Vz'Address use Z'Address; +-- X128 : constant m128 := To_m128 (Xf32); +-- Y128 : constant m128 := To_m128 (Yf32); -- begin --- X := To_M128 ((1.0, 1.0, 2.0, 2.0)); --- Y := To_M128 ((2.0, 2.0, 1.0, 1.0)); --- Z := mm_add_ss (X, Y); - --- if vz /= (3.0, 1.0, 2.0, 2.0) then --- raise Program_Error; --- end if; --- end; +-- -- Operations & overlays + +-- declare +-- Z128 : m128; +-- Zf32 : Vf32_View; +-- for Zf32'Address use Z128'Address; +-- begin +-- Z128 := ia32_addps (X128, Y128); +-- if Zf32 /= (3.0, 3.0, 3.0, 3.0) then +-- raise Program_Error; +-- end if; +-- end; + +-- declare +-- type m128_View_Kind is (SSE, F32); +-- type m128_Object (View : m128_View_Kind := F32) is record +-- case View is +-- when SSE => V128 : m128; +-- when F32 => Vf32 : Vf32_View; +-- end case; +-- end record; +-- pragma Unchecked_Union (m128_Object); + +-- O1 : constant m128_Object := (View => SSE, V128 => X128); +-- begin +-- if O1.Vf32 /= Xf32 then +-- raise Program_Error; +-- end if; +-- end; +-- end SSE_Base; package GNAT.SSE is - type Float32 is new Float; - type Float64 is new Long_Float; - type Integer64 is new Long_Long_Integer; + + ----------------------------------- + -- Common vector characteristics -- + ----------------------------------- VECTOR_BYTES : constant := 16; -- Common size of all the SSE vector types, in bytes. @@ -100,4 +126,12 @@ package GNAT.SSE is -- We apply that consistently to all the Ada vector types, as GCC does -- for the corresponding C types. + ---------------------------- + -- Vector component types -- + ---------------------------- + + type Float32 is new Float; + type Float64 is new Long_Float; + type Integer64 is new Long_Long_Integer; + end GNAT.SSE; diff --git a/gcc/ada/g-ssinty.ads b/gcc/ada/g-ssinty.ads deleted file mode 100644 index becdc7661d6..00000000000 --- a/gcc/ada/g-ssinty.ads +++ /dev/null @@ -1,77 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- G N A T . S S E . I N T E R N A L _ T Y P E S -- --- -- --- S p e c -- --- -- --- Copyright (C) 2009, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception 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/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - --- This unit exposes low level types to interface with the GCC vector --- builtins directly. These are useful for the development of higher level --- bindings to the reference Intel intrinsic operations. - --- See GNAT.SSE for the list of targets where this facility is supported. - -package GNAT.SSE.Internal_Types is - - type v4sf is private; - type v2df is private; - type v2di is private; - -private - - -- GCC'wise, vector operations operate on objects of vector modes, - -- conveyed through vector types obtained in C by setting an attribute on - -- what looks like a component typedef. For example, in xmmintrin.h: - -- - -- typedef float __v4sf __attribute__ ((__vector_size__ (16))); - - -- Applying a 'vector_size' machine attribute in Ada, as in - -- - -- type Vf is new Float; - -- pragma Machine_Attribute (Vf, "vector_size", 16); - -- - -- makes Vf a 16bytes long V4SFmode GCC type but the effect on the type - -- layout is not conveyed to the front-end. The latter still sees "Vf" - -- as a 4bytes long single float, with numerous potential pitfalls. - - -- We devised a 'vector_type' alternate machine attribute, which applies - -- to array types of the proper size and alignment from the front-end - -- perspective: - - type v4sf is array (1 .. 4) of GNAT.SSE.Float32; - for v4sf'Alignment use GNAT.SSE.VECTOR_ALIGN; - pragma Machine_Attribute (v4sf, "vector_type"); - - type v2di is array (1 .. 2) of GNAT.SSE.Integer64; - for v2di'Alignment use GNAT.SSE.VECTOR_ALIGN; - pragma Machine_Attribute (v2di, "vector_type"); - - type v2df is array (1 .. 2) of GNAT.SSE.Float64; - for v2df'Alignment use GNAT.SSE.VECTOR_ALIGN; - pragma Machine_Attribute (v2df, "vector_type"); - -end GNAT.SSE.Internal_Types; diff --git a/gcc/ada/g-ssvety.ads b/gcc/ada/g-ssvety.ads index 42e49bf5d83..c40706474a4 100644 --- a/gcc/ada/g-ssvety.ads +++ b/gcc/ada/g-ssvety.ads @@ -49,7 +49,7 @@ package GNAT.SSE.Vector_Types is -- access the byte elements and structures. -- -- * Use new data types only with the respective intrinsics described - -- in this documentation. >> + -- in this documentation. type m128 is private; -- SSE >= 1 type m128d is private; -- SSE >= 2 @@ -69,7 +69,7 @@ private -- typedef float __v4sf __attribute__ ((__vector_size__ (16))); ------------ - -- M128 -- + -- m128 -- ------------ -- The __m128 data type can hold four 32-bit floating-point values diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in index 9a28ea3ef48..c5efdb5d214 100644 --- a/gcc/ada/gcc-interface/Make-lang.in +++ b/gcc/ada/gcc-interface/Make-lang.in @@ -159,8 +159,8 @@ GNAT_ADA_OBJS = ada/s-bitops.o ada/ada.o ada/a-charac.o ada/a-chlat1.o ada/a-exc ada/sem_ch12.o ada/sem_ch13.o ada/sem_ch2.o ada/sem_ch3.o ada/sem_ch4.o \ ada/sem_ch5.o ada/sem_ch6.o ada/sem_ch7.o ada/sem_ch8.o ada/sem_ch9.o \ ada/sem_case.o ada/sem_disp.o ada/sem_dist.o ada/sem_elab.o ada/sem_elim.o \ - ada/sem_eval.o ada/sem_intr.o ada/sem_mech.o ada/sem_prag.o \ - ada/sem_res.o ada/sem_smem.o ada/sem_type.o ada/sem_util.o ada/sem_vfpt.o \ + ada/sem_eval.o ada/sem_intr.o ada/sem_mech.o ada/sem_prag.o ada/sem_res.o \ + ada/sem_scil.o ada/sem_smem.o ada/sem_type.o ada/sem_util.o ada/sem_vfpt.o \ ada/sem_warn.o ada/sinfo-cn.o ada/sinfo.o ada/sinput.o ada/sinput-d.o \ ada/sinput-l.o ada/snames.o ada/sprint.o ada/stand.o ada/stringt.o \ ada/style.o ada/styleg.o ada/switch.o ada/switch-c.o \ @@ -1303,18 +1303,18 @@ ada/checks.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/restrict.adb ada/rident.ads ada/rtsfind.ads ada/rtsfind.adb \ ada/sem.ads ada/sem_aux.ads ada/sem_cat.ads ada/sem_ch3.ads \ ada/sem_ch6.ads ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_dist.ads \ - ada/sem_eval.ads ada/sem_eval.adb ada/sem_res.ads ada/sem_type.ads \ - ada/sem_util.ads ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb \ - ada/sinput.ads ada/snames.ads ada/sprint.ads ada/stand.ads \ - ada/stringt.ads ada/stringt.adb ada/system.ads ada/s-exctab.ads \ - ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ - ada/s-parame.ads ada/s-rident.ads ada/s-soflin.ads ada/s-stache.ads \ - ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ - ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ - ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ - ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads ada/urealp.adb ada/validsw.ads + ada/sem_eval.ads ada/sem_eval.adb ada/sem_res.ads ada/sem_scil.ads \ + ada/sem_type.ads ada/sem_util.ads ada/sem_warn.ads ada/sinfo.ads \ + ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/sprint.ads \ + ada/stand.ads ada/stringt.ads ada/stringt.adb ada/system.ads \ + ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ + ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-soflin.ads \ + ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ + ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/urealp.adb ada/validsw.ads ada/comperr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -1350,19 +1350,20 @@ ada/cstand.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/rident.ads ada/rtsfind.ads ada/scans.ads ada/scn.ads ada/scng.ads \ ada/scng.adb ada/sem.ads ada/sem_attr.ads ada/sem_aux.ads \ ada/sem_ch8.ads ada/sem_disp.ads ada/sem_eval.ads ada/sem_mech.ads \ - ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \ - ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/sinput.adb \ - ada/snames.ads ada/stand.ads ada/stringt.ads ada/style.ads \ - ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ - ada/s-crc32.ads ada/s-crc32.adb ada/s-exctab.ads ada/s-htable.ads \ - ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ - ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ - ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ - ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ - ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ - ada/tree_io.ads ada/ttypef.ads ada/ttypes.ads ada/types.ads \ - ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/urealp.adb ada/widechar.ads + ada/sem_res.ads ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads \ + ada/sem_util.adb ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ + ada/sinput.adb ada/snames.ads ada/stand.ads ada/stringt.ads \ + ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ + ada/system.ads ada/s-crc32.ads ada/s-crc32.adb ada/s-exctab.ads \ + ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ + ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \ + ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads \ + ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ + ada/tbuild.ads ada/tree_io.ads ada/ttypef.ads ada/ttypes.ads \ + ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ + ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \ + ada/widechar.ads ada/debug.o : ada/debug.ads ada/debug.adb ada/system.ads @@ -1477,18 +1478,18 @@ ada/exp_aggr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_attr.ads ada/sem_aux.ads ada/sem_cat.ads ada/sem_ch3.ads \ ada/sem_ch6.ads ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_disp.ads \ ada/sem_dist.ads ada/sem_eval.ads ada/sem_eval.adb ada/sem_res.ads \ - ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \ - ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads \ - ada/sprint.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \ - ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ - ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-exctab.adb \ - ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ - ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \ - ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ - ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads \ - ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ - ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ - ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ + ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \ + ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ + ada/snames.ads ada/sprint.ads ada/stand.ads ada/stringt.ads \ + ada/stringt.adb ada/style.ads ada/styleg.ads ada/styleg.adb \ + ada/stylesw.ads ada/system.ads ada/s-crc32.ads ada/s-exctab.ads \ + ada/s-exctab.adb ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ + ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \ + ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ + ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ + ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ + ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ + ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads \ ada/widechar.ads @@ -1505,16 +1506,17 @@ ada/exp_atag.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads ada/restrict.ads \ ada/rident.ads ada/rtsfind.ads ada/rtsfind.adb ada/sem.ads \ ada/sem_aux.ads ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_dist.ads \ - ada/sem_eval.ads ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads \ - ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ - ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-htable.ads \ - ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ - ada/s-rident.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ - ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ - ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ - ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ - ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads + ada/sem_eval.ads ada/sem_res.ads ada/sem_scil.ads ada/sem_type.ads \ + ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ + ada/snames.ads ada/stand.ads ada/stringt.ads ada/system.ads \ + ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ + ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-soflin.ads \ + ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ + ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/exp_attr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -1535,19 +1537,20 @@ ada/exp_attr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/rtsfind.ads ada/scans.ads ada/scn.ads ada/scng.ads ada/scng.adb \ ada/sem.ads ada/sem_attr.ads ada/sem_aux.ads ada/sem_ch6.ads \ ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_disp.ads ada/sem_eval.ads \ - ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \ - ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ - ada/stringt.ads ada/stringt.adb ada/style.ads ada/styleg.ads \ - ada/styleg.adb ada/stylesw.ads ada/system.ads ada/s-carun8.ads \ - ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ - ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ - ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ - ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/types.adb \ - ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/widechar.ads + ada/sem_res.ads ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads \ + ada/sem_util.adb ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ + ada/snames.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \ + ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ + ada/system.ads ada/s-carun8.ads ada/s-crc32.ads ada/s-exctab.ads \ + ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ + ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \ + ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads \ + ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ + ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ + ada/types.ads ada/types.adb ada/uintp.ads ada/uintp.adb ada/uname.ads \ + ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads \ + ada/widechar.ads ada/exp_ch11.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -1638,16 +1641,16 @@ ada/exp_ch3.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/restrict.adb ada/rident.ads ada/rtsfind.ads ada/sem.ads \ ada/sem_attr.ads ada/sem_aux.ads ada/sem_cat.ads ada/sem_ch3.ads \ ada/sem_ch6.ads ada/sem_ch8.ads ada/sem_disp.ads ada/sem_eval.ads \ - ada/sem_mech.ads ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads \ - ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ - ada/snames.ads ada/sprint.ads ada/stand.ads ada/stringt.ads \ - ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ - ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ - ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ - ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ - ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ - ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ + ada/sem_mech.ads ada/sem_res.ads ada/sem_scil.ads ada/sem_type.ads \ + ada/sem_util.ads ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb \ + ada/sinput.ads ada/snames.ads ada/sprint.ads ada/stand.ads \ + ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-htable.ads \ + ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ + ada/s-rident.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ + ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ + ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ + ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ + ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/exp_ch4.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ @@ -1666,18 +1669,18 @@ ada/exp_ch4.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/restrict.ads ada/restrict.adb ada/rident.ads ada/rtsfind.ads \ ada/sem.ads ada/sem_aux.ads ada/sem_cat.ads ada/sem_ch13.ads \ ada/sem_ch3.ads ada/sem_ch6.ads ada/sem_ch8.ads ada/sem_eval.ads \ - ada/sem_eval.adb ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads \ - ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ - ada/snames.ads ada/sprint.ads ada/stand.ads ada/stringt.ads \ - ada/stringt.adb ada/system.ads ada/s-exctab.ads ada/s-exctab.adb \ - ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ - ada/s-parame.ads ada/s-rident.ads ada/s-soflin.ads ada/s-stache.ads \ - ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ - ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ - ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ - ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads ada/urealp.adb ada/validsw.ads + ada/sem_eval.adb ada/sem_res.ads ada/sem_scil.ads ada/sem_type.ads \ + ada/sem_util.ads ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb \ + ada/sinput.ads ada/snames.ads ada/sprint.ads ada/stand.ads \ + ada/stringt.ads ada/stringt.adb ada/system.ads ada/s-exctab.ads \ + ada/s-exctab.adb ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ + ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-soflin.ads \ + ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ + ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/urealp.adb ada/validsw.ads ada/exp_ch5.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -1696,20 +1699,20 @@ ada/exp_ch5.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/scans.ads ada/scn.ads ada/scng.ads ada/scng.adb ada/sem.ads \ ada/sem_attr.ads ada/sem_aux.ads ada/sem_cat.ads ada/sem_ch13.ads \ ada/sem_ch3.ads ada/sem_ch6.ads ada/sem_ch8.ads ada/sem_disp.ads \ - ada/sem_eval.ads ada/sem_eval.adb ada/sem_res.ads ada/sem_type.ads \ - ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads ada/sinfo.ads \ - ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/sprint.ads \ - ada/stand.ads ada/stringt.ads ada/stringt.adb ada/style.ads \ - ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ - ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ - ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ - ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ - ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ - ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads ada/validsw.ads ada/widechar.ads + ada/sem_eval.ads ada/sem_eval.adb ada/sem_res.ads ada/sem_scil.ads \ + ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \ + ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads \ + ada/sprint.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \ + ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ + ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads \ + ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ + ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ + ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ + ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ + ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/widechar.ads ada/exp_ch6.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -1732,19 +1735,19 @@ ada/exp_ch6.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_aux.ads ada/sem_ch12.ads ada/sem_ch13.ads ada/sem_ch3.ads \ ada/sem_ch6.ads ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_disp.ads \ ada/sem_dist.ads ada/sem_eval.ads ada/sem_mech.ads ada/sem_res.ads \ - ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \ - ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads \ - ada/sprint.ads ada/stand.ads ada/stringt.ads ada/style.ads \ - ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ - ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ - ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ - ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ - ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ - ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads ada/validsw.ads ada/widechar.ads + ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \ + ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ + ada/snames.ads ada/sprint.ads ada/stand.ads ada/stringt.ads \ + ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ + ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads \ + ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ + ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ + ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ + ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ + ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/widechar.ads ada/exp_ch7.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -1760,16 +1763,17 @@ ada/exp_ch7.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads ada/restrict.ads \ ada/restrict.adb ada/rident.ads ada/rtsfind.ads ada/sem.ads \ ada/sem_aux.ads ada/sem_ch3.ads ada/sem_ch7.ads ada/sem_ch8.ads \ - ada/sem_eval.ads ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads \ - ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ - ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-htable.ads \ - ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ - ada/s-rident.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ - ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ - ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ - ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ - ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads + ada/sem_eval.ads ada/sem_res.ads ada/sem_scil.ads ada/sem_type.ads \ + ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ + ada/snames.ads ada/stand.ads ada/stringt.ads ada/system.ads \ + ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ + ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-soflin.ads \ + ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ + ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/exp_ch8.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -1782,15 +1786,16 @@ ada/exp_ch8.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/lib.ads ada/namet.ads ada/nlists.ads ada/nlists.adb ada/nmake.ads \ ada/opt.ads ada/output.ads ada/restrict.ads ada/rident.ads \ ada/rtsfind.ads ada/sem.ads ada/sem_aux.ads ada/sem_ch8.ads \ - ada/sem_eval.ads ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads \ - ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ - ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-htable.ads \ - ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ - ada/s-rident.ads ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ - ada/targparm.ads ada/tbuild.ads ada/tree_io.ads ada/ttypes.ads \ - ada/types.ads ada/uintp.ads ada/uintp.adb ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/validsw.ads + ada/sem_eval.ads ada/sem_res.ads ada/sem_scil.ads ada/sem_type.ads \ + ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ + ada/snames.ads ada/stand.ads ada/stringt.ads ada/system.ads \ + ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ + ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-stalib.ads \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ + ada/uintp.adb ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads \ + ada/validsw.ads ada/exp_ch9.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -1809,8 +1814,8 @@ ada/exp_ch9.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/scn.ads ada/scng.ads ada/scng.adb ada/sem.ads ada/sem_attr.ads \ ada/sem_aux.ads ada/sem_ch11.ads ada/sem_ch6.ads ada/sem_ch8.ads \ ada/sem_disp.ads ada/sem_elab.ads ada/sem_eval.ads ada/sem_res.ads \ - ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sinfo.ads \ - ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ + ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \ + ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ ada/stringt.ads ada/style.ads ada/styleg.ads ada/styleg.adb \ ada/stylesw.ads ada/system.ads ada/s-crc32.ads ada/s-exctab.ads \ ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ @@ -1837,9 +1842,9 @@ ada/exp_code.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/rident.ads ada/rtsfind.ads ada/scans.ads ada/scn.ads ada/scng.ads \ ada/scng.adb ada/sem.ads ada/sem_attr.ads ada/sem_aux.ads \ ada/sem_cat.ads ada/sem_ch6.ads ada/sem_ch8.ads ada/sem_disp.ads \ - ada/sem_eval.ads ada/sem_eval.adb ada/sem_res.ads ada/sem_type.ads \ - ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads ada/sinfo.ads \ - ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ + ada/sem_eval.ads ada/sem_eval.adb ada/sem_res.ads ada/sem_scil.ads \ + ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \ + ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ ada/stringt.ads ada/stringt.adb ada/style.ads ada/styleg.ads \ ada/styleg.adb ada/stylesw.ads ada/system.ads ada/s-carun8.ads \ ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ @@ -1885,19 +1890,20 @@ ada/exp_disp.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/rtsfind.ads ada/scans.ads ada/scn.ads ada/scng.ads ada/scng.adb \ ada/sem.ads ada/sem_attr.ads ada/sem_aux.ads ada/sem_ch6.ads \ ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_disp.ads ada/sem_eval.ads \ - ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \ - ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ - ada/stringt.ads ada/stringt.adb ada/style.ads ada/styleg.ads \ - ada/styleg.adb ada/stylesw.ads ada/system.ads ada/s-carun8.ads \ - ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ - ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ - ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ - ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/types.adb \ - ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/widechar.ads + ada/sem_res.ads ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads \ + ada/sem_util.adb ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ + ada/snames.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \ + ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ + ada/system.ads ada/s-carun8.ads ada/s-crc32.ads ada/s-exctab.ads \ + ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ + ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \ + ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads \ + ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ + ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ + ada/types.ads ada/types.adb ada/uintp.ads ada/uintp.adb ada/uname.ads \ + ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads \ + ada/widechar.ads ada/exp_dist.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -1979,17 +1985,18 @@ ada/exp_intr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads ada/restrict.ads \ ada/restrict.adb ada/rident.ads ada/rtsfind.ads ada/sem.ads \ ada/sem_aux.ads ada/sem_ch8.ads ada/sem_eval.ads ada/sem_res.ads \ - ada/sem_type.ads ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb \ - ada/sinput.ads ada/sinput.adb ada/snames.ads ada/stand.ads \ - ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-htable.ads \ - ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ - ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ - ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ - ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ - ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ - ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads ada/urealp.adb ada/validsw.ads ada/widechar.ads + ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads ada/sinfo.ads \ + ada/sinfo.adb ada/sinput.ads ada/sinput.adb ada/snames.ads \ + ada/stand.ads ada/stringt.ads ada/system.ads ada/s-exctab.ads \ + ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ + ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \ + ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ + ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/urealp.adb ada/validsw.ads \ + ada/widechar.ads ada/exp_pakd.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -2004,17 +2011,17 @@ ada/exp_pakd.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads \ ada/restrict.ads ada/rident.ads ada/rtsfind.ads ada/sem.ads \ ada/sem_aux.ads ada/sem_ch13.ads ada/sem_ch3.ads ada/sem_ch8.ads \ - ada/sem_eval.ads ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads \ - ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ - ada/snames.ads ada/sprint.ads ada/stand.ads ada/stringt.ads \ - ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ - ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ - ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ - ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ - ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ - ada/types.ads ada/uintp.ads ada/uintp.adb ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/validsw.ads + ada/sem_eval.ads ada/sem_res.ads ada/sem_scil.ads ada/sem_type.ads \ + ada/sem_util.ads ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb \ + ada/sinput.ads ada/snames.ads ada/sprint.ads ada/stand.ads \ + ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-htable.ads \ + ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ + ada/s-rident.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ + ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ + ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ + ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ + ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb \ + ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/exp_prag.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -2119,18 +2126,18 @@ ada/exp_util.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads ada/restrict.ads \ ada/restrict.adb ada/rident.ads ada/rtsfind.ads ada/sem.ads \ ada/sem_aux.ads ada/sem_cat.ads ada/sem_ch6.ads ada/sem_ch8.ads \ - ada/sem_eval.ads ada/sem_eval.adb ada/sem_res.ads ada/sem_type.ads \ - ada/sem_util.ads ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb \ - ada/sinput.ads ada/snames.ads ada/stand.ads ada/stringt.ads \ - ada/stringt.adb ada/system.ads ada/s-exctab.ads ada/s-htable.ads \ - ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ - ada/s-rident.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ - ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ - ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ - ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ - ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \ - ada/validsw.ads + ada/sem_eval.ads ada/sem_eval.adb ada/sem_res.ads ada/sem_scil.ads \ + ada/sem_type.ads ada/sem_util.ads ada/sem_warn.ads ada/sinfo.ads \ + ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ + ada/stringt.ads ada/stringt.adb ada/system.ads ada/s-exctab.ads \ + ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ + ada/s-parame.ads ada/s-rident.ads ada/s-soflin.ads ada/s-stache.ads \ + ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ + ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \ + ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ + ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ + ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ + ada/urealp.ads ada/urealp.adb ada/validsw.ads ada/exp_vfpt.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -2215,19 +2222,19 @@ ada/freeze.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_ch6.ads ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_disp.ads \ ada/sem_dist.ads ada/sem_elab.ads ada/sem_elim.ads ada/sem_eval.ads \ ada/sem_intr.ads ada/sem_mech.ads ada/sem_prag.ads ada/sem_res.ads \ - ada/sem_res.adb ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \ - ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ - ada/snames.ads ada/stand.ads ada/stringt.ads ada/style.ads \ - ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ - ada/s-crc32.ads ada/s-exctab.ads ada/s-exctab.adb ada/s-htable.ads \ - ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ - ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ - ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ - ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ - ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ - ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ - ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads ada/validsw.ads ada/widechar.ads + ada/sem_res.adb ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads \ + ada/sem_util.adb ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb \ + ada/sinput.ads ada/snames.ads ada/stand.ads ada/stringt.ads \ + ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ + ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-exctab.adb \ + ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ + ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \ + ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads \ + ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ + ada/tbuild.ads ada/tree_io.ads ada/ttypes.ads ada/types.ads \ + ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/widechar.ads ada/frontend.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -2244,17 +2251,17 @@ ada/frontend.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/restrict.ads ada/restrict.adb ada/rident.ads ada/rtsfind.ads \ ada/scans.ads ada/scn.ads ada/scng.ads ada/scng.adb ada/sem.ads \ ada/sem_aux.ads ada/sem_ch8.ads ada/sem_elab.ads ada/sem_prag.ads \ - ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ - ada/sinput.adb ada/sinput-l.ads ada/snames.ads ada/sprint.ads \ - ada/stand.ads ada/stringt.ads ada/style.ads ada/styleg.ads \ - ada/styleg.adb ada/stylesw.ads ada/system.ads ada/s-crc32.ads \ - ada/s-crc32.adb ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ - ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ - ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ - ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ - ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ - ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ + ada/sem_scil.ads ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb \ + ada/sinput.ads ada/sinput.adb ada/sinput-l.ads ada/snames.ads \ + ada/sprint.ads ada/stand.ads ada/stringt.ads ada/style.ads \ + ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ + ada/s-crc32.ads ada/s-crc32.adb ada/s-exctab.ads ada/s-htable.ads \ + ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ + ada/s-rident.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ + ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ + ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ + ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ + ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads ada/g-byorma.o : ada/gnat.ads ada/g-byorma.ads ada/g-byorma.adb \ @@ -2435,8 +2442,8 @@ ada/layout.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/rtsfind.ads ada/scans.ads ada/scn.ads ada/scng.ads ada/scng.adb \ ada/sem.ads ada/sem_attr.ads ada/sem_aux.ads ada/sem_ch13.ads \ ada/sem_ch8.ads ada/sem_disp.ads ada/sem_eval.ads ada/sem_res.ads \ - ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sinfo.ads \ - ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ + ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \ + ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ ada/stringt.ads ada/style.ads ada/styleg.ads ada/styleg.adb \ ada/stylesw.ads ada/system.ads ada/s-crc32.ads ada/s-exctab.ads \ ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ @@ -3024,20 +3031,20 @@ ada/sem_aggr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/scng.adb ada/sem.ads ada/sem_aggr.ads ada/sem_aggr.adb \ ada/sem_attr.ads ada/sem_aux.ads ada/sem_cat.ads ada/sem_ch13.ads \ ada/sem_ch3.ads ada/sem_ch6.ads ada/sem_ch8.ads ada/sem_disp.ads \ - ada/sem_eval.ads ada/sem_eval.adb ada/sem_res.ads ada/sem_type.ads \ - ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads ada/sinfo.ads \ - ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/sprint.ads \ - ada/stand.ads ada/stringt.ads ada/stringt.adb ada/style.ads \ - ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ - ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ - ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ - ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ - ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ - ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads ada/validsw.ads ada/widechar.ads + ada/sem_eval.ads ada/sem_eval.adb ada/sem_res.ads ada/sem_scil.ads \ + ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \ + ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads \ + ada/sprint.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \ + ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ + ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads \ + ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ + ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ + ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ + ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ + ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/widechar.ads ada/sem_attr.o : ada/ada.ads ada/a-charac.ads ada/a-chlat1.ads \ ada/a-except.ads ada/a-unccon.ads ada/a-uncdea.ads ada/alloc.ads \ @@ -3058,21 +3065,21 @@ ada/sem_attr.o : ada/ada.ads ada/a-charac.ads ada/a-chlat1.ads \ ada/sem_ch13.ads ada/sem_ch3.ads ada/sem_ch4.ads ada/sem_ch6.ads \ ada/sem_ch8.ads ada/sem_disp.ads ada/sem_dist.ads ada/sem_elab.ads \ ada/sem_elim.ads ada/sem_eval.ads ada/sem_eval.adb ada/sem_intr.ads \ - ada/sem_res.ads ada/sem_res.adb ada/sem_type.ads ada/sem_util.ads \ - ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ - ada/sinput.adb ada/snames.ads ada/snames.adb ada/sprint.ads \ - ada/stand.ads ada/stringt.ads ada/stringt.adb ada/style.ads \ - ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ - ada/s-carun8.ads ada/s-exctab.ads ada/s-exctab.adb ada/s-htable.ads \ - ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ - ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ - ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ - ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ - ada/tree_io.ads ada/ttypef.ads ada/ttypes.ads ada/types.ads \ - ada/types.adb ada/uintp.ads ada/uintp.adb ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/urealp.adb ada/validsw.ads \ - ada/widechar.ads + ada/sem_res.ads ada/sem_res.adb ada/sem_scil.ads ada/sem_type.ads \ + ada/sem_util.ads ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb \ + ada/sinput.ads ada/sinput.adb ada/snames.ads ada/snames.adb \ + ada/sprint.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \ + ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ + ada/system.ads ada/s-carun8.ads ada/s-exctab.ads ada/s-exctab.adb \ + ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ + ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \ + ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tbuild.adb ada/tree_io.ads ada/ttypef.ads ada/ttypes.ads \ + ada/types.ads ada/types.adb ada/uintp.ads ada/uintp.adb \ + ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \ + ada/validsw.ads ada/widechar.ads ada/sem_aux.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -3118,18 +3125,19 @@ ada/sem_cat.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/output.ads ada/rident.ads ada/rtsfind.ads ada/scans.ads ada/scn.ads \ ada/scng.ads ada/scng.adb ada/sem.ads ada/sem_attr.ads ada/sem_aux.ads \ ada/sem_cat.ads ada/sem_cat.adb ada/sem_ch8.ads ada/sem_disp.ads \ - ada/sem_eval.ads ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads \ - ada/sem_util.adb ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ - ada/snames.ads ada/stand.ads ada/stringt.ads ada/style.ads \ - ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ - ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ - ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ - ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tree_io.ads \ - ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ - ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads + ada/sem_eval.ads ada/sem_res.ads ada/sem_scil.ads ada/sem_type.ads \ + ada/sem_util.ads ada/sem_util.adb ada/sinfo.ads ada/sinfo.adb \ + ada/sinput.ads ada/snames.ads ada/stand.ads ada/stringt.ads \ + ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ + ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads \ + ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ + ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ + ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ + ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ + ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ + ada/urealp.ads ada/widechar.ads ada/sem_ch10.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -3147,19 +3155,20 @@ ada/sem_ch10.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/scng.adb ada/sem.ads ada/sem_attr.ads ada/sem_aux.ads \ ada/sem_ch10.ads ada/sem_ch10.adb ada/sem_ch3.ads ada/sem_ch6.ads \ ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_disp.ads ada/sem_dist.ads \ - ada/sem_eval.ads ada/sem_prag.ads ada/sem_res.ads ada/sem_type.ads \ - ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads ada/sinfo.ads \ - ada/sinfo.adb ada/sinfo-cn.ads ada/sinput.ads ada/sinput.adb \ - ada/snames.ads ada/stand.ads ada/stringt.ads ada/style.ads \ - ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ - ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ - ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ - ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tree_io.ads \ - ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ - ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads + ada/sem_eval.ads ada/sem_prag.ads ada/sem_res.ads ada/sem_scil.ads \ + ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \ + ada/sinfo.ads ada/sinfo.adb ada/sinfo-cn.ads ada/sinput.ads \ + ada/sinput.adb ada/snames.ads ada/stand.ads ada/stringt.ads \ + ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ + ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads \ + ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ + ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ + ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ + ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ + ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ + ada/urealp.ads ada/widechar.ads ada/sem_ch11.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -3199,20 +3208,20 @@ ada/sem_ch12.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_ch12.adb ada/sem_ch13.ads ada/sem_ch3.ads ada/sem_ch6.ads \ ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_disp.ads ada/sem_dist.ads \ ada/sem_elab.ads ada/sem_elim.ads ada/sem_eval.ads ada/sem_res.ads \ - ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \ - ada/sinfo.ads ada/sinfo.adb ada/sinfo-cn.ads ada/sinput.ads \ - ada/sinput-l.ads ada/snames.ads ada/stand.ads ada/stringt.ads \ - ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ - ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-exctab.adb \ - ada/s-htable.ads ada/s-htable.adb ada/s-imenne.ads ada/s-memory.ads \ - ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \ - ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ - ada/s-stoele.adb ada/s-strhas.ads ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ - ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ - ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads ada/urealp.adb ada/widechar.ads + ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \ + ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinfo-cn.ads \ + ada/sinput.ads ada/sinput-l.ads ada/snames.ads ada/stand.ads \ + ada/stringt.ads ada/style.ads ada/styleg.ads ada/styleg.adb \ + ada/stylesw.ads ada/system.ads ada/s-crc32.ads ada/s-exctab.ads \ + ada/s-exctab.adb ada/s-htable.ads ada/s-htable.adb ada/s-imenne.ads \ + ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ + ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ + ada/s-stoele.ads ada/s-stoele.adb ada/s-strhas.ads ada/s-string.ads \ + ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ + ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/urealp.adb ada/widechar.ads ada/sem_ch13.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -3272,20 +3281,21 @@ ada/sem_ch3.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_cat.adb ada/sem_ch13.ads ada/sem_ch3.ads ada/sem_ch3.adb \ ada/sem_ch6.ads ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_disp.ads \ ada/sem_dist.ads ada/sem_elim.ads ada/sem_eval.ads ada/sem_eval.adb \ - ada/sem_mech.ads ada/sem_res.ads ada/sem_smem.ads ada/sem_type.ads \ - ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads ada/sinfo.ads \ - ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/sprint.ads \ - ada/stand.ads ada/stringt.ads ada/stringt.adb ada/style.ads \ - ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ - ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ - ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ - ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ - ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ - ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads ada/urealp.adb ada/validsw.ads ada/widechar.ads + ada/sem_mech.ads ada/sem_res.ads ada/sem_scil.ads ada/sem_smem.ads \ + ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \ + ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads \ + ada/sprint.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \ + ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ + ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads \ + ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ + ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ + ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ + ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ + ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/urealp.adb ada/validsw.ads \ + ada/widechar.ads ada/sem_ch4.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -3305,19 +3315,19 @@ ada/sem_ch4.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_ch13.ads ada/sem_ch3.ads ada/sem_ch4.ads ada/sem_ch4.adb \ ada/sem_ch6.ads ada/sem_ch8.ads ada/sem_disp.ads ada/sem_dist.ads \ ada/sem_elab.ads ada/sem_elim.ads ada/sem_eval.ads ada/sem_intr.ads \ - ada/sem_res.ads ada/sem_res.adb ada/sem_type.ads ada/sem_util.ads \ - ada/sem_util.adb ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb \ - ada/sinput.ads ada/snames.ads ada/stand.ads ada/stringt.ads \ - ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ - ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads \ - ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ - ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ - ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ - ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ - ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ - ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ - ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/widechar.ads + ada/sem_res.ads ada/sem_res.adb ada/sem_scil.ads ada/sem_type.ads \ + ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads ada/sinfo.ads \ + ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ + ada/stringt.ads ada/style.ads ada/styleg.ads ada/styleg.adb \ + ada/stylesw.ads ada/system.ads ada/s-crc32.ads ada/s-exctab.ads \ + ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ + ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \ + ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads \ + ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ + ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ + ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ + ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads ada/sem_ch5.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -3338,20 +3348,20 @@ ada/sem_ch5.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_ch4.ads ada/sem_ch5.ads ada/sem_ch5.adb ada/sem_ch6.ads \ ada/sem_ch8.ads ada/sem_disp.ads ada/sem_dist.ads ada/sem_elab.ads \ ada/sem_elim.ads ada/sem_eval.ads ada/sem_eval.adb ada/sem_intr.ads \ - ada/sem_res.ads ada/sem_res.adb ada/sem_type.ads ada/sem_util.ads \ - ada/sem_util.adb ada/sem_warn.ads ada/sem_warn.adb ada/sinfo.ads \ - ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/sprint.ads \ - ada/stand.ads ada/stringt.ads ada/stringt.adb ada/style.ads \ - ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ - ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ - ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ - ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tree_io.ads \ - ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ - ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads \ - ada/widechar.ads + ada/sem_res.ads ada/sem_res.adb ada/sem_scil.ads ada/sem_type.ads \ + ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads ada/sem_warn.adb \ + ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads \ + ada/sprint.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \ + ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ + ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads \ + ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ + ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ + ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ + ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ + ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ + ada/urealp.ads ada/validsw.ads ada/widechar.ads ada/sem_ch6.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -3371,21 +3381,21 @@ ada/sem_ch6.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_ch10.ads ada/sem_ch12.ads ada/sem_ch3.ads ada/sem_ch4.ads \ ada/sem_ch5.ads ada/sem_ch6.ads ada/sem_ch6.adb ada/sem_ch8.ads \ ada/sem_disp.ads ada/sem_dist.ads ada/sem_elim.ads ada/sem_eval.ads \ - ada/sem_mech.ads ada/sem_prag.ads ada/sem_res.ads ada/sem_type.ads \ - ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads ada/sinfo.ads \ - ada/sinfo.adb ada/sinfo-cn.ads ada/sinput.ads ada/sinput.adb \ - ada/snames.ads ada/snames.adb ada/stand.ads ada/stringt.ads \ - ada/stringt.adb ada/style.ads ada/styleg.ads ada/styleg.adb \ - ada/stylesw.ads ada/system.ads ada/s-carun8.ads ada/s-crc32.ads \ - ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ - ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \ - ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ - ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ - ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ - ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ - ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ - ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads \ - ada/widechar.ads + ada/sem_mech.ads ada/sem_prag.ads ada/sem_res.ads ada/sem_scil.ads \ + ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \ + ada/sinfo.ads ada/sinfo.adb ada/sinfo-cn.ads ada/sinput.ads \ + ada/sinput.adb ada/snames.ads ada/snames.adb ada/stand.ads \ + ada/stringt.ads ada/stringt.adb ada/style.ads ada/styleg.ads \ + ada/styleg.adb ada/stylesw.ads ada/system.ads ada/s-carun8.ads \ + ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ + ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ + ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ + ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ + ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ + ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ + ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ + ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ + ada/urealp.ads ada/validsw.ads ada/widechar.ads ada/sem_ch7.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -3403,19 +3413,19 @@ ada/sem_ch7.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_cat.ads ada/sem_ch10.ads ada/sem_ch12.ads ada/sem_ch3.ads \ ada/sem_ch6.ads ada/sem_ch7.ads ada/sem_ch7.adb ada/sem_ch8.ads \ ada/sem_disp.ads ada/sem_eval.ads ada/sem_prag.ads ada/sem_res.ads \ - ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \ - ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/sinput.adb \ - ada/snames.ads ada/snames.adb ada/stand.ads ada/stringt.ads \ - ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ - ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads \ - ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ - ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ - ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ - ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ - ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ - ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ - ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads ada/widechar.ads + ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \ + ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ + ada/sinput.adb ada/snames.ads ada/snames.adb ada/stand.ads \ + ada/stringt.ads ada/style.ads ada/styleg.ads ada/styleg.adb \ + ada/stylesw.ads ada/system.ads ada/s-crc32.ads ada/s-exctab.ads \ + ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ + ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \ + ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads \ + ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ + ada/tbuild.ads ada/tree_io.ads ada/ttypes.ads ada/types.ads \ + ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/widechar.ads ada/sem_ch8.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -3436,18 +3446,18 @@ ada/sem_ch8.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_ch13.ads ada/sem_ch3.ads ada/sem_ch4.ads ada/sem_ch6.ads \ ada/sem_ch8.ads ada/sem_ch8.adb ada/sem_disp.ads ada/sem_dist.ads \ ada/sem_elab.ads ada/sem_elim.ads ada/sem_eval.ads ada/sem_intr.ads \ - ada/sem_res.ads ada/sem_res.adb ada/sem_type.ads ada/sem_util.ads \ - ada/sem_util.adb ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb \ - ada/sinfo-cn.ads ada/sinput.ads ada/sinput.adb ada/snames.ads \ - ada/stand.ads ada/stringt.ads ada/style.ads ada/styleg.ads \ - ada/styleg.adb ada/stylesw.ads ada/system.ads ada/s-crc32.ads \ - ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ - ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \ - ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ - ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ - ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ - ada/targparm.ads ada/tbuild.ads ada/tree_io.ads ada/ttypes.ads \ - ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ + ada/sem_res.ads ada/sem_res.adb ada/sem_scil.ads ada/sem_type.ads \ + ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads ada/sinfo.ads \ + ada/sinfo.adb ada/sinfo-cn.ads ada/sinput.ads ada/sinput.adb \ + ada/snames.ads ada/stand.ads ada/stringt.ads ada/style.ads \ + ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ + ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ + ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ + ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ + ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ + ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ + ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tree_io.ads \ + ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads ada/sem_ch9.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ @@ -3469,19 +3479,19 @@ ada/sem_ch9.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_ch6.ads ada/sem_ch8.ads ada/sem_ch9.ads ada/sem_ch9.adb \ ada/sem_disp.ads ada/sem_dist.ads ada/sem_elab.ads ada/sem_elim.ads \ ada/sem_eval.ads ada/sem_intr.ads ada/sem_res.ads ada/sem_res.adb \ - ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \ - ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/sinput.adb \ - ada/snames.ads ada/sprint.ads ada/stand.ads ada/stringt.ads \ - ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ - ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads \ - ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ - ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ - ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ - ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ - ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ - ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ - ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads ada/validsw.ads ada/widechar.ads + ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \ + ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ + ada/sinput.adb ada/snames.ads ada/sprint.ads ada/stand.ads \ + ada/stringt.ads ada/style.ads ada/styleg.ads ada/styleg.adb \ + ada/stylesw.ads ada/system.ads ada/s-crc32.ads ada/s-exctab.ads \ + ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ + ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \ + ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads \ + ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ + ada/tbuild.ads ada/tree_io.ads ada/ttypes.ads ada/types.ads \ + ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/widechar.ads ada/sem_disp.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -3499,19 +3509,19 @@ ada/sem_disp.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/scans.ads ada/scn.ads ada/scng.ads ada/scng.adb ada/sem.ads \ ada/sem_attr.ads ada/sem_aux.ads ada/sem_ch3.ads ada/sem_ch6.ads \ ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_disp.ads ada/sem_disp.adb \ - ada/sem_eval.ads ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads \ - ada/sem_util.adb ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ - ada/snames.ads ada/stand.ads ada/stringt.ads ada/style.ads \ - ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ - ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ - ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ - ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tree_io.ads \ - ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ - ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads \ - ada/widechar.ads + ada/sem_eval.ads ada/sem_res.ads ada/sem_scil.ads ada/sem_type.ads \ + ada/sem_util.ads ada/sem_util.adb ada/sinfo.ads ada/sinfo.adb \ + ada/sinput.ads ada/snames.ads ada/stand.ads ada/stringt.ads \ + ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ + ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads \ + ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ + ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ + ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ + ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ + ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ + ada/urealp.ads ada/validsw.ads ada/widechar.ads ada/sem_dist.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -3546,18 +3556,18 @@ ada/sem_elab.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/rtsfind.ads ada/scans.ads ada/scn.ads ada/scng.ads ada/scng.adb \ ada/sem.ads ada/sem_attr.ads ada/sem_aux.ads ada/sem_cat.ads \ ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_disp.ads ada/sem_elab.ads \ - ada/sem_elab.adb ada/sem_eval.ads ada/sem_res.ads ada/sem_type.ads \ - ada/sem_util.ads ada/sem_util.adb ada/sinfo.ads ada/sinfo.adb \ - ada/sinput.ads ada/sinput.adb ada/snames.ads ada/stand.ads \ - ada/stringt.ads ada/style.ads ada/styleg.ads ada/styleg.adb \ - ada/stylesw.ads ada/system.ads ada/s-crc32.ads ada/s-exctab.ads \ - ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ - ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \ - ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ - ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads \ - ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ - ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ - ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ + ada/sem_elab.adb ada/sem_eval.ads ada/sem_res.ads ada/sem_scil.ads \ + ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sinfo.ads \ + ada/sinfo.adb ada/sinput.ads ada/sinput.adb ada/snames.ads \ + ada/stand.ads ada/stringt.ads ada/style.ads ada/styleg.ads \ + ada/styleg.adb ada/stylesw.ads ada/system.ads ada/s-crc32.ads \ + ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ + ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \ + ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ + ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ + ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ + ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ + ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads ada/sem_elim.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ @@ -3594,19 +3604,19 @@ ada/sem_eval.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_ch4.ads ada/sem_ch6.ads ada/sem_ch8.ads ada/sem_disp.ads \ ada/sem_dist.ads ada/sem_elab.ads ada/sem_elim.ads ada/sem_eval.ads \ ada/sem_eval.adb ada/sem_intr.ads ada/sem_res.ads ada/sem_res.adb \ - ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \ - ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ - ada/stringt.ads ada/stringt.adb ada/style.ads ada/styleg.ads \ - ada/styleg.adb ada/stylesw.ads ada/system.ads ada/s-crc32.ads \ - ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ - ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \ - ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ - ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ - ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ - ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ - ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ - ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \ - ada/widechar.ads + ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \ + ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ + ada/snames.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \ + ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ + ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads \ + ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ + ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ + ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ + ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ + ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ + ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/urealp.adb ada/widechar.ads ada/sem_intr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -3662,21 +3672,22 @@ ada/sem_prag.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_ch8.ads ada/sem_disp.ads ada/sem_dist.ads ada/sem_elab.ads \ ada/sem_elim.ads ada/sem_eval.ads ada/sem_eval.adb ada/sem_intr.ads \ ada/sem_mech.ads ada/sem_prag.ads ada/sem_prag.adb ada/sem_res.ads \ - ada/sem_res.adb ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \ - ada/sem_vfpt.ads ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb \ - ada/sinfo-cn.ads ada/sinput.ads ada/sinput.adb ada/snames.ads \ - ada/snames.adb ada/stand.ads ada/stringt.ads ada/stringt.adb \ - ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ - ada/system.ads ada/s-carun8.ads ada/s-crc32.ads ada/s-exctab.ads \ - ada/s-exctab.adb ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ - ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \ - ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ - ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ - ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ - ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ - ada/ttypes.ads ada/types.ads ada/types.adb ada/uintp.ads ada/uintp.adb \ - ada/uname.ads ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads \ - ada/urealp.adb ada/validsw.ads ada/widechar.ads + ada/sem_res.adb ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads \ + ada/sem_util.adb ada/sem_vfpt.ads ada/sem_warn.ads ada/sinfo.ads \ + ada/sinfo.adb ada/sinfo-cn.ads ada/sinput.ads ada/sinput.adb \ + ada/snames.ads ada/snames.adb ada/stand.ads ada/stringt.ads \ + ada/stringt.adb ada/style.ads ada/styleg.ads ada/styleg.adb \ + ada/stylesw.ads ada/system.ads ada/s-carun8.ads ada/s-crc32.ads \ + ada/s-exctab.ads ada/s-exctab.adb ada/s-htable.ads ada/s-imenne.ads \ + ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ + ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ + ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ + ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ + ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ + ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/types.adb \ + ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/urealp.adb ada/validsw.ads \ + ada/widechar.ads ada/sem_res.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -3699,21 +3710,35 @@ ada/sem_res.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_ch13.ads ada/sem_ch3.ads ada/sem_ch4.ads ada/sem_ch6.ads \ ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_disp.ads ada/sem_dist.ads \ ada/sem_elab.ads ada/sem_elim.ads ada/sem_eval.ads ada/sem_eval.adb \ - ada/sem_intr.ads ada/sem_res.ads ada/sem_res.adb ada/sem_type.ads \ - ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads ada/sinfo.ads \ - ada/sinfo.adb ada/sinput.ads ada/sinput.adb ada/snames.ads \ - ada/sprint.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \ - ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ - ada/system.ads ada/s-carun8.ads ada/s-crc32.ads ada/s-exctab.ads \ + ada/sem_intr.ads ada/sem_res.ads ada/sem_res.adb ada/sem_scil.ads \ + ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \ + ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/sinput.adb \ + ada/snames.ads ada/sprint.ads ada/stand.ads ada/stringt.ads \ + ada/stringt.adb ada/style.ads ada/styleg.ads ada/styleg.adb \ + ada/stylesw.ads ada/system.ads ada/s-carun8.ads ada/s-crc32.ads \ + ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ + ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \ + ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ + ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ + ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ + ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ + ada/ttypes.ads ada/types.ads ada/types.adb ada/uintp.ads ada/uintp.adb \ + ada/uname.ads ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads \ + ada/urealp.adb ada/validsw.ads ada/widechar.ads + +ada/sem_scil.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ + ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ + ada/casing.ads ada/debug.ads ada/einfo.ads ada/einfo.adb ada/gnat.ads \ + ada/g-htable.ads ada/hostparm.ads ada/namet.ads ada/nlists.ads \ + ada/nlists.adb ada/nmake.ads ada/opt.ads ada/output.ads ada/rtsfind.ads \ + ada/sem.ads ada/sem_aux.ads ada/sem_scil.ads ada/sem_scil.adb \ + ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ + ada/snames.ads ada/stand.ads ada/system.ads ada/s-exctab.ads \ ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ - ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \ - ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ - ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads \ - ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ - ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ - ada/types.ads ada/types.adb ada/uintp.ads ada/uintp.adb ada/uname.ads \ - ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \ - ada/validsw.ads ada/widechar.ads + ada/s-parame.ads ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads \ + ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ + ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uintp.adb \ + ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/sem_smem.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -3743,18 +3768,18 @@ ada/sem_type.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/scn.ads ada/scng.ads ada/scng.adb ada/sem.ads ada/sem_attr.ads \ ada/sem_aux.ads ada/sem_ch12.ads ada/sem_ch6.ads ada/sem_ch8.ads \ ada/sem_disp.ads ada/sem_dist.ads ada/sem_eval.ads ada/sem_res.ads \ - ada/sem_type.ads ada/sem_type.adb ada/sem_util.ads ada/sem_util.adb \ - ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ - ada/stringt.ads ada/style.ads ada/styleg.ads ada/styleg.adb \ - ada/stylesw.ads ada/system.ads ada/s-crc32.ads ada/s-exctab.ads \ - ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ - ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \ - ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ - ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads \ - ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ - ada/tbuild.ads ada/tree_io.ads ada/ttypes.ads ada/types.ads \ - ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/widechar.ads + ada/sem_scil.ads ada/sem_type.ads ada/sem_type.adb ada/sem_util.ads \ + ada/sem_util.adb ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ + ada/snames.ads ada/stand.ads ada/stringt.ads ada/style.ads \ + ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ + ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ + ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ + ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ + ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ + ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ + ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tree_io.ads \ + ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ + ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads ada/sem_util.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \ @@ -3771,19 +3796,19 @@ ada/sem_util.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/scn.ads ada/scng.ads ada/scng.adb ada/sem.ads ada/sem_attr.ads \ ada/sem_aux.ads ada/sem_cat.ads ada/sem_ch6.ads ada/sem_ch8.ads \ ada/sem_disp.ads ada/sem_eval.ads ada/sem_eval.adb ada/sem_res.ads \ - ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \ - ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/sinput.adb \ - ada/snames.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \ - ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ - ada/system.ads ada/s-carun8.ads ada/s-crc32.ads ada/s-crc32.adb \ - ada/s-exctab.ads ada/s-htable.ads ada/s-htable.adb ada/s-imenne.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ - ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ - ada/s-stoele.ads ada/s-stoele.adb ada/s-strhas.ads ada/s-string.ads \ - ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \ - ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ - ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ - ada/types.adb ada/uintp.ads ada/uintp.adb ada/uname.ads \ + ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \ + ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \ + ada/sinput.adb ada/snames.ads ada/stand.ads ada/stringt.ads \ + ada/stringt.adb ada/style.ads ada/styleg.ads ada/styleg.adb \ + ada/stylesw.ads ada/system.ads ada/s-carun8.ads ada/s-crc32.ads \ + ada/s-crc32.adb ada/s-exctab.ads ada/s-htable.ads ada/s-htable.adb \ + ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ + ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ + ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-strhas.ads \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads \ + ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ + ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ + ada/types.ads ada/types.adb ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \ ada/widechar.ads @@ -3814,18 +3839,18 @@ ada/sem_warn.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/output.ads ada/par_sco.ads ada/rident.ads ada/rtsfind.ads \ ada/scans.ads ada/scn.ads ada/scng.ads ada/scng.adb ada/sem.ads \ ada/sem_attr.ads ada/sem_aux.ads ada/sem_ch8.ads ada/sem_disp.ads \ - ada/sem_eval.ads ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads \ - ada/sem_util.adb ada/sem_warn.ads ada/sem_warn.adb ada/sinfo.ads \ - ada/sinfo.adb ada/sinput.ads ada/sinput.adb ada/snames.ads \ - ada/stand.ads ada/stringt.ads ada/style.ads ada/styleg.ads \ - ada/styleg.adb ada/stylesw.ads ada/system.ads ada/s-crc32.ads \ - ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ - ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \ - ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ - ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ - ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ - ada/targparm.ads ada/tbuild.ads ada/tree_io.ads ada/ttypes.ads \ - ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ + ada/sem_eval.ads ada/sem_res.ads ada/sem_scil.ads ada/sem_type.ads \ + ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads ada/sem_warn.adb \ + ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/sinput.adb \ + ada/snames.ads ada/stand.ads ada/stringt.ads ada/style.ads \ + ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ + ada/s-crc32.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ + ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ + ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ + ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ + ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ + ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tree_io.ads \ + ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads ada/sinfo-cn.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in index 0e8080853fa..d487716cc53 100644 --- a/gcc/ada/gcc-interface/Makefile.in +++ b/gcc/ada/gcc-interface/Makefile.in @@ -1052,7 +1052,7 @@ ifeq ($(strip $(filter-out %86 linux%,$(arch) $(osys))),) endif THREADSLIB = -lpthread - EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o g-ssinty.o + EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o EXTRA_GNATRTL_TASKING_OBJS=s-linux.o endif @@ -1593,7 +1593,7 @@ ifeq ($(strip $(filter-out cygwin32% mingw32% pe,$(osys))),) endif EXTRA_GNATRTL_NONTASKING_OBJS = \ - s-win32.o s-winext.o g-regist.o g-sse.o g-ssvety.o g-ssinty.o + s-win32.o s-winext.o g-regist.o g-sse.o g-ssvety.o EXTRA_GNATRTL_TASKING_OBJS = a-exetim.o MISCLIB = -lws2_32 @@ -2003,7 +2003,7 @@ ifeq ($(strip $(filter-out %x86_64 linux%,$(arch) $(osys))),) mlib-tgt-specific.adb<mlib-tgt-specific-linux.adb \ indepsw.adb<indepsw-gnu.adb - EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o g-ssinty.o + EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o EXTRA_GNATRTL_TASKING_OBJS=s-linux.o EH_MECHANISM=-gcc THREADSLIB=-lpthread diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 12599675d83..0dcc5937e1a 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -3494,7 +3494,11 @@ gnat_to_gnu (Node_Id gnat_node) If we are in the elaboration procedure, check if we are violating a No_Elaboration_Code restriction by having a statement there. */ if ((IN (Nkind (gnat_node), N_Statement_Other_Than_Procedure_Call) - && Nkind (gnat_node) != N_Null_Statement) + && Nkind (gnat_node) != N_Null_Statement + && Nkind (gnat_node) != N_SCIL_Dispatch_Table_Object_Init + && Nkind (gnat_node) != N_SCIL_Dispatch_Table_Tag_Init + && Nkind (gnat_node) != N_SCIL_Dispatching_Call + && Nkind (gnat_node) != N_SCIL_Tag_Init) || Nkind (gnat_node) == N_Procedure_Call_Statement || Nkind (gnat_node) == N_Label || Nkind (gnat_node) == N_Implicit_Label_Declaration @@ -5290,6 +5294,15 @@ 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: + gnu_result = alloc_stmt_list (); + break; + case N_Raise_Statement: case N_Function_Specification: case N_Procedure_Specification: diff --git a/gcc/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb index 199e3ffb8da..ca4fe86c8f6 100644 --- a/gcc/ada/gnat1drv.adb +++ b/gcc/ada/gnat1drv.adb @@ -112,9 +112,12 @@ procedure Gnat1drv is procedure Adjust_Global_Switches is begin - -- Debug flag -gnatd.I is a synonym of Generate_SCIL + -- Debug flag -gnatd.I is a synonym for Generate_SCIL and requires code + -- generation. - if Debug_Flag_Dot_II then + if Debug_Flag_Dot_II + and then Operating_Mode = Generate_Code + then Generate_SCIL := True; end if; @@ -460,25 +463,6 @@ procedure Gnat1drv is end if; end Check_Bad_Body; - -------------------- - -- Check_Rep_Info -- - -------------------- - - procedure Check_Rep_Info is - begin - if List_Representation_Info /= 0 - or else List_Representation_Info_Mechanisms - then - Set_Standard_Error; - Write_Eol; - Write_Str - ("cannot generate representation information, no code generated"); - Write_Eol; - Write_Eol; - Set_Standard_Output; - end if; - end Check_Rep_Info; - ------------------------- -- Check_Library_Items -- ------------------------- @@ -508,6 +492,25 @@ procedure Gnat1drv is Walk; end Check_Library_Items; + -------------------- + -- Check_Rep_Info -- + -------------------- + + procedure Check_Rep_Info is + begin + if List_Representation_Info /= 0 + or else List_Representation_Info_Mechanisms + then + Set_Standard_Error; + Write_Eol; + Write_Str + ("cannot generate representation information, no code generated"); + Write_Eol; + Write_Eol; + Set_Standard_Output; + end if; + end Check_Rep_Info; + -- Start of processing for Gnat1drv begin diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index 14a7a8f733f..1f26563397b 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -382,7 +382,6 @@ The GNAT Library * GNAT.Spitbol.Table_Integer (g-sptain.ads):: * GNAT.Spitbol.Table_VString (g-sptavs.ads):: * GNAT.SSE (g-sse.ads):: -* GNAT.SSE.Internal_Types (g-ssinty.ads):: * GNAT.SSE.Vector_Types (g-ssvety.ads):: * GNAT.Strings (g-string.ads):: * GNAT.String_Split (g-strspl.ads):: @@ -13572,7 +13571,6 @@ of GNAT, and will generate a warning message. * GNAT.Spitbol.Table_Integer (g-sptain.ads):: * GNAT.Spitbol.Table_VString (g-sptavs.ads):: * GNAT.SSE (g-sse.ads):: -* GNAT.SSE.Internal_Types (g-ssinty.ads):: * GNAT.SSE.Vector_Types (g-ssvety.ads):: * GNAT.Strings (g-string.ads):: * GNAT.String_Split (g-strspl.ads):: @@ -14643,15 +14641,6 @@ the Intel(r) Streaming SIMD Extensions with GNAT on the x86 family of targets. It exposes vector component types together with a general introduction to the binding contents and use. -@node GNAT.SSE.Internal_Types (g-ssinty.ads) -@section @code{GNAT.SSE.Internal_Types} (@file{g-ssinty.ads}) -@cindex @code{GNAT.SSE.Internal_Types} (@file{g-ssinty.ads}) - -@noindent -Low level GCC vector types for direct use of the vector related -builtins, required for the development of higher level bindings to SSE -intrinsic operations. - @node GNAT.SSE.Vector_Types (g-ssvety.ads) @section @code{GNAT.SSE.Vector_Types} (@file{g-ssvety.ads}) @cindex @code{GNAT.SSE.Vector_Types} (@file{g-ssvety.ads}) diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi index c2bcfbefe49..d3ed3458203 100644 --- a/gcc/ada/gnat_ugn.texi +++ b/gcc/ada/gnat_ugn.texi @@ -490,6 +490,7 @@ Verifying Properties Using gnatcheck * gnatcheck Rule Options:: * Adding the Results of Compiler Checks to gnatcheck Output:: * Project-Wide Checks:: +* Rule exemption:: * Predefined Rules:: Sample Bodies Using gnatstub @@ -15590,6 +15591,13 @@ Do not look for sources in the system default directory. @cindex @option{-nostdlib} (@command{gnatfind}) Do not look for library files in the system default directory. +@item --ext=@var{extension} +@cindex @option{--ext} (@command{gnatfind}) +Specify an alternate ali file extension. The default is @code{ali} and other +extensions (e.g. @code{sli} for SPARK library files) may be specified via this +switch. Note that if this switch overrides the default, which means that only +the new extension will be considered. + @item --RTS=@var{rts-path} @cindex @option{--RTS} (@command{gnatfind}) Specifies the default location of the runtime library. Same meaning as the @@ -20689,6 +20697,7 @@ Either a @file{@var{filename}} or an @file{@var{arg_list_filename}} must be supp * gnatcheck Rule Options:: * Adding the Results of Compiler Checks to gnatcheck Output:: * Project-Wide Checks:: +* Rule exemption:: * Predefined Rules:: @end menu @@ -20705,14 +20714,13 @@ named named @file{^gnatcheck.out^GNATCHECK.OUT^} and it is located in the curren directory, @option{^-o^/OUTPUT^} option can be used to change the name and/or location of the report file. This report contains: @itemize @bullet -@item a list of the Ada source files being checked, -@item a list of enabled and disabled rules, -@item a list of the diagnostic messages, ordered in three different ways -and collected in three separate -sections. Section 1 contains the raw list of diagnostic messages. It -corresponds to the output going to @file{stdout}. Section 2 contains -messages ordered by rules. -Section 3 contains messages ordered by source files. +@item date and time of @command{gnatcheck} run, the version of +the tool that has generated this report and the full paarmeters +of the @command{gnatcheck} invocation; +@item the list of enabled rules; +@item the total number of detected violations; +@item list of source files for that rule violations have been detected; +@item list of source files with no violations detected; @end itemize @node General gnatcheck Switches @@ -20940,6 +20948,108 @@ the @option{-U} option followed by the name of the main unit: @end smallexample +@node Rule exemption +@section Rule exemption +@cindex Rule exemption (for @command{gnatcheck}) + +@noindent +@command{gnatcheck} can be used to inforce a coding standard. It may be +appropriate, in some circumstances, to accept violations of the coding +standard. In such a case, it is a good idea to justify the violation within +the sources themselves. It makes it possible to maintain the justification +for such violations along with the sources containing them. +@command{gnatcheck} supports such justified violations with the notion of +``exemption'' covering a specific source code section. Usually, +@command{gnatcheck} issues rule violation messages both on @file{stderr} +and in a report file. Exempted violations are not reported at all on +@file{stderr} so that users using @command{gnatcheck} in interactive mode +(e.g. in its GPS interface) do not need to pay attention to known and +justified violations. The @command{gnatcheck} report includes exempted +violations in a special section along with their justification. + +@menu +* Using pragma Annotate to Control Rule Exemption:: +* gnatcheck Annotations Rules:: +@end menu + +@node Using pragma Annotate to Control Rule Exemption +@subsection Using pragma @code{Annotate} to Control Rule Exemption +@cindex Using pragma Annotate to control rule exemption + +@noindent +Rule exemption is controlled by pragma @code{Annotate} when its first parameter is +``gnatcheck''. Here is the syntax of @command{gnatcheck} annotations: + +@smallexample @c ada +pragma Annotate (gnatcheck, exemption_control, Rule_Name, [justification]); + +exemption_control ::= "Exempt_On" | "Exempt_Off" + +Rule_Name ::= string_literal + +justification ::= string_literal + +@end smallexample + +@noindent +When a @command{gnatcheck} annotatation has more then four parameters, +@command{gnatcheck} issues a warning and ignore additional parameters. +If the additional parameters do not follow the syntax above, +@command{gnatcheck} emits a warning and ignores the annotation. + +@code{Rule_Name} should be the name of some existing @command{gnatcheck} rule. +If this is not the case, the warning message is generated and the pragma is +ignored. If @code{Rule_Name} denotes a rule that is not activated by the given +@command{gnatcheck} call, the pragma is ignored silently. + +A source code section where an exemption is active for a given rule starts with +an extempt_on annotation and terminates with an exempt_off one: + +@smallexample @c ada +pragma Annotate (gnatcheck, "Exempt_On", Rule_Name, "justification"); +-- source code section +pragma Annotate (gnatcheck, "Exempt_Off", Rule_Name); +@end smallexample + + +@node gnatcheck Annotations Rules +@subsection @command{gnatcheck} Annotations Rules +@cindex @command{gnatcheck} annotations rules + +@itemize @bullet + +@item +an ``Exempt_Off'' annotation can only appear after a corresponding +``Exempt_On'' annotation in order to create a properly formed exempted source +code section; + +@item +exempted source code sections are only based on the source location of the +annotations. Any source construct having a source location in between the two +annotations is part of the exempted source code section; + +@item +exempted source code sections for different rules are independent. They can +be nested or intersect with one another without limitation. It is not allowed +to create nested or intersecting source code sections for the same rule; + +@item +malformed exempted source code sections are reported by a warning and +the corresponding rule exemption is ignored; + +@item +when an exempted source code section does not contain at least one violation +of the exempted rule, a warning is emitted on @file{stderr}. This allow proper +maintenance of exempted source code sections; + +@item +if an exempted source code section reaches the end of the compilation unit +source and there is no @code{Annotate} pragma closing this section, then the +exemption for the given rule is turned off and a warning is issued. + +@end itemize + + @node Predefined Rules @section Predefined Rules @cindex Predefined rules (for @command{gnatcheck}) @@ -21209,20 +21319,23 @@ This rule has no parameters. @cindex @code{Complex_Inlined_Subprograms} rule (for @command{gnatcheck}) @noindent -Flags the body of a subprogram (or generic subprogram) if -pragma Inline has been applied to the subprogram but the body -is too complex to be expanded inline. - -A subprogram (or generic subprogram) is considered too complex for inline -expansion if its body meets at least one of the following conditions: +Flags a subprogram (or generic subprogram) if +pragma Inline is applied to the subprogram and at least one of the following +conditions is met: @itemize @bullet @item -The number of local declarations and statements exceeds -a value specified by the @option{N} rule parameter; +it contains at least one complex declaration such as a subprogram body, +package, task, protected declaration, or a generic instantiation +(except instantiation of @code{Ada.Unchecked_Conversion}); + +@item +it contains at least one complex statement such as a loop, a case +or a if statement, or a short circuit control form; @item -The body contains a @code{loop}, @code{if} or @code{case} statement; +the number of statements exceeds +a value specified by the @option{N} rule parameter; @end itemize @noindent @@ -21230,8 +21343,8 @@ This rule has the following (mandatory) parameter for the @option{+R} option: @table @emph @item N -Positive integer specifying the maximum allowed total number of local -declarations and statements in the subprogram body. +Positive integer specifying the maximum allowed total number of statements +in the subprogram body. @end table @@ -21252,15 +21365,15 @@ This rule has no parameters. @cindex @code{Deep_Inheritance_Hierarchies} rule (for @command{gnatcheck}) @noindent -Flags a tagged derived type declaration if its depth (in its inheritance +Flags a tagged derived type declaration or an interface type declaration if +its depth (in its inheritance hierarchy) exceeds the value specified by the @option{N} rule parameter. -The depth of a root tagged type (ie, a tagged type that is not a derived type) -is 0. -If tagged type T2 derives directly from tagged type T1, then the depth of T2 -is one more than the depth of T1. +The inheritance depth of a tagged type or interface type is defined as 0 for +a type with no parent and no progenitor, and otherwise as 1 + max of the +depths of the immediate parent and immediate progenitors. -This rule does not flag interface types or private extension +This rule does not flag private extension declarations. In the case of a private extension, the correspondong full declaration is checked. @@ -21268,8 +21381,9 @@ This rule has the following (mandatory) parameter for the @option{+R} option: @table @emph @item N -Positive integer specifying the maximal allowed depth of any inheritance -hierarchy. +Integer not less then -1 specifying the maximal allowed depth of any inheritance +hierarchy. If the rule parameter is set to -1, the rule flags all the declarations +of tagged and interface types. @end table @@ -21297,23 +21411,12 @@ for a generic declaration. @cindex @code{Deeply_Nested_Inlining} rule (for @command{gnatcheck}) @noindent -Flags the body of a subprogram (or generic subprogram) if -pragma Inline has been applied to the subprogram but the body -contains a call to another inlined subprogram that results in nested inlining +Flags a subprogram (or generic subprogram) if +pragma Inline has been applied to the subprogram but the subprogram +calls to another inlined subprogram that results in nested inlining with nesting depth exceeding the value specified by the @option{N} rule parameter. -This rule assumes that pragma Inline applies equally to calls on -subprograms regardless of whether the subprogram declaration appears in the -same compilation unit as the call, or in a separately compiled -(e.g., @i{with}ed) unit. - -This rule may be useful when either the @option{-gnatn} or @option{-gnatN} -option is used. - -If a subprogram should be flagged according to this rule, the body declaration -is flagged only if it is not a completion of a subprogram declaration. - This rule requires the global analysis of all the compilation units that are @command{gnatcheck} arguments; such analysis may affect the tool's performance. @@ -22679,9 +22782,14 @@ This rule has no parameters. Flag each function returning an unconstrained array. Function declarations, function bodies (and body stubs) having no separate specifications, and generic function instantiations are checked. -Generic function declarations, function calls and function renamings are +Function calls and function renamings are not checked. +Generic function declarations, and function declarations in generic +packages are not checked, instead this rule checks the results of +generic instantiations (that is, expanded specification and expanded +body corresponding to an instantiation). + This rule has no parameters. @node Universal_Ranges @@ -24852,7 +24960,7 @@ GNAT always follows the Alpha implementation. For GNAT running on other than VMS systems, all the HP Ada 83 pragmas and attributes are recognized, although only a subset of them can sensibly be implemented. The description of pragmas in -@xref{Implementation Defined Pragmas,,, gnat_rm, GNAT Reference Manual} +@xref{Implementation Defined Pragmas,,, gnat_rm, GNAT Reference Manual}, indicates whether or not they are applicable to non-VMS systems. @menu @@ -25299,7 +25407,7 @@ pragma Extend_System (Aux_DEC); @noindent The pragma @code{Extend_System} is a configuration pragma that is most conveniently placed in the @file{gnat.adc} file. @xref{Pragma -Extend_System,,, gnat_rm, GNAT Reference Manual} for further details. +Extend_System,,, gnat_rm, GNAT Reference Manual}, for further details. HP Ada does not allow the recompilation of the package @code{SYSTEM}. Instead HP Ada provides several pragmas @@ -25330,7 +25438,7 @@ are virtually identical to those provided by the HP Ada 83 package @code{TO_ADDRESS} function for type @code{UNSIGNED_LONGWORD} is changed to @code{TO_ADDRESS_LONG}. -@xref{Address Clauses,,, gnat_rm, GNAT Reference Manual} for a +@xref{Address Clauses,,, gnat_rm, GNAT Reference Manual}, for a discussion of why this change was necessary. @noindent diff --git a/gcc/ada/gnatfind.adb b/gcc/ada/gnatfind.adb index 69415ef963e..8af7b9e4f8b 100644 --- a/gcc/ada/gnatfind.adb +++ b/gcc/ada/gnatfind.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1998-2008, Free Software Foundation, Inc. -- +-- Copyright (C) 1998-2009, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -64,6 +64,9 @@ procedure Gnatfind is RTS_Specified : String_Access := null; -- Used to detect multiple use of --RTS= switch + EXT_Specified : String_Access := null; + -- Used to detect multiple use of --ext= switch + procedure Parse_Cmd_Line; -- Parse every switch on the command line @@ -95,7 +98,7 @@ procedure Gnatfind is loop case GNAT.Command_Line.Getopt - ("a aI: aO: d e f g h I: nostdinc nostdlib p: r s t -RTS=") + ("a aI: aO: d e f g h I: nostdinc nostdlib p: r s t -RTS= -ext=") is when ASCII.NUL => exit; @@ -154,45 +157,74 @@ procedure Gnatfind is -- Only switch starting with -- recognized is --RTS - when '-' => - -- Check that it is the first time we see this switch - - if RTS_Specified = null then - RTS_Specified := new String'(GNAT.Command_Line.Parameter); - - elsif RTS_Specified.all /= GNAT.Command_Line.Parameter then - Osint.Fail ("--RTS cannot be specified multiple times"); - end if; - - Opt.No_Stdinc := True; - Opt.RTS_Switch := True; - - declare - Src_Path_Name : constant String_Ptr := - Get_RTS_Search_Dir - (GNAT.Command_Line.Parameter, Include); - Lib_Path_Name : constant String_Ptr := - Get_RTS_Search_Dir - (GNAT.Command_Line.Parameter, Objects); + when '-' => + if GNAT.Command_Line.Full_Switch = "-RTS" then - begin - if Src_Path_Name /= null and then Lib_Path_Name /= null then - Add_Search_Dirs (Src_Path_Name, Include); - Add_Search_Dirs (Lib_Path_Name, Objects); + -- Check that it is the first time we see this switch - elsif Src_Path_Name = null and then Lib_Path_Name = null then - Osint.Fail ("RTS path not valid: missing " & - "adainclude and adalib directories"); + if RTS_Specified = null then + RTS_Specified := new String'(GNAT.Command_Line.Parameter); + elsif RTS_Specified.all /= GNAT.Command_Line.Parameter then + Osint.Fail ("--RTS cannot be specified multiple times"); + end if; - elsif Src_Path_Name = null then - Osint.Fail ("RTS path not valid: missing " & - "adainclude directory"); + Opt.No_Stdinc := True; + Opt.RTS_Switch := True; + + declare + Src_Path_Name : constant String_Ptr := + Get_RTS_Search_Dir + (GNAT.Command_Line.Parameter, + Include); + Lib_Path_Name : constant String_Ptr := + Get_RTS_Search_Dir + (GNAT.Command_Line.Parameter, + Objects); + + begin + if Src_Path_Name /= null + and then Lib_Path_Name /= null + then + Add_Search_Dirs (Src_Path_Name, Include); + Add_Search_Dirs (Lib_Path_Name, Objects); + + elsif Src_Path_Name = null + and then Lib_Path_Name = null + then + Osint.Fail ("RTS path not valid: missing " & + "adainclude and adalib directories"); + + elsif Src_Path_Name = null then + Osint.Fail ("RTS path not valid: missing " & + "adainclude directory"); + + elsif Lib_Path_Name = null then + Osint.Fail ("RTS path not valid: missing " & + "adalib directory"); + end if; + end; + + -- Process -ext switch + + elsif GNAT.Command_Line.Full_Switch = "-ext" then + + -- Check that it is the first time we see this switch + + if EXT_Specified = null then + EXT_Specified := new String'(GNAT.Command_Line.Parameter); + elsif EXT_Specified.all /= GNAT.Command_Line.Parameter then + Osint.Fail ("--ext cannot be specified multiple times"); + end if; - elsif Lib_Path_Name = null then - Osint.Fail ("RTS path not valid: missing " & - "adalib directory"); + if + EXT_Specified'Length = Osint.ALI_Default_Suffix'Length + then + Osint.ALI_Suffix := EXT_Specified.all'Access; + else + Osint.Fail ("--ext argument must have 3 characters"); end if; - end; + + end if; when others => Write_Usage; @@ -281,6 +313,7 @@ procedure Gnatfind is & " directory"); Put_Line (" -nostdlib Don't look for library files in the system" & " default directory"); + Put_Line (" --ext=xxx Specify alternate ali file extension"); Put_Line (" --RTS=dir specify the default source and object search" & " path"); Put_Line (" -p file Use file as the default project file"); diff --git a/gcc/ada/lib-xref.ads b/gcc/ada/lib-xref.ads index b494454e38e..2e9c8d26439 100644 --- a/gcc/ada/lib-xref.ads +++ b/gcc/ada/lib-xref.ads @@ -177,6 +177,7 @@ package Lib.Xref is -- k = implicit reference to parent unit in child unit -- l = label on END line -- m = modification + -- o = own variable reference (SPARK only) -- p = primitive operation -- P = overriding primitive operation -- r = reference @@ -271,6 +272,10 @@ package Lib.Xref is -- graph construction). Again, in the case of an accept there -- can be multiple l lines. + -- o is used for variables referenced from a SPARK 'own' + -- definition. In the SPARK language, it is allowed to use a + -- variable before its actual declaration. + -- p is used to mark a primitive operation of the given entity. -- For example, if we have a type Tx, and a primitive operation -- Pq of this type, then an entry in the list of references to diff --git a/gcc/ada/make.adb b/gcc/ada/make.adb index a0f3b0b42fa..998e1e4a2da 100644 --- a/gcc/ada/make.adb +++ b/gcc/ada/make.adb @@ -343,8 +343,6 @@ package body Make is Current_Verbosity : Prj.Verbosity := Prj.Default; -- Verbosity to parse the project files - Project_Tree : constant Project_Tree_Ref := new Project_Tree_Data; - Main_Project : Prj.Project_Id := No_Project; -- The project id of the main project file, if any @@ -557,25 +555,6 @@ package body Make is procedure List_Bad_Compilations; -- Prints out the list of all files for which the compilation failed - procedure Verbose_Msg - (N1 : Name_Id; - S1 : String; - N2 : Name_Id := No_Name; - S2 : String := ""; - Prefix : String := " -> "; - Minimum_Verbosity : Verbosity_Level_Type := Opt.Low); - procedure Verbose_Msg - (N1 : File_Name_Type; - S1 : String; - N2 : File_Name_Type := No_File; - S2 : String := ""; - Prefix : String := " -> "; - Minimum_Verbosity : Verbosity_Level_Type := Opt.Low); - -- If the verbose flag (Verbose_Mode) is set and the verbosity level is - -- at least equal to Minimum_Verbosity, then print Prefix to standard - -- output followed by N1 and S1. If N2 /= No_Name then N2 is printed after - -- S1. S2 is printed last. Both N1 and N2 are printed in quotation marks. - Usage_Needed : Boolean := True; -- Flag used to make sure Makeusg is call at most once @@ -1434,10 +1413,6 @@ package body Make is O_File : out File_Name_Type; O_Stamp : out Time_Stamp_Type) is - function File_Not_A_Source_Of - (Uname : Name_Id; - Sfile : File_Name_Type) return Boolean; - function First_New_Spec (A : ALI_Id) return File_Name_Type; -- Looks in the with table entries of A and returns the spec file name -- of the first withed unit (subprogram) for which no spec existed when @@ -1452,34 +1427,6 @@ package body Make is -- services, but this causes the whole compiler to be dragged along -- for gnatbind and gnatmake. - -------------------------- - -- File_Not_A_Source_Of -- - -------------------------- - - function File_Not_A_Source_Of - (Uname : Name_Id; - Sfile : File_Name_Type) return Boolean - is - UID : Prj.Unit_Index; - - begin - UID := Units_Htable.Get (Project_Tree.Units_HT, Uname); - - if UID /= Prj.No_Unit_Index then - if (UID.File_Names (Impl) = null - or else UID.File_Names (Impl).File /= Sfile) - and then - (UID.File_Names (Spec) = null - or else UID.File_Names (Spec).File /= Sfile) - then - Verbose_Msg (Uname, "sources do not include ", Name_Id (Sfile)); - return True; - end if; - end if; - - return False; - end File_Not_A_Source_Of; - -------------------- -- First_New_Spec -- -------------------- @@ -1855,72 +1802,10 @@ package body Make is elsif not Read_Only and then Main_Project /= No_Project then - -- Check if a file name does not correspond to the mapping of - -- units to file names. - - declare - SD : Sdep_Record; - WR : With_Record; - Unit_Name : Name_Id; - - begin - U_Chk : - for U in ALIs.Table (ALI).First_Unit .. - ALIs.Table (ALI).Last_Unit - loop - -- Check if the file name is one of the source of the - -- unit. - - Get_Name_String (Units.Table (U).Uname); - Name_Len := Name_Len - 2; - Unit_Name := Name_Find; - - if File_Not_A_Source_Of - (Unit_Name, Units.Table (U).Sfile) - then - ALI := No_ALI_Id; - return; - end if; - - -- Do the same check for each of the withed units - - W_Check : - for W in Units.Table (U).First_With - .. - Units.Table (U).Last_With - loop - WR := Withs.Table (W); - - if WR.Sfile /= No_File then - Get_Name_String (WR.Uname); - Name_Len := Name_Len - 2; - Unit_Name := Name_Find; - - if File_Not_A_Source_Of (Unit_Name, WR.Sfile) then - ALI := No_ALI_Id; - return; - end if; - end if; - end loop W_Check; - end loop U_Chk; - - -- Check also the subunits - - D_Check : - for D in ALIs.Table (ALI).First_Sdep .. - ALIs.Table (ALI).Last_Sdep - loop - SD := Sdep.Table (D); - Unit_Name := SD.Subunit_Name; - - if Unit_Name /= No_Name then - if File_Not_A_Source_Of (Unit_Name, SD.Sfile) then - ALI := No_ALI_Id; - return; - end if; - end if; - end loop D_Check; - end; + if not Check_Source_Info_In_ALI (ALI) then + ALI := No_ALI_Id; + return; + end if; -- Check that the ALI file is in the correct object directory. -- If it is in the object directory of a project that is @@ -4772,6 +4657,11 @@ package body Make is Exit_Program (E_Success); else + -- Call Get_Target_Parameters to ensure that VM_Target and + -- AAMP_On_Target get set before calling Usage. + + Targparm.Get_Target_Parameters; + -- Output usage information if no files to compile Usage; @@ -8235,52 +8125,6 @@ package body Make is end if; end Usage; - ----------------- - -- Verbose_Msg -- - ----------------- - - procedure Verbose_Msg - (N1 : Name_Id; - S1 : String; - N2 : Name_Id := No_Name; - S2 : String := ""; - Prefix : String := " -> "; - Minimum_Verbosity : Verbosity_Level_Type := Opt.Low) - is - begin - if (not Verbose_Mode) or else (Minimum_Verbosity > Verbosity_Level) then - return; - end if; - - Write_Str (Prefix); - Write_Str (""""); - Write_Name (N1); - Write_Str (""" "); - Write_Str (S1); - - if N2 /= No_Name then - Write_Str (" """); - Write_Name (N2); - Write_Str (""" "); - end if; - - Write_Str (S2); - Write_Eol; - end Verbose_Msg; - - procedure Verbose_Msg - (N1 : File_Name_Type; - S1 : String; - N2 : File_Name_Type := No_File; - S2 : String := ""; - Prefix : String := " -> "; - Minimum_Verbosity : Verbosity_Level_Type := Opt.Low) - is - begin - Verbose_Msg - (Name_Id (N1), S1, Name_Id (N2), S2, Prefix, Minimum_Verbosity); - end Verbose_Msg; - begin -- Make sure that in case of failure, the temp files will be deleted diff --git a/gcc/ada/makeutl.adb b/gcc/ada/makeutl.adb index 46169d5fa62..c0d9de4d764 100644 --- a/gcc/ada/makeutl.adb +++ b/gcc/ada/makeutl.adb @@ -23,9 +23,11 @@ -- -- ------------------------------------------------------------------------------ +with ALI; use ALI; with Debug; with Osint; use Osint; with Output; use Output; +with Opt; use Opt; with Prj.Ext; with Prj.Util; with Snames; use Snames; @@ -154,6 +156,98 @@ package body Makeutl is end if; end Add_Linker_Option; + ------------------------------ + -- Check_Source_Info_In_ALI -- + ------------------------------ + + function Check_Source_Info_In_ALI (The_ALI : ALI_Id) return Boolean is + Unit_Name : Name_Id; + + begin + -- Loop through units + + for U in ALIs.Table (The_ALI).First_Unit .. + ALIs.Table (The_ALI).Last_Unit + loop + -- Check if the file name is one of the source of the unit + + Get_Name_String (Units.Table (U).Uname); + Name_Len := Name_Len - 2; + Unit_Name := Name_Find; + + if File_Not_A_Source_Of (Unit_Name, Units.Table (U).Sfile) then + return False; + end if; + + -- Loop to do same check for each of the withed units + + for W in Units.Table (U).First_With .. Units.Table (U).Last_With loop + declare + WR : ALI.With_Record renames Withs.Table (W); + + begin + if WR.Sfile /= No_File then + Get_Name_String (WR.Uname); + Name_Len := Name_Len - 2; + Unit_Name := Name_Find; + + if File_Not_A_Source_Of (Unit_Name, WR.Sfile) then + return False; + end if; + end if; + end; + end loop; + end loop; + + -- Loop to check subunits + + for D in ALIs.Table (The_ALI).First_Sdep .. + ALIs.Table (The_ALI).Last_Sdep + loop + declare + SD : Sdep_Record renames Sdep.Table (D); + + begin + Unit_Name := SD.Subunit_Name; + + if Unit_Name /= No_Name then + + -- For separates, the file is no longer associated with the + -- unit ("proc-sep.adb" is not associated with unit "proc.sep". + -- So we need to check whether the source file still exists in + -- the source tree: it will if it matches the naming scheme + -- (and then will be for the same unit). + + if Find_Source + (In_Tree => Project_Tree, + Project => No_Project, + Base_Name => SD.Sfile) = No_Source + then + -- If this is not a runtime file (when using -a) ? Otherwise + -- we get complaints about a-except.adb, which uses + -- separates. + + if not Check_Readonly_Files + or else Find_File (SD.Sfile, Osint.Source) = No_File + then + if Verbose_Mode then + Write_Line + ("While parsing ALI file: Sdep associates " + & Get_Name_String (SD.Sfile) + & " with unit " & Get_Name_String (Unit_Name) + & " but this does not match what was found while" + & " parsing the project. Will recompile"); + end if; + return False; + end if; + end if; + end if; + end; + end loop; + + return True; + end Check_Source_Info_In_ALI; + ----------------- -- Create_Name -- ----------------- @@ -264,6 +358,47 @@ package body Makeutl is end; end Executable_Prefix_Path; + -------------------------- + -- File_Not_A_Source_Of -- + -------------------------- + + function File_Not_A_Source_Of + (Uname : Name_Id; + Sfile : File_Name_Type) return Boolean + is + Unit : constant Unit_Index := + Units_Htable.Get (Project_Tree.Units_HT, Uname); + + At_Least_One_File : Boolean := False; + + begin + if Unit /= No_Unit_Index then + for F in Unit.File_Names'Range loop + if Unit.File_Names (F) /= null then + At_Least_One_File := True; + if Unit.File_Names (F).File = Sfile then + return False; + end if; + end if; + end loop; + + if not At_Least_One_File then + + -- The unit was probably created initially for a separate unit + -- (which are initially created as IMPL when both suffixes are the + -- same). Later on, Override_Kind changed the type of the file, + -- and the unit is no longer valid in fact. + + return False; + end if; + + Verbose_Msg (Uname, "sources do not include ", Name_Id (Sfile)); + return True; + end if; + + return False; + end File_Not_A_Source_Of; + ---------- -- Hash -- ---------- @@ -749,4 +884,52 @@ package body Makeutl is return Result; end Unit_Index_Of; + ----------------- + -- Verbose_Msg -- + ----------------- + + procedure Verbose_Msg + (N1 : Name_Id; + S1 : String; + N2 : Name_Id := No_Name; + S2 : String := ""; + Prefix : String := " -> "; + Minimum_Verbosity : Opt.Verbosity_Level_Type := Opt.Low) + is + begin + if not Opt.Verbose_Mode + or else Minimum_Verbosity > Opt.Verbosity_Level + then + return; + end if; + + Write_Str (Prefix); + Write_Str (""""); + Write_Name (N1); + Write_Str (""" "); + Write_Str (S1); + + if N2 /= No_Name then + Write_Str (" """); + Write_Name (N2); + Write_Str (""" "); + end if; + + Write_Str (S2); + Write_Eol; + end Verbose_Msg; + + procedure Verbose_Msg + (N1 : File_Name_Type; + S1 : String; + N2 : File_Name_Type := No_File; + S2 : String := ""; + Prefix : String := " -> "; + Minimum_Verbosity : Opt.Verbosity_Level_Type := Opt.Low) + is + begin + Verbose_Msg + (Name_Id (N1), S1, Name_Id (N2), S2, Prefix, Minimum_Verbosity); + end Verbose_Msg; + end Makeutl; diff --git a/gcc/ada/makeutl.ads b/gcc/ada/makeutl.ads index ae55ebbe62a..1dff5a16aa1 100644 --- a/gcc/ada/makeutl.ads +++ b/gcc/ada/makeutl.ads @@ -23,7 +23,9 @@ -- -- ------------------------------------------------------------------------------ +with ALI; with Namet; use Namet; +with Opt; with Osint; with Prj; use Prj; with Types; use Types; @@ -34,8 +36,8 @@ package Makeutl is type Fail_Proc is access procedure (S : String); Do_Fail : Fail_Proc := Osint.Fail'Access; - -- Failing procedure called from procedure Test_If_Relative_Path below. - -- May be redirected. + -- Failing procedure called from procedure Test_If_Relative_Path below. May + -- be redirected. Project_Tree : constant Project_Tree_Ref := new Project_Tree_Data; -- The project tree @@ -69,6 +71,18 @@ package Makeutl is procedure Inform (N : File_Name_Type; Msg : String); -- Prints out the program name followed by a colon, N and S + function File_Not_A_Source_Of + (Uname : Name_Id; + Sfile : File_Name_Type) return Boolean; + -- Check that file name Sfile is one of the source of unit Uname. Returns + -- True if the unit is in one of the project file, but the file name is not + -- one of its source. Returns False otherwise. + + function Check_Source_Info_In_ALI (The_ALI : ALI.ALI_Id) return Boolean; + -- Check whether all file references in ALI are still valid (ie the + -- source files are still associated with the same units). Return True + -- if everything is still valid + function Is_External_Assignment (Argv : String) return Boolean; -- Verify that an external assignment switch is syntactically correct -- @@ -78,9 +92,30 @@ package Makeutl is -- -X"name=other value" -- -- Assumptions: 'First = 1, Argv (1 .. 2) = "-X" - -- When this function returns True, the external assignment has - -- been entered by a call to Prj.Ext.Add, so that in a project - -- file, External ("name") will return "value". + -- + -- When this function returns True, the external assignment has been + -- entered by a call to Prj.Ext.Add, so that in a project file, External + -- ("name") will return "value". + + procedure Verbose_Msg + (N1 : Name_Id; + S1 : String; + N2 : Name_Id := No_Name; + S2 : String := ""; + Prefix : String := " -> "; + Minimum_Verbosity : Opt.Verbosity_Level_Type := Opt.Low); + procedure Verbose_Msg + (N1 : File_Name_Type; + S1 : String; + N2 : File_Name_Type := No_File; + S2 : String := ""; + Prefix : String := " -> "; + Minimum_Verbosity : Opt.Verbosity_Level_Type := Opt.Low); + -- If the verbose flag (Verbose_Mode) is set and the verbosity level is + -- at least equal to Minimum_Verbosity, then print Prefix to standard + -- output followed by N1 and S1. If N2 /= No_Name then N2 is printed after + -- S1. S2 is printed last. Both N1 and N2 are printed in quotation marks. + -- The two forms differ only in taking Name_Id or File_name_Type arguments. function Linker_Options_Switches (Project : Project_Id; @@ -94,8 +129,8 @@ package Makeutl is -- files exist and that they belong to a project file. function Unit_Index_Of (ALI_File : File_Name_Type) return Int; - -- Find the index of a unit in a source file. Return zero if the file - -- is not a multi-unit source file. + -- Find the index of a unit in a source file. Return zero if the file is + -- not a multi-unit source file. package Mains is @@ -116,8 +151,8 @@ package Makeutl is -- Reset the index to the beginning of the table function Next_Main return String; - -- Increase the index and return the next main. - -- If table is exhausted, return an empty string. + -- Increase the index and return the next main. If table is exhausted, + -- return an empty string. function Get_Location return Source_Ptr; -- Get the location of the current main @@ -137,12 +172,12 @@ package Makeutl is Including_L_Switch : Boolean := True; Including_Non_Switch : Boolean := True; Including_RTS : Boolean := False); - -- Test if Switch is a relative search path switch. - -- If it is, fail if Parent is the empty string, otherwise prepend the path - -- with Parent. This subprogram is only called when using project files. - -- For gnatbind switches, Including_L_Switch is False, because the - -- argument of the -L switch is not a path. If Including_RTS is True, - -- process also switches --RTS=. + -- Test if Switch is a relative search path switch. If it is, fail if + -- Parent is the empty string, otherwise prepend the path with Parent. + -- This subprogram is only called when using project files. For gnatbind + -- switches, Including_L_Switch is False, because the argument of the -L + -- switch is not a path. If Including_RTS is True, process also switches + -- --RTS=. function Path_Or_File_Name (Path : Path_Name_Type) return String; -- Returns a file name if -df is used, otherwise return a path name @@ -152,9 +187,9 @@ package Makeutl is ---------------------- procedure Mark (Source_File : File_Name_Type; Index : Int := 0); - -- Mark a unit, identified by its source file and, when Index is not 0, - -- the index of the unit in the source file. Marking is used to signal - -- that the unit has already been inserted in the Q. + -- Mark a unit, identified by its source file and, when Index is not 0, the + -- index of the unit in the source file. Marking is used to signal that the + -- unit has already been inserted in the Q. function Is_Marked (Source_File : File_Name_Type; diff --git a/gcc/ada/osint.ads b/gcc/ada/osint.ads index 5de8eced2ac..a44d4e24b3c 100644 --- a/gcc/ada/osint.ads +++ b/gcc/ada/osint.ads @@ -571,10 +571,11 @@ package Osint is pragma Import (C, Len_Arg, "__gnat_len_arg"); -- Get length of argument -private + ALI_Default_Suffix : constant String_Ptr := new String'("ali"); + ALI_Suffix : String_Ptr := ALI_Default_Suffix; + -- The suffixes used for the library files (also known as ALI files) - ALI_Suffix : constant String_Ptr := new String'("ali"); - -- The suffix used for the library files (also known as ALI files) +private Current_Main : File_Name_Type := No_File; -- Used to save a simple file name between calls to Next_Main_Source and diff --git a/gcc/ada/prj-nmsc.adb b/gcc/ada/prj-nmsc.adb index f0ded903ff9..75e4c6ea717 100644 --- a/gcc/ada/prj-nmsc.adb +++ b/gcc/ada/prj-nmsc.adb @@ -726,11 +726,28 @@ package body Prj.Nmsc is Id.Kind := Kind; Id.Alternate_Languages := Alternate_Languages; Id.Locally_Removed := Locally_Removed; + Id.Index := Index; + Id.File := File_Name; + Id.Display_File := Display_File; + Id.Dep_Name := Dependency_Name + (File_Name, Lang_Id.Config.Dependency_Kind); + Id.Naming_Exception := Naming_Exception; -- Add the source id to the Unit_Sources_HT hash table, if the unit name -- is not null. if Unit /= No_Name then + + -- Note: we might be creating a dummy unit here, when we in fact have + -- a separate. For instance, file file-bar.adb will initially be + -- assumed to be the IMPL of unit "file.bar". Only later on (in + -- Check_Object_Files) will we parse those units that only have an + -- impl and no spec to make sure whether we have a Separate in fact + -- (that significantly reduces the number of times we need to parse + -- the files, since we are then only interested in those with no + -- spec). We still need those dummy units in the table, since that's + -- the name we find in the ALI file + UData := Units_Htable.Get (Data.Tree.Units_HT, Unit); if UData = No_Unit_Index then @@ -746,13 +763,6 @@ package body Prj.Nmsc is Override_Kind (Id, Kind); end if; - Id.Index := Index; - Id.File := File_Name; - Id.Display_File := Display_File; - Id.Dep_Name := Dependency_Name - (File_Name, Lang_Id.Config.Dependency_Kind); - Id.Naming_Exception := Naming_Exception; - if Is_Compilable (Id) and then Config.Object_Generated then Id.Object := Object_Name (File_Name, Config.Object_File_Suffix); Id.Switches := Switches_Name (File_Name); @@ -6541,6 +6551,14 @@ package body Prj.Nmsc is Source.Kind := Kind; + if Current_Verbosity = High + and then Source.File /= No_File + then + Write_Line ("Override kind for " + & Get_Name_String (Source.File) + & " kind=" & Source.Kind'Img); + end if; + if Source.Kind in Spec_Or_Body and then Source.Unit /= null then Source.Unit.File_Names (Source.Kind) := Source; end if; diff --git a/gcc/ada/prj-tree.adb b/gcc/ada/prj-tree.adb index 1f15c80b27b..2d94f5c4bbb 100644 --- a/gcc/ada/prj-tree.adb +++ b/gcc/ada/prj-tree.adb @@ -989,14 +989,14 @@ package body Prj.Tree is -- Free -- ---------- - procedure Free (Prj : in out Project_Node_Tree_Ref) is + procedure Free (Proj : in out Project_Node_Tree_Ref) is procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Project_Node_Tree_Data, Project_Node_Tree_Ref); begin - if Prj /= null then - Project_Node_Table.Free (Prj.Project_Nodes); - Projects_Htable.Reset (Prj.Projects_HT); - Unchecked_Free (Prj); + if Proj /= null then + Project_Node_Table.Free (Proj.Project_Nodes); + Projects_Htable.Reset (Proj.Projects_HT); + Unchecked_Free (Proj); end if; end Free; diff --git a/gcc/ada/prj-tree.ads b/gcc/ada/prj-tree.ads index 46cfcf14a21..e68c36eaad4 100644 --- a/gcc/ada/prj-tree.ads +++ b/gcc/ada/prj-tree.ads @@ -1373,7 +1373,7 @@ package Prj.Tree is end record; -- The data for a project node tree - procedure Free (Prj : in out Project_Node_Tree_Ref); + procedure Free (Proj : in out Project_Node_Tree_Ref); -- Free memory used by Prj private diff --git a/gcc/ada/prj.adb b/gcc/ada/prj.adb index fb002f45cfe..2ad790324a7 100644 --- a/gcc/ada/prj.adb +++ b/gcc/ada/prj.adb @@ -600,9 +600,9 @@ package body Prj is -- Image -- ----------- - function Image (Casing : Casing_Type) return String is + function Image (The_Casing : Casing_Type) return String is begin - return The_Casing_Images (Casing).all; + return The_Casing_Images (The_Casing).all; end Image; ----------------------------- @@ -1053,6 +1053,7 @@ package body Prj is ----------------------------------- procedure Compute_All_Imported_Projects (Project : Project_Id) is + procedure Recursive_Add (Prj : Project_Id; Dummy : in out Boolean); -- Recursively add the projects imported by project Project, but not -- those that are extended. @@ -1069,8 +1070,9 @@ package body Prj is begin -- A project is not importing itself - if Project /= Prj then - Prj2 := Ultimate_Extending_Project_Of (Prj); + Prj2 := Ultimate_Extending_Project_Of (Prj); + + if Project /= Prj2 then -- Check that the project is not already in the list. We know the -- one passed to Recursive_Add have never been visited before, but @@ -1081,6 +1083,7 @@ package body Prj is if List.Project = Prj2 then return; end if; + List := List.Next; end loop; @@ -1095,6 +1098,7 @@ package body Prj is procedure For_All_Projects is new For_Every_Project_Imported (Boolean, Recursive_Add); + Dummy : Boolean := False; begin diff --git a/gcc/ada/prj.ads b/gcc/ada/prj.ads index ff2e01f0e49..8f95c08b59f 100644 --- a/gcc/ada/prj.ads +++ b/gcc/ada/prj.ads @@ -600,15 +600,24 @@ package Prj is type Source_Kind is (Spec, Impl, Sep); subtype Spec_Or_Body is Source_Kind range Spec .. Impl; + -- The following declarations declare a structure used to store the Name + -- and File and Path names of a unit, with a reference to its GNAT Project + -- File(s). Some units might have neither Spec nor Impl when they were + -- created for a "separate". + type File_Names_Data is array (Spec_Or_Body) of Source_Id; + type Unit_Data is record Name : Name_Id := No_Name; File_Names : File_Names_Data; end record; + type Unit_Index is access all Unit_Data; + No_Unit_Index : constant Unit_Index := null; - -- Name and File and Path names of a unit, with a reference to its - -- GNAT Project File(s). + -- Used to indicate a null entry for no unit + + -- Structure to define source data type Source_Data is record Project : Project_Id := No_Project; @@ -625,7 +634,7 @@ package Prj is Declared_In_Interfaces : Boolean := False; -- True when source is declared in attribute Interfaces - Alternate_Languages : Language_List; + Alternate_Languages : Language_List := null; -- List of languages a header file may also be, in addition of language -- Language_Name. @@ -786,7 +795,7 @@ package Prj is Symbol_Policy => Autonomous); -- The default value of the symbol data - function Image (Casing : Casing_Type) return String; + function Image (The_Casing : Casing_Type) return String; -- Similar to 'Image (but avoid use of this attribute in compiler) function Value (Image : String) return Casing_Type; @@ -1052,7 +1061,8 @@ package Prj is -- The list of all directly imported projects, if any All_Imported_Projects : Project_List; - -- The list of all projects imported directly or indirectly, if any + -- The list of all projects imported directly or indirectly, if any. + -- This does not include the project itself. ----------------- -- Directories -- diff --git a/gcc/ada/raise.c b/gcc/ada/raise.c index d82132354f8..1f087783b67 100644 --- a/gcc/ada/raise.c +++ b/gcc/ada/raise.c @@ -29,11 +29,8 @@ * * ****************************************************************************/ -/* Shared routines to support exception handling. - Note that _gnat_builtin_longjmp should disappear at some point, replaced - by direct call to __builtin_longjmp from Ada code. - __gnat_unhandled_terminate is code shared between all exception handling - mechanisms */ +/* Shared routines to support exception handling. __gnat_unhandled_terminate + is shared between all exception handling mechanisms. */ #ifdef IN_RTS #include "tconfig.h" @@ -46,13 +43,19 @@ #include "adaint.h" #include "raise.h" -/* We have not yet figured out how to import this directly */ +/* Wrapper to builtin_longjmp. This is for the compiler eh only, as the sjlj + runtime library interfaces directly to the intrinsic. We can't yet do + this for the compiler itself, because this capability relies on changes + made in april 2008 and we need to preserve the possibility to bootstrap + with an older base version. */ +#if defined (IN_GCC) && !defined (IN_RTS) void _gnat_builtin_longjmp (void *ptr, int flag ATTRIBUTE_UNUSED) { __builtin_longjmp (ptr, 1); } +#endif /* When an exception is raised for which no handler exists, the procedure Ada.Exceptions.Unhandled_Exception is called, which performs the call to diff --git a/gcc/ada/s-linux-hppa.ads b/gcc/ada/s-linux-hppa.ads index 16393c539f6..6176376cbeb 100644 --- a/gcc/ada/s-linux-hppa.ads +++ b/gcc/ada/s-linux-hppa.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2009, Free Software Foundation, Inc. -- +-- Copyright (C) 2008-2009, Free Software Foundation, Inc. -- -- -- -- GNARL is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- diff --git a/gcc/ada/s-linux.ads b/gcc/ada/s-linux.ads index 83b07c018e6..29918d7d4ca 100644 --- a/gcc/ada/s-linux.ads +++ b/gcc/ada/s-linux.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2009, Free Software Foundation, Inc. -- +-- Copyright (C) 2008-2009, Free Software Foundation, Inc. -- -- -- -- GNARL is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c index b5dd2a86a7b..c4218c2ab78 100644 --- a/gcc/ada/s-oscons-tmplt.c +++ b/gcc/ada/s-oscons-tmplt.c @@ -78,6 +78,11 @@ pragma Style_Checks ("M32766"); ** $ RUN xoscons **/ +#if defined (__linux__) && !defined (_XOPEN_SOURCE) +/* For Linux _XOPEN_SOURCE must be defined, otherwise IOV_MAX is not defined */ +#define _XOPEN_SOURCE 500 +#endif + #include <stdlib.h> #include <string.h> #include <limits.h> diff --git a/gcc/ada/s-soflin.ads b/gcc/ada/s-soflin.ads index 16b483b28b8..783fd8878eb 100644 --- a/gcc/ada/s-soflin.ads +++ b/gcc/ada/s-soflin.ads @@ -242,7 +242,7 @@ package System.Soft_Links is function Get_Exc_Stack_Addr_NT return Address; Get_Exc_Stack_Addr : Get_Address_Call := Get_Exc_Stack_Addr_NT'Access; - function Get_Current_Excep_NT return EOA; + function Get_Current_Excep_NT return EOA; Get_Current_Excep : Get_EOA_Call := Get_Current_Excep_NT'Access; diff --git a/gcc/ada/s-tasini.adb b/gcc/ada/s-tasini.adb index f473e0e7595..cacd86c4c22 100644 --- a/gcc/ada/s-tasini.adb +++ b/gcc/ada/s-tasini.adb @@ -190,12 +190,13 @@ package body System.Tasking.Initialization is return; end if; - -- pragma Assert - -- ((Self_ID.Pending_ATC_Level >= Self_ID.ATC_Nesting_Level or else - -- Self_ID.Deferral_Level > 0)); + -- The following assertion is by default disabled. See the comment in + -- Defer_Abort on the situations in which it may be useful to uncomment + -- this assertion and enable the test. - -- See comment in Defer_Abort on the situations in which it may be - -- useful to uncomment the above assertion. + -- pragma Assert + -- (Self_ID.Pending_ATC_Level >= Self_ID.ATC_Nesting_Level or else + -- Self_ID.Deferral_Level > 0); Self_ID.Deferral_Level := Self_ID.Deferral_Level + 1; end Defer_Abort_Nestable; diff --git a/gcc/ada/sem.adb b/gcc/ada/sem.adb index 94b2acf3a48..bac147c96b9 100644 --- a/gcc/ada/sem.adb +++ b/gcc/ada/sem.adb @@ -243,7 +243,7 @@ package body Sem is Analyze_Free_Statement (N); when N_Freeze_Entity => - null; -- no semantic processing required + Analyze_Freeze_Entity (N); when N_Full_Type_Declaration => Analyze_Type_Declaration (N); @@ -603,6 +603,18 @@ package body Sem is when N_Push_Pop_xxx_Label => null; + -- SCIL nodes don't need analysis because they are decorated when + -- they are built. They are added to the tree by Insert_Actions and + -- the call to analyze them is generated when the full list is + -- analyzed. + + when + N_SCIL_Dispatch_Table_Object_Init | + N_SCIL_Dispatch_Table_Tag_Init | + N_SCIL_Dispatching_Call | + N_SCIL_Tag_Init => + null; + -- For the remaining node types, we generate compiler abort, because -- these nodes are always analyzed within the Sem_Chn routines and -- there should never be a case of making a call to the main Analyze @@ -1680,8 +1692,16 @@ package body Sem is -------------------- procedure Do_Withed_Unit (Withed_Unit : Node_Id) is + Save_Do_Main : constant Boolean := Do_Main; + begin + -- Do not process the main unit if coming from a with_clause, + -- as would happen with a parent body that has a child spec + -- in its context. + + Do_Main := False; Do_Unit_And_Dependents (Withed_Unit, Unit (Withed_Unit)); + Do_Main := Save_Do_Main; end Do_Withed_Unit; procedure Do_Withed_Units is new Walk_Withs (Do_Withed_Unit); @@ -1691,104 +1711,102 @@ package body Sem is begin if not Seen (Unit_Num) then - Seen (Unit_Num) := True; - - -- Process corresponding spec of body first - - if Nkind_In (Item, N_Package_Body, N_Subprogram_Body) then - declare - Spec_Unit : constant Node_Id := Library_Unit (CU); - begin - if Spec_Unit = CU then -- ???Why needed? - pragma Assert (Acts_As_Spec (CU)); - null; - else - Do_Unit_And_Dependents (Spec_Unit, Unit (Spec_Unit)); - end if; - end; - end if; - -- Process the with clauses Do_Withed_Units (CU, Include_Limited => False); - -- Process the unit itself + -- Process the unit if it is a spec. If it is the main unit, + -- process it only if we have done all other units. if not Nkind_In (Item, N_Package_Body, N_Subprogram_Body) or else Acts_As_Spec (CU) - or else (CU = Cunit (Main_Unit) and then Do_Main) then - Do_Action (CU, Item); - Done (Unit_Num) := True; + if CU = Cunit (Main_Unit) and then not Do_Main then + Seen (Unit_Num) := False; + + else + Seen (Unit_Num) := True; + Do_Action (CU, Item); + Done (Unit_Num) := True; + end if; end if; end if; - -- Process corresponding body of spec last. This is either the main - -- unit, or the body of a spec that is in the context of the main - -- unit, and that is instantiated, or else contains a generic that - -- is instantiated, or a subprogram that is inlined in the main unit. + -- Process bodies. The spec, if present, has been processed already. + -- A body appears if it is the main, or the body of a spec that is + -- in the context of the main unit, and that is instantiated, or else + -- contains a generic that is instantiated, or a subprogram that is + -- or a subprogram that is inlined in the main unit. -- We exclude bodies that may appear in a circular dependency list, -- where spec A depends on spec B and body of B depends on spec A. -- This is not an elaboration issue, but body B must be excluded -- from the processing. - if Nkind (Item) = N_Package_Declaration then - declare - Body_Unit : constant Node_Id := Library_Unit (CU); + declare + Body_Unit : Node_Id := Empty; + Body_Num : Unit_Number_Type; - function Circular_Dependence (B : Node_Id) return Boolean; - -- Check whether this body depends on a spec that is pending, - -- that is to say has been seen but not processed yet. + function Circular_Dependence (B : Node_Id) return Boolean; + -- Check whether this body depends on a spec that is pending, + -- that is to say has been seen but not processed yet. - ------------------------- - -- Circular_Dependence -- - ------------------------- + ------------------------- + -- Circular_Dependence -- + ------------------------- - function Circular_Dependence (B : Node_Id) return Boolean is - Item : Node_Id; - UN : Unit_Number_Type; + function Circular_Dependence (B : Node_Id) return Boolean is + Item : Node_Id; + UN : Unit_Number_Type; - begin - Item := First (Context_Items (B)); - while Present (Item) loop - if Nkind (Item) = N_With_Clause then - UN := Get_Cunit_Unit_Number (Library_Unit (Item)); - - if Seen (UN) - and then not Done (UN) - then - return True; - end if; + begin + Item := First (Context_Items (B)); + while Present (Item) loop + if Nkind (Item) = N_With_Clause then + UN := Get_Cunit_Unit_Number (Library_Unit (Item)); + + if Seen (UN) + and then not Done (UN) + then + return True; end if; + end if; - Next (Item); - end loop; + Next (Item); + end loop; - return False; - end Circular_Dependence; + return False; + end Circular_Dependence; - begin - if Present (Body_Unit) + begin + if Nkind (Item) = N_Package_Declaration then + Body_Unit := Library_Unit (CU); - -- Since specs and bodies are not done at the same time, - -- guard against listing a body more than once. + elsif Nkind_In (Item, N_Package_Body, N_Subprogram_Body) then + Body_Unit := CU; + end if; - and then not Seen (Get_Cunit_Unit_Number (Body_Unit)) + if Present (Body_Unit) - -- Would be good to comment each of these tests ??? + -- Since specs and bodies are not done at the same time, + -- guard against listing a body more than once. Bodies are + -- only processed when the main unit is being processed, + -- after all other units in the list. The DEC extension + -- to System is excluded because of circularities. - and then Body_Unit /= Cunit (Main_Unit) - and then Unit_Num /= Get_Source_Unit (System_Aux_Id) - and then not Circular_Dependence (Body_Unit) - and then Do_Main - then - Do_Unit_And_Dependents (Body_Unit, Unit (Body_Unit)); - Do_Action (Body_Unit, Unit (Body_Unit)); - Done (Get_Cunit_Unit_Number (Body_Unit)) := True; - end if; - end; - end if; + and then not Seen (Get_Cunit_Unit_Number (Body_Unit)) + and then + (No (System_Aux_Id) + or else Unit_Num /= Get_Source_Unit (System_Aux_Id)) + and then not Circular_Dependence (Body_Unit) + and then Do_Main + then + Body_Num := Get_Cunit_Unit_Number (Body_Unit); + Seen (Body_Num) := True; + Do_Action (Body_Unit, Unit (Body_Unit)); + Done (Body_Num) := True; + end if; + end; end Do_Unit_And_Dependents; -- Local Declarations @@ -1862,7 +1880,25 @@ package body Sem is if not Done (Main_Unit) then Do_Main := True; - Do_Unit_And_Dependents (Cunit (Main_Unit), Unit (Cunit (Main_Unit))); + + declare + Main_CU : constant Node_Id := Cunit (Main_Unit); + + begin + -- If the main unit is an instantiation, the body appears before + -- the instance spec, which is added later to the unit list. Do + -- the spec if present, body will follow. + + if Nkind (Original_Node (Unit (Main_CU))) + in N_Generic_Instantiation + and then Present (Library_Unit (Main_CU)) + then + Do_Unit_And_Dependents + (Library_Unit (Main_CU), Unit (Library_Unit (Main_CU))); + else + Do_Unit_And_Dependents (Main_CU, Unit (Main_CU)); + end if; + end; end if; if Debug_Unit_Walk then @@ -1940,9 +1976,11 @@ package body Sem is end loop; -- See if it belongs to current unit, and if so, include its - -- with_clauses. + -- with_clauses. Do not process main unit prematurely. - if Pnode = CU then + if Pnode = CU + and then CU /= Cunit (Main_Unit) + then Walk_Immediate (Cunit (S), Include_Limited); end if; end; diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb index 36fd6dc8e4b..af29d9a3fdc 100644 --- a/gcc/ada/sem_aggr.adb +++ b/gcc/ada/sem_aggr.adb @@ -2737,7 +2737,7 @@ package body Sem_Aggr is end if; end if; - Generate_Reference (Compon, Selector_Name); + Generate_Reference (Compon, Selector_Name, 'm'); else Error_Msg_NE diff --git a/gcc/ada/sem_aux.adb b/gcc/ada/sem_aux.adb index 6513e73d073..c1b3a331892 100755 --- a/gcc/ada/sem_aux.adb +++ b/gcc/ada/sem_aux.adb @@ -312,11 +312,11 @@ package body Sem_Aux is Ent : Entity_Id; begin - -- If the base type has no freeze node, it is a type in standard, + -- If the base type has no freeze node, it is a type in Standard, -- and always acts as its own first subtype unless it is one of the -- predefined integer types. If the type is formal, it is also a first -- subtype, and its base type has no freeze node. On the other hand, a - -- subtype of a generic formal is not its own first_subtype. Its base + -- subtype of a generic formal is not its own first subtype. Its base -- type, if anonymous, is attached to the formal type decl. from which -- the first subtype is obtained. diff --git a/gcc/ada/sem_aux.ads b/gcc/ada/sem_aux.ads index f8467446130..464a764a3e3 100755 --- a/gcc/ada/sem_aux.ads +++ b/gcc/ada/sem_aux.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2008, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -36,7 +36,7 @@ -- Historical note. Many of the routines here were originally in Einfo, but -- Einfo is supposed to be a relatively low level package dealing with the -- content of entities in the tree, so this package is used for routines that --- require more than minimal semantic knowldge. +-- require more than minimal semantic knowledge. with Alloc; use Alloc; with Table; diff --git a/gcc/ada/sem_cat.adb b/gcc/ada/sem_cat.adb index e24b456952f..d5d38235f36 100644 --- a/gcc/ada/sem_cat.adb +++ b/gcc/ada/sem_cat.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2008, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -1774,12 +1774,12 @@ package body Sem_Cat is -- Check RCI or RT unit type declaration. It may not contain the -- declaration of an access-to-object type unless it is a general access - -- type that designates a class-wide limited private type. There are - -- also constraints on the primitive subprograms of the class-wide type - -- (RM E.2.2(14), see Validate_RACW_Primitives). + -- type that designates a class-wide limited private type or subtype. + -- There are also constraints on the primitive subprograms of the + -- class-wide type (RM E.2.2(14), see Validate_RACW_Primitives). if Ekind (T) /= E_General_Access_Type - or else Ekind (Designated_Type (T)) /= E_Class_Wide_Type + or else not Is_Class_Wide_Type (Designated_Type (T)) then if In_RCI_Declaration (Parent (T)) then Error_Msg_N diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb index a2156b38cd4..d76475f7d30 100644 --- a/gcc/ada/sem_ch13.adb +++ b/gcc/ada/sem_ch13.adb @@ -40,6 +40,7 @@ with Rident; use Rident; with Rtsfind; use Rtsfind; with Sem; use Sem; with Sem_Aux; use Sem_Aux; +with Sem_Ch3; use Sem_Ch3; with Sem_Ch8; use Sem_Ch8; with Sem_Eval; use Sem_Eval; with Sem_Res; use Sem_Res; @@ -2197,6 +2198,38 @@ package body Sem_Ch13 is Analyze (Expression (N)); end Analyze_Free_Statement; + --------------------------- + -- Analyze_Freeze_Entity -- + --------------------------- + + -- This does not belong in sem_ch13, and I don't like the big new + -- dependency on sem_ch3, I would in fact move this to sem_ch3 or + -- somewhere else, and then Add_Internal_Interface_Entitites can be + -- private to sem_ch3.adb. ??? + + procedure Analyze_Freeze_Entity (N : Node_Id) is + E : constant Entity_Id := Entity (N); + + begin + -- For tagged types covering interfaces add internal entities that link + -- the primitives of the interfaces with the primitives that cover them. + + -- Note: These entities were originally generated only when generating + -- code because their main purpose was to provide support to initialize + -- the secondary dispatch tables. They are now generated also when + -- compiling with no code generation to provide ASIS the relationship + -- between interface primitives and tagged type primitives. + + if Ada_Version >= Ada_05 + and then Ekind (E) = E_Record_Type + and then Is_Tagged_Type (E) + and then not Is_Interface (E) + and then Has_Interfaces (E) + then + Add_Internal_Interface_Entities (E); + end if; + end Analyze_Freeze_Entity; + ------------------------------------------ -- Analyze_Record_Representation_Clause -- ------------------------------------------ diff --git a/gcc/ada/sem_ch13.ads b/gcc/ada/sem_ch13.ads index 175f3040fc8..93587fd38d2 100644 --- a/gcc/ada/sem_ch13.ads +++ b/gcc/ada/sem_ch13.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2008, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -31,6 +31,7 @@ package Sem_Ch13 is procedure Analyze_Attribute_Definition_Clause (N : Node_Id); procedure Analyze_Enumeration_Representation_Clause (N : Node_Id); procedure Analyze_Free_Statement (N : Node_Id); + procedure Analyze_Freeze_Entity (N : Node_Id); procedure Analyze_Record_Representation_Clause (N : Node_Id); procedure Analyze_Code_Statement (N : Node_Id); diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb index b96b9d9ba38..adea69db29e 100644 --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -753,6 +753,7 @@ package body Sem_Ch3 is -- is associated with one of the protected operations, and must -- be available in the scope that encloses the protected declaration. -- Otherwise the type is in the scope enclosing the subprogram. + -- If the function has formals, The return type of a subprogram -- declaration is analyzed in the scope of the subprogram (see -- Process_Formals) and thus the protected type, if present, is @@ -1506,6 +1507,96 @@ package body Sem_Ch3 is end if; end Add_Interface_Tag_Components; + ------------------------------------- + -- Add_Internal_Interface_Entities -- + ------------------------------------- + + procedure Add_Internal_Interface_Entities (Tagged_Type : Entity_Id) is + Elmt : Elmt_Id; + Iface : Entity_Id; + Iface_Elmt : Elmt_Id; + Iface_Prim : Entity_Id; + Ifaces_List : Elist_Id; + New_Subp : Entity_Id := Empty; + Prim : Entity_Id; + + begin + pragma Assert (Ada_Version >= Ada_05 + and then Is_Record_Type (Tagged_Type) + and then Is_Tagged_Type (Tagged_Type) + and then Has_Interfaces (Tagged_Type) + and then not Is_Interface (Tagged_Type)); + + Collect_Interfaces (Tagged_Type, Ifaces_List); + + Iface_Elmt := First_Elmt (Ifaces_List); + while Present (Iface_Elmt) loop + Iface := Node (Iface_Elmt); + + -- Exclude from this processing interfaces that are parents of + -- Tagged_Type because their primitives are located in the primary + -- dispatch table (and hence no auxiliary internal entities are + -- required to handle secondary dispatch tables in such case). + + if not Is_Ancestor (Iface, Tagged_Type) then + Elmt := First_Elmt (Primitive_Operations (Iface)); + while Present (Elmt) loop + Iface_Prim := Node (Elmt); + + if not Is_Predefined_Dispatching_Operation (Iface_Prim) then + Prim := + Find_Primitive_Covering_Interface + (Tagged_Type => Tagged_Type, + Iface_Prim => Iface_Prim); + + pragma Assert (Present (Prim)); + + Derive_Subprogram + (New_Subp => New_Subp, + Parent_Subp => Iface_Prim, + Derived_Type => Tagged_Type, + Parent_Type => Iface); + + -- Ada 2005 (AI-251): Decorate internal entity Iface_Subp + -- associated with interface types. These entities are + -- only registered in the list of primitives of its + -- corresponding tagged type because they are only used + -- to fill the contents of the secondary dispatch tables. + -- Therefore they are removed from the homonym chains. + + Set_Is_Hidden (New_Subp); + Set_Is_Internal (New_Subp); + Set_Alias (New_Subp, Prim); + Set_Is_Abstract_Subprogram (New_Subp, + Is_Abstract_Subprogram (Prim)); + Set_Interface_Alias (New_Subp, Iface_Prim); + + -- Internal entities associated with interface types are + -- only registered in the list of primitives of the tagged + -- type. They are only used to fill the contents of the + -- secondary dispatch tables. Therefore they are not needed + -- in the homonym chains. + + Remove_Homonym (New_Subp); + + -- Hidden entities associated with interfaces must have set + -- the Has_Delay_Freeze attribute to ensure that, in case of + -- locally defined tagged types (or compiling with static + -- dispatch tables generation disabled) the corresponding + -- entry of the secondary dispatch table is filled when + -- such an entity is frozen. + + Set_Has_Delayed_Freeze (New_Subp); + end if; + + Next_Elmt (Elmt); + end loop; + end if; + + Next_Elmt (Iface_Elmt); + end loop; + end Add_Internal_Interface_Entities; + ----------------------------------- -- Analyze_Component_Declaration -- ----------------------------------- @@ -2588,8 +2679,8 @@ package body Sem_Ch3 is and then Is_Access_Constant (Etype (E)) then Error_Msg_N - ("access to variable cannot be initialized " & - "with an access-to-constant expression", E); + ("access to variable cannot be initialized " + & "with an access-to-constant expression", E); end if; if not Assignment_OK (N) then @@ -2598,10 +2689,9 @@ package body Sem_Ch3 is Check_Unset_Reference (E); - -- If this is a variable, then set current value. - -- If this is a declared constant of a scalar type - -- with a static expression, indicate that it is - -- always valid. + -- If this is a variable, then set current value. If this is a + -- declared constant of a scalar type with a static expression, + -- indicate that it is always valid. if not Constant_Present (N) then if Compile_Time_Known_Value (E) then @@ -4827,17 +4917,74 @@ package body Sem_Ch3 is Parent_Type : Entity_Id; Derived_Type : Entity_Id) is - D_Constraint : Node_Id; - Disc_Spec : Node_Id; - Old_Disc : Entity_Id; - New_Disc : Entity_Id; + Loc : constant Source_Ptr := Sloc (N); + + Corr_Record : constant Entity_Id := + Make_Defining_Identifier (Loc, New_Internal_Name ('C')); + + Corr_Decl : Node_Id; + Corr_Decl_Needed : Boolean; + -- If the derived type has fewer discriminants than its parent, the + -- corresponding record is also a derived type, in order to account for + -- the bound discriminants. We create a full type declaration for it in + -- this case. Constraint_Present : constant Boolean := - Nkind (Subtype_Indication (Type_Definition (N))) - = N_Subtype_Indication; + Nkind (Subtype_Indication (Type_Definition (N))) = + N_Subtype_Indication; + + D_Constraint : Node_Id; + New_Constraint : Elist_Id; + Old_Disc : Entity_Id; + New_Disc : Entity_Id; + New_N : Node_Id; begin Set_Stored_Constraint (Derived_Type, No_Elist); + Corr_Decl_Needed := False; + Old_Disc := Empty; + + if Present (Discriminant_Specifications (N)) + and then Constraint_Present + then + Old_Disc := First_Discriminant (Parent_Type); + New_Disc := First (Discriminant_Specifications (N)); + while Present (New_Disc) and then Present (Old_Disc) loop + Next_Discriminant (Old_Disc); + Next (New_Disc); + end loop; + end if; + + if Present (Old_Disc) then + + -- The new type has fewer discriminants, so we need to create a new + -- corresponding record, which is derived from the corresponding + -- record of the parent, and has a stored constraint that captures + -- the values of the discriminant constraints. + + -- The type declaration for the derived corresponding record has + -- the same discriminant part and constraints as the current + -- declaration. Copy the unanalyzed tree to build declaration. + + Corr_Decl_Needed := True; + New_N := Copy_Separate_Tree (N); + + Corr_Decl := + Make_Full_Type_Declaration (Loc, + Defining_Identifier => Corr_Record, + Discriminant_Specifications => + Discriminant_Specifications (New_N), + Type_Definition => + Make_Derived_Type_Definition (Loc, + Subtype_Indication => + Make_Subtype_Indication (Loc, + Subtype_Mark => + New_Occurrence_Of + (Corresponding_Record_Type (Parent_Type), Loc), + Constraint => + Constraint + (Subtype_Indication (Type_Definition (New_N)))))); + end if; -- Copy Storage_Size and Relative_Deadline variables if task case @@ -4851,6 +4998,16 @@ package body Sem_Ch3 is if Present (Discriminant_Specifications (N)) then Push_Scope (Derived_Type); Check_Or_Process_Discriminants (N, Derived_Type); + + if Constraint_Present then + New_Constraint := + Expand_To_Stored_Constraint + (Parent_Type, + Build_Discriminant_Constraints + (Parent_Type, + Subtype_Indication (Type_Definition (N)), True)); + end if; + End_Scope; elsif Constraint_Present then @@ -4881,9 +5038,9 @@ package body Sem_Ch3 is end; end if; - -- All attributes are inherited from parent. In particular, - -- entries and the corresponding record type are the same. - -- Discriminants may be renamed, and must be treated separately. + -- By default, operations and private data are inherited from parent. + -- However, in the presence of bound discriminants, a new corresponding + -- record will be created, see below. Set_Has_Discriminants (Derived_Type, Has_Discriminants (Parent_Type)); @@ -4911,61 +5068,110 @@ package body Sem_Ch3 is (Constraints (Constraint (Subtype_Indication (Type_Definition (N))))); - Old_Disc := First_Discriminant (Parent_Type); - New_Disc := First_Discriminant (Derived_Type); - Disc_Spec := First (Discriminant_Specifications (N)); - while Present (Old_Disc) and then Present (Disc_Spec) loop - if Nkind (Discriminant_Type (Disc_Spec)) /= - N_Access_Definition - then - Analyze (Discriminant_Type (Disc_Spec)); + Old_Disc := First_Discriminant (Parent_Type); - if not Subtypes_Statically_Compatible ( - Etype (Discriminant_Type (Disc_Spec)), - Etype (Old_Disc)) - then - Error_Msg_N - ("not statically compatible with parent discriminant", - Discriminant_Type (Disc_Spec)); + while Present (D_Constraint) loop + if Nkind (D_Constraint) /= N_Discriminant_Association then + + -- Positional constraint. If it is a reference to a new + -- discriminant, it constrains the corresponding old one. + + if Nkind (D_Constraint) = N_Identifier then + New_Disc := First_Discriminant (Derived_Type); + while Present (New_Disc) loop + exit when Chars (New_Disc) = Chars (D_Constraint); + Next_Discriminant (New_Disc); + end loop; + + if Present (New_Disc) then + Set_Corresponding_Discriminant (New_Disc, Old_Disc); + end if; + end if; + + Next_Discriminant (Old_Disc); + + -- if this is a named constraint, search by name for the old + -- discriminants constrained by the new one. + + elsif Nkind (Expression (D_Constraint)) = N_Identifier then + + -- Find new discriminant with that name + + New_Disc := First_Discriminant (Derived_Type); + while Present (New_Disc) loop + exit when + Chars (New_Disc) = Chars (Expression (D_Constraint)); + Next_Discriminant (New_Disc); + end loop; + + if Present (New_Disc) then + + -- Verify that new discriminant renames some discriminant + -- of the parent type, and associate the new discriminant + -- with one or more old ones that it renames. + + declare + Selector : Node_Id; + + begin + Selector := First (Selector_Names (D_Constraint)); + while Present (Selector) loop + Old_Disc := First_Discriminant (Parent_Type); + while Present (Old_Disc) loop + exit when Chars (Old_Disc) = Chars (Selector); + Next_Discriminant (Old_Disc); + end loop; + + if Present (Old_Disc) then + Set_Corresponding_Discriminant + (New_Disc, Old_Disc); + end if; + + Next (Selector); + end loop; + end; end if; end if; - if Nkind (D_Constraint) = N_Identifier - and then Chars (D_Constraint) /= - Chars (Defining_Identifier (Disc_Spec)) + Next (D_Constraint); + end loop; + + New_Disc := First_Discriminant (Derived_Type); + while Present (New_Disc) loop + if No (Corresponding_Discriminant (New_Disc)) then + Error_Msg_NE + ("new discriminant& must constrain old one", N, New_Disc); + + elsif not + Subtypes_Statically_Compatible + (Etype (New_Disc), + Etype (Corresponding_Discriminant (New_Disc))) then - Error_Msg_N ("new discriminants must constrain old ones", - D_Constraint); - else - Set_Corresponding_Discriminant (New_Disc, Old_Disc); + Error_Msg_NE + ("& not statically compatible with parent discriminant", + N, New_Disc); end if; - Next_Discriminant (Old_Disc); Next_Discriminant (New_Disc); - Next (Disc_Spec); end loop; - - if Present (Old_Disc) or else Present (Disc_Spec) then - Error_Msg_N ("discriminant mismatch in derivation", N); - end if; - end if; elsif Present (Discriminant_Specifications (N)) then Error_Msg_N - ("missing discriminant constraint in untagged derivation", - N); + ("missing discriminant constraint in untagged derivation", N); end if; + -- The entity chain of the derived type includes the new discriminants + -- but shares operations with the parent. + if Present (Discriminant_Specifications (N)) then Old_Disc := First_Discriminant (Parent_Type); while Present (Old_Disc) loop - if No (Next_Entity (Old_Disc)) or else Ekind (Next_Entity (Old_Disc)) /= E_Discriminant then - Set_Next_Entity (Last_Entity (Derived_Type), - Next_Entity (Old_Disc)); + Set_Next_Entity + (Last_Entity (Derived_Type), Next_Entity (Old_Disc)); exit; end if; @@ -4984,6 +5190,13 @@ package body Sem_Ch3 is Set_Last_Entity (Derived_Type, Last_Entity (Parent_Type)); Set_Has_Completion (Derived_Type); + + if Corr_Decl_Needed then + Set_Stored_Constraint (Derived_Type, New_Constraint); + Insert_After (N, Corr_Decl); + Analyze (Corr_Decl); + Set_Corresponding_Record_Type (Derived_Type, Corr_Record); + end if; end Build_Derived_Concurrent_Type; ------------------------------------ diff --git a/gcc/ada/sem_ch3.ads b/gcc/ada/sem_ch3.ads index 6c7dbaae032..6bfa52844d0 100644 --- a/gcc/ada/sem_ch3.ads +++ b/gcc/ada/sem_ch3.ads @@ -64,6 +64,11 @@ package Sem_Ch3 is -- the signature of the implicit type works like the profile of a regular -- subprogram. + procedure Add_Internal_Interface_Entities (Tagged_Type : Entity_Id); + -- Add to the list of primitives of Tagged_Type the internal entities + -- associated with covered interface primitives. These entities link the + -- interface primitives with the tagged type primitives that cover them. + procedure Analyze_Declarations (L : List_Id); -- Called to analyze a list of declarations (in what context ???). Also -- performs necessary freezing actions (more description needed ???) @@ -95,23 +100,22 @@ package Sem_Ch3 is -- Could both mechanisms be merged ??? procedure Check_Abstract_Overriding (T : Entity_Id); - -- Check that all abstract subprograms inherited from T's parent type - -- have been overridden as required, and that nonabstract subprograms - -- have not been incorrectly overridden with an abstract subprogram. + -- Check that all abstract subprograms inherited from T's parent type have + -- been overridden as required, and that nonabstract subprograms have not + -- been incorrectly overridden with an abstract subprogram. procedure Check_Aliased_Component_Types (T : Entity_Id); -- Given an array type or record type T, check that if the type is - -- nonlimited, then the nominal subtype of any components of T - -- that have discriminants must be constrained. + -- nonlimited, then the nominal subtype of any components of T that + -- have discriminants must be constrained. procedure Check_Completion (Body_Id : Node_Id := Empty); - -- At the end of a declarative part, verify that all entities that - -- require completion have received one. If Body_Id is absent, the - -- error indicating a missing completion is placed on the declaration - -- that needs completion. If Body_Id is present, it is the defining - -- identifier of a package body, and errors are posted on that node, - -- rather than on the declarations that require completion in the package - -- declaration. + -- At the end of a declarative part, verify that all entities that require + -- completion have received one. If Body_Id is absent, the error indicating + -- a missing completion is placed on the declaration that needs completion. + -- If Body_Id is present, it is the defining identifier of a package body, + -- and errors are posted on that node, rather than on the declarations that + -- require completion in the package declaration. procedure Derive_Subprogram (New_Subp : in out Entity_Id; @@ -138,8 +142,8 @@ package Sem_Ch3 is -- the derived subprograms are aliased to those of the actual, not those of -- the ancestor. -- - -- Note: one might expect this to be private to the package body, but - -- there is one rather unusual usage in package Exp_Dist. + -- Note: one might expect this to be private to the package body, but there + -- is one rather unusual usage in package Exp_Dist. function Find_Hidden_Interface (Src : Elist_Id; @@ -162,8 +166,8 @@ package Sem_Ch3 is Typ_For_Constraint : Entity_Id; Constraint : Elist_Id) return Node_Id; -- ??? MORE DOCUMENTATION - -- Given a discriminant somewhere in the Typ_For_Constraint tree - -- and a Constraint, return the value of that discriminant. + -- Given a discriminant somewhere in the Typ_For_Constraint tree and a + -- Constraint, return the value of that discriminant. function Is_Null_Extension (T : Entity_Id) return Boolean; -- Returns True if the tagged type T has an N_Full_Type_Declaration that @@ -232,7 +236,7 @@ package Sem_Ch3 is -- of the dependant private subtypes. The second action is to recopy the -- primitive operations of the private view (in the tagged case). -- N is the N_Full_Type_Declaration node. - + -- -- Full_T is the full view of the type whose full declaration is in N. -- -- Priv_T is the private view of the type whose full declaration is in N. @@ -243,16 +247,16 @@ package Sem_Ch3 is Check_List : List_Id := Empty_List; R_Check_Off : Boolean := False); -- Process a range expression that appears in a declaration context. The - -- range is analyzed and resolved with the base type of the given type, - -- and an appropriate check for expressions in non-static contexts made - -- on the bounds. R is analyzed and resolved using T, so the caller should - -- if necessary link R into the tree before the call, and in particular in - -- the case of a subtype declaration, it is appropriate to set the parent - -- pointer of R so that the types get properly frozen. The Check_List - -- parameter is used when the subprogram is called from - -- Build_Record_Init_Proc and is used to return a set of constraint - -- checking statements generated by the Checks package. R_Check_Off is set - -- to True when the call to Range_Check is to be skipped. + -- range is analyzed and resolved with the base type of the given type, and + -- an appropriate check for expressions in non-static contexts made on the + -- bounds. R is analyzed and resolved using T, so the caller should if + -- necessary link R into the tree before the call, and in particular in the + -- case of a subtype declaration, it is appropriate to set the parent + -- pointer of R so that the types get properly frozen. Check_List is used + -- when the subprogram is called from Build_Record_Init_Proc and is used to + -- return a set of constraint checking statements generated by the Checks + -- package. R_Check_Off is set to True when the call to Range_Check is to + -- be skipped. function Process_Subtype (S : Node_Id; diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb index 826380e4c27..28856d0f24d 100644 --- a/gcc/ada/sem_ch4.adb +++ b/gcc/ada/sem_ch4.adb @@ -47,6 +47,7 @@ with Sem_Cat; use Sem_Cat; with Sem_Ch3; use Sem_Ch3; with Sem_Ch6; use Sem_Ch6; with Sem_Ch8; use Sem_Ch8; +with Sem_SCIL; use Sem_SCIL; with Sem_Disp; use Sem_Disp; with Sem_Dist; use Sem_Dist; with Sem_Eval; use Sem_Eval; @@ -3875,6 +3876,15 @@ package body Sem_Ch4 is T : Entity_Id; begin + -- Check if the expression is a function call for which we need to + -- adjust a SCIL dispatching node. + + if Generate_SCIL + and then Nkind (Expr) = N_Function_Call + then + Adjust_SCIL_Node (N, Expr); + end if; + -- If Conversion_OK is set, then the Etype is already set, and the -- only processing required is to analyze the expression. This is -- used to construct certain "illegal" conversions which are not diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb index fe7ffbc49c3..1f6806b231a 100644 --- a/gcc/ada/sem_ch5.adb +++ b/gcc/ada/sem_ch5.adb @@ -46,6 +46,7 @@ with Sem_Disp; use Sem_Disp; with Sem_Elab; use Sem_Elab; with Sem_Eval; use Sem_Eval; with Sem_Res; use Sem_Res; +with Sem_SCIL; use Sem_SCIL; with Sem_Type; use Sem_Type; with Sem_Util; use Sem_Util; with Sem_Warn; use Sem_Warn; @@ -1570,6 +1571,15 @@ package body Sem_Ch5 is Name => New_Occurrence_Of (Id, Loc), Expression => Relocate_Node (Original_Bound)); + -- If the relocated node is a function call then check if some + -- SCIL node references it and needs readjustment. + + if Generate_SCIL + and then Nkind (Original_Bound) = N_Function_Call + then + Adjust_SCIL_Node (Original_Bound, Expression (Assign)); + end if; + Insert_Before (Parent (N), Assign); Analyze (Assign); diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index 7d4bcd15211..32323400b6d 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -681,6 +681,11 @@ package body Sem_Ch6 is end if; end if; + -- Mark the return object as referenced, since the return is an + -- implicit reference of the object. + + Set_Referenced (Defining_Identifier (Obj_Decl)); + Check_References (Stm_Entity); end; end if; @@ -4370,6 +4375,13 @@ package body Sem_Ch6 is elsif Ekind (Subp) = E_Entry then Decl := Parent (Subp); + -- No point in analyzing a malformed operator + + elsif Nkind (Subp) = N_Defining_Operator_Symbol + and then Error_Posted (Subp) + then + return; + else Decl := Unit_Declaration_Node (Subp); end if; @@ -4471,7 +4483,8 @@ package body Sem_Ch6 is Style.Missing_Overriding (Decl, Subp); end if; - -- If Subp is an operator, it may override a predefined operation. + -- If Subp is an operator, it may override a predefined operation, if + -- it is defined in the same scope as the type to which it applies. -- In that case overridden_subp is empty because of our implicit -- representation for predefined operators. We have to check whether the -- signature of Subp matches that of a predefined operator. Note that @@ -4482,54 +4495,65 @@ package body Sem_Ch6 is -- explicit overridden operation. elsif Nkind (Subp) = N_Defining_Operator_Symbol then + declare + Typ : constant Entity_Id := + Base_Type (Etype (First_Formal (Subp))); - if Must_Not_Override (Spec) then - - -- If this is not a primitive operation or protected subprogram, - -- then "not overriding" is illegal. + Can_Override : constant Boolean := + Operator_Matches_Spec (Subp, Subp) + and then Scope (Subp) = Scope (Typ) + and then not Is_Class_Wide_Type (Typ); - if not Is_Primitive - and then Ekind (Scope (Subp)) /= E_Protected_Type - then - Error_Msg_N - ("overriding indicator only allowed " - & "if subprogram is primitive", Subp); + begin + if Must_Not_Override (Spec) then - elsif Operator_Matches_Spec (Subp, Subp) then - Error_Msg_NE - ("subprogram & overrides predefined operator ", Spec, Subp); - end if; + -- If this is not a primitive or a protected subprogram, then + -- "not overriding" is illegal. - elsif Must_Override (Spec) then - if Is_Overriding_Operation (Subp) then - Set_Is_Overriding_Operation (Subp); + if not Is_Primitive + and then Ekind (Scope (Subp)) /= E_Protected_Type + then + Error_Msg_N + ("overriding indicator only allowed " + & "if subprogram is primitive", Subp); - elsif not Operator_Matches_Spec (Subp, Subp) then - Error_Msg_NE ("subprogram & is not overriding", Spec, Subp); - end if; + elsif Can_Override then + Error_Msg_NE + ("subprogram & overrides predefined operator ", + Spec, Subp); + end if; - elsif not Error_Posted (Subp) - and then Style_Check - and then Operator_Matches_Spec (Subp, Subp) - and then - not Is_Predefined_File_Name - (Unit_File_Name (Get_Source_Unit (Subp))) - then - Set_Is_Overriding_Operation (Subp); + elsif Must_Override (Spec) then + if Is_Overriding_Operation (Subp) then + Set_Is_Overriding_Operation (Subp); - -- If style checks are enabled, indicate that the indicator is - -- missing. However, at the point of declaration, the type of - -- which this is a primitive operation may be private, in which - -- case the indicator would be premature. + elsif not Can_Override then + Error_Msg_NE ("subprogram & is not overriding", Spec, Subp); + end if; - if Has_Private_Declaration (Etype (Subp)) - or else Has_Private_Declaration (Etype (First_Formal (Subp))) + elsif not Error_Posted (Subp) + and then Style_Check + and then Can_Override + and then + not Is_Predefined_File_Name + (Unit_File_Name (Get_Source_Unit (Subp))) then - null; - else - Style.Missing_Overriding (Decl, Subp); + Set_Is_Overriding_Operation (Subp); + + -- If style checks are enabled, indicate that the indicator is + -- missing. However, at the point of declaration, the type of + -- which this is a primitive operation may be private, in which + -- case the indicator would be premature. + + if Has_Private_Declaration (Etype (Subp)) + or else Has_Private_Declaration (Etype (First_Formal (Subp))) + then + null; + else + Style.Missing_Overriding (Decl, Subp); + end if; end if; - end if; + end; elsif Must_Override (Spec) then if Ekind (Subp) = E_Entry then @@ -7673,10 +7697,22 @@ package body Sem_Ch6 is Set_Is_Overriding_Operation (S); Check_Overriding_Indicator (S, E, Is_Primitive => True); - -- Indicate that S overrides the operation from which - -- E is inherited. - - if Comes_From_Source (S) then + -- If S is a user-defined subprogram or a null procedure + -- expanded to override an inherited null procedure, then + -- indicate that E overrides the operation from which S + -- is inherited. It seems odd that Overridden_Operation + -- isn't set in all cases where Is_Overriding_Operation + -- is true, but doing so causes infinite loops in the + -- compiler for implicit overriding subprograms. ??? + + if Comes_From_Source (S) + or else + (Present (Parent (S)) + and then + Nkind (Parent (S)) = N_Procedure_Specification + and then + Null_Present (Parent (S))) + then if Present (Alias (E)) then Set_Overridden_Operation (S, Alias (E)); else diff --git a/gcc/ada/sem_ch7.adb b/gcc/ada/sem_ch7.adb index c3a1fb39713..27505f215a9 100644 --- a/gcc/ada/sem_ch7.adb +++ b/gcc/ada/sem_ch7.adb @@ -1907,12 +1907,15 @@ package body Sem_Ch7 is if Tagged_Present (Def) then Set_Ekind (Id, E_Record_Type_With_Private); - Make_Class_Wide_Type (Id); Set_Primitive_Operations (Id, New_Elmt_List); Set_Is_Abstract_Type (Id, Abstract_Present (Def)); Set_Is_Limited_Record (Id, Limited_Present (Def)); Set_Has_Delayed_Freeze (Id, True); + -- Create a class-wide type with the same attributes + + Make_Class_Wide_Type (Id); + elsif Abstract_Present (Def) then Error_Msg_N ("only a tagged type can be abstract", N); end if; diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb index 385337a99bb..18853d72729 100644 --- a/gcc/ada/sem_eval.adb +++ b/gcc/ada/sem_eval.adb @@ -424,6 +424,10 @@ package body Sem_Eval is -- have a 'Last/'First reference in which case the value returned is the -- appropriate type bound. + function Is_Known_Valid_Operand (Opnd : Node_Id) return Boolean; + -- Even if the context does not assume that values are valid, some + -- simple cases can be recognized. + function Is_Same_Value (L, R : Node_Id) return Boolean; -- Returns True iff L and R represent expressions that definitely -- have identical (but not necessarily compile time known) values @@ -522,7 +526,7 @@ package body Sem_Eval is else -- Attribute_Name (N) = Name_Last return Make_Integer_Literal (Sloc (N), Intval => Intval (String_Literal_Low_Bound (Xtyp)) - + String_Literal_Length (Xtyp)); + + String_Literal_Length (Xtyp)); end if; end if; @@ -551,6 +555,22 @@ package body Sem_Eval is return N; end Compare_Fixup; + ---------------------------- + -- Is_Known_Valid_Operand -- + ---------------------------- + + function Is_Known_Valid_Operand (Opnd : Node_Id) return Boolean is + begin + return (Is_Entity_Name (Opnd) + and then + (Is_Known_Valid (Entity (Opnd)) + or else Ekind (Entity (Opnd)) = E_In_Parameter + or else + (Ekind (Entity (Opnd)) in Object_Kind + and then Present (Current_Value (Entity (Opnd)))))) + or else Is_OK_Static_Expression (Opnd); + end Is_Known_Valid_Operand; + ------------------- -- Is_Same_Value -- ------------------- @@ -560,12 +580,11 @@ package body Sem_Eval is Rf : constant Node_Id := Compare_Fixup (R); function Is_Same_Subscript (L, R : List_Id) return Boolean; - -- L, R are the Expressions values from two attribute nodes - -- for First or Last attributes. Either may be set to No_List - -- if no expressions are present (indicating subscript 1). - -- The result is True if both expressions represent the same - -- subscript (note that one case is where one subscript is - -- missing and the other is explicitly set to 1). + -- L, R are the Expressions values from two attribute nodes for First + -- or Last attributes. Either may be set to No_List if no expressions + -- are present (indicating subscript 1). The result is True if both + -- expressions represent the same subscript (note one case is where + -- one subscript is missing and the other is explicitly set to 1). ----------------------- -- Is_Same_Subscript -- @@ -886,20 +905,12 @@ package body Sem_Eval is and then LLo = RLo then - -- if the range includes a single literal and we - -- can assume validity then the result is known - -- even if an operand is not static. + -- If the range includes a single literal and we can assume + -- validity then the result is known even if an operand is + -- not static. if Assume_Valid then return EQ; - - elsif Is_Entity_Name (L) - and then Is_Entity_Name (R) - and then Is_Known_Valid (Entity (L)) - and then Is_Known_Valid (Entity (R)) - then - return EQ; - else return Unknown; end if; @@ -909,6 +920,15 @@ package body Sem_Eval is elsif RHi = LLo then return GE; + + elsif not Is_Known_Valid_Operand (L) + and then not Assume_Valid + then + if Is_Same_Value (L, R) then + return EQ; + else + return Unknown; + end if; end if; end if; end; diff --git a/gcc/ada/sem_scil.adb b/gcc/ada/sem_scil.adb new file mode 100644 index 00000000000..f47d1288f81 --- /dev/null +++ b/gcc/ada/sem_scil.adb @@ -0,0 +1,649 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- S E M _ S C I L -- +-- -- +-- B o d y -- +-- -- +-- Copyright (C) 2009, Free Software Foundation, Inc. -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- +-- http://www.gnu.org/licenses for a complete copy of the license. -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +with Einfo; use Einfo; +with Namet; use Namet; +with Nlists; use Nlists; +with Opt; use Opt; +with Rtsfind; use Rtsfind; +with Sem; use Sem; +with Sem_Aux; use Sem_Aux; +with Sem_Util; use Sem_Util; +with Sinfo; use Sinfo; +with Snames; use Snames; +with Stand; use Stand; + +package body Sem_SCIL is + + ---------------------- + -- Adjust_SCIL_Node -- + ---------------------- + + procedure Adjust_SCIL_Node (Old_Node : Node_Id; New_Node : Node_Id) is + SCIL_Node : Node_Id; + + begin + pragma Assert (Generate_SCIL); + + -- Check cases in which no action is required. Currently the only SCIL + -- nodes that may require adjustment are those of dispatching calls + -- internally generated by the frontend. + + if Comes_From_Source (Old_Node) + or else not + Nkind_In (New_Node, N_Function_Call, N_Procedure_Call_Statement) + then + return; + + -- Conditional expression associated with equality operator. Old_Node + -- may be part of the expansion of the predefined equality operator of + -- a tagged type and hence we need to check if it has a SCIL dispatching + -- node that needs adjustment. + + elsif Nkind (Old_Node) = N_Conditional_Expression + and then (Nkind (Original_Node (Old_Node)) = N_Op_Eq + or else + (Nkind (Original_Node (Old_Node)) = N_Function_Call + and then Chars (Name (Original_Node (Old_Node))) = + Name_Op_Eq)) + then + null; + + -- Type conversions may involve dispatching calls to functions whose + -- associated SCIL dispatching node needs adjustment. + + elsif Nkind (Old_Node) = N_Type_Conversion then + null; + + -- Relocated subprogram call + + elsif Nkind (Old_Node) = Nkind (New_Node) + and then Original_Node (Old_Node) = Original_Node (New_Node) + then + null; + + else + return; + end if; + + -- Search for the SCIL node and update it (if found) + + SCIL_Node := Find_SCIL_Node (Old_Node); + + if Present (SCIL_Node) then + Set_SCIL_Related_Node (SCIL_Node, New_Node); + end if; + end Adjust_SCIL_Node; + + --------------------- + -- Check_SCIL_Node -- + --------------------- + + -- Is this a good name for the function, given it only deals with + -- N_SCIL_Dispatching_Call case ??? + + function Check_SCIL_Node (N : Node_Id) return Traverse_Result is + Ctrl_Tag : Node_Id; + Ctrl_Typ : Entity_Id; + + begin + if Nkind (N) = N_SCIL_Dispatching_Call then + Ctrl_Tag := SCIL_Controlling_Tag (N); + + -- SCIL_Related_Node of SCIL dispatching call nodes MUST reference + -- subprogram calls. + + if not Nkind_In (SCIL_Related_Node (N), N_Function_Call, + N_Procedure_Call_Statement) + then + pragma Assert (False); + raise Program_Error; + + -- In simple cases the controlling tag is the tag of the controlling + -- argument (i.e. Obj.Tag). + + elsif Nkind (Ctrl_Tag) = N_Selected_Component then + Ctrl_Typ := Etype (Ctrl_Tag); + + -- Interface types are unsupported + + if Is_Interface (Ctrl_Typ) + or else (RTE_Available (RE_Interface_Tag) + and then Ctrl_Typ = RTE (RE_Interface_Tag)) + then + null; + + else + pragma Assert (Ctrl_Typ = RTE (RE_Tag)); + null; + end if; + + -- When the controlling tag of a dispatching call is an identifier + -- the SCIL_Controlling_Tag attribute references the corresponding + -- object or parameter declaration. Interface types are still + -- unsupported. + + elsif Nkind_In (Ctrl_Tag, N_Object_Declaration, + N_Parameter_Specification) + then + Ctrl_Typ := Etype (Defining_Identifier (Ctrl_Tag)); + + -- Interface types are unsupported. + + if Is_Interface (Ctrl_Typ) + or else (RTE_Available (RE_Interface_Tag) + and then Ctrl_Typ = RTE (RE_Interface_Tag)) + or else (Is_Access_Type (Ctrl_Typ) + and then + Is_Interface + (Available_View + (Base_Type (Designated_Type (Ctrl_Typ))))) + then + null; + + else + pragma Assert + (Ctrl_Typ = RTE (RE_Tag) + or else + (Is_Access_Type (Ctrl_Typ) + and then Available_View + (Base_Type (Designated_Type (Ctrl_Typ))) = + RTE (RE_Tag))); + null; + end if; + + -- Interface types are unsupported + + elsif Is_Interface (Etype (Ctrl_Tag)) then + null; + + else + pragma Assert (False); + raise Program_Error; + end if; + + return Skip; + + -- Node is not N_SCIL_Dispatching_Call + + else + return OK; + end if; + end Check_SCIL_Node; + + -------------------- + -- Find_SCIL_Node -- + -------------------- + + function Find_SCIL_Node (Node : Node_Id) return Node_Id is + Found_Node : Node_Id; + -- This variable stores the last node found by the nested subprogram + -- Find_SCIL_Node. + + function Find_SCIL_Node (L : List_Id) return Boolean; + -- Searches in list L for a SCIL node associated with a dispatching call + -- whose SCIL_Related_Node is Node. If found returns true and stores the + -- SCIL node in Found_Node; otherwise returns False and sets Found_Node + -- to Empty. + + -------------------- + -- Find_SCIL_Node -- + -------------------- + + function Find_SCIL_Node (L : List_Id) return Boolean is + N : Node_Id; + + begin + N := First (L); + while Present (N) loop + if Nkind (N) in N_SCIL_Node + and then SCIL_Related_Node (N) = Node + then + Found_Node := N; + return True; + end if; + + Next (N); + end loop; + + Found_Node := Empty; + return False; + end Find_SCIL_Node; + + -- Local variables + + P : Node_Id; + + -- Start of processing for Find_SCIL_Node + + begin + pragma Assert (Generate_SCIL); + + -- Search for the SCIL node in list associated with a transient scope + + if Scope_Is_Transient then + declare + SE : Scope_Stack_Entry + renames Scope_Stack.Table (Scope_Stack.Last); + begin + if SE.Is_Transient + and then Present (SE.Actions_To_Be_Wrapped_Before) + and then Find_SCIL_Node (SE.Actions_To_Be_Wrapped_Before) + then + return Found_Node; + end if; + end; + end if; + + -- Otherwise climb up the tree searching for the SCIL node analyzing + -- all the lists in which Insert_Actions may have inserted it + + P := Node; + while Present (P) loop + case Nkind (P) is + + -- Actions associated with AND THEN or OR ELSE + + when N_Short_Circuit => + if Present (Actions (P)) + and then Find_SCIL_Node (Actions (P)) + then + return Found_Node; + end if; + + -- Actions of conditional expressions + + when N_Conditional_Expression => + if (Present (Then_Actions (P)) + and then Find_SCIL_Node (Actions (P))) + or else + (Present (Else_Actions (P)) + and then Find_SCIL_Node (Else_Actions (P))) + then + return Found_Node; + end if; + + -- Conditions of while expression or elsif. + + when N_Iteration_Scheme | + N_Elsif_Part + => + if Present (Condition_Actions (P)) + and then Find_SCIL_Node (Condition_Actions (P)) + then + return Found_Node; + end if; + + -- Statements, declarations, pragmas, representation clauses + + when + -- Statements + + N_Procedure_Call_Statement | + N_Statement_Other_Than_Procedure_Call | + + -- Pragmas + + N_Pragma | + + -- Representation_Clause + + N_At_Clause | + N_Attribute_Definition_Clause | + N_Enumeration_Representation_Clause | + N_Record_Representation_Clause | + + -- Declarations + + N_Abstract_Subprogram_Declaration | + N_Entry_Body | + N_Exception_Declaration | + N_Exception_Renaming_Declaration | + N_Formal_Abstract_Subprogram_Declaration | + N_Formal_Concrete_Subprogram_Declaration | + N_Formal_Object_Declaration | + N_Formal_Type_Declaration | + N_Full_Type_Declaration | + N_Function_Instantiation | + N_Generic_Function_Renaming_Declaration | + N_Generic_Package_Declaration | + N_Generic_Package_Renaming_Declaration | + N_Generic_Procedure_Renaming_Declaration | + N_Generic_Subprogram_Declaration | + N_Implicit_Label_Declaration | + N_Incomplete_Type_Declaration | + N_Number_Declaration | + N_Object_Declaration | + N_Object_Renaming_Declaration | + N_Package_Body | + N_Package_Body_Stub | + N_Package_Declaration | + N_Package_Instantiation | + N_Package_Renaming_Declaration | + N_Private_Extension_Declaration | + N_Private_Type_Declaration | + N_Procedure_Instantiation | + N_Protected_Body | + N_Protected_Body_Stub | + N_Protected_Type_Declaration | + N_Single_Task_Declaration | + N_Subprogram_Body | + N_Subprogram_Body_Stub | + N_Subprogram_Declaration | + N_Subprogram_Renaming_Declaration | + N_Subtype_Declaration | + N_Task_Body | + N_Task_Body_Stub | + N_Task_Type_Declaration | + + -- Freeze entity behaves like a declaration or statement + + N_Freeze_Entity + => + -- Do not search here if the item is not a list member + + if not Is_List_Member (P) then + null; + + -- Do not search if parent of P is an N_Component_Association + -- node (i.e. we are in the context of an N_Aggregate or + -- N_Extension_Aggregate node). In this case the node should + -- have been added before the entire aggregate. + + elsif Nkind (Parent (P)) = N_Component_Association then + null; + + -- Do not search if the parent of P is either an N_Variant + -- node or an N_Record_Definition node. In this case the node + -- should have been added before the entire record. + + elsif Nkind (Parent (P)) = N_Variant + or else Nkind (Parent (P)) = N_Record_Definition + then + null; + + -- Otherwise search it in the list containing this node + + elsif Find_SCIL_Node (List_Containing (P)) then + return Found_Node; + end if; + + -- A special case, N_Raise_xxx_Error can act either as a statement + -- or a subexpression. We diferentiate them by looking at the + -- Etype. It is set to Standard_Void_Type in the statement case. + + when + N_Raise_xxx_Error => + if Etype (P) = Standard_Void_Type then + if Is_List_Member (P) + and then Find_SCIL_Node (List_Containing (P)) + then + return Found_Node; + end if; + + -- In the subexpression case, keep climbing + + else + null; + end if; + + -- If a component association appears within a loop created for + -- an array aggregate, check if the SCIL node was added to the + -- the list of nodes attached to the association. + + when + N_Component_Association => + if Nkind (Parent (P)) = N_Aggregate + and then Present (Loop_Actions (P)) + and then Find_SCIL_Node (Loop_Actions (P)) + then + return Found_Node; + end if; + + -- Another special case, an attribute denoting a procedure call + + when + N_Attribute_Reference => + if Is_Procedure_Attribute_Name (Attribute_Name (P)) + and then Find_SCIL_Node (List_Containing (P)) + then + return Found_Node; + + -- In the subexpression case, keep climbing + + else + null; + end if; + + -- SCIL nodes do not have subtrees and hence they can never be + -- found climbing tree + + when + N_SCIL_Dispatch_Table_Object_Init | + N_SCIL_Dispatch_Table_Tag_Init | + N_SCIL_Dispatching_Call | + N_SCIL_Tag_Init + => + pragma Assert (False); + raise Program_Error; + + -- For all other node types, keep climbing tree + + when + N_Abortable_Part | + N_Accept_Alternative | + N_Access_Definition | + N_Access_Function_Definition | + N_Access_Procedure_Definition | + N_Access_To_Object_Definition | + N_Aggregate | + N_Allocator | + N_Case_Statement_Alternative | + N_Character_Literal | + N_Compilation_Unit | + N_Compilation_Unit_Aux | + N_Component_Clause | + N_Component_Declaration | + N_Component_Definition | + N_Component_List | + N_Constrained_Array_Definition | + N_Decimal_Fixed_Point_Definition | + N_Defining_Character_Literal | + N_Defining_Identifier | + N_Defining_Operator_Symbol | + N_Defining_Program_Unit_Name | + N_Delay_Alternative | + N_Delta_Constraint | + N_Derived_Type_Definition | + N_Designator | + N_Digits_Constraint | + N_Discriminant_Association | + N_Discriminant_Specification | + N_Empty | + N_Entry_Body_Formal_Part | + N_Entry_Call_Alternative | + N_Entry_Declaration | + N_Entry_Index_Specification | + N_Enumeration_Type_Definition | + N_Error | + N_Exception_Handler | + N_Expanded_Name | + N_Explicit_Dereference | + N_Extension_Aggregate | + N_Floating_Point_Definition | + N_Formal_Decimal_Fixed_Point_Definition | + N_Formal_Derived_Type_Definition | + N_Formal_Discrete_Type_Definition | + N_Formal_Floating_Point_Definition | + N_Formal_Modular_Type_Definition | + N_Formal_Ordinary_Fixed_Point_Definition | + N_Formal_Package_Declaration | + N_Formal_Private_Type_Definition | + N_Formal_Signed_Integer_Type_Definition | + N_Function_Call | + N_Function_Specification | + N_Generic_Association | + N_Handled_Sequence_Of_Statements | + N_Identifier | + N_In | + N_Index_Or_Discriminant_Constraint | + N_Indexed_Component | + N_Integer_Literal | + N_Itype_Reference | + N_Label | + N_Loop_Parameter_Specification | + N_Mod_Clause | + N_Modular_Type_Definition | + N_Not_In | + N_Null | + N_Op_Abs | + N_Op_Add | + N_Op_And | + N_Op_Concat | + N_Op_Divide | + N_Op_Eq | + N_Op_Expon | + N_Op_Ge | + N_Op_Gt | + N_Op_Le | + N_Op_Lt | + N_Op_Minus | + N_Op_Mod | + N_Op_Multiply | + N_Op_Ne | + N_Op_Not | + N_Op_Or | + N_Op_Plus | + N_Op_Rem | + N_Op_Rotate_Left | + N_Op_Rotate_Right | + N_Op_Shift_Left | + N_Op_Shift_Right | + N_Op_Shift_Right_Arithmetic | + N_Op_Subtract | + N_Op_Xor | + N_Operator_Symbol | + N_Ordinary_Fixed_Point_Definition | + N_Others_Choice | + N_Package_Specification | + N_Parameter_Association | + N_Parameter_Specification | + N_Pop_Constraint_Error_Label | + N_Pop_Program_Error_Label | + N_Pop_Storage_Error_Label | + N_Pragma_Argument_Association | + N_Procedure_Specification | + N_Protected_Definition | + N_Push_Constraint_Error_Label | + N_Push_Program_Error_Label | + N_Push_Storage_Error_Label | + N_Qualified_Expression | + N_Range | + N_Range_Constraint | + N_Real_Literal | + N_Real_Range_Specification | + N_Record_Definition | + N_Reference | + N_Selected_Component | + N_Signed_Integer_Type_Definition | + N_Single_Protected_Declaration | + N_Slice | + N_String_Literal | + N_Subprogram_Info | + N_Subtype_Indication | + N_Subunit | + N_Task_Definition | + N_Terminate_Alternative | + N_Triggering_Alternative | + N_Type_Conversion | + N_Unchecked_Expression | + N_Unchecked_Type_Conversion | + N_Unconstrained_Array_Definition | + N_Unused_At_End | + N_Unused_At_Start | + N_Use_Package_Clause | + N_Use_Type_Clause | + N_Variant | + N_Variant_Part | + N_Validate_Unchecked_Conversion | + N_With_Clause + => + null; + + end case; + + -- If we fall through above tests, keep climbing tree + + if Nkind (Parent (P)) = N_Subunit then + + -- This is the proper body corresponding to a stub. Insertion done + -- at the point of the stub, which is in the declarative part of + -- the parent unit. + + P := Corresponding_Stub (Parent (P)); + + else + P := Parent (P); + end if; + end loop; + + -- SCIL node not found + + return Empty; + end Find_SCIL_Node; + + ------------------------- + -- First_Non_SCIL_Node -- + ------------------------- + + function First_Non_SCIL_Node (L : List_Id) return Node_Id is + N : Node_Id; + + begin + N := First (L); + while Nkind (N) in N_SCIL_Node loop + Next (N); + end loop; + + return N; + end First_Non_SCIL_Node; + + ------------------------ + -- Next_Non_SCIL_Node -- + ------------------------ + + function Next_Non_SCIL_Node (N : Node_Id) return Node_Id is + Aux_N : Node_Id; + + begin + Aux_N := Next (N); + while Nkind (Aux_N) in N_SCIL_Node loop + Next (Aux_N); + end loop; + + return Aux_N; + end Next_Non_SCIL_Node; + +end Sem_SCIL; diff --git a/gcc/ada/sem_scil.ads b/gcc/ada/sem_scil.ads new file mode 100644 index 00000000000..f257e636295 --- /dev/null +++ b/gcc/ada/sem_scil.ads @@ -0,0 +1,58 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- S E M _ S C I L -- +-- -- +-- B o d y -- +-- -- +-- Copyright (C) 2009, Free Software Foundation, Inc. -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- +-- http://www.gnu.org/licenses for a complete copy of the license. -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +-- This package contains routines involved in the frontend addition and +-- verification of SCIL nodes. + +with Atree; use Atree; +with Types; use Types; + +package Sem_SCIL is + + -- Here would be a good place to document what SCIL is all about ??? + + procedure Adjust_SCIL_Node (Old_Node : Node_Id; New_Node : Node_Id); + -- Searches for a SCIL dispatching node associated with Old_Node. If found + -- then update its SCIL_Related_Node field to reference New_Node. + + function Check_SCIL_Node (N : Node_Id) return Traverse_Result; + -- Process a single node during the tree traversal. Done to verify that + -- SCIL nodes decoration fulfill the requirements of the SCIL backend. + + procedure Check_SCIL_Nodes is new Traverse_Proc (Check_SCIL_Node); + -- The traversal procedure itself + + function Find_SCIL_Node (Node : Node_Id) return Node_Id; + -- Searches for a SCIL dispatching node associated with Node. If not found + -- then return Empty. + + function First_Non_SCIL_Node (L : List_Id) return Node_Id; + -- Returns the first non-SCIL node of list L + + function Next_Non_SCIL_Node (N : Node_Id) return Node_Id; + -- N must be a member of a list. Returns the next non SCIL node in the list + -- containing N, or Empty if this is the last non SCIL node in the list. + +end Sem_SCIL; diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index 8cd32783e1a..37965afb69a 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -50,6 +50,7 @@ with Sem_Ch8; use Sem_Ch8; with Sem_Disp; use Sem_Disp; with Sem_Eval; use Sem_Eval; with Sem_Res; use Sem_Res; +with Sem_SCIL; use Sem_SCIL; with Sem_Type; use Sem_Type; with Sinfo; use Sinfo; with Sinput; use Sinput; @@ -5229,6 +5230,16 @@ package body Sem_Util is begin Save_Interps (N, New_Prefix); + + -- Check if the node relocation requires readjustment of some SCIL + -- dispatching node. + + if Generate_SCIL + and then Nkind (N) = N_Function_Call + then + Adjust_SCIL_Node (N, New_Prefix); + end if; + Rewrite (N, Make_Explicit_Dereference (Sloc (N), Prefix => New_Prefix)); Set_Etype (N, Designated_Type (Etype (New_Prefix))); @@ -5334,6 +5345,19 @@ package body Sem_Util is and then E = Base_Type (E); end Is_AAMP_Float; + ----------------------------- + -- Is_Actual_Out_Parameter -- + ----------------------------- + + function Is_Actual_Out_Parameter (N : Node_Id) return Boolean is + Formal : Entity_Id; + Call : Node_Id; + begin + Find_Actual (N, Formal, Call); + return Present (Formal) + and then Ekind (Formal) = E_Out_Parameter; + end Is_Actual_Out_Parameter; + ------------------------- -- Is_Actual_Parameter -- ------------------------- @@ -6113,6 +6137,21 @@ package body Sem_Util is end if; end Is_Fully_Initialized_Variant; + ------------ + -- Is_LHS -- + ------------ + + -- We seem to have a lot of overlapping functions that do similar things + -- (testing for left hand sides or lvalues???). Anyway, since this one is + -- purely syntactic, it should be in Sem_Aux I would think??? + + function Is_LHS (N : Node_Id) return Boolean is + P : constant Node_Id := Parent (N); + begin + return Nkind (P) = N_Assignment_Statement + and then Name (P) = N; + end Is_LHS; + ---------------------------- -- Is_Inherited_Operation -- ---------------------------- @@ -7114,19 +7153,33 @@ package body Sem_Util is Last_Assignment_Only : Boolean := False) is begin + -- ??? do we have to worry about clearing cached checks? + if Is_Assignable (Ent) then Set_Last_Assignment (Ent, Empty); end if; - if not Last_Assignment_Only and then Is_Object (Ent) then - Kill_Checks (Ent); - Set_Current_Value (Ent, Empty); + if Is_Object (Ent) then + if not Last_Assignment_Only then + Kill_Checks (Ent); + Set_Current_Value (Ent, Empty); - if not Can_Never_Be_Null (Ent) then - Set_Is_Known_Non_Null (Ent, False); - end if; + if not Can_Never_Be_Null (Ent) then + Set_Is_Known_Non_Null (Ent, False); + end if; + + Set_Is_Known_Null (Ent, False); - Set_Is_Known_Null (Ent, False); + -- Reset Is_Known_Valid unless type is always valid, or if we have + -- a loop parameter (loop parameters are always valid, since their + -- bounds are defined by the bounds given in the loop header). + + if not Is_Known_Valid (Etype (Ent)) + and then Ekind (Ent) /= E_Loop_Parameter + then + Set_Is_Known_Valid (Ent, False); + end if; + end if; end if; end Kill_Current_Values; @@ -10396,10 +10449,7 @@ package body Sem_Util is begin -- Deal with indexed or selected component where prefix is modified - if Nkind (N) = N_Indexed_Component - or else - Nkind (N) = N_Selected_Component - then + if Nkind_In (N, N_Indexed_Component, N_Selected_Component) then Pref := Prefix (N); -- If prefix is access type, then it is the designated object that is diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads index aa3958f8b4f..0e3dde668e6 100644 --- a/gcc/ada/sem_util.ads +++ b/gcc/ada/sem_util.ads @@ -629,6 +629,9 @@ package Sem_Util is -- the dependency of Einfo on Targparm which would be required for a -- synthesized attribute. + function Is_Actual_Out_Parameter (N : Node_Id) return Boolean; + -- Determines if N is an actual parameter of out mode in a subprogram call + function Is_Actual_Parameter (N : Node_Id) return Boolean; -- Determines if N is an actual parameter in a subprogram call @@ -659,11 +662,10 @@ package Sem_Util is function Is_Dependent_Component_Of_Mutable_Object (Object : Node_Id) return Boolean; - -- Returns True if Object is the name of a subcomponent that - -- depends on discriminants of a variable whose nominal subtype - -- is unconstrained and not indefinite, and the variable is - -- not aliased. Otherwise returns False. The nodes passed - -- to this function are assumed to denote objects. + -- Returns True if Object is the name of a subcomponent that depends on + -- discriminants of a variable whose nominal subtype is unconstrained and + -- not indefinite, and the variable is not aliased. Otherwise returns + -- False. The nodes passed to this function are assumed to denote objects. function Is_Dereferenced (N : Node_Id) return Boolean; -- N is a subexpression node of an access type. This function returns @@ -690,19 +692,21 @@ package Sem_Util is -- point type T, i.e. if it is an exact multiple of Small. function Is_Fully_Initialized_Type (Typ : Entity_Id) return Boolean; - -- Typ is a type entity. This function returns true if this type is - -- fully initialized, meaning that an object of the type is fully - -- initialized. Note that initialization resulting from the use of - -- pragma Normalized_Scalars does not count. Note that this is only - -- used for the purpose of issuing warnings for objects that are - -- potentially referenced uninitialized. This means that the result - -- returned is not crucial, but probably should err on the side of - -- thinking things are fully initialized if it does not know. + -- Typ is a type entity. This function returns true if this type is fully + -- initialized, meaning that an object of the type is fully initialized. + -- Note that initialization resulting from use of pragma Normalized_Scalars + -- does not count. Note that this is only used for the purpose of issuing + -- warnings for objects that are potentially referenced uninitialized. This + -- means that the result returned is not crucial, but should err on the + -- side of thinking things are fully initialized if it does not know. function Is_Inherited_Operation (E : Entity_Id) return Boolean; -- E is a subprogram. Return True is E is an implicit operation inherited -- by a derived type declarations. + function Is_LHS (N : Node_Id) return Boolean; + -- Returns True iff N is used as Name in an assignment statement. + function Is_Library_Level_Entity (E : Entity_Id) return Boolean; -- A library-level declaration is one that is accessible from Standard, -- i.e. a library unit or an entity declared in a library package. @@ -816,9 +820,9 @@ package Sem_Util is -- clear the Is_True_Constant flag, since that only gets reset if there -- really is an assignment somewhere in the entity scope). This procedure -- also calls Kill_All_Checks, since this is a special case of needing to - -- forget saved values. This procedure also clears Is_Known_Non_Null flags - -- in variables, constants or parameters since these are also not known to - -- be valid. + -- forget saved values. This procedure also clears the Is_Known_Null and + -- Is_Known_Non_Null and Is_Known_Valid flags in variables, constants or + -- parameters since these are also not known to be trustable any more. -- -- The Last_Assignment_Only flag is set True to clear only Last_Assignment -- fields and leave other fields unchanged. This is used when we encounter @@ -835,8 +839,8 @@ package Sem_Util is Last_Assignment_Only : Boolean := False); -- This performs the same processing as described above for the form with -- no argument, but for the specific entity given. The call has no effect - -- if the entity Ent is not for an object. Again, Last_Assignment_Only is - -- set if you want to clear only the Last_Assignment field (see above). + -- if the entity Ent is not for an object. Last_Assignment_Only has the + -- same meaning as for the call with no Ent. procedure Kill_Size_Check_Code (E : Entity_Id); -- Called when an address clause or pragma Import is applied to an entity. diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb index e580f474820..e917ccf7327 100644 --- a/gcc/ada/sem_warn.adb +++ b/gcc/ada/sem_warn.adb @@ -3904,7 +3904,6 @@ package body Sem_Warn is then if Warn_On_Modified_Unread and then not Is_Imported (E) - and then not Is_Return_Object (E) and then not Is_Aliased (E) and then No (Renamed_Object (E)) then diff --git a/gcc/ada/sinfo.adb b/gcc/ada/sinfo.adb index 3ecaf513ffe..816adcf5afc 100644 --- a/gcc/ada/sinfo.adb +++ b/gcc/ada/sinfo.adb @@ -1703,14 +1703,6 @@ package body Sinfo is return Flag7 (N); end Is_Protected_Subprogram_Body; - function Is_SCIL_Node - (N : Node_Id) return Boolean is - begin - pragma Assert (False - or else NT (N).Nkind = N_Null_Statement); - return Flag4 (N); - end Is_SCIL_Node; - function Is_Static_Coextension (N : Node_Id) return Boolean is begin @@ -2541,27 +2533,33 @@ package body Sinfo is return Flag18 (N); end Rounded_Result; - function SCIL_Entity + function SCIL_Controlling_Tag (N : Node_Id) return Node_Id is begin pragma Assert (False - or else NT (N).Nkind = N_Null_Statement); - return Node4 (N); - end SCIL_Entity; + or else NT (N).Nkind = N_SCIL_Dispatching_Call); + return Node5 (N); + end SCIL_Controlling_Tag; - function SCIL_Nkind - (N : Node_Id) return Uint is + function SCIL_Entity + (N : Node_Id) return Node_Id is begin pragma Assert (False - or else NT (N).Nkind = N_Null_Statement); - return Uint3 (N); - end SCIL_Nkind; + or else NT (N).Nkind = N_SCIL_Dispatch_Table_Object_Init + or else NT (N).Nkind = N_SCIL_Dispatch_Table_Tag_Init + or else NT (N).Nkind = N_SCIL_Dispatching_Call + or else NT (N).Nkind = N_SCIL_Tag_Init); + return Node4 (N); + end SCIL_Entity; function SCIL_Related_Node (N : Node_Id) return Node_Id is begin pragma Assert (False - or else NT (N).Nkind = N_Null_Statement); + or else NT (N).Nkind = N_SCIL_Dispatch_Table_Object_Init + or else NT (N).Nkind = N_SCIL_Dispatch_Table_Tag_Init + or else NT (N).Nkind = N_SCIL_Dispatching_Call + or else NT (N).Nkind = N_SCIL_Tag_Init); return Node1 (N); end SCIL_Related_Node; @@ -2569,7 +2567,7 @@ package body Sinfo is (N : Node_Id) return Node_Id is begin pragma Assert (False - or else NT (N).Nkind = N_Null_Statement); + or else NT (N).Nkind = N_SCIL_Dispatching_Call); return Node2 (N); end SCIL_Target_Prim; @@ -4557,14 +4555,6 @@ package body Sinfo is Set_Flag7 (N, Val); end Set_Is_Protected_Subprogram_Body; - procedure Set_Is_SCIL_Node - (N : Node_Id; Val : Boolean := True) is - begin - pragma Assert (False - or else NT (N).Nkind = N_Null_Statement); - Set_Flag4 (N, Val); - end Set_Is_SCIL_Node; - procedure Set_Is_Static_Coextension (N : Node_Id; Val : Boolean := True) is begin @@ -5395,36 +5385,42 @@ package body Sinfo is Set_Flag18 (N, Val); end Set_Rounded_Result; - procedure Set_SCIL_Entity + procedure Set_SCIL_Controlling_Tag (N : Node_Id; Val : Node_Id) is begin pragma Assert (False - or else NT (N).Nkind = N_Null_Statement); - Set_Node4 (N, Val); -- semantic field, no parent set - end Set_SCIL_Entity; + or else NT (N).Nkind = N_SCIL_Dispatching_Call); + Set_Node5 (N, Val); -- semantic field, no parent set + end Set_SCIL_Controlling_Tag; - procedure Set_SCIL_Nkind - (N : Node_Id; Val : Uint) is + procedure Set_SCIL_Entity + (N : Node_Id; Val : Node_Id) is begin pragma Assert (False - or else NT (N).Nkind = N_Null_Statement); - Set_Uint3 (N, Val); - end Set_SCIL_Nkind; + or else NT (N).Nkind = N_SCIL_Dispatch_Table_Object_Init + or else NT (N).Nkind = N_SCIL_Dispatch_Table_Tag_Init + or else NT (N).Nkind = N_SCIL_Dispatching_Call + or else NT (N).Nkind = N_SCIL_Tag_Init); + Set_Node4 (N, Val); -- semantic field, no parent set + end Set_SCIL_Entity; procedure Set_SCIL_Related_Node (N : Node_Id; Val : Node_Id) is begin pragma Assert (False - or else NT (N).Nkind = N_Null_Statement); - Set_Node1 (N, Val); + or else NT (N).Nkind = N_SCIL_Dispatch_Table_Object_Init + or else NT (N).Nkind = N_SCIL_Dispatch_Table_Tag_Init + or else NT (N).Nkind = N_SCIL_Dispatching_Call + or else NT (N).Nkind = N_SCIL_Tag_Init); + Set_Node1 (N, Val); -- semantic field, no parent set end Set_SCIL_Related_Node; procedure Set_SCIL_Target_Prim (N : Node_Id; Val : Node_Id) is begin pragma Assert (False - or else NT (N).Nkind = N_Null_Statement); - Set_Node2 (N, Val); + or else NT (N).Nkind = N_SCIL_Dispatching_Call); + Set_Node2 (N, Val); -- semantic field, no parent set end Set_SCIL_Target_Prim; procedure Set_Scope diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads index bf0841fb5b5..b598b771de3 100644 --- a/gcc/ada/sinfo.ads +++ b/gcc/ada/sinfo.ads @@ -1251,15 +1251,6 @@ package Sinfo is -- handler to make sure that the associated protected object is unlocked -- when the subprogram completes. - -- Is_SCIL_Node (Flag4-Sem) - -- Present in N_Null_Statement nodes. Set to indicate that it is a SCIL - -- node. SCIL nodes are special nodes that help the CodePeer backend - -- locating nodes that require special processing. In order to minimize - -- the impact on the compiler and ASIS, and also to maximize flexibility - -- when adding SCIL nodes to the tree, instead of adding new kind of - -- nodes, SCIL nodes are added to the tree as N_Null_Statement nodes on - -- which this attribute is set. - -- Is_Static_Coextension (Flag14-Sem) -- Present in N_Allocator nodes. Set if the allocator is a coextension -- of an object allocated on the stack rather than the heap. @@ -1599,21 +1590,20 @@ package Sinfo is -- and multiplication operations. -- SCIL_Entity (Node4-Sem) - -- Present in N_Null_Statement nodes that are SCIL nodes. Used to - -- reference the tagged type associated with the SCIL node. - - -- SCIL_Nkind (Uint3-Sem) - -- Present in N_Null_Statement nodes that are SCIL nodes. Used to - -- indicate the kind of SCIL node (see SCIL node kinds in exp_disp.ads). + -- Present in SCIL nodes. Used to reference the tagged type associated + -- with the SCIL node. -- SCIL_Related_Node (Node1-Sem) - -- Present in N_Null_Statement nodes that are SCIL nodes. Used to - -- reference a tree node that requires special processing in the - -- CodePeer backend. + -- Present in SCIL nodes. Used to reference a tree node that requires + -- special processing in the CodePeer backend. + + -- SCIL_Controlling_Tag (Node5-Sem) + -- Present in N_SCIL_Dispatching_Call nodes. Used to reference the + -- controlling tag of a dispatching call. -- SCIL_Target_Prim (Node2-Sem) - -- Present in N_Null_Statement nodes. Used to reference the tagged type - -- primitive associated with the SCIL node. + -- Present in N_SCIL_Dispatching_Call nodes. Used to reference the tagged + -- type primitive associated with the SCIL node. -- Scope (Node3-Sem) -- Present in defining identifiers, defining character literals and @@ -3862,11 +3852,6 @@ package Sinfo is -- N_Null_Statement -- Sloc points to NULL - -- Is_SCIL_Node (Flag4-Sem) - -- SCIL_Nkind (Uint3-Sem) - -- SCIL_Related_Node (Node1-Sem) - -- SCIL_Entity (Node4-Sem) - -- SCIL_Target_Prim (Node2-Sem) ---------------- -- 5.1 Label -- @@ -6861,6 +6846,43 @@ package Sinfo is -- Note: in the case where a debug source file is generated, the Sloc -- for this node points to the quote in the Sprint file output. + ----------------- + -- SCIL Nodes -- + ----------------- + + -- SCIL nodes are special nodes added to the tree when the CodePeer + -- mode is active. They help the CodePeer backend to locate nodes that + -- require special processing. + + -- Major documentation on the general design of the SCIL interface, and + -- in particular detailed description of these nodes is missing and is + -- to be supplied in the future, when the design has finalized ??? + + -- Meanwhile these nodes should be considered in experimental form, and + -- should be ignored by all code generating back ends. ??? + + -- N_SCIL_Dispatch_Table_Object_Init + -- Sloc references a declaration node containing a dispatch table + -- SCIL_Related_Node (Node1-Sem) + -- SCIL_Entity (Node4-Sem) + + -- N_SCIL_Dispatch_Table_Tag_Init + -- Sloc references a node for a tag initialization + -- SCIL_Related_Node (Node1-Sem) + -- SCIL_Entity (Node4-Sem) + + -- N_SCIL_Dispatching_Call + -- Sloc references the node of a dispatching call + -- SCIL_Related_Node (Node1-Sem) + -- SCIL_Target_Prim (Node2-Sem) + -- SCIL_Entity (Node4-Sem) + -- SCIL_Controlling_Tag (Node5-Sem) + + -- N_SCIL_Tag_Init + -- Sloc references the node of a tag component initialization + -- SCIL_Related_Node (Node1-Sem) + -- SCIL_Entity (Node4-Sem) + --------------------- -- Subprogram_Info -- --------------------- @@ -7298,6 +7320,13 @@ package Sinfo is N_Pop_Program_Error_Label, N_Pop_Storage_Error_Label, + -- SCIL nodes + + N_SCIL_Dispatch_Table_Object_Init, + N_SCIL_Dispatch_Table_Tag_Init, + N_SCIL_Dispatching_Call, + N_SCIL_Tag_Init, + -- Other nodes (not part of any subtype class) N_Abortable_Part, @@ -7430,12 +7459,6 @@ package Sinfo is N_Attribute_Reference; -- Nodes that have Entity fields -- Warning: DOES NOT INCLUDE N_Freeze_Entity! - -- - -- Warning: DOES NOT INCLUDE N_Null_Assignment because it not always - -- available. The Entity attribute is only available in SCIL nodes - -- (that is, N_Null_Assignment nodes that have Is_Scil_Node set to true). - -- Processing such nodes never requires testing if the node is in - -- N_Has_Entity node kind. subtype N_Has_Etype is Node_Kind range N_Error .. @@ -7511,8 +7534,12 @@ package Sinfo is N_Attribute_Definition_Clause; subtype N_Short_Circuit is Node_Kind range - N_And_Then .. - N_Or_Else; + N_And_Then .. + N_Or_Else; + + subtype N_SCIL_Node is Node_Kind range + N_SCIL_Dispatch_Table_Object_Init .. + N_SCIL_Tag_Init; subtype N_Statement_Other_Than_Procedure_Call is Node_Kind range N_Abort_Statement .. @@ -8088,9 +8115,6 @@ package Sinfo is function Is_Protected_Subprogram_Body (N : Node_Id) return Boolean; -- Flag7 - function Is_SCIL_Node - (N : Node_Id) return Boolean; -- Flag4 - function Is_Static_Coextension (N : Node_Id) return Boolean; -- Flag14 @@ -8346,12 +8370,12 @@ package Sinfo is function Rounded_Result (N : Node_Id) return Boolean; -- Flag18 + function SCIL_Controlling_Tag + (N : Node_Id) return Node_Id; -- Node5 + function SCIL_Entity (N : Node_Id) return Node_Id; -- Node4 - function SCIL_Nkind - (N : Node_Id) return Uint; -- Uint3 - function SCIL_Related_Node (N : Node_Id) return Node_Id; -- Node1 @@ -9000,9 +9024,6 @@ package Sinfo is procedure Set_Is_Protected_Subprogram_Body (N : Node_Id; Val : Boolean := True); -- Flag7 - procedure Set_Is_SCIL_Node - (N : Node_Id; Val : Boolean := True); -- Flag4 - procedure Set_Is_Static_Coextension (N : Node_Id; Val : Boolean := True); -- Flag14 @@ -9258,12 +9279,12 @@ package Sinfo is procedure Set_Rounded_Result (N : Node_Id; Val : Boolean := True); -- Flag18 + procedure Set_SCIL_Controlling_Tag + (N : Node_Id; Val : Node_Id); -- Node5 + procedure Set_SCIL_Entity (N : Node_Id; Val : Node_Id); -- Node4 - procedure Set_SCIL_Nkind - (N : Node_Id; Val : Uint); -- Uint3 - procedure Set_SCIL_Related_Node (N : Node_Id; Val : Node_Id); -- Node1 @@ -10998,6 +11019,36 @@ package Sinfo is -- End of inserted output from makeisf program + -- Entries for SCIL nodes + + N_SCIL_Dispatch_Table_Object_Init => + (1 => False, -- SCIL_Related_Node (Node1-Sem) + 2 => False, -- unused + 3 => False, -- unused + 4 => False, -- SCIL_Entity (Node4-Sem) + 5 => False), -- unused + + N_SCIL_Dispatch_Table_Tag_Init => + (1 => False, -- SCIL_Related_Node (Node1-Sem) + 2 => False, -- unused + 3 => False, -- unused + 4 => False, -- SCIL_Entity (Node4-Sem) + 5 => False), -- unused + + N_SCIL_Dispatching_Call => + (1 => False, -- SCIL_Related_Node (Node1-Sem) + 2 => False, -- SCIL_Target_Prim (Node2-Sem) + 3 => False, -- unused + 4 => False, -- SCIL_Entity (Node4-Sem) + 5 => False), -- SCIL_Controlling_Tag (Node5-Sem) + + N_SCIL_Tag_Init => + (1 => False, -- SCIL_Related_Node (Node1-Sem) + 2 => False, -- unused + 3 => False, -- unused + 4 => False, -- SCIL_Entity (Node4-Sem) + 5 => False), -- unused + -- Entries for Empty, Error and Unused. Even thought these have a Chars -- field for debugging purposes, they are not really syntactic fields, so -- we mark all fields as unused. @@ -11210,7 +11261,6 @@ package Sinfo is pragma Inline (Is_Overloaded); pragma Inline (Is_Power_Of_2_For_Shift); pragma Inline (Is_Protected_Subprogram_Body); - pragma Inline (Is_SCIL_Node); pragma Inline (Is_Static_Coextension); pragma Inline (Is_Static_Expression); pragma Inline (Is_Subprogram_Descriptor); @@ -11296,8 +11346,8 @@ package Sinfo is pragma Inline (Reverse_Present); pragma Inline (Right_Opnd); pragma Inline (Rounded_Result); + pragma Inline (SCIL_Controlling_Tag); pragma Inline (SCIL_Entity); - pragma Inline (SCIL_Nkind); pragma Inline (SCIL_Related_Node); pragma Inline (SCIL_Target_Prim); pragma Inline (Scope); @@ -11510,7 +11560,6 @@ package Sinfo is pragma Inline (Set_Is_Overloaded); pragma Inline (Set_Is_Power_Of_2_For_Shift); pragma Inline (Set_Is_Protected_Subprogram_Body); - pragma Inline (Set_Is_SCIL_Node); pragma Inline (Set_Has_Self_Reference); pragma Inline (Set_Is_Static_Coextension); pragma Inline (Set_Is_Static_Expression); @@ -11596,8 +11645,8 @@ package Sinfo is pragma Inline (Set_Reverse_Present); pragma Inline (Set_Right_Opnd); pragma Inline (Set_Rounded_Result); + pragma Inline (Set_SCIL_Controlling_Tag); pragma Inline (Set_SCIL_Entity); - pragma Inline (Set_SCIL_Nkind); pragma Inline (Set_SCIL_Related_Node); pragma Inline (Set_SCIL_Target_Prim); pragma Inline (Set_Scope); diff --git a/gcc/ada/sprint.adb b/gcc/ada/sprint.adb index ec042b9ed79..e73d204d758 100644 --- a/gcc/ada/sprint.adb +++ b/gcc/ada/sprint.adb @@ -2637,6 +2637,23 @@ package body Sprint is Write_Char (';'); + -- Don't we want to print more detail??? + + -- Doc of this extended syntax belongs in sinfo.ads and/or + -- sprint.ads ??? + + when N_SCIL_Dispatch_Table_Object_Init => + Write_Indent_Str ("[N_SCIL_Dispatch_Table_Object_Init]"); + + when N_SCIL_Dispatch_Table_Tag_Init => + Write_Indent_Str ("[N_SCIL_Dispatch_Table_Tag_Init]"); + + when N_SCIL_Dispatching_Call => + Write_Indent_Str ("[N_SCIL_Dispatching_Node]"); + + when N_SCIL_Tag_Init => + Write_Indent_Str ("[N_SCIL_Dispatch_Table_Tag_Init]"); + when N_Simple_Return_Statement => if Present (Expression (Node)) then Write_Indent_Str_Sloc ("return "); diff --git a/gcc/ada/usage.adb b/gcc/ada/usage.adb index 0d6e9ccac91..6d704403da9 100644 --- a/gcc/ada/usage.adb +++ b/gcc/ada/usage.adb @@ -91,9 +91,9 @@ begin Write_Eol; - -- Common GCC switches not available in JGNAT/MGNAT + -- Common GCC switches not available for JVM, .NET, and AAMP targets - if VM_Target = No_VM then + if VM_Target = No_VM and then not AAMP_On_Target then Write_Switch_Char ("fstack-check ", ""); Write_Line ("Generate stack checking code"); diff --git a/gcc/ada/xr_tabls.adb b/gcc/ada/xr_tabls.adb index 82b2e7d0382..95bdfa985d8 100644 --- a/gcc/ada/xr_tabls.adb +++ b/gcc/ada/xr_tabls.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1998-2008, Free Software Foundation, Inc. -- +-- Copyright (C) 1998-2009, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -495,9 +495,10 @@ package body Xr_Tabls is begin if Index /= 0 then - return Ada_File_Name (Ada_File_Name'First .. Index) & "ali"; + return Ada_File_Name (Ada_File_Name'First .. Index) + & Osint.ALI_Suffix.all; else - return Ada_File_Name & ".ali"; + return Ada_File_Name & "." & Osint.ALI_Suffix.all; end if; end ALI_File_Name; @@ -823,12 +824,14 @@ package body Xr_Tabls is end if; if File.Dir = null then - if Ada.Strings.Fixed.Tail (File.File.all, 3) = "ali" then + if Ada.Strings.Fixed.Tail (File.File.all, 3) = + Osint.ALI_Suffix.all + then Tmp := Locate_Regular_File - (Internal_Strip (File.File.all), Directories.Obj_Dir); + (Internal_Strip (File.File.all), Directories.Obj_Dir); else Tmp := Locate_Regular_File - (File.File.all, Directories.Src_Dir); + (File.File.all, Directories.Src_Dir); end if; if Tmp = null then @@ -1392,7 +1395,7 @@ package body Xr_Tabls is -- least for gnatxref, and probably for gnatfind as well if F'Length > 4 - and then F (F'Last - 3 .. F'Last) = ".ali" + and then F (F'Last - 3 .. F'Last) = "." & Osint.ALI_Suffix.all then Unvisited_Files := new Unvisited_Files_Record' (File => File_Ref, diff --git a/gcc/ada/xref_lib.adb b/gcc/ada/xref_lib.adb index 935291328fe..475f15e3816 100644 --- a/gcc/ada/xref_lib.adb +++ b/gcc/ada/xref_lib.adb @@ -308,7 +308,7 @@ package body Xref_Lib is -- Case where we have an ALI file, accept it even though this is -- not official usage, since the intention is obvious - if Tail (File, 4) = ".ali" then + if Tail (File, 4) = "." & Osint.ALI_Suffix.all then File_Ref := Add_To_Xref_File (File, Visited => False, Emit_Warning => True); @@ -466,7 +466,9 @@ package body Xref_Lib is return; end if; - elsif Last > 4 and then Dir_Ent (Last - 3 .. Last) = ".ali" then + elsif Last > 4 + and then Dir_Ent (Last - 3 .. Last) = "." & Osint.ALI_Suffix.all + then File_Ref := Add_To_Xref_File (Dir_Ent (1 .. Last), Visited => False); end if; diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 359433922d5..c172c96a580 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; } 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/cgraph.c b/gcc/cgraph.c index ea47aa32cdc..ded99f9cb81 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -654,8 +654,8 @@ cgraph_set_call_stmt (struct cgraph_edge *e, gimple new_stmt) } } -/* Like cgraph_set_call_stmt but walk the clone tree and update all clones sharing - same function body. */ +/* Like cgraph_set_call_stmt but walk the clone tree and update all + clones sharing the same function body. */ void cgraph_set_call_stmt_including_clones (struct cgraph_node *orig, @@ -666,8 +666,10 @@ cgraph_set_call_stmt_including_clones (struct cgraph_node *orig, if (edge) cgraph_set_call_stmt (edge, new_stmt); - if (orig->clones) - for (node = orig->clones; node != orig;) + + node = orig->clones; + if (node) + while (node != orig) { struct cgraph_edge *edge = cgraph_edge (node, old_stmt); if (edge) @@ -690,29 +692,36 @@ cgraph_set_call_stmt_including_clones (struct cgraph_node *orig, same function body. TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative - frequencies of the clones. - */ + frequencies of the clones. */ void -cgraph_create_edge_including_clones (struct cgraph_node *orig, struct cgraph_node *callee, - gimple stmt, gcov_type count, int freq, - int loop_depth, +cgraph_create_edge_including_clones (struct cgraph_node *orig, + struct cgraph_node *callee, + gimple stmt, gcov_type count, + int freq, int loop_depth, cgraph_inline_failed_t reason) { struct cgraph_node *node; + struct cgraph_edge *edge; if (!cgraph_edge (orig, stmt)) - cgraph_create_edge (orig, callee, stmt, - count, freq, loop_depth)->inline_failed = reason; + { + edge = cgraph_create_edge (orig, callee, stmt, count, freq, loop_depth); + edge->inline_failed = reason; + } - if (orig->clones) - for (node = orig->clones; node != orig;) + node = orig->clones; + if (node) + while (node != orig) { /* It is possible that we already constant propagated into the clone and turned indirect call into dirrect call. */ if (!cgraph_edge (node, stmt)) - cgraph_create_edge (node, callee, stmt, count, freq, - loop_depth)->inline_failed = reason; + { + edge = cgraph_create_edge (node, callee, stmt, count, + freq, loop_depth); + edge->inline_failed = reason; + } if (node->clones) node = node->clones; diff --git a/gcc/common.opt b/gcc/common.opt index 1175767fc1a..5fa7bf46d81 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -637,6 +637,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 +fgraphite-force-parallel +Common Report Var(flag_graphite_force_parallel) Optimization +Mark all loops as parallel + floop-strip-mine Common Report Var(flag_loop_strip_mine) Optimization Enable Loop Strip Mining transformation @@ -649,11 +659,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..ea24e1670c6 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" diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 1e7de8e7c24..a9f5fba7ca5 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -3548,7 +3548,7 @@ alpha_expand_unaligned_store (rtx dst, rtx src, emit_insn (gen_insll_le (insl, gen_lowpart (SImode, src), addr)); break; case 8: - emit_insn (gen_insql_le (insl, src, addr)); + emit_insn (gen_insql_le (insl, gen_lowpart (DImode, src), addr)); break; } } @@ -7837,6 +7837,17 @@ alpha_start_function (FILE *file, const char *fnname, TREE_ASM_WRITTEN (name_tree) = 1; } +#if TARGET_ABI_OPEN_VMS + if (vms_debug_main + && strncmp (vms_debug_main, fnname, strlen (vms_debug_main)) == 0) + { + targetm.asm_out.globalize_label (asm_out_file, VMS_DEBUG_MAIN_POINTER); + ASM_OUTPUT_DEF (asm_out_file, VMS_DEBUG_MAIN_POINTER, fnname); + switch_to_section (text_section); + vms_debug_main = NULL; + } +#endif + alpha_fnname = fnname; sa_size = alpha_sa_size (); diff --git a/gcc/config/alpha/t-vms b/gcc/config/alpha/t-vms index 5b815288aa3..5e86f14e14b 100644 --- a/gcc/config/alpha/t-vms +++ b/gcc/config/alpha/t-vms @@ -1,5 +1,5 @@ # Copyright (C) 1996, 1997, 1998, 2001, 2002, -# 2007 Free Software Foundation, Inc. +# 2007, 2009 Free Software Foundation, Inc. # # This file is part of GCC. # @@ -32,13 +32,6 @@ $(T)vms-dwarf2.o : $(srcdir)/config/alpha/vms-dwarf2.asm $(T)vms-dwarf2eh.o : $(srcdir)/config/alpha/vms-dwarf2eh.asm gcc -c -x assembler $< -o $@ -# Assemble startup files. -$(T)vcrt0.o: $(CRT0_S) $(GCC_PASSES) - decc -c /names=as_is $(srcdir)/config/alpha/vms-crt0.c -o $(T)vcrt0.o - -$(T)pcrt0.o: $(CRT0_S) $(GCC_PASSES) - decc -c /names=as_is $(srcdir)/config/alpha/vms-psxcrt0.c -o $(T)pcrt0.o - MULTILIB_OPTIONS = mcpu=ev6 MULTILIB_DIRNAMES = ev6 LIBGCC = stmp-multilib diff --git a/gcc/config/alpha/t-vms64 b/gcc/config/alpha/t-vms64 deleted file mode 100644 index 38503a96429..00000000000 --- a/gcc/config/alpha/t-vms64 +++ /dev/null @@ -1,8 +0,0 @@ -# Assemble startup files. -$(T)vcrt0.o: $(CRT0_S) $(GCC_PASSES) - decc -c /names=as_is /pointer_size=64 \ - $(srcdir)/config/alpha/vms-crt0-64.c -o $(T)vcrt0.o - -$(T)pcrt0.o: $(CRT0_S) $(GCC_PASSES) - decc -c /names=as_is /pointer_size=64 \ - $(srcdir)/config/alpha/vms-psxcrt0-64.c -o $(T)pcrt0.o diff --git a/gcc/config/alpha/vms-cc.c b/gcc/config/alpha/vms-cc.c deleted file mode 100644 index 9ba2707240f..00000000000 --- a/gcc/config/alpha/vms-cc.c +++ /dev/null @@ -1,355 +0,0 @@ -/* VMS DEC C wrapper. - Copyright (C) 2001, 2003, 2007 Free Software Foundation, Inc. - Contributed by Douglas B. Rupp (rupp@gnat.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/>. */ - -/* This program is a wrapper around the VMS DEC C compiler. - It translates Unix style command line options into corresponding - VMS style qualifiers and then spawns the DEC C compiler. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" - -#undef PATH_SEPARATOR -#undef PATH_SEPARATOR_STR -#define PATH_SEPARATOR ',' -#define PATH_SEPARATOR_STR "," - -/* These can be set by command line arguments */ -static int verbose = 0; -static int save_temps = 0; - -static int comp_arg_max = -1; -static const char **comp_args = 0; -static int comp_arg_index = -1; -static char *objfilename = 0; - -static char *system_search_dirs = (char *) ""; -static char *search_dirs; - -static char *default_defines = (char *) ""; -static char *defines; - -/* Translate a Unix syntax directory specification into VMS syntax. - If indicators of VMS syntax found, return input string. */ -static char *to_host_dir_spec (char *); - -/* Translate a Unix syntax file specification into VMS syntax. - If indicators of VMS syntax found, return input string. */ -static char *to_host_file_spec (char *); - -/* Add a translated arg to the list to be passed to DEC CC. */ -static void addarg (const char *); - -/* Preprocess the number of args in P_ARGC and contained in ARGV. - Look for special flags, etc. that must be handled first. */ -static void preprocess_args (int *, char **); - -/* Process the number of args in P_ARGC and contained in ARGV. Look - for special flags, etc. that must be handled for the VMS compiler. */ -static void process_args (int *, char **); - -/* Action routine called by decc$to_vms */ -static int translate_unix (char *, int); - -/* Add the argument contained in STR to the list of arguments to pass to the - compiler. */ - -static void -addarg (const char *str) -{ - int i; - - if (++comp_arg_index >= comp_arg_max) - { - const char **new_comp_args - = (const char **) xcalloc (comp_arg_max + 1000, sizeof (char *)); - - for (i = 0; i <= comp_arg_max; i++) - new_comp_args [i] = comp_args [i]; - - if (comp_args) - free (comp_args); - - comp_arg_max += 1000; - comp_args = new_comp_args; - } - - comp_args [comp_arg_index] = str; -} - -static void -preprocess_args (int *p_argc, char *argv[]) -{ - int i; - - for (i = 1; i < *p_argc; i++) - { - if (strcmp (argv[i], "-o") == 0) - { - char *buff, *ptr; - - i++; - ptr = to_host_file_spec (argv[i]); - objfilename = xstrdup (ptr); - buff = concat ("/obj=", ptr, NULL); - addarg (buff); - } - } -} - -static void -process_args (int *p_argc, char *argv[]) -{ - int i; - - for (i = 1; i < *p_argc; i++) - { - if (strlen (argv[i]) < 2) - continue; - - if (strncmp (argv[i], "-I", 2) == 0) - { - char *ptr; - int new_len, search_dirs_len; - - ptr = to_host_dir_spec (&argv[i][2]); - new_len = strlen (ptr); - search_dirs_len = strlen (search_dirs); - - search_dirs = xrealloc (search_dirs, search_dirs_len + new_len + 2); - if (search_dirs_len > 0) - strcat (search_dirs, PATH_SEPARATOR_STR); - strcat (search_dirs, ptr); - } - else if (strncmp (argv[i], "-D", 2) == 0) - { - char *ptr; - int new_len, defines_len; - - ptr = &argv[i][2]; - new_len = strlen (ptr); - defines_len = strlen (defines); - - defines = xrealloc (defines, defines_len + new_len + 4); - if (defines_len > 0) - strcat (defines, ","); - - strcat (defines, "\""); - strcat (defines, ptr); - strcat (defines, "\""); - } - else if (strcmp (argv[i], "-v") == 0) - verbose = 1; - else if (strcmp (argv[i], "-g0") == 0) - addarg ("/nodebug"); - else if (strcmp (argv[i], "-O0") == 0) - addarg ("/noopt"); - else if (strncmp (argv[i], "-g", 2) == 0) - addarg ("/debug"); - else if (strcmp (argv[i], "-E") == 0) - addarg ("/preprocess"); - else if (strcmp (argv[i], "-save-temps") == 0) - save_temps = 1; - } -} - -/* The main program. Spawn the VMS DEC C compiler after fixing up the - Unix-like flags and args to be what VMS DEC C wants. */ - -typedef struct dsc {unsigned short len, mbz; char *adr; } Descr; - -int -main (int argc, char **argv) -{ - int i; - char cwdev [128], *devptr; - int devlen; - char *cwd = getcwd (0, 1024); - - devptr = strchr (cwd, ':'); - devlen = (devptr - cwd) + 1; - strncpy (cwdev, cwd, devlen); - cwdev [devlen] = '\0'; - - search_dirs = xstrdup (system_search_dirs); - defines = xstrdup (default_defines); - - addarg ("cc"); - preprocess_args (&argc , argv); - process_args (&argc , argv); - - if (strlen (search_dirs) > 0) - { - addarg ("/include=("); - addarg (search_dirs); - addarg (")"); - } - - if (strlen (defines) > 0) - { - addarg ("/define=("); - addarg (defines); - addarg (")"); - } - - for (i = 1; i < argc; i++) - { - int arg_len = strlen (argv[i]); - - if (strcmp (argv[i], "-o") == 0) - i++; - else if (strcmp (argv[i], "-v" ) == 0 - || strcmp (argv[i], "-E") == 0 - || strcmp (argv[i], "-c") == 0 - || strncmp (argv[i], "-g", 2 ) == 0 - || strncmp (argv[i], "-O", 2 ) == 0 - || strcmp (argv[i], "-save-temps") == 0 - || (arg_len > 2 && strncmp (argv[i], "-I", 2) == 0) - || (arg_len > 2 && strncmp (argv[i], "-D", 2) == 0)) - ; - - /* Unix style file specs and VMS style switches look alike, so assume - an arg consisting of one and only one slash, and that being first, is - really a switch. */ - else if ((argv[i][0] == '/') && (strchr (&argv[i][1], '/') == 0)) - addarg (argv[i]); - else - { - /* Assume filename arg */ - char buff [256], *ptr; - - ptr = to_host_file_spec (argv[i]); - arg_len = strlen (ptr); - - if (ptr[0] == '[') - sprintf (buff, "%s%s", cwdev, ptr); - else if (strchr (ptr, ':')) - sprintf (buff, "%s", ptr); - else - sprintf (buff, "%s%s", cwd, ptr); - - ptr = xstrdup (buff); - addarg (ptr); - } - } - - addarg (NULL); - - if (verbose) - { - int i; - - for (i = 0; i < comp_arg_index; i++) - printf ("%s ", comp_args [i]); - - putchar ('\n'); - } - - { - int i; - int len = 0; - - for (i = 0; comp_args[i]; i++) - len = len + strlen (comp_args[i]) + 1; - - { - char *allargs = (char *) alloca (len + 1); - Descr cmd; - int status; - int status1 = 1; - - for (i = 0; i < len + 1; i++) - allargs [i] = 0; - - for (i = 0; comp_args [i]; i++) - { - strcat (allargs, comp_args [i]); - strcat (allargs, " "); - } - - cmd.adr = allargs; - cmd.len = len; - cmd.mbz = 0; - - i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status); - - if ((i & 1) != 1) - { - LIB$SIGNAL (i); - exit (1); - } - - if ((status & 1) == 1 && (status1 & 1) == 1) - exit (0); - - exit (1); - } - } -} - -static char new_host_filespec [255]; -static char new_host_dirspec [255]; -static char filename_buff [256]; - -static int -translate_unix (char *name, int type ATTRIBUTE_UNUSED) -{ - strcpy (filename_buff, name); - return 0; -} - -static char * -to_host_dir_spec (char *dirspec) -{ - int len = strlen (dirspec); - - strcpy (new_host_dirspec, dirspec); - - if (strchr (new_host_dirspec, ']') || strchr (new_host_dirspec, ':')) - return new_host_dirspec; - - while (len > 1 && new_host_dirspec [len-1] == '/') - { - new_host_dirspec [len-1] = 0; - len--; - } - - decc$to_vms (new_host_dirspec, translate_unix, 1, 2); - strcpy (new_host_dirspec, filename_buff); - - return new_host_dirspec; - -} - -static char * -to_host_file_spec (char *filespec) -{ - strcpy (new_host_filespec, ""); - if (strchr (filespec, ']') || strchr (filespec, ':')) - strcpy (new_host_filespec, filespec); - else - { - decc$to_vms (filespec, translate_unix, 1, 1); - strcpy (new_host_filespec, filename_buff); - } - - return new_host_filespec; -} diff --git a/gcc/config/alpha/vms-crt0.c b/gcc/config/alpha/vms-crt0.c deleted file mode 100644 index affe0e8ac3e..00000000000 --- a/gcc/config/alpha/vms-crt0.c +++ /dev/null @@ -1,66 +0,0 @@ -/* VMS crt0 returning VMS style condition codes . - Copyright (C) 2001, 2009 Free Software Foundation, Inc. - Contributed by Douglas B. Rupp (rupp@gnat.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. - -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/>. */ - -#if !defined(__DECC) -You Lose! This file can only be compiled with DEC C. -#else - -/* This file can only be compiled with DEC C, due to the call to - lib$establish. */ - -#include <stdlib.h> -#include <string.h> -#include <ssdef.h> - -extern void decc$main (); - -extern int main (); - -static int -handler (sigargs, mechargs) - void *sigargs; - void *mechargs; -{ - return SS$_RESIGNAL; -} - -int -__main (arg1, arg2, arg3, image_file_desc, arg5, arg6) - void *arg1, *arg2, *arg3; - void *image_file_desc; - void *arg5, *arg6; -{ - int argc; - char **argv; - char **envp; - - lib$establish (handler); - - decc$main(arg1, arg2, arg3, image_file_desc, arg5, arg6, - &argc, &argv, &envp); - - return main (argc, argv, envp); -} -#endif diff --git a/gcc/config/alpha/vms-ld.c b/gcc/config/alpha/vms-ld.c deleted file mode 100644 index d3b4af27385..00000000000 --- a/gcc/config/alpha/vms-ld.c +++ /dev/null @@ -1,763 +0,0 @@ -/* VMS linker wrapper. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2007 - Free Software Foundation, Inc. - Contributed by Douglas B. Rupp (rupp@gnat.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/>. */ - -/* This program is a wrapper around the VMS linker. - It translates Unix style command line options into corresponding - VMS style qualifiers and then spawns the VMS linker. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" - -typedef struct dsc {unsigned short len, mbz; char *adr; } Descr; - -#undef PATH_SEPARATOR -#undef PATH_SEPARATOR_STR -#define PATH_SEPARATOR ',' -#define PATH_SEPARATOR_STR "," - -/* Local variable declarations. */ - -/* File specification for vms-dwarf2.o. */ -static char *vmsdwarf2spec = 0; - -/* File specification for vms-dwarf2eh.o. */ -static char *vmsdwarf2ehspec = 0; - -/* verbose = 1 if -v passed. */ -static int verbose = 0; - -/* save_temps = 1 if -save-temps passed. */ -static int save_temps = 0; - -/* By default don't generate executable file if there are errors - in the link. Override with --noinhibit-exec. */ -static int inhibit_exec = 1; - -/* debug = 1 if -g passed. */ -static int debug = 0; - -/* By default prefer to link with shareable image libraries. - Override with -static. */ -static int staticp = 0; - -/* By default generate an executable, not a shareable image library. - Override with -shared. */ -static int share = 0; - -/* Remember if IDENTIFICATION given on command line. */ -static int ident = 0; - -/* Keep track of arg translations. */ -static int link_arg_max = -1; -static const char **link_args = 0; -static int link_arg_index = -1; - -/* Keep track of filenames */ -static char optfilefullname [267]; -static char *sharefilename = 0; -static char *exefilename = 0; - -/* System search dir list. Leave blank since link handles this - internally. */ -static char *system_search_dirs = ""; - -/* Search dir list passed on command line (with -L). */ -static char *search_dirs; - -/* Local function declarations. */ - -/* Add STR to the list of arguments to pass to the linker. Expand the list as - necessary to accommodate. */ -static void addarg (const char *); - -/* Check to see if NAME is a regular file, i.e. not a directory */ -static int is_regular_file (char *); - -/* Translate a Unix syntax file specification FILESPEC into VMS syntax. - If indicators of VMS syntax found, return input string. */ -static char *to_host_file_spec (char *); - -/* Locate the library named LIB_NAME in the set of paths PATH_VAL. */ -static char *locate_lib (char *, char *); - -/* Given a library name NAME, i.e. foo, Look for libfoo.lib and then - libfoo.a in the set of directories we are allowed to search in. */ -static const char *expand_lib (char *); - -/* Preprocess the number of args P_ARGC in ARGV. - Look for special flags, etc. that must be handled first. */ -static void preprocess_args (int *, char **); - -/* Preprocess the number of args P_ARGC in ARGV. Look for - special flags, etc. that must be handled for the VMS linker. */ -static void process_args (int *, char **); - -/* Action routine called by decc$to_vms. NAME is a file name or - directory name. TYPE is unused. */ -static int translate_unix (char *, int); - -int main (int, char **); - -static void -addarg (const char *str) -{ - int i; - - if (++link_arg_index >= link_arg_max) - { - const char **new_link_args - = (const char **) xcalloc (link_arg_max + 1000, sizeof (char *)); - - for (i = 0; i <= link_arg_max; i++) - new_link_args [i] = link_args [i]; - - if (link_args) - free (link_args); - - link_arg_max += 1000; - link_args = new_link_args; - } - - link_args [link_arg_index] = str; -} - -static char * -locate_lib (char *lib_name, char *path_val) -{ - int lib_len = strlen (lib_name); - char *eptr, *sptr; - - for (sptr = path_val; *sptr; sptr = eptr) - { - char *buf, *ptr; - - while (*sptr == PATH_SEPARATOR) - sptr ++; - - eptr = strchr (sptr, PATH_SEPARATOR); - if (eptr == 0) - eptr = strchr (sptr, 0); - - buf = alloca ((eptr-sptr) + lib_len + 4 + 2); - strncpy (buf, sptr, eptr-sptr); - buf [eptr-sptr] = 0; - strcat (buf, "/"); - strcat (buf, lib_name); - ptr = strchr (buf, 0); - - if (debug || staticp) - { - /* For debug or static links, look for shareable image libraries - last. */ - strcpy (ptr, ".a"); - if (is_regular_file (buf)) - return xstrdup (to_host_file_spec (buf)); - - strcpy (ptr, ".olb"); - if (is_regular_file (buf)) - return xstrdup (to_host_file_spec (buf)); - - strcpy (ptr, ".exe"); - if (is_regular_file (buf)) - return xstrdup (to_host_file_spec (buf)); - } - else - { - /* Otherwise look for shareable image libraries first. */ - strcpy (ptr, ".exe"); - if (is_regular_file (buf)) - return xstrdup (to_host_file_spec (buf)); - - strcpy (ptr, ".a"); - if (is_regular_file (buf)) - return xstrdup (to_host_file_spec (buf)); - - strcpy (ptr, ".olb"); - if (is_regular_file (buf)) - return xstrdup (to_host_file_spec (buf)); - } - } - - return 0; -} - -static const char * -expand_lib (char *name) -{ - char *lib, *lib_path; - - if (strcmp (name, "c") == 0) - /* IEEE VAX C compatible library for non-prefixed (e.g. no DECC$) - C RTL functions. */ - return "sys$library:vaxcrtltx.olb"; - - else if (strcmp (name, "m") == 0) - /* No separate library for math functions */ - return ""; - - else - { - lib = xmalloc (strlen (name) + 14); - - strcpy (lib, "lib"); - strcat (lib, name); - lib_path = locate_lib (lib, search_dirs); - - if (lib_path) - return lib_path; - } - - fprintf (stderr, - "Couldn't locate library: lib%s.exe, lib%s.a or lib%s.olb\n", - name, name, name); - - exit (1); -} - -static int -is_regular_file (char *name) -{ - int ret; - struct stat statbuf; - - ret = stat (name, &statbuf); - return !ret && S_ISREG (statbuf.st_mode); -} - -static void -preprocess_args (int *p_argc, char **argv) -{ - int i; - - for (i = 1; i < *p_argc; i++) - if (strlen (argv[i]) >= 6 && strncmp (argv[i], "-shared", 7) == 0) - share = 1; - - for (i = 1; i < *p_argc; i++) - if (strcmp (argv[i], "-o") == 0) - { - char *buff, *ptr; - int out_len; - int len; - - i++; - ptr = to_host_file_spec (argv[i]); - exefilename = xstrdup (ptr); - out_len = strlen (ptr); - buff = xmalloc (out_len + 18); - - if (share) - strcpy (buff, "/share="); - else - strcpy (buff, "/exe="); - - strcat (buff, ptr); - addarg (buff); - - if (share) - { - sharefilename = xmalloc (out_len+5); - if (ptr == strchr (argv[i], ']')) - strcpy (sharefilename, ++ptr); - else if (ptr == strchr (argv[i], ':')) - strcpy (sharefilename, ++ptr); - else if (ptr == strrchr (argv[i], '/')) - strcpy (sharefilename, ++ptr); - else - strcpy (sharefilename, argv[i]); - - len = strlen (sharefilename); - if (strncasecmp (&sharefilename[len-4], ".exe", 4) == 0) - sharefilename[len-4] = 0; - - for (ptr = sharefilename; *ptr; ptr++) - *ptr = TOUPPER (*ptr); - } - } -} - -static void -process_args (int *p_argc, char **argv) -{ - int i; - - for (i = 1; i < *p_argc; i++) - { - if (strlen (argv[i]) < 2) - continue; - - if (strncmp (argv[i], "-L", 2) == 0) - { - char *nbuff, *ptr; - int new_len, search_dirs_len; - - ptr = &argv[i][2]; - new_len = strlen (ptr); - search_dirs_len = strlen (search_dirs); - - nbuff = xmalloc (new_len + 1); - strcpy (nbuff, ptr); - - /* Remove trailing slashes. */ - while (new_len > 1 && nbuff [new_len - 1] == '/') - { - nbuff [new_len - 1] = 0; - new_len--; - } - - search_dirs = xrealloc (search_dirs, search_dirs_len + new_len + 2); - if (search_dirs_len > 0) - strcat (search_dirs, PATH_SEPARATOR_STR); - - strcat (search_dirs, nbuff); - free (nbuff); - } - - /* -v turns on verbose option here and is passed on to gcc. */ - else if (strcmp (argv[i], "-v") == 0) - verbose = 1; - else if (strcmp (argv[i], "-g0") == 0) - addarg ("/notraceback"); - else if (strncmp (argv[i], "-g", 2) == 0) - { - addarg ("/debug"); - debug = 1; - } - else if (strcmp (argv[i], "-static") == 0) - staticp = 1; - else if (strcmp (argv[i], "-map") == 0) - { - char *buff, *ptr; - - buff = xmalloc (strlen (exefilename) + 5); - strcpy (buff, exefilename); - ptr = strchr (buff, '.'); - if (ptr) - *ptr = 0; - - strcat (buff, ".map"); - addarg ("/map="); - addarg (buff); - addarg ("/full"); - } - else if (strcmp (argv[i], "-save-temps") == 0) - save_temps = 1; - else if (strcmp (argv[i], "--noinhibit-exec") == 0) - inhibit_exec = 0; - } -} - -/* The main program. Spawn the VMS linker after fixing up the Unix-like flags - and args to be what the VMS linker wants. */ - -int -main (int argc, char **argv) -{ - int i; - char cwdev [128], *devptr; - int devlen; - int optfd; - FILE *optfile; - char *cwd = getcwd (0, 1024); - char *optfilename; - - devptr = strchr (cwd, ':'); - devlen = (devptr - cwd) + 1; - strncpy (cwdev, cwd, devlen); - cwdev [devlen] = '\0'; - - search_dirs = xstrdup (system_search_dirs); - - addarg ("link"); - - /* Pass to find args that have to be append first. */ - preprocess_args (&argc , argv); - - /* Pass to find the rest of the args. */ - process_args (&argc , argv); - - /* Create a temp file to hold args, otherwise we can easily exceed the VMS - command line length limits. */ - optfilename = alloca (strlen ("LDXXXXXX") + 1); - strcpy (optfilename, "LDXXXXXX"); - optfd = mkstemp (optfilename); - getcwd (optfilefullname, 256, 1); /* VMS style cwd. */ - strcat (optfilefullname, optfilename); - strcat (optfilefullname, "."); - optfile = fdopen (optfd, "w"); - - /* Write out the IDENTIFICATION argument first so that it can be overridden - by an options file. */ - for (i = 1; i < argc; i++) - { - int arg_len = strlen (argv[i]); - - if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0) - { - /* Comes from command line. If present will always appear before - IDENTIFICATION=... and will override. */ - - if (!ident) - ident = 1; - } - else if (arg_len > 15 - && strncasecmp (argv[i], "IDENTIFICATION=", 15) == 0) - { - /* Comes from pragma Ident (). */ - - if (!ident) - { - fprintf (optfile, "case_sensitive=yes\n"); - fprintf (optfile, "IDENTIFICATION=\"%15.15s\"\n", &argv[i][15]); - fprintf (optfile, "case_sensitive=NO\n"); - ident = 1; - } - } - } - - for (i = 1; i < argc; i++) - { - int arg_len = strlen (argv[i]); - - if (strcmp (argv[i], "-o") == 0) - i++; - else if (arg_len > 2 && strncmp (argv[i], "-l", 2) == 0) - { - const char *libname = expand_lib (&argv[i][2]); - const char *ext; - int len; - - if ((len = strlen (libname)) > 0) - { - char buff [256]; - - if (len > 4 && strcasecmp (&libname [len-4], ".exe") == 0) - ext = "/shareable"; - else - ext = "/library"; - - if (libname[0] == '[') - sprintf (buff, "%s%s", cwdev, libname); - else - sprintf (buff, "%s", libname); - - fprintf (optfile, "%s%s\n", buff, ext); - } - } - - else if (strcmp (argv[i], "-v" ) == 0 - || strncmp (argv[i], "-g", 2 ) == 0 - || strcmp (argv[i], "-static" ) == 0 - || strcmp (argv[i], "-map" ) == 0 - || strcmp (argv[i], "-save-temps") == 0 - || strcmp (argv[i], "--noinhibit-exec") == 0 - || (arg_len > 2 && strncmp (argv[i], "-L", 2) == 0) - || (arg_len >= 6 && strncmp (argv[i], "-share", 6) == 0)) - ; - else if (arg_len > 1 && argv[i][0] == '@') - { - FILE *atfile; - char *ptr, *ptr1; - struct stat statbuf; - char *buff; - int len; - - if (stat (&argv[i][1], &statbuf)) - { - fprintf (stderr, "Couldn't open linker response file: %s\n", - &argv[i][1]); - exit (1); - } - - buff = xmalloc (statbuf.st_size + 1); - atfile = fopen (&argv[i][1], "r"); - fgets (buff, statbuf.st_size + 1, atfile); - fclose (atfile); - - len = strlen (buff); - if (buff [len - 1] == '\n') - { - buff [len - 1] = 0; - len--; - } - - ptr = buff; - - do - { - ptr1 = strchr (ptr, ' '); - if (ptr1) - *ptr1 = 0; - ptr = to_host_file_spec (ptr); - if (ptr[0] == '[') - fprintf (optfile, "%s%s\n", cwdev, ptr); - else - fprintf (optfile, "%s\n", ptr); - ptr = ptr1 + 1; - } while (ptr1); - } - - /* Unix style file specs and VMS style switches look alike, so assume an - arg consisting of one and only one slash, and that being first, is - really a switch. */ - else if ((argv[i][0] == '/') && (strchr (&argv[i][1], '/') == 0)) - addarg (argv[i]); - else if (arg_len > 4 - && strncasecmp (&argv[i][arg_len-4], ".OPT", 4) == 0) - { - FILE *optfile1; - char buff [256]; - - optfile1 = fopen (argv[i], "r"); - while (fgets (buff, 256, optfile1)) - fputs (buff, optfile); - - fclose (optfile1); - } - else if (arg_len > 7 && strncasecmp (argv[i], "GSMATCH", 7) == 0) - fprintf (optfile, "%s\n", argv[i]); - else if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0) - { - /* Comes from command line and will override pragma. */ - fprintf (optfile, "case_sensitive=yes\n"); - fprintf (optfile, "IDENT=\"%15.15s\"\n", &argv[i][6]); - fprintf (optfile, "case_sensitive=NO\n"); - ident = 1; - } - else if (arg_len > 15 - && strncasecmp (argv[i], "IDENTIFICATION=", 15) == 0) - ; - else - { - /* Assume filename arg. */ - const char *addswitch = ""; - char buff [256]; - int buff_len; - int is_cld = 0; - - argv[i] = to_host_file_spec (argv[i]); - arg_len = strlen (argv[i]); - - if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".exe") == 0) - addswitch = "/shareable"; - - if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".cld") == 0) - { - addswitch = "/shareable"; - is_cld = 1; - } - - if (arg_len > 2 && strcasecmp (&argv[i][arg_len-2], ".a") == 0) - addswitch = "/lib"; - - if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".olb") == 0) - addswitch = "/lib"; - - if (argv[i][0] == '[') - sprintf (buff, "%s%s%s\n", cwdev, argv[i], addswitch); - else if (strchr (argv[i], ':')) - sprintf (buff, "%s%s\n", argv[i], addswitch); - else - sprintf (buff, "%s%s%s\n", cwd, argv[i], addswitch); - - buff_len = strlen (buff); - - if (buff_len >= 15 - && strcasecmp (&buff[buff_len - 15], "vms-dwarf2eh.o\n") == 0) - vmsdwarf2ehspec = xstrdup (buff); - else if (buff_len >= 13 - && strcasecmp (&buff[buff_len - 13],"vms-dwarf2.o\n") == 0) - vmsdwarf2spec = xstrdup (buff); - else if (is_cld) - { - addarg (buff); - addarg (","); - } - else - fprintf (optfile, buff); - } - } - -#if 0 - if (share) - fprintf (optfile, "symbol_vector=(main=procedure)\n"); -#endif - - if (vmsdwarf2ehspec) - { - fprintf (optfile, "case_sensitive=yes\n"); - fprintf (optfile, "cluster=DWARF2eh,,,%s", vmsdwarf2ehspec); - fprintf (optfile, "collect=DWARF2eh,eh_frame\n"); - fprintf (optfile, "case_sensitive=NO\n"); - } - - if (debug && vmsdwarf2spec) - { - fprintf (optfile, "case_sensitive=yes\n"); - fprintf (optfile, "cluster=DWARF2debug,,,%s", vmsdwarf2spec); - fprintf (optfile, "collect=DWARF2debug,debug_abbrev,debug_aranges,-\n"); - fprintf (optfile, " debug_frame,debug_info,debug_line,debug_loc,-\n"); - fprintf (optfile, " debug_macinfo,debug_pubnames,debug_str,-\n"); - fprintf (optfile, " debug_zzzzzz\n"); - fprintf (optfile, "case_sensitive=NO\n"); - } - - if (debug && share) - { - fprintf (optfile, "case_sensitive=yes\n"); - fprintf (optfile, "symbol_vector=(-\n"); - fprintf (optfile, - "%s$DWARF2.DEBUG_ABBREV/$dwarf2.debug_abbrev=DATA,-\n", - sharefilename); - fprintf (optfile, - "%s$DWARF2.DEBUG_ARANGES/$dwarf2.debug_aranges=DATA,-\n", - sharefilename); - fprintf (optfile, "%s$DWARF2.DEBUG_FRAME/$dwarf2.debug_frame=DATA,-\n", - sharefilename); - fprintf (optfile, "%s$DWARF2.DEBUG_INFO/$dwarf2.debug_info=DATA,-\n", - sharefilename); - fprintf (optfile, "%s$DWARF2.DEBUG_LINE/$dwarf2.debug_line=DATA,-\n", - sharefilename); - fprintf (optfile, "%s$DWARF2.DEBUG_LOC/$dwarf2.debug_loc=DATA,-\n", - sharefilename); - fprintf (optfile, - "%s$DWARF2.DEBUG_MACINFO/$dwarf2.debug_macinfo=DATA,-\n", - sharefilename); - fprintf (optfile, - "%s$DWARF2.DEBUG_PUBNAMES/$dwarf2.debug_pubnames=DATA,-\n", - sharefilename); - fprintf (optfile, "%s$DWARF2.DEBUG_STR/$dwarf2.debug_str=DATA,-\n", - sharefilename); - fprintf (optfile, "%s$DWARF2.DEBUG_ZZZZZZ/$dwarf2.debug_zzzzzz=DATA)\n", - sharefilename); - fprintf (optfile, "case_sensitive=NO\n"); - } - - fclose (optfile); - addarg (optfilefullname); - addarg ("/opt"); - - addarg (NULL); - - if (verbose) - { - int i; - - for (i = 0; i < link_arg_index; i++) - printf ("%s ", link_args [i]); - putchar ('\n'); - } - - { - int i; - int len = 0; - - for (i = 0; link_args[i]; i++) - len = len + strlen (link_args[i]) + 1; - - { - char *allargs = (char *) alloca (len + 1); - Descr cmd; - int status; - int status1 = 1; - - for (i = 0; i < len + 1; i++) - allargs [i] = 0; - - for (i = 0; link_args [i]; i++) - { - strcat (allargs, link_args [i]); - strcat (allargs, " "); - } - - cmd.adr = allargs; - cmd.len = len; - cmd.mbz = 0; - - i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status); - if ((i & 1) != 1) - { - LIB$SIGNAL (i); - exit (1); - } - - if (debug && !share) - { - strcpy (allargs, "@gnu:[bin]set_exe "); - strcat (allargs, exefilename); - strcat (allargs, " /nodebug /silent"); - len = strlen (allargs); - cmd.adr = allargs; - cmd.len = len; - cmd.mbz = 0; - - if (verbose) - printf (allargs); - - i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status1); - - if ((i & 1) != 1) - { - LIB$SIGNAL (i); - exit (1); - } - } - - if (!save_temps) - remove (optfilefullname); - - if ((status & 1) == 1 && (status1 & 1) == 1) - exit (0); - - if (exefilename && inhibit_exec == 1) - remove (exefilename); - - exit (1); - } - } -} - -static char new_host_filespec [255]; -static char filename_buff [256]; - -static int -translate_unix (char *name, int type ATTRIBUTE_UNUSED) -{ - strcpy (filename_buff, name); - return 0; -} - -static char * -to_host_file_spec (char *filespec) -{ - strcpy (new_host_filespec, ""); - if (strchr (filespec, ']') || strchr (filespec, ':')) - strcpy (new_host_filespec, filespec); - else - { - decc$to_vms (filespec, translate_unix, 1, 1); - strcpy (new_host_filespec, filename_buff); - } - - return new_host_filespec; -} diff --git a/gcc/config/alpha/vms.h b/gcc/config/alpha/vms.h index 4f043a5dc8a..d7a6389512f 100644 --- a/gcc/config/alpha/vms.h +++ b/gcc/config/alpha/vms.h @@ -1,5 +1,6 @@ /* Output variables, constants and external declarations, for GNU compiler. - Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2004, 2005, 2007, 2008 + Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2004, 2005, 2007, 2008, + 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -50,6 +51,8 @@ along with GCC; see the file COPYING3. If not see #undef TARGET_VERSION #define TARGET_VERSION fprintf (stderr, " (%s)", TARGET_NAME); +#define VMS_DEBUG_MAIN_POINTER "TRANSFER$BREAK$GO" + #undef PCC_STATIC_STRUCT_RETURN /* "long" is 32 bits, but 64 bits for Ada. */ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 863a6705ba3..5d12f902502 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -3507,7 +3507,7 @@ if (TARGET_THUMB1) { if (GET_CODE (operands[1]) != REG) - operands[1] = force_reg (SImode, operands[1]); + operands[1] = force_reg (DImode, operands[1]); } " ) diff --git a/gcc/config/arm/lib1funcs.asm b/gcc/config/arm/lib1funcs.asm index 987bfcb3ba4..03446f8d03b 100644 --- a/gcc/config/arm/lib1funcs.asm +++ b/gcc/config/arm/lib1funcs.asm @@ -1108,8 +1108,8 @@ LSYM(Lover12): #ifdef L_clear_cache #if defined __ARM_EABI__ && defined __linux__ @ EABI GNU/Linux call to cacheflush syscall. - FUNC_START clear_cache - push {r7} + ARM_FUNC_START clear_cache + do_push {r7} #if __ARM_ARCH__ >= 7 || defined(__ARM_ARCH_6T2__) movw r7, #2 movt r7, #0xf @@ -1119,7 +1119,7 @@ LSYM(Lover12): #endif mov r2, #0 swi 0 - pop {r7} + do_pop {r7} RET FUNC_END clear_cache #else diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h index bc81554a3dd..5fc0c1d41c5 100644 --- a/gcc/config/i386/cygming.h +++ b/gcc/config/i386/cygming.h @@ -287,6 +287,10 @@ do { \ /* The logic of this #if must be kept synchronised with the logic for selecting the tmake_eh_file fragment in config.gcc. */ #define DWARF2_UNWIND_INFO 1 +/* If multilib is selected break build as sjlj is required. */ +#if defined (TARGET_BI_ARCH) +#error For 64-bit windows and 32-bit based multilib version of gcc just SJLJ exceptions are supported. +#endif #else #define DWARF2_UNWIND_INFO 0 #endif diff --git a/gcc/config/i386/mingw-w64.h b/gcc/config/i386/mingw-w64.h index 7996f69adc0..e38418f7dcd 100644 --- a/gcc/config/i386/mingw-w64.h +++ b/gcc/config/i386/mingw-w64.h @@ -56,7 +56,7 @@ along with GCC; see the file COPYING3. If not see #endif #undef LINK_SPEC -#define LINK_SPEC SUB_LINK_SPEC "%{mwindows:--subsystem windows} \ +#define LINK_SPEC SUB_LINK_SPEC " %{mwindows:--subsystem windows} \ %{mconsole:--subsystem console} \ %{shared: %{mdll: %eshared and mdll are not compatible}} \ %{shared: --shared} %{mdll:--dll} \ diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h index a5657c083c0..e856ecdbc97 100644 --- a/gcc/config/i386/mingw32.h +++ b/gcc/config/i386/mingw32.h @@ -207,7 +207,9 @@ __enable_execute_stack (void *addr) \ #include <windows.h> #endif -#if !TARGET_64BIT +/* For 64-bit Windows we can't use DW2 unwind info. Also for multilib + builds we can't use it, too. */ +#if !TARGET_64BIT && !defined (TARGET_BI_ARCH) #define MD_UNWIND_SUPPORT "config/i386/w32-unwind.h" #endif diff --git a/gcc/config/mep/mep.c b/gcc/config/mep/mep.c index a5869ca1c18..cf2e7d53fc0 100644 --- a/gcc/config/mep/mep.c +++ b/gcc/config/mep/mep.c @@ -129,6 +129,10 @@ static GTY(()) section * farbss_section; static GTY(()) section * frodata_section; static GTY(()) section * srodata_section; +static GTY(()) section * vtext_section; +static GTY(()) section * vftext_section; +static GTY(()) section * ftext_section; + static void mep_set_leaf_registers (int); static bool symbol_p (rtx); static bool symbolref_p (rtx); @@ -3530,15 +3534,23 @@ mep_expand_builtin_saveregs (void) rtx regbuf; ns = cfun->machine->arg_regs_to_save; - bufsize = ns * (TARGET_IVC2 ? 12 : 4); - regbuf = assign_stack_local (SImode, bufsize, 32); + if (TARGET_IVC2) + { + bufsize = 8 * ((ns + 1) / 2) + 8 * ns; + regbuf = assign_stack_local (SImode, bufsize, 64); + } + else + { + bufsize = ns * 4; + regbuf = assign_stack_local (SImode, bufsize, 32); + } move_block_from_reg (5-ns, regbuf, ns); if (TARGET_IVC2) { rtx tmp = gen_rtx_MEM (DImode, XEXP (regbuf, 0)); - int ofs = 4 * ns; + int ofs = 8 * ((ns+1)/2); for (i=0; i<ns; i++) { @@ -3627,7 +3639,9 @@ mep_expand_va_start (tree valist, rtx nextarg) TREE_SIDE_EFFECTS (t) = 1; expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - /* va_list.next_cop = va_list.next_gp_limit; */ + u = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, u, + size_int (8 * ((ns+1)/2))); + /* va_list.next_cop = ROUND_UP(va_list.next_gp_limit,8); */ t = build2 (MODIFY_EXPR, ptr_type_node, next_cop, u); TREE_SIDE_EFFECTS (t) = 1; expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); @@ -4543,38 +4557,6 @@ mep_encode_section_info (tree decl, rtx rtl, int first) maxsize); } } - - /* Functions do not go through select_section, so we force it here - by using the DECL_SECTION_NAME as if the user specified the - .vtext or .ftext sections. */ - if (! DECL_SECTION_NAME (decl) - && TREE_CODE (decl) == FUNCTION_DECL) - { - tree secname; - - if (lookup_attribute ("vliw", TYPE_ATTRIBUTES (TREE_TYPE (decl)))) - { - if (encoding == 'f') - DECL_SECTION_NAME (decl) = build_string (7, ".vftext"); - else - DECL_SECTION_NAME (decl) = build_string (6, ".vtext"); - } - else if (encoding == 'f') - { - if (flag_function_sections || DECL_ONE_ONLY (decl)) - mep_unique_section (decl, 0); - else - DECL_SECTION_NAME (decl) = build_string (6, ".ftext"); - } - - /* This is so we can control inlining. It does not matter what - attribute we add, just that it has one. */ - secname = build_tree_list (get_identifier ("section"), DECL_SECTION_NAME (decl)); - if (TYPE_P (decl)) - TYPE_ATTRIBUTES (decl) = chainon (TYPE_ATTRIBUTES (decl), secname); - else - DECL_ATTRIBUTES (decl) = chainon (DECL_ATTRIBUTES (decl), secname); - } } const char * @@ -4596,6 +4578,7 @@ mep_select_section (tree decl, int reloc ATTRIBUTE_UNUSED, unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) { int readonly = 1; + int encoding; switch (TREE_CODE (decl)) { @@ -4616,6 +4599,30 @@ mep_select_section (tree decl, int reloc ATTRIBUTE_UNUSED, break; } + if (TREE_CODE (decl) == FUNCTION_DECL) + { + const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0); + + if (name[0] == '@' && name[2] == '.') + encoding = name[1]; + else + encoding = 0; + + if (flag_function_sections || DECL_ONE_ONLY (decl)) + mep_unique_section (decl, 0); + else if (lookup_attribute ("vliw", TYPE_ATTRIBUTES (TREE_TYPE (decl)))) + { + if (encoding == 'f') + return vftext_section; + else + return vtext_section; + } + else if (encoding == 'f') + return ftext_section; + else + return text_section; + } + if (TREE_CODE (decl) == VAR_DECL) { const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0); @@ -4670,7 +4677,9 @@ mep_unique_section (tree decl, int reloc) { ".far.", ".gnu.linkonce.far." }, { ".ftext.", ".gnu.linkonce.ft." }, { ".frodata.", ".gnu.linkonce.frd." }, - { ".srodata.", ".gnu.linkonce.srd." } + { ".srodata.", ".gnu.linkonce.srd." }, + { ".vtext.", ".gnu.linkonce.v." }, + { ".vftext.", ".gnu.linkonce.vf." } }; int sec = 2; /* .data */ int len; @@ -4682,7 +4691,12 @@ mep_unique_section (tree decl, int reloc) name = XSTR (XEXP (DECL_RTL (decl), 0), 0); if (TREE_CODE (decl) == FUNCTION_DECL) - sec = 0; /* .text */ + { + if (lookup_attribute ("vliw", TYPE_ATTRIBUTES (TREE_TYPE (decl)))) + sec = 9; /* .vtext */ + else + sec = 0; /* .text */ + } else if (decl_readonly_section (decl, reloc)) sec = 1; /* .rodata */ @@ -4702,6 +4716,8 @@ mep_unique_section (tree decl, int reloc) case 'f': if (sec == 0) sec = 6; /* .ftext */ + else if (sec == 9) + sec = 10; /* .vftext */ else if (sec == 1) sec = 7; /* .frodata */ else @@ -7343,6 +7359,18 @@ mep_asm_init_sections (void) = get_unnamed_section (0, output_section_asm_op, "\t.section .srodata,\"a\""); + vtext_section + = get_unnamed_section (SECTION_CODE | SECTION_MEP_VLIW, output_section_asm_op, + "\t.section .vtext,\"axv\"\n\t.vliw"); + + vftext_section + = get_unnamed_section (SECTION_CODE | SECTION_MEP_VLIW, output_section_asm_op, + "\t.section .vftext,\"axv\"\n\t.vliw"); + + ftext_section + = get_unnamed_section (SECTION_CODE, output_section_asm_op, + "\t.section .ftext,\"ax\"\n\t.core"); + } #include "gt-mep.h" diff --git a/gcc/config/mep/mep.h b/gcc/config/mep/mep.h index 353823cef01..1cdd7468284 100644 --- a/gcc/config/mep/mep.h +++ b/gcc/config/mep/mep.h @@ -621,6 +621,8 @@ typedef struct #define DATA_SECTION_ASM_OP "\t.data" #define BSS_SECTION_ASM_OP ".bss" +#define USE_SELECT_SECTION_FOR_FUNCTIONS 1 + #define TARGET_ASM_FILE_END mep_file_cleanups #define ASM_APP_ON "#APP\n" 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/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..25cacc46e91 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); @@ -1395,6 +1396,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 +1876,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 +2168,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 +2764,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 +2787,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 +2923,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 +3012,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 +3782,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 +4137,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 +4145,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 +4262,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 +4307,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 +5685,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 +6290,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 +8436,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 +8634,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 +8715,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 +8805,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 +9003,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 +9079,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 +9094,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 +9109,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 +9188,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 +9715,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 +10054,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 +10165,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 +10705,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 +10965,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 +11023,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 +11470,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 +11482,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 +11586,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 +11613,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 +11646,9 @@ altivec_init_builtins (void) case V4SFmode: type = v4sf_ftype_v4sf; break; + case V2DFmode: + type = v2df_ftype_v2df; + break; default: gcc_unreachable (); } @@ -11193,6 +11708,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 +11746,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 +11781,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 +11889,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 +11910,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 +12012,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 +12053,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 +12111,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 +22803,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 +22836,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 +22849,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 +22862,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 +22907,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 +25145,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/sh/sh.c b/gcc/config/sh/sh.c index 788b0fe1391..5b555f83e1a 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -6743,13 +6743,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); diff --git a/gcc/config/alpha/x-vms b/gcc/config/vms/t-vms index 23f960f283c..132a53b205c 100644 --- a/gcc/config/alpha/x-vms +++ b/gcc/config/vms/t-vms @@ -1,4 +1,5 @@ -# Copyright (C) 2001, 2002, 2004, 2005, 2008 Free Software Foundation, Inc. +# Copyright (C) 2009 +# Free Software Foundation, Inc. # # This file is part of GCC. # @@ -15,24 +16,23 @@ # 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/>. -# + +STMP_FIXPROTO = +STMP_FIXINC = +LIMITS_H_TEST = false + # Under VMS, directory names cannot contain dots. version:=$(shell echo $(BASEVER_c) | sed -e 's/\./_/g') -libsubdir=$(libdir)/gcc-lib +# Temporary restriction: VMS_EXTRA_PARTS must be compiled by DEC C. +#VMS_EXTRA_PARTS=vcrt0.o pcrt0.o +VMS_EXTRA_PARTS= -# Rules for linker and compiler wrappers. These are only useful on -# a VMS host. -vms-ld.o : $(srcdir)/config/alpha/vms-ld.c - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) -ld.exe : vms-ld.o - $(CC) -o $@ vms-ld.o ../libiberty/libiberty.a +DECC=`echo $(CC) | sed -e 's/xgcc -B.*/decc$(exeext)/' -e 's/^gcc/decc/' -e 's/^decc/.\/decc/' -e 's/\(.*\)-gcc/\1-decc/'` -vms-cc.o : $(srcdir)/config/alpha/vms-cc.c - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) -decc.exe : vms-cc.o - $(CC) -o $@ vms-cc.o ../libiberty/libiberty.a +# Assemble startup files. +$(T)vcrt0.o: $(CRT0_S) $(GCC_PASSES) + $(DECC) -c /names=as_is $(srcdir)/config/vms/vms-crt0.c -o $(T)vcrt0.o -# These extra parts can only be compiled on a VMS host and are only needed -# on a VMS target. The rules are in t-vms. -VMS_EXTRA_PARTS=vcrt0.o pcrt0.o +$(T)pcrt0.o: $(CRT0_S) $(GCC_PASSES) + $(DECC) -c /names=as_is $(srcdir)/config/vms/vms-psxcrt0.c -o $(T)pcrt0.o diff --git a/gcc/config/vms/t-vms64 b/gcc/config/vms/t-vms64 new file mode 100644 index 00000000000..2fe00692fb5 --- /dev/null +++ b/gcc/config/vms/t-vms64 @@ -0,0 +1,27 @@ +# 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. +# +# 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/>. + +# Assemble startup files. +$(T)vcrt0.o: $(CRT0_S) $(GCC_PASSES) + $(DECC) -c /names=as_is /pointer_size=64 \ + $(srcdir)/config/vms/vms-crt0-64.c -o $(T)vcrt0.o + +$(T)pcrt0.o: $(CRT0_S) $(GCC_PASSES) + $(DECC) -c /names=as_is /pointer_size=64 \ + $(srcdir)/config/vms/vms-psxcrt0-64.c -o $(T)pcrt0.o diff --git a/gcc/config/alpha/vms-crt0-64.c b/gcc/config/vms/vms-crt0-64.c index 283e8bee964..ec59d81d6af 100644 --- a/gcc/config/alpha/vms-crt0-64.c +++ b/gcc/config/vms/vms-crt0-64.c @@ -2,26 +2,26 @@ Copyright (C) 2001, 2009 Free Software Foundation, Inc. Contributed by Douglas B. Rupp (rupp@gnat.com). -This file is part of GCC. + 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 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. + 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. + 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/>. */ + 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/>. */ #if !defined(__DECC) You Lose! This file can only be compiled with DEC C. @@ -72,18 +72,19 @@ __main (arg1, arg2, arg3, image_file_desc, arg5, arg6) #pragma __pointer_size long - /* Reallocate argv with 64-bit pointers. */ - long_argv = (char **) malloc (sizeof (char *) * (argc + 1)); + /* Reallocate argv with 64 bit pointers. */ + long_argv = (char **) _malloc32 (sizeof (char *) * (argc + 1)); for (i = 0; i < argc; i++) - long_argv[i] = strdup (argv[i]); + long_argv[i] = (char *) _strdup32 (argv[i]); long_argv[argc] = (char *) 0; - long_envp = (char **) malloc (sizeof (char *) * 5); + for (i = 0; envp[i]; i++); + long_envp = (char **) _malloc32 (sizeof (char *) * (i + 1)); for (i = 0; envp[i]; i++) - long_envp[i] = strdup (envp[i]); + long_envp[i] = (char *) _strdup32 (envp[i]); long_envp[i] = (char *) 0; diff --git a/gcc/config/vms/vms-crt0.c b/gcc/config/vms/vms-crt0.c new file mode 100644 index 00000000000..c0fdaaf16c6 --- /dev/null +++ b/gcc/config/vms/vms-crt0.c @@ -0,0 +1,66 @@ +/* VMS crt0 returning VMS style condition codes . + Copyright (C) 2001, 2009 Free Software Foundation, Inc. + Contributed by Douglas B. Rupp (rupp@gnat.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. + + 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/>. */ + +#if !defined(__DECC) +You Lose! This file can only be compiled with DEC C. +#else + +/* This file can only be compiled with DEC C, due to the call to + lib$establish. */ + +#include <stdlib.h> +#include <string.h> +#include <ssdef.h> + +extern void decc$main (); + +extern int main (); + +static int +handler (sigargs, mechargs) + void *sigargs; + void *mechargs; +{ + return SS$_RESIGNAL; +} + +int +__main (arg1, arg2, arg3, image_file_desc, arg5, arg6) + void *arg1, *arg2, *arg3; + void *image_file_desc; + void *arg5, *arg6; +{ + int argc; + char **argv; + char **envp; + + lib$establish (handler); + + decc$main(arg1, arg2, arg3, image_file_desc, arg5, arg6, + &argc, &argv, &envp); + + return main (argc, argv, envp); +} +#endif diff --git a/gcc/config/vms/vms-crtl-64.h b/gcc/config/vms/vms-crtl-64.h new file mode 100644 index 00000000000..6b91f31558a --- /dev/null +++ b/gcc/config/vms/vms-crtl-64.h @@ -0,0 +1,190 @@ +/* Definitions of target machine GNU compiler. 64bit VMS version. + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Douglas B Rupp (rupp@gnat.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/>. */ + +/* + Correlation array of 64bit standard CRTL names with DECCRTL + function names. Currently contains only a partial list, + e.g. those functions use in GNAT and GCC. Memory allocation + routines are 32bit but this can be overridden by -mmalloc + subtarget switch. + + Note: Please keep in alphabetical order. +*/ + +#undef CRTL_NAMES +#define CRTL_NAMES \ +{ \ +{"_calloc32", "decc$calloc", 0}, \ +{"_malloc32", "decc$malloc", 0}, \ +{"_realloc32", "decc$realloc", 0}, \ +{"_strdup32", "decc$strdup", 0}, \ +{"abs", "decc$abs", 0}, \ +{"abort", "decc$abort", 0}, \ +{"access", "decc$access", 0}, \ +{"accept", "decc$accept", 0}, \ +{"acos", "decc$tacos", 0}, \ +{"alarm", "decc$alarm", 0}, \ +{"asin", "decc$tasin", 0}, \ +{"atan", "decc$tatan", 0}, \ +{"atan2", "decc$tatan2", 0}, \ +{"atexit", "decc$atexit", 0}, \ +{"atoi", "decc$atoi", 0}, \ +{"atoll", "decc$atoll", 0}, \ +{"atoq", "decc$atoq", 0}, \ +{"basename", "decc$_basename64", 0}, \ +{"bcmp", "decc$bcmp", 0}, \ +{"bcopy", "decc$bcopy", 0}, \ +{"bsearch", "decc$_bsearch64", 0}, \ +{"bzero", "decc$bzero", 0}, \ +{"calloc", "decc$calloc", 0}, \ +{"ceil", "decc$tceil", 0}, \ +{"chdir", "decc$chdir", 0}, \ +{"chown", "decc$chown", 0}, \ +{"clearerr", "decc$clearerr", 0}, \ +{"clock", "decc$clock", 0}, \ +{"close", "decc$close", 0}, \ +{"cos", "decc$tcos", 0}, \ +{"connect", "decc$connect", 0}, \ +{"ctime", "decc$ctime", 0}, \ +{"dup", "decc$dup", 0}, \ +{"dup2", "decc$dup2", 0}, \ +{"exit", "decc$exit", 0}, \ +{"exp", "decc$texp", 0}, \ +{"fabs", "decc$tfabs", 0}, \ +{"fclose", "decc$fclose", 0}, \ +{"fdopen", "decc$fdopen", 0}, \ +{"fgetc", "decc$fgetc", 0}, \ +{"fgets", "decc$_fgets64", 0}, \ +{"fflush", "decc$fflush", 0}, \ +{"ffs", "decc$ffs", 0}, \ +{"floor", "decc$tfloor", 0}, \ +{"fopen", "decc$fopen", 0}, \ +{"fputc", "decc$fputc", 0}, \ +{"fputs", "decc$fputs", 0}, \ +{"free", "decc$free", 0}, \ +{"fread", "decc$fread", 0}, \ +{"freopen", "decc$freopen", 0}, \ +{"fseek", "decc$fseek", 0}, \ +{"ftell", "decc$ftell", 0}, \ +{"fwrite", "decc$fwrite", 0}, \ +{"getcwd", "decc$_getcwd64", 0}, \ +{"getegid", "decc$getegid", 0}, \ +{"getenv", "decc$getenv", 0}, \ +{"geteuid", "decc$geteuid", 0}, \ +{"getgid", "decc$getgid", 0}, \ +{"gethostbyname","decc$gethostbyname",0}, \ +{"getpagesize", "decc$getpagesize", 0}, \ +{"getpid", "decc$getpid", 0}, \ +{"getservbyname","decc$getservbyname",0}, \ +{"gettimeofday", "decc$gettimeofday", 0}, \ +{"getuid", "decc$getuid", 0}, \ +{"htons", "decc$htons", 0}, \ +{"iconv", "decc$iconv", 0}, \ +{"index", "decc$_index64", 0}, \ +{"isatty", "decc$isatty", 0}, \ +{"isdigit", "decc$isdigit", 0}, \ +{"kill", "decc$kill", 0}, \ +{"log", "decc$tlog", 0}, \ +{"log10", "decc$tlog10", 0}, \ +{"lseek", "decc$lseek", 0}, \ +{"ioctl", "decc$ioctl", 0}, \ +{"malloc", "decc$malloc", 0}, \ +{"mbstowcs", "decc$_mbstowcs64", 0}, \ +{"memchr", "decc$_memchr64", 0}, \ +{"memcmp", "decc$memcmp", 0}, \ +{"memcpy", "decc$_memcpy64", 0}, \ +{"memmove", "decc$_memmove64", 0}, \ +{"memset", "decc$_memset64", 0}, \ +{"mkstemp", "decc$mkstemp", 0}, \ +{"mktemp", "decc$_mktemp64", 0}, \ +{"mmap", "decc$_mmap64", 0}, \ +{"munmap", "decc$munmap", 0}, \ +{"nl_langinfo", "decc$nl_langinfo", 0}, \ +{"pclose", "decc$pclose", 0}, \ +{"popen", "decc$popen", 0}, \ +{"pow", "decc$tpow", 0}, \ +{"printf", "decc$txprintf", 0}, \ +{"putenv", "decc$putenv", 0}, \ +{"puts", "decc$puts", 0}, \ +{"random", "decc$random", 0}, \ +{"read", "decc$read", 0}, \ +{"realloc", "decc$realloc", 0}, \ +{"recv", "decc$recv", 0}, \ +{"recvfrom", "decc$recvfrom", 0}, \ +{"rename", "decc$rename", 0}, \ +{"rewind", "decc$rewind", 0}, \ +{"rindex", "decc$_rindex64", 0}, \ +{"rmdir", "decc$rmdir", 0}, \ +{"send", "decc$send", 0}, \ +{"sendto", "decc$sendto", 0}, \ +{"setenv", "decc$setenv", 0}, \ +{"setlocale", "decc$setlocale", 0}, \ +{"setvbuf", "decc$setvbuf", 0}, \ +{"signal", "decc$signal", 0}, \ +{"sigsetmask", "decc$sigsetmask", 0}, \ +{"sin", "decc$tsin", 0}, \ +{"snprintf", "decc$txsnprintf", 0}, \ +{"socket", "decc$socket", 0}, \ +{"sqrt", "decc$tsqrt", 0}, \ +{"strcasecmp", "decc$strcasecmp", 0}, \ +{"strchr", "decc$_strchr64", 0}, \ +{"strcpy", "decc$_strcpy64", 0}, \ +{"strdup", "decc$strdup", 0}, \ +{"strerror", "decc$strerror", 0}, \ +{"strlen", "decc$strlen", 0}, \ +{"strncasecmp", "decc$strncasecmp", 0}, \ +{"strncmp", "decc$strncmp", 0}, \ +{"strncpy", "decc$_strncpy64", 0}, \ +{"strrchr", "decc$_strrchr64", 0}, \ +{"strstr", "decc$_strstr64", 0}, \ +{"strtod", "decc$t_strtod64", 0}, \ +{"strtol", "decc$_strtoll64", 0}, \ +{"strtoul", "decc$_strtoull64", 0}, \ +{"sysconf", "decc$sysconf", 0}, \ +{"system", "decc$system", 0}, \ +{"tan", "decc$ttan", 0}, \ +{"time", "decc$time", 0}, \ +{"times", "decc$times", 0}, \ +{"tmpfile", "decc$tmpfile", 0}, \ +{"tmpnam", "decc$_tmpnam64", 0}, \ +{"ungetc", "decc$ungetc", 0}, \ +{"unlink", "decc$unlink", 0}, \ +{"umask", "decc$umask", 0}, \ +{"utime", "decc$utime", 0}, \ +{"wait", "decc$wait", 0}, \ +{"waitpid", "decc$waitpid", 0}, \ +{"wcswidth", "decc$wcswidth", 0}, \ +{"write", "decc$write", 0}, \ +{"vfprintf", "decc$txvfprintf", 0}, \ +{"vprintf", "decc$txvprintf", 0}, \ +{"vsprintf", "decc$txvsprintf", 0}, \ +{"vsnprintf", "decc$txvsnprintf", 0}, \ +{NULL, NULL, 0} \ +} + +/* Initialize of libfuncs that are 32/64 bit memory specific. */ + +#undef MEM_LIBFUNCS_INIT +#define MEM_LIBFUNCS_INIT \ +do { \ + memcpy_libfunc = init_one_libfunc ("decc$_memcpy64"); \ + memmove_libfunc = init_one_libfunc ("decc$_memmove64"); \ + memset_libfunc = init_one_libfunc ("decc$_memset64"); \ +} while (0) diff --git a/gcc/config/vms/vms-crtl.h b/gcc/config/vms/vms-crtl.h new file mode 100644 index 00000000000..39e647ac436 --- /dev/null +++ b/gcc/config/vms/vms-crtl.h @@ -0,0 +1,186 @@ +/* Definitions of target machine GNU compiler. 32bit VMS version. + Copyright (C) 2009 Free Software Foundation, Inc. + Contributed by Douglas B Rupp (rupp@gnat.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/>. */ + +/* + Correlation array of standard CRTL names with DECCRTL + function names. Currently contains only a partial list, + e.g. those functions use in GNAT and GCC + + Note: Please keep in alphabetical order. +*/ + +#define CRTL_NAMES \ +{ \ +{"_calloc32", "decc$calloc", 0}, \ +{"_malloc32", "decc$malloc", 0}, \ +{"_realloc32", "decc$realloc", 0}, \ +{"_strdup32", "decc$strdup", 0}, \ +{"abs", "decc$abs", 0}, \ +{"abort", "decc$abort", 0}, \ +{"access", "decc$access", 0}, \ +{"accept", "decc$accept", 0}, \ +{"acos", "decc$tacos", 0}, \ +{"alarm", "decc$alarm", 0}, \ +{"asin", "decc$tasin", 0}, \ +{"atan", "decc$tatan", 0}, \ +{"atan2", "decc$tatan2", 0}, \ +{"atexit", "decc$atexit", 0}, \ +{"atoi", "decc$atoi", 0}, \ +{"atoll", "decc$atoll", 0}, \ +{"atoq", "decc$atoq", 0}, \ +{"basename", "decc$basename", 0}, \ +{"bcmp", "decc$bcmp", 0}, \ +{"bcopy", "decc$bcopy", 0}, \ +{"bsearch", "decc$bsearch", 0}, \ +{"bzero", "decc$bzero", 0}, \ +{"calloc", "decc$calloc", 0}, \ +{"ceil", "decc$tceil", 0}, \ +{"chdir", "decc$chdir", 0}, \ +{"chown", "decc$chown", 0}, \ +{"clearerr", "decc$clearerr", 0}, \ +{"clock", "decc$clock", 0}, \ +{"close", "decc$close", 0}, \ +{"cos", "decc$tcos", 0}, \ +{"connect", "decc$connect", 0}, \ +{"ctime", "decc$ctime", 0}, \ +{"dup", "decc$dup", 0}, \ +{"dup2", "decc$dup2", 0}, \ +{"exit", "decc$exit", 0}, \ +{"exp", "decc$texp", 0}, \ +{"fabs", "decc$tfabs", 0}, \ +{"fclose", "decc$fclose", 0}, \ +{"fdopen", "decc$fdopen", 0}, \ +{"fgetc", "decc$fgetc", 0}, \ +{"fgets", "decc$fgets", 0}, \ +{"fflush", "decc$fflush", 0}, \ +{"ffs", "decc$ffs", 0}, \ +{"floor", "decc$tfloor", 0}, \ +{"fopen", "decc$fopen", 0}, \ +{"fputc", "decc$fputc", 0}, \ +{"fputs", "decc$fputs", 0}, \ +{"free", "decc$free", 0}, \ +{"fread", "decc$fread", 0}, \ +{"freopen", "decc$freopen", 0}, \ +{"fseek", "decc$fseek", 0}, \ +{"ftell", "decc$ftell", 0}, \ +{"fwrite", "decc$fwrite", 0}, \ +{"getcwd", "decc$getcwd", 0}, \ +{"getegid", "decc$getegid", 0}, \ +{"getenv", "decc$getenv", 0}, \ +{"geteuid", "decc$geteuid", 0}, \ +{"getgid", "decc$getgid", 0}, \ +{"gethostbyname","decc$gethostbyname",0}, \ +{"getpagesize", "decc$getpagesize", 0}, \ +{"getpid", "decc$getpid", 0}, \ +{"getservbyname","decc$getservbyname",0}, \ +{"gettimeofday", "decc$gettimeofday", 0}, \ +{"getuid", "decc$getuid", 0}, \ +{"htons", "decc$htons", 0}, \ +{"iconv", "decc$iconv", 0}, \ +{"index", "decc$index", 0}, \ +{"isatty", "decc$isatty", 0}, \ +{"isdigit", "decc$isdigit", 0}, \ +{"kill", "decc$kill", 0}, \ +{"log", "decc$tlog", 0}, \ +{"log10", "decc$tlog10", 0}, \ +{"lseek", "decc$lseek", 0}, \ +{"ioctl", "decc$ioctl", 0}, \ +{"malloc", "decc$malloc", 0}, \ +{"mbstowcs", "decc$mbstowcs", 0}, \ +{"memchr", "decc$memchr", 0}, \ +{"memcmp", "decc$memcmp", 0}, \ +{"memcpy", "decc$memcpy", 0}, \ +{"memmove", "decc$memmove", 0}, \ +{"memset", "decc$memset", 0}, \ +{"mkstemp", "decc$mkstemp", 0}, \ +{"mktemp", "decc$mktemp", 0}, \ +{"mmap", "decc$mmap", 0}, \ +{"munmap", "decc$munmap", 0}, \ +{"nl_langinfo", "decc$nl_langinfo", 0}, \ +{"pclose", "decc$pclose", 0}, \ +{"popen", "decc$popen", 0}, \ +{"pow", "decc$tpow", 0}, \ +{"printf", "decc$txprintf", 0}, \ +{"putenv", "decc$putenv", 0}, \ +{"puts", "decc$puts", 0}, \ +{"random", "decc$random", 0}, \ +{"read", "decc$read", 0}, \ +{"realloc", "decc$realloc", 0}, \ +{"recv", "decc$recv", 0}, \ +{"recvfrom", "decc$recvfrom", 0}, \ +{"rename", "decc$rename", 0}, \ +{"rewind", "decc$rewind", 0}, \ +{"rindex", "decc$rindex", 0}, \ +{"rmdir", "decc$rmdir", 0}, \ +{"send", "decc$send", 0}, \ +{"sendto", "decc$sendto", 0}, \ +{"setenv", "decc$setenv", 0}, \ +{"setlocale", "decc$setlocale", 0}, \ +{"setvbuf", "decc$setvbuf", 0}, \ +{"signal", "decc$signal", 0}, \ +{"sigsetmask", "decc$sigsetmask", 0}, \ +{"sin", "decc$tsin", 0}, \ +{"snprintf", "decc$txsnprintf", 0}, \ +{"socket", "decc$socket", 0}, \ +{"sqrt", "decc$tsqrt", 0}, \ +{"strcasecmp", "decc$strcasecmp", 0}, \ +{"strchr", "decc$strchr", 0}, \ +{"strcpy", "decc$strcpy", 0}, \ +{"strdup", "decc$strdup", 0}, \ +{"strerror", "decc$strerror", 0}, \ +{"strlen", "decc$strlen", 0}, \ +{"strncasecmp", "decc$strncasecmp", 0}, \ +{"strncmp", "decc$strncmp", 0}, \ +{"strncpy", "decc$strncpy", 0}, \ +{"strrchr", "decc$strrchr", 0}, \ +{"strstr", "decc$strstr", 0}, \ +{"strtod", "decc$tstrtod", 0}, \ +{"strtol", "decc$strtoll", 0}, \ +{"strtoul", "decc$strtoull", 0}, \ +{"sysconf", "decc$sysconf", 0}, \ +{"system", "decc$system", 0}, \ +{"tan", "decc$ttan", 0}, \ +{"time", "decc$time", 0}, \ +{"times", "decc$times", 0}, \ +{"tmpfile", "decc$tmpfile", 0}, \ +{"tmpnam", "decc$tmpnam", 0}, \ +{"ungetc", "decc$ungetc", 0}, \ +{"unlink", "decc$unlink", 0}, \ +{"umask", "decc$umask", 0}, \ +{"utime", "decc$utime", 0}, \ +{"wait", "decc$wait", 0}, \ +{"waitpid", "decc$waitpid", 0}, \ +{"wcswidth", "decc$wcswidth", 0}, \ +{"write", "decc$write", 0}, \ +{"vfprintf", "decc$txvfprintf", 0}, \ +{"vprintf", "decc$txvprintf", 0}, \ +{"vsprintf", "decc$txvsprintf", 0}, \ +{"vsnprintf", "decc$txvsnprintf", 0}, \ +{NULL, NULL, 0} \ +} + +/* Initialize of libfuncs that are 32/64 bit memory specific. */ + +#define MEM_LIBFUNCS_INIT \ +do { \ + memcpy_libfunc = init_one_libfunc ("decc$memcpy"); \ + memmove_libfunc = init_one_libfunc ("decc$memmove"); \ + memset_libfunc = init_one_libfunc ("decc$memset"); \ +} while (0) diff --git a/gcc/config/alpha/vms-psxcrt0-64.c b/gcc/config/vms/vms-psxcrt0-64.c index 1b74b6d18d2..45afbc9a03d 100644 --- a/gcc/config/alpha/vms-psxcrt0-64.c +++ b/gcc/config/vms/vms-psxcrt0-64.c @@ -2,26 +2,26 @@ Copyright (C) 2001, 2009 Free Software Foundation, Inc. Contributed by Douglas B. Rupp (rupp@gnat.com). -This file is part of GCC. + 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 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. + 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. + 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/>. */ + 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/>. */ #if !defined(__DECC) You Lose! This file can only be compiled with DEC C. @@ -53,7 +53,7 @@ int __main (arg1, arg2, arg3, image_file_desc, arg5, arg6) void *arg1, *arg2, *arg3; void *image_file_desc; - void *arg5, *arg6) + void *arg5, *arg6; { int argc; char **argv; @@ -74,18 +74,19 @@ __main (arg1, arg2, arg3, image_file_desc, arg5, arg6) #pragma __pointer_size long - /* Reallocate argv with 64-bit pointers. */ - long_argv = (char **) malloc (sizeof (char *) * (argc + 1)); + /* Reallocate argv with 64 bit pointers. */ + long_argv = (char **) _malloc32 (sizeof (char *) * (argc + 1)); for (i = 0; i < argc; i++) - long_argv[i] = strdup (argv[i]); + long_argv[i] = (char *) _strdup32 (argv[i]); long_argv[argc] = (char *) 0; - long_envp = (char **) malloc (sizeof (char *) * 5); + for (i = 0; envp[i]; i++); + long_envp = (char **) _malloc32 (sizeof (char *) * (i + 1)); for (i = 0; envp[i]; i++) - long_envp[i] = strdup (envp[i]); + long_envp[i] = (char *) _strdup32 (envp[i]); long_envp[i] = (char *) 0; diff --git a/gcc/config/alpha/vms-psxcrt0.c b/gcc/config/vms/vms-psxcrt0.c index 69d97ec75d3..5ad5ddb0fd8 100644 --- a/gcc/config/alpha/vms-psxcrt0.c +++ b/gcc/config/vms/vms-psxcrt0.c @@ -2,26 +2,26 @@ Copyright (C) 2001, 2009 Free Software Foundation, Inc. Contributed by Douglas B. Rupp (rupp@gnat.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. - -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/>. */ + 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/>. */ #if !defined(__DECC) You Lose! This file can only be compiled with DEC C. diff --git a/gcc/config/vms/vms.opt b/gcc/config/vms/vms.opt new file mode 100644 index 00000000000..dd4b46b333e --- /dev/null +++ b/gcc/config/vms/vms.opt @@ -0,0 +1,25 @@ +; 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. +; +; 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/>. + +mmalloc64 +Target Report Mask(MALLOC64) +Malloc data into P2 space + +mdebug-main= +Target RejectNegative Joined Var(vms_debug_main) +Set name of main routine for the debugger diff --git a/gcc/config/vms/x-vms b/gcc/config/vms/x-vms new file mode 100644 index 00000000000..b232c8e6804 --- /dev/null +++ b/gcc/config/vms/x-vms @@ -0,0 +1,27 @@ +# Copyright (C) 2001, 2002, 2004, 2005, 2008, 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. +# +# 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/>. + +LN = cp -p +LN_S = cp -p + +# Doesn't work on VMS +USE_COLLECT2= + +# There are no man pages on VMS +POD2MAN = false diff --git a/gcc/config/alpha/xm-vms.h b/gcc/config/vms/xm-vms.h index ea95bcfbaed..7907f9263cf 100644 --- a/gcc/config/alpha/xm-vms.h +++ b/gcc/config/vms/xm-vms.h @@ -1,6 +1,7 @@ -/* Configuration for GNU C-compiler for openVMS/Alpha. - Copyright (C) 1996, 1997, 2001, 2004, 2007 Free Software Foundation, Inc. - Contributed by Klaus Kaempf (kkaempf@progis.de). +/* Configuration for GCC for hosting on VMS + using a Unix style C library. + Copyright (C) 1996, 1997, 2001, 2004, 2007, 2009 + Free Software Foundation, Inc. This file is part of GCC. @@ -23,17 +24,14 @@ along with GCC; see the file COPYING3. If not see #define VMS #endif -/* Define a local equivalent (sort of) for unlink */ -#define unlink remove - /* Causes exit() to be redefined to __posix_exit() and - Posix compatible failure and success codes to be used */ + Posix compatible failure and success codes to be used. */ #define _POSIX_EXIT 1 -/* Open files in stream mode if not otherwise explicitly specified */ +/* Open files in stream mode if not otherwise explicitly specified. */ #define __UNIX_FOPEN 1 -/* Write to stdout using fputc to avoid record terminators in pipes */ +/* Write to stdout using fputc to avoid record terminators in pipes. */ #define __UNIX_FWRITE 1 #define STDC_HEADERS 1 @@ -54,3 +52,7 @@ do \ break; \ } \ } while (0) + +#define STANDARD_EXEC_PREFIX "/gnu/libexec/gcc/" +#define STANDARD_STARTFILE_PREFIX "/gnu/lib/" +#define STANDARD_INCLUDE_DIR "/gnu/include" diff --git a/gcc/config/vms/xm-vms64.h b/gcc/config/vms/xm-vms64.h new file mode 100644 index 00000000000..9e77f890aaa --- /dev/null +++ b/gcc/config/vms/xm-vms64.h @@ -0,0 +1,23 @@ +/* Configuration for GCC for hosting on 64bit VMS + using a Unix style C library. + 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. + +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 HOST_LONG_FORMAT "ll" +#define HOST_PTR_PRINTF "%llp" diff --git a/gcc/configure b/gcc/configure index 3e7165c382f..d0d1ef29fbe 100755 --- a/gcc/configure +++ b/gcc/configure @@ -3135,11 +3135,13 @@ fi # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` +#AC_REQUIRE_AUX_FILE(compile) # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC -ac_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` -if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then +am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. @@ -3148,6 +3150,7 @@ if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then CC="$am_aux_dir/compile $CC" fi + ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -15360,13 +15363,13 @@ if test "${lt_cv_nm_interface+set}" = set; then else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:15363: $ac_compile\"" >&5) + (eval echo "\"\$as_me:15365: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:15366: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:15368: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:15369: output\"" >&5) + (eval echo "\"\$as_me:15371: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -16523,7 +16526,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 16526 "configure"' > conftest.$ac_ext + echo '#line 16528 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -18416,11 +18419,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:18419: $lt_compile\"" >&5) + (eval echo "\"\$as_me:18421: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:18423: \$? = $ac_status" >&5 + echo "$as_me:18425: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -18755,11 +18758,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:18758: $lt_compile\"" >&5) + (eval echo "\"\$as_me:18760: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:18762: \$? = $ac_status" >&5 + echo "$as_me:18764: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -18860,11 +18863,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:18863: $lt_compile\"" >&5) + (eval echo "\"\$as_me:18865: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:18867: \$? = $ac_status" >&5 + echo "$as_me:18869: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -18915,11 +18918,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:18918: $lt_compile\"" >&5) + (eval echo "\"\$as_me:18920: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:18922: \$? = $ac_status" >&5 + echo "$as_me:18924: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -21727,7 +21730,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 21730 "configure" +#line 21732 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -21823,7 +21826,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 21826 "configure" +#line 21828 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -23839,11 +23842,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:23842: $lt_compile\"" >&5) + (eval echo "\"\$as_me:23844: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:23846: \$? = $ac_status" >&5 + echo "$as_me:23848: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -23938,11 +23941,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:23941: $lt_compile\"" >&5) + (eval echo "\"\$as_me:23943: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:23945: \$? = $ac_status" >&5 + echo "$as_me:23947: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -23990,11 +23993,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:23993: $lt_compile\"" >&5) + (eval echo "\"\$as_me:23995: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:23997: \$? = $ac_status" >&5 + echo "$as_me:23999: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized diff --git a/gcc/convert.c b/gcc/convert.c index a1ac3300cac..f7ddfc956fc 100644 --- a/gcc/convert.c +++ b/gcc/convert.c @@ -59,12 +59,21 @@ convert_to_pointer (tree type, tree expr) case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE: - if (TYPE_PRECISION (TREE_TYPE (expr)) != POINTER_SIZE) - expr = fold_build1_loc (loc, NOP_EXPR, - lang_hooks.types.type_for_size (POINTER_SIZE, 0), - expr); - return fold_build1_loc (loc, CONVERT_EXPR, type, expr); + { + /* If the input precision differs from the target pointer type + precision, first convert the input expression to an integer type of + the target precision. Some targets, e.g. VMS, need several pointer + sizes to coexist so the latter isn't necessarily POINTER_SIZE. */ + unsigned int pprec = TYPE_PRECISION (type); + unsigned int eprec = TYPE_PRECISION (TREE_TYPE (expr)); + + if (eprec != pprec) + expr = fold_build1_loc (loc, NOP_EXPR, + lang_hooks.types.type_for_size (pprec, 0), + expr); + } + return fold_build1_loc (loc, CONVERT_EXPR, type, expr); default: error ("cannot convert to a pointer type"); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ee37b654aed..c52c6da89e1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2009-07-29 Jason Merrill <jason@redhat.com> + + PR c++/14912 + * cp-tree.h (enum tsubst_flags): Add tf_no_class_instantiations. + * error.c (count_non_default_template_args): Pass it. + * pt.c (tsubst) [TYPENAME_TYPE]: Don't complete type if it's set. + +2009-07-29 Richard Guenther <rguenther@suse.de> + + PR c++/40834 + * cp-gimplify.c (cp_genericize_r): Properly walk the BIND_EXPR + vars. + 2009-07-26 Simon Martin <simartin@users.sourceforge.net> PR c++/40749 diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 184ae9e3072..b4d36de44ca 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -810,7 +810,6 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) cp_walk_tree (&BIND_EXPR_BODY (stmt), cp_genericize_r, data, NULL); VEC_pop (tree, wtd->bind_expr_stack); - *walk_subtrees = 0; } else if (TREE_CODE (stmt) == USING_STMT) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 2bc2d6214e4..dcad9348788 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3616,6 +3616,8 @@ enum tsubst_flags { conversion. */ tf_no_access_control = 1 << 7, /* Do not perform access checks, even when issuing other errors. */ + /* Do not instantiate classes (used by count_non_default_template_args). */ + tf_no_class_instantiations = 1 << 8, /* Convenient substitution flags combinations. */ tf_warning_or_error = tf_warning | tf_error }; diff --git a/gcc/cp/error.c b/gcc/cp/error.c index c5310ff6ca0..25a05801622 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -182,7 +182,10 @@ count_non_default_template_args (tree args, tree params) if (uses_template_parms (def)) { ++processing_template_decl; - def = tsubst_copy_and_build (def, args, tf_none, NULL_TREE, false, true); + /* This speculative substitution must not cause any classes to be + instantiated that otherwise wouldn't be. */ + def = tsubst_copy_and_build (def, args, tf_no_class_instantiations, + NULL_TREE, false, true); --processing_template_decl; } if (!cp_tree_equal (TREE_VEC_ELT (inner_args, last), def)) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index de9f828c645..ed45324b9ab 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9890,7 +9890,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) But, such constructs have already been resolved by this point, so here CTX really should have complete type, unless it's a partial instantiation. */ - ctx = complete_type (ctx); + if (!(complain & tf_no_class_instantiations)) + ctx = complete_type (ctx); if (!COMPLETE_TYPE_P (ctx)) { if (complain & tf_error) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 37c50895eab..b545c328e2c 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7298,7 +7298,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 @@ -9776,7 +9776,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 @@ -9802,6 +9802,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. @@ -10067,6 +10080,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); @@ -11669,6 +11684,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 1632d3a6b2e..2d5ccb7863b 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 +-fgraphite-force-parallel @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 @@ -535,7 +536,7 @@ Objective-C and Objective-C++ Dialects}. -mmemory-latency=@var{time}} @emph{DEC Alpha/VMS Options} -@gccoptlist{-mvms-return-codes} +@gccoptlist{-mvms-return-codes -mdebug-main=@var{prefix}} @emph{FR30 Options} @gccoptlist{-msmall-model -mno-lsim} @@ -739,7 +740,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 @@ -753,7 +755,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 @@ -6596,6 +6598,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 -fgraphite-force-parallel +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 @@ -10587,8 +10604,13 @@ These @samp{-m} options are defined for the DEC Alpha/VMS implementations: @table @gcctabopt @item -mvms-return-codes @opindex mvms-return-codes -Return VMS condition codes from main. The default is to return POSIX +Return VMS condition codes from main. The default is to return POSIX style condition (e.g.@: error) codes. + +@item -mdebug-main=@var{prefix} +@opindex mdebug-main=@var{prefix} +Flag the first routine whose name starts with @var{prefix} as the main +routine for the debugger. @end table @node FR30 Options @@ -14116,6 +14138,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 +14164,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 +14215,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 +14296,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 +14399,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/options.texi b/gcc/doc/options.texi index 53ad66bb7f6..2041de97353 100644 --- a/gcc/doc/options.texi +++ b/gcc/doc/options.texi @@ -84,7 +84,16 @@ configurations and yet the masks always need to be defined. @node Option properties @section Option properties -The second field of an option record can specify the following properties: +The second field of an option record can specify any of the following +properties. When an option takes an argument, it is enlosed in parentheses +following the option property name. The parser that handles option files +is quite simplistic, and will be tricked by any nested parentheses within +the argument text itself; in this case, the entire option argument can +be wrapped in curly braces within the parentheses to demarcate it, e.g.: + +@smallexample +Condition(@{defined (USE_CYGWIN_LIBSTDCXX_WRAPPERS)@}) +@end smallexample @table @code @item Common diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index c6211620446..fe7b72de7a0 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -96,6 +96,22 @@ static void dwarf2out_source_line (unsigned int, const char *, int, bool); static rtx last_var_location_insn; #endif +#ifdef VMS_DEBUGGING_INFO +int vms_file_stats_name (const char *, long long *, long *, char *, int *); + +/* Define this macro to be a nonzero value if the directory specifications + which are output in the debug info should end with a separator. */ +#define DWARF2_DIR_SHOULD_END_WITH_SEPARATOR 1 +/* Define this macro to evaluate to a nonzero value if GCC should refrain + from generating indirect strings in DWARF2 debug information, for instance + if your target is stuck with an old version of GDB that is unable to + process them properly or uses VMS Debug. */ +#define DWARF2_INDIRECT_STRING_SUPPORT_MISSING_ON_TARGET 1 +#else +#define DWARF2_DIR_SHOULD_END_WITH_SEPARATOR 0 +#define DWARF2_INDIRECT_STRING_SUPPORT_MISSING_ON_TARGET 0 +#endif + #ifndef DWARF2_FRAME_INFO # ifdef DWARF2_DEBUGGING_INFO # define DWARF2_FRAME_INFO \ @@ -3214,57 +3230,311 @@ output_cfi_directive (dw_cfi_ref cfi) } } -/* Return true if *CFIP should be output after switching sections. */ +DEF_VEC_P (dw_cfi_ref); +DEF_VEC_ALLOC_P (dw_cfi_ref, heap); -static bool -output_cfi_p (dw_cfi_ref *cfip, dw_cfi_ref *cfi_args_sizep) +/* Output CFIs to bring current FDE to the same state as after executing + CFIs in CFI chain. DO_CFI_ASM is true if .cfi_* directives shall + be emitted, false otherwise. If it is false, FDE and FOR_EH are the + other arguments to pass to output_cfi. */ + +static void +output_cfis (dw_cfi_ref cfi, bool do_cfi_asm, dw_fde_ref fde, bool for_eh) { - dw_cfi_ref cfi = *cfip, cfi2; + struct dw_cfi_struct cfi_buf; + dw_cfi_ref cfi2; + dw_cfi_ref cfi_args_size = NULL, cfi_cfa = NULL, cfi_cfa_offset = NULL; + VEC (dw_cfi_ref, heap) *regs = VEC_alloc (dw_cfi_ref, heap, 32); + unsigned int len, idx; - switch (cfi->dw_cfi_opc) - { - case DW_CFA_advance_loc: - case DW_CFA_advance_loc1: - case DW_CFA_advance_loc2: - case DW_CFA_advance_loc4: - case DW_CFA_MIPS_advance_loc8: - case DW_CFA_set_loc: - /* All advances should be ignored. */ - return false; - case DW_CFA_remember_state: - /* Skip everything between .cfi_remember_state and - .cfi_restore_state. */ - for (cfi2 = cfi->dw_cfi_next; cfi2; cfi2 = cfi2->dw_cfi_next) - if (cfi2->dw_cfi_opc == DW_CFA_restore_state) + for (;; cfi = cfi->dw_cfi_next) + switch (cfi ? cfi->dw_cfi_opc : DW_CFA_nop) + { + case DW_CFA_advance_loc: + case DW_CFA_advance_loc1: + case DW_CFA_advance_loc2: + case DW_CFA_advance_loc4: + case DW_CFA_MIPS_advance_loc8: + case DW_CFA_set_loc: + /* All advances should be ignored. */ + break; + case DW_CFA_remember_state: + { + dw_cfi_ref args_size = cfi_args_size; + + /* Skip everything between .cfi_remember_state and + .cfi_restore_state. */ + for (cfi2 = cfi->dw_cfi_next; cfi2; cfi2 = cfi2->dw_cfi_next) + if (cfi2->dw_cfi_opc == DW_CFA_restore_state) + break; + else if (cfi2->dw_cfi_opc == DW_CFA_GNU_args_size) + args_size = cfi2; + else + gcc_assert (cfi2->dw_cfi_opc != DW_CFA_remember_state); + + if (cfi2 == NULL) + goto flush_all; + else + { + cfi = cfi2; + cfi_args_size = args_size; + } break; - else if (cfi2->dw_cfi_opc == DW_CFA_GNU_args_size) - *cfi_args_sizep = cfi2; - else - gcc_assert (cfi2->dw_cfi_opc != DW_CFA_remember_state); - if (cfi2 == NULL) - return true; - *cfip = cfi2; - return false; - case DW_CFA_def_cfa_offset: - case DW_CFA_def_cfa_offset_sf: - /* Only keep the last of these if they are consecutive. */ - for (cfi2 = cfi->dw_cfi_next; cfi2; cfi2 = cfi2->dw_cfi_next) - if (cfi2->dw_cfi_opc == cfi->dw_cfi_opc) - *cfip = cfi2; - else if (cfi2->dw_cfi_opc == DW_CFA_GNU_args_size) - *cfi_args_sizep = cfi2; + } + case DW_CFA_GNU_args_size: + cfi_args_size = cfi; + break; + case DW_CFA_GNU_window_save: + goto flush_all; + case DW_CFA_offset: + case DW_CFA_offset_extended: + case DW_CFA_offset_extended_sf: + case DW_CFA_restore: + case DW_CFA_restore_extended: + case DW_CFA_undefined: + case DW_CFA_same_value: + case DW_CFA_register: + case DW_CFA_val_offset: + case DW_CFA_val_offset_sf: + case DW_CFA_expression: + case DW_CFA_val_expression: + case DW_CFA_GNU_negative_offset_extended: + if (VEC_length (dw_cfi_ref, regs) <= cfi->dw_cfi_oprnd1.dw_cfi_reg_num) + VEC_safe_grow_cleared (dw_cfi_ref, heap, regs, + cfi->dw_cfi_oprnd1.dw_cfi_reg_num + 1); + VEC_replace (dw_cfi_ref, regs, cfi->dw_cfi_oprnd1.dw_cfi_reg_num, cfi); + break; + case DW_CFA_def_cfa: + case DW_CFA_def_cfa_sf: + case DW_CFA_def_cfa_expression: + cfi_cfa = cfi; + cfi_cfa_offset = cfi; + break; + case DW_CFA_def_cfa_register: + cfi_cfa = cfi; + break; + case DW_CFA_def_cfa_offset: + case DW_CFA_def_cfa_offset_sf: + cfi_cfa_offset = cfi; + break; + case DW_CFA_nop: + gcc_assert (cfi == NULL); + flush_all: + len = VEC_length (dw_cfi_ref, regs); + for (idx = 0; idx < len; idx++) + { + cfi2 = VEC_replace (dw_cfi_ref, regs, idx, NULL); + if (cfi2 != NULL + && cfi2->dw_cfi_opc != DW_CFA_restore + && cfi2->dw_cfi_opc != DW_CFA_restore_extended) + { + if (do_cfi_asm) + output_cfi_directive (cfi2); + else + output_cfi (cfi2, fde, for_eh); + } + } + if (cfi_cfa && cfi_cfa_offset && cfi_cfa_offset != cfi_cfa) + { + gcc_assert (cfi_cfa->dw_cfi_opc != DW_CFA_def_cfa_expression); + cfi_buf = *cfi_cfa; + switch (cfi_cfa_offset->dw_cfi_opc) + { + case DW_CFA_def_cfa_offset: + cfi_buf.dw_cfi_opc = DW_CFA_def_cfa; + cfi_buf.dw_cfi_oprnd2 = cfi_cfa_offset->dw_cfi_oprnd1; + break; + case DW_CFA_def_cfa_offset_sf: + cfi_buf.dw_cfi_opc = DW_CFA_def_cfa_sf; + cfi_buf.dw_cfi_oprnd2 = cfi_cfa_offset->dw_cfi_oprnd1; + break; + case DW_CFA_def_cfa: + case DW_CFA_def_cfa_sf: + cfi_buf.dw_cfi_opc = cfi_cfa_offset->dw_cfi_opc; + cfi_buf.dw_cfi_oprnd2 = cfi_cfa_offset->dw_cfi_oprnd2; + break; + default: + gcc_unreachable (); + } + cfi_cfa = &cfi_buf; + } + else if (cfi_cfa_offset) + cfi_cfa = cfi_cfa_offset; + if (cfi_cfa) + { + if (do_cfi_asm) + output_cfi_directive (cfi_cfa); + else + output_cfi (cfi_cfa, fde, for_eh); + } + cfi_cfa = NULL; + cfi_cfa_offset = NULL; + if (cfi_args_size + && cfi_args_size->dw_cfi_oprnd1.dw_cfi_offset) + { + if (do_cfi_asm) + output_cfi_directive (cfi_args_size); + else + output_cfi (cfi_args_size, fde, for_eh); + } + cfi_args_size = NULL; + if (cfi == NULL) + { + VEC_free (dw_cfi_ref, heap, regs); + return; + } + else if (do_cfi_asm) + output_cfi_directive (cfi); else - break; - return true; - case DW_CFA_GNU_args_size: - /* One DW_CFA_GNU_args_size, the last one, is enough. */ - *cfi_args_sizep = cfi; - return false; - default: - return true; + output_cfi (cfi, fde, for_eh); + break; + default: + gcc_unreachable (); + } +} + +/* Output one FDE. */ + +static void +output_fde (dw_fde_ref fde, bool for_eh, bool second, + char *section_start_label, int fde_encoding, char *augmentation, + bool any_lsda_needed, int lsda_encoding) +{ + const char *begin, *end; + static unsigned int j; + char l1[20], l2[20]; + dw_cfi_ref cfi; + + targetm.asm_out.unwind_label (asm_out_file, fde->decl, for_eh, + /* empty */ 0); + targetm.asm_out.internal_label (asm_out_file, FDE_LABEL, + for_eh + j); + ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + j); + ASM_GENERATE_INTERNAL_LABEL (l2, FDE_END_LABEL, for_eh + j); + if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4 && !for_eh) + dw2_asm_output_data (4, 0xffffffff, "Initial length escape value" + " indicating 64-bit DWARF extension"); + dw2_asm_output_delta (for_eh ? 4 : DWARF_OFFSET_SIZE, l2, l1, + "FDE Length"); + ASM_OUTPUT_LABEL (asm_out_file, l1); + + if (for_eh) + dw2_asm_output_delta (4, l1, section_start_label, "FDE CIE offset"); + else + dw2_asm_output_offset (DWARF_OFFSET_SIZE, section_start_label, + debug_frame_section, "FDE CIE offset"); + + if (!fde->dw_fde_switched_sections) + { + begin = fde->dw_fde_begin; + end = fde->dw_fde_end; + } + else if (second ^ fde->dw_fde_switched_cold_to_hot) + { + begin = fde->dw_fde_unlikely_section_label; + end = fde->dw_fde_unlikely_section_end_label; + } + else + { + begin = fde->dw_fde_hot_section_label; + end = fde->dw_fde_hot_section_end_label; + } + + if (for_eh) + { + rtx sym_ref = gen_rtx_SYMBOL_REF (Pmode, begin); + SYMBOL_REF_FLAGS (sym_ref) |= SYMBOL_FLAG_LOCAL; + dw2_asm_output_encoded_addr_rtx (fde_encoding, sym_ref, false, + "FDE initial location"); + dw2_asm_output_delta (size_of_encoded_value (fde_encoding), + end, begin, "FDE address range"); + } + else + { + dw2_asm_output_addr (DWARF2_ADDR_SIZE, begin, "FDE initial location"); + dw2_asm_output_delta (DWARF2_ADDR_SIZE, end, begin, "FDE address range"); + } + + if (augmentation[0]) + { + if (any_lsda_needed) + { + int size = size_of_encoded_value (lsda_encoding); + + if (lsda_encoding == DW_EH_PE_aligned) + { + int offset = ( 4 /* Length */ + + 4 /* CIE offset */ + + 2 * size_of_encoded_value (fde_encoding) + + 1 /* Augmentation size */ ); + int pad = -offset & (PTR_SIZE - 1); + + size += pad; + gcc_assert (size_of_uleb128 (size) == 1); + } + + dw2_asm_output_data_uleb128 (size, "Augmentation size"); + + if (fde->uses_eh_lsda) + { + ASM_GENERATE_INTERNAL_LABEL (l1, "LLSDA", fde->funcdef_number); + dw2_asm_output_encoded_addr_rtx (lsda_encoding, + gen_rtx_SYMBOL_REF (Pmode, l1), + false, + "Language Specific Data Area"); + } + else + { + if (lsda_encoding == DW_EH_PE_aligned) + ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE)); + dw2_asm_output_data (size_of_encoded_value (lsda_encoding), 0, + "Language Specific Data Area (none)"); + } + } + else + dw2_asm_output_data_uleb128 (0, "Augmentation size"); } + + /* Loop through the Call Frame Instructions associated with + this FDE. */ + fde->dw_fde_current_label = begin; + if (!fde->dw_fde_switched_sections) + for (cfi = fde->dw_fde_cfi; cfi != NULL; cfi = cfi->dw_cfi_next) + output_cfi (cfi, fde, for_eh); + else if (!second) + { + if (fde->dw_fde_switch_cfi) + for (cfi = fde->dw_fde_cfi; cfi != NULL; cfi = cfi->dw_cfi_next) + { + output_cfi (cfi, fde, for_eh); + if (cfi == fde->dw_fde_switch_cfi) + break; + } + } + else + { + dw_cfi_ref cfi_next = fde->dw_fde_cfi; + + if (fde->dw_fde_switch_cfi) + { + cfi_next = fde->dw_fde_switch_cfi->dw_cfi_next; + fde->dw_fde_switch_cfi->dw_cfi_next = NULL; + output_cfis (fde->dw_fde_cfi, false, fde, for_eh); + fde->dw_fde_switch_cfi->dw_cfi_next = cfi_next; + } + for (cfi = cfi_next; cfi != NULL; cfi = cfi->dw_cfi_next) + output_cfi (cfi, fde, for_eh); + } + + /* Pad the FDE out to an address sized boundary. */ + ASM_OUTPUT_ALIGN (asm_out_file, + floor_log2 ((for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE))); + ASM_OUTPUT_LABEL (asm_out_file, l2); + + j += 2; } + /* Output the call frame information used to record information that relates to calculating the frame pointer, and records the location of saved registers. */ @@ -3272,7 +3542,7 @@ output_cfi_p (dw_cfi_ref *cfip, dw_cfi_ref *cfi_args_sizep) static void output_call_frame_info (int for_eh) { - unsigned int i, j; + unsigned int i; dw_fde_ref fde; dw_cfi_ref cfi; char l1[20], l2[20], section_start_label[20]; @@ -3478,7 +3748,7 @@ output_call_frame_info (int for_eh) ASM_OUTPUT_LABEL (asm_out_file, l2); /* Loop through all of the FDE's. */ - for (i = 0, j = 0; i < fde_table_in_use; i++) + for (i = 0; i < fde_table_in_use; i++) { unsigned int k; fde = &fde_table[i]; @@ -3491,153 +3761,8 @@ output_call_frame_info (int for_eh) continue; for (k = 0; k < (fde->dw_fde_switched_sections ? 2 : 1); k++) - { - const char *begin, *end; - - targetm.asm_out.unwind_label (asm_out_file, fde->decl, for_eh, - /* empty */ 0); - targetm.asm_out.internal_label (asm_out_file, FDE_LABEL, - for_eh + j); - ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + j); - ASM_GENERATE_INTERNAL_LABEL (l2, FDE_END_LABEL, for_eh + j); - if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4 && !for_eh) - dw2_asm_output_data (4, 0xffffffff, "Initial length escape value" - " indicating 64-bit DWARF extension"); - dw2_asm_output_delta (for_eh ? 4 : DWARF_OFFSET_SIZE, l2, l1, - "FDE Length"); - ASM_OUTPUT_LABEL (asm_out_file, l1); - - if (for_eh) - dw2_asm_output_delta (4, l1, section_start_label, - "FDE CIE offset"); - else - dw2_asm_output_offset (DWARF_OFFSET_SIZE, section_start_label, - debug_frame_section, "FDE CIE offset"); - - if (!fde->dw_fde_switched_sections) - { - begin = fde->dw_fde_begin; - end = fde->dw_fde_end; - } - else if (k ^ fde->dw_fde_switched_cold_to_hot) - { - begin = fde->dw_fde_unlikely_section_label; - end = fde->dw_fde_unlikely_section_end_label; - } - else - { - begin = fde->dw_fde_hot_section_label; - end = fde->dw_fde_hot_section_end_label; - } - - if (for_eh) - { - rtx sym_ref = gen_rtx_SYMBOL_REF (Pmode, begin); - SYMBOL_REF_FLAGS (sym_ref) |= SYMBOL_FLAG_LOCAL; - dw2_asm_output_encoded_addr_rtx (fde_encoding, - sym_ref, - false, - "FDE initial location"); - dw2_asm_output_delta (size_of_encoded_value (fde_encoding), - end, begin, "FDE address range"); - } - else - { - dw2_asm_output_addr (DWARF2_ADDR_SIZE, begin, - "FDE initial location"); - dw2_asm_output_delta (DWARF2_ADDR_SIZE, end, begin, - "FDE address range"); - } - - if (augmentation[0]) - { - if (any_lsda_needed) - { - int size = size_of_encoded_value (lsda_encoding); - - if (lsda_encoding == DW_EH_PE_aligned) - { - int offset = ( 4 /* Length */ - + 4 /* CIE offset */ - + 2 * size_of_encoded_value (fde_encoding) - + 1 /* Augmentation size */ ); - int pad = -offset & (PTR_SIZE - 1); - - size += pad; - gcc_assert (size_of_uleb128 (size) == 1); - } - - dw2_asm_output_data_uleb128 (size, "Augmentation size"); - - if (fde->uses_eh_lsda) - { - ASM_GENERATE_INTERNAL_LABEL (l1, "LLSDA", - fde->funcdef_number); - dw2_asm_output_encoded_addr_rtx (lsda_encoding, - gen_rtx_SYMBOL_REF (Pmode, l1), - false, - "Language Specific Data Area"); - } - else - { - if (lsda_encoding == DW_EH_PE_aligned) - ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE)); - dw2_asm_output_data ( - size_of_encoded_value (lsda_encoding), 0, - "Language Specific Data Area (none)"); - } - } - else - dw2_asm_output_data_uleb128 (0, "Augmentation size"); - } - - /* Loop through the Call Frame Instructions associated with - this FDE. */ - fde->dw_fde_current_label = begin; - if (!fde->dw_fde_switched_sections) - for (cfi = fde->dw_fde_cfi; cfi != NULL; cfi = cfi->dw_cfi_next) - output_cfi (cfi, fde, for_eh); - else if (k == 0) - { - if (fde->dw_fde_switch_cfi) - for (cfi = fde->dw_fde_cfi; cfi != NULL; - cfi = cfi->dw_cfi_next) - { - output_cfi (cfi, fde, for_eh); - if (cfi == fde->dw_fde_switch_cfi) - break; - } - } - else - { - dw_cfi_ref cfi_next = fde->dw_fde_cfi; - - if (fde->dw_fde_switch_cfi) - { - dw_cfi_ref cfi_args_size = NULL; - cfi_next = fde->dw_fde_switch_cfi->dw_cfi_next; - fde->dw_fde_switch_cfi->dw_cfi_next = NULL; - for (cfi = fde->dw_fde_cfi; cfi != NULL; - cfi = cfi->dw_cfi_next) - if (output_cfi_p (&cfi, &cfi_args_size)) - output_cfi (cfi, fde, for_eh); - if (cfi_args_size - && cfi_args_size->dw_cfi_oprnd1.dw_cfi_offset) - output_cfi (cfi_args_size, fde, for_eh); - fde->dw_fde_switch_cfi->dw_cfi_next = cfi_next; - } - for (cfi = cfi_next; cfi != NULL; cfi = cfi->dw_cfi_next) - output_cfi (cfi, fde, for_eh); - } - - /* Pad the FDE out to an address sized boundary. */ - ASM_OUTPUT_ALIGN (asm_out_file, - floor_log2 ((for_eh - ? PTR_SIZE : DWARF2_ADDR_SIZE))); - ASM_OUTPUT_LABEL (asm_out_file, l2); - - j += 2; - } + output_fde (fde, for_eh, k, section_start_label, fde_encoding, + augmentation, any_lsda_needed, lsda_encoding); } if (for_eh && targetm.terminate_dw2_eh_frame_info) @@ -3913,16 +4038,10 @@ dwarf2out_switch_text_section (void) if (dwarf2out_do_cfi_asm ()) { - dw_cfi_ref cfi, cfi_args_size = NULL; - dwarf2out_do_cfi_startproc (); /* As this is a different FDE, insert all current CFI instructions again. */ - for (cfi = fde->dw_fde_cfi; cfi; cfi = cfi->dw_cfi_next) - if (output_cfi_p (&cfi, &cfi_args_size)) - output_cfi_directive (cfi); - if (cfi_args_size && cfi_args_size->dw_cfi_oprnd1.dw_cfi_offset) - output_cfi_directive (cfi_args_size); + output_cfis (fde->dw_fde_cfi, true, fde, true); } else { @@ -6594,8 +6713,9 @@ AT_string_form (dw_attr_ref a) /* If we cannot expect the linker to merge strings in .debug_str section, only put it into .debug_str if it is worth even in this single module. */ - if ((debug_str_section->common.flags & SECTION_MERGE) == 0 - && (len - DWARF_OFFSET_SIZE) * node->refcount <= len) + if (DWARF2_INDIRECT_STRING_SUPPORT_MISSING_ON_TARGET + || ((debug_str_section->common.flags & SECTION_MERGE) == 0 + && (len - DWARF_OFFSET_SIZE) * node->refcount <= len)) return node->form = DW_FORM_string; ASM_GENERATE_INTERNAL_LABEL (label, "LASF", dw2_string_counter); @@ -9498,7 +9618,9 @@ output_file_names (void) idx = 1; idx_offset = dirs[0].length > 0 ? 1 : 0; for (i = 1 - idx_offset; i < ndirs; i++) - dw2_asm_output_nstring (dirs[i].path, dirs[i].length - 1, + dw2_asm_output_nstring (dirs[i].path, + dirs[i].length + - !DWARF2_DIR_SHOULD_END_WITH_SEPARATOR, "Directory Entry: 0x%x", i + idx_offset); dw2_asm_output_data (1, 0, "End directory table"); @@ -9516,6 +9638,42 @@ output_file_names (void) int file_idx = backmap[i]; int dir_idx = dirs[files[file_idx].dir_idx].dir_idx; +#ifdef VMS_DEBUGGING_INFO +#define MAX_VMS_VERSION_LEN 6 /* ";32768" */ + + /* Setting these fields can lead to debugger miscomparisons, + but VMS Debug requires them to be set correctly. */ + + int ver; + long long cdt; + long siz; + int maxfilelen = strlen (files[file_idx].path) + + dirs[dir_idx].length + + MAX_VMS_VERSION_LEN + 1; + char *filebuf = XALLOCAVEC (char, maxfilelen); + + vms_file_stats_name (files[file_idx].path, 0, 0, 0, &ver); + snprintf (filebuf, maxfilelen, "%s;%d", + files[file_idx].path + dirs[dir_idx].length, ver); + + dw2_asm_output_nstring + (filebuf, -1, "File Entry: 0x%x", (unsigned) i + 1); + + /* Include directory index. */ + dw2_asm_output_data_uleb128 (dir_idx + idx_offset, NULL); + + /* Modification time. */ + dw2_asm_output_data_uleb128 + ((vms_file_stats_name (files[file_idx].path, &cdt, 0, 0, 0) == 0) + ? cdt : 0, + NULL); + + /* File length in bytes. */ + dw2_asm_output_data_uleb128 + ((vms_file_stats_name (files[file_idx].path, 0, &siz, 0, 0) == 0) + ? siz : 0, + NULL); +#else dw2_asm_output_nstring (files[file_idx].path + dirs[dir_idx].length, -1, "File Entry: 0x%x", (unsigned) i + 1); @@ -9527,6 +9685,7 @@ output_file_names (void) /* File length in bytes. */ dw2_asm_output_data_uleb128 (0, NULL); +#endif } dw2_asm_output_data (1, 0, "End file name table"); @@ -12780,7 +12939,23 @@ static void add_comp_dir_attribute (dw_die_ref die) { const char *wd = get_src_pwd (); - if (wd != NULL) + char *wd1; + + if (wd == NULL) + return; + + if (DWARF2_DIR_SHOULD_END_WITH_SEPARATOR) + { + int wdlen; + + wdlen = strlen (wd); + wd1 = GGC_NEWVEC (char, wdlen + 2); + strcpy (wd1, wd); + wd1 [wdlen] = DIR_SEPARATOR; + wd1 [wdlen + 1] = 0; + wd = wd1; + } + add_AT_string (die, DW_AT_comp_dir, remap_debug_filename (wd)); } @@ -13173,7 +13348,7 @@ add_name_and_src_coords_attributes (dw_die_ref die, tree decl) { add_AT_addr (die, DW_AT_VMS_rtnbeg_pd_address, XEXP (DECL_RTL (decl), 0)); - VEC_safe_push (tree, gc, used_rtx_array, XEXP (DECL_RTL (decl), 0)); + VEC_safe_push (rtx, gc, used_rtx_array, XEXP (DECL_RTL (decl), 0)); } #endif } diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index ca320ca8e71..f89a8af3e38 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,39 @@ +2009-07-29 Tobias Burnus <burnus@net-b.de> + + PR fortran/40898 + * trans-types.c (gfc_get_function_type): Do not add hidden + string-length argument for BIND(C) procedures. + * trans-decl.c (create_function_arglist): Skip over nonexisting + string-length arguments for BIND(C) procedures. + +2009-07-28 Jakub Jelinek <jakub@redhat.com> + + PR fortran/40878 + * openmp.c (gfc_match_omp_clauses): Use gfc_error_now instead of + gfc_error to diagnose invalid COLLAPSE arguments. + +2009-07-28 Janus Weil <janus@gcc.gnu.org> + + PR fortran/40882 + * trans-types.c (gfc_get_ppc_type): For derived types, directly use the + backend_decl, instead of calling gfc_typenode_for_spec, to avoid + infinte loop. + (gfc_get_derived_type): Correctly handle PPCs returning derived types, + avoiding infinite recursion. + +2009-07-27 Janus Weil <janus@gcc.gnu.org> + + PR fortran/40848 + * interface.c (gfc_compare_interfaces): Call 'count_types_test' before + 'generic_correspondence', and only if checking a generic interface. + +2009-07-27 Tobias Burnus <burnus@net-b.de> + + PR fortran/40851 + * resolve.c (resolve_symbol): Do not initialize pointer derived-types. + * trans-decl.c (init_intent_out_dt): Ditto. + (generate_local_decl): No need to set attr.referenced for DT pointers. + 2009-07-26 Tobias Burnus <burnus@net-b.de> PR fortran/33197 diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index cedca457f0c..982aa290e22 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -983,6 +983,8 @@ gfc_compare_interfaces (gfc_symbol *s1, gfc_symbol *s2, int generic_flag, if (generic_flag) { + if (count_types_test (f1, f2) || count_types_test (f2, f1)) + return 0; if (generic_correspondence (f1, f2) || generic_correspondence (f2, f1)) return 0; } @@ -1034,13 +1036,6 @@ gfc_compare_interfaces (gfc_symbol *s1, gfc_symbol *s2, int generic_flag, f2 = f2->next; } - if (count_types_test (f1, f2) || count_types_test (f2, f1)) - { - if (errmsg != NULL) - snprintf (errmsg, err_len, "Interface not matching"); - return 0; - } - return 1; } diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index 608d605c951..320fb65c97c 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -396,12 +396,13 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, int mask) const char *p = gfc_extract_int (cexpr, &collapse); if (p) { - gfc_error (p); + gfc_error_now (p); collapse = 1; } else if (collapse <= 0) { - gfc_error ("COLLAPSE clause argument not constant positive integer at %C"); + gfc_error_now ("COLLAPSE clause argument not" + " constant positive integer at %C"); collapse = 1; } c->collapse = collapse; diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index aaab554d4de..053ec839a08 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -10036,7 +10036,7 @@ resolve_symbol (gfc_symbol *sym) if ((!a->save && !a->dummy && !a->pointer && !a->in_common && !a->use_assoc && !(a->function && sym != sym->result)) - || (a->dummy && a->intent == INTENT_OUT)) + || (a->dummy && a->intent == INTENT_OUT && !a->pointer)) apply_default_init (sym); } diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index e4ac20f58b2..783c8f8308e 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -1724,7 +1724,8 @@ create_function_arglist (gfc_symbol * sym) type = TREE_VALUE (typelist); - if (f->sym->ts.type == BT_CHARACTER) + if (f->sym->ts.type == BT_CHARACTER + && (!sym->attr.is_bind_c || sym->attr.entry_master)) { tree len_type = TREE_VALUE (hidden_typelist); tree length = NULL_TREE; @@ -2958,7 +2959,8 @@ init_intent_out_dt (gfc_symbol * proc_sym, tree body) gfc_init_block (&fnblock); for (f = proc_sym->formal; f; f = f->next) if (f->sym && f->sym->attr.intent == INTENT_OUT - && f->sym->ts.type == BT_DERIVED) + && !f->sym->attr.pointer + && f->sym->ts.type == BT_DERIVED) { if (f->sym->ts.derived->attr.alloc_comp) { @@ -3708,6 +3710,7 @@ generate_local_decl (gfc_symbol * sym) if (!sym->attr.referenced && sym->ts.type == BT_DERIVED && sym->ts.derived->attr.alloc_comp + && !sym->attr.pointer && ((sym->attr.dummy && sym->attr.intent == INTENT_OUT) || (sym->attr.result && sym != sym->result))) diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index 99967ce3705..7b842360280 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -1894,7 +1894,12 @@ gfc_get_ppc_type (gfc_component* c) { tree t; if (c->attr.function && !c->attr.dimension) - t = gfc_typenode_for_spec (&c->ts); + { + if (c->ts.type == BT_DERIVED) + t = c->ts.derived->backend_decl; + else + t = gfc_typenode_for_spec (&c->ts); + } else t = void_type_node; /* TODO: Build argument list. */ @@ -1974,7 +1979,8 @@ gfc_get_derived_type (gfc_symbol * derived) if (c->ts.type != BT_DERIVED) continue; - if (!c->attr.pointer || c->ts.derived->backend_decl == NULL) + if ((!c->attr.pointer && !c->attr.proc_pointer) + || c->ts.derived->backend_decl == NULL) c->ts.derived->backend_decl = gfc_get_derived_type (c->ts.derived); if (c->ts.derived && c->ts.derived->attr.is_iso_c) @@ -2003,10 +2009,10 @@ gfc_get_derived_type (gfc_symbol * derived) fieldlist = NULL_TREE; for (c = derived->components; c; c = c->next) { - if (c->ts.type == BT_DERIVED) - field_type = c->ts.derived->backend_decl; - else if (c->attr.proc_pointer) + if (c->attr.proc_pointer) field_type = gfc_get_ppc_type (c); + else if (c->ts.type == BT_DERIVED) + field_type = c->ts.derived->backend_decl; else { if (c->ts.type == BT_CHARACTER) @@ -2243,7 +2249,7 @@ gfc_get_function_type (gfc_symbol * sym) Contained procedures could pass by value as these are never used without an explicit interface, and cannot be passed as actual parameters for a dummy procedure. */ - if (arg->ts.type == BT_CHARACTER) + if (arg->ts.type == BT_CHARACTER && !sym->attr.is_bind_c) nstr++; typelist = gfc_chainon_list (typelist, type); } 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..da2beb3c4d7 --- /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_graphite_force_parallel) + 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..997e164a344 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_graphite_force_parallel) + 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/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-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/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..3a4a1f40c55 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); diff --git a/gcc/opt-functions.awk b/gcc/opt-functions.awk index ae1e1cb38c6..98414dae9a9 100644 --- a/gcc/opt-functions.awk +++ b/gcc/opt-functions.awk @@ -41,7 +41,13 @@ function opt_args(name, flags) if (flags !~ " " name "\\(") return "" sub(".* " name "\\(", "", flags) - sub("\\).*", "", flags) + if (flags ~ "^{") + { + sub ("^{", "", flags) + sub("}\\).*", "", flags) + } + else + sub("\\).*", "", flags) return flags } 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/po/ChangeLog b/gcc/po/ChangeLog index acd84f5303f..0b8cf4f41e4 100644 --- a/gcc/po/ChangeLog +++ b/gcc/po/ChangeLog @@ -1,3 +1,7 @@ +2009-07-29 Joseph Myers <joseph@codesourcery.com> + + * sv.po: Update. + 2009-07-23 Joseph Myers <joseph@codesourcery.com> * be.po, da.po, de.po, el.po, es.po, fi.po, fr.po, id.po, ja.po, diff --git a/gcc/po/sv.po b/gcc/po/sv.po index ed446c2663d..f8a9b4dd67d 100644 --- a/gcc/po/sv.po +++ b/gcc/po/sv.po @@ -1,17 +1,17 @@ # Swedish messages for GCC. -# Copyright © 2000, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# Copyright © 2000, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is distributed under the same license as the gcc package. # Dennis Björklund <db@zigo.dhs.org>, 2000, 2001, 2002. -# Göran Uddeborg <goeran@uddeborg.se>, 2005, 2006, 2007, 2008. +# Göran Uddeborg <goeran@uddeborg.se>, 2005, 2006, 2007, 2008, 2009. # # Remember: GCC team does not want RCS keywords in the header! # msgid "" msgstr "" -"Project-Id-Version: gcc 4.4-b20081121\n" +"Project-Id-Version: gcc 4.4.1\n" "Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n" "POT-Creation-Date: 2009-07-15 13:37+0200\n" -"PO-Revision-Date: 2009-01-11 16:07+0100\n" +"PO-Revision-Date: 2009-07-28 12:12+0200\n" "Last-Translator: Göran Uddeborg <goeran@uddeborg.se>\n" "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n" "MIME-Version: 1.0\n" @@ -872,9 +872,8 @@ msgid " --target-help Display target specific command line options\n msgstr " --target-help Visa specifika kommandoradsflaggor för mål\n" #: gcc.c:3231 -#, fuzzy msgid " --help={target|optimizers|warnings|params|[^]{joined|separate|undocumented}}[,...]\n" -msgstr " --help={target|optimizers|warnings|undocumented|params}[,{[^]joined|[^]separate}]\n" +msgstr " --help={target|optimizers|warnings|params|[^]{joined|separate|undocumented}}[,...]\n" #: gcc.c:3232 msgid " Display specific types of command line options\n" @@ -885,9 +884,8 @@ msgid " (Use '-v --help' to display command line options of sub-processes)\n" msgstr " (Använd '-v --help' för att visa kommandoradsflaggor för barnprocesser)\n" #: gcc.c:3235 -#, fuzzy msgid " --version Display compiler version information\n" -msgstr " --help Visa den här informationen\n" +msgstr " --version Visa information om kompilatorversion\n" #: gcc.c:3236 msgid " -dumpspecs Display all of the built in spec strings\n" @@ -1071,9 +1069,9 @@ msgid "couldn't run '%s': %s" msgstr "gick inte att köra \"%s\": %s" #: gcc.c:3439 -#, fuzzy, c-format +#, c-format msgid "couldn't run '%s': %s: %s" -msgstr "gick inte att köra \"%s\": %s" +msgstr "gick inte att köra \"%s\": %s: %s" #. translate_options () has turned --version into -fversion. #: gcc.c:3643 @@ -1262,7 +1260,9 @@ msgid "" "For bug reporting instructions, please see:\n" msgstr "" "\n" -"För felrapporteringsinstruktioner se:\n" +"Synpunkter på översättningen till svenska rapporteras till\n" +"<tp-sv@listor.tp-sv.se>.\n" +"För felrapporteringsinstruktioner i övrigt, se:\n" #: gcc.c:6616 #, c-format @@ -1894,14 +1894,12 @@ msgid "The following options are not documented" msgstr "Följande flaggor är inte dokumenterade" #: opts.c:1385 -#, fuzzy msgid "The following options take separate arguments" -msgstr "Följande flaggor är inte dokumenterade" +msgstr "Följande flaggor tar separata argument" #: opts.c:1387 -#, fuzzy msgid "The following options take joined arguments" -msgstr "Följande flaggor är inte dokumenterade" +msgstr "Följande flaggor tar sammanslagna argument" #: opts.c:1398 msgid "The following options are language-related" @@ -2857,7 +2855,7 @@ msgstr "maximalt slingantal för regional RA" #: params.def:755 msgid "max size of conflict table in MB" -msgstr "" +msgstr "maximal storlek på konflikttabell i MB" #: params.def:763 msgid "The maximum ratio between array size and switch branches for a switch conversion to take place" @@ -2865,7 +2863,7 @@ msgstr "Det maximala förhållandet mellan vektorstorlek och switch-grenar för att #: params.def:771 msgid "max basic blocks number in loop for loop invariant motion" -msgstr "" +msgstr "maximalt antal grundblock i slinga-för-slinga-invarianta förflyttningar" #: config/alpha/alpha.c:5039 #, c-format @@ -3313,19 +3311,19 @@ msgid "invalid UNSPEC as operand" msgstr "ogiltig UNSPEC som operand" #: config/i386/i386.c:11065 config/i386/i386.c:11104 config/i386/i386.c:11278 -#, fuzzy, c-format +#, c-format msgid "operand is not a condition code, invalid operand code 'D'" -msgstr "operand är varken en konstant eller en villkorskod, ogiltig operandkod \"c\"" +msgstr "operand är inte en villkorskod, ogiltig operandkod \"D\"" #: config/i386/i386.c:11129 -#, fuzzy, c-format +#, c-format msgid "operand is neither a constant nor a condition code, invalid operand code 'C'" -msgstr "operand är varken en konstant eller en villkorskod, ogiltig operandkod \"c\"" +msgstr "operand är varken en konstant eller en villkorskod, ogiltig operandkod \"C\"" #: config/i386/i386.c:11139 -#, fuzzy, c-format +#, c-format msgid "operand is neither a constant nor a condition code, invalid operand code 'F'" -msgstr "operand är varken en konstant eller en villkorskod, ogiltig operandkod \"c\"" +msgstr "operand är varken en konstant eller en villkorskod, ogiltig operandkod \"F\"" #: config/i386/i386.c:11157 #, c-format @@ -3333,9 +3331,9 @@ msgid "operand is neither a constant nor a condition code, invalid operand code msgstr "operand är varken en konstant eller en villkorskod, ogiltig operandkod \"c\"" #: config/i386/i386.c:11167 -#, fuzzy, c-format +#, c-format msgid "operand is neither a constant nor a condition code, invalid operand code 'f'" -msgstr "operand är varken en konstant eller en villkorskod, ogiltig operandkod \"c\"" +msgstr "operand är varken en konstant eller en villkorskod, ogiltig operandkod \"f\"" #: config/i386/i386.c:11292 #, c-format @@ -4093,9 +4091,9 @@ msgid "'dim' argument of '%s' intrinsic at %L is not a valid dimension index" msgstr "\"dim\"-argumentet till inbyggd \"%s\" vid %L är inte ett giltigt dimensionsindex" #: fortran/check.c:431 -#, fuzzy, no-c-format +#, no-c-format msgid "Unequal character lengths (%ld/%ld) in %s at %L" -msgstr "Olika teckenlängder (%ld och %ld) i inbyggd %s vid %L" +msgstr "Olika teckenlängder (%ld/%ld) i %s vid %L" #: fortran/check.c:537 fortran/check.c:2039 fortran/check.c:2054 #, no-c-format @@ -4221,9 +4219,9 @@ msgid "'a1' argument of '%s' intrinsic at %L must be INTEGER, REAL or CHARACTER" msgstr "\"a1\"-argumentet till inbyggd \"%s\" vid %L måste vara INTEGER, REAL eller CHARACTER" #: fortran/check.c:1821 -#, fuzzy, no-c-format +#, no-c-format msgid "Argument types of '%s' intrinsic at %L must match (%s/%s)" -msgstr "\"a%d\"-argumentet till inbyggd \"%s\" vid %L måste vara %s(%d)" +msgstr "Argumenttyper till inbyggd \"%s\" vid %L måste stämma överens (%s/%s)" #: fortran/check.c:1835 #, no-c-format @@ -4316,9 +4314,9 @@ msgid "Different shape in dimension %d for MASK and FIELD arguments of UNPACK at msgstr "Olika form i dimension %d för argumenten MASK och FIELD till UNPACK vid %L" #: fortran/check.c:3190 fortran/check.c:3222 -#, fuzzy, no-c-format +#, no-c-format msgid "Size of '%s' argument of '%s' intrinsic at %L too small (%i/%i)" -msgstr "\"%s\"-argumentet till inbyggd \"%s\" vid %L måste vara %s" +msgstr "Stolek på \"%s\"-argumentet till inbyggd \"%s\" vid %L är för liten (%i/%i)" #: fortran/check.c:3230 #, no-c-format @@ -4646,9 +4644,9 @@ msgid "Kind %d not supported for type %s at %C" msgstr "Sorten %d stöds inte för typen %s vid %C" #: fortran/decl.c:1992 -#, fuzzy, no-c-format +#, no-c-format msgid "C kind type parameter is for type %s but type at %L is %s" -msgstr "Parameter med sort C är för typ %s men symbolen \"%s\" vid %L är av typ %s" +msgstr "Parameter med sort C är för typ %s men typen vid %L är %s" #: fortran/decl.c:2001 #, no-c-format @@ -5820,14 +5818,14 @@ msgid "Bad pointer object in PURE procedure at %L" msgstr "Felaktigt pekarobjekt i PURE-procedur vid %L" #: fortran/expr.c:3134 -#, fuzzy, no-c-format +#, no-c-format msgid "Invalid procedure pointer assignment at %L" -msgstr "Olika ordning i pekartilldelning vid %L" +msgstr "Ogiltig procedurpekartilldelning vid %L" #: fortran/expr.c:3140 -#, fuzzy, no-c-format +#, no-c-format msgid "Abstract interface '%s' is invalid in procedure pointer assignment at %L" -msgstr "Olika sorters typparametrar i pekartilldelning vid %L" +msgstr "Abstrakt gränssnitt \"%s\" är ogiltigt i procedurpekartilldelning vid %L" #: fortran/expr.c:3159 #, no-c-format @@ -6382,9 +6380,8 @@ msgid "Fortran 2008: 'G0' in format at %C" msgstr "Fortran 2008: \"G0\" i format vid %C" #: fortran/io.c:745 -#, fuzzy msgid "E specifier not allowed with g0 descriptor" -msgstr "Redigeringsbeskrivning P förväntades" +msgstr "Specificeraren E är inte tillåten vid g0-deskriptor" #: fortran/io.c:759 fortran/io.c:761 fortran/io.c:822 fortran/io.c:824 #, no-c-format @@ -7313,19 +7310,19 @@ msgid "Error writing module file '%s' for writing: %s" msgstr "Fel när modulfilen \"%s\" skrevs: %s" #: fortran/module.c:4876 -#, fuzzy, no-c-format +#, no-c-format msgid "Can't delete module file '%s': %s" -msgstr "%s: kan inte radera fil \"%s\": %s\n" +msgstr "Kan inte radera modulfil \"%s\": %s" #: fortran/module.c:4879 -#, fuzzy, no-c-format +#, no-c-format msgid "Can't rename module file '%s' to '%s': %s" -msgstr "%s: varning: kan inte ändra namn på filen \"%s\" till \"%s\": %s\n" +msgstr "Kan inte ändra namn på modulfilen \"%s\" till \"%s\": %s" #: fortran/module.c:4885 -#, fuzzy, no-c-format +#, no-c-format msgid "Can't delete temporary module file '%s': %s" -msgstr "%s: kan inte radera fil med övrig info \"%s\": %s\n" +msgstr "Kan inte radera temporär modulfil \"%s\": %s" #: fortran/module.c:4905 fortran/module.c:4987 #, no-c-format @@ -7404,12 +7401,18 @@ msgstr "Filen \"%s\" öppnad vid %C är inte en GFORTRAN-modulfil" #: fortran/module.c:5252 #, no-c-format msgid "Parse error when checking module version for file '%s' opened at %C" -msgstr "" +msgstr "Tolkningsfel vid kontroll av modulversion för filen \"%s\" öppnad vid %C" +# Meddelandet avhugget på grund av att den här delsträngen konkateneras +# med andra strängar i källkoden, men den följande strängen är en +# preprocessorsymbol. Stränextraktionen för översättning klarar +# uppenbarligen inte det. +# +# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40849 #: fortran/module.c:5257 #, no-c-format msgid "Wrong module version '%s' (expected '" -msgstr "" +msgstr "Fel modulversion \"%s\" (förväntade \"" #: fortran/module.c:5270 #, no-c-format @@ -8599,7 +8602,7 @@ msgstr "GENERIC procedur \"%s\" är inte tillåten som aktuellt argument vid %L" #: fortran/resolve.c:1163 #, no-c-format msgid "Non-RECURSIVE procedure '%s' at %L is possibly calling itself recursively. Declare it RECURSIVE or use -frecursive" -msgstr "" +msgstr "Icke RECURSIVE procedur \"%s\" vid %L anropar kanske sig själv rekursivt. Deklarera den RECURSIVE eller använd -frecursive." #: fortran/resolve.c:1196 fortran/resolve.c:6023 fortran/resolve.c:6778 #, no-c-format @@ -8786,14 +8789,14 @@ msgid "Function reference to '%s' at %L is to a non-PURE procedure within a PURE msgstr "Funktionsreferens till \"%s\" vid %L är till en icke-PURE-procedur inuti en PURE-procedur" #: fortran/resolve.c:2493 -#, fuzzy, no-c-format +#, no-c-format msgid "ENTRY '%s' at %L cannot be called recursively, as function '%s' is not RECURSIVE" -msgstr "Anrop till ENTRY \"%s\" vid %L är rekursivt, men funktionen \"%s\" är inte deklarerad som RECURSIVE" +msgstr "ENTRY \"%s\" vid %L får inte anropas rekursivt, eftersom funktionen \"%s\" inte är RECURSIVE" #: fortran/resolve.c:2497 -#, fuzzy, no-c-format +#, no-c-format msgid "Function '%s' at %L cannot be called recursively, as it is not RECURSIVE" -msgstr "Funktion \"%s\" vid %L får inte anropa sig själv, eftersom den inte är RECURSIVE" +msgstr "Funktion \"%s\" vid %L får inte anropas rekursivt, eftersom den inte är RECURSIVE" #: fortran/resolve.c:2544 #, no-c-format @@ -8841,14 +8844,14 @@ msgid "'%s' at %L has a type, which is not consistent with the CALL at %L" msgstr "\"%s\" vid %L har en typ som inte är konsistent med CALL vid %L" #: fortran/resolve.c:2957 -#, fuzzy, no-c-format +#, no-c-format msgid "ENTRY '%s' at %L cannot be called recursively, as subroutine '%s' is not RECURSIVE" -msgstr "Anrop av ENTRY \"%s\" vid %L är rekursiv, men subroutine \"%s\" är inte deklarerad som RECURSIVE" +msgstr "ENTRY \"%s\" vid %L är får inte anropas rekursivt, eftersom subrutinen \"%s\" inte är RECURSIVE" #: fortran/resolve.c:2961 -#, fuzzy, no-c-format +#, no-c-format msgid "SUBROUTINE '%s' at %L cannot be called recursively, as it is not RECURSIVE" -msgstr "SUBROUTINE \"%s\" vid %L får inte anropa sig själv, eftersom den inte är RECURSIVE" +msgstr "SUBROUTINE \"%s\" vid %L får inte anropas rekursivt, eftersom den inte är RECURSIVE" #: fortran/resolve.c:3035 #, no-c-format @@ -9779,9 +9782,9 @@ msgid "Character length of component '%s' needs to be a constant specification e msgstr "Teckenlängd på komponent \"%s\" behöver vara ett konstant specifikationsuttryck vid %L" #: fortran/resolve.c:8735 -#, fuzzy, no-c-format +#, no-c-format msgid "Fortran 2003: the component '%s' is a PRIVATE type and cannot be a component of '%s', which is PUBLIC at %L" -msgstr "Komponenten \"%s\" är en PRIVATE-typ och kan inte vara en komponent i \"%s\", som är PUBLIC vid %L" +msgstr "Fortran 2003: komponenten \"%s\" är en PRIVATE-typ och kan inte vara en komponent i \"%s\", som är PUBLIC vid %L" #: fortran/resolve.c:8746 #, no-c-format @@ -9939,9 +9942,9 @@ msgid "Threadprivate at %L isn't SAVEd" msgstr "Trådprivat vid %L är inte SAVE:ad" #: fortran/resolve.c:9448 -#, fuzzy, no-c-format +#, no-c-format msgid "non-constant DATA value at %L" -msgstr "ickekonstant vektor i DATA-sats %L" +msgstr "ickekonstant DATA-värde vid %L" #: fortran/resolve.c:9488 #, no-c-format @@ -11055,7 +11058,7 @@ msgid "" msgstr "" "För felrapporteringsinstruktioner se:\n" "%s.\n" -"Skcka synpunkter på översättningen <tp-sv@listor.tp-sv.se>\n" +"Skicka synpunkter på översättningen <tp-sv@listor.tp-sv.se>\n" #: java/jcf-dump.c:1189 java/jcf-dump.c:1257 #, c-format @@ -11218,7 +11221,7 @@ msgstr "Statisk länkning stöds inte.\n" #: ada/gcc-interface/lang-specs.h:34 msgid "-c or -S required for Ada" -msgstr "" +msgstr "-c eller -S krävs för Ada" #: config/s390/tpf.h:119 msgid "static is not supported on TPF-OS" @@ -11610,7 +11613,7 @@ msgstr "Generera kod med omvänd byteordning" #: config/mcore/mcore.opt:56 config/fr30/fr30.opt:27 msgid "Assume that run-time support has been provided, so omit -lsim from the linker command line" -msgstr "" +msgstr "Anta att körtidsstöd finns, så utelämna -lsim från länkningskommandoraden" #: config/mcore/mcore.opt:60 msgid "Use arbitrary sized immediates in bit operations" @@ -12173,9 +12176,8 @@ msgid "Allow branches to be packed with other instructions" msgstr "Tillåt grenar att packas med andra instruktioner" #: config/picochip/picochip.opt:23 -#, fuzzy msgid "Specify which type of AE to target. This option sets the mul-type and byte-access." -msgstr "Ange vilken typ av AE att ha som mål. Denna flagga sätter mul-typen" +msgstr "Ange vilken typ av AE att ha som mål. Denna flagga sätter mul-typen och byte-åtkomst." #: config/picochip/picochip.opt:27 msgid "Specify which type of multiplication to use. Can be mem, mac or none." @@ -12189,10 +12191,7 @@ msgstr "Ange om instruktioner för byteåtkomst skall användas. Aktiverat som sta msgid "Enable debug output to be generated." msgstr "Aktivera generering av felsökningsutdata." -# Avhugget p.g.a. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38442 -# Hela meddelandet är översatt #: config/picochip/picochip.opt:39 -#, fuzzy msgid "Allow a symbol value to be used as an immediate value in an instruction." msgstr "Tillåt ett symbolvärde att användas som ett omedelbart värde i en instruktion." @@ -12970,7 +12969,7 @@ msgstr "Generera load/store-instruktioner med uppdatering" #: config/rs6000/rs6000.opt:124 msgid "Avoid generation of indexed load/store instructions when possible" -msgstr "" +msgstr "Undvik att generera indexerade load/store-instruktioner så långt möjligt" #: config/rs6000/rs6000.opt:128 msgid "Do not generate fused multiply/add instructions" @@ -14625,7 +14624,7 @@ msgstr "Bygg för SDRAM" #: config/bfin/bfin.opt:101 msgid "Assume ICPLBs are enabled at runtime." -msgstr "" +msgstr "Anta ICPLBs är aktiverade vid körtillfället." #: java/lang.opt:69 msgid "Warn if deprecated empty statements are found" @@ -15275,13 +15274,12 @@ msgid "Perform structure layout optimizations based" msgstr "Utför optimeringar av postutläggning baserat" #: common.opt:680 -#, fuzzy msgid "-fira-algorithm=[CB|priority] Set the used IRA algorithm" -msgstr "-fira-algorithm=[regional|CB|mixed] Bestäm den använda IRA-algoritmen" +msgstr "-fira-algorithm=[CB|priority] Bestäm den använda IRA-algoritmen" #: common.opt:684 msgid "-fira-region=[one|all|mixed] Set regions for IRA" -msgstr "" +msgstr "-fira-region=[one|all|mixed] Sätt regioner för IRA" #: common.opt:688 msgid "Do optimistic coalescing." @@ -16275,7 +16273,7 @@ msgstr "Varna för åsidosättande initierare utan sidoeffekter" #: c.opt:373 msgid "Warn about packed bit-fields whose offset changed in GCC 4.4" -msgstr "" +msgstr "Varna för packade bitfält vars avstånd ändrats i GCC 4.4" #: c.opt:377 msgid "Warn about possibly missing parentheses" @@ -16542,9 +16540,8 @@ msgid "Enable Objective-C setjmp exception handling runtime" msgstr "Aktivera Objective-C:s setjmp-undantagshantering i körtidsmiljön" #: c.opt:694 -#, fuzzy msgid "Enable OpenMP (implies -frecursive in Fortran)" -msgstr "Aktivera OpenMP (sätter även frecursive)" +msgstr "Aktivera OpenMP (implicerar -frecursive i Fortran)" #: c.opt:698 msgid "Recognize C++ keywords like \"compl\" and \"xor\"" @@ -18574,9 +18571,9 @@ msgstr "ISO C90 stödjer inte flexibla vektormedlemmar" #. C99 6.7.5.2p4 #: c-decl.c:4431 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%<[*]%> not in a declaration" -msgstr "%<[*]%> är inte tillåtet annat än i en deklaration" +msgstr "%<[*]%> är inte i en deklaration" #: c-decl.c:4444 #, gcc-internal-format @@ -21234,7 +21231,7 @@ msgstr "pekar-/heltalstyper stämmer inte i villkorsuttryck" #: c-typeck.c:3587 #, gcc-internal-format msgid "type mismatch in conditional expression" -msgstr "typfel i villkorsuttryck" +msgstr "typer stämmer inte i villkorsuttryck" #: c-typeck.c:3628 #, gcc-internal-format @@ -22560,9 +22557,9 @@ msgid "assuming signed overflow does not occur when negating a division" msgstr "antar att teckenspill inte förekommer vid negering av en division" #: fold-const.c:4017 fold-const.c:4028 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "comparison is always %d due to width of bit-field" -msgstr "jämförelsen är alltid sann på grund av begränsat intervall för datatypen" +msgstr "jämförelsen är alltid %d på grund av bredd på bitfält" #: fold-const.c:5361 #, gcc-internal-format @@ -22963,9 +22960,9 @@ msgid "-freorder-blocks-and-partition does not work on this architecture" msgstr "-freorder-blocks-and-partition fungerar inte på denna arkitektur" #: opts.c:1081 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "-fira-algorithm=CB does not work on this architecture" -msgstr "-fira fungerar inte på denna arkitektur" +msgstr "-fira-algorithm=CB fungerar inte på denna arkitektur" #: opts.c:1390 #, gcc-internal-format @@ -23003,9 +23000,9 @@ msgid "unknown ira algorithm \"%s\"" msgstr "okänd ira-algoritm \"%s\"" #: opts.c:1980 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "unknown ira region \"%s\"" -msgstr "okänd ira-algoritm \"%s\"" +msgstr "okänd ira-region \"%s\"" #: opts.c:2083 #, gcc-internal-format @@ -23425,7 +23422,7 @@ msgstr "fyller ut post för att justera %q+D" #: stor-layout.c:969 #, gcc-internal-format msgid "Offset of packed bit-field %qD has changed in GCC 4.4" -msgstr "" +msgstr "Avstånd till packat bitfält %qD har ändrats i GCC 4.4" #: stor-layout.c:1273 #, gcc-internal-format @@ -23658,9 +23655,9 @@ msgid "SSA name in freelist but still referenced" msgstr "SSA-namn i frilista men fortfarande refererad" #: tree-cfg.c:2829 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Indirect reference's operand is not a register or a constant." -msgstr "%s: Tredje källoperanden är inte en konstant" +msgstr "Indirekta referensens operand är inte ett register eller en konstant." #: tree-cfg.c:2838 #, gcc-internal-format @@ -23670,7 +23667,7 @@ msgstr "ASSERT_EXPR med villkor som alltid är falskt" #: tree-cfg.c:2844 #, gcc-internal-format msgid "MODIFY_EXPR not expected while having tuples." -msgstr "" +msgstr "MODIFY_EXPR förväntades inte när man har tupler." #: tree-cfg.c:2865 #, gcc-internal-format @@ -24272,19 +24269,19 @@ msgid "unimplemented functionality" msgstr "oimplementerad funktionalitet" #: tree-ssa-structalias.c:4791 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "initialized from %qE" -msgstr "oinitierade const %qD" +msgstr "initierade från %qE" #: tree-ssa-structalias.c:4795 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "initialized from here" -msgstr "anropad härifrån" +msgstr "initierade härifrån" #: tree-ssa-structalias.c:4844 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "dereferencing pointer %qD does break strict-aliasing rules" -msgstr "dereferens av en typstampad pekare %D kommer bryta regler för strikt aliasing" +msgstr "att dereferera pekare %qD bryter regler för strikt aliasing" #: tree-ssa.c:252 #, gcc-internal-format @@ -25253,7 +25250,7 @@ msgstr "avbrottsservicerutiner kan inte kodas i Thumb-läge" #: config/arm/arm.c:19618 #, gcc-internal-format msgid "the mangling of %<va_list%> has changed in GCC 4.4" -msgstr "" +msgstr "manglingen av %<va_list%> har ändrats i GCC 4.4" #: config/arm/pe.c:158 config/mcore/mcore.c:2900 #, gcc-internal-format @@ -25268,17 +25265,17 @@ msgstr "statisk variabel %q+D är markerad som dllimport" #: config/avr/avr.c:399 #, gcc-internal-format msgid "the -mno-tablejump switch is deprecated" -msgstr "" +msgstr "flaggan -mno-tablejump bör undvikas" #: config/avr/avr.c:400 #, gcc-internal-format msgid "GCC 4.4 is the last release with this switch" -msgstr "" +msgstr "GCC 4.4 är den sista utgåvan med denna flagga" #: config/avr/avr.c:401 #, gcc-internal-format msgid "use the -fno-jump-tables switch instead" -msgstr "" +msgstr "använd flaggan -fno-jump-tables istället" #: config/avr/avr.c:4626 #, gcc-internal-format @@ -25686,9 +25683,9 @@ msgid "%sregparm=%d%s is not between 0 and %d" msgstr "%sregparm=%d%s är inte mellan 0 och %d" #: config/i386/i386.c:2918 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%salign-loops%s is obsolete, use -falign-loops%s" -msgstr "%salign-loops%s är föråldrat, använd %salign-loops%s" +msgstr "%salign-loops%s är föråldrat, använd -falign-loops%s" #: config/i386/i386.c:2924 config/i386/i386.c:2939 config/i386/i386.c:2954 #, gcc-internal-format @@ -25696,14 +25693,14 @@ msgid "%salign-loops=%d%s is not between 0 and %d" msgstr "%salign-loops=%d%s är inte mellan 0 och %d" #: config/i386/i386.c:2933 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%salign-jumps%s is obsolete, use -falign-jumps%s" -msgstr "%salign-jumps%s är föråldrat, använd %salign-jumps%s" +msgstr "%salign-jumps%s är föråldrat, använd -falign-jumps%s" #: config/i386/i386.c:2948 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%salign-functions%s is obsolete, use -falign-functions%s" -msgstr "%salign-functions%s är föråldrat, använd %salign-functions%s" +msgstr "%salign-functions%s är föråldrat, använd -falign-functions%s" #: config/i386/i386.c:2983 #, gcc-internal-format @@ -25838,7 +25835,7 @@ msgstr "Anrop av %qT med attributet sseregparm utan SSE/SSE2 aktiverat" #: config/i386/i386.c:4722 #, gcc-internal-format msgid "ms_abi attribute requires -maccumulate-outgoing-args or subtarget optimization implying it" -msgstr "" +msgstr "attributet ms_abi kräver -maccumulate-outgoing-args eller optimering av undermålarkitektur som implicerar det" #: config/i386/i386.c:4840 #, gcc-internal-format @@ -25848,17 +25845,17 @@ msgstr "AVX-vektorargument utan AVX aktiverat ändrar ABI:et" #: config/i386/i386.c:5020 #, gcc-internal-format msgid "The ABI of passing struct with a flexible array member has changed in GCC 4.4" -msgstr "" +msgstr "ABI:et för att skicka en post med en flexibel vektormedlem har ändrats i GCC 4.4" #: config/i386/i386.c:5139 #, gcc-internal-format msgid "The ABI of passing union with long double has changed in GCC 4.4" -msgstr "" +msgstr "ABI:et för att skicka unioner med long double har ändrats i GCC 4.4" #: config/i386/i386.c:5254 #, gcc-internal-format msgid "The ABI of passing structure with complex float member has changed in GCC 4.4" -msgstr "" +msgstr "ABI:et för att skicka en post med complex float medlem har ändrats i GCC 4.4" #: config/i386/i386.c:5399 #, gcc-internal-format @@ -26068,14 +26065,14 @@ msgid "bad value %<%s%> for -mtls-size= switch" msgstr "felaktigt värde %<%s%> till flaggan -mtls-size=" #: config/ia64/ia64.c:5254 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "value %<%s%> for -mtune= switch is deprecated" -msgstr "felaktigt värde %<%s%> till flaggan -mtune=" +msgstr "värde %<%s%> till flaggan -mtune= bör undvikas" #: config/ia64/ia64.c:5256 #, gcc-internal-format msgid "GCC 4.4 is the last release with Itanium1 tuning support" -msgstr "" +msgstr "GCC 4.4 är den sista utgåvan med stöd för trimning av Itanium1" #: config/ia64/ia64.c:5263 #, gcc-internal-format @@ -27156,7 +27153,7 @@ msgstr "fel i omdeklaration av %q+D: dllimport:erad symbol har inte extern länkk #: config/sh/symbian.c:325 #, gcc-internal-format msgid "%s %q+D %s after being referenced with dllimport linkage" -msgstr "" +msgstr "\"%s\" %q+D \"%s\" efter att refererats med dllimport-länkningsklass" #: config/sh/symbian.c:891 cp/tree.c:2840 #, gcc-internal-format @@ -27500,42 +27497,42 @@ msgstr "anrop av %<(%T) (%A)%> är tvetydigt" #: cp/call.c:3327 #, gcc-internal-format msgid "%s for ternary %<operator?:%> in %<%E ? %E : %E%>" -msgstr "" +msgstr "\"%s\" för treställig %<operator?:%> i %<%E ? %E : %E%>" # Första "%s" blir några ord som beskriver ett problem. # Felrapporterat: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29917 #: cp/call.c:3333 #, gcc-internal-format msgid "%s for %<operator%s%> in %<%E%s%>" -msgstr "" +msgstr "\"%s\" för %<operator%s%> i %<%E%s%>" # Första "%s" blir några ord som beskriver ett problem. # Felrapporterat: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29917 #: cp/call.c:3337 #, gcc-internal-format msgid "%s for %<operator[]%> in %<%E[%E]%>" -msgstr "" +msgstr "\"%s\" för %<operator[]%> i %<%E[%E]%>" # Första "%s" blir några ord som beskriver ett problem. # Felrapporterat: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29917 #: cp/call.c:3342 #, gcc-internal-format msgid "%s for %qs in %<%s %E%>" -msgstr "" +msgstr "\"%s\" för %qs i %<%s %E%>" # Första "%s" blir några ord som beskriver ett problem. # Felrapporterat: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29917 #: cp/call.c:3347 #, gcc-internal-format msgid "%s for %<operator%s%> in %<%E %s %E%>" -msgstr "" +msgstr "\"%s\" för %<operator%s%> i %<%E %s %E%>" # Första "%s" blir några ord som beskriver ett problem. # Felrapporterat: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29917 #: cp/call.c:3350 #, gcc-internal-format msgid "%s for %<operator%s%> in %<%s%E%>" -msgstr "" +msgstr "\"%s\" för %<operator%s%> i %<%s%E%>" #: cp/call.c:3444 #, gcc-internal-format @@ -27623,9 +27620,9 @@ msgid "converting %<false%> to pointer type for argument %P of %qD" msgstr "konverterar %<false%> till pekartyp för argument %P till %qD" #: cp/call.c:4573 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "too many braces around initializer for %qT" -msgstr "klamrar saknas runt initierare för %qT" +msgstr "för många klamrar runt initierare för %qT" #: cp/call.c:4595 cp/cvt.c:217 #, gcc-internal-format @@ -27744,19 +27741,19 @@ msgid " because conversion sequence for the argument is better" msgstr " för att konverteringssekvensen för argumentet är bättre" #: cp/call.c:6899 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default argument mismatch in overload resolution" -msgstr "standardargument angivet i explicit specialisering" +msgstr "standardargument stämmer inte överens i upplösning av överlagring" #: cp/call.c:6902 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid " candidate 1: %q+#F" -msgstr "kandidat är: %+#D" +msgstr " kandidat 1: %q+#F" #: cp/call.c:6904 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid " candidate 2: %q+#F" -msgstr "kandidat är: %+#D" +msgstr " kandidat 2: %q+#F" #: cp/call.c:6942 #, gcc-internal-format @@ -28755,9 +28752,9 @@ msgid "cannot initialize %qT from %qT" msgstr "det går inte att initiera %qT från %qT" #: cp/decl.c:4437 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "name used in a GNU-style designated initializer for an array" -msgstr "namnet %qD använt i en designerad initierare i GNU-stil för en vektor" +msgstr "namn använt i en designerad initierare i GNU-stil för en vektor" #: cp/decl.c:4442 #, gcc-internal-format @@ -29425,9 +29422,9 @@ msgid "cannot declare pointer to %q#T member" msgstr "det går inte att deklarera pekare medlem av %q#T" #: cp/decl.c:8500 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "cannot declare %s to qualified function type %qT" -msgstr "det går inte att deklarera bitfält %qD med funktionstyp" +msgstr "det går inte att deklarera %s som en kvalificerad funktionstyp %qT" #: cp/decl.c:8537 #, gcc-internal-format @@ -29675,9 +29672,9 @@ msgid "%<inline%> specifier invalid for function %qs declared out of global scop msgstr "specificerare %<inline%> är ogiltig för funktionen %qs deklarerad utanför global räckvidd" #: cp/decl.c:9365 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%q#T is not a class or a namespace" -msgstr "%qT är inte en klass eller namnrymd" +msgstr "%q#T är inte en klass eller namnrymd" #: cp/decl.c:9373 #, gcc-internal-format @@ -29685,9 +29682,9 @@ msgid "virtual non-class function %qs" msgstr "virtuell icke klassfunktion %qs" #: cp/decl.c:9380 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%qs defined in a non-class scope" -msgstr "attributet %qE ignorerat typer som inte är klasser" +msgstr "%qs definierat utan att vara i klassräckvidd" #: cp/decl.c:9413 #, gcc-internal-format @@ -30023,9 +30020,9 @@ msgid "%<operator=%> should return a reference to %<*this%>" msgstr "%<operator=%> skall returnera en referens till %<*this%>" #: cp/decl.c:11874 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "invalid function declaration" -msgstr "ogiltig medlemsfunktionsdeklaration" +msgstr "ogiltig funktionsdeklaration" #: cp/decl.c:11958 #, gcc-internal-format @@ -30098,9 +30095,9 @@ msgid "Java method %qD has non-Java parameter type %qT" msgstr "Javametod %qD har typ %qT som inte är Javaparametertyp" #: cp/decl2.c:579 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "template parameter lists provided don't match the template parameters of %qD" -msgstr "mallparametrar stämmer inte med mallen" +msgstr "mallparametrerlistan som ges stämmer inte mallparametrarna till %qD" #: cp/decl2.c:647 #, gcc-internal-format @@ -30209,12 +30206,12 @@ msgstr "%<operator new%> tar typen %<size_t%> (%qT) som första parameter" #: cp/decl2.c:1452 #, gcc-internal-format msgid "%<operator delete%> must return type %qT" -msgstr "%<operator new%> måste returnera typ %qT" +msgstr "%<operator delete%> måste returnera typ %qT" #: cp/decl2.c:1461 #, gcc-internal-format msgid "%<operator delete%> takes type %qT as first parameter" -msgstr "%<operator new%> tar typen %qT som första parameter" +msgstr "%<operator delete%> tar typen %qT som första parameter" #: cp/decl2.c:2152 #, gcc-internal-format @@ -30416,9 +30413,9 @@ msgid "%J%qD should be initialized in the member initialization list" msgstr "%J%qD skall initieras i medlemsinitieringslistan" #: cp/init.c:454 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%Jvalue-initialization of %q#D, which has reference type" -msgstr "%Jstandardinitiering av %q#D, som har referenstyp" +msgstr "%Jvärdeinitiering av %q#D, som har referenstyp" #. TYPE_NEEDS_CONSTRUCTING can be set just because we have a #. vtable; still give this diagnostic. @@ -30578,9 +30575,9 @@ msgid "request for member %qD is ambiguous" msgstr "begäran av medlem %qD är tvetydig" #: cp/init.c:2136 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "non-constant array size in new, unable to verify length of initializer-list" -msgstr "ickekonstant vektorindex i initierare" +msgstr "ickekonstant vektorstorlek i new, kan inte verifiera längden på initierarlistan" #: cp/init.c:2145 #, gcc-internal-format @@ -30705,17 +30702,17 @@ msgstr "manglar typeof, använd decltype istället" #: cp/mangle.c:1903 #, gcc-internal-format msgid "mangling unknown fixed point type" -msgstr "" +msgstr "manglar okänd fixdecimaltyp" #: cp/mangle.c:2332 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "mangling %C" -msgstr "varning: " +msgstr "manglar %C" #: cp/mangle.c:2387 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "mangling new-expression" -msgstr "utelämnat ökningsuttryck" +msgstr "manglar new-uttryck" #: cp/mangle.c:2407 #, gcc-internal-format @@ -31154,9 +31151,9 @@ msgid "%Hunsupported non-standard concatenation of string literals" msgstr "%Hicke-standardsuffix på flyttalskonstant stöds inte" #: cp/parser.c:3154 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%Hfixed-point types not supported in C++" -msgstr "fixdecimaltyper stöds inte för denna målarkitektur" +msgstr "%Hfixdecimaltyper stöds inte i C++" #: cp/parser.c:3235 #, gcc-internal-format @@ -31404,9 +31401,9 @@ msgid "use %<%T::template %D%> to indicate that it is a template" msgstr "använd %<%T::template %D%> för att indikera att det är en mall" #: cp/parser.c:10483 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%Hexpected parameter pack before %<...%>" -msgstr "deklarationsspecificerare eller %<...%> förväntades" +msgstr "%Hparameterpaket förväntades före %<...%>" #: cp/parser.c:10893 #, gcc-internal-format @@ -32181,14 +32178,14 @@ msgid "%qE is not a valid template argument for type %qT because object %qD has msgstr "%qE är inte ett giltigt mallargument för typ %qT eftersom objekt %qD inte har extern länkklass" #: cp/pt.c:4578 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%qE is not a valid template argument for type %qT" -msgstr "%qE är inte ett giltigt mallargument för typen %qT eftersom det är en pekare" +msgstr "%qE är inte ett giltigt mallargument för typen %qT" #: cp/pt.c:4579 #, gcc-internal-format msgid "it must be the address of a function with external linkage" -msgstr "" +msgstr "det måste vara adressen till en funktion med extern lagringsklass" #: cp/pt.c:4593 #, gcc-internal-format @@ -32253,9 +32250,9 @@ msgstr " förväntade en mall av typen %qD, fick %qD" #. Not sure if this is reachable, but it doesn't hurt #. to be robust. #: cp/pt.c:5091 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "type mismatch in nontype parameter pack" -msgstr "typfel i komponentreferens" +msgstr "typer stämmer inte i icke-typs parameterpaket" #: cp/pt.c:5113 #, gcc-internal-format @@ -33076,7 +33073,7 @@ msgstr "%s mellan olika pekartyper %qT och %qT saknar en typkonvertering" #: cp/typeck.c:542 #, gcc-internal-format msgid "ISO C++ forbids %s between pointer of type %<void *%> and pointer-to-function" -msgstr "" +msgstr "ISO C++ förbjuder \"%s\" mellan pekare av typ %<void *%> och pekare till funktion" #: cp/typeck.c:603 #, gcc-internal-format @@ -33164,9 +33161,9 @@ msgid "invalid use of %qD" msgstr "ogiltigt användning av %qD" #: cp/typeck.c:2150 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "object type %qT does not match destructor name ~%qT" -msgstr "kvalificerad typ %qT matchar inte destruerarnamnet ~%qT" +msgstr "objekttyp %qT stämmer inte med destruerarnamnet ~%qT" #: cp/typeck.c:2158 #, gcc-internal-format @@ -33670,35 +33667,35 @@ msgstr "typen %qT är inte en bastyp för typen %qT" #: cp/typeck2.c:97 #, gcc-internal-format msgid "%s of read-only parameter %qD" -msgstr "" +msgstr "\"%s\" av endast läsbar parameter %qD" # %s blir olika ord, eller i vissa fall sekvens av ord. # Felrapporterat: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34836 #: cp/typeck2.c:102 #, gcc-internal-format msgid "%s of read-only reference %qD" -msgstr "" +msgstr "\"%s\" av endast läsbar referens %qD" # %s blir olika ord, eller i vissa fall sekvens av ord. # Felrapporterat: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34836 #: cp/typeck2.c:104 #, gcc-internal-format msgid "%s of read-only named return value %qD" -msgstr "" +msgstr "\"%s\" av endast läsbart namngivet returvärde %qD" # %s blir olika ord, eller i vissa fall sekvens av ord. # Felrapporterat: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34836 #: cp/typeck2.c:106 #, gcc-internal-format msgid "%s of function %qD" -msgstr "" +msgstr "\"%s\" av funktion %qD" # %s blir olika ord, eller i vissa fall sekvens av ord. # Felrapporterat: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34836 #: cp/typeck2.c:108 #, gcc-internal-format msgid "%s of read-only location %qE" -msgstr "" +msgstr "\"%s\" av endast läsbar plats %qE" #: cp/typeck2.c:288 #, gcc-internal-format @@ -33862,9 +33859,9 @@ msgid "pointer to member type %qT incompatible with object type %qT" msgstr "pekare-på-medlemstyp %qT är inkompatibel med objekttyp %qT" #: cp/typeck2.c:1450 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "invalid value-initialization of reference types" -msgstr "värdeinitiering av referens" +msgstr "ogiltig värdeinitiering av referenstyper" #: cp/typeck2.c:1637 #, gcc-internal-format @@ -34430,7 +34427,7 @@ msgstr "det går inte att använda ett objekt som parameter till en metod" #: objc/objc-act.c:6098 #, gcc-internal-format msgid "multiple %s named %<%c%s%> found" -msgstr "" +msgstr "multipla \"%s\" med namnet %<%c%s%> funna" #: objc/objc-act.c:6324 #, gcc-internal-format @@ -34650,65 +34647,12 @@ msgid "local declaration of %qs hides instance variable" msgstr "lokal deklaration av %qs döljer instansvariabel" #: ada/gcc-interface/misc.c:221 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "missing argument to \"-%s\"" -msgstr "argument saknas \"%s\"" +msgstr "argument saknas till \"-%s\"" +# Vissa felmeddelanden är roligare än andra! :-) #: ada/gcc-interface/misc.c:279 #, gcc-internal-format msgid "%<-gnat%> misspelled as %<-gant%>" -msgstr "" - -#~ msgid "Multiplier used for determining the double-queueing threshold" -#~ msgstr "Faktor som används för att avgöra tröskeln för dubbelköande" - -#~ msgid "Array PUT of intrinsic %s is too small (%i/%i) at %L" -#~ msgstr "Vektor-PUT av inbyggd %s är för liten (%i/%i) vid %L" - -#~ msgid "Different character lengths in pointer assignment at %L" -#~ msgstr "Olika teckenlängder i pekartilldelning vid %L" - -#~ msgid "Reference to ENTRY '%s' at %L is recursive, but procedure '%s' is not declared as RECURSIVE" -#~ msgstr "Referens till ENTRY \"%s\" vid %L är rekursiv, men procedur \"%s\" är inte deklarerad som RECURSIVE" - -#~ msgid "Add a directory for INCLUDE and MODULE searching" -#~ msgstr "Lägg till en katalog för INCLUDE- och MODULE-sökning" - -#~ msgid "Warn about implicit conversion" -#~ msgstr "Varna för implicita konverteringar" - -#~ msgid "Dump details about macro names and definitions during preprocessing" -#~ msgstr "Skriv ut detaljer om makronamn och definitioner under preprocessning" - -#~ msgid "Treat the input file as preprocessed" -#~ msgstr "Behandla indatafilen som redan preprocessad" - -#~ msgid "Set maximum alignment to 4" -#~ msgstr "Sätt maximal justering till 4" - -#~ msgid "Set maximum alignment to 8" -#~ msgstr "Sätt maximal justering till 8" - -#~ msgid "Warn about deprecated compiler features" -#~ msgstr "Varna för kompilatorfunktioner bör undvikas" - -#~ msgid "Enable OpenMP" -#~ msgstr "Aktivera OpenMP" - -#~ msgid "Warn on calls to these functions" -#~ msgstr "Varna vid arnop till dessa funktioner" - -#~ msgid "Use integrated register allocator." -#~ msgstr "Använd integrerad registerallokerare." - -#~ msgid "disallowed call to %qs" -#~ msgstr "otillåtet anrop till %qs" - -#~ msgid "GIMPLE register modified with BIT_FIELD_REF" -#~ msgstr "GIMPLE-register modifierat med BIT_FIELD_REF" - -#~ msgid "%Hlikely type-punning may break strict-aliasing rules: object %<%s%s%> of main type %qT is referenced at or around %s:%d and may be aliased to object %<%s%s%> of main type %qT which is referenced at or around %s:%d." -#~ msgstr "%Htrolig typstampning kan göra sönder regler för strikt aliasning: objekt %<%s%s%> av huvudtyp %qT refereras vid eller nära %s:%d och kan vara ett alias för objekt %<%s%s%> av huvudtyp %qT som refereras vid eller nära %s:%d." - -#~ msgid "mangling function-style cast with more than one argument" -#~ msgstr "manglar typkonvertering i funktionsstil med mer än ett argument" +msgstr "%<-gnat%> felstavat %<-gant%>" 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/system.h b/gcc/system.h index 51dcf54c1d8..7a9ca816693 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -1,6 +1,7 @@ /* Get common system includes and various definitions and declarations based on autoconf macros. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, + 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -46,6 +47,9 @@ along with GCC; see the file COPYING3. If not see #endif /* Use the unlocked open routines from libiberty. */ +#ifdef fopen /* fopen is a #define on VMS. */ +#undef fopen +#endif #define fopen(PATH,MODE) fopen_unlocked(PATH,MODE) #define fdopen(FILDES,MODE) fdopen_unlocked(FILDES,MODE) #define freopen(PATH,MODE,STREAM) freopen_unlocked(PATH,MODE,STREAM) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f9bbf626f92..c38a075b4ae 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,315 @@ +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 + * g++.dg/template/defarg13.C: New. + +2009-07-29 Richard Guenther <rguenther@suse.de> + + PR c++/40834 + * g++.dg/torture/pr40834.C: New testcase. + +2009-07-29 Michael Matz <matz@suse.de> + + PR middle-end/40830 + * gcc.dg/vect/vect-pre-interact.c: XFAIL for no_align targets. + +2009-07-28 Kaz Kojima <kkojima@gcc.gnu.org> + + * gfortran.dg/maxlocval_2.f90: Add -mieee for alpha*-*-* and + sh*-*-* targets. Skip on spu-*-* targets. + * gfortran.dg/maxlocval_4.f90: Likewise. + * gfortran.dg/minlocval_1.f90: Likewise. + * gfortran.dg/minlocval_4.f90: Likewise. + +2009-07-28 Jakub Jelinek <jakub@redhat.com> + + PR fortran/40878 + * gfortran.dg/gomp/pr40878-1.f90: New test. + * gfortran.dg/gomp/pr40878-2.f90: New test. + + PR testsuite/40891 + * gcc.dg/cdce1.c: Adjust note line number. + * gcc.dg/cdce2.c: Likewise. + +2009-07-28 Janus Weil <janus@gcc.gnu.org> + + PR fortran/40882 + * gfortran.dg/proc_ptr_comp_13.f90: New. + +2009-07-28 Jan Beulich <jbeulich@novell.com> + + * gcc.target/i386/avx-vtestpd-1.c: Add -DNEED_IEEE754_DOUBLE. + * gcc.target/i386/avx-vtestpd-2.c: Likewise. + * gcc.target/i386/avx-vtestpd-256-1.c: Likewise. + * gcc.target/i386/avx-vtestpd-256-2.c: Likewise. + * gcc.target/i386/avx-vtestpd-256-3.c: Likewise. + * gcc.target/i386/avx-vtestpd-3.c: Likewise. + * gcc.target/i386/avx-vtestps-1.c: Add -DNEED_IEEE754_FLOAT. + * gcc.target/i386/avx-vtestps-2.c: Likewise. + * gcc.target/i386/avx-vtestps-256-1.c: Likewise. + * gcc.target/i386/avx-vtestps-256-2.c: Likewise. + * gcc.target/i386/avx-vtestps-256-3.c: Likewise. + * gcc.target/i386/avx-vtestps-3.c: Likewise. + * gcc.target/i386/m128-check.h (union ieee754_float): Put into + #ifdef NEED_IEEE754_FLOAT conditional. + (union ieee754_double): Put into #ifdef NEED_IEEE754_DOUBLE + conditional. + +2009-07-28 Jan Beulich <jbeulich@novell.com> + + * g++.dg/ext/bitfield2.C: Add -mno-ms-bitfields for + i?86-*-netware. + * g++.dg/ext/bitfield3.C: Likewise. + * g++.dg/ext/bitfield4.C: Likewise. + * g++.dg/ext/bitfield5.C: Likewise. + * gcc.dg/bitfld-15.c: Likewise. + * gcc.dg/bitfld-16.c: Likewise. + * gcc.dg/bitfld-17.c: Likewise. + * gcc.dg/bitfld-18.c: Likewise. + * g++.old-deja/g++.jason/thunk2.C: Remove dg-bogus. + * gcc.dg/20010912-1.c: Likewise. + * gcc.dg/20021018-1.c: Likewise. + * gcc.dg/20030213-1.c: Likewise. + * gcc.dg/20030225-1.c: Likewise. + * gcc.dg/20030708-1.c: Likewise. + * gcc.dg/20050321-2.c: Likewise. + * gcc.dg/cdce1.c: Don't pass -lm for *-*-netware*. + * gcc.dg/cdce2.c: Likewise. + * gcc.target/i386/pr37248-2.c: Don't test on default_packet + targets. + * gcc.target/i386/pr37248-3.c: Likewise. + +2009-07-27 Janus Weil <janus@gcc.gnu.org> + + PR fortran/40848 + * gfortran.dg/altreturn_7.f90: New. + +2009-07-27 Simon Baldwin <simonb@google.com> + + PR testsuite/40829 + * gcc.dg/vect/no-scevccp-noreassoc-outer-2.c: Extended array 'a' + so that indexing no longer runs off array end. + +2009-07-27 Tobias Burnus <burnus@net-b.de> + + PR fortran/40851 + * gfortran.dg/derived_init_3.f90: New test. + 2009-07-26 Tobias Burnus <burnus@net-b.de> PR fortran/33197 diff --git a/gcc/testsuite/g++.dg/ext/bitfield2.C b/gcc/testsuite/g++.dg/ext/bitfield2.C index 303d82de267..3d89505e2ef 100644 --- a/gcc/testsuite/g++.dg/ext/bitfield2.C +++ b/gcc/testsuite/g++.dg/ext/bitfield2.C @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* Remove pedantic. Allow the GCC extension to use char for bitfields. */ /* { dg-options "" } */ +/* { dg-options "-mno-ms-bitfields" { target i?86-*-netware } } */ struct t { /* { dg-message "note: Offset of packed bit-field 't::b' has changed in GCC 4.4" "" { target pcc_bitfield_type_matters } } */ diff --git a/gcc/testsuite/g++.dg/ext/bitfield3.C b/gcc/testsuite/g++.dg/ext/bitfield3.C index 3b30cc9b002..0a89bdab1ff 100644 --- a/gcc/testsuite/g++.dg/ext/bitfield3.C +++ b/gcc/testsuite/g++.dg/ext/bitfield3.C @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-Wno-packed-bitfield-compat" } */ +/* { dg-options "-Wno-packed-bitfield-compat -mno-ms-bitfields" { target i?86-*-netware } } */ struct t { diff --git a/gcc/testsuite/g++.dg/ext/bitfield4.C b/gcc/testsuite/g++.dg/ext/bitfield4.C index 258b3338c23..f9858d78c0e 100644 --- a/gcc/testsuite/g++.dg/ext/bitfield4.C +++ b/gcc/testsuite/g++.dg/ext/bitfield4.C @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "" } */ +/* { dg-options "-mno-ms-bitfields" { target i?86-*-netware } } */ struct t { /* { dg-message "note: Offset of packed bit-field 't::b' has changed in GCC 4.4" "" { target pcc_bitfield_type_matters } } */ diff --git a/gcc/testsuite/g++.dg/ext/bitfield5.C b/gcc/testsuite/g++.dg/ext/bitfield5.C index 2cd8e7daa94..cb24c65d723 100644 --- a/gcc/testsuite/g++.dg/ext/bitfield5.C +++ b/gcc/testsuite/g++.dg/ext/bitfield5.C @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-Wno-packed-bitfield-compat" } */ +/* { dg-options "-Wno-packed-bitfield-compat -mno-ms-bitfields" { target i?86-*-netware } } */ struct t { diff --git a/gcc/testsuite/g++.dg/template/defarg13.C b/gcc/testsuite/g++.dg/template/defarg13.C new file mode 100644 index 00000000000..ba2980bfaea --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg13.C @@ -0,0 +1,19 @@ +// PR c++/14912 +// Bug: We were instantiating A<B> in order to compare it to the matching +// argument for C<B,B>, which fails. + +template <class T> +struct A +{ + typedef typename T::F F; +}; + +struct B { }; + +template <class T, class U = typename A<T>::F > +struct C +{ + typename T::F f; // { dg-error "no type" } +}; + +C<B, B> c; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/torture/pr40834.C b/gcc/testsuite/g++.dg/torture/pr40834.C new file mode 100644 index 00000000000..67d3028532a --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr40834.C @@ -0,0 +1,52 @@ +/* { dg-do run } */ + +extern "C" void abort (void); +class XalanDOMString +{ +public: + int y; +}; + +class XObject +{ +public: + const XalanDOMString& str() const { return x; } + XalanDOMString x; +}; + +class XObjectPtr +{ +public: + XObjectPtr(const XObjectPtr& theSource) + { + m_xobjectPtr = theSource.m_xobjectPtr; + } + const XObject* operator->() const + { + return m_xobjectPtr; + }; + XObjectPtr(XObject *p) { m_xobjectPtr = p; } + XObject* m_xobjectPtr; +}; + +class FunctionSubstringBefore +{ +public: + int execute( const XObjectPtr arg1) const + { + const XalanDOMString& theFirstString = arg1->str(); + return theFirstString.y; + } +}; + +int +main () +{ + XObject x; + XObjectPtr y (&x); + x.x.y = -1; + FunctionSubstringBefore z; + if (z.execute (y) != -1) + abort (); + return 0; +} 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/g++.old-deja/g++.jason/thunk2.C b/gcc/testsuite/g++.old-deja/g++.jason/thunk2.C index ad13022ddb3..88e06d8766f 100644 --- a/gcc/testsuite/g++.old-deja/g++.jason/thunk2.C +++ b/gcc/testsuite/g++.old-deja/g++.jason/thunk2.C @@ -1,6 +1,5 @@ // { dg-do run { target fpic } } // { dg-options "-fPIC" } -// { dg-bogus "\[Uu\]nresolved symbol .(_GLOBAL_OFFSET_TABLE_|\[_.A-Za-z\]\[_.0-9A-Za-z\]*@(PLT|GOT|GOTOFF))|\[Bb\]ad fixup at .DATA.:" "PIC unsupported" { xfail *-*-netware* } 0 } // { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } { "*" } { "" } } // Test that non-variadic function calls using thunks and PIC work right. 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/20010912-1.c b/gcc/testsuite/gcc.dg/20010912-1.c index f41f698745f..bf81e3bac8c 100644 --- a/gcc/testsuite/gcc.dg/20010912-1.c +++ b/gcc/testsuite/gcc.dg/20010912-1.c @@ -1,6 +1,5 @@ /* { dg-do run { target fpic } } */ /* { dg-options "-O2 -fpic" } */ -/* { dg-bogus "\[Uu\]nresolved symbol .(_GLOBAL_OFFSET_TABLE_|\[_.A-Za-z\]\[_.0-9A-Za-z\]*@(PLT|GOT|GOTOFF))" "PIC unsupported" { xfail *-*-netware* } 0 } */ extern void abort (void); extern void exit (int); diff --git a/gcc/testsuite/gcc.dg/20021018-1.c b/gcc/testsuite/gcc.dg/20021018-1.c index f1d296dc3f5..bbc88956683 100644 --- a/gcc/testsuite/gcc.dg/20021018-1.c +++ b/gcc/testsuite/gcc.dg/20021018-1.c @@ -1,6 +1,5 @@ /* { dg-do run { target fpic } } */ /* { dg-options "-O2 -fpic" } */ -/* { dg-bogus "\[Uu\]nresolved symbol .(_GLOBAL_OFFSET_TABLE_|\[_.A-Za-z\]\[_.0-9A-Za-z\]*@(PLT|GOT|GOTOFF))" "PIC unsupported" { xfail *-*-netware* } 0 } */ extern void abort (void); extern void exit (int); diff --git a/gcc/testsuite/gcc.dg/20030213-1.c b/gcc/testsuite/gcc.dg/20030213-1.c index a1cf180364f..35bfe22fe26 100644 --- a/gcc/testsuite/gcc.dg/20030213-1.c +++ b/gcc/testsuite/gcc.dg/20030213-1.c @@ -1,7 +1,6 @@ /* Testcase for http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01017.html */ /* { dg-do link { target fpic } } */ /* { dg-options "-O -fpic" } */ -/* { dg-bogus "\[Uu\]nresolved symbol .(_GLOBAL_OFFSET_TABLE_|\[_.A-Za-z\]\[_.0-9A-Za-z\]*@(PLT|GOT|GOTOFF))" "PIC unsupported" { xfail *-*-netware* } 0 } */ int *g; diff --git a/gcc/testsuite/gcc.dg/20030225-1.c b/gcc/testsuite/gcc.dg/20030225-1.c index 7f32fdcfee7..97a436b4ba1 100644 --- a/gcc/testsuite/gcc.dg/20030225-1.c +++ b/gcc/testsuite/gcc.dg/20030225-1.c @@ -5,7 +5,6 @@ and Benjamin Herrenschmidt <benh@kernel.crashing.org>. */ /* { dg-do run { target fpic } } */ /* { dg-options "-O2 -fPIC" } */ -/* { dg-bogus "\[Uu\]nresolved symbol .(_GLOBAL_OFFSET_TABLE_|\[_.A-Za-z\]\[_.0-9A-Za-z\]*@(PLT|GOT|GOTOFF))" "PIC unsupported" { xfail *-*-netware* } 0 } */ extern void exit (int); diff --git a/gcc/testsuite/gcc.dg/20030708-1.c b/gcc/testsuite/gcc.dg/20030708-1.c index 819ad126606..344bb4e18d4 100644 --- a/gcc/testsuite/gcc.dg/20030708-1.c +++ b/gcc/testsuite/gcc.dg/20030708-1.c @@ -1,7 +1,6 @@ /* PR c/11420 */ /* { dg-do link { target fpic } } */ /* { dg-options "-O2 -fpic" } */ -/* { dg-bogus "\[Uu\]nresolved symbol .(_GLOBAL_OFFSET_TABLE_|\[_.A-Za-z\]\[_.0-9A-Za-z\]*@(PLT|GOT|GOTOFF))" "PIC unsupported" { xfail *-*-netware* } 0 } */ void (* volatile fn) (void); static void foo (void) diff --git a/gcc/testsuite/gcc.dg/20050321-2.c b/gcc/testsuite/gcc.dg/20050321-2.c index 7f7e1c09dff..1c5575bde21 100644 --- a/gcc/testsuite/gcc.dg/20050321-2.c +++ b/gcc/testsuite/gcc.dg/20050321-2.c @@ -5,7 +5,6 @@ figure out branch to lab is too far. */ /* { dg-do link { target fpic } } */ /* { dg-options "-g1 -fpic" } */ -/* { dg-bogus "\[Uu\]nresolved symbol .(_GLOBAL_OFFSET_TABLE_|\[_.A-Za-z\]\[_.0-9A-Za-z\]*@(PLT|GOT|GOTOFF))" "PIC unsupported" { xfail *-*-netware* } 0 } */ /* { dg-require-effective-target int32plus } */ #define A(n) \ diff --git a/gcc/testsuite/gcc.dg/bitfld-15.c b/gcc/testsuite/gcc.dg/bitfld-15.c index 1c066bb4865..968290f06ae 100644 --- a/gcc/testsuite/gcc.dg/bitfld-15.c +++ b/gcc/testsuite/gcc.dg/bitfld-15.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* Remove pedantic. Allow the GCC extension to use char for bitfields. */ /* { dg-options "" } */ +/* { dg-options "-mno-ms-bitfields" { target i?86-*-netware } } */ struct t { diff --git a/gcc/testsuite/gcc.dg/bitfld-16.c b/gcc/testsuite/gcc.dg/bitfld-16.c index 3b30cc9b002..0a89bdab1ff 100644 --- a/gcc/testsuite/gcc.dg/bitfld-16.c +++ b/gcc/testsuite/gcc.dg/bitfld-16.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-Wno-packed-bitfield-compat" } */ +/* { dg-options "-Wno-packed-bitfield-compat -mno-ms-bitfields" { target i?86-*-netware } } */ struct t { diff --git a/gcc/testsuite/gcc.dg/bitfld-17.c b/gcc/testsuite/gcc.dg/bitfld-17.c index 32b9c1efd78..a0ad1ffeeac 100644 --- a/gcc/testsuite/gcc.dg/bitfld-17.c +++ b/gcc/testsuite/gcc.dg/bitfld-17.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "" } */ +/* { dg-options "-mno-ms-bitfields" { target i?86-*-netware } } */ struct t { diff --git a/gcc/testsuite/gcc.dg/bitfld-18.c b/gcc/testsuite/gcc.dg/bitfld-18.c index 2cd8e7daa94..cb24c65d723 100644 --- a/gcc/testsuite/gcc.dg/bitfld-18.c +++ b/gcc/testsuite/gcc.dg/bitfld-18.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-Wno-packed-bitfield-compat" } */ +/* { dg-options "-Wno-packed-bitfield-compat -mno-ms-bitfields" { target i?86-*-netware } } */ struct t { diff --git a/gcc/testsuite/gcc.dg/cdce1.c b/gcc/testsuite/gcc.dg/cdce1.c index 3bd35ecb786..58a3ddfb3a9 100644 --- a/gcc/testsuite/gcc.dg/cdce1.c +++ b/gcc/testsuite/gcc.dg/cdce1.c @@ -1,6 +1,7 @@ /* { dg-do run } */ /* { dg-options "-O2 -fmath-errno -fdump-tree-cdce-details -lm" } */ -/* { dg-final { scan-tree-dump "cdce1.c:16: note: function call is shrink-wrapped into error conditions\." "cdce" } } */ +/* { dg-options "-O2 -fmath-errno -fdump-tree-cdce-details" { target *-*-netware* } } */ +/* { dg-final { scan-tree-dump "cdce1.c:17: note: function call is shrink-wrapped into error conditions\." "cdce" } } */ /* { dg-final { cleanup-tree-dump "cdce" } } */ /* { dg-require-effective-target large_double } */ diff --git a/gcc/testsuite/gcc.dg/cdce2.c b/gcc/testsuite/gcc.dg/cdce2.c index a461ce7ac30..eebebaa2390 100644 --- a/gcc/testsuite/gcc.dg/cdce2.c +++ b/gcc/testsuite/gcc.dg/cdce2.c @@ -1,7 +1,8 @@ /* { dg-do run } */ /* { dg-skip-if "doubles are floats" { "avr-*-*" } { "*" } { "" } } */ /* { dg-options "-O2 -fmath-errno -fdump-tree-cdce-details -lm" } */ -/* { dg-final { scan-tree-dump "cdce2.c:16: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/ +/* { dg-options "-O2 -fmath-errno -fdump-tree-cdce-details" { target *-*-netware* } } */ +/* { dg-final { scan-tree-dump "cdce2.c:17: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/ /* { dg-final { cleanup-tree-dump "cdce" } } */ #include <stdlib.h> 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..5ec47fe8d07 --- /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 -fgraphite-force-parallel \ +-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/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/vect/no-scevccp-noreassoc-outer-2.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-2.c index 71897ff6a6f..9a4fa3f2538 100644 --- a/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-2.c +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-2.c @@ -4,7 +4,7 @@ #include "tree-vect.h" #define N 40 -int a[200*N]; +int a[200*N+N]; __attribute__ ((noinline)) void foo (){ diff --git a/gcc/testsuite/gcc.dg/vect/vect-pre-interact.c b/gcc/testsuite/gcc.dg/vect/vect-pre-interact.c index 38f078f1b81..096839f9c2d 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-pre-interact.c +++ b/gcc/testsuite/gcc.dg/vect/vect-pre-interact.c @@ -12,5 +12,5 @@ void foo (void) res[i] = data[i] + data[i + 1]; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ /* { 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/i386/avx-vtestpd-1.c b/gcc/testsuite/gcc.target/i386/avx-vtestpd-1.c index 3bfecf916e1..6b52d786baa 100644 --- a/gcc/testsuite/gcc.target/i386/avx-vtestpd-1.c +++ b/gcc/testsuite/gcc.target/i386/avx-vtestpd-1.c @@ -1,6 +1,8 @@ /* { dg-do run } */ /* { dg-require-effective-target avx } */ -/* { dg-options "-O2 -mavx" } */ +/* { dg-options "-O2 -mavx -DNEED_IEEE754_DOUBLE" } */ +/* { dg-warning "attribute ignored" "" { target default_packed } 164 } */ +/* { dg-message " from " "include chain" { target default_packed } 0 } */ #include "avx-check.h" diff --git a/gcc/testsuite/gcc.target/i386/avx-vtestpd-2.c b/gcc/testsuite/gcc.target/i386/avx-vtestpd-2.c index cb79b24d14c..57dfeeb7d20 100644 --- a/gcc/testsuite/gcc.target/i386/avx-vtestpd-2.c +++ b/gcc/testsuite/gcc.target/i386/avx-vtestpd-2.c @@ -1,6 +1,8 @@ /* { dg-do run } */ /* { dg-require-effective-target avx } */ -/* { dg-options "-O2 -mavx" } */ +/* { dg-options "-O2 -mavx -DNEED_IEEE754_DOUBLE" } */ +/* { dg-warning "attribute ignored" "" { target default_packed } 164 } */ +/* { dg-message " from " "include chain" { target default_packed } 0 } */ #include "avx-check.h" diff --git a/gcc/testsuite/gcc.target/i386/avx-vtestpd-256-1.c b/gcc/testsuite/gcc.target/i386/avx-vtestpd-256-1.c index d7d491981e6..050f140f70b 100644 --- a/gcc/testsuite/gcc.target/i386/avx-vtestpd-256-1.c +++ b/gcc/testsuite/gcc.target/i386/avx-vtestpd-256-1.c @@ -1,6 +1,8 @@ /* { dg-do run } */ /* { dg-require-effective-target avx } */ -/* { dg-options "-O2 -mavx" } */ +/* { dg-options "-O2 -mavx -DNEED_IEEE754_DOUBLE" } */ +/* { dg-warning "attribute ignored" "" { target default_packed } 164 } */ +/* { dg-message " from " "include chain" { target default_packed } 0 } */ #include "avx-check.h" diff --git a/gcc/testsuite/gcc.target/i386/avx-vtestpd-256-2.c b/gcc/testsuite/gcc.target/i386/avx-vtestpd-256-2.c index 5b61c071e05..0954f1dd802 100644 --- a/gcc/testsuite/gcc.target/i386/avx-vtestpd-256-2.c +++ b/gcc/testsuite/gcc.target/i386/avx-vtestpd-256-2.c @@ -1,6 +1,8 @@ /* { dg-do run } */ /* { dg-require-effective-target avx } */ -/* { dg-options "-O2 -mavx" } */ +/* { dg-options "-O2 -mavx -DNEED_IEEE754_DOUBLE" } */ +/* { dg-warning "attribute ignored" "" { target default_packed } 164 } */ +/* { dg-message " from " "include chain" { target default_packed } 0 } */ #include "avx-check.h" diff --git a/gcc/testsuite/gcc.target/i386/avx-vtestpd-256-3.c b/gcc/testsuite/gcc.target/i386/avx-vtestpd-256-3.c index 747107895c8..8a6e32e4147 100644 --- a/gcc/testsuite/gcc.target/i386/avx-vtestpd-256-3.c +++ b/gcc/testsuite/gcc.target/i386/avx-vtestpd-256-3.c @@ -1,6 +1,8 @@ /* { dg-do run } */ /* { dg-require-effective-target avx } */ -/* { dg-options "-O2 -mavx" } */ +/* { dg-options "-O2 -mavx -DNEED_IEEE754_DOUBLE" } */ +/* { dg-warning "attribute ignored" "" { target default_packed } 164 } */ +/* { dg-message " from " "include chain" { target default_packed } 0 } */ #include "avx-check.h" diff --git a/gcc/testsuite/gcc.target/i386/avx-vtestpd-3.c b/gcc/testsuite/gcc.target/i386/avx-vtestpd-3.c index 609c825f2ef..74c5dc868aa 100644 --- a/gcc/testsuite/gcc.target/i386/avx-vtestpd-3.c +++ b/gcc/testsuite/gcc.target/i386/avx-vtestpd-3.c @@ -1,6 +1,8 @@ /* { dg-do run } */ /* { dg-require-effective-target avx } */ -/* { dg-options "-O2 -mavx" } */ +/* { dg-options "-O2 -mavx -DNEED_IEEE754_DOUBLE" } */ +/* { dg-warning "attribute ignored" "" { target default_packed } 164 } */ +/* { dg-message " from " "include chain" { target default_packed } 0 } */ #include "avx-check.h" diff --git a/gcc/testsuite/gcc.target/i386/avx-vtestps-1.c b/gcc/testsuite/gcc.target/i386/avx-vtestps-1.c index bc22dc4153e..fb0c802fb2e 100644 --- a/gcc/testsuite/gcc.target/i386/avx-vtestps-1.c +++ b/gcc/testsuite/gcc.target/i386/avx-vtestps-1.c @@ -1,6 +1,8 @@ /* { dg-do run } */ /* { dg-require-effective-target avx } */ -/* { dg-options "-O2 -mavx" } */ +/* { dg-options "-O2 -mavx -DNEED_IEEE754_FLOAT" } */ +/* { dg-warning "attribute ignored" "" { target default_packed } 150 } */ +/* { dg-message " from " "include chain" { target default_packed } 0 } */ #include "avx-check.h" diff --git a/gcc/testsuite/gcc.target/i386/avx-vtestps-2.c b/gcc/testsuite/gcc.target/i386/avx-vtestps-2.c index 2dd45d90180..7482dae4ecd 100644 --- a/gcc/testsuite/gcc.target/i386/avx-vtestps-2.c +++ b/gcc/testsuite/gcc.target/i386/avx-vtestps-2.c @@ -1,6 +1,8 @@ /* { dg-do run } */ /* { dg-require-effective-target avx } */ -/* { dg-options "-O2 -mavx" } */ +/* { dg-options "-O2 -mavx -DNEED_IEEE754_FLOAT" } */ +/* { dg-warning "attribute ignored" "" { target default_packed } 150 } */ +/* { dg-message " from " "include chain" { target default_packed } 0 } */ #include "avx-check.h" diff --git a/gcc/testsuite/gcc.target/i386/avx-vtestps-256-1.c b/gcc/testsuite/gcc.target/i386/avx-vtestps-256-1.c index a1ebd66b852..6362c418334 100644 --- a/gcc/testsuite/gcc.target/i386/avx-vtestps-256-1.c +++ b/gcc/testsuite/gcc.target/i386/avx-vtestps-256-1.c @@ -1,6 +1,8 @@ /* { dg-do run } */ /* { dg-require-effective-target avx } */ -/* { dg-options "-O2 -mavx" } */ +/* { dg-options "-O2 -mavx -DNEED_IEEE754_FLOAT" } */ +/* { dg-warning "attribute ignored" "" { target default_packed } 150 } */ +/* { dg-message " from " "include chain" { target default_packed } 0 } */ #include "avx-check.h" diff --git a/gcc/testsuite/gcc.target/i386/avx-vtestps-256-2.c b/gcc/testsuite/gcc.target/i386/avx-vtestps-256-2.c index b5c62513911..de23ab2e930 100644 --- a/gcc/testsuite/gcc.target/i386/avx-vtestps-256-2.c +++ b/gcc/testsuite/gcc.target/i386/avx-vtestps-256-2.c @@ -1,6 +1,8 @@ /* { dg-do run } */ /* { dg-require-effective-target avx } */ -/* { dg-options "-O2 -mavx" } */ +/* { dg-options "-O2 -mavx -DNEED_IEEE754_FLOAT" } */ +/* { dg-warning "attribute ignored" "" { target default_packed } 150 } */ +/* { dg-message " from " "include chain" { target default_packed } 0 } */ #include "avx-check.h" diff --git a/gcc/testsuite/gcc.target/i386/avx-vtestps-256-3.c b/gcc/testsuite/gcc.target/i386/avx-vtestps-256-3.c index ef10361c2b9..717e5bb2836 100644 --- a/gcc/testsuite/gcc.target/i386/avx-vtestps-256-3.c +++ b/gcc/testsuite/gcc.target/i386/avx-vtestps-256-3.c @@ -1,6 +1,8 @@ /* { dg-do run } */ /* { dg-require-effective-target avx } */ -/* { dg-options "-O2 -mavx" } */ +/* { dg-options "-O2 -mavx -DNEED_IEEE754_FLOAT" } */ +/* { dg-warning "attribute ignored" "" { target default_packed } 150 } */ +/* { dg-message " from " "include chain" { target default_packed } 0 } */ #include "avx-check.h" diff --git a/gcc/testsuite/gcc.target/i386/avx-vtestps-3.c b/gcc/testsuite/gcc.target/i386/avx-vtestps-3.c index e69b9466879..61f58a6b3c7 100644 --- a/gcc/testsuite/gcc.target/i386/avx-vtestps-3.c +++ b/gcc/testsuite/gcc.target/i386/avx-vtestps-3.c @@ -1,6 +1,8 @@ /* { dg-do run } */ /* { dg-require-effective-target avx } */ -/* { dg-options "-O2 -mavx" } */ +/* { dg-options "-O2 -mavx -DNEED_IEEE754_FLOAT" } */ +/* { dg-warning "attribute ignored" "" { target default_packed } 150 } */ +/* { dg-message " from " "include chain" { target default_packed } 0 } */ #include "avx-check.h" diff --git a/gcc/testsuite/gcc.target/i386/m128-check.h b/gcc/testsuite/gcc.target/i386/m128-check.h index 071381fd25c..4e2deecb172 100644 --- a/gcc/testsuite/gcc.target/i386/m128-check.h +++ b/gcc/testsuite/gcc.target/i386/m128-check.h @@ -138,6 +138,7 @@ checkV##ARRAY (const TYPE *v, const TYPE *e, int n) \ CHECK_FP_ARRAY (d, double, ESP_DOUBLE, "%f") CHECK_FP_ARRAY (f, float, ESP_FLOAT, "%f") +#ifdef NEED_IEEE754_FLOAT union ieee754_float { float d; @@ -148,7 +149,9 @@ union ieee754_float unsigned sign : 1; } bits __attribute__((packed)); }; +#endif +#ifdef NEED_IEEE754_DOUBLE union ieee754_double { double d; @@ -160,3 +163,4 @@ union ieee754_double unsigned sign : 1; } bits __attribute__((packed)); }; +#endif diff --git a/gcc/testsuite/gcc.target/i386/pr37248-2.c b/gcc/testsuite/gcc.target/i386/pr37248-2.c index 0265a8ac64f..3ea4d669393 100644 --- a/gcc/testsuite/gcc.target/i386/pr37248-2.c +++ b/gcc/testsuite/gcc.target/i386/pr37248-2.c @@ -1,5 +1,5 @@ /* PR middle-end/37248 */ -/* { dg-do compile } */ +/* { dg-do compile { target { ! default_packed } } } */ /* { dg-options "-O2 -fdump-tree-optimized" } */ struct S diff --git a/gcc/testsuite/gcc.target/i386/pr37248-3.c b/gcc/testsuite/gcc.target/i386/pr37248-3.c index 309184ba045..60ef716963a 100644 --- a/gcc/testsuite/gcc.target/i386/pr37248-3.c +++ b/gcc/testsuite/gcc.target/i386/pr37248-3.c @@ -1,6 +1,6 @@ /* PR middle-end/37248 */ -/* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-do compile { target { ! default_packed } } } */ +/* { dg-options "-O2 -fdump-tree-optimized -mno-ms-bitfields" } */ struct S { 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/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/altreturn_7.f90 b/gcc/testsuite/gfortran.dg/altreturn_7.f90 new file mode 100644 index 00000000000..6eb0c78bde7 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/altreturn_7.f90 @@ -0,0 +1,34 @@ +! { dg-do compile } +! +! PR 40848: [4.5 Regression] ICE with alternate returns +! +! Contributed by Joost VandeVondele <jv244@cam.ac.uk> + +MODULE TT + +INTERFACE M + MODULE PROCEDURE M1,M2 +END INTERFACE + +CONTAINS + + SUBROUTINE M1(I,*) + INTEGER :: I + RETURN 1 + END SUBROUTINE + + SUBROUTINE M2(I,J) + INTEGER :: I,J + END SUBROUTINE + +END MODULE + + + USE TT + CALL M(1,*2) + CALL ABORT() +2 CONTINUE +END + +! { dg-final { cleanup-modules "tt" } } + diff --git a/gcc/testsuite/gfortran.dg/derived_init_3.f90 b/gcc/testsuite/gfortran.dg/derived_init_3.f90 new file mode 100644 index 00000000000..a1c4a0c7e0d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/derived_init_3.f90 @@ -0,0 +1,34 @@ +! { dg-do run } +! +! PR fortran/40851 +! +! Make sure the an INTENT(OUT) dummy is not initialized +! when it is a pointer. +! +! Contributed by Juergen Reuter <juergen.reuter@desy.de>. +! +program main + + type :: string + character,dimension(:),allocatable :: chars + end type string + + type :: string_container + type(string) :: string + end type string_container + + type(string_container), target :: tgt + type(string_container), pointer :: ptr + + ptr => tgt + call set_ptr (ptr) + if (associated(ptr)) call abort() + +contains + + subroutine set_ptr (ptr) + type(string_container), pointer, intent(out) :: ptr + ptr => null () + end subroutine set_ptr + +end program main diff --git a/gcc/testsuite/gfortran.dg/gomp/pr40878-1.f90 b/gcc/testsuite/gfortran.dg/gomp/pr40878-1.f90 new file mode 100644 index 00000000000..86202ab5d0e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr40878-1.f90 @@ -0,0 +1,63 @@ +! PR fortran/40878 +! { dg-do compile } +! { dg-options "-fopenmp" } + +subroutine test1 + integer :: j, k + integer :: m = 2 +!$omp parallel do collapse(m) schedule (static,1) ! { dg-error "Constant expression required" } + do k = 1, 2 + do j = 1, 6 + enddo + enddo +!$omp end parallel do +end +subroutine test2 + integer :: j, k + integer :: m + m = 2 +!$omp parallel do collapse(m) schedule (static,1) ! { dg-error "Constant expression required" } + do k = 1, 2 + do j = 1, 6 + enddo + enddo +!$omp end parallel do +end +subroutine test3 + integer :: j, k + integer, parameter :: m = 0 +!$omp parallel do collapse(m) schedule (static,1) ! { dg-error "not constant positive integer" } + do k = 1, 2 + do j = 1, 6 + enddo + enddo +!$omp end parallel do +end +subroutine test4 + integer :: j, k + integer, parameter :: m = -2 +!$omp parallel do collapse(m) schedule (static,1) ! { dg-error "not constant positive integer" } + do k = 1, 2 + do j = 1, 6 + enddo + enddo +!$omp end parallel do +end +subroutine test5 + integer :: j, k +!$omp parallel do collapse(0) schedule (static,1) ! { dg-error "not constant positive integer" } + do k = 1, 2 + do j = 1, 6 + enddo + enddo +!$omp end parallel do +end +subroutine test6 + integer :: j, k +!$omp parallel do collapse(-1) schedule (static,1) ! { dg-error "not constant positive integer" } + do k = 1, 2 + do j = 1, 6 + enddo + enddo +!$omp end parallel do +end diff --git a/gcc/testsuite/gfortran.dg/gomp/pr40878-2.f90 b/gcc/testsuite/gfortran.dg/gomp/pr40878-2.f90 new file mode 100644 index 00000000000..a118aa86025 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr40878-2.f90 @@ -0,0 +1,23 @@ +! PR fortran/40878 +! { dg-do compile } +! { dg-options "-fopenmp" } + +subroutine test1 + integer :: j, k + integer, parameter :: m = 2 +!$omp parallel do collapse(m) schedule (static,1) + do k = 1, 2 + do j = 1, 6 + enddo + enddo +!$omp end parallel do +end +subroutine test2 + integer :: j, k +!$omp parallel do collapse(2) schedule (static,1) + do k = 1, 2 + do j = 1, 6 + enddo + enddo +!$omp end parallel do +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/maxlocval_2.f90 b/gcc/testsuite/gfortran.dg/maxlocval_2.f90 index 82f917a9bc1..afbfee030fe 100644 --- a/gcc/testsuite/gfortran.dg/maxlocval_2.f90 +++ b/gcc/testsuite/gfortran.dg/maxlocval_2.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-mieee" { target alpha*-*-* sh*-*-* } } +! { dg-skip-if "NaN not supported" { spu-*-* } { "*" } { "" } } real :: a(3), nan, minf, pinf real, allocatable :: c(:) logical :: l diff --git a/gcc/testsuite/gfortran.dg/maxlocval_4.f90 b/gcc/testsuite/gfortran.dg/maxlocval_4.f90 index 408b08d6fad..8edf5357c31 100644 --- a/gcc/testsuite/gfortran.dg/maxlocval_4.f90 +++ b/gcc/testsuite/gfortran.dg/maxlocval_4.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-mieee" { target alpha*-*-* sh*-*-* } } +! { dg-skip-if "NaN not supported" { spu-*-* } { "*" } { "" } } real :: a(3,3), b(3), nan, minf, pinf, h logical :: l, l2 logical :: l3(3,3), l4(3,3), l5(3,3) diff --git a/gcc/testsuite/gfortran.dg/minlocval_1.f90 b/gcc/testsuite/gfortran.dg/minlocval_1.f90 index f821e54bd68..b66499afca9 100644 --- a/gcc/testsuite/gfortran.dg/minlocval_1.f90 +++ b/gcc/testsuite/gfortran.dg/minlocval_1.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-mieee" { target alpha*-*-* sh*-*-* } } +! { dg-skip-if "NaN not supported" { spu-*-* } { "*" } { "" } } real :: a(3), nan, minf, pinf real, allocatable :: c(:) logical :: l diff --git a/gcc/testsuite/gfortran.dg/minlocval_4.f90 b/gcc/testsuite/gfortran.dg/minlocval_4.f90 index 1e72ba8e2a9..5332e823a7e 100644 --- a/gcc/testsuite/gfortran.dg/minlocval_4.f90 +++ b/gcc/testsuite/gfortran.dg/minlocval_4.f90 @@ -1,4 +1,6 @@ ! { dg-do run } +! { dg-options "-mieee" { target alpha*-*-* sh*-*-* } } +! { dg-skip-if "NaN not supported" { spu-*-* } { "*" } { "" } } real :: a(3,3), b(3), nan, minf, pinf, h logical :: l, l2 logical :: l3(3,3), l4(3,3), l5(3,3) 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/proc_ptr_comp_13.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_comp_13.f90 new file mode 100644 index 00000000000..45ffa1e1274 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/proc_ptr_comp_13.f90 @@ -0,0 +1,35 @@ +! { dg-do run } +! +! PR 40882: [F03] infinite recursion in gfc_get_derived_type with PPC returning derived type +! +! Contributed by Janus Weil <janus@gcc.gnu.org> + +implicit none + +type :: t + integer :: data + procedure(foo), pointer, nopass :: ppc +end type + +type(t) :: o,o2 + +o%data = 1 +o%ppc => foo + +o2 = o%ppc() + +if (o%data /= 1) call abort() +if (o2%data /= 5) call abort() +if (.not. associated(o%ppc)) call abort() +if (associated(o2%ppc)) call abort() + +contains + + function foo() + type(t) :: foo + foo%data = 5 + foo%ppc => NULL() + end function + +end + 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 aec45283ee4..15299ee68d2 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1820,7 +1820,8 @@ process_options (void) || flag_loop_block || flag_loop_interchange || flag_loop_strip_mine - || flag_graphite_identity) + || flag_graphite_identity + || flag_graphite_force_parallel) sorry ("Graphite loop optimizations cannot be used"); #endif @@ -2065,7 +2066,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 49345c2535b..a6097edf3fe 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)); } } 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 cec5ed7a13a..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); @@ -746,7 +747,7 @@ unsigned int tree_unroll_loops_completely (bool, bool); unsigned int tree_ssa_prefetch_arrays (void); void tree_ssa_iv_optimize (void); unsigned tree_predictive_commoning (void); -tree canonicalize_loop_ivs (struct loop *, htab_t, tree *); +tree canonicalize_loop_ivs (struct loop *, tree *); bool parallelize_loops (void); bool loop_only_exit_p (const struct loop *, const_edge); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 605f91ef1a9..f79ba758088 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1496,67 +1496,69 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, callgraph edges and update or duplicate them. */ if (is_gimple_call (stmt)) { - struct cgraph_edge *edge = cgraph_edge (id->src_node, orig_stmt); + struct cgraph_edge *edge; int flags; switch (id->transform_call_graph_edges) { - case CB_CGE_DUPLICATE: - if (edge) - cgraph_clone_edge (edge, id->dst_node, stmt, - REG_BR_PROB_BASE, 1, - edge->frequency, true); - break; - - case CB_CGE_MOVE_CLONES: - cgraph_set_call_stmt_including_clones (id->dst_node, orig_stmt, stmt); - break; - - case CB_CGE_MOVE: - if (edge) - cgraph_set_call_stmt (edge, stmt); - break; - - default: - gcc_unreachable (); + case CB_CGE_DUPLICATE: + edge = cgraph_edge (id->src_node, orig_stmt); + if (edge) + edge = cgraph_clone_edge (edge, id->dst_node, stmt, + REG_BR_PROB_BASE, 1, + edge->frequency, true); + break; + + case CB_CGE_MOVE_CLONES: + cgraph_set_call_stmt_including_clones (id->dst_node, + orig_stmt, stmt); + edge = cgraph_edge (id->dst_node, stmt); + break; + + case CB_CGE_MOVE: + edge = cgraph_edge (id->dst_node, orig_stmt); + if (edge) + cgraph_set_call_stmt (edge, stmt); + break; + + default: + gcc_unreachable (); } - edge = cgraph_edge (id->src_node, orig_stmt); - /* Constant propagation on argument done during inlining - may create new direct call. Produce an edge for it. */ - if ((!edge - || (edge->indirect_call - && id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)) - && is_gimple_call (stmt) - && (fn = gimple_call_fndecl (stmt)) != NULL) - { - struct cgraph_node *dest = cgraph_node (fn); - - /* We have missing edge in the callgraph. This can happen in one case - where previous inlining turned indirect call into direct call by - constant propagating arguments. In all other cases we hit a bug - (incorrect node sharing is most common reason for missing edges. */ - gcc_assert (dest->needed || !dest->analyzed); - if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES) - cgraph_create_edge_including_clones (id->dst_node, dest, stmt, - bb->count, - compute_call_stmt_bb_frequency (id->dst_node->decl, bb), - bb->loop_depth, - CIF_ORIGINALLY_INDIRECT_CALL); - else - cgraph_create_edge (id->dst_node, dest, stmt, - bb->count, CGRAPH_FREQ_BASE, - bb->loop_depth)->inline_failed - = CIF_ORIGINALLY_INDIRECT_CALL; - if (dump_file) - { - fprintf (dump_file, "Created new direct edge to %s", - cgraph_node_name (dest)); - } - } + /* Constant propagation on argument done during inlining + may create new direct call. Produce an edge for it. */ + if ((!edge + || (edge->indirect_call + && id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)) + && is_gimple_call (stmt) + && (fn = gimple_call_fndecl (stmt)) != NULL) + { + struct cgraph_node *dest = cgraph_node (fn); + + /* We have missing edge in the callgraph. This can happen + when previous inlining turned an indirect call into a + direct call by constant propagating arguments. In all + other cases we hit a bug (incorrect node sharing is the + most common reason for missing edges). */ + gcc_assert (dest->needed || !dest->analyzed); + if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES) + cgraph_create_edge_including_clones + (id->dst_node, dest, stmt, bb->count, + compute_call_stmt_bb_frequency (id->dst_node->decl, bb), + bb->loop_depth, CIF_ORIGINALLY_INDIRECT_CALL); + else + cgraph_create_edge (id->dst_node, dest, stmt, + bb->count, CGRAPH_FREQ_BASE, + bb->loop_depth)->inline_failed + = CIF_ORIGINALLY_INDIRECT_CALL; + if (dump_file) + { + fprintf (dump_file, "Created new direct edge to %s", + cgraph_node_name (dest)); + } + } flags = gimple_call_flags (stmt); - if (flags & ECF_MAY_BE_ALLOCA) cfun->calls_alloca = true; if (flags & ECF_RETURNS_TWICE) @@ -1826,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..696c7259eed 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); } }); } @@ -537,6 +582,7 @@ static void elim_create (elim_graph g, int T) { int P, S; + source_location locus; if (elim_unvisited_predecessor (g, T)) { @@ -544,23 +590,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 +620,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 +657,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 +1041,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 28c96a26f59..9acf0ff75f0 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -241,175 +241,22 @@ name_to_copy_elt_hash (const void *aa) return (hashval_t) a->version; } -/* Returns true if the iterations of LOOP are independent on each other (that - is, if we can execute them in parallel), and if LOOP satisfies other - conditions that we need to be able to parallelize it. Description of number - of iterations is stored to NITER. Reduction analysis is done, if - reductions are found, they are inserted to the REDUCTION_LIST. */ + +/* Data dependency analysis. Returns true if the iterations of LOOP + are independent on each other (that is, if we can execute them + in parallel). */ static bool -loop_parallel_p (struct loop *loop, htab_t reduction_list, - struct tree_niter_desc *niter) +loop_parallel_p (struct loop *loop) { - edge exit = single_dom_exit (loop); VEC (ddr_p, heap) * dependence_relations; VEC (data_reference_p, heap) *datarefs; lambda_trans_matrix trans; bool ret = false; - gimple_stmt_iterator gsi; - loop_vec_info simple_loop_info; - - /* Only consider innermost loops with just one exit. The innermost-loop - restriction is not necessary, but it makes things simpler. */ - if (loop->inner || !exit) - return false; if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "\nConsidering loop %d\n", loop->num); - /* We need to know # of iterations, and there should be no uses of values - defined inside loop outside of it, unless the values are invariants of - the loop. */ - if (!number_of_iterations_exit (loop, exit, niter, false)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " FAILED: number of iterations not known\n"); - return false; - } - - vect_dump = NULL; - simple_loop_info = vect_analyze_loop_form (loop); - - for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple phi = gsi_stmt (gsi); - gimple reduc_stmt = NULL; - bool dummy; - - /* ??? TODO: Change this into a generic function that - recognizes reductions. */ - if (!is_gimple_reg (PHI_RESULT (phi))) - continue; - if (simple_loop_info) - reduc_stmt = vect_is_simple_reduction (simple_loop_info, phi, true, - &dummy); - - /* Create a reduction_info struct, initialize it and insert it to - the reduction list. */ - - if (reduc_stmt) - { - PTR *slot; - struct reduction_info *new_reduction; - - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, - "Detected reduction. reduction stmt is: \n"); - print_gimple_stmt (dump_file, reduc_stmt, 0, 0); - fprintf (dump_file, "\n"); - } - - new_reduction = XCNEW (struct reduction_info); - - new_reduction->reduc_stmt = reduc_stmt; - new_reduction->reduc_phi = phi; - new_reduction->reduction_code = gimple_assign_rhs_code (reduc_stmt); - slot = htab_find_slot (reduction_list, new_reduction, INSERT); - *slot = new_reduction; - } - } - - /* Get rid of the information created by the vectorizer functions. */ - destroy_loop_vec_info (simple_loop_info, true); - - for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple phi = gsi_stmt (gsi); - struct reduction_info *red; - imm_use_iterator imm_iter; - use_operand_p use_p; - gimple reduc_phi; - tree val = PHI_ARG_DEF_FROM_EDGE (phi, exit); - - if (is_gimple_reg (val)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "phi is "); - print_gimple_stmt (dump_file, phi, 0, 0); - fprintf (dump_file, "arg of phi to exit: value "); - print_generic_expr (dump_file, val, 0); - fprintf (dump_file, " used outside loop\n"); - fprintf (dump_file, - " checking if it a part of reduction pattern: \n"); - } - if (htab_elements (reduction_list) == 0) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - " FAILED: it is not a part of reduction.\n"); - return false; - } - reduc_phi = NULL; - FOR_EACH_IMM_USE_FAST (use_p, imm_iter, val) - { - if (flow_bb_inside_loop_p (loop, gimple_bb (USE_STMT (use_p)))) - { - reduc_phi = USE_STMT (use_p); - break; - } - } - red = reduction_phi (reduction_list, reduc_phi); - if (red == NULL) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - " FAILED: it is not a part of reduction.\n"); - return false; - } - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "reduction phi is "); - print_gimple_stmt (dump_file, red->reduc_phi, 0, 0); - fprintf (dump_file, "reduction stmt is "); - print_gimple_stmt (dump_file, red->reduc_stmt, 0, 0); - } - - } - } - - /* The iterations of the loop may communicate only through bivs whose - iteration space can be distributed efficiently. */ - for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple phi = gsi_stmt (gsi); - tree def = PHI_RESULT (phi); - affine_iv iv; - - if (is_gimple_reg (def) && !simple_iv (loop, loop, def, &iv, true)) - { - struct reduction_info *red; - - red = reduction_phi (reduction_list, phi); - if (red == NULL) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - " FAILED: scalar dependency between iterations\n"); - return false; - } - } - } - - /* We need to version the loop to verify assumptions in runtime. */ - if (!can_duplicate_loop_p (loop)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " FAILED: cannot be duplicated\n"); - return false; - } - /* Check for problems with dependences. If the loop can be reversed, the iterations are independent. */ datarefs = VEC_alloc (data_reference_p, heap, 10); @@ -900,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. @@ -918,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; @@ -1330,114 +1179,6 @@ create_loop_fn (void) return decl; } -/* Bases all the induction variables in LOOP on a single induction - variable (unsigned with base 0 and step 1), whose final value is - compared with *NIT. When the IV type precision has to be larger - than *NIT type precision, *NIT is converted to the larger type, the - conversion code is inserted before the loop, and *NIT is updated to - the new definition. The induction variable is incremented in the - loop latch. REDUCTION_LIST describes the reductions in LOOP. - Return the induction variable that was created. */ - -tree -canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree *nit) -{ - unsigned precision = TYPE_PRECISION (TREE_TYPE (*nit)); - unsigned original_precision = precision; - tree res, type, var_before, val, atype, mtype; - gimple_stmt_iterator gsi, psi; - gimple phi, stmt; - bool ok; - affine_iv iv; - edge exit = single_dom_exit (loop); - struct reduction_info *red; - gimple_seq stmts; - - for (psi = gsi_start_phis (loop->header); - !gsi_end_p (psi); gsi_next (&psi)) - { - phi = gsi_stmt (psi); - res = PHI_RESULT (phi); - - if (is_gimple_reg (res) && TYPE_PRECISION (TREE_TYPE (res)) > precision) - precision = TYPE_PRECISION (TREE_TYPE (res)); - } - - type = lang_hooks.types.type_for_size (precision, 1); - - if (original_precision != precision) - { - *nit = fold_convert (type, *nit); - *nit = force_gimple_operand (*nit, &stmts, true, NULL_TREE); - if (stmts) - gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts); - } - - gsi = gsi_last_bb (loop->latch); - create_iv (build_int_cst_type (type, 0), build_int_cst (type, 1), NULL_TREE, - loop, &gsi, true, &var_before, NULL); - - gsi = gsi_after_labels (loop->header); - for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); ) - { - phi = gsi_stmt (psi); - res = PHI_RESULT (phi); - - if (!is_gimple_reg (res) || res == var_before) - { - gsi_next (&psi); - continue; - } - - ok = simple_iv (loop, loop, res, &iv, true); - - if (reduction_list) - red = reduction_phi (reduction_list, phi); - else - red = NULL; - - /* We preserve the reduction phi nodes. */ - if (!ok && red) - { - gsi_next (&psi); - continue; - } - else - gcc_assert (ok); - remove_phi_node (&psi, false); - - atype = TREE_TYPE (res); - mtype = POINTER_TYPE_P (atype) ? sizetype : atype; - val = fold_build2 (MULT_EXPR, mtype, unshare_expr (iv.step), - fold_convert (mtype, var_before)); - val = fold_build2 (POINTER_TYPE_P (atype) - ? POINTER_PLUS_EXPR : PLUS_EXPR, - atype, unshare_expr (iv.base), val); - val = force_gimple_operand_gsi (&gsi, val, false, NULL_TREE, true, - GSI_SAME_STMT); - stmt = gimple_build_assign (res, val); - gsi_insert_before (&gsi, stmt, GSI_SAME_STMT); - SSA_NAME_DEF_STMT (res) = stmt; - } - - stmt = last_stmt (exit->src); - /* Make the loop exit if the control condition is not satisfied. */ - if (exit->flags & EDGE_TRUE_VALUE) - { - edge te, fe; - - extract_true_false_edges_from_block (exit->src, &te, &fe); - te->flags = EDGE_FALSE_VALUE; - fe->flags = EDGE_TRUE_VALUE; - } - gimple_cond_set_code (stmt, LT_EXPR); - gimple_cond_set_lhs (stmt, var_before); - gimple_cond_set_rhs (stmt, *nit); - update_stmt (stmt); - - return var_before; -} - /* Moves the exit condition of LOOP to the beginning of its header, and duplicates the part of the last iteration that gets disabled to the exit of the loop. NIT is the number of iterations of the loop @@ -1480,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) { @@ -1631,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; @@ -1675,12 +1422,14 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data, return paral_bb; } -/* Generates code to execute the iterations of LOOP in N_THREADS threads in - parallel. NITER describes number of iterations of LOOP. +/* Generates code to execute the iterations of LOOP in N_THREADS + threads in parallel. + + NITER describes number of iterations of LOOP. REDUCTION_LIST describes the reductions existent in the LOOP. */ static void -gen_parallel_loop (struct loop *loop, htab_t reduction_list, +gen_parallel_loop (struct loop *loop, htab_t reduction_list, unsigned n_threads, struct tree_niter_desc *niter) { struct loop *nloop; @@ -1782,7 +1531,7 @@ gen_parallel_loop (struct loop *loop, htab_t reduction_list, free_original_copy_tables (); /* Base all the induction variables in LOOP on a single control one. */ - canonicalize_loop_ivs (loop, reduction_list, &nit); + canonicalize_loop_ivs (loop, &nit); /* Ensure that the exit condition is the first statement in the loop. */ transform_to_exit_first_loop (loop, reduction_list, nit); @@ -1848,6 +1597,184 @@ loop_has_vector_phi_nodes (struct loop *loop ATTRIBUTE_UNUSED) return res; } +/* Create a reduction_info struct, initialize it with REDUC_STMT + and PHI, insert it to the REDUCTION_LIST. */ + +static void +build_new_reduction (htab_t reduction_list, gimple reduc_stmt, gimple phi) +{ + PTR *slot; + struct reduction_info *new_reduction; + + gcc_assert (reduc_stmt); + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, + "Detected reduction. reduction stmt is: \n"); + print_gimple_stmt (dump_file, reduc_stmt, 0, 0); + fprintf (dump_file, "\n"); + } + + new_reduction = XCNEW (struct reduction_info); + + new_reduction->reduc_stmt = reduc_stmt; + new_reduction->reduc_phi = phi; + new_reduction->reduction_code = gimple_assign_rhs_code (reduc_stmt); + slot = htab_find_slot (reduction_list, new_reduction, INSERT); + *slot = new_reduction; +} + +/* Detect all reductions in the LOOP, insert them into REDUCTION_LIST. */ + +static void +gather_scalar_reductions (loop_p loop, htab_t reduction_list) +{ + gimple_stmt_iterator gsi; + loop_vec_info simple_loop_info; + + vect_dump = NULL; + simple_loop_info = vect_analyze_loop_form (loop); + + for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple phi = gsi_stmt (gsi); + affine_iv iv; + tree res = PHI_RESULT (phi); + bool double_reduc; + + if (!is_gimple_reg (res)) + continue; + + if (!simple_iv (loop, loop, res, &iv, true) + && simple_loop_info) + { + gimple reduc_stmt = vect_is_simple_reduction (simple_loop_info, phi, true, &double_reduc); + if (reduc_stmt) + build_new_reduction (reduction_list, reduc_stmt, phi); + } + } + destroy_loop_vec_info (simple_loop_info, true); +} + +/* Try to initialize NITER for code generation part. */ + +static bool +try_get_loop_niter (loop_p loop, struct tree_niter_desc *niter) +{ + edge exit = single_dom_exit (loop); + + gcc_assert (exit); + + /* We need to know # of iterations, and there should be no uses of values + defined inside loop outside of it, unless the values are invariants of + the loop. */ + if (!number_of_iterations_exit (loop, exit, niter, false)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " FAILED: number of iterations not known\n"); + return false; + } + + return true; +} + +/* Try to initialize REDUCTION_LIST for code generation part. + REDUCTION_LIST describes the reductions. */ + +static bool +try_create_reduction_list (loop_p loop, htab_t reduction_list) +{ + edge exit = single_dom_exit (loop); + gimple_stmt_iterator gsi; + + gcc_assert (exit); + + gather_scalar_reductions (loop, reduction_list); + + + for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple phi = gsi_stmt (gsi); + struct reduction_info *red; + imm_use_iterator imm_iter; + use_operand_p use_p; + gimple reduc_phi; + tree val = PHI_ARG_DEF_FROM_EDGE (phi, exit); + + if (is_gimple_reg (val)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "phi is "); + print_gimple_stmt (dump_file, phi, 0, 0); + fprintf (dump_file, "arg of phi to exit: value "); + print_generic_expr (dump_file, val, 0); + fprintf (dump_file, " used outside loop\n"); + fprintf (dump_file, + " checking if it a part of reduction pattern: \n"); + } + if (htab_elements (reduction_list) == 0) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " FAILED: it is not a part of reduction.\n"); + return false; + } + reduc_phi = NULL; + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, val) + { + if (flow_bb_inside_loop_p (loop, gimple_bb (USE_STMT (use_p)))) + { + reduc_phi = USE_STMT (use_p); + break; + } + } + red = reduction_phi (reduction_list, reduc_phi); + if (red == NULL) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " FAILED: it is not a part of reduction.\n"); + return false; + } + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "reduction phi is "); + print_gimple_stmt (dump_file, red->reduc_phi, 0, 0); + fprintf (dump_file, "reduction stmt is "); + print_gimple_stmt (dump_file, red->reduc_stmt, 0, 0); + } + } + } + + /* The iterations of the loop may communicate only through bivs whose + iteration space can be distributed efficiently. */ + for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple phi = gsi_stmt (gsi); + tree def = PHI_RESULT (phi); + affine_iv iv; + + if (is_gimple_reg (def) && !simple_iv (loop, loop, def, &iv, true)) + { + struct reduction_info *red; + + red = reduction_phi (reduction_list, phi); + if (red == NULL) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " FAILED: scalar dependency between iterations\n"); + return false; + } + } + } + + + return true; +} + /* Detect parallel loops and generate parallel code using libgomp primitives. Returns true if some loop was parallelized, false otherwise. */ @@ -1867,26 +1794,41 @@ parallelize_loops (void) return false; reduction_list = htab_create (10, reduction_info_hash, - reduction_info_eq, free); + reduction_info_eq, free); init_stmt_vec_info_vec (); FOR_EACH_LOOP (li, loop, 0) { htab_empty (reduction_list); - if (/* Do not bother with loops in cold areas. */ - optimize_loop_nest_for_size_p (loop) - /* Or loops that roll too little. */ - || expected_loop_iterations (loop) <= n_threads - /* And of course, the loop must be parallelizable. */ - || !can_duplicate_loop_p (loop) + + /* FIXME: Only consider innermost loops with just one exit. */ + if (loop->inner || !single_dom_exit (loop)) + continue; + + if (/* And of course, the loop must be parallelizable. */ + !can_duplicate_loop_p (loop) || loop_has_blocks_with_irreducible_flag (loop) /* FIXME: the check for vector phi nodes could be removed. */ - || loop_has_vector_phi_nodes (loop) - || !loop_parallel_p (loop, reduction_list, &niter_desc)) + || loop_has_vector_phi_nodes (loop)) + continue; + + if (/* Do not bother with loops in cold areas. */ + optimize_loop_nest_for_size_p (loop) + /* Or loops that roll too little. */ + || expected_loop_iterations (loop) <= n_threads) + continue; + if (!try_get_loop_niter (loop, &niter_desc)) + continue; + + if (!try_create_reduction_list (loop, reduction_list)) + continue; + + if (!loop_parallel_p (loop)) continue; changed = true; - gen_parallel_loop (loop, reduction_list, n_threads, &niter_desc); + gen_parallel_loop (loop, reduction_list, + n_threads, &niter_desc); verify_flow_info (); verify_dominators (CDI_DOMINATORS); verify_loop_structure (); 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 bbf37f7a028..2eec3147886 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -828,9 +828,6 @@ mark_virtual_phi_result_for_renaming (gimple phi) } FOR_EACH_IMM_USE_STMT (stmt, iter, gimple_phi_result (phi)) { - if (gimple_code (stmt) != GIMPLE_PHI - && !gimple_plf (stmt, STMT_NECESSARY)) - continue; FOR_EACH_IMM_USE_ON_STMT (use_p, iter) SET_USE (use_p, SSA_NAME_VAR (gimple_phi_result (phi))); update_stmt (stmt); @@ -954,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) @@ -978,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 b891ea64957..e43c0bc404a 100644 --- a/gcc/tree-ssa-loop-manip.c +++ b/gcc/tree-ssa-loop-manip.c @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-scalar-evolution.h" #include "params.h" #include "tree-inline.h" +#include "langhooks.h" /* Creates an induction variable with value BASE + STEP * iteration in LOOP. It is expected that neither BASE nor STEP are shared with other expressions @@ -124,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. */ @@ -155,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. @@ -475,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); @@ -493,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); } @@ -1013,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); } @@ -1100,3 +1103,132 @@ tree_unroll_loop (struct loop *loop, unsigned factor, tree_transform_and_unroll_loop (loop, factor, exit, desc, NULL, NULL); } + +/* Rewrite the phi node at position PSI in function of the main + induction variable MAIN_IV and insert the generated code at GSI. */ + +static void +rewrite_phi_with_iv (loop_p loop, + gimple_stmt_iterator *psi, + gimple_stmt_iterator *gsi, + tree main_iv) +{ + affine_iv iv; + gimple stmt, phi = gsi_stmt (*psi); + tree atype, mtype, val, res = PHI_RESULT (phi); + + if (!is_gimple_reg (res) || res == main_iv) + { + gsi_next (psi); + return; + } + + if (!simple_iv (loop, loop, res, &iv, true)) + { + gsi_next (psi); + return; + } + + remove_phi_node (psi, false); + + atype = TREE_TYPE (res); + mtype = POINTER_TYPE_P (atype) ? sizetype : atype; + val = fold_build2 (MULT_EXPR, mtype, unshare_expr (iv.step), + fold_convert (mtype, main_iv)); + val = fold_build2 (POINTER_TYPE_P (atype) + ? POINTER_PLUS_EXPR : PLUS_EXPR, + atype, unshare_expr (iv.base), val); + val = force_gimple_operand_gsi (gsi, val, false, NULL_TREE, true, + GSI_SAME_STMT); + stmt = gimple_build_assign (res, val); + gsi_insert_before (gsi, stmt, GSI_SAME_STMT); + SSA_NAME_DEF_STMT (res) = stmt; +} + +/* Rewrite all the phi nodes of LOOP in function of the main induction + variable MAIN_IV. */ + +static void +rewrite_all_phi_nodes_with_iv (loop_p loop, tree main_iv) +{ + unsigned i; + basic_block *bbs = get_loop_body_in_dom_order (loop); + gimple_stmt_iterator psi; + + for (i = 0; i < loop->num_nodes; i++) + { + basic_block bb = bbs[i]; + gimple_stmt_iterator gsi = gsi_after_labels (bb); + + if (bb->loop_father != loop) + continue; + + for (psi = gsi_start_phis (bb); !gsi_end_p (psi); ) + rewrite_phi_with_iv (loop, &psi, &gsi, main_iv); + } + + free (bbs); +} + +/* Bases all the induction variables in LOOP on a single induction + variable (unsigned with base 0 and step 1), whose final value is + compared with *NIT. When the IV type precision has to be larger + than *NIT type precision, *NIT is converted to the larger type, the + conversion code is inserted before the loop, and *NIT is updated to + the new definition. The induction variable is incremented in the + loop latch. Return the induction variable that was created. */ + +tree +canonicalize_loop_ivs (struct loop *loop, tree *nit) +{ + unsigned precision = TYPE_PRECISION (TREE_TYPE (*nit)); + unsigned original_precision = precision; + tree type, var_before; + gimple_stmt_iterator gsi, psi; + gimple stmt; + edge exit = single_dom_exit (loop); + gimple_seq stmts; + + for (psi = gsi_start_phis (loop->header); + !gsi_end_p (psi); gsi_next (&psi)) + { + gimple phi = gsi_stmt (psi); + tree res = PHI_RESULT (phi); + + if (is_gimple_reg (res) && TYPE_PRECISION (TREE_TYPE (res)) > precision) + precision = TYPE_PRECISION (TREE_TYPE (res)); + } + + type = lang_hooks.types.type_for_size (precision, 1); + + if (original_precision != precision) + { + *nit = fold_convert (type, *nit); + *nit = force_gimple_operand (*nit, &stmts, true, NULL_TREE); + if (stmts) + gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts); + } + + gsi = gsi_last_bb (loop->latch); + create_iv (build_int_cst_type (type, 0), build_int_cst (type, 1), NULL_TREE, + loop, &gsi, true, &var_before, NULL); + + rewrite_all_phi_nodes_with_iv (loop, var_before); + + stmt = last_stmt (exit->src); + /* Make the loop exit if the control condition is not satisfied. */ + if (exit->flags & EDGE_TRUE_VALUE) + { + edge te, fe; + + extract_true_false_edges_from_block (exit->src, &te, &fe); + te->flags = EDGE_FALSE_VALUE; + fe->flags = EDGE_TRUE_VALUE; + } + gimple_cond_set_code (stmt, LT_EXPR); + gimple_cond_set_lhs (stmt, var_before); + gimple_cond_set_rhs (stmt, *nit); + update_stmt (stmt); + + return var_before; +} diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c index 0aab6d3a2d3..cac6d6d35cd 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_graphite_force_parallel) 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..e8033cd46ca 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); 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.h b/gcc/tree.h index fbae2080c04..a1370fa5e55 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -577,6 +577,7 @@ struct GTY(()) tree_common { TREE_DEPRECATED in all decls + all types IDENTIFIER_TRANSPARENT_ALIAS in IDENTIFIER_NODE @@ -584,9 +585,6 @@ struct GTY(()) tree_common { STMT_IN_SSA_EDGE_WORKLIST in all expressions (tree-ssa-propagate.c) - TYPE_VECTOR_OPAQUE in - VECTOR_TYPE - visited: TREE_VISITED in @@ -605,6 +603,9 @@ struct GTY(()) tree_common { default_def_flag: + TYPE_VECTOR_OPAQUE in + VECTOR_TYPE + SSA_NAME_IS_DEFAULT_DEF in SSA_NAME */ @@ -1887,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; }; @@ -2187,7 +2189,7 @@ extern enum machine_mode vector_type_mode (const_tree); /* Nonzero in a VECTOR_TYPE if the frontends should not emit warnings about missing conversions to other vector types of the same size. */ #define TYPE_VECTOR_OPAQUE(NODE) \ - (VECTOR_TYPE_CHECK (NODE)->base.deprecated_flag) + (VECTOR_TYPE_CHECK (NODE)->base.default_def_flag) /* Indicates that objects of this type must be initialized by calling a function when they are created. */ diff --git a/gcc/vmsdbgout.c b/gcc/vmsdbgout.c index d133a777bda..f7cca03d051 100644 --- a/gcc/vmsdbgout.c +++ b/gcc/vmsdbgout.c @@ -1,6 +1,6 @@ /* Output VMS debug format symbol table information from GCC. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Douglas B. Rupp (rupp@gnat.com). Updated by Bernard W. Giroud (bgiroud@users.sourceforge.net). @@ -41,6 +41,8 @@ along with GCC; see the file COPYING3. If not see /* Difference in seconds between the VMS Epoch and the Unix Epoch */ static const long long vms_epoch_offset = 3506716800ll; +int vms_file_stats_name (const char *, long long *, long *, char *, int *); + /* NOTE: In the comments in this file, many references are made to "Debug Symbol Table". This term is abbreviated as `DST' throughout the remainder of this file. */ @@ -1443,47 +1445,16 @@ lookup_filename (const char *file_name) register char *fn; register unsigned i; const char *fnam; - long long cdt; - long ebk; - short ffb; - char rfo; char flen; - struct stat statbuf; + long long cdt = 0; + long ebk = 0; + short ffb = 0; + char rfo = 0; + long siz = 0; + int ver = 0; - if (stat (file_name, &statbuf) == 0) - { - long gmtoff; -#ifdef VMS - struct tm *ts; - - /* Adjust for GMT. */ - ts = (struct tm *) localtime (&statbuf.st_ctime); - gmtoff = ts->tm_gmtoff; - - /* VMS has multiple file format types. */ - rfo = statbuf.st_fab_rfm; -#else - /* Is GMT adjustment an issue with a cross-compiler? */ - gmtoff = 0; - - /* Assume stream LF type file. */ - rfo = 2; -#endif - cdt = 10000000 * (statbuf.st_ctime + gmtoff + vms_epoch_offset); - ebk = statbuf.st_size / 512 + 1; - ffb = statbuf.st_size - ((statbuf.st_size / 512) * 512); - fnam = full_name (file_name); - flen = strlen (fnam); - } - else - { - cdt = 0; - ebk = 0; - ffb = 0; - rfo = 0; - fnam = ""; - flen = 0; - } + fnam = full_name (file_name); + flen = strlen (fnam); /* Check to see if the file name that was searched on the previous call matches this file name. If so, return the index. */ @@ -1515,6 +1486,12 @@ lookup_filename (const char *file_name) file_info_table_allocated); } + if (vms_file_stats_name (file_name, &cdt, &siz, &rfo, &ver) == 0) + { + ebk = siz / 512 + 1; + ffb = siz - ((siz / 512) * 512); + } + /* Add the new entry to the end of the filename table. */ file_info_table[file_info_table_in_use].file_name = xstrdup (fnam); file_info_table[file_info_table_in_use].max_line = 0; @@ -1730,4 +1707,237 @@ vmsdbgout_finish (const char *main_input_filename ATTRIBUTE_UNUSED) totsize = write_modend (1); write_modend (0); } -#endif /* VMS_DEBUGGING_INFO */ + +/* Need for both Dwarf2 on IVMS and VMS Debug on AVMS */ + +#ifdef VMS +#define __NEW_STARLET 1 +#include <vms/rms.h> +#include <vms/atrdef.h> +#include <vms/fibdef.h> +#include <vms/stsdef.h> +#include <vms/iodef.h> +#include <vms/fatdef.h> +#include <errno.h> +#include <vms/descrip.h> +#include <string.h> +#include <unixlib.h> + +#define MAXPATH 256 + +/* descrip.h doesn't have everything ... */ +typedef struct fibdef* __fibdef_ptr32 __attribute__ (( mode (SI) )); +struct dsc$descriptor_fib +{ + unsigned int fib$l_len; + __fibdef_ptr32 fib$l_addr; +}; + +/* I/O Status Block. */ +struct IOSB +{ + unsigned short status, count; + unsigned int devdep; +}; + +static char *tryfile; + +/* Variable length string. */ +struct vstring +{ + short length; + char string[NAM$C_MAXRSS+1]; +}; + +static char filename_buff [MAXPATH]; +static char vms_filespec [MAXPATH]; + +/* Callback function for filespec style conversion. */ + +static int +translate_unix (char *name, int type ATTRIBUTE_UNUSED) +{ + strncpy (filename_buff, name, MAXPATH); + filename_buff [MAXPATH - 1] = (char) 0; + return 0; +} + +/* Wrapper for DECC function that converts a Unix filespec + to VMS style filespec. */ + +static char * +to_vms_file_spec (char *filespec) +{ + strncpy (vms_filespec, "", MAXPATH); + decc$to_vms (filespec, translate_unix, 1, 1); + strncpy (vms_filespec, filename_buff, MAXPATH); + + vms_filespec [MAXPATH - 1] = (char) 0; + + return vms_filespec; +} + +#else +#define VMS_EPOCH_OFFSET 35067168000000000 +#define VMS_GRANULARITY_FACTOR 10000000 +#endif + +/* Return VMS file date, size, format, version given a name. */ + +int +vms_file_stats_name (const char *filename, long long *cdt, long *siz, char *rfo, + int *ver) +{ +#ifdef VMS + struct FAB fab; + struct NAM nam; + + unsigned long long create; + FAT recattr; + char ascnamebuff [256]; + + ATRDEF atrlst[] + = { + { ATR$S_CREDATE, ATR$C_CREDATE, &create }, + { ATR$S_RECATTR, ATR$C_RECATTR, &recattr }, + { ATR$S_ASCNAME, ATR$C_ASCNAME, &ascnamebuff }, + { 0, 0, 0} + }; + + FIBDEF fib; + struct dsc$descriptor_fib fibdsc = {sizeof (fib), (void *) &fib}; + + struct IOSB iosb; + + long status; + unsigned short chan; + + struct vstring file; + struct dsc$descriptor_s filedsc + = {NAM$C_MAXRSS, DSC$K_DTYPE_T, DSC$K_CLASS_S, (void *) file.string}; + struct vstring device; + struct dsc$descriptor_s devicedsc + = {NAM$C_MAXRSS, DSC$K_DTYPE_T, DSC$K_CLASS_S, (void *) device.string}; + struct vstring result; + struct dsc$descriptor_s resultdsc + = {NAM$C_MAXRSS, DSC$K_DTYPE_VT, DSC$K_CLASS_VS, (void *) result.string}; + + if (strcmp (filename, "<internal>") == 0 + || strcmp (filename, "<built-in>") == 0) + { + if (cdt) + *cdt = 0; + + if (siz) + *siz = 0; + + if (rfo) + *rfo = 0; + + if (ver) + *ver = 0; + + return 0; + } + + tryfile = to_vms_file_spec (filename); + + /* Allocate and initialize a FAB and NAM structures. */ + fab = cc$rms_fab; + nam = cc$rms_nam; + + nam.nam$l_esa = file.string; + nam.nam$b_ess = NAM$C_MAXRSS; + nam.nam$l_rsa = result.string; + nam.nam$b_rss = NAM$C_MAXRSS; + fab.fab$l_fna = tryfile; + fab.fab$b_fns = strlen (tryfile); + fab.fab$l_nam = &nam; + + /* Validate filespec syntax and device existence. */ + status = SYS$PARSE (&fab, 0, 0); + if ((status & 1) != 1) + return 1; + + file.string[nam.nam$b_esl] = 0; + + /* Find matching filespec. */ + status = SYS$SEARCH (&fab, 0, 0); + if ((status & 1) != 1) + return 1; + + file.string[nam.nam$b_esl] = 0; + result.string[result.length=nam.nam$b_rsl] = 0; + + /* Get the device name and assign an IO channel. */ + strncpy (device.string, nam.nam$l_dev, nam.nam$b_dev); + devicedsc.dsc$w_length = nam.nam$b_dev; + chan = 0; + status = SYS$ASSIGN (&devicedsc, &chan, 0, 0, 0); + if ((status & 1) != 1) + return 1; + + /* Initialize the FIB and fill in the directory id field. */ + memset (&fib, 0, sizeof (fib)); + fib.fib$w_did[0] = nam.nam$w_did[0]; + fib.fib$w_did[1] = nam.nam$w_did[1]; + fib.fib$w_did[2] = nam.nam$w_did[2]; + fib.fib$l_acctl = 0; + fib.fib$l_wcc = 0; + strcpy (file.string, (strrchr (result.string, ']') + 1)); + filedsc.dsc$w_length = strlen (file.string); + result.string[result.length = 0] = 0; + + /* Open and close the file to fill in the attributes. */ + status + = SYS$QIOW (0, chan, IO$_ACCESS|IO$M_ACCESS, &iosb, 0, 0, + &fibdsc, &filedsc, &result.length, &resultdsc, &atrlst, 0); + if ((status & 1) != 1) + return 1; + if ((iosb.status & 1) != 1) + return 1; + + result.string[result.length] = 0; + status = SYS$QIOW (0, chan, IO$_DEACCESS, &iosb, 0, 0, &fibdsc, 0, 0, 0, + &atrlst, 0); + if ((status & 1) != 1) + return 1; + if ((iosb.status & 1) != 1) + return 1; + + /* Deassign the channel and exit. */ + status = SYS$DASSGN (chan); + if ((status & 1) != 1) + return 1; + + if (cdt) *cdt = create; + if (siz) *siz = (512 * 65536 * recattr.fat$w_efblkh) + + (512 * (recattr.fat$w_efblkl - 1)) + + recattr.fat$w_ffbyte; + if (rfo) *rfo = recattr.fat$v_rtype; + if (ver) *ver = strtol (strrchr (ascnamebuff, ';')+1, 0, 10); + + return 0; +#else + struct stat buff; + + if ((stat (filename, &buff)) != 0) + return 1; + + if (cdt) + *cdt = (long long) (buff.st_mtime * VMS_GRANULARITY_FACTOR) + + VMS_EPOCH_OFFSET; + + if (siz) + *siz = buff.st_size; + + if (rfo) + *rfo = 2; /* Stream LF format */ + + if (ver) + *ver = 1; + + return 0; +#endif +} +#endif 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/ChangeLog b/libcpp/ChangeLog index 7fcfa5649bc..9da83176bd4 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,8 @@ +2009-07-27 Douglas B Rupp <rupp@gnat.com> + + * include/cpplib.h (INO_T_CPP): New macro. + (struct cpp_dir): Use it. + 2009-07-20 Jerry Quinn <jlquinn@optonline.net> PR regression/40800 diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index 71c7ef26351..e873ccfeea5 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -505,6 +505,12 @@ struct cpp_callbacks void (*before_define) (cpp_reader *); }; +#ifdef VMS +#define INO_T_CPP ino_t ino[3] +#else +#define INO_T_CPP ino_t ino +#endif + /* Chain of directories to look for include files in. */ struct cpp_dir { @@ -538,7 +544,7 @@ struct cpp_dir /* The C front end uses these to recognize duplicated directories in the search path. */ - ino_t ino; + INO_T_CPP; dev_t dev; }; 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 7ba9023932f..1412b0b980d 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,23 @@ +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 + * c99_functions.c: Define complex I, if not defined. + Create prototypes for C99 functions to silence warnings. + * gfortran.map: Add missing functions to GFORTRAN_C99_1.0 + and new GFORTRAN_C99_1.1. + 2009-07-25 Tobias Burnus <burnus@net-b.de> PR fortran/33197 diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am index 4a974ba0066..ee969d06936 100644 --- a/libgfortran/Makefile.am +++ b/libgfortran/Makefile.am @@ -37,6 +37,10 @@ AM_CFLAGS += -fcx-fortran-rules SECTION_FLAGS = @SECTION_FLAGS@ AM_CFLAGS += $(SECTION_FLAGS) +# Some targets require additional compiler options for IEEE compatibility. +IEEE_FLAGS = @IEEE_FLAGS@ +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..d7742ff7302 100644 --- a/libgfortran/Makefile.in +++ b/libgfortran/Makefile.in @@ -815,7 +815,8 @@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ # Fortran rules for complex multiplication and division -AM_CFLAGS = @AM_CFLAGS@ -fcx-fortran-rules $(SECTION_FLAGS) +AM_CFLAGS = @AM_CFLAGS@ -fcx-fortran-rules $(SECTION_FLAGS) \ + $(IEEE_FLAGS) AM_FCFLAGS = @AM_FCFLAGS@ AR = @AR@ AS = @AS@ @@ -843,6 +844,9 @@ FCFLAGS = @FCFLAGS@ FGREP = @FGREP@ FPU_HOST_HEADER = @FPU_HOST_HEADER@ GREP = @GREP@ + +# Some targets require additional compiler options for IEEE compatibility. +IEEE_FLAGS = @IEEE_FLAGS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ 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/gfortran.map b/libgfortran/gfortran.map index c8de09cf055..4b7a1ed7c47 100644 --- a/libgfortran/gfortran.map +++ b/libgfortran/gfortran.map @@ -1206,13 +1206,20 @@ GFORTRAN_C99_1.0 { jnf; lgamma; lgammaf; + llround; + llroundf; + llroundl; log10f; log10l; logf; + lround; + lroundf; + lroundl; nextafterf; powf; round; roundf; + roundl; scalbn; scalbnf; sinf; @@ -1228,3 +1235,25 @@ GFORTRAN_C99_1.0 { y1f; ynf; }; + +GFORTRAN_C99_1.1 { + global: + cacos; + cacosf; + cacosh; + cacoshf; + cacoshl; + cacosl; + casin; + casinf; + casinh; + casinhf; + casinhl; + casinl; + catan; + catanf; + catanh; + catanhf; + catanhl; + catanl; +} GFORTRAN_C99_1.0; diff --git a/libgfortran/intrinsics/c99_functions.c b/libgfortran/intrinsics/c99_functions.c index 3c40c1fad3d..03bcbfedaa6 100644 --- a/libgfortran/intrinsics/c99_functions.c +++ b/libgfortran/intrinsics/c99_functions.c @@ -54,19 +54,20 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define cabsl __gfc_cabsl #endif -/* Prototypes to silence -Wstrict-prototypes -Wmissing-prototypes. */ - -float cabsf(float complex); -double cabs(double complex); -long double cabsl(long double complex); - -float cargf(float complex); -double carg(double complex); -long double cargl(long double complex); +/* On a C99 system "I" (with I*I = -1) should be defined in complex.h; + if not, we define a fallback version here. */ +#ifndef I +# if defined(_Imaginary_I) +# define I _Imaginary_I +# elif defined(_Complex_I) +# define I _Complex_I +# else +# define I (1.0fi) +# endif +#endif -float complex clog10f(float complex); -double complex clog10(double complex); -long double complex clog10l(long double complex); +/* Prototypes are included to silence -Wstrict-prototypes + -Wmissing-prototypes. */ /* Wrappers for systems without the various C99 single precision Bessel @@ -74,7 +75,7 @@ long double complex clog10l(long double complex); #if defined(HAVE_J0) && ! defined(HAVE_J0F) #define HAVE_J0F 1 -extern float j0f (float); +float j0f (float); float j0f (float x) @@ -85,7 +86,7 @@ j0f (float x) #if defined(HAVE_J1) && !defined(HAVE_J1F) #define HAVE_J1F 1 -extern float j1f (float); +float j1f (float); float j1f (float x) { @@ -95,7 +96,7 @@ float j1f (float x) #if defined(HAVE_JN) && !defined(HAVE_JNF) #define HAVE_JNF 1 -extern float jnf (int, float); +float jnf (int, float); float jnf (int n, float x) @@ -106,7 +107,7 @@ jnf (int n, float x) #if defined(HAVE_Y0) && !defined(HAVE_Y0F) #define HAVE_Y0F 1 -extern float y0f (float); +float y0f (float); float y0f (float x) @@ -117,7 +118,7 @@ y0f (float x) #if defined(HAVE_Y1) && !defined(HAVE_Y1F) #define HAVE_Y1F 1 -extern float y1f (float); +float y1f (float); float y1f (float x) @@ -128,7 +129,7 @@ y1f (float x) #if defined(HAVE_YN) && !defined(HAVE_YNF) #define HAVE_YNF 1 -extern float ynf (int, float); +float ynf (int, float); float ynf (int n, float x) @@ -142,7 +143,7 @@ ynf (int n, float x) #if defined(HAVE_ERF) && !defined(HAVE_ERFF) #define HAVE_ERFF 1 -extern float erff (float); +float erff (float); float erff (float x) @@ -153,7 +154,7 @@ erff (float x) #if defined(HAVE_ERFC) && !defined(HAVE_ERFCF) #define HAVE_ERFCF 1 -extern float erfcf (float); +float erfcf (float); float erfcf (float x) @@ -165,14 +166,18 @@ erfcf (float x) #ifndef HAVE_ACOSF #define HAVE_ACOSF 1 +float acosf (float x); + float -acosf(float x) +acosf (float x) { - return (float) acos(x); + return (float) acos (x); } #endif #if HAVE_ACOSH && !HAVE_ACOSHF +float acoshf (float x); + float acoshf (float x) { @@ -182,14 +187,18 @@ acoshf (float x) #ifndef HAVE_ASINF #define HAVE_ASINF 1 +float asinf (float x); + float -asinf(float x) +asinf (float x) { - return (float) asin(x); + return (float) asin (x); } #endif #if HAVE_ASINH && !HAVE_ASINHF +float asinhf (float x); + float asinhf (float x) { @@ -199,23 +208,29 @@ asinhf (float x) #ifndef HAVE_ATAN2F #define HAVE_ATAN2F 1 +float atan2f (float y, float x); + float -atan2f(float y, float x) +atan2f (float y, float x) { - return (float) atan2(y, x); + return (float) atan2 (y, x); } #endif #ifndef HAVE_ATANF #define HAVE_ATANF 1 +float atanf (float x); + float -atanf(float x) +atanf (float x) { - return (float) atan(x); + return (float) atan (x); } #endif #if HAVE_ATANH && !HAVE_ATANHF +float atanhf (float x); + float atanhf (float x) { @@ -225,69 +240,85 @@ atanhf (float x) #ifndef HAVE_CEILF #define HAVE_CEILF 1 +float ceilf (float x); + float -ceilf(float x) +ceilf (float x) { - return (float) ceil(x); + return (float) ceil (x); } #endif #ifndef HAVE_COPYSIGNF #define HAVE_COPYSIGNF 1 +float copysignf (float x, float y); + float -copysignf(float x, float y) +copysignf (float x, float y) { - return (float) copysign(x, y); + return (float) copysign (x, y); } #endif #ifndef HAVE_COSF #define HAVE_COSF 1 +float cosf (float x); + float -cosf(float x) +cosf (float x) { - return (float) cos(x); + return (float) cos (x); } #endif #ifndef HAVE_COSHF #define HAVE_COSHF 1 +float coshf (float x); + float -coshf(float x) +coshf (float x) { - return (float) cosh(x); + return (float) cosh (x); } #endif #ifndef HAVE_EXPF #define HAVE_EXPF 1 +float expf (float x); + float -expf(float x) +expf (float x) { - return (float) exp(x); + return (float) exp (x); } #endif #ifndef HAVE_FABSF #define HAVE_FABSF 1 +float fabsf (float x); + float -fabsf(float x) +fabsf (float x) { - return (float) fabs(x); + return (float) fabs (x); } #endif #ifndef HAVE_FLOORF #define HAVE_FLOORF 1 +float floorf (float x); + float -floorf(float x) +floorf (float x) { - return (float) floor(x); + return (float) floor (x); } #endif #ifndef HAVE_FMODF #define HAVE_FMODF 1 +float fmodf (float x, float y); + float fmodf (float x, float y) { @@ -297,111 +328,135 @@ fmodf (float x, float y) #ifndef HAVE_FREXPF #define HAVE_FREXPF 1 +float frexpf (float x, int *exp); + float -frexpf(float x, int *exp) +frexpf (float x, int *exp) { - return (float) frexp(x, exp); + return (float) frexp (x, exp); } #endif #ifndef HAVE_HYPOTF #define HAVE_HYPOTF 1 +float hypotf (float x, float y); + float -hypotf(float x, float y) +hypotf (float x, float y) { - return (float) hypot(x, y); + return (float) hypot (x, y); } #endif #ifndef HAVE_LOGF #define HAVE_LOGF 1 +float logf (float x); + float -logf(float x) +logf (float x) { - return (float) log(x); + return (float) log (x); } #endif #ifndef HAVE_LOG10F #define HAVE_LOG10F 1 +float log10f (float x); + float -log10f(float x) +log10f (float x) { - return (float) log10(x); + return (float) log10 (x); } #endif #ifndef HAVE_SCALBN #define HAVE_SCALBN 1 +double scalbn (double x, int y); + double -scalbn(double x, int y) +scalbn (double x, int y) { #if (FLT_RADIX == 2) && defined(HAVE_LDEXP) return ldexp (x, y); #else - return x * pow(FLT_RADIX, y); + return x * pow (FLT_RADIX, y); #endif } #endif #ifndef HAVE_SCALBNF #define HAVE_SCALBNF 1 +float scalbnf (float x, int y); + float -scalbnf(float x, int y) +scalbnf (float x, int y) { - return (float) scalbn(x, y); + return (float) scalbn (x, y); } #endif #ifndef HAVE_SINF #define HAVE_SINF 1 +float sinf (float x); + float -sinf(float x) +sinf (float x) { - return (float) sin(x); + return (float) sin (x); } #endif #ifndef HAVE_SINHF #define HAVE_SINHF 1 +float sinhf (float x); + float -sinhf(float x) +sinhf (float x) { - return (float) sinh(x); + return (float) sinh (x); } #endif #ifndef HAVE_SQRTF #define HAVE_SQRTF 1 +float sqrtf (float x); + float -sqrtf(float x) +sqrtf (float x) { - return (float) sqrt(x); + return (float) sqrt (x); } #endif #ifndef HAVE_TANF #define HAVE_TANF 1 +float tanf (float x); + float -tanf(float x) +tanf (float x) { - return (float) tan(x); + return (float) tan (x); } #endif #ifndef HAVE_TANHF #define HAVE_TANHF 1 +float tanhf (float x); + float -tanhf(float x) +tanhf (float x) { - return (float) tanh(x); + return (float) tanh (x); } #endif #ifndef HAVE_TRUNC #define HAVE_TRUNC 1 +double trunc (double x); + double -trunc(double x) +trunc (double x) { if (!isfinite (x)) return x; @@ -415,8 +470,10 @@ trunc(double x) #ifndef HAVE_TRUNCF #define HAVE_TRUNCF 1 +float truncf (float x); + float -truncf(float x) +truncf (float x) { return (float) trunc (x); } @@ -427,15 +484,17 @@ truncf(float x) /* This is a portable implementation of nextafterf that is intended to be independent of the floating point format or its in memory representation. This implementation works correctly with denormalized values. */ +float nextafterf (float x, float y); + float -nextafterf(float x, float y) +nextafterf (float x, float y) { /* This variable is marked volatile to avoid excess precision problems on some platforms, including IA-32. */ volatile float delta; float absx, denorm_min; - if (isnan(x) || isnan(y)) + if (isnan (x) || isnan (y)) return x + y; if (x == y) return x; @@ -490,10 +549,12 @@ nextafterf(float x, float y) #ifndef HAVE_POWF #define HAVE_POWF 1 #endif +float powf (float x, float y); + float -powf(float x, float y) +powf (float x, float y) { - return (float) pow(x, y); + return (float) pow (x, y); } #endif @@ -503,12 +564,14 @@ powf(float x, float y) #if !defined(HAVE_ROUNDL) #define HAVE_ROUNDL 1 +long double roundl (long double x); + #if defined(HAVE_CEILL) /* Round to nearest integral value. If the argument is halfway between two integral values then round away from zero. */ long double -roundl(long double x) +roundl (long double x) { long double t; if (!isfinite (x)) @@ -516,14 +579,14 @@ roundl(long double x) if (x >= 0.0) { - t = ceill(x); + t = ceill (x); if (t - x > 0.5) t -= 1.0; return (t); } else { - t = ceill(-x); + t = ceill (-x); if (t + x > 0.5) t -= 1.0; return (-t); @@ -533,7 +596,7 @@ roundl(long double x) /* Poor version of roundl for system that don't have ceill. */ long double -roundl(long double x) +roundl (long double x) { if (x > DBL_MAX || x < -DBL_MAX) { @@ -546,7 +609,7 @@ roundl(long double x) } else /* Use round(). */ - return round((double) x); + return round ((double) x); } #endif @@ -556,9 +619,10 @@ roundl(long double x) #define HAVE_ROUND 1 /* Round to nearest integral value. If the argument is halfway between two integral values then round away from zero. */ +double round (double x); double -round(double x) +round (double x) { double t; if (!isfinite (x)) @@ -566,14 +630,14 @@ round(double x) if (x >= 0.0) { - t = floor(x); + t = floor (x); if (t - x <= -0.5) t += 1.0; return (t); } else { - t = floor(-x); + t = floor (-x); if (t + x <= -0.5) t += 1.0; return (-t); @@ -585,9 +649,10 @@ round(double x) #define HAVE_ROUNDF 1 /* Round to nearest integral value. If the argument is halfway between two integral values then round away from zero. */ +float roundf (float x); float -roundf(float x) +roundf (float x) { float t; if (!isfinite (x)) @@ -595,14 +660,14 @@ roundf(float x) if (x >= 0.0) { - t = floorf(x); + t = floorf (x); if (t - x <= -0.5) t += 1.0; return (t); } else { - t = floorf(-x); + t = floorf (-x); if (t + x <= -0.5) t += 1.0; return (-t); @@ -615,6 +680,8 @@ roundf(float x) #if !defined(HAVE_LROUNDF) && defined(HAVE_ROUNDF) #define HAVE_LROUNDF 1 +long int lroundf (float x); + long int lroundf (float x) { @@ -624,6 +691,8 @@ lroundf (float x) #if !defined(HAVE_LROUND) && defined(HAVE_ROUND) #define HAVE_LROUND 1 +long int lround (double x); + long int lround (double x) { @@ -633,6 +702,8 @@ lround (double x) #if !defined(HAVE_LROUNDL) && defined(HAVE_ROUNDL) #define HAVE_LROUNDL 1 +long int lroundl (long double x); + long int lroundl (long double x) { @@ -642,6 +713,8 @@ lroundl (long double x) #if !defined(HAVE_LLROUNDF) && defined(HAVE_ROUNDF) #define HAVE_LLROUNDF 1 +long long int llroundf (float x); + long long int llroundf (float x) { @@ -651,6 +724,8 @@ llroundf (float x) #if !defined(HAVE_LLROUND) && defined(HAVE_ROUND) #define HAVE_LLROUND 1 +long long int llround (double x); + long long int llround (double x) { @@ -660,6 +735,8 @@ llround (double x) #if !defined(HAVE_LLROUNDL) && defined(HAVE_ROUNDL) #define HAVE_LLROUNDL 1 +long long int llroundl (long double x); + long long int llroundl (long double x) { @@ -672,8 +749,10 @@ llroundl (long double x) #define HAVE_LOG10L 1 /* log10 function for long double variables. The version provided here reduces the argument until it fits into a double, then use log10. */ +long double log10l (long double x); + long double -log10l(long double x) +log10l (long double x) { #if LDBL_MAX_EXP > DBL_MAX_EXP if (x > DBL_MAX) @@ -699,7 +778,7 @@ log10l(long double x) if (x < 0x1p-4093L) { p2_result += 4093; x /= 0x1p-4093L; } if (x < 0x1p-2045L) { p2_result += 2045; x /= 0x1p-2045L; } if (x < 0x1p-1021L) { p2_result += 1021; x /= 0x1p-1021L; } - val = fabs(log10 ((double) x)); + val = fabs (log10 ((double) x)); return (- val - p2_result * .30102999566398119521373889472449302L); } #endif @@ -710,6 +789,8 @@ log10l(long double x) #ifndef HAVE_FLOORL #define HAVE_FLOORL 1 +long double floorl (long double x); + long double floorl (long double x) { @@ -736,6 +817,8 @@ floorl (long double x) #ifndef HAVE_FMODL #define HAVE_FMODL 1 +long double fmodl (long double x, long double y); + long double fmodl (long double x, long double y) { @@ -751,6 +834,8 @@ fmodl (long double x, long double y) #if !defined(HAVE_CABSF) #define HAVE_CABSF 1 +float cabsf (float complex z); + float cabsf (float complex z) { @@ -760,6 +845,8 @@ cabsf (float complex z) #if !defined(HAVE_CABS) #define HAVE_CABS 1 +double cabs (double complex z); + double cabs (double complex z) { @@ -769,6 +856,8 @@ cabs (double complex z) #if !defined(HAVE_CABSL) && defined(HAVE_HYPOTL) #define HAVE_CABSL 1 +long double cabsl (long double complex z); + long double cabsl (long double complex z) { @@ -779,6 +868,8 @@ cabsl (long double complex z) #if !defined(HAVE_CARGF) #define HAVE_CARGF 1 +float cargf (float complex z); + float cargf (float complex z) { @@ -788,6 +879,8 @@ cargf (float complex z) #if !defined(HAVE_CARG) #define HAVE_CARG 1 +double carg (double complex z); + double carg (double complex z) { @@ -797,6 +890,8 @@ carg (double complex z) #if !defined(HAVE_CARGL) && defined(HAVE_ATAN2L) #define HAVE_CARGL 1 +long double cargl (long double complex z); + long double cargl (long double complex z) { @@ -808,6 +903,8 @@ cargl (long double complex z) /* exp(z) = exp(a)*(cos(b) + i sin(b)) */ #if !defined(HAVE_CEXPF) #define HAVE_CEXPF 1 +float complex cexpf (float complex z); + float complex cexpf (float complex z) { @@ -823,6 +920,8 @@ cexpf (float complex z) #if !defined(HAVE_CEXP) #define HAVE_CEXP 1 +double complex cexp (double complex z); + double complex cexp (double complex z) { @@ -838,6 +937,8 @@ cexp (double complex z) #if !defined(HAVE_CEXPL) && defined(HAVE_COSL) && defined(HAVE_SINL) && defined(EXPL) #define HAVE_CEXPL 1 +long double complex cexpl (long double complex z); + long double complex cexpl (long double complex z) { @@ -855,6 +956,8 @@ cexpl (long double complex z) /* log(z) = log (cabs(z)) + i*carg(z) */ #if !defined(HAVE_CLOGF) #define HAVE_CLOGF 1 +float complex clogf (float complex z); + float complex clogf (float complex z) { @@ -867,6 +970,8 @@ clogf (float complex z) #if !defined(HAVE_CLOG) #define HAVE_CLOG 1 +double complex clog (double complex z); + double complex clog (double complex z) { @@ -879,6 +984,8 @@ clog (double complex z) #if !defined(HAVE_CLOGL) && defined(HAVE_LOGL) && defined(HAVE_CABSL) && defined(HAVE_CARGL) #define HAVE_CLOGL 1 +long double complex clogl (long double complex z); + long double complex clogl (long double complex z) { @@ -893,6 +1000,8 @@ clogl (long double complex z) /* log10(z) = log10 (cabs(z)) + i*carg(z) */ #if !defined(HAVE_CLOG10F) #define HAVE_CLOG10F 1 +float complex clog10f (float complex z); + float complex clog10f (float complex z) { @@ -905,6 +1014,8 @@ clog10f (float complex z) #if !defined(HAVE_CLOG10) #define HAVE_CLOG10 1 +double complex clog10 (double complex z); + double complex clog10 (double complex z) { @@ -917,6 +1028,8 @@ clog10 (double complex z) #if !defined(HAVE_CLOG10L) && defined(HAVE_LOG10L) && defined(HAVE_CABSL) && defined(HAVE_CARGL) #define HAVE_CLOG10L 1 +long double complex clog10l (long double complex z); + long double complex clog10l (long double complex z) { @@ -931,6 +1044,8 @@ clog10l (long double complex z) /* pow(base, power) = cexp (power * clog (base)) */ #if !defined(HAVE_CPOWF) #define HAVE_CPOWF 1 +float complex cpowf (float complex base, float complex power); + float complex cpowf (float complex base, float complex power) { @@ -940,6 +1055,8 @@ cpowf (float complex base, float complex power) #if !defined(HAVE_CPOW) #define HAVE_CPOW 1 +double complex cpow (double complex base, double complex power); + double complex cpow (double complex base, double complex power) { @@ -949,6 +1066,8 @@ cpow (double complex base, double complex power) #if !defined(HAVE_CPOWL) && defined(HAVE_CEXPL) && defined(HAVE_CLOGL) #define HAVE_CPOWL 1 +long double complex cpowl (long double complex base, long double complex power); + long double complex cpowl (long double complex base, long double complex power) { @@ -960,6 +1079,8 @@ cpowl (long double complex base, long double complex power) /* sqrt(z). Algorithm pulled from glibc. */ #if !defined(HAVE_CSQRTF) #define HAVE_CSQRTF 1 +float complex csqrtf (float complex z); + float complex csqrtf (float complex z) { @@ -1013,6 +1134,8 @@ csqrtf (float complex z) #if !defined(HAVE_CSQRT) #define HAVE_CSQRT 1 +double complex csqrt (double complex z); + double complex csqrt (double complex z) { @@ -1066,6 +1189,8 @@ csqrt (double complex z) #if !defined(HAVE_CSQRTL) && defined(HAVE_COPYSIGNL) && defined(HAVE_SQRTL) && defined(HAVE_FABSL) && defined(HAVE_HYPOTL) #define HAVE_CSQRTL 1 +long double complex csqrtl (long double complex z); + long double complex csqrtl (long double complex z) { @@ -1121,6 +1246,8 @@ csqrtl (long double complex z) /* sinh(a + i b) = sinh(a) cos(b) + i cosh(a) sin(b) */ #if !defined(HAVE_CSINHF) #define HAVE_CSINHF 1 +float complex csinhf (float complex a); + float complex csinhf (float complex a) { @@ -1136,6 +1263,8 @@ csinhf (float complex a) #if !defined(HAVE_CSINH) #define HAVE_CSINH 1 +double complex csinh (double complex a); + double complex csinh (double complex a) { @@ -1151,6 +1280,8 @@ csinh (double complex a) #if !defined(HAVE_CSINHL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL) #define HAVE_CSINHL 1 +long double complex csinhl (long double complex a); + long double complex csinhl (long double complex a) { @@ -1168,6 +1299,8 @@ csinhl (long double complex a) /* cosh(a + i b) = cosh(a) cos(b) + i sinh(a) sin(b) */ #if !defined(HAVE_CCOSHF) #define HAVE_CCOSHF 1 +float complex ccoshf (float complex a); + float complex ccoshf (float complex a) { @@ -1183,6 +1316,8 @@ ccoshf (float complex a) #if !defined(HAVE_CCOSH) #define HAVE_CCOSH 1 +double complex ccosh (double complex a); + double complex ccosh (double complex a) { @@ -1198,6 +1333,8 @@ ccosh (double complex a) #if !defined(HAVE_CCOSHL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL) #define HAVE_CCOSHL 1 +long double complex ccoshl (long double complex a); + long double complex ccoshl (long double complex a) { @@ -1215,6 +1352,8 @@ ccoshl (long double complex a) /* tanh(a + i b) = (tanh(a) + i tan(b)) / (1 + i tanh(a) tan(b)) */ #if !defined(HAVE_CTANHF) #define HAVE_CTANHF 1 +float complex ctanhf (float complex a); + float complex ctanhf (float complex a) { @@ -1232,6 +1371,7 @@ ctanhf (float complex a) #if !defined(HAVE_CTANH) #define HAVE_CTANH 1 +double complex ctanh (double complex a); double complex ctanh (double complex a) { @@ -1249,6 +1389,8 @@ ctanh (double complex a) #if !defined(HAVE_CTANHL) && defined(HAVE_TANL) && defined(HAVE_TANHL) #define HAVE_CTANHL 1 +long double complex ctanhl (long double complex a); + long double complex ctanhl (long double complex a) { @@ -1268,6 +1410,8 @@ ctanhl (long double complex a) /* sin(a + i b) = sin(a) cosh(b) + i cos(a) sinh(b) */ #if !defined(HAVE_CSINF) #define HAVE_CSINF 1 +float complex csinf (float complex a); + float complex csinf (float complex a) { @@ -1283,6 +1427,8 @@ csinf (float complex a) #if !defined(HAVE_CSIN) #define HAVE_CSIN 1 +double complex csin (double complex a); + double complex csin (double complex a) { @@ -1298,6 +1444,8 @@ csin (double complex a) #if !defined(HAVE_CSINL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL) #define HAVE_CSINL 1 +long double complex csinl (long double complex a); + long double complex csinl (long double complex a) { @@ -1315,6 +1463,8 @@ csinl (long double complex a) /* cos(a + i b) = cos(a) cosh(b) - i sin(a) sinh(b) */ #if !defined(HAVE_CCOSF) #define HAVE_CCOSF 1 +float complex ccosf (float complex a); + float complex ccosf (float complex a) { @@ -1330,6 +1480,8 @@ ccosf (float complex a) #if !defined(HAVE_CCOS) #define HAVE_CCOS 1 +double complex ccos (double complex a); + double complex ccos (double complex a) { @@ -1345,6 +1497,8 @@ ccos (double complex a) #if !defined(HAVE_CCOSL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL) #define HAVE_CCOSL 1 +long double complex ccosl (long double complex a); + long double complex ccosl (long double complex a) { @@ -1362,6 +1516,8 @@ ccosl (long double complex a) /* tan(a + i b) = (tan(a) + i tanh(b)) / (1 - i tan(a) tanh(b)) */ #if !defined(HAVE_CTANF) #define HAVE_CTANF 1 +float complex ctanf (float complex a); + float complex ctanf (float complex a) { @@ -1379,6 +1535,8 @@ ctanf (float complex a) #if !defined(HAVE_CTAN) #define HAVE_CTAN 1 +double complex ctan (double complex a); + double complex ctan (double complex a) { @@ -1396,6 +1554,8 @@ ctan (double complex a) #if !defined(HAVE_CTANL) && defined(HAVE_TANL) && defined(HAVE_TANHL) #define HAVE_CTANL 1 +long double complex ctanl (long double complex a); + long double complex ctanl (long double complex a) { @@ -1417,6 +1577,8 @@ ctanl (long double complex a) #if !defined(HAVE_CASINF) && defined(HAVE_CLOGF) && defined(HAVE_CSQRTF) #define HAVE_CASINF 1 +complex float casinf (complex float z); + complex float casinf (complex float z) { @@ -1427,6 +1589,8 @@ casinf (complex float z) #if !defined(HAVE_CASIN) && defined(HAVE_CLOG) && defined(HAVE_CSQRT) #define HAVE_CASIN 1 +complex double casin (complex double z); + complex double casin (complex double z) { @@ -1437,6 +1601,8 @@ casin (complex double z) #if !defined(HAVE_CASINL) && defined(HAVE_CLOGL) && defined(HAVE_CSQRTL) #define HAVE_CASINL 1 +complex long double casinl (complex long double z); + complex long double casinl (complex long double z) { @@ -1450,17 +1616,21 @@ casinl (complex long double z) #if !defined(HAVE_CACOSF) && defined(HAVE_CLOGF) && defined(HAVE_CSQRTF) #define HAVE_CACOSF 1 +complex float cacosf (complex float z); + complex float cacosf (complex float z) { - return -I*clogf (z + I*csqrtf(1.0f-z*z)); + return -I*clogf (z + I*csqrtf (1.0f-z*z)); } #endif -complex double #if !defined(HAVE_CACOS) && defined(HAVE_CLOG) && defined(HAVE_CSQRT) #define HAVE_CACOS 1 +complex double cacos (complex double z); + +complex double cacos (complex double z) { return -I*clog (z + I*csqrt (1.0-z*z)); @@ -1470,6 +1640,8 @@ cacos (complex double z) #if !defined(HAVE_CACOSL) && defined(HAVE_CLOGL) && defined(HAVE_CSQRTL) #define HAVE_CACOSL 1 +complex long double cacosl (complex long double z); + complex long double cacosl (complex long double z) { @@ -1483,6 +1655,8 @@ cacosl (complex long double z) #if !defined(HAVE_CATANF) && defined(HAVE_CLOGF) #define HAVE_CACOSF 1 +complex float catanf (complex float z); + complex float catanf (complex float z) { @@ -1493,6 +1667,8 @@ catanf (complex float z) #if !defined(HAVE_CATAN) && defined(HAVE_CLOG) #define HAVE_CACOS 1 +complex double catan (complex double z); + complex double catan (complex double z) { @@ -1503,6 +1679,8 @@ catan (complex double z) #if !defined(HAVE_CATANL) && defined(HAVE_CLOGL) #define HAVE_CACOSL 1 +complex long double catanl (complex long double z); + complex long double catanl (complex long double z) { @@ -1516,6 +1694,8 @@ catanl (complex long double z) #if !defined(HAVE_CASINHF) && defined(HAVE_CLOGF) && defined(HAVE_CSQRTF) #define HAVE_CASINHF 1 +complex float casinhf (complex float z); + complex float casinhf (complex float z) { @@ -1526,6 +1706,8 @@ casinhf (complex float z) #if !defined(HAVE_CASINH) && defined(HAVE_CLOG) && defined(HAVE_CSQRT) #define HAVE_CASINH 1 +complex double casinh (complex double z); + complex double casinh (complex double z) { @@ -1536,6 +1718,8 @@ casinh (complex double z) #if !defined(HAVE_CASINHL) && defined(HAVE_CLOGL) && defined(HAVE_CSQRTL) #define HAVE_CASINHL 1 +complex long double casinhl (complex long double z); + complex long double casinhl (complex long double z) { @@ -1549,6 +1733,8 @@ casinhl (complex long double z) #if !defined(HAVE_CACOSHF) && defined(HAVE_CLOGF) && defined(HAVE_CSQRTF) #define HAVE_CACOSHF 1 +complex float cacoshf (complex float z); + complex float cacoshf (complex float z) { @@ -1559,6 +1745,8 @@ cacoshf (complex float z) #if !defined(HAVE_CACOSH) && defined(HAVE_CLOG) && defined(HAVE_CSQRT) #define HAVE_CACOSH 1 +complex double cacosh (complex double z); + complex double cacosh (complex double z) { @@ -1569,6 +1757,8 @@ cacosh (complex double z) #if !defined(HAVE_CACOSHL) && defined(HAVE_CLOGL) && defined(HAVE_CSQRTL) #define HAVE_CACOSHL 1 +complex long double cacoshl (complex long double z); + complex long double cacoshl (complex long double z) { @@ -1582,6 +1772,8 @@ cacoshl (complex long double z) #if !defined(HAVE_CATANHF) && defined(HAVE_CLOGF) #define HAVE_CATANHF 1 +complex float catanhf (complex float z); + complex float catanhf (complex float z) { @@ -1592,6 +1784,8 @@ catanhf (complex float z) #if !defined(HAVE_CATANH) && defined(HAVE_CLOG) #define HAVE_CATANH 1 +complex double catanh (complex double z); + complex double catanh (complex double z) { @@ -1601,6 +1795,8 @@ catanh (complex double z) #if !defined(HAVE_CATANHL) && defined(HAVE_CLOGL) #define HAVE_CATANHL 1 +complex long double catanhl (complex long double z); + complex long double catanhl (complex long double z) { @@ -1611,8 +1807,7 @@ catanhl (complex long double z) #if !defined(HAVE_TGAMMA) #define HAVE_TGAMMA 1 - -extern double tgamma (double); +double tgamma (double); /* Fallback tgamma() function. Uses the algorithm from http://www.netlib.org/specfun/gamma and references therein. */ @@ -1652,7 +1847,7 @@ tgamma (double x) static double eps = 0; if (eps == 0) - eps = nextafter(1., 2.) - 1.; + eps = nextafter (1., 2.) - 1.; parity = 0; fact = 1; @@ -1665,14 +1860,14 @@ tgamma (double x) if (y <= 0) { y = -x; - y1 = trunc(y); + y1 = trunc (y); res = y - y1; if (res != 0) { - if (y1 != trunc(y1*0.5l)*2) + if (y1 != trunc (y1*0.5l)*2) parity = 1; - fact = -PI / sin(PI*res); + fact = -PI / sin (PI*res); y = y + 1; } else @@ -1730,8 +1925,8 @@ tgamma (double x) sum = sum / ysq + c[i]; sum = sum/y - y + SQRTPI; - sum = sum + (y - 0.5) * log(y); - res = exp(sum); + sum = sum + (y - 0.5) * log (y); + res = exp (sum); } else return x < 0 ? xnan : xinf; @@ -1750,8 +1945,7 @@ tgamma (double x) #if !defined(HAVE_LGAMMA) #define HAVE_LGAMMA 1 - -extern double lgamma (double); +double lgamma (double); /* Fallback lgamma() function. Uses the algorithm from http://www.netlib.org/specfun/algama and references therein, @@ -1818,17 +2012,17 @@ lgamma (double y) double corr, res, xden, xm1, xm2, xm4, xnum, ysq; if (eps == 0) - eps = __builtin_nextafter(1., 2.) - 1.; + eps = __builtin_nextafter (1., 2.) - 1.; if ((y > 0) && (y <= xbig)) { if (y <= eps) - res = -log(y); + res = -log (y); else if (y <= 1.5) { if (y < PNT68) { - corr = -log(y); + corr = -log (y); xm1 = y; } else @@ -1896,7 +2090,7 @@ lgamma (double y) res = res / ysq + c[i]; } res = res/y; - corr = log(y); + corr = log (y); res = res + SQRTPI - 0.5*corr; res = res + y*(corr-1); } @@ -1921,7 +2115,7 @@ lgamma (double y) #if defined(HAVE_TGAMMA) && !defined(HAVE_TGAMMAF) #define HAVE_TGAMMAF 1 -extern float tgammaf (float); +float tgammaf (float); float tgammaf (float x) @@ -1932,7 +2126,7 @@ tgammaf (float x) #if defined(HAVE_LGAMMA) && !defined(HAVE_LGAMMAF) #define HAVE_LGAMMAF 1 -extern float lgammaf (float); +float lgammaf (float); float lgammaf (float x) diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 5ef1785e213..e10c45589a4 100644 --- a/libgomp/ChangeLog +++ b/libgomp/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/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 6033935edc3..b2f41208bf8 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,19 @@ +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. + +2009-07-27 Douglas B Rupp <rupp@gnat.com> + + * pex-unix.c (vfork): Remove VMS specific definition (get from header + file instead). + (to_ptr32): New function. + (pex_unix_exec_child): Use it. + 2009-07-24 Ian Lance Taylor <iant@google.com> PR bootstrap/40854 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/libiberty/make-temp-file.c b/libiberty/make-temp-file.c index eadcf850213..13e19256534 100644 --- a/libiberty/make-temp-file.c +++ b/libiberty/make-temp-file.c @@ -1,5 +1,5 @@ /* Utility to pick a temporary filename prefix. - Copyright (C) 1996, 1997, 1998, 2001 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 2001, 2009 Free Software Foundation, Inc. This file is part of the libiberty library. Libiberty is free software; you can redistribute it and/or @@ -111,9 +111,14 @@ choose_tmpdir (void) char *tmpdir; unsigned int len; +#ifdef VMS + /* Try VMS standard temp logical. */ + base = try_dir ("/sys$scratch", base); +#else base = try_dir (getenv ("TMPDIR"), base); base = try_dir (getenv ("TMP"), base); base = try_dir (getenv ("TEMP"), base); +#endif #ifdef P_tmpdir base = try_dir (P_tmpdir, base); diff --git a/libiberty/pex-unix.c b/libiberty/pex-unix.c index 366e96ef8d2..baf2bb4995b 100644 --- a/libiberty/pex-unix.c +++ b/libiberty/pex-unix.c @@ -1,7 +1,7 @@ /* Utilities to execute a program in a subprocess (possibly linked by pipes with other subprocesses), and wait for it. Generic Unix version (also used for UWIN and VMS). - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2009 Free Software Foundation, Inc. This file is part of the libiberty library. @@ -65,11 +65,40 @@ extern int errno; #ifdef HAVE_VFORK_H #include <vfork.h> #endif -#ifdef VMS -#define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \ - lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1) -#endif /* VMS */ +#if defined(VMS) && defined (__LONG_POINTERS) +#ifndef __CHAR_PTR32 +typedef char * __char_ptr32 +__attribute__ ((mode (SI))); +#endif + +typedef __char_ptr32 *__char_ptr_char_ptr32 +__attribute__ ((mode (SI))); + +/* Return a 32 bit pointer to an array of 32 bit pointers + given a 64 bit pointer to an array of 64 bit pointers. */ + +static __char_ptr_char_ptr32 +to_ptr32 (char **ptr64) +{ + int argc; + __char_ptr_char_ptr32 short_argv; + + for (argc=0; ptr64[argc]; argc++); + /* Reallocate argv with 32 bit pointers. */ + short_argv = (__char_ptr_char_ptr32) decc$malloc + (sizeof (__char_ptr32) * (argc + 1)); + + for (argc=0; ptr64[argc]; argc++) + short_argv[argc] = (__char_ptr32) decc$strdup (ptr64[argc]); + + short_argv[argc] = (__char_ptr32) 0; + return short_argv; + +} +#else +#define to_ptr32(argv) argv +#endif /* File mode to use for private and world-readable files. */ @@ -425,12 +454,12 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, if ((flags & PEX_SEARCH) != 0) { - execvp (executable, argv); + execvp (executable, to_ptr32 (argv)); pex_child_error (obj, executable, "execvp", errno); } else { - execv (executable, argv); + execv (executable, to_ptr32 (argv)); pex_child_error (obj, executable, "execv", errno); } diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 477d5365009..a4784e51ffb 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,24 @@ +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 + dump file name base. + +2009-07-27 Andrew John Hughes <ahughes@redhat.com> + + PR libgcj/40616 + * java/io/PrintStream.class: Regenerated. + * java/io/PrintStream.h: Updated. + * java/io/PrintStream.java: + (PrintStream(File)): Ported from GNU Classpath + version. + (PrintStream(File, String)): Likewise. + (PrintStream(String)): Likewise. + (PrintStream(String, String)): Likewise. + 2009-07-24 Kai Tietz <kai.tietz@onevision.com> * gnu/java/security/jce/prng/natVMSecureRandomWin32.cc: New Win32 diff --git a/libjava/classpath/lib/java/io/PrintStream.class b/libjava/classpath/lib/java/io/PrintStream.class Binary files differindex c5db701b9df..78d5cd79aa8 100644 --- a/libjava/classpath/lib/java/io/PrintStream.class +++ b/libjava/classpath/lib/java/io/PrintStream.class diff --git a/libjava/classpath/tools/classes/gnu/classpath/tools/gjdoc/ConstructorDocImpl.class b/libjava/classpath/tools/classes/gnu/classpath/tools/gjdoc/ConstructorDocImpl.class Binary files differindex 774e33c0dad..e75c4e09569 100644 --- a/libjava/classpath/tools/classes/gnu/classpath/tools/gjdoc/ConstructorDocImpl.class +++ b/libjava/classpath/tools/classes/gnu/classpath/tools/gjdoc/ConstructorDocImpl.class 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/libjava/gnu/gcj/util/natGCInfo.cc b/libjava/gnu/gcj/util/natGCInfo.cc index a9240961f8b..a5936174da7 100644 --- a/libjava/gnu/gcj/util/natGCInfo.cc +++ b/libjava/gnu/gcj/util/natGCInfo.cc @@ -407,7 +407,7 @@ nomem_handler(size_t size) if (oomDumpName) { char temp[strlen(oomDumpName) + 20]; - sprintf(temp, "%s%03d", temp, GC_dump_count++); + sprintf(temp, "%s%03d", oomDumpName, GC_dump_count++); printf("nomem_handler(%zd) called\n", size); gc_ok--; GC_enumerator x(temp); diff --git a/libjava/java/io/PrintStream.h b/libjava/java/io/PrintStream.h index b76912e34ef..6247ba8292c 100644 --- a/libjava/java/io/PrintStream.h +++ b/libjava/java/io/PrintStream.h @@ -29,6 +29,10 @@ class java::io::PrintStream : public ::java::io::FilterOutputStream public: PrintStream(::java::io::OutputStream *); PrintStream(::java::io::OutputStream *, jboolean); + PrintStream(::java::io::File *); + PrintStream(::java::io::File *, ::java::lang::String *); + PrintStream(::java::lang::String *); + PrintStream(::java::lang::String *, ::java::lang::String *); PrintStream(::java::io::OutputStream *, jboolean, ::java::lang::String *); virtual jboolean checkError(); public: // actually protected diff --git a/libjava/java/io/PrintStream.java b/libjava/java/io/PrintStream.java index d3f386dc083..be28619059a 100644 --- a/libjava/java/io/PrintStream.java +++ b/libjava/java/io/PrintStream.java @@ -123,6 +123,74 @@ public class PrintStream extends FilterOutputStream implements Appendable } /** + * This method initializes a new <code>PrintStream</code> object to write + * to the specified output File. Doesn't autoflush. + * + * @param file The <code>File</code> to write to. + * @throws FileNotFoundException if an error occurs while opening the file. + * + * @since 1.5 + */ + public PrintStream (File file) + throws FileNotFoundException + { + this (new FileOutputStream(file), false); + } + + /** + * This method initializes a new <code>PrintStream</code> object to write + * to the specified output File. Doesn't autoflush. + * + * @param file The <code>File</code> to write to. + * @param encoding The name of the character encoding to use for this + * object. + * @throws FileNotFoundException If an error occurs while opening the file. + * @throws UnsupportedEncodingException If the charset specified by + * <code>encoding</code> is invalid. + * + * @since 1.5 + */ + public PrintStream (File file, String encoding) + throws FileNotFoundException,UnsupportedEncodingException + { + this (new FileOutputStream(file), false, encoding); + } + + /** + * This method initializes a new <code>PrintStream</code> object to write + * to the specified output File. Doesn't autoflush. + * + * @param fileName The name of the <code>File</code> to write to. + * @throws FileNotFoundException if an error occurs while opening the file, + * + * @since 1.5 + */ + public PrintStream (String fileName) + throws FileNotFoundException + { + this (new FileOutputStream(new File(fileName)), false); + } + + /** + * This method initializes a new <code>PrintStream</code> object to write + * to the specified output File. Doesn't autoflush. + * + * @param fileName The name of the <code>File</code> to write to. + * @param encoding The name of the character encoding to use for this + * object. + * @throws FileNotFoundException if an error occurs while opening the file. + * @throws UnsupportedEncodingException If the charset specified by + * <code>encoding</code> is invalid. + * + * @since 1.5 + */ + public PrintStream (String fileName, String encoding) + throws FileNotFoundException,UnsupportedEncodingException + { + this (new FileOutputStream(new File(fileName)), false, encoding); + } + + /** * This method intializes a new <code>PrintStream</code> object to write * to the specified output sink. This constructor also allows "auto-flush" * functionality to be specified where the stream will be flushed after 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 21f67c5d670..a1e43db356c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,60 @@ +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 + * config/abi/pre/gnu.ver: Avoid exporting inadvertently std::mutex + symbols at GLIBCXX_3.4. + +2009-07-29 Paolo Carlini <paolo.carlini@oracle.com> + + * config/abi/pre/gnu.ver: Add GLIBCXX_3.4.13, move a symbol into it. + * testsuite/util/testsuite_abi.cc: Adjust. + * configure.ac: Bump libtool_VERSION to 6:13:0. + * configure: Regenerate. + +2009-07-28 Benjamin Kosnik <bkoz@redhat.com> + Tyler Earman <rem.intellegare@gmail.com> + + * doc/xml/manual/configure.xml: Consistent placement of + ABI-changing options, clarify --enable-clocale. + +2009-07-28 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * python/Makefile.in: Regenerate. + +2009-07-27 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * python/Makefile.am (install-data-local): Use DESTDIR + correctly. + 2009-07-24 Jason Merrill <jason@redhat.com> Core issue 901 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/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 3a24dc9fb16..9fcf6ce7a10 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -108,7 +108,10 @@ GLIBCXX_3.4 { std::locale::_S_normalize_category*; std::locale::_[T-Za-z]*; # std::[A-Zm-r]*; - std::[A-Zm]*; +# std::[A-Zm]*; + std::[A-Z]*; + std::messages*; + std::money*; # std::n[^u]*; std::n[^au]*; std::nu[^m]*; @@ -964,10 +967,14 @@ GLIBCXX_3.4.12 { _ZSt27__set_once_functor_lock_ptrPSt11unique_lockISt5mutexE; _ZSt16__get_once_mutexv; +} GLIBCXX_3.4.11; + +GLIBCXX_3.4.13 { + # future _ZSt15future_category; -} GLIBCXX_3.4.11; +} GLIBCXX_3.4.12; # Symbols in the support library (libsupc++) have their own tag. CXXABI_1.3 { diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 13f477ed34b..8d09b543257 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -1567,7 +1567,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu ### am handles this now? ORIGINAL_LD_FOR_MULTILIBS=$LD # For libtool versioning info, format is CURRENT:REVISION:AGE -libtool_VERSION=6:12:0 +libtool_VERSION=6:13:0 # Find the rest of the source tree framework. diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac index 334e918e349..977e12cf91d 100644 --- a/libstdc++-v3/configure.ac +++ b/libstdc++-v3/configure.ac @@ -12,7 +12,7 @@ AC_CONFIG_HEADER(config.h) ### am handles this now? ORIGINAL_LD_FOR_MULTILIBS=$LD # For libtool versioning info, format is CURRENT:REVISION:AGE -libtool_VERSION=6:12:0 +libtool_VERSION=6:13:0 AC_SUBST(libtool_VERSION) # Find the rest of the source tree framework. diff --git a/libstdc++-v3/doc/xml/manual/configure.xml b/libstdc++-v3/doc/xml/manual/configure.xml index 7fa5a1e14a7..3a827b0bd22 100644 --- a/libstdc++-v3/doc/xml/manual/configure.xml +++ b/libstdc++-v3/doc/xml/manual/configure.xml @@ -29,7 +29,7 @@ Here are all of the configure options specific to libstdc++. Keep in mind that <!-- This SECnn should be the "Choosing Package Options" section. --> - <ulink url="http://www.gnu.org/software/autoconf/manual/autoconf-2.57/html_node/autoconf_131.html#SEC131">they + <ulink url="http://sourceware.org/autobook/autobook/autobook_14.html">they all have opposite forms as well</ulink> (enable/disable and with/without). The defaults are for the <emphasis>current development sources</emphasis>, which may be different than those @@ -75,28 +75,28 @@ <varlistentry><term><code>--with-gxx-include-dir=<include-files dir></code></term> <listitem><para>Adds support for named libstdc++ include directory. For instance, the following puts all the libstdc++ headers into a directory - called "2.97-20001008" instead of the usual + called "4.4-20090404" instead of the usual "c++/(version)". </para> <programlisting> - --with-gxx-include-dir=/foo/H-x86-gcc-3-c-gxx-inc/include/2.97-20001008</programlisting> </listitem></varlistentry> + --with-gxx-include-dir=/foo/H-x86-gcc-3-c-gxx-inc/include/4.4-20090404</programlisting> </listitem></varlistentry> <varlistentry><term><code>--enable-cstdio</code></term> <listitem><para>This is an abbreviated form of <code>'--enable-cstdio=stdio'</code> - (described next). This option can change the library ABI. + (described next). </para> </listitem></varlistentry> <varlistentry><term><code>--enable-cstdio=OPTION</code></term> <listitem><para>Select a target-specific I/O package. At the moment, the only choice is to use 'stdio', a generic "C" abstraction. - The default is 'stdio'. + The default is 'stdio'. This option can change the library ABI. </para> </listitem></varlistentry> <varlistentry><term><code>--enable-clocale</code></term> <listitem><para>This is an abbreviated form of <code>'--enable-clocale=generic'</code> - (described next). This option can change the library ABI. + (described next). </para> </listitem></varlistentry> @@ -110,19 +110,19 @@ abstraction which consists of "C" locale info. </para> - <para>As part of the configuration process, the "C" library is - probed both for sufficient vintage, and installed locale - data. If either of these elements are not present, the C++ - locale model default to 'generic.' On glibc-based systems of - version 2.2.5 and above with installed locale files, 'gnu' is - automatically selected. + <para>If not explicitly specified, the configure proccess tries + to guess the most suitable package from the choices above. The + default is 'generic'. On glibc-based systems of sufficient + vintage (2.2.5 and newer) and capability (with installed DE and + FR locale data), 'gnu' is automatically selected. This option + can change the library ABI. </para> </listitem></varlistentry> <varlistentry><term><code>--enable-libstdcxx-allocator</code></term> <listitem><para>This is an abbreviated form of <code>'--enable-libstdcxx-allocator=auto'</code> (described - next). This option can change the library ABI. + next). </para> </listitem></varlistentry> @@ -131,8 +131,9 @@ choices are 'new' to specify a wrapper for new, 'malloc' to specify a wrapper for malloc, 'mt' for a fixed power of two allocator, 'pool' for the SGI pooled allocator or 'bitmap' for a bitmap allocator. - This option can change the library ABI. See this page for more information on allocator - <link linkend="allocator.ext">extensions</link> + See this page for more information on allocator + <link linkend="allocator.ext">extensions</link>. This option + can change the library ABI. </para> </listitem></varlistentry> @@ -141,20 +142,22 @@ compatibility with C++. Options are c, c_std, and c_global. These correspond to the source directory's include/c, include/c_std, and include/c_global, and may also include - include/c_compatibility. The default is c_global. + include/c_compatibility. The default is 'c_global'. </para> </listitem></varlistentry> <varlistentry><term><code>--enable-threads</code></term> <listitem><para>This is an abbreviated form of <code>'--enable-threads=yes'</code> - (described next). This option can change the library ABI. + (described next). </para> </listitem></varlistentry> <varlistentry><term><code>--enable-threads=OPTION</code></term> - <listitem><para>Select a threading library. A full description is given in the + <listitem><para>Select a threading library. A full description is + given in the general <ulink url="http://gcc.gnu.org/install/configure.html">compiler - configuration instructions</ulink>. + configuration instructions</ulink>. This option can change the + library ABI. </para> </listitem></varlistentry> diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono new file mode 100644 index 00000000000..aa4888d9a9d --- /dev/null +++ b/libstdc++-v3/include/std/chrono @@ -0,0 +1,694 @@ +// <chrono> -*- C++ -*- + +// 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. + +// 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/>. + +/** @file include/chrono + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_CHRONO +#define _GLIBCXX_CHRONO 1 + +#pragma GCC system_header + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ +# include <c++0x_warning.h> +#else + +#ifdef _GLIBCXX_INCLUDE_AS_TR1 +# error C++0x header cannot be included from TR1 header +#endif + +#include <ratio> +#include <type_traits> +#include <limits> +#include <ctime> + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + +namespace std +{ + /** + * @defgroup chrono Time + * @ingroup utilities + * + * Classes and functions for time. + * @{ + */ + + /** @namespace std::chrono + * @brief ISO C++ 0x entities sub namespace for time and date. + */ + namespace chrono + { + template<typename _Rep, typename _Period = ratio<1>> + struct duration; + + template<typename _Clock, typename _Duration = typename _Clock::duration> + struct time_point; + } + + // 20.8.2.3 specialization of common_type (for duration) + template<typename _Rep1, typename _Period1, typename _Rep2, typename _Period2> + struct common_type<chrono::duration<_Rep1, _Period1>, + chrono::duration<_Rep2, _Period2>> + { + typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type, + ratio<__static_gcd<_Period1::num, _Period2::num>::value, + (_Period1::den / __static_gcd<_Period1::den, _Period2::den>::value) + * _Period2::den>> type; + }; + + // 20.8.2.3 specialization of common_type (for time_point) + template<typename _Clock, typename _Duration1, typename _Duration2> + struct common_type<chrono::time_point<_Clock, _Duration1>, + chrono::time_point<_Clock, _Duration2>> + { + typedef chrono::time_point<_Clock, + typename common_type<_Duration1, _Duration2>::type> type; + }; + + namespace chrono + { + // Primary template for duration_cast impl. + template<typename _ToDuration, typename _CF, typename _CR, + bool _NumIsOne = false, bool _DenIsOne = false> + struct __duration_cast_impl + { + template<typename _Rep, typename _Period> + static _ToDuration __cast(const duration<_Rep, _Period>& __d) + { + return _ToDuration(static_cast< + typename _ToDuration::rep>(static_cast<_CR>(__d.count()) + * static_cast<_CR>(_CF::num) + / static_cast<_CR>(_CF::den))); + } + }; + + template<typename _ToDuration, typename _CF, typename _CR> + struct __duration_cast_impl<_ToDuration, _CF, _CR, true, true> + { + template<typename _Rep, typename _Period> + static _ToDuration __cast(const duration<_Rep, _Period>& __d) + { + return _ToDuration( + static_cast<typename _ToDuration::rep>(__d.count())); + } + }; + + template<typename _ToDuration, typename _CF, typename _CR> + struct __duration_cast_impl<_ToDuration, _CF, _CR, true, false> + { + template<typename _Rep, typename _Period> + static _ToDuration __cast(const duration<_Rep, _Period>& __d) + { + return _ToDuration(static_cast<typename _ToDuration::rep>( + static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den))); + } + }; + + template<typename _ToDuration, typename _CF, typename _CR> + struct __duration_cast_impl<_ToDuration, _CF, _CR, false, true> + { + template<typename _Rep, typename _Period> + static _ToDuration __cast(const duration<_Rep, _Period>& __d) + { + return _ToDuration(static_cast<typename _ToDuration::rep>( + static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num))); + } + }; + + /// duration_cast + template<typename _ToDuration, typename _Rep, typename _Period> + inline _ToDuration + duration_cast(const duration<_Rep, _Period>& __d) + { + typedef typename + ratio_divide<_Period, typename _ToDuration::period>::type __cf; + typedef typename + common_type<typename _ToDuration::rep, _Rep, intmax_t>::type __cr; + + return __duration_cast_impl<_ToDuration, __cf, __cr, + __cf::num == 1, __cf::den == 1>::__cast(__d); + } + + /// treat_as_floating_point + template<typename _Rep> + struct treat_as_floating_point + : is_floating_point<_Rep> + { }; + + /// duration_values + template<typename _Rep> + struct duration_values + { + static const _Rep + zero() + { return _Rep(0); } + + static const _Rep + max() + { return numeric_limits<_Rep>::max(); } + + static const _Rep + min() + { return numeric_limits<_Rep>::min(); } + }; + + template<typename _Tp> + struct __is_duration + : std::false_type + { }; + + template<typename _Rep, typename _Period> + struct __is_duration<duration<_Rep, _Period>> + : std::true_type + { }; + + template<typename T> + struct __is_ratio + : std::false_type + { }; + + template<intmax_t _Num, intmax_t _Den> + struct __is_ratio<ratio<_Num, _Den>> + : std::true_type + { }; + + /// duration + template<typename _Rep, typename _Period> + struct duration + { + static_assert(!__is_duration<_Rep>::value, "rep cannot be a duration"); + static_assert(__is_ratio<_Period>::value, + "period must be a specialization of ratio"); + static_assert(_Period::num > 0, "period must be positive"); + + typedef _Rep rep; + typedef _Period period; + + // 20.8.3.1 construction / copy / destroy + duration() = default; + + template<typename _Rep2> + explicit duration(const _Rep2& __rep) + : __r(static_cast<rep>(__rep)) + { + static_assert(is_convertible<_Rep2,rep>::value + && (treat_as_floating_point<rep>::value + || !treat_as_floating_point<_Rep2>::value), + "cannot construct integral duration with floating point type"); + } + + template<typename _Rep2, typename _Period2> + duration(const duration<_Rep2, _Period2>& __d) + : __r(duration_cast<duration>(__d).count()) + { + static_assert(treat_as_floating_point<rep>::value == true + || ratio_divide<_Period2, period>::type::den == 1, + "the resulting duration is not exactly representable"); + } + + ~duration() = default; + duration(const duration&) = default; + duration& operator=(const duration&) = default; + + // 20.8.3.2 observer + rep + count() const + { return __r; } + + // 20.8.3.3 arithmetic + duration + operator+() const + { return *this; } + + duration + operator-() const + { return duration(-__r); } + + duration& + operator++() + { + ++__r; + return *this; + } + + duration + operator++(int) + { return duration(__r++); } + + duration& + operator--() + { + --__r; + return *this; + } + + duration + operator--(int) + { return duration(__r--); } + + duration& + operator+=(const duration& __d) + { + __r += __d.count(); + return *this; + } + + duration& + operator-=(const duration& __d) + { + __r -= __d.count(); + return *this; + } + + duration& + operator*=(const rep& __rhs) + { + __r *= __rhs; + return *this; + } + + duration& + operator/=(const rep& __rhs) + { + __r /= __rhs; + return *this; + } + + // DR 934. + template<typename _Rep2 = rep> + typename enable_if<!treat_as_floating_point<_Rep2>::value, + duration&>::type + operator%=(const rep& __rhs) + { + __r %= __rhs; + return *this; + } + + template<typename _Rep2 = rep> + typename enable_if<!treat_as_floating_point<_Rep2>::value, + duration&>::type + operator%=(const duration& __d) + { + __r %= __d.count(); + return *this; + } + + // 20.8.3.4 special values + // TODO: These should be constexprs. + static const duration + zero() + { return duration(duration_values<rep>::zero()); } + + static const duration + min() + { return duration(duration_values<rep>::min()); } + + static const duration + max() + { return duration(duration_values<rep>::max()); } + + private: + rep __r; + }; + + template<typename _Rep1, typename _Period1, + typename _Rep2, typename _Period2> + inline typename common_type<duration<_Rep1, _Period1>, + duration<_Rep2, _Period2>>::type + operator+(const duration<_Rep1, _Period1>& __lhs, + const duration<_Rep2, _Period2>& __rhs) + { + typedef typename common_type<duration<_Rep1, _Period1>, + duration<_Rep2, _Period2>>::type __ct; + return __ct(__lhs) += __rhs; + } + + template<typename _Rep1, typename _Period1, + typename _Rep2, typename _Period2> + inline typename common_type<duration<_Rep1, _Period1>, + duration<_Rep2, _Period2>>::type + operator-(const duration<_Rep1, _Period1>& __lhs, + const duration<_Rep2, _Period2>& __rhs) + { + typedef typename common_type<duration<_Rep1, _Period1>, + duration<_Rep2, _Period2>>::type __ct; + return __ct(__lhs) -= __rhs; + } + + template<typename _Rep1, typename _Period, typename _Rep2> + inline duration<typename common_type<_Rep1, _Rep2>::type, _Period> + operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) + { + typedef typename common_type<_Rep1, _Rep2>::type __cr; + return duration<__cr, _Period>(__d) *= __s; + } + + template<typename _Rep1, typename _Period, typename _Rep2> + inline duration<typename common_type<_Rep1, _Rep2>::type, _Period> + operator*(const _Rep2& __s, const duration<_Rep1, _Period>& __d) + { return __d * __s; } + + template<typename _Rep1, typename _Period, typename _Rep2> + inline duration<typename common_type<_Rep1, typename + enable_if<!__is_duration<_Rep2>::value, _Rep2>::type>::type, _Period> + operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) + { + typedef typename common_type<_Rep1, _Rep2>::type __cr; + return duration<__cr, _Period>(__d) /= __s; + } + + template<typename _Rep1, typename _Period1, + typename _Rep2, typename _Period2> + inline typename common_type<_Rep1, _Rep2>::type + operator/(const duration<_Rep1, _Period1>& __lhs, + const duration<_Rep2, _Period2>& __rhs) + { + typedef typename common_type<duration<_Rep1, _Period1>, + duration<_Rep2, _Period2>>::type __ct; + return __ct(__lhs).count() / __ct(__rhs).count(); + } + + // DR 934. + template<typename _Rep1, typename _Period, typename _Rep2> + inline duration<typename common_type<_Rep1, typename + enable_if<!__is_duration<_Rep2>::value, _Rep2>::type>::type, _Period> + operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) + { + typedef typename common_type<_Rep1, _Rep2>::type __cr; + return duration<__cr, _Period>(__d) %= __s; + } + + template<typename _Rep1, typename _Period1, + typename _Rep2, typename _Period2> + inline typename common_type<duration<_Rep1, _Period1>, + duration<_Rep2, _Period2>>::type + operator%(const duration<_Rep1, _Period1>& __lhs, + const duration<_Rep2, _Period2>& __rhs) + { + typedef typename common_type<duration<_Rep1, _Period1>, + duration<_Rep2, _Period2>>::type __ct; + return __ct(__lhs) %= __rhs; + } + + // comparisons + template<typename _Rep1, typename _Period1, + typename _Rep2, typename _Period2> + inline bool + operator==(const duration<_Rep1, _Period1>& __lhs, + const duration<_Rep2, _Period2>& __rhs) + { + typedef typename common_type<duration<_Rep1, _Period1>, + duration<_Rep2, _Period2>>::type __ct; + return __ct(__lhs).count() == __ct(__rhs).count(); + } + + template<typename _Rep1, typename _Period1, + typename _Rep2, typename _Period2> + inline bool + operator<(const duration<_Rep1, _Period1>& __lhs, + const duration<_Rep2, _Period2>& __rhs) + { + typedef typename common_type<duration<_Rep1, _Period1>, + duration<_Rep2, _Period2>>::type __ct; + return __ct(__lhs).count() < __ct(__rhs).count(); + } + + template<typename _Rep1, typename _Period1, + typename _Rep2, typename _Period2> + inline bool + operator!=(const duration<_Rep1, _Period1>& __lhs, + const duration<_Rep2, _Period2>& __rhs) + { return !(__lhs == __rhs); } + + template<typename _Rep1, typename _Period1, + typename _Rep2, typename _Period2> + inline bool + operator<=(const duration<_Rep1, _Period1>& __lhs, + const duration<_Rep2, _Period2>& __rhs) + { return !(__rhs < __lhs); } + + template<typename _Rep1, typename _Period1, + typename _Rep2, typename _Period2> + inline bool + operator>(const duration<_Rep1, _Period1>& __lhs, + const duration<_Rep2, _Period2>& __rhs) + { return __rhs < __lhs; } + + template<typename _Rep1, typename _Period1, + typename _Rep2, typename _Period2> + inline bool + operator>=(const duration<_Rep1, _Period1>& __lhs, + const duration<_Rep2, _Period2>& __rhs) + { return !(__lhs < __rhs); } + + /// nanoseconds + typedef duration<int64_t, nano> nanoseconds; + + /// microseconds + typedef duration<int64_t, micro> microseconds; + + /// milliseconds + typedef duration<int64_t, milli> milliseconds; + + /// seconds + typedef duration<int64_t > seconds; + + /// minutes + typedef duration<int, ratio< 60>> minutes; + + /// hours + typedef duration<int, ratio<3600>> hours; + + /// time_point + template<typename _Clock, typename _Duration> + struct time_point + { + typedef _Clock clock; + typedef _Duration duration; + typedef typename duration::rep rep; + typedef typename duration::period period; + + time_point() : __d(duration::zero()) + { } + + explicit time_point(const duration& __dur) + : __d(duration::zero() + __dur) + { } + + // conversions + template<typename _Duration2> + time_point(const time_point<clock, _Duration2>& __t) + : __d(__t.time_since_epoch()) + { } + + // observer + duration + time_since_epoch() const + { return __d; } + + // arithmetic + time_point& + operator+=(const duration& __dur) + { + __d += __dur; + return *this; + } + + time_point& + operator-=(const duration& __dur) + { + __d -= __dur; + return *this; + } + + // special values + // TODO: These should be constexprs. + static const time_point + min() + { return time_point(duration::min()); } + + static const time_point + max() + { return time_point(duration::max()); } + + private: + duration __d; + }; + + /// time_point_cast + template<typename _ToDuration, typename _Clock, typename _Duration> + inline time_point<_Clock, _ToDuration> + time_point_cast(const time_point<_Clock, _Duration>& __t) + { + return time_point<_Clock, _ToDuration>( + duration_cast<_ToDuration>(__t.time_since_epoch())); + } + + template<typename _Clock, typename _Duration1, + typename _Rep2, typename _Period2> + inline time_point<_Clock, + typename common_type<_Duration1, duration<_Rep2, _Period2>>::type> + operator+(const time_point<_Clock, _Duration1>& __lhs, + const duration<_Rep2, _Period2>& __rhs) + { + typedef time_point<_Clock, + typename common_type<_Duration1, + duration<_Rep2, _Period2>>::type> __ct; + return __ct(__lhs) += __rhs; + } + + template<typename _Rep1, typename _Period1, + typename _Clock, typename _Duration2> + inline time_point<_Clock, + typename common_type<duration<_Rep1, _Period1>, _Duration2>::type> + operator+(const duration<_Rep1, _Period1>& __lhs, + const time_point<_Clock, _Duration2>& __rhs) + { return __rhs + __lhs; } + + template<typename _Clock, typename _Duration1, + typename _Rep2, typename _Period2> + inline time_point<_Clock, + typename common_type<_Duration1, duration<_Rep2, _Period2>>::type> + operator-(const time_point<_Clock, _Duration1>& __lhs, + const duration<_Rep2, _Period2>& __rhs) + { return __lhs + (-__rhs); } + + template<typename _Clock, typename _Duration1, typename _Duration2> + inline typename common_type<_Duration1, _Duration2>::type + operator-(const time_point<_Clock, _Duration1>& __lhs, + const time_point<_Clock, _Duration2>& __rhs) + { return __lhs.time_since_epoch() - __rhs.time_since_epoch(); } + + template<typename _Clock, typename _Duration1, typename _Duration2> + inline bool + operator==(const time_point<_Clock, _Duration1>& __lhs, + const time_point<_Clock, _Duration2>& __rhs) + { return __lhs.time_since_epoch() == __rhs.time_since_epoch(); } + + template<typename _Clock, typename _Duration1, typename _Duration2> + inline bool + operator!=(const time_point<_Clock, _Duration1>& __lhs, + const time_point<_Clock, _Duration2>& __rhs) + { return !(__lhs == __rhs); } + + template<typename _Clock, typename _Duration1, typename _Duration2> + inline bool + operator<(const time_point<_Clock, _Duration1>& __lhs, + const time_point<_Clock, _Duration2>& __rhs) + { return __lhs.time_since_epoch() < __rhs.time_since_epoch(); } + + template<typename _Clock, typename _Duration1, typename _Duration2> + inline bool + operator<=(const time_point<_Clock, _Duration1>& __lhs, + const time_point<_Clock, _Duration2>& __rhs) + { return !(__rhs < __lhs); } + + template<typename _Clock, typename _Duration1, typename _Duration2> + inline bool + operator>(const time_point<_Clock, _Duration1>& __lhs, + const time_point<_Clock, _Duration2>& __rhs) + { return __rhs < __lhs; } + + template<typename _Clock, typename _Duration1, typename _Duration2> + inline bool + operator>=(const time_point<_Clock, _Duration1>& __lhs, + const time_point<_Clock, _Duration2>& __rhs) + { return !(__lhs < __rhs); } + + /// system_clock + struct system_clock + { +#ifdef _GLIBCXX_USE_CLOCK_REALTIME + typedef chrono::nanoseconds duration; +#elif defined(_GLIBCXX_USE_GETTIMEOFDAY) + typedef chrono::microseconds duration; +#else + typedef chrono::seconds duration; +#endif + + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point<system_clock, duration> time_point; + + static const bool is_monotonic = false; + + static time_point + now() throw (); + + // Map to C API + static std::time_t + to_time_t(const time_point& __t) + { + return std::time_t( + duration_cast<chrono::seconds>(__t.time_since_epoch()).count()); + } + + static time_point + from_time_t(std::time_t __t) + { + return time_point_cast<system_clock::duration>( + chrono::time_point<system_clock, chrono::seconds>( + chrono::seconds(__t))); + } + + // TODO: requires constexpr + /* + static_assert( + system_clock::duration::min() < + system_clock::duration::zero(), + "a clock's minimum duration cannot be less than its epoch"); + */ + }; + +#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC + /// monotonic_clock + struct monotonic_clock + { + typedef chrono::nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point<monotonic_clock, duration> time_point; + + static const bool is_monotonic = true; + + static time_point + now(); + }; +#else + typedef system_clock monotonic_clock; +#endif + + typedef system_clock high_resolution_clock; + } // namespace chrono + + // @} group chrono +} // namespace std + +#endif //_GLIBCXX_USE_C99_STDINT_TR1 + +#endif //__GXX_EXPERIMENTAL_CXX0X__ + +#endif //_GLIBCXX_CHRONO diff --git a/libstdc++-v3/python/Makefile.am b/libstdc++-v3/python/Makefile.am index 50cc6d94541..457e45ba46d 100644 --- a/libstdc++-v3/python/Makefile.am +++ b/libstdc++-v3/python/Makefile.am @@ -44,7 +44,7 @@ install-data-local: gdb.py ## .la file, and any previous -gdb.py file. This is inherently ## fragile, but there does not seem to be a better option, because ## libtool hides the real names from us. - @here=`pwd`; cd $(toolexeclibdir); \ + @here=`pwd`; cd $(DESTDIR)$(toolexeclibdir); \ for file in libstdc++*; do \ case $$file in \ *-gdb.py) ;; \ diff --git a/libstdc++-v3/python/Makefile.in b/libstdc++-v3/python/Makefile.in index 88cc7ea34c3..44aa2f08de1 100644 --- a/libstdc++-v3/python/Makefile.in +++ b/libstdc++-v3/python/Makefile.in @@ -497,7 +497,7 @@ gdb.py: hook.in Makefile install-data-local: gdb.py @$(mkdir_p) $(DESTDIR)$(toolexeclibdir) - @here=`pwd`; cd $(toolexeclibdir); \ + @here=`pwd`; cd $(DESTDIR)$(toolexeclibdir); \ for file in libstdc++*; do \ case $$file in \ *-gdb.py) ;; \ 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/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/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/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/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc index ca1bb912ce5..ae146babb87 100644 --- a/libstdc++-v3/testsuite/util/testsuite_abi.cc +++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc @@ -184,6 +184,7 @@ check_version(symbol& test, bool added) known_versions.push_back("GLIBCXX_3.4.10"); known_versions.push_back("GLIBCXX_3.4.11"); known_versions.push_back("GLIBCXX_3.4.12"); + known_versions.push_back("GLIBCXX_3.4.13"); known_versions.push_back("GLIBCXX_LDBL_3.4"); known_versions.push_back("GLIBCXX_LDBL_3.4.7"); known_versions.push_back("GLIBCXX_LDBL_3.4.10"); 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) |