From ef5c0ad1f0be177c654766e31c63142a03378a66 Mon Sep 17 00:00:00 2001 From: hjl Date: Fri, 23 Apr 2010 12:26:09 +0000 Subject: [PATCH] Merged r158465 through r158660 into branch. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/ifunc@158664 138bc75d-0d04-0410-961f-82ee72b054a4 --- ChangeLog | 5 + configure | 2 +- configure.ac | 2 +- contrib/ChangeLog | 4 + contrib/gcc_update | 6 + gcc/ChangeLog | 619 ++++++++++++- gcc/DATESTAMP | 2 +- gcc/Makefile.in | 5 - gcc/ada/ChangeLog | 33 + gcc/ada/gcc-interface/decl.c | 207 +++-- gcc/ada/gcc-interface/misc.c | 19 +- gcc/ada/gcc-interface/utils.c | 24 +- gcc/ada/gcc-interface/utils2.c | 34 +- gcc/ada/gsocket.h | 3 +- gcc/ada/uintp.h | 4 + gcc/builtins.c | 88 +- gcc/builtins.def | 6 +- gcc/c-decl.c | 2 +- gcc/c-parser.c | 43 +- gcc/c-tree.h | 10 +- gcc/c-typeck.c | 161 ++-- gcc/cfgexpand.c | 25 +- gcc/cgraph.c | 11 +- gcc/cgraph.h | 6 +- gcc/cgraphunit.c | 13 +- gcc/config/arm/arm.md | 16 +- gcc/config/arm/bpabi-v6m.S | 10 + gcc/config/arm/bpabi.S | 10 + gcc/config/arm/crti.asm | 9 + gcc/config/arm/crtn.asm | 10 + gcc/config/arm/lib1funcs.asm | 4 +- gcc/config/arm/libunwind.S | 10 + gcc/config/avr/avr-devices.c | 49 +- gcc/config/avr/t-avr | 47 +- gcc/config/i386/i386.c | 72 +- gcc/config/i386/i386.md | 492 +++++------ gcc/config/ia64/ia64.c | 3 + gcc/config/ia64/ia64.h | 4 +- gcc/config/rs6000/x-aix | 2 +- gcc/config/s390/s390.c | 24 +- gcc/config/sh/sh.c | 17 + gcc/config/stormy16/stormy16-lib2-ucmpsi2.c | 2 + gcc/config/stormy16/stormy16-lib2.c | 25 +- gcc/config/stormy16/stormy16.c | 2 +- gcc/config/stormy16/stormy16.h | 329 ++----- gcc/config/stormy16/stormy16.md | 33 - gcc/config/stormy16/t-stormy16 | 5 +- gcc/configure | 6 +- gcc/configure.ac | 4 +- gcc/cp/ChangeLog | 38 + gcc/cp/cp-tree.h | 12 +- gcc/cp/cvt.c | 2 + gcc/cp/decl.c | 4 +- gcc/cp/init.c | 9 +- gcc/cp/typeck.c | 26 +- gcc/df-problems.c | 21 +- gcc/df.h | 1 + gcc/dojump.c | 3 +- gcc/double-int.c | 12 + gcc/double-int.h | 1 + gcc/dwarf2out.c | 139 ++- gcc/emit-rtl.c | 12 +- gcc/expmed.c | 53 +- gcc/expr.c | 201 ++--- gcc/fold-const.c | 41 +- gcc/fortran/ChangeLog | 58 ++ gcc/fortran/f95-lang.c | 5 +- gcc/fortran/gfortran.texi | 4 +- gcc/fortran/intrinsic.c | 2 +- gcc/fortran/openmp.c | 29 +- gcc/fortran/resolve.c | 36 +- gcc/fortran/trans-array.c | 32 +- gcc/fortran/trans-decl.c | 3 +- gcc/fortran/trans.c | 1 - gcc/fortran/trans.h | 1 - gcc/gcc.c | 2 +- gcc/gimple-fold.c | 2 +- gcc/gimple.h | 1 + gcc/gimplify.c | 31 +- gcc/ifcvt.c | 73 +- gcc/ipa-cp.c | 3 +- gcc/ipa-inline.c | 29 +- gcc/ipa-prop.c | 6 +- gcc/ipa-pure-const.c | 3 +- gcc/ipa-reference.c | 3 +- gcc/ipa.c | 5 +- gcc/ira-color.c | 4 +- gcc/ira-lives.c | 3 + gcc/java/ChangeLog | 5 + gcc/java/decl.c | 2 +- gcc/lambda-code.c | 84 +- gcc/lambda-mat.c | 73 +- gcc/lambda-trans.c | 16 +- gcc/lambda.h | 11 +- gcc/lto-cgraph.c | 83 +- gcc/lto-section-in.c | 1 - gcc/lto-section-out.c | 42 - gcc/lto-streamer-out.c | 6 +- gcc/lto-streamer.c | 3 - gcc/lto-streamer.h | 4 - gcc/lto-wpa-fixup.c | 282 ------ gcc/lto/ChangeLog | 28 + gcc/lto/lto-lang.c | 2 +- gcc/lto/lto.c | 139 ++- gcc/omp-low.c | 28 +- gcc/optabs.c | 63 +- gcc/optabs.h | 3 + gcc/opts.c | 9 + gcc/passes.c | 118 ++- gcc/po/ChangeLog | 8 + gcc/po/es.po | 203 ++--- gcc/po/zh_CN.po | 195 ++-- gcc/reginfo.c | 2 + gcc/rtl.h | 1 + gcc/simplify-rtx.c | 69 +- gcc/stor-layout.c | 72 +- gcc/testsuite/ChangeLog | 190 +++- gcc/testsuite/g++.dg/debug/dwarf2/enum1.C | 19 + gcc/testsuite/g++.dg/debug/dwarf2/rv1.C | 15 + gcc/testsuite/g++.dg/init/member1.C | 2 +- gcc/testsuite/g++.dg/other/fold1.C | 2 +- gcc/testsuite/g++.dg/parse/crash36.C | 2 +- gcc/testsuite/g++.dg/template/recurse2.C | 7 + gcc/testsuite/g++.dg/template/typedef32.C | 46 + gcc/testsuite/g++.dg/template/typedef33.C | 21 + gcc/testsuite/g++.dg/torture/pr39417.C | 56 ++ gcc/testsuite/g++.dg/tree-ssa/fold-compare.C | 28 + gcc/testsuite/g++.dg/vect/pr43771.cc | 14 + gcc/testsuite/gcc.c-torture/compile/pr43635.c | 7 + gcc/testsuite/gcc.c-torture/compile/pr43845.c | 12 + gcc/testsuite/gcc.c-torture/execute/pr43783.c | 21 + .../gcc.dg/cproj-fails-with-broken-glibc.c | 25 + gcc/testsuite/gcc.dg/graphite/interchange-0.c | 2 +- gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c | 2 +- gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c | 32 + gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c | 175 ++++ gcc/testsuite/gcc.dg/torture/builtin-cproj-2.c | 46 + gcc/testsuite/gcc.dg/vect/pr37027.c | 37 + gcc/testsuite/gcc.dg/vect/pr43842.c | 55 ++ gcc/testsuite/gcc.dg/vect/slp-reduc-1.c | 49 + gcc/testsuite/gcc.dg/vect/slp-reduc-2.c | 44 + gcc/testsuite/gcc.dg/vect/slp-reduc-3.c | 62 ++ gcc/testsuite/gcc.dg/vect/slp-reduc-4.c | 60 ++ gcc/testsuite/gcc.dg/vect/slp-reduc-5.c | 49 + gcc/testsuite/gcc.dg/vect/slp-reduc-6.c | 50 ++ gcc/testsuite/gcc.target/arm/wmul-1.c | 18 + gcc/testsuite/gcc.target/arm/wmul-2.c | 12 + gcc/testsuite/gcc.target/bfin/wmul-1.c | 18 + gcc/testsuite/gcc.target/bfin/wmul-2.c | 12 + gcc/testsuite/gcc.target/i386/pr43662.c | 24 + gcc/testsuite/gcc.target/i386/pr43766.c | 10 + gcc/testsuite/gcc.target/i386/wmul-1.c | 19 + gcc/testsuite/gcc.target/i386/wmul-2.c | 13 + gcc/testsuite/gfortran.dg/abstract_type_6.f03 | 53 ++ gcc/testsuite/gfortran.dg/assign_10.f90 | 8 +- gcc/testsuite/gfortran.dg/bounds_check_fail_3.f90 | 2 +- gcc/testsuite/gfortran.dg/bounds_check_fail_4.f90 | 2 +- gcc/testsuite/gfortran.dg/gomp/pr43337.f90 | 30 + gcc/testsuite/gfortran.dg/gomp/pr43836.f90 | 10 + gcc/testsuite/gfortran.dg/gomp/sharing-2.f90 | 12 +- gcc/testsuite/gfortran.dg/pr43796.f90 | 51 ++ gcc/testsuite/gfortran.dg/proc_decl_23.f90 | 43 + gcc/testsuite/gfortran.dg/reassoc_6.f | 20 + gcc/testsuite/gfortran.dg/vector_subscript_6.f90 | 33 + gcc/testsuite/gnat.dg/rep_clause5.adb | 39 + gcc/testsuite/gnat.dg/rep_clause5.ads | 12 + gcc/testsuite/gnat.dg/rep_clause5_pkg.ads | 383 ++++++++ .../gnat.dg/{sizetype.adb => sizetype1.adb} | 2 +- gcc/testsuite/gnat.dg/sizetype2.adb | 27 + gcc/testsuite/lib/prune.exp | 1 + gcc/testsuite/lib/target-supports.exp | 19 + gcc/timevar.def | 1 - gcc/tree-cfg.c | 7 +- gcc/tree-data-ref.c | 10 +- gcc/tree-data-ref.h | 4 +- gcc/tree-dfa.c | 6 +- gcc/tree-loop-distribution.c | 9 +- gcc/tree-loop-linear.c | 5 +- gcc/tree-nested.c | 5 +- gcc/tree-object-size.c | 3 +- gcc/tree-parloops.c | 12 +- gcc/tree-pass.h | 17 +- gcc/tree-predcom.c | 16 +- gcc/tree-sra.c | 10 +- gcc/tree-ssa-address.c | 6 +- gcc/tree-ssa-math-opts.c | 134 +++ gcc/tree-ssa-phiopt.c | 5 +- gcc/tree-ssa-phiprop.c | 5 +- gcc/tree-ssa-pre.c | 88 +- gcc/tree-ssa-reassoc.c | 37 +- gcc/tree-ssa-structalias.c | 73 +- gcc/tree-tailcall.c | 10 +- gcc/tree-vect-loop.c | 982 +++++++++++++-------- gcc/tree-vect-patterns.c | 10 +- gcc/tree-vect-slp.c | 405 +++++++-- gcc/tree-vect-stmts.c | 13 +- gcc/tree-vectorizer.h | 9 +- gcc/tree-vrp.c | 21 +- gcc/tree.c | 4 +- gcc/tree.h | 17 +- gcc/unwind-dw2-fde.c | 34 +- gcc/unwind-dw2.c | 11 +- gcc/varpool.c | 6 + include/ChangeLog | 4 + include/sha1.h | 4 +- libcpp/po/ChangeLog | 8 + libcpp/po/es.po | 6 +- libcpp/po/zh_CN.po | 8 +- libgomp/ChangeLog | 17 + libgomp/config/linux/affinity.c | 17 +- libgomp/config/linux/proc.c | 24 +- libgomp/sections.c | 20 +- libgomp/testsuite/libgomp.fortran/vla8.f90 | 254 ++++++ libjava/ChangeLog | 5 + libjava/configure | 33 + libjava/configure.ac | 15 + libstdc++-v3/ChangeLog | 17 + libstdc++-v3/doc/html/api.html | 35 +- libstdc++-v3/doc/html/bk02.html | 6 +- libstdc++-v3/doc/html/bk03.html | 6 +- libstdc++-v3/doc/html/faq.html | 16 +- libstdc++-v3/doc/html/manual/abi.html | 157 ++-- libstdc++-v3/doc/html/manual/algorithms.html | 70 +- libstdc++-v3/doc/html/manual/api.html | 14 +- .../doc/html/manual/appendix_contributing.html | 54 +- libstdc++-v3/doc/html/manual/appendix_free.html | 12 +- libstdc++-v3/doc/html/manual/appendix_gfdl.html | 8 +- libstdc++-v3/doc/html/manual/appendix_gpl.html | 12 +- libstdc++-v3/doc/html/manual/appendix_porting.html | 12 +- libstdc++-v3/doc/html/manual/associative.html | 113 ++- libstdc++-v3/doc/html/manual/atomics.html | 31 + libstdc++-v3/doc/html/manual/auto_ptr.html | 90 -- libstdc++-v3/doc/html/manual/backwards.html | 211 +++-- libstdc++-v3/doc/html/manual/bitmap_allocator.html | 14 +- libstdc++-v3/doc/html/manual/bitset.html | 105 --- libstdc++-v3/doc/html/manual/bk01ix01.html | 51 -- libstdc++-v3/doc/html/manual/bk01pt02.html | 46 + libstdc++-v3/doc/html/manual/bk01pt02ch04s02.html | 49 - libstdc++-v3/doc/html/manual/bk01pt02ch04s03.html | 29 - .../{bk01pt03ch08.html => bk01pt02ch05s02.html} | 9 +- libstdc++-v3/doc/html/manual/bk01pt02pr01.html | 17 - libstdc++-v3/doc/html/manual/bk01pt03ch07s02.html | 20 - libstdc++-v3/doc/html/manual/bk01pt03ch07s03.html | 4 - .../{bk01pt12ch30s02.html => bk01pt03ch17s02.html} | 6 +- libstdc++-v3/doc/html/manual/bk01pt03ch17s03.html | 24 + .../{bk01pt12ch30s04.html => bk01pt03ch17s04.html} | 32 +- .../{bk01pt12ch31s02.html => bk01pt03ch18s02.html} | 4 +- .../{bk01pt12ch31s03.html => bk01pt03ch18s03.html} | 6 +- .../{bk01pt12ch31s04.html => bk01pt03ch18s04.html} | 10 +- .../{bk01pt12ch31s05.html => bk01pt03ch18s05.html} | 8 +- .../{bk01pt12ch32s02.html => bk01pt03ch19s02.html} | 22 +- .../{bk01pt12ch32s03.html => bk01pt03ch19s03.html} | 4 +- .../{bk01pt12ch32s04.html => bk01pt03ch19s04.html} | 4 +- .../{bk01pt12ch32s05.html => bk01pt03ch19s05.html} | 14 +- .../{bk01pt12ch32s06.html => bk01pt03ch19s06.html} | 16 +- .../{bk01pt12ch32s07.html => bk01pt03ch19s07.html} | 100 +-- .../{bk01pt12ch34s02.html => bk01pt03ch21s02.html} | 6 +- .../{bk01pt12ch34s03.html => bk01pt03ch21s03.html} | 4 +- .../{bk01pt12ch41s02.html => bk01pt03ch28s02.html} | 6 +- .../{bk01pt12ch41s03.html => bk01pt03ch28s03.html} | 7 +- .../{bk01pt12pr03.html => bk01pt03pr01.html} | 14 +- libstdc++-v3/doc/html/manual/bk01pt04.html | 21 + libstdc++-v3/doc/html/manual/bk01pt05ch13.html | 90 -- libstdc++-v3/doc/html/manual/bk01pt05ch13s02.html | 40 - libstdc++-v3/doc/html/manual/bk01pt05ch13s03.html | 57 -- libstdc++-v3/doc/html/manual/bk01pt05ch13s04.html | 79 -- libstdc++-v3/doc/html/manual/bk01pt05ch13s05.html | 16 - libstdc++-v3/doc/html/manual/bk01pt05ch13s06.html | 94 -- libstdc++-v3/doc/html/manual/bk01pt08ch19.html | 39 - libstdc++-v3/doc/html/manual/bk01pt08ch19s02.html | 86 -- libstdc++-v3/doc/html/manual/bk01pt09ch20.html | 19 - libstdc++-v3/doc/html/manual/bk01pt09pr02.html | 41 - libstdc++-v3/doc/html/manual/bk01pt10ch23s02.html | 19 - libstdc++-v3/doc/html/manual/bk01pt12ch30s03.html | 24 - libstdc++-v3/doc/html/manual/bugs.html | 270 +++--- libstdc++-v3/doc/html/manual/codecvt.html | 379 -------- libstdc++-v3/doc/html/manual/complex.html | 25 - libstdc++-v3/doc/html/manual/concurrency.html | 42 + libstdc++-v3/doc/html/manual/configure.html | 258 +++--- libstdc++-v3/doc/html/manual/containers.html | 64 +- libstdc++-v3/doc/html/manual/containers_and_c.html | 20 +- libstdc++-v3/doc/html/manual/debug.html | 33 +- libstdc++-v3/doc/html/manual/debug_mode.html | 8 +- libstdc++-v3/doc/html/manual/diagnostics.html | 52 +- .../doc/html/manual/documentation_style.html | 76 +- libstdc++-v3/doc/html/manual/dynamic_memory.html | 15 +- libstdc++-v3/doc/html/manual/exceptions.html | 22 - libstdc++-v3/doc/html/manual/ext_algorithms.html | 10 +- libstdc++-v3/doc/html/manual/ext_allocators.html | 80 +- .../doc/html/manual/ext_compile_checks.html | 6 +- libstdc++-v3/doc/html/manual/ext_concurrency.html | 16 +- libstdc++-v3/doc/html/manual/ext_containers.html | 6 +- libstdc++-v3/doc/html/manual/ext_demangling.html | 8 +- libstdc++-v3/doc/html/manual/ext_io.html | 58 +- libstdc++-v3/doc/html/manual/ext_iterators.html | 6 +- libstdc++-v3/doc/html/manual/ext_numerics.html | 6 +- libstdc++-v3/doc/html/manual/ext_utilities.html | 14 +- libstdc++-v3/doc/html/manual/extensions.html | 8 +- libstdc++-v3/doc/html/manual/facets.html | 723 ++++++++++++++- .../manual/{bk01pt11ch27s02.html => fstreams.html} | 77 +- libstdc++-v3/doc/html/manual/functors.html | 15 - .../doc/html/manual/fundamental_types.html | 43 - .../manual/generalized_numeric_operations.html | 11 +- libstdc++-v3/doc/html/manual/internals.html | 86 +- libstdc++-v3/doc/html/manual/intro.html | 2 +- .../html/manual/{iostream_objects.html => io.html} | 30 +- .../manual/{bk01pt11ch28s02.html => io_and_c.html} | 16 +- libstdc++-v3/doc/html/manual/iterators.html | 139 ++- libstdc++-v3/doc/html/manual/license.html | 4 +- .../manual/{locales.html => localization.html} | 69 +- libstdc++-v3/doc/html/manual/memory.html | 511 +++++++++-- libstdc++-v3/doc/html/manual/messages.html | 284 ------ libstdc++-v3/doc/html/manual/numerics.html | 39 +- libstdc++-v3/doc/html/manual/numerics_and_c.html | 22 +- libstdc++-v3/doc/html/manual/pairs.html | 11 +- libstdc++-v3/doc/html/manual/parallel_mode.html | 10 +- libstdc++-v3/doc/html/manual/profile_mode.html | 22 +- libstdc++-v3/doc/html/manual/sequences.html | 43 - libstdc++-v3/doc/html/manual/setup.html | 18 +- libstdc++-v3/doc/html/manual/shared_ptr.html | 304 ------- .../doc/html/manual/source_code_style.html | 92 +- .../doc/html/manual/source_organization.html | 12 +- libstdc++-v3/doc/html/manual/spine.html | 40 +- libstdc++-v3/doc/html/manual/status.html | 28 +- .../{bk01pt11ch25s02.html => streambufs.html} | 76 +- libstdc++-v3/doc/html/manual/strings.html | 375 +++++++- libstdc++-v3/doc/html/manual/stringstreams.html | 10 +- libstdc++-v3/doc/html/manual/support.html | 139 ++- libstdc++-v3/doc/html/manual/termination.html | 172 +++- libstdc++-v3/doc/html/manual/test.html | 10 +- libstdc++-v3/doc/html/manual/traits.html | 20 +- libstdc++-v3/doc/html/manual/using.html | 4 +- .../doc/html/manual/using_concurrency.html | 2 +- .../doc/html/manual/using_dynamic_or_shared.html | 26 +- libstdc++-v3/doc/html/manual/using_exceptions.html | 91 +- libstdc++-v3/doc/html/manual/using_headers.html | 12 +- libstdc++-v3/doc/html/manual/using_macros.html | 10 +- libstdc++-v3/doc/html/manual/utilities.html | 26 +- libstdc++-v3/doc/html/manual/vector.html | 13 - .../doc/html/manual/verbose_termination.html | 79 -- libstdc++-v3/doc/html/spine.html | 38 +- libstdc++-v3/doc/xml/faq.xml | 10 +- .../doc/xml/manual/appendix_contributing.xml | 2 +- libstdc++-v3/doc/xml/manual/prerequisites.xml | 6 + libstdc++-v3/doc/xml/manual/strings.xml | 4 + libstdc++-v3/doc/xml/manual/using.xml | 28 +- libstdc++-v3/include/parallel/partition.h | 146 ++- 347 files changed, 10531 insertions(+), 6396 deletions(-) create mode 100644 gcc/config/stormy16/stormy16-lib2-ucmpsi2.c delete mode 100644 gcc/lto-wpa-fixup.c create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/enum1.C create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/rv1.C create mode 100644 gcc/testsuite/g++.dg/template/recurse2.C create mode 100644 gcc/testsuite/g++.dg/template/typedef32.C create mode 100644 gcc/testsuite/g++.dg/template/typedef33.C create mode 100644 gcc/testsuite/g++.dg/torture/pr39417.C create mode 100644 gcc/testsuite/g++.dg/tree-ssa/fold-compare.C create mode 100644 gcc/testsuite/g++.dg/vect/pr43771.cc create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr43635.c create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr43845.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr43783.c create mode 100644 gcc/testsuite/gcc.dg/cproj-fails-with-broken-glibc.c create mode 100644 gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c create mode 100644 gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c create mode 100644 gcc/testsuite/gcc.dg/torture/builtin-cproj-2.c create mode 100644 gcc/testsuite/gcc.dg/vect/pr37027.c create mode 100644 gcc/testsuite/gcc.dg/vect/pr43842.c create mode 100644 gcc/testsuite/gcc.dg/vect/slp-reduc-1.c create mode 100644 gcc/testsuite/gcc.dg/vect/slp-reduc-2.c create mode 100644 gcc/testsuite/gcc.dg/vect/slp-reduc-3.c create mode 100644 gcc/testsuite/gcc.dg/vect/slp-reduc-4.c create mode 100644 gcc/testsuite/gcc.dg/vect/slp-reduc-5.c create mode 100644 gcc/testsuite/gcc.dg/vect/slp-reduc-6.c create mode 100644 gcc/testsuite/gcc.target/arm/wmul-1.c create mode 100644 gcc/testsuite/gcc.target/arm/wmul-2.c create mode 100644 gcc/testsuite/gcc.target/bfin/wmul-1.c create mode 100644 gcc/testsuite/gcc.target/bfin/wmul-2.c create mode 100644 gcc/testsuite/gcc.target/i386/pr43662.c create mode 100644 gcc/testsuite/gcc.target/i386/pr43766.c create mode 100644 gcc/testsuite/gcc.target/i386/wmul-1.c create mode 100644 gcc/testsuite/gcc.target/i386/wmul-2.c create mode 100644 gcc/testsuite/gfortran.dg/abstract_type_6.f03 create mode 100644 gcc/testsuite/gfortran.dg/gomp/pr43337.f90 create mode 100644 gcc/testsuite/gfortran.dg/gomp/pr43836.f90 create mode 100644 gcc/testsuite/gfortran.dg/pr43796.f90 create mode 100644 gcc/testsuite/gfortran.dg/proc_decl_23.f90 create mode 100644 gcc/testsuite/gfortran.dg/reassoc_6.f create mode 100644 gcc/testsuite/gfortran.dg/vector_subscript_6.f90 create mode 100644 gcc/testsuite/gnat.dg/rep_clause5.adb create mode 100644 gcc/testsuite/gnat.dg/rep_clause5.ads create mode 100644 gcc/testsuite/gnat.dg/rep_clause5_pkg.ads rename gcc/testsuite/gnat.dg/{sizetype.adb => sizetype1.adb} (91%) create mode 100644 gcc/testsuite/gnat.dg/sizetype2.adb create mode 100644 libgomp/testsuite/libgomp.fortran/vla8.f90 rewrite libstdc++-v3/doc/html/bk02.html (65%) rewrite libstdc++-v3/doc/html/bk03.html (68%) rewrite libstdc++-v3/doc/html/manual/algorithms.html (86%) create mode 100644 libstdc++-v3/doc/html/manual/atomics.html delete mode 100644 libstdc++-v3/doc/html/manual/auto_ptr.html delete mode 100644 libstdc++-v3/doc/html/manual/bitset.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01ix01.html create mode 100644 libstdc++-v3/doc/html/manual/bk01pt02.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt02ch04s02.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt02ch04s03.html rename libstdc++-v3/doc/html/manual/{bk01pt03ch08.html => bk01pt02ch05s02.html} (61%) delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt02pr01.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt03ch07s02.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt03ch07s03.html rename libstdc++-v3/doc/html/manual/{bk01pt12ch30s02.html => bk01pt03ch17s02.html} (92%) create mode 100644 libstdc++-v3/doc/html/manual/bk01pt03ch17s03.html rename libstdc++-v3/doc/html/manual/{bk01pt12ch30s04.html => bk01pt03ch17s04.html} (96%) rename libstdc++-v3/doc/html/manual/{bk01pt12ch31s02.html => bk01pt03ch18s02.html} (82%) rename libstdc++-v3/doc/html/manual/{bk01pt12ch31s03.html => bk01pt03ch18s03.html} (95%) rename libstdc++-v3/doc/html/manual/{bk01pt12ch31s04.html => bk01pt03ch18s04.html} (95%) rename libstdc++-v3/doc/html/manual/{bk01pt12ch31s05.html => bk01pt03ch18s05.html} (84%) rename libstdc++-v3/doc/html/manual/{bk01pt12ch32s02.html => bk01pt03ch19s02.html} (86%) rename libstdc++-v3/doc/html/manual/{bk01pt12ch32s03.html => bk01pt03ch19s03.html} (80%) rename libstdc++-v3/doc/html/manual/{bk01pt12ch32s04.html => bk01pt03ch19s04.html} (80%) rename libstdc++-v3/doc/html/manual/{bk01pt12ch32s05.html => bk01pt03ch19s05.html} (88%) rename libstdc++-v3/doc/html/manual/{bk01pt12ch32s06.html => bk01pt03ch19s06.html} (89%) rename libstdc++-v3/doc/html/manual/{bk01pt12ch32s07.html => bk01pt03ch19s07.html} (94%) rename libstdc++-v3/doc/html/manual/{bk01pt12ch34s02.html => bk01pt03ch21s02.html} (89%) rename libstdc++-v3/doc/html/manual/{bk01pt12ch34s03.html => bk01pt03ch21s03.html} (92%) rename libstdc++-v3/doc/html/manual/{bk01pt12ch41s02.html => bk01pt03ch28s02.html} (92%) rename libstdc++-v3/doc/html/manual/{bk01pt12ch41s03.html => bk01pt03ch28s03.html} (63%) rename libstdc++-v3/doc/html/manual/{bk01pt12pr03.html => bk01pt03pr01.html} (81%) create mode 100644 libstdc++-v3/doc/html/manual/bk01pt04.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt05ch13.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt05ch13s02.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt05ch13s03.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt05ch13s04.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt05ch13s05.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt05ch13s06.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt08ch19.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt08ch19s02.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt09ch20.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt09pr02.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt10ch23s02.html delete mode 100644 libstdc++-v3/doc/html/manual/bk01pt12ch30s03.html delete mode 100644 libstdc++-v3/doc/html/manual/codecvt.html delete mode 100644 libstdc++-v3/doc/html/manual/complex.html create mode 100644 libstdc++-v3/doc/html/manual/concurrency.html rewrite libstdc++-v3/doc/html/manual/containers.html (87%) rewrite libstdc++-v3/doc/html/manual/diagnostics.html (86%) delete mode 100644 libstdc++-v3/doc/html/manual/exceptions.html rename libstdc++-v3/doc/html/manual/{bk01pt11ch27s02.html => fstreams.html} (52%) delete mode 100644 libstdc++-v3/doc/html/manual/functors.html delete mode 100644 libstdc++-v3/doc/html/manual/fundamental_types.html rename libstdc++-v3/doc/html/manual/{iostream_objects.html => io.html} (66%) rename libstdc++-v3/doc/html/manual/{bk01pt11ch28s02.html => io_and_c.html} (53%) rewrite libstdc++-v3/doc/html/manual/iterators.html (85%) rename libstdc++-v3/doc/html/manual/{locales.html => localization.html} (65%) delete mode 100644 libstdc++-v3/doc/html/manual/messages.html rewrite libstdc++-v3/doc/html/manual/numerics.html (87%) delete mode 100644 libstdc++-v3/doc/html/manual/sequences.html delete mode 100644 libstdc++-v3/doc/html/manual/shared_ptr.html rename libstdc++-v3/doc/html/manual/{bk01pt11ch25s02.html => streambufs.html} (51%) rewrite libstdc++-v3/doc/html/manual/strings.html (85%) rewrite libstdc++-v3/doc/html/manual/support.html (88%) rewrite libstdc++-v3/doc/html/manual/termination.html (60%) rewrite libstdc++-v3/doc/html/manual/traits.html (74%) rewrite libstdc++-v3/doc/html/manual/utilities.html (91%) delete mode 100644 libstdc++-v3/doc/html/manual/vector.html delete mode 100644 libstdc++-v3/doc/html/manual/verbose_termination.html diff --git a/ChangeLog b/ChangeLog index 155e1abe374..8a1a4c71668 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-20 Eric Botcazou + + * configure.ac (BUILD_CONFIG): Redirect output to /dev/null. + * configure: Regenerate. + 2010-04-17 Ralf Corsépius * configure.ac (*-*-rtems*): Add target-libiberty to $skipdirs. diff --git a/configure b/configure index c8c60593155..91986d8b971 100755 --- a/configure +++ b/configure @@ -7665,7 +7665,7 @@ else mv conftest.o conftest.o.g0 && ${CC} -c -g conftest.c && mv conftest.o conftest.o.g && - ${srcdir}/contrib/compare-debug conftest.o.g0 conftest.o.g; then + ${srcdir}/contrib/compare-debug conftest.o.g0 conftest.o.g > /dev/null 2>&1; then : else BUILD_CONFIG= diff --git a/configure.ac b/configure.ac index 34308c212c5..c46fc4d9946 100644 --- a/configure.ac +++ b/configure.ac @@ -2720,7 +2720,7 @@ else mv conftest.o conftest.o.g0 && ${CC} -c -g conftest.c && mv conftest.o conftest.o.g && - ${srcdir}/contrib/compare-debug conftest.o.g0 conftest.o.g; then + ${srcdir}/contrib/compare-debug conftest.o.g0 conftest.o.g > /dev/null 2>&1; then : else BUILD_CONFIG= diff --git a/contrib/ChangeLog b/contrib/ChangeLog index ea62ec4f2b1..3a5f8f56597 100644 --- a/contrib/ChangeLog +++ b/contrib/ChangeLog @@ -1,3 +1,7 @@ +2010-04-22 Basile Starynkevitch + + * gcc_update: Sets the locale to C. + 2010-04-06 Joseph Myers * gennews (files): Add files for GCC 4.5. diff --git a/contrib/gcc_update b/contrib/gcc_update index 3e5a842338c..37e65af59c4 100755 --- a/contrib/gcc_update +++ b/contrib/gcc_update @@ -43,6 +43,12 @@ GCC_SVN=${GCC_SVN-${SVN-svn}} # Default options used when updating via SVN (none). UPDATE_OPTIONS="" +# Set the locale to C to make this script work for users with foreign +# locale like e.g. French UTF-8. +LANG=C +LC_ALL=C +export LANG LC_ALL + ######## Anything below shouldn't be changed by regular users. # Arrange for the value of $0 to be available for functions diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 700faedc68d..3d8c5b0272e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,601 @@ +2010-04-22 Kaz Kojima + + PR target/43744 + * config/sh/sh.c (find_barrier): Don't emit a constant pool + in the middle of insns for casesi_worker_2. + +2010-04-22 David Edelsohn + + * config/rs6000/x-aix: Override LDFLAGS for all COMPILERS. + +2010-04-22 Ira Rosen + + PR tree-optimization/43842 + * tree-vect-loop.c (vect_create_epilog_for_reduction): Handle + loop unrolling in update of exit phis. Fix comment. + * tree-vect-slp.c (vect_analyze_slp): Check that there are at + least two reduction statements in the loop before starting SLP + analysis. + +2010-04-22 Nick Clifton + + * config/stormy16/stormy16-lib2.c (__ucmpsi2): Fix thinko. + +2010-04-22 Alexander Monakov + + * tree-ssa-reassoc.c (eliminate_plus_minus_pair): Handle BIT_NOT_EXPR + to simplify a + ~a. + +2010-04-22 Laurynas Biveinis + + * tree-parloops.c (loop_parallel_p): New argument + parloop_obstack. Pass it down. + (parallelize_loops): New variable parloop_obstack. Initialize it, + pass it down, free it. + + * tree-loop-linear.c (linear_transform_loops): Pass down + lambda_obstack. + + * tree-data-ref.h (lambda_compute_access_matrices): New argument + of type struct obstack *. + + * tree-data-ref.c (analyze_subscript_affine_affine): New variable + scratch_obstack. Initialize it, pass down, free it. + + * lambda.h (lambda_loop_new): Remove. + (lambda_matrix_new, lambda_matrix_inverse) + (lambda_trans_matrix_new, lambda_trans_matrix_inverse): New + argument of type struct obstack *. + + * lambda-trans.c (lambda_trans_matrix_new): New argument + lambda_obstack. Pass it down, use obstack allocation for ret. + (lambda_trans_matrix_inverse): New argument lambda_obstack. Pass + it down. + + * lambda-mat.c (lambda_matrix_get_column) + (lambda_matrix_project_to_null): Remove. + (lambda_matrix_new): New argument lambda_obstack. Use obstack + allocation for mat. + (lambda_matrix_inverse_hard, lambda_matrix_inverse): New argument + lambda_obstack. + + * lambda-code.c (lambda_loop_new): New function. + (lambda_lattice_new, compute_nest_using_fourier_motzkin) + (lambda_compute_auxillary_space, lambda_compute_target_space) + (lambda_loopnest_transform, gcc_loop_to_lambda_loop) + (lambda_loopnest_to_gcc_loopnest): Pass down lambda_obstack. + (build_access_matrix): New argument lambda_obstack. Use obstack + allocation for am. + (lambda_compute_step_signs, lambda_compute_access_matrices): New + argument lambda_obstack. Pass it down. + +2010-04-22 Bernd Schmidt + + * optabs.h (expand_widening_mult): Declare. + +2010-04-22 Richard Guenther + + PR tree-optimization/43845 + * tree-ssa-pre.c (create_component_ref_by_pieces_1): Properly + lookup the CALL_EXPR function and arguments. + +2010-04-22 Nick Clifton + + * config/stormy16/stormy16.c + (xstormy16_asm_output_aligned_common): Handle a NULL decl parameter. + * config/stormy16/stormy16.h: Tidy up formatting. + (DONT_USE_BUILTIN_SETJMP): Remove definition. + * config/stormy16/stormy16.c (cbranchsi4): Delete pattern. + (ineqbranchsi): Delete pattern. + * config/stormy16/stormy16-lib2-ucmpsi2.c: New file. + * config/stormy16/stormy16-lib2.c (__ucmpsi2): New function. + * config/stormy16/t-stormy16 (LIB2FUNCS_EXTRA): Add + stormy16-lib2-ucmpsi2.c. + +2010-04-22 Bernd Schmidt + + * ifcvt.c (dead_or_predicable): Use df_simulate_find_defs and + df_simulate_find_noclobber_defs as appropriate. Keep track of an + extra set merge_set_noclobber, and use it to relax the final test + slightly. + * df.h (df_simulate_find_noclobber_defs): Declare. + * df-problems.c (df_simulate_find_defs): Don't ignore partial or + conditional defs. + (df_simulate_find_noclobber_defs): New function. + +2010-04-22 Uros Bizjak + + * config/i386/i386.md: Use {} around multi-line preparation statements. + +2010-04-22 Laurynas Biveinis + + * c-tree.h (push_init_level, pop_init_level, set_init_index) + (process_init_element): New argument of type struct obstack *. + + * c-typeck.c (push_init_level, pop_init_level, set_designator) + (set_init_index, set_init_label, set_nonincremental_init) + (set_nonincremental_init_from_string, find_init_member) + (output_init_element, output_pending_init_elements) + (process_init_element): New argument braced_init_obstack. Pass it + down. + (push_range_stack, add_pending_init): New argument + braced_init_obstack. Use obstack allocation. + + * c-parser.c (c_parser_initelt, c_parser_initval): New argument + braced_init_obstack. Pass it down. + (c_parser_braced_init): New variables ret, braced_init_obstack. + Initialize obstack, pass it down and finally free it. + +2010-04-22 Bernd Schmidt + + PR middle-end/29274 + * tree-pass.h (pass_optimize_widening_mul): Declare. + * tree-ssa-math-opts.c (execute_optimize_widening_mul, + gate_optimize_widening_mul): New static functions. + (pass_optimize_widening_mul): New. + * expr.c (expand_expr_real_2) : New + case. + : Remove support for widening multiplies. + * tree.def (WIDEN_MULT_EXPR): Tweak comment. + * cfgexpand.c (expand_debug_expr) : Use + simplify_gen_unary rather than directly building extensions. + * tree-cfg.c (verify_gimple_assign_binary): Add tests for + WIDEN_MULT_EXPR. + * expmed.c (expand_widening_mult): New function. + * passes.c (init_optimization_passes): Add pass_optimize_widening_mul. + +2010-04-21 Jan Hubicka + + * timevar.def (TV_WHOPR_WPA_FIXUP): Remove. + * lto-section-in.c (lto_section_name): Remove wpa_fixup. + * lto-wpa-fixup.c: Remove. + * Makefile.in (lto-wpa-fixup.o): Remove. + * passes.c (init_optimization_passes): Remove pass_ipa_lto_wpa_fixup. + (execute_all_ipa_transforms): Set cgraph_state to CGRAPH_STATE_IPA_SSA. + * lto-streamer.c (lto_get_section_name): Remove wpa_fixup section. + +2010-04-21 Jan Hubicka + + * tree-pass.h (ipa_opt_pass_d): Rename function_read_summary; + add write_optimization_summary, read_optimization_summary. + (ipa_write_summaries_of_cgraph_node_set): Remove. + (ipa_write_optimization_summaries): Declare. + (ipa_read_optimization_summaries): Declare. + * ipa-cp.c (pass_ipa_cp): Update. + * ipa-reference.c (pass_ipa_reference): Update. + * ipa-pure-const.c (pass_ipa_pure_const): Update. + * lto-streamer-out.c (pass_ipa_lto_gimple, pass_ipa_lto_finish): + Update. + * ipa-inline.c (pass_ipa_inline): Update. + * ipa.c (pass_ipa_whole_program): Update. + * lto-wpa-fixup.c (pass_ipa_lto_wpa_fixup): Update. + * passes.c (ipa_write_summaries_1): Do not test wpa. + (ipa_write_optimization_summaries_1): New. + (ipa_write_optimization_summaries): New. + (ipa_read_summaries): Do not test ltrans. + (ipa_read_optimization_summaries_1): New. + (ipa_read_optimization_summaries): New. + +2010-04-21 Jan Hubicka + + * lto-cgraph.c (lto_output_node): Do not output comdat groups + for boundary nodes. + (output_cgraph): Do not arrange comdat groups for boundary nodes. + +2010-04-21 Jakub Jelinek + + PR debug/40040 + * dwarf2out.c (add_name_and_src_coords_attributes): Add + DW_AT_{,MIPS_}linkage_name even for Fortran decls. + +2010-04-21 Jan Hubicka + + * ipa-prop.c (ipa_edge_removal_hook): Check for bounds. + +2010-04-21 Jan Hubicka + + * varpool.c (decide_is_variable_needed): Variable is always needed + during ltrans. + +2010-04-21 Jan Hubicka + + * opts.c (decode_options): Enable pure-const pass for whopr. + +2010-04-21 Jan Hubicka + + * cgraph.c (dump_cgraph_node): Dump also assembler name. + * ipa-inline.c (cgraph_decide_inlining_of_small_functions): Do not ice + at WPA dumping. + (cgraph_decide_inlining): Do not expect callee to be removed in all + cases. + +2010-04-21 Eric B. Weddington + + * config/avr/avr-devices.c (avr_mcu_types): Add missing comma. + +2010-04-21 Uros Bizjak + + * config/i386/i386.md (x86_shrd): Add athlon_decode and + amdfam10_decode attributes. + +2010-04-21 Jakub Jelinek + + PR middle-end/43570 + * omp-low.c (scan_sharing_clauses): Don't scan_omp_op + OMP_CLAUSE_DECL for OMP_CLAUSE_COPYPRIVATE. + (lower_copyprivate_clauses): Use private var in outer + context instead of original var. Make sure the types + are correct for VLAs. + +2010-04-21 Richard Guenther + + * tree-ssa-structalias.c (do_ds_constraint): Avoid escaping + to non-pointer objects. + +2010-04-21 Jakub Jelinek + + * dwarf2out.c (add_var_loc_to_decl): Add LABEL argument. Drop + last chain entry if it starts with the still current label. + (add_location_or_const_value_attribute): Check that + loc_list->first->next is NULL instead of comparing ->first with ->last. + (dwarf2out_var_location): Pass last_label resp. last_postcall_label + to add_var_loc_to_decl. + + * dwarf2out.c (output_call_frame_info): For dw_cie_version + >= 4 add also address size and segment size fields into CIE header. + + * unwind-dw2.c (extract_cie_info): Handle CIE version 4, as + long as address size is the same as sizeof (void *) and + segment size is 0. + * unwind-dw2-fde.c (get_cie_encoding): Likewise. If + address size or segment size is unexpected, return DW_EH_PE_omit. + (classify_object_over_fdes): If get_cie_encoding returned + DW_EH_PE_omit, return -1. + (init_object): If classify_object_over_fdes returned -1, + pretend there were no FDEs at all. + +2010-04-21 Uros Bizjak + + * config/i386/i386.md (bswap2): Macroize expander from + bswap{si,di}2 using SWI48 mode iterator. + (*bswap2_movbe): Macroize insn from *bswap{si,di}_movbe using + SWI48 mode iterator. Set type attribute of bswap insn to bitmanip, + set modrm attribute of bswap insn to 0 and remove length attribute. + (*bswap2_1): Macroize insn from *bswap{si,di}_1 using SWI48 mode + iterator. Set type attribute to bitmanip, set modrm attribute to 0, + set mode attribute to and remove length attribute. + +2010-04-20 James E. Wilson + + PR rtl-optimization/43520 + * ira-lives.c (ira_implicitly_set_insn_hard_regs): Exclude classes with + zero available registers. + +2010-04-20 Kaveh R. Ghazi + + * builtins.c (fold_builtin_cproj): Fold more cases. + +2010-04-20 Kaveh R. Ghazi + + * builtins.c (build_complex_cproj, fold_builtin_cproj): New. + (fold_builtin_1): Fold builtin cproj. + * builtins.def (BUILT_IN_CPROJ, BUILT_IN_CPROJF, BUILT_IN_CPROJL): + Use ATTR_CONST_NOTHROW_LIST. + +2010-04-20 Uros Bizjak + + * config/i386/i386.md (ffs2): Macroize expander from ffs_cmove + and ffsdi2 using SWI48 mode iterator. Expand SImode insn through + ffsi2_no_cmove for !TARGET_CMOVE. + (ffssi2_no_cmove): Rename from *ffs_no_cmove. Make public. + (ffssi2): Remove expander. + (*ffs_1): Macroize insn from *ffs{si,di} using SWI48 + mode iterator. + (ctz2): Ditto from ctz{si,di}2. + (clz2): Macroize expander from ctz{hi,si,di}2 using SWI248 + mode iterator. + (clz2_abm): Macroize insn from clz{hi,si,di}2_abm using SWI248 + mode iterator. + +2010-04-20 Jakub Jelinek + + * dwarf2out.c (AT_linkage_name): Define. + (clone_as_declaration): Handle DW_AT_linkage_name. + (add_name_and_src_coords_attributes): Use AT_linkage_name instead + of DW_AT_MIPS_linkage_name. + (move_linkage_attr): Likewise. + (dwarf2out_finish): Likewise. + +2010-04-20 Xinliang David Li + + PR middle-end/41952 + * fold-const.c (fold_comparison): New folding rule. + +2010-04-20 Anatoly Sokolov + + * double-int.h (double_int_setbit): Declare. + * double-int.c (double_int_setbit): New function. + * rtl.h (immed_double_int_const): Declare. + * emit-rtl.c (immed_double_int_const): New function. + * builtins.c (expand_builtin_signbit): Clean up, use double_int_* + and immed_double_int_const functions. + * optabs.c (expand_absneg_bit, expand_copysign_absneg, + expand_copysign_bit): (Ditto.). + * simplify-rtx.c (simplify_binary_operation_1): (Ditto.). + * tree-ssa-address.c (addr_for_mem_ref): (Ditto.). + * dojump.c (prefer_and_bit_test): (Ditto.). + * expr.c (convert_modes, reduce_to_bit_field_precision, + const_vector_from_tree): (Ditto.). + * expmed.c (mask_rtx, lshift_value): (Ditto.). + +2010-04-20 Jan Hubicka + + * cgraph.c (cgraph_remove_node): Kill bodies in other partitoin. + (dump_cgraph_node): Dump new flags. + * cgraph.h (struct cgraph_node): Add flags + reachable_from_other_partition and in_other_partition. + (cgraph_can_remove_if_no_direct_calls_p): Functions used by + other partition can not be removed. + * cgraphunit.c (cgraph_mark_functions_to_output): Functions used by + the other partition must be output; silence sanity checking on + leaking functions bodies from other paritition. + * lto-cgraph.c (reachable_from_other_partition_p): New function. + (lto_output_node): Output new flags; do not sanity check that inline + clones are output; drop lto_forced_extern_inline_p code; do not mock + visibility flags at partition boundaries. + (add_node_to): New function. + (output_cgraph): Use it to sort functions so masters appear before + clones. + (input_overwrite_node): Input new flags. + * passes.c (ipa_write_summaries): Do not call + lto_new_extern_inline_states. + * lto-section-out.c (forced_extern_inline, lto_new_extern_inline_states, + lto_delete_extern_inline_states, lto_force_functions_extern_inline, + lto_forced_extern_inline_p): Kill. + * lto-streamer.h (lto_new_extern_inline_states, + * lto_delete_extern_inline_states, lto_force_functions_extern_inline, + lto_forced_extern_inline_p): Kill. + +2010-04-20 Richard Guenther + + * tree-ssa-structalias.c (do_sd_constraint): Add edges only + from vars that can have pointers. + (process_constraint): Dump useless constraints. + +2010-04-20 Richard Guenther + + * tree-ssa-structalias.c (do_structure_copy): Properly handle DEREF. + (dump_sa_points_to_info): Remove asserts. + (init_base_vars): nothing_id isn't an escape point nor does it + have pointers. + +2010-04-20 Jakub Jelinek + + * tree.h (TYPE_REF_IS_RVALUE): Define. + * dwarf2out.c (attr_checksum_ordered, is_type_die, is_comdat_die, + should_move_die_to_comdat, prune_unused_types_walk): Handle + DW_TAG_rvalue_reference_type like DW_TAG_reference_type. + (modified_type_die, gen_reference_type_die): Emit + DW_TAG_rvalue_reference_type instead of DW_TAG_reference_type + if TYPE_REF_IS_RVALUE and -gdwarf-4. + +2010-04-20 Andreas Krebbel + + PR target/43635 + * config/s390/s390.c (s390_emit_call): Turn direct into indirect + calls for -fpic -m31 if they have been sibcall optimized. + +2010-04-19 James E. Wilson + + * config/ia64/ia64.h (FIXED_REGISTERS, CALL_USED_REGISTERS): Make + ar.lc fixed and call-used. + + * config/ia64/ia64.c (TARGET_INVALID_WITHIN_DOLOOP): Define. + +2010-04-19 Jan Hubicka + + * opts.c (decode_options): Disable whpr incompatible passes. + * lto/lto.c (lto_1_to_1_map): Skip clones. + (read_cgraph_and_symbols): Do not mark everything as needed. + (do_whole_program_analysis): Do map only after optimizing; + set proper cgraph_state; use passmanager. + +2010-04-19 DJ Delorie + + * cfgexpand.c (expand_debug_expr): Check for mismatched modes in + POINTER_PLUS_EXPR and fix them. + +2010-04-19 Eric B. Weddington + + * config/avr/avr-devices.c (avr_mcu_types): Add support for new + devices atmega644pa, attiny2313a, attiny24a, attiny261a, attiny4313, + attiny44a, attiny861a, atmega16a, atmega168a, atmega164a, atmega165a, + atmega169a, atmega169pa, atmega16hva2, atmega324a, atmega324pa, + atmega325a, atmega3250a, atmega328, atmega329a, atmega329pa, + atmega3290a, atmega48a, atmega644a, atmega645a, atmega645p, + atmega6450a, atmega6450p, atmega649a, atmega649p, atmega6490a, + atmega6490p, atmega64hve, atmega88a, atmega88pa, attiny461a, attiny84a, + m3000. Remove support for devices atmega8m1, atmega8c1, atmega16c1, + atmega4hvd, atmega8hvd, attiny327, m3000f, m3000s, m3001b. + * config/avr/t-avr.c (MULTILIB_MATCHES): Same. + +2010-04-19 Eric Botcazou + + * ifcvt.c (noce_try_cmove_arith): Fix long lines. + (check_cond_move_block): Likewise. + (cond_move_process_if_block): Likewise. + (noce_find_if_block): Improve formatting. + (find_if_header): Pass 0 to memset and tweak conditions. + (cond_exec_find_if_block): Fix long lines and tweak conditions. + +2010-04-19 Jakub Jelinek + + * dwarf2out.c (lower_bound_default): For DW_LANG_Python return 0 + for -gdwarf-4. + + PR middle-end/43337 + * tree-nested.c (convert_nonlocal_omp_clauses): OMP_CLAUSE_PRIVATE + with non-local decl doesn't need chain. + +2010-04-19 Vladimir Makarov + + * ira-color.c (allocno_reload_assign): Avoid accumulating + reload registers in ALLOCNO_TOTAL_CONFLICT_HARD_REGS. + +2010-04-19 Martin Jambor + + * gimple.h (create_tmp_reg): Declare. + * gimplify.c (create_tmp_reg): New function. + (gimplify_return_expr): Use create_tmp_reg. + (gimplify_omp_atomic): Likewise. + (gimple_regimplify_operands): Likewise. + * tree-dfa.c (make_rename_temp): Likewise. + * tree-predcom.c (predcom_tmp_var): Likewise. + (reassociate_to_the_same_stmt): Likewise. + * tree-sra.c (replace_uses_with_default_def_ssa_name): Likewise. + (get_replaced_param_substitute): Likewise. + * tree-ssa-phiprop.c (phiprop_insert_phi): Likewise. + * tree-ssa-phiopt.c (cond_store_replacement): Likewise. + * tree-ssa-pre.c (get_representative_for): Likewise. + (create_expression_by_pieces): Likewise. + * tree-tailcall.c (adjust_return_value_with_ops): Likewise. + (create_tailcall_accumulator): Likewise. + +2010-04-19 Martin Jambor + + * cgraphunit.c (cgraph_redirect_edge_call_stmt_to_callee): Update + new_stmt. + (cgraph_materialize_all_clones): Assert !need_ssa_update_p. + +2010-04-19 Richard Guenther + + PR tree-optimization/43796 + * tree-vrp.c (adjust_range_with_scev): Lookup init and step + from SCEV in the lattice. + (vrp_visit_phi_node): Dump change. + +2010-04-19 Richard Guenther + + * configure.ac: Fix quoting around elf_getshstrndx ABI check. + * configure: Re-generated. + +2010-04-19 Richard Guenther + + PR tree-optimization/43783 + * tree-ssa-pre.c (create_component_ref_by_pieces_1): Drop + constant ARRAY_REF operands two and three if possible. + +2010-04-19 Uros Bizjak + + PR target/43766 + * config/i386/i386.c (ix86_decompose_address): Handle ASHIFT addends. + +2010-04-19 Jie Zhang + + PR target/43662 + * reginfo.c (reinit_regs): Set caller_save_initialized_p to false. + +2010-04-19 Ira Rosen + + PR tree-optimization/37027 + * tree-vectorizer.h (struct _loop_vec_info): Add new field reductions + and macro to access it. + (vectorizable_reduction): Add argument. + (vect_get_slp_defs): Likewise. + * tree-vect-loop.c (vect_analyze_scalar_cycles_1): Collect reduction + statements for possible use in SLP. + (new_loop_vec_info): Initialize LOOP_VINFO_REDUCTIONS. + (destroy_loop_vec_info): Free LOOP_VINFO_REDUCTIONS. + (vect_create_epilog_for_reduction): Handle SLP. Modify documentation, + add new argument. + (vectorizable_reduction): Likewise. + * tree-vect-stmts.c (vect_get_vec_defs): Update call to + vect_get_slp_defs. + (vectorizable_type_demotion, vectorizable_type_promotion, + vectorizable_store): Likewise. + (vect_analyze_stmt): Update call to vectorizable_reduction. + (vect_transform_stmt): Likewise. + * tree-vect-slp.c (vect_get_and_check_slp_defs): Handle reduction. + (vect_build_slp_tree): Fix indentation. Check that there are no loads + from different interleaving chains in same node. + (vect_slp_rearrange_stmts): New function. + (vect_supported_load_permutation_p): Allow load permutations for + reductions. Call vect_slp_rearrange_stmts() to rearrange statements + inside SLP nodes if necessary. + (vect_analyze_slp_instance): Handle reductions. + (vect_analyze_slp): Try to build SLP instances originating from groups + of reductions. + (vect_detect_hybrid_slp_stmts): Skip reduction statements. + (vect_get_constant_vectors): Create initial vectors for reductions + according to reduction code. Add new argument. + (vect_get_slp_defs): Add new argument, pass it to + vect_get_constant_vectors. + (vect_schedule_slp_instance): Remove SLP tree root statements. + +2010-04-19 Jakub Jelinek + + * tree.h (ENUM_IS_SCOPED): Define. + * dwarf2out.c (gen_enumeration_type_die): Add DW_AT_enum_class + for ENUM_IS_SCOPED enums. + +2010-04-18 Eric Botcazou + + * fold-const.c (fold_comparison): Use ssizetype. + * gimple-fold.c (maybe_fold_offset_to_array_ref): Likewise. + * ipa-prop.c (ipa_modify_call_arguments): Use sizetype. + * tree-loop-distribution.c (build_size_arg_loc): Likewise. + * tree-object-size.c (compute_object_sizes): Use size_type_node. + + * tree.h (initialize_sizetypes): Remove parameter. + (build_common_tree_nodes): Remove second parameter. + * stor-layout.c (initialize_sizetypes): Remove parameter. + Always create an unsigned type. + (set_sizetype): Assert that the passed type is unsigned and simplify. + * tree.c (build_common_tree_nodes): Remove second parameter. + Adjust call to initialize_sizetypes. + * c-decl.c (c_init_decl_processing): Remove second argument in call to + build_common_tree_nodes. + +2010-04-18 Matthias Klose + + * gcc.c (main): Search for liblto_plugin.so with mode R_OK. + +2010-04-18 Ira Rosen + + PR tree-optimization/43771 + * tree-vect-slp.c (vect_supported_load_permutation_p): Check that + load permutation doesn't have gaps. + +2010-04-18 Jan Hubicka + + * i386.md (UNSPEC_SSE_PROLOGUE_SAVE_LOW): New. + (sse_prologue_save_insn expander): Use new pattern. + (sse_prologue_save_insn1): New pattern and splitter. + (sse_prologue_save_insn): Update to deal also with 64bit aligned + blocks. + * i386.c (setup_incoming_varargs_64): Do not compute jump + destination here. + (ix86_gimplify_va_arg): Update alignment needed. + (ix86_local_alignment): Do not align all local arrays to 128bit. + +2010-04-17 Jan Hubicka + + * ipa-inline.c (cgraph_early_inlining): Handle flattening too. + +2010-04-17 Richard Earnshaw + + * arm.md (negdi2): Remove redundant code to force values into a + register. + +2010-04-17 Richard Earnshaw + + * arm/bpabi.S: Add EABI alignment attributes to objects. + * arm/bpabi-v6m.S: Likewise. + * arm/crti.asm: Likewise. + * arm/crtn.asm: Likewise. + * arm/lib1funcs.asm: Likewise. + * arm/libunwind.S: Likewise. + 2010-04-17 Richard Earnshaw * arm-protos.h (tune_params): New structure. @@ -51,7 +649,7 @@ * config/i386/i386.md (*jcc_bt): Fix build breakage by adding missing left parenthesis. - + 2010-04-16 Uros Bizjak * config/i386/i386.md (*bt): Macroize insn from *btsi and @@ -83,7 +681,7 @@ * config/h8300/h8300.h (OK_FOR_U): Support 'U' constraint for H8300SX. - * config/h8300/h8300.md (movqi_h8sx, movhi_h8sx, movsi_h8sx, + * config/h8300/h8300.md (movqi_h8sx, movhi_h8sx, movsi_h8sx, cmphi_h8300hs_znvc, cmpsi, addhi3_h8sx) : Emit instructions in #xx:3 and #xx:4 mode. @@ -95,8 +693,7 @@ 2010-04-16 Rainer Orth - * configure.ac: Check for elf_getshdrstrndx or elf_getshstrndx - flavor. + * configure.ac: Check for elf_getshdrstrndx or elf_getshstrndx flavor. * configure: Regenerate. * config.in: Regenerate. * doc/install.texi (Prerequisites): Document that Solaris 2 libelf @@ -127,8 +724,7 @@ 2010-04-16 Diego Novillo - * doc/invoke.texi: Explain how are unrecognized -Wno- warnings - handled. + * doc/invoke.texi: Explain how are unrecognized -Wno- warnings handled. 2010-04-16 Bernd Schmidt @@ -258,8 +854,7 @@ (dump_points_to_solution): Likewise. * tree-dfa.c (dump_variable): Also dump DECL_PT_UID. * tree-inline.c (remap_ssa_name): Copy IPA points-to solution. - (remap_gimple_stmt): Reset call clobber/use information if - necessary. + (remap_gimple_stmt): Reset call clobber/use information if necessary. (copy_decl_to_var): Copy DECL_PT_UID. (copy_result_decl_to_var): Likewise. * tree.c (make_node_stat): Initialize DECL_PT_UID. @@ -327,7 +922,7 @@ PR target/43742 * config/sh/sh.md (doloop_end_split): Remove "+r" constraint - in an input-only operand. + in an input-only operand. 2010-04-15 Anatoly Sokolov @@ -336,7 +931,7 @@ (double_int_negative_p): Convert to static inline function. * double-int.c (double_int_lshift, double_int_lshift): Add new function. (double_int_negative_p): Remove. - * tree.h (lshift_double, rshift_double): + * tree.h (lshift_double, rshift_double): * tree.c (build_low_bits_mask): Clean up, use double_int_* functions. * fold-const.c (fold_convert_const_int_from_real, fold_convert_const_int_from_fixed, div_if_zero_remainder): (Ditto.). @@ -346,7 +941,7 @@ * expmed.c (mask_rtx, lshift_value): (Ditto.). 2010-04-14 Bernd Schmidt - + PR target/21803 * ifcvt.c (cond_exec_process_if_block): Look for identical sequences at the start and end of the then/else blocks, and omit them from the @@ -4178,7 +4773,7 @@ statements ... (vrp_visit_phi_node): ... but only for loop PHI nodes. -2010-02-16 Ira Rosen +2010-02-16 Ira Rosen PR tree-optimization/43074 * tree-vectorizer.h (VECTORIZABLE_CYCLE_DEF): New. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index d96e14963aa..8a9ee03883d 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20100417 +20100423 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index e212225fdeb..3d9aac8376f 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1258,7 +1258,6 @@ OBJS-common = \ lto-symtab.o \ lto-opts.o \ lto-streamer.o \ - lto-wpa-fixup.o \ lto-compress.o \ mcf.o \ mode-switching.o \ @@ -2251,10 +2250,6 @@ lto-opts.o: lto-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ lto-streamer.o: lto-streamer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TREE_H) $(GIMPLE_H) $(BITMAP_H) $(LTO_STREAMER_H) $(FLAGS_H) \ $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(LTO_SYMTAB_H) $(TOPLEV_H) -lto-wpa-fixup.o: lto-wpa-fixup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TM_H) $(TOPLEV_H) $(TREE_H) $(EXPR_H) $(FLAGS_H) $(CGRAPH_H) \ - $(FUNCTION_H) $(DIAGNOSTIC_H) $(BITMAP_H) $(TIMEVAR_H) \ - $(TREE_FLOW_H) $(TREE_PASS_H) $(LTO_STREAMER_H) langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(TOPLEV_H) $(TREE_INLINE_H) $(RTL_H) insn-config.h $(INTEGRATE_H) \ langhooks.h $(TARGET_H) $(LANGHOOKS_DEF_H) $(FLAGS_H) $(GGC_H) $(DIAGNOSTIC_H) \ diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 2a0af0b7bcc..76aa31591c1 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,36 @@ +2010-04-18 Eric Botcazou + + * gcc-interface/misc.c (gnat_init): Remove second argument in call to + build_common_tree_nodes. + +2010-04-18 Ozkan Sezer + + * gsocket.h: Make sure that winsock2.h is included before windows.h. + +2010-04-17 Eric Botcazou + + * gcc-interface/utils2.c (build_unary_op) : Do not + issue warning. + +2010-04-17 Eric Botcazou + + * uintp.h (UI_Lt): Declare. + * gcc-interface/decl.c (gnat_to_gnu_entity) : Do the size + computation in sizetype. + : Use unified handling for all index types. Do not + generate MAX_EXPR-based expressions, only COND_EXPR-based ones. Add + bypass for PATs. + (annotate_value): Change test for negative values. + (validate_size): Apply test for negative values on GNAT nodes. + (set_rm_size): Likewise. + * gcc-interface/misc.c (gnat_init): Set unsigned types for sizetypes. + * gcc-interface/utils.c (rest_of_record_type_compilation): Change test + for negative values. + (max_size) : Do not reassociate a COND_EXPR on the LHS. + (builtin_type_for_size): Adjust definition of signed_size_type_node. + * gcc-interface/utils2.c (compare_arrays): Optimize comparison of + lengths against zero. + 2010-04-17 Eric Botcazou * back-end.adb (Call_Back_End): Pass Standard_Character to gigi. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 5d6bc79fd93..f9d88a6a9bb 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -1889,55 +1889,59 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) char field_name[16]; tree gnu_index_base_type = get_unpadded_type (Base_Type (Etype (gnat_index))); - tree gnu_low_field, gnu_high_field, gnu_low, gnu_high, gnu_max; + tree gnu_lb_field, gnu_hb_field, gnu_orig_min, gnu_orig_max; + tree gnu_min, gnu_max, gnu_high; /* Make the FIELD_DECLs for the low and high bounds of this type and then make extractions of these fields from the template. */ sprintf (field_name, "LB%d", index); - gnu_low_field = create_field_decl (get_identifier (field_name), - gnu_index_base_type, - gnu_template_type, 0, - NULL_TREE, NULL_TREE, 0); + gnu_lb_field = create_field_decl (get_identifier (field_name), + gnu_index_base_type, + gnu_template_type, 0, + NULL_TREE, NULL_TREE, 0); Sloc_to_locus (Sloc (gnat_entity), - &DECL_SOURCE_LOCATION (gnu_low_field)); + &DECL_SOURCE_LOCATION (gnu_lb_field)); field_name[0] = 'U'; - gnu_high_field = create_field_decl (get_identifier (field_name), - gnu_index_base_type, - gnu_template_type, 0, - NULL_TREE, NULL_TREE, 0); + gnu_hb_field = create_field_decl (get_identifier (field_name), + gnu_index_base_type, + gnu_template_type, 0, + NULL_TREE, NULL_TREE, 0); Sloc_to_locus (Sloc (gnat_entity), - &DECL_SOURCE_LOCATION (gnu_high_field)); + &DECL_SOURCE_LOCATION (gnu_hb_field)); - gnu_temp_fields[index] = chainon (gnu_low_field, gnu_high_field); + gnu_temp_fields[index] = chainon (gnu_lb_field, gnu_hb_field); /* We can't use build_component_ref here since the template type isn't complete yet. */ - gnu_low = build3 (COMPONENT_REF, gnu_index_base_type, - gnu_template_reference, gnu_low_field, - NULL_TREE); - gnu_high = build3 (COMPONENT_REF, gnu_index_base_type, - gnu_template_reference, gnu_high_field, - NULL_TREE); - TREE_READONLY (gnu_low) = TREE_READONLY (gnu_high) = 1; - - /* Compute the size of this dimension. */ - gnu_max - = build3 (COND_EXPR, gnu_index_base_type, - build2 (GE_EXPR, boolean_type_node, gnu_high, gnu_low), - gnu_high, - build2 (MINUS_EXPR, gnu_index_base_type, - gnu_low, fold_convert (gnu_index_base_type, - integer_one_node))); + gnu_orig_min = build3 (COMPONENT_REF, gnu_index_base_type, + gnu_template_reference, gnu_lb_field, + NULL_TREE); + gnu_orig_max = build3 (COMPONENT_REF, gnu_index_base_type, + gnu_template_reference, gnu_hb_field, + NULL_TREE); + TREE_READONLY (gnu_orig_min) = TREE_READONLY (gnu_orig_max) = 1; + + gnu_min = convert (sizetype, gnu_orig_min); + gnu_max = convert (sizetype, gnu_orig_max); + + /* Compute the size of this dimension. See the E_Array_Subtype + case below for the rationale. */ + gnu_high + = build3 (COND_EXPR, sizetype, + build2 (GE_EXPR, boolean_type_node, + gnu_orig_max, gnu_orig_min), + gnu_max, + size_binop (MINUS_EXPR, gnu_min, size_one_node)); /* Make a range type with the new range in the Ada base type. Then make an index type with the size range in sizetype. */ gnu_index_types[index] - = create_index_type (convert (sizetype, gnu_low), - convert (sizetype, gnu_max), + = create_index_type (gnu_min, gnu_high, create_range_type (gnu_index_base_type, - gnu_low, gnu_high), + gnu_orig_min, + gnu_orig_max), gnat_entity); /* Update the maximum size of the array in elements. */ @@ -2112,15 +2116,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) gnat_base_index = Next_Index (gnat_base_index)) { tree gnu_index_type = get_unpadded_type (Etype (gnat_index)); - const int prec_comp - = compare_tree_int (rm_size (gnu_index_type), - TYPE_PRECISION (sizetype)); - const bool subrange_p = (prec_comp < 0 - && (TYPE_UNSIGNED (gnu_index_type) - || !TYPE_UNSIGNED (sizetype))) - || (prec_comp == 0 - && TYPE_UNSIGNED (gnu_index_type) - == TYPE_UNSIGNED (sizetype)); tree gnu_orig_min = TYPE_MIN_VALUE (gnu_index_type); tree gnu_orig_max = TYPE_MAX_VALUE (gnu_index_type); tree gnu_min = convert (sizetype, gnu_orig_min); @@ -2129,7 +2124,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) = get_unpadded_type (Etype (gnat_base_index)); tree gnu_base_orig_min = TYPE_MIN_VALUE (gnu_base_index_type); tree gnu_base_orig_max = TYPE_MAX_VALUE (gnu_base_index_type); - tree gnu_high, gnu_low; + tree gnu_high; /* See if the base array type is already flat. If it is, we are probably compiling an ACATS test but it will cause the @@ -2145,8 +2140,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) /* Similarly, if one of the values overflows in sizetype and the range is null, use 1..0 for the sizetype bounds. */ - else if (!subrange_p - && TREE_CODE (gnu_min) == INTEGER_CST + else if (TREE_CODE (gnu_min) == INTEGER_CST && TREE_CODE (gnu_max) == INTEGER_CST && (TREE_OVERFLOW (gnu_min) || TREE_OVERFLOW (gnu_max)) && tree_int_cst_lt (gnu_orig_max, gnu_orig_min)) @@ -2159,8 +2153,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) /* If the minimum and maximum values both overflow in sizetype, but the difference in the original type does not overflow in sizetype, ignore the overflow indication. */ - else if (!subrange_p - && TREE_CODE (gnu_min) == INTEGER_CST + else if (TREE_CODE (gnu_min) == INTEGER_CST && TREE_CODE (gnu_max) == INTEGER_CST && TREE_OVERFLOW (gnu_min) && TREE_OVERFLOW (gnu_max) && !TREE_OVERFLOW @@ -2179,57 +2172,49 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) deal with the "superflat" case. There are three ways to do this. If we can prove that the array can never be superflat, we can just use the high bound of the index type. */ - else if (Nkind (gnat_index) == N_Range - && cannot_be_superflat_p (gnat_index)) + else if ((Nkind (gnat_index) == N_Range + && cannot_be_superflat_p (gnat_index)) + /* Packed Array Types are never superflat. */ + || Is_Packed_Array_Type (gnat_entity)) gnu_high = gnu_max; - /* Otherwise, if we can prove that the low bound minus one and - the high bound cannot overflow, we can just use the expression - MAX (hb, lb - 1). Similarly, if we can prove that the high - bound plus one and the low bound cannot overflow, we can use - the high bound as-is and MIN (hb + 1, lb) for the low bound. - Otherwise, we have to fall back to the most general expression - (hb >= lb) ? hb : lb - 1. Note that the comparison must be - done in the original index type, to avoid any overflow during - the conversion. */ - else + /* Otherwise, if the high bound is constant but the low bound is + not, we use the expression (hb >= lb) ? lb : hb + 1 for the + lower bound. Note that the comparison must be done in the + original type to avoid any overflow during the conversion. */ + else if (TREE_CODE (gnu_max) == INTEGER_CST + && TREE_CODE (gnu_min) != INTEGER_CST) { - gnu_high = size_binop (MINUS_EXPR, gnu_min, size_one_node); - gnu_low = size_binop (PLUS_EXPR, gnu_max, size_one_node); - - /* If gnu_high is a constant that has overflowed, the low - bound is the smallest integer so cannot be the maximum. - If gnu_low is a constant that has overflowed, the high - bound is the highest integer so cannot be the minimum. */ - if ((TREE_CODE (gnu_high) == INTEGER_CST - && TREE_OVERFLOW (gnu_high)) - || (TREE_CODE (gnu_low) == INTEGER_CST - && TREE_OVERFLOW (gnu_low))) - gnu_high = gnu_max; - - /* If the index type is a subrange and gnu_high a constant - that hasn't overflowed, we can use the maximum. */ - else if (subrange_p && TREE_CODE (gnu_high) == INTEGER_CST) - gnu_high = size_binop (MAX_EXPR, gnu_max, gnu_high); - - /* If the index type is a subrange and gnu_low a constant - that hasn't overflowed, we can use the minimum. */ - else if (subrange_p && TREE_CODE (gnu_low) == INTEGER_CST) - { - gnu_high = gnu_max; - gnu_min = size_binop (MIN_EXPR, gnu_min, gnu_low); - } - - else - gnu_high - = build_cond_expr (sizetype, - build_binary_op (GE_EXPR, - boolean_type_node, - gnu_orig_max, - gnu_orig_min), - gnu_max, gnu_high); + gnu_high = gnu_max; + gnu_min + = build_cond_expr (sizetype, + build_binary_op (GE_EXPR, + boolean_type_node, + gnu_orig_max, + gnu_orig_min), + gnu_min, + size_binop (PLUS_EXPR, gnu_max, + size_one_node)); } + /* Finally we use (hb >= lb) ? hb : lb - 1 for the upper bound + in all the other cases. Note that, here as well as above, + the condition used in the comparison must be equivalent to + the condition (length != 0). This is relied upon in order + to optimize array comparisons in compare_arrays. */ + else + gnu_high + = build_cond_expr (sizetype, + build_binary_op (GE_EXPR, + boolean_type_node, + gnu_orig_max, + gnu_orig_min), + gnu_max, + size_binop (MINUS_EXPR, gnu_min, + size_one_node)); + + /* Reuse the index type for the range type. Then make an index + type with the size range in sizetype. */ gnu_index_types[index] = create_index_type (gnu_min, gnu_high, gnu_index_type, gnat_entity); @@ -2299,7 +2284,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) && TREE_CODE (TREE_TYPE (gnu_index_type)) != INTEGER_TYPE) || TYPE_BIASED_REPRESENTATION_P (gnu_index_type) - || prec_comp > 0) + || compare_tree_int (rm_size (gnu_index_type), + TYPE_PRECISION (sizetype)) > 0) need_index_type_struct = true; } @@ -7128,9 +7114,11 @@ annotate_value (tree gnu_size) this is in bitsizetype. */ gnu_size = convert (bitsizetype, gnu_size); - /* For a negative value, use NEGATE_EXPR of the opposite. Such values - appear in expressions containing aligning patterns. */ - if (tree_int_cst_sgn (gnu_size) < 0) + /* For a negative value, build NEGATE_EXPR of the opposite. Such values + appear in expressions containing aligning patterns. Note that, since + sizetype is sign-extended but nonetheless unsigned, we don't directly + use tree_int_cst_sgn. */ + if (TREE_INT_CST_HIGH (gnu_size) < 0) { tree op_size = fold_build1 (NEGATE_EXPR, bitsizetype, gnu_size); return annotate_value (build1 (NEGATE_EXPR, bitsizetype, op_size)); @@ -7498,6 +7486,10 @@ validate_size (Uint uint_size, tree gnu_type, Entity_Id gnat_object, if (uint_size == No_Uint) return NULL_TREE; + /* Ignore a negative size since that corresponds to our back-annotation. */ + if (UI_Lt (uint_size, Uint_0)) + return NULL_TREE; + /* Find the node to use for errors. */ if ((Ekind (gnat_object) == E_Component || Ekind (gnat_object) == E_Discriminant) @@ -7522,9 +7514,8 @@ validate_size (Uint uint_size, tree gnu_type, Entity_Id gnat_object, return NULL_TREE; } - /* Ignore a negative size since that corresponds to our back-annotation. - Also ignore a zero size if it is not permitted. */ - if (tree_int_cst_sgn (size) < 0 || (integer_zerop (size) && !zero_ok)) + /* Ignore a zero size if it is not permitted. */ + if (!zero_ok && integer_zerop (size)) return NULL_TREE; /* The size of objects is always a multiple of a byte. */ @@ -7611,6 +7602,10 @@ set_rm_size (Uint uint_size, tree gnu_type, Entity_Id gnat_entity) if (uint_size == No_Uint) return; + /* Ignore a negative size since that corresponds to our back-annotation. */ + if (UI_Lt (uint_size, Uint_0)) + return; + /* Only issue an error if a Value_Size clause was explicitly given. Otherwise, we'd be duplicating an error on the Size clause. */ gnat_attr_node @@ -7627,15 +7622,13 @@ set_rm_size (Uint uint_size, tree gnu_type, Entity_Id gnat_entity) return; } - /* Ignore a negative size since that corresponds to our back-annotation. - Also ignore a zero size unless a Value_Size clause exists, or a size - clause exists, or this is an integer type, in which case the front-end - will have always set it. */ - if (tree_int_cst_sgn (size) < 0 - || (integer_zerop (size) - && No (gnat_attr_node) - && !Has_Size_Clause (gnat_entity) - && !Is_Discrete_Or_Fixed_Point_Type (gnat_entity))) + /* Ignore a zero size unless a Value_Size clause exists, or a size clause + exists, or this is an integer type, in which case the front-end will + have always set it. */ + if (No (gnat_attr_node) + && integer_zerop (size) + && !Has_Size_Clause (gnat_entity) + && !Is_Discrete_Or_Fixed_Point_Type (gnat_entity)) return; old_size = rm_size (gnu_type); diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c index f3e7b1b7482..41c61853c70 100644 --- a/gcc/ada/gcc-interface/misc.c +++ b/gcc/ada/gcc-interface/misc.c @@ -6,7 +6,7 @@ * * * C Implementation File * * * - * Copyright (C) 1992-2009, Free Software Foundation, Inc. * + * Copyright (C) 1992-2010, 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- * @@ -391,13 +391,16 @@ gnat_init (void) /* Do little here, most of the standard declarations are set up after the front-end has been run. Use the same `char' as C, this doesn't really matter since we'll use the explicit `unsigned char' for Character. */ - build_common_tree_nodes (flag_signed_char, true); - - /* In Ada, we use a signed type for SIZETYPE. Use the signed type - corresponding to the width of Pmode. In most cases when ptr_mode - and Pmode differ, C will use the width of ptr_mode for SIZETYPE. - But we get far better code using the width of Pmode. */ - size_type_node = gnat_type_for_mode (Pmode, 0); + build_common_tree_nodes (flag_signed_char); + + /* In Ada, we use the unsigned type corresponding to the width of Pmode as + SIZETYPE. In most cases when ptr_mode and Pmode differ, C will use the + width of ptr_mode for SIZETYPE, but we get better code using the width + of Pmode. Note that, although we manipulate negative offsets for some + internal constructs and rely on compile time overflow detection in size + computations, using unsigned types for SIZETYPEs is fine since they are + treated specially by the middle-end, in particular sign-extended. */ + size_type_node = gnat_type_for_mode (Pmode, 1); set_sizetype (size_type_node); TYPE_NAME (sizetype) = get_identifier ("size_type"); diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 668226bd906..7b403a7bab8 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -839,11 +839,13 @@ rest_of_record_type_compilation (tree record_type) align = tree_low_cst (TREE_OPERAND (curpos, 1), 1); /* An offset which is a bitwise AND with a negative power of 2 - means an alignment corresponding to this power of 2. */ + means an alignment corresponding to this power of 2. Note + that, as sizetype is sign-extended but nonetheless unsigned, + we don't directly use tree_int_cst_sgn. */ offset = remove_conversions (offset, true); if (TREE_CODE (offset) == BIT_AND_EXPR && host_integerp (TREE_OPERAND (offset, 1), 0) - && tree_int_cst_sgn (TREE_OPERAND (offset, 1)) < 0) + && TREE_INT_CST_HIGH (TREE_OPERAND (offset, 1)) < 0) { unsigned int pow = - tree_low_cst (TREE_OPERAND (offset, 1), 0); @@ -2175,22 +2177,6 @@ max_size (tree exp, bool max_p) if (code == COMPOUND_EXPR) return max_size (TREE_OPERAND (exp, 1), max_p); - /* Calculate "(A ? B : C) - D" as "A ? B - D : C - D" which - may provide a tighter bound on max_size. */ - if (code == MINUS_EXPR - && TREE_CODE (TREE_OPERAND (exp, 0)) == COND_EXPR) - { - tree lhs = fold_build2 (MINUS_EXPR, type, - TREE_OPERAND (TREE_OPERAND (exp, 0), 1), - TREE_OPERAND (exp, 1)); - tree rhs = fold_build2 (MINUS_EXPR, type, - TREE_OPERAND (TREE_OPERAND (exp, 0), 2), - TREE_OPERAND (exp, 1)); - return fold_build2 (max_p ? MAX_EXPR : MIN_EXPR, type, - max_size (lhs, max_p), - max_size (rhs, max_p)); - } - { tree lhs = max_size (TREE_OPERAND (exp, 0), max_p); tree rhs = max_size (TREE_OPERAND (exp, 1), @@ -4707,7 +4693,7 @@ builtin_type_for_size (int size, bool unsignedp) static void install_builtin_elementary_types (void) { - signed_size_type_node = size_type_node; + signed_size_type_node = gnat_signed_type (size_type_node); pid_type_node = integer_type_node; void_list_node = build_void_list_node (); diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c index be7044bddfa..9b00c0dfced 100644 --- a/gcc/ada/gcc-interface/utils2.c +++ b/gcc/ada/gcc-interface/utils2.c @@ -351,14 +351,26 @@ compare_arrays (tree result_type, tree a1, tree a2) if (EXPR_P (comparison)) SET_EXPR_LOCATION (comparison, input_location); - this_a1_is_null = build_binary_op (EQ_EXPR, result_type, length1, - size_zero_node); - if (EXPR_P (this_a1_is_null)) + /* If the length expression is of the form (cond ? val : 0), assume + that cond is equivalent to (length != 0). That's guaranteed by + construction of the array types in gnat_to_gnu_entity. */ + if (TREE_CODE (length1) == COND_EXPR + && integer_zerop (TREE_OPERAND (length1, 2))) + this_a1_is_null = invert_truthvalue (TREE_OPERAND (length1, 0)); + else + this_a1_is_null = build_binary_op (EQ_EXPR, result_type, length1, + size_zero_node); + if (EXPR_P (this_a1_is_null)) SET_EXPR_LOCATION (this_a1_is_null, input_location); - this_a2_is_null = build_binary_op (EQ_EXPR, result_type, length2, - size_zero_node); - if (EXPR_P (this_a2_is_null)) + /* Likewise for the second array. */ + if (TREE_CODE (length2) == COND_EXPR + && integer_zerop (TREE_OPERAND (length2, 2))) + this_a2_is_null = invert_truthvalue (TREE_OPERAND (length2, 0)); + else + this_a2_is_null = build_binary_op (EQ_EXPR, result_type, length2, + size_zero_node); + if (EXPR_P (this_a2_is_null)) SET_EXPR_LOCATION (this_a2_is_null, input_location); } @@ -1068,9 +1080,8 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand) case ARRAY_RANGE_REF: case COMPONENT_REF: case BIT_FIELD_REF: - /* If this is for 'Address, find the address of the prefix and - add the offset to the field. Otherwise, do this the normal - way. */ + /* If this is for 'Address, find the address of the prefix and add + the offset to the field. Otherwise, do this the normal way. */ if (op_code == ATTR_ADDR_EXPR) { HOST_WIDE_INT bitsize; @@ -1097,11 +1108,6 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand) if (!offset) offset = size_zero_node; - if (bitpos % BITS_PER_UNIT != 0) - post_error - ("taking address of object not aligned on storage unit?", - error_gnat_node); - offset = size_binop (PLUS_EXPR, offset, size_int (bitpos / BITS_PER_UNIT)); diff --git a/gcc/ada/gsocket.h b/gcc/ada/gsocket.h index ca016c921c0..a8e6faa2467 100644 --- a/gcc/ada/gsocket.h +++ b/gcc/ada/gsocket.h @@ -71,7 +71,6 @@ #elif defined (WINNT) #define FD_SETSIZE 1024 -#include #ifdef __MINGW32__ #include @@ -160,6 +159,8 @@ #endif +#include + #elif defined(VMS) #define FD_SETSIZE 4096 #ifndef IN_RTS diff --git a/gcc/ada/uintp.h b/gcc/ada/uintp.h index de70e115f43..630fcd18e06 100644 --- a/gcc/ada/uintp.h +++ b/gcc/ada/uintp.h @@ -75,6 +75,10 @@ typedef struct {const int *Array; Vector_Template *Bounds; } #define Vector_To_Uint uintp__vector_to_uint extern Uint Vector_To_Uint (Int_Vector, Boolean); +/* Compare integer values for less than. */ +#define UI_Lt uintp__ui_lt +extern Boolean UI_Lt (Uint, Uint); + /* Universal integers are represented by the Uint type which is an index into the Uints_Ptr table containing Uint_Entry values. A Uint_Entry contains an index and length for getting the "digits" of the universal integer from the diff --git a/gcc/builtins.c b/gcc/builtins.c index dbab4847af0..997c13a5505 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -5279,7 +5279,6 @@ expand_builtin_signbit (tree exp, rtx target) { const struct real_format *fmt; enum machine_mode fmode, imode, rmode; - HOST_WIDE_INT hi, lo; tree arg; int word, bitpos; enum insn_code icode; @@ -5355,21 +5354,12 @@ expand_builtin_signbit (tree exp, rtx target) if (bitpos < GET_MODE_BITSIZE (rmode)) { - if (bitpos < HOST_BITS_PER_WIDE_INT) - { - hi = 0; - lo = (HOST_WIDE_INT) 1 << bitpos; - } - else - { - hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT); - lo = 0; - } + double_int mask = double_int_setbit (double_int_zero, bitpos); if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode)) temp = gen_lowpart (rmode, temp); temp = expand_binop (rmode, and_optab, temp, - immed_double_const (lo, hi, rmode), + immed_double_int_const (mask, rmode), NULL_RTX, 1, OPTAB_LIB_WIDEN); } else @@ -7052,6 +7042,77 @@ fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl) return NULL_TREE; } +/* Build a complex (inf +- 0i) for the result of cproj. TYPE is the + complex tree type of the result. If NEG is true, the imaginary + zero is negative. */ + +static tree +build_complex_cproj (tree type, bool neg) +{ + REAL_VALUE_TYPE rinf, rzero = dconst0; + + real_inf (&rinf); + rzero.sign = neg; + return build_complex (type, build_real (TREE_TYPE (type), rinf), + build_real (TREE_TYPE (type), rzero)); +} + +/* Fold call to builtin cproj, cprojf or cprojl with argument ARG. TYPE is the + return type. Return NULL_TREE if no simplification can be made. */ + +static tree +fold_builtin_cproj (location_t loc, tree arg, tree type) +{ + if (!validate_arg (arg, COMPLEX_TYPE) + || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE) + return NULL_TREE; + + /* If there are no infinities, return arg. */ + if (! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (type)))) + return non_lvalue_loc (loc, arg); + + /* Calculate the result when the argument is a constant. */ + if (TREE_CODE (arg) == COMPLEX_CST) + { + const REAL_VALUE_TYPE *real = TREE_REAL_CST_PTR (TREE_REALPART (arg)); + const REAL_VALUE_TYPE *imag = TREE_REAL_CST_PTR (TREE_IMAGPART (arg)); + + if (real_isinf (real) || real_isinf (imag)) + return build_complex_cproj (type, imag->sign); + else + return arg; + } + else if (TREE_CODE (arg) == COMPLEX_EXPR) + { + tree real = TREE_OPERAND (arg, 0); + tree imag = TREE_OPERAND (arg, 1); + + STRIP_NOPS (real); + STRIP_NOPS (imag); + + /* If the real part is inf and the imag part is known to be + nonnegative, return (inf + 0i). Remember side-effects are + possible in the imag part. */ + if (TREE_CODE (real) == REAL_CST + && real_isinf (TREE_REAL_CST_PTR (real)) + && tree_expr_nonnegative_p (imag)) + return omit_one_operand_loc (loc, type, + build_complex_cproj (type, false), + arg); + + /* If the imag part is inf, return (inf+I*copysign(0,imag)). + Remember side-effects are possible in the real part. */ + if (TREE_CODE (imag) == REAL_CST + && real_isinf (TREE_REAL_CST_PTR (imag))) + return + omit_one_operand_loc (loc, type, + build_complex_cproj (type, TREE_REAL_CST_PTR + (imag)->sign), arg); + } + + return NULL_TREE; +} + /* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG. Return NULL_TREE if no simplification can be made. */ @@ -9809,6 +9870,9 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore) CASE_FLT_FN (BUILT_IN_CCOSH): return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ true); + CASE_FLT_FN (BUILT_IN_CPROJ): + return fold_builtin_cproj(loc, arg0, type); + CASE_FLT_FN (BUILT_IN_CSIN): if (validate_arg (arg0, COMPLEX_TYPE) && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) diff --git a/gcc/builtins.def b/gcc/builtins.def index 09177a9001a..4e4eb3edc03 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -479,9 +479,9 @@ DEF_C99_BUILTIN (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLE DEF_C99_BUILTIN (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) DEF_C99_BUILTIN (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) DEF_C99_BUILTIN (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) -DEF_C99_BUILTIN (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) -DEF_C99_BUILTIN (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) -DEF_C99_BUILTIN (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LIST) +DEF_C99_BUILTIN (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LIST) +DEF_C99_BUILTIN (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST) DEF_C99_BUILTIN (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LIST) DEF_C99_BUILTIN (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LIST) DEF_C99_BUILTIN (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST) diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 1aa924fd873..b34ea6038f8 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -3471,7 +3471,7 @@ c_init_decl_processing (void) using preprocessed headers. */ input_location = BUILTINS_LOCATION; - build_common_tree_nodes (flag_signed_char, false); + build_common_tree_nodes (flag_signed_char); c_common_nodes_and_builtins (); diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 27f0b819880..a8feb27b883 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -906,8 +906,9 @@ static tree c_parser_attributes (c_parser *); static struct c_type_name *c_parser_type_name (c_parser *); static struct c_expr c_parser_initializer (c_parser *); static struct c_expr c_parser_braced_init (c_parser *, tree, bool); -static void c_parser_initelt (c_parser *); -static void c_parser_initval (c_parser *, struct c_expr *); +static void c_parser_initelt (c_parser *, struct obstack *); +static void c_parser_initval (c_parser *, struct c_expr *, + struct obstack *); static tree c_parser_compound_statement (c_parser *); static void c_parser_compound_statement_nostart (c_parser *); static void c_parser_label (c_parser *); @@ -3088,11 +3089,14 @@ c_parser_initializer (c_parser *parser) static struct c_expr c_parser_braced_init (c_parser *parser, tree type, bool nested_p) { + struct c_expr ret; + struct obstack braced_init_obstack; location_t brace_loc = c_parser_peek_token (parser)->location; + gcc_obstack_init (&braced_init_obstack); gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE)); c_parser_consume_token (parser); if (nested_p) - push_init_level (0); + push_init_level (0, &braced_init_obstack); else really_start_incremental_init (type); if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) @@ -3105,7 +3109,7 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p) comma. */ while (true) { - c_parser_initelt (parser); + c_parser_initelt (parser, &braced_init_obstack); if (parser->error) break; if (c_parser_next_token_is (parser, CPP_COMMA)) @@ -3118,22 +3122,24 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p) } if (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE)) { - struct c_expr ret; ret.value = error_mark_node; ret.original_code = ERROR_MARK; ret.original_type = NULL; c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, "expected %<}%>"); - pop_init_level (0); + pop_init_level (0, &braced_init_obstack); + obstack_free (&braced_init_obstack, NULL); return ret; } c_parser_consume_token (parser); - return pop_init_level (0); + ret = pop_init_level (0, &braced_init_obstack); + obstack_free (&braced_init_obstack, NULL); + return ret; } /* Parse a nested initializer, including designators. */ static void -c_parser_initelt (c_parser *parser) +c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack) { /* Parse any designator or designator list. A single array designator may have the subsequent "=" omitted in GNU C, but a @@ -3142,7 +3148,8 @@ c_parser_initelt (c_parser *parser) && c_parser_peek_2nd_token (parser)->type == CPP_COLON) { /* Old-style structure member designator. */ - set_init_label (c_parser_peek_token (parser)->value); + set_init_label (c_parser_peek_token (parser)->value, + braced_init_obstack); /* Use the colon as the error location. */ pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_pedantic, "obsolete use of designated initializer with %<:%>"); @@ -3170,7 +3177,8 @@ c_parser_initelt (c_parser *parser) c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_NAME)) { - set_init_label (c_parser_peek_token (parser)->value); + set_init_label (c_parser_peek_token (parser)->value, + braced_init_obstack); c_parser_consume_token (parser); } else @@ -3181,7 +3189,7 @@ c_parser_initelt (c_parser *parser) init.original_type = NULL; c_parser_error (parser, "expected identifier"); c_parser_skip_until_found (parser, CPP_COMMA, NULL); - process_init_element (init, false); + process_init_element (init, false, braced_init_obstack); return; } } @@ -3262,7 +3270,7 @@ c_parser_initelt (c_parser *parser) /* Now parse and process the remainder of the initializer, starting with this message expression as a primary-expression. */ - c_parser_initval (parser, &mexpr); + c_parser_initval (parser, &mexpr, braced_init_obstack); return; } c_parser_consume_token (parser); @@ -3281,7 +3289,7 @@ c_parser_initelt (c_parser *parser) if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) { c_parser_consume_token (parser); - set_init_index (first, second); + set_init_index (first, second, braced_init_obstack); if (second) pedwarn (ellipsis_loc, OPT_pedantic, "ISO C forbids specifying range of elements to initialize"); @@ -3313,13 +3321,13 @@ c_parser_initelt (c_parser *parser) init.original_type = NULL; c_parser_error (parser, "expected %<=%>"); c_parser_skip_until_found (parser, CPP_COMMA, NULL); - process_init_element (init, false); + process_init_element (init, false, braced_init_obstack); return; } } } } - c_parser_initval (parser, NULL); + c_parser_initval (parser, NULL, braced_init_obstack); } /* Parse a nested initializer; as c_parser_initializer but parses @@ -3329,7 +3337,8 @@ c_parser_initelt (c_parser *parser) initializer. */ static void -c_parser_initval (c_parser *parser, struct c_expr *after) +c_parser_initval (c_parser *parser, struct c_expr *after, + struct obstack * braced_init_obstack) { struct c_expr init; gcc_assert (!after || c_dialect_objc ()); @@ -3344,7 +3353,7 @@ c_parser_initval (c_parser *parser, struct c_expr *after) && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR) init = default_function_array_read_conversion (loc, init); } - process_init_element (init, false); + process_init_element (init, false, braced_init_obstack); } /* Parse a compound statement (possibly a function body) (C90 6.6.2, diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 3681ed7dfec..681fe9b4ffe 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -539,11 +539,11 @@ extern void maybe_warn_string_init (tree, struct c_expr); extern void start_init (tree, tree, int); extern void finish_init (void); extern void really_start_incremental_init (tree); -extern void push_init_level (int); -extern struct c_expr pop_init_level (int); -extern void set_init_index (tree, tree); -extern void set_init_label (tree); -extern void process_init_element (struct c_expr, bool); +extern void push_init_level (int, struct obstack *); +extern struct c_expr pop_init_level (int, struct obstack *); +extern void set_init_index (tree, tree, struct obstack *); +extern void set_init_label (tree, struct obstack *); +extern void process_init_element (struct c_expr, bool, struct obstack *); extern tree build_compound_literal (location_t, tree, tree, bool); extern void check_compound_literal_type (location_t, struct c_type_name *); extern tree c_start_case (location_t, location_t, tree); diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 9122c6894a1..4baa8b4786a 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -97,14 +97,15 @@ static int spelling_length (void); static char *print_spelling (char *); static void warning_init (int, const char *); static tree digest_init (location_t, tree, tree, tree, bool, bool, int); -static void output_init_element (tree, tree, bool, tree, tree, int, bool); -static void output_pending_init_elements (int); -static int set_designator (int); -static void push_range_stack (tree); -static void add_pending_init (tree, tree, tree, bool); -static void set_nonincremental_init (void); -static void set_nonincremental_init_from_string (tree); -static tree find_init_member (tree); +static void output_init_element (tree, tree, bool, tree, tree, int, bool, + struct obstack *); +static void output_pending_init_elements (int, struct obstack *); +static int set_designator (int, struct obstack *); +static void push_range_stack (tree, struct obstack *); +static void add_pending_init (tree, tree, tree, bool, struct obstack *); +static void set_nonincremental_init (struct obstack *); +static void set_nonincremental_init_from_string (tree, struct obstack *); +static tree find_init_member (tree, struct obstack *); static void readonly_error (tree, enum lvalue_use); static void readonly_warning (tree, enum lvalue_use); static int lvalue_or_else (const_tree, enum lvalue_use); @@ -6433,7 +6434,7 @@ really_start_incremental_init (tree type) IMPLICIT is 1 (or 2 if the push is because of designator list). */ void -push_init_level (int implicit) +push_init_level (int implicit, struct obstack * braced_init_obstack) { struct constructor_stack *p; tree value = NULL_TREE; @@ -6451,12 +6452,14 @@ push_init_level (int implicit) if ((TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) && constructor_fields == 0) - process_init_element (pop_init_level (1), true); + process_init_element (pop_init_level (1, braced_init_obstack), + true, braced_init_obstack); else if (TREE_CODE (constructor_type) == ARRAY_TYPE && constructor_max_index && tree_int_cst_lt (constructor_max_index, constructor_index)) - process_init_element (pop_init_level (1), true); + process_init_element (pop_init_level (1, braced_init_obstack), + true, braced_init_obstack); else break; } @@ -6469,9 +6472,9 @@ push_init_level (int implicit) if ((TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) && constructor_fields) - value = find_init_member (constructor_fields); + value = find_init_member (constructor_fields, braced_init_obstack); else if (TREE_CODE (constructor_type) == ARRAY_TYPE) - value = find_init_member (constructor_index); + value = find_init_member (constructor_index, braced_init_obstack); } p = XNEW (struct constructor_stack); @@ -6557,7 +6560,7 @@ push_init_level (int implicit) if (!VEC_empty (constructor_elt, constructor_elements) && (TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == ARRAY_TYPE)) - set_nonincremental_init (); + set_nonincremental_init (braced_init_obstack); } if (implicit == 1 && warn_missing_braces && !missing_braces_mentioned) @@ -6618,7 +6621,7 @@ push_init_level (int implicit) /* We need to split the char/wchar array into individual characters, so that we don't have to special case it everywhere. */ - set_nonincremental_init_from_string (value); + set_nonincremental_init_from_string (value, braced_init_obstack); } } else @@ -6642,7 +6645,7 @@ push_init_level (int implicit) Otherwise, return a CONSTRUCTOR expression as the value. */ struct c_expr -pop_init_level (int implicit) +pop_init_level (int implicit, struct obstack * braced_init_obstack) { struct constructor_stack *p; struct c_expr ret; @@ -6655,14 +6658,16 @@ pop_init_level (int implicit) /* When we come to an explicit close brace, pop any inner levels that didn't have explicit braces. */ while (constructor_stack->implicit) - process_init_element (pop_init_level (1), true); - + { + process_init_element (pop_init_level (1, braced_init_obstack), + true, braced_init_obstack); + } gcc_assert (!constructor_range_stack); } /* Now output all pending elements. */ constructor_incremental = 1; - output_pending_init_elements (1); + output_pending_init_elements (1, braced_init_obstack); p = constructor_stack; @@ -6803,7 +6808,7 @@ pop_init_level (int implicit) ARRAY argument is nonzero for array ranges. Returns zero for success. */ static int -set_designator (int array) +set_designator (int array, struct obstack * braced_init_obstack) { tree subtype; enum tree_code subcode; @@ -6825,7 +6830,10 @@ set_designator (int array) /* Designator list starts at the level of closest explicit braces. */ while (constructor_stack->implicit) - process_init_element (pop_init_level (1), true); + { + process_init_element (pop_init_level (1, braced_init_obstack), + true, braced_init_obstack); + } constructor_designated = 1; return 0; } @@ -6858,7 +6866,7 @@ set_designator (int array) } constructor_designated = 1; - push_init_level (2); + push_init_level (2, braced_init_obstack); return 0; } @@ -6867,11 +6875,13 @@ set_designator (int array) NULL_TREE if there is no range designator at this level. */ static void -push_range_stack (tree range_end) +push_range_stack (tree range_end, struct obstack * braced_init_obstack) { struct constructor_range_stack *p; - p = GGC_NEW (struct constructor_range_stack); + p = (struct constructor_range_stack *) + obstack_alloc (braced_init_obstack, + sizeof (struct constructor_range_stack)); p->prev = constructor_range_stack; p->next = 0; p->fields = constructor_fields; @@ -6889,9 +6899,10 @@ push_range_stack (tree range_end) of indices, running from FIRST through LAST. */ void -set_init_index (tree first, tree last) +set_init_index (tree first, tree last, + struct obstack * braced_init_obstack) { - if (set_designator (1)) + if (set_designator (1, braced_init_obstack)) return; designator_erroneous = 1; @@ -6963,18 +6974,18 @@ set_init_index (tree first, tree last) designator_depth++; designator_erroneous = 0; if (constructor_range_stack || last) - push_range_stack (last); + push_range_stack (last, braced_init_obstack); } } /* Within a struct initializer, specify the next field to be initialized. */ void -set_init_label (tree fieldname) +set_init_label (tree fieldname, struct obstack * braced_init_obstack) { tree tail; - if (set_designator (0)) + if (set_designator (0, braced_init_obstack)) return; designator_erroneous = 1; @@ -7001,7 +7012,7 @@ set_init_label (tree fieldname) designator_depth++; designator_erroneous = 0; if (constructor_range_stack) - push_range_stack (NULL_TREE); + push_range_stack (NULL_TREE, braced_init_obstack); } } @@ -7016,7 +7027,8 @@ set_init_label (tree fieldname) existing initializer. */ static void -add_pending_init (tree purpose, tree value, tree origtype, bool implicit) +add_pending_init (tree purpose, tree value, tree origtype, bool implicit, + struct obstack * braced_init_obstack) { struct init_node *p, **q, *r; @@ -7075,7 +7087,8 @@ add_pending_init (tree purpose, tree value, tree origtype, bool implicit) } } - r = GGC_NEW (struct init_node); + r = (struct init_node *) obstack_alloc (braced_init_obstack, + sizeof (struct init_node)); r->purpose = purpose; r->value = value; r->origtype = origtype; @@ -7244,7 +7257,7 @@ add_pending_init (tree purpose, tree value, tree origtype, bool implicit) /* Build AVL tree from a sorted chain. */ static void -set_nonincremental_init (void) +set_nonincremental_init (struct obstack * braced_init_obstack) { unsigned HOST_WIDE_INT ix; tree index, value; @@ -7254,7 +7267,10 @@ set_nonincremental_init (void) return; FOR_EACH_CONSTRUCTOR_ELT (constructor_elements, ix, index, value) - add_pending_init (index, value, NULL_TREE, false); + { + add_pending_init (index, value, NULL_TREE, false, + braced_init_obstack); + } constructor_elements = 0; if (TREE_CODE (constructor_type) == RECORD_TYPE) { @@ -7281,7 +7297,8 @@ set_nonincremental_init (void) /* Build AVL tree from a string constant. */ static void -set_nonincremental_init_from_string (tree str) +set_nonincremental_init_from_string (tree str, + struct obstack * braced_init_obstack) { tree value, purpose, type; HOST_WIDE_INT val[2]; @@ -7344,7 +7361,8 @@ set_nonincremental_init_from_string (tree str) } value = build_int_cst_wide (type, val[1], val[0]); - add_pending_init (purpose, value, NULL_TREE, false); + add_pending_init (purpose, value, NULL_TREE, false, + braced_init_obstack); } constructor_incremental = 0; @@ -7354,7 +7372,7 @@ set_nonincremental_init_from_string (tree str) not initialized yet. */ static tree -find_init_member (tree field) +find_init_member (tree field, struct obstack * braced_init_obstack) { struct init_node *p; @@ -7362,7 +7380,7 @@ find_init_member (tree field) { if (constructor_incremental && tree_int_cst_lt (field, constructor_unfilled_index)) - set_nonincremental_init (); + set_nonincremental_init (braced_init_obstack); p = constructor_pending_elts; while (p) @@ -7383,7 +7401,7 @@ find_init_member (tree field) && (!constructor_unfilled_fields || tree_int_cst_lt (bitpos, bit_position (constructor_unfilled_fields)))) - set_nonincremental_init (); + set_nonincremental_init (braced_init_obstack); p = constructor_pending_elts; while (p) @@ -7427,7 +7445,8 @@ find_init_member (tree field) static void output_init_element (tree value, tree origtype, bool strict_string, tree type, - tree field, int pending, bool implicit) + tree field, int pending, bool implicit, + struct obstack * braced_init_obstack) { tree semantic_type = NULL_TREE; constructor_elt *celt; @@ -7544,9 +7563,10 @@ output_init_element (tree value, tree origtype, bool strict_string, tree type, { if (constructor_incremental && tree_int_cst_lt (field, constructor_unfilled_index)) - set_nonincremental_init (); + set_nonincremental_init (braced_init_obstack); - add_pending_init (field, value, origtype, implicit); + add_pending_init (field, value, origtype, implicit, + braced_init_obstack); return; } else if (TREE_CODE (constructor_type) == RECORD_TYPE @@ -7559,7 +7579,7 @@ output_init_element (tree value, tree origtype, bool strict_string, tree type, if (constructor_incremental) { if (!constructor_unfilled_fields) - set_nonincremental_init (); + set_nonincremental_init (braced_init_obstack); else { tree bitpos, unfillpos; @@ -7568,11 +7588,12 @@ output_init_element (tree value, tree origtype, bool strict_string, tree type, unfillpos = bit_position (constructor_unfilled_fields); if (tree_int_cst_lt (bitpos, unfillpos)) - set_nonincremental_init (); + set_nonincremental_init (braced_init_obstack); } } - add_pending_init (field, value, origtype, implicit); + add_pending_init (field, value, origtype, implicit, + braced_init_obstack); return; } else if (TREE_CODE (constructor_type) == UNION_TYPE @@ -7621,7 +7642,7 @@ output_init_element (tree value, tree origtype, bool strict_string, tree type, /* Now output any pending elements which have become next. */ if (pending) - output_pending_init_elements (0); + output_pending_init_elements (0, braced_init_obstack); } /* Output any pending elements which have become next. @@ -7634,9 +7655,8 @@ output_init_element (tree value, tree origtype, bool strict_string, tree type, If ALL is 1, we output space as necessary so that we can output all the pending elements. */ - static void -output_pending_init_elements (int all) +output_pending_init_elements (int all, struct obstack * braced_init_obstack) { struct init_node *elt = constructor_pending_elts; tree next; @@ -7657,7 +7677,8 @@ output_pending_init_elements (int all) constructor_unfilled_index)) output_init_element (elt->value, elt->origtype, true, TREE_TYPE (constructor_type), - constructor_unfilled_index, 0, false); + constructor_unfilled_index, 0, false, + braced_init_obstack); else if (tree_int_cst_lt (constructor_unfilled_index, elt->purpose)) { @@ -7711,7 +7732,8 @@ output_pending_init_elements (int all) constructor_unfilled_fields = elt->purpose; output_init_element (elt->value, elt->origtype, true, TREE_TYPE (elt->purpose), - elt->purpose, 0, false); + elt->purpose, 0, false, + braced_init_obstack); } else if (tree_int_cst_lt (ctor_unfilled_bitpos, elt_bitpos)) { @@ -7782,7 +7804,8 @@ output_pending_init_elements (int all) existing initializer. */ void -process_init_element (struct c_expr value, bool implicit) +process_init_element (struct c_expr value, bool implicit, + struct obstack * braced_init_obstack) { tree orig_value = value.value; int string_flag = orig_value != 0 && TREE_CODE (orig_value) == STRING_CST; @@ -7823,13 +7846,15 @@ process_init_element (struct c_expr value, bool implicit) if ((TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) && constructor_fields == 0) - process_init_element (pop_init_level (1), true); + process_init_element (pop_init_level (1, braced_init_obstack), + true, braced_init_obstack); else if ((TREE_CODE (constructor_type) == ARRAY_TYPE || TREE_CODE (constructor_type) == VECTOR_TYPE) && (constructor_max_index == 0 || tree_int_cst_lt (constructor_max_index, constructor_index))) - process_init_element (pop_init_level (1), true); + process_init_element (pop_init_level (1, braced_init_obstack), + true, braced_init_obstack); else break; } @@ -7899,7 +7924,7 @@ process_init_element (struct c_expr value, bool implicit) && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE || fieldcode == UNION_TYPE || fieldcode == VECTOR_TYPE)) { - push_init_level (1); + push_init_level (1, braced_init_obstack); continue; } @@ -7908,7 +7933,8 @@ process_init_element (struct c_expr value, bool implicit) push_member_name (constructor_fields); output_init_element (value.value, value.original_type, strict_string, fieldtype, - constructor_fields, 1, implicit); + constructor_fields, 1, implicit, + braced_init_obstack); RESTORE_SPELLING_DEPTH (constructor_depth); } else @@ -7990,7 +8016,7 @@ process_init_element (struct c_expr value, bool implicit) && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE || fieldcode == UNION_TYPE || fieldcode == VECTOR_TYPE)) { - push_init_level (1); + push_init_level (1, braced_init_obstack); continue; } @@ -7999,7 +8025,8 @@ process_init_element (struct c_expr value, bool implicit) push_member_name (constructor_fields); output_init_element (value.value, value.original_type, strict_string, fieldtype, - constructor_fields, 1, implicit); + constructor_fields, 1, implicit, + braced_init_obstack); RESTORE_SPELLING_DEPTH (constructor_depth); } else @@ -8031,7 +8058,7 @@ process_init_element (struct c_expr value, bool implicit) && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE || eltcode == UNION_TYPE || eltcode == VECTOR_TYPE)) { - push_init_level (1); + push_init_level (1, braced_init_obstack); continue; } @@ -8050,7 +8077,8 @@ process_init_element (struct c_expr value, bool implicit) push_array_bounds (tree_low_cst (constructor_index, 1)); output_init_element (value.value, value.original_type, strict_string, elttype, - constructor_index, 1, implicit); + constructor_index, 1, implicit, + braced_init_obstack); RESTORE_SPELLING_DEPTH (constructor_depth); } @@ -8084,7 +8112,8 @@ process_init_element (struct c_expr value, bool implicit) elttype = TYPE_MAIN_VARIANT (constructor_type); output_init_element (value.value, value.original_type, strict_string, elttype, - constructor_index, 1, implicit); + constructor_index, 1, implicit, + braced_init_obstack); } constructor_index @@ -8112,7 +8141,8 @@ process_init_element (struct c_expr value, bool implicit) if (value.value) output_init_element (value.value, value.original_type, strict_string, constructor_type, - NULL_TREE, 1, implicit); + NULL_TREE, 1, implicit, + braced_init_obstack); constructor_fields = 0; } @@ -8128,14 +8158,17 @@ process_init_element (struct c_expr value, bool implicit) while (constructor_stack != range_stack->stack) { gcc_assert (constructor_stack->implicit); - process_init_element (pop_init_level (1), true); + process_init_element (pop_init_level (1, + braced_init_obstack), + true, braced_init_obstack); } for (p = range_stack; !p->range_end || tree_int_cst_equal (p->index, p->range_end); p = p->prev) { gcc_assert (constructor_stack->implicit); - process_init_element (pop_init_level (1), true); + process_init_element (pop_init_level (1, braced_init_obstack), + true, braced_init_obstack); } p->index = size_binop_loc (input_location, @@ -8155,7 +8188,7 @@ process_init_element (struct c_expr value, bool implicit) p = p->next; if (!p) break; - push_init_level (2); + push_init_level (2, braced_init_obstack); p->stack = constructor_stack; if (p->range_end && tree_int_cst_equal (p->index, p->range_end)) p->index = p->range_start; diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 48173d9b992..319b1832295 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -2616,6 +2616,22 @@ expand_debug_expr (tree exp) return gen_rtx_FIX (mode, op0); case POINTER_PLUS_EXPR: + /* For the rare target where pointers are not the same size as + size_t, we need to check for mis-matched modes and correct + the addend. */ + if (op0 && op1 + && GET_MODE (op0) != VOIDmode && GET_MODE (op1) != VOIDmode + && GET_MODE (op0) != GET_MODE (op1)) + { + if (GET_MODE_BITSIZE (GET_MODE (op0)) < GET_MODE_BITSIZE (GET_MODE (op1))) + op1 = gen_rtx_TRUNCATE (GET_MODE (op0), op1); + else + /* We always sign-extend, regardless of the signedness of + the operand, because the operand is always unsigned + here even if the original C expression is signed. */ + op1 = gen_rtx_SIGN_EXTEND (GET_MODE (op0), op1); + } + /* Fall through. */ case PLUS_EXPR: return gen_rtx_PLUS (mode, op0, op1); @@ -3007,14 +3023,15 @@ expand_debug_expr (tree exp) if (SCALAR_INT_MODE_P (GET_MODE (op0)) && SCALAR_INT_MODE_P (mode)) { + enum machine_mode inner_mode = GET_MODE (op0); if (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0)))) - op0 = gen_rtx_ZERO_EXTEND (mode, op0); + op0 = simplify_gen_unary (ZERO_EXTEND, mode, op0, inner_mode); else - op0 = gen_rtx_SIGN_EXTEND (mode, op0); + op0 = simplify_gen_unary (SIGN_EXTEND, mode, op0, inner_mode); if (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 1)))) - op1 = gen_rtx_ZERO_EXTEND (mode, op1); + op1 = simplify_gen_unary (ZERO_EXTEND, mode, op1, inner_mode); else - op1 = gen_rtx_SIGN_EXTEND (mode, op1); + op1 = simplify_gen_unary (SIGN_EXTEND, mode, op1, inner_mode); return gen_rtx_MULT (mode, op0, op1); } return NULL; diff --git a/gcc/cgraph.c b/gcc/cgraph.c index c698d9a5502..c5e0f3d940c 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -1467,7 +1467,8 @@ cgraph_remove_node (struct cgraph_node *node) struct cgraph_node *n = (struct cgraph_node *) *slot; if (!n->clones && !n->clone_of && !n->global.inlined_to && (cgraph_global_info_ready - && (TREE_ASM_WRITTEN (n->decl) || DECL_EXTERNAL (n->decl)))) + && (TREE_ASM_WRITTEN (n->decl) || DECL_EXTERNAL (n->decl) + || n->in_other_partition))) kill_body = true; } if (assembler_name_hash) @@ -1628,6 +1629,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) fprintf (f, "%s/%i(%i)", cgraph_node_name (node), node->uid, node->pid); dump_addr (f, " @", (void *)node); + if (DECL_ASSEMBLER_NAME_SET_P (node->decl)) + fprintf (f, " (asm: %s)", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl))); if (node->global.inlined_to) fprintf (f, " (inline copy in %s/%i)", cgraph_node_name (node->global.inlined_to), @@ -1639,6 +1642,10 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) if (cgraph_function_flags_ready) fprintf (f, " availability:%s", cgraph_availability_names [cgraph_function_body_availability (node)]); + if (node->analyzed) + fprintf (f, " analyzed"); + if (node->in_other_partition) + fprintf (f, " in_other_partition"); if (node->count) fprintf (f, " executed "HOST_WIDEST_INT_PRINT_DEC"x", (HOST_WIDEST_INT)node->count); @@ -1666,6 +1673,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) fprintf (f, " address_taken"); else if (node->reachable) fprintf (f, " reachable"); + else if (node->reachable_from_other_partition) + fprintf (f, " reachable_from_other_partition"); if (gimple_has_body_p (node->decl)) fprintf (f, " body"); if (node->process) diff --git a/gcc/cgraph.h b/gcc/cgraph.h index dc6168a83ac..6bc565a2d17 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -249,11 +249,15 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node { cgraph_remove_unreachable_nodes cgraph still can contain unreachable nodes when they are needed for virtual clone instantiation. */ unsigned reachable : 1; + /* Set when function is reachable by call from other LTRANS partition. */ + unsigned reachable_from_other_partition : 1; /* Set once the function is lowered (i.e. its CFG is built). */ unsigned lowered : 1; /* Set once the function has been instantiated and its callee lists created. */ unsigned analyzed : 1; + /* Set when function is available in the other LTO partition. */ + unsigned in_other_partition : 1; /* Set when function is scheduled to be processed by local passes. */ unsigned process : 1; /* Set for aliases once they got through assemble_alias. */ @@ -723,7 +727,7 @@ cgraph_only_called_directly_p (struct cgraph_node *node) static inline bool cgraph_can_remove_if_no_direct_calls_p (struct cgraph_node *node) { - return (!node->needed + return (!node->needed && !node->reachable_from_other_partition && (DECL_COMDAT (node->decl) || !node->local.externally_visible)); } diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 8fe3a879534..608a4af7c46 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1146,7 +1146,7 @@ cgraph_mark_functions_to_output (void) outside the current compilation unit. */ if (node->analyzed && !node->global.inlined_to - && (node->needed + && (node->needed || node->reachable_from_other_partition || (e && node->reachable)) && !TREE_ASM_WRITTEN (decl) && !DECL_EXTERNAL (decl)) @@ -1173,6 +1173,10 @@ cgraph_mark_functions_to_output (void) #ifdef ENABLE_CHECKING if (!node->global.inlined_to && gimple_has_body_p (decl) + /* FIXME: in ltrans unit when offline copy is outside partition but inline copies + are inside partition, we can end up not removing the body since we no longer + have analyzed node pointing to it. */ + && !node->in_other_partition && !DECL_EXTERNAL (decl)) { dump_cgraph_node (stderr, node); @@ -1181,6 +1185,7 @@ cgraph_mark_functions_to_output (void) #endif gcc_assert (node->global.inlined_to || !gimple_has_body_p (decl) + || node->in_other_partition || DECL_EXTERNAL (decl)); } @@ -1194,6 +1199,10 @@ cgraph_mark_functions_to_output (void) tree decl = node->decl; if (!node->global.inlined_to && gimple_has_body_p (decl) + /* FIXME: in ltrans unit when offline copy is outside partition but inline copies + are inside partition, we can end up not removing the body since we no longer + have analyzed node pointing to it. */ + && !node->in_other_partition && !DECL_EXTERNAL (decl)) { dump_cgraph_node (stderr, node); @@ -2276,6 +2285,7 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e) gsi = gsi_for_stmt (e->call_stmt); gsi_replace (&gsi, new_stmt, true); + update_stmt (new_stmt); /* Update EH information too, just in case. */ maybe_clean_or_replace_eh_stmt (e->call_stmt, new_stmt); @@ -2379,6 +2389,7 @@ cgraph_materialize_all_clones (void) push_cfun (DECL_STRUCT_FUNCTION (node->decl)); for (e = node->callees; e; e = e->next_callee) cgraph_redirect_edge_call_stmt_to_callee (e); + gcc_assert (!need_ssa_update_p (cfun)); pop_cfun (); current_function_decl = NULL; #ifdef ENABLE_CHECKING diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 2d5003bcfee..9682ba12d25 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -3533,17 +3533,11 @@ (define_expand "negdi2" [(parallel - [(set (match_operand:DI 0 "s_register_operand" "") - (neg:DI (match_operand:DI 1 "s_register_operand" ""))) + [(set (match_operand:DI 0 "s_register_operand" "") + (neg:DI (match_operand:DI 1 "s_register_operand" ""))) (clobber (reg:CC CC_REGNUM))])] "TARGET_EITHER" - " - if (TARGET_THUMB1) - { - if (GET_CODE (operands[1]) != REG) - operands[1] = force_reg (DImode, operands[1]); - } - " + "" ) ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1). @@ -3559,8 +3553,8 @@ ) (define_insn "*thumb1_negdi2" - [(set (match_operand:DI 0 "register_operand" "=&l") - (neg:DI (match_operand:DI 1 "register_operand" "l"))) + [(set (match_operand:DI 0 "register_operand" "=&l") + (neg:DI (match_operand:DI 1 "register_operand" "l"))) (clobber (reg:CC CC_REGNUM))] "TARGET_THUMB1" "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1" diff --git a/gcc/config/arm/bpabi-v6m.S b/gcc/config/arm/bpabi-v6m.S index 75d50d967a7..db1d0ed2529 100644 --- a/gcc/config/arm/bpabi-v6m.S +++ b/gcc/config/arm/bpabi-v6m.S @@ -22,6 +22,16 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see . */ +#ifdef __ARM_EABI__ +/* Some attributes that are common to all routines in this file. */ + /* Tag_ABI_align_needed: This code does not require 8-byte + alignment from the caller. */ + /* .eabi_attribute 24, 0 -- default setting. */ + /* Tag_ABI_align_preserved: This code preserves 8-byte + alignment in any callee. */ + .eabi_attribute 25, 1 +#endif /* __ARM_EABI__ */ + #ifdef L_aeabi_lcmp FUNC_START aeabi_lcmp diff --git a/gcc/config/arm/bpabi.S b/gcc/config/arm/bpabi.S index ccc569e9821..10e0f95654d 100644 --- a/gcc/config/arm/bpabi.S +++ b/gcc/config/arm/bpabi.S @@ -22,6 +22,16 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see . */ +#ifdef __ARM_EABI__ +/* Some attributes that are common to all routines in this file. */ + /* Tag_ABI_align_needed: This code does not require 8-byte + alignment from the caller. */ + /* .eabi_attribute 24, 0 -- default setting. */ + /* Tag_ABI_align_preserved: This code preserves 8-byte + alignment in any callee. */ + .eabi_attribute 25, 1 +#endif /* __ARM_EABI__ */ + #ifdef L_aeabi_lcmp ARM_FUNC_START aeabi_lcmp diff --git a/gcc/config/arm/crti.asm b/gcc/config/arm/crti.asm index 310d7840dee..bda56c56fe8 100644 --- a/gcc/config/arm/crti.asm +++ b/gcc/config/arm/crti.asm @@ -35,6 +35,15 @@ #else #define TYPE(x) #endif +#ifdef __ARM_EABI__ +/* Some attributes that are common to all routines in this file. */ + /* Tag_ABI_align_needed: This code does not require 8-byte + alignment from the caller. */ + /* .eabi_attribute 24, 0 -- default setting. */ + /* Tag_ABI_align_preserved: This code preserves 8-byte + alignment in any callee. */ + .eabi_attribute 25, 1 +#endif /* __ARM_EABI__ */ # Note - this macro is complemented by the FUNC_END macro # in crtn.asm. If you change this macro you must also change diff --git a/gcc/config/arm/crtn.asm b/gcc/config/arm/crtn.asm index 006b7d5260a..e4d59803ad1 100644 --- a/gcc/config/arm/crtn.asm +++ b/gcc/config/arm/crtn.asm @@ -26,6 +26,16 @@ .previous #endif +#ifdef __ARM_EABI__ +/* Some attributes that are common to all routines in this file. */ + /* Tag_ABI_align_needed: This code does not require 8-byte + alignment from the caller. */ + /* .eabi_attribute 24, 0 -- default setting. */ + /* Tag_ABI_align_preserved: This code preserves 8-byte + alignment in any callee. */ + .eabi_attribute 25, 1 +#endif /* __ARM_EABI__ */ + # This file just makes sure that the .fini and .init sections do in # fact return. Users may put any desired instructions in those sections. # This file is the last thing linked into any executable. diff --git a/gcc/config/arm/lib1funcs.asm b/gcc/config/arm/lib1funcs.asm index cd64da35860..34aa23e6979 100644 --- a/gcc/config/arm/lib1funcs.asm +++ b/gcc/config/arm/lib1funcs.asm @@ -31,10 +31,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #ifdef __ARM_EABI__ /* Some attributes that are common to all routines in this file. */ - /* Tag_ABI_align8_needed: This code does not require 8-byte + /* Tag_ABI_align_needed: This code does not require 8-byte alignment from the caller. */ /* .eabi_attribute 24, 0 -- default setting. */ - /* Tag_ABI_align8_preserved: This code preserves 8-byte + /* Tag_ABI_align_preserved: This code preserves 8-byte alignment in any callee. */ .eabi_attribute 25, 1 #endif /* __ARM_EABI__ */ diff --git a/gcc/config/arm/libunwind.S b/gcc/config/arm/libunwind.S index 800e7e0caa9..b04e41731fa 100644 --- a/gcc/config/arm/libunwind.S +++ b/gcc/config/arm/libunwind.S @@ -27,6 +27,16 @@ .previous #endif +#ifdef __ARM_EABI__ +/* Some attributes that are common to all routines in this file. */ + /* Tag_ABI_align_needed: This code does not require 8-byte + alignment from the caller. */ + /* .eabi_attribute 24, 0 -- default setting. */ + /* Tag_ABI_align_preserved: This code preserves 8-byte + alignment in any callee. */ + .eabi_attribute 25, 1 +#endif /* __ARM_EABI__ */ + #ifndef __symbian__ #include "lib1funcs.asm" diff --git a/gcc/config/avr/avr-devices.c b/gcc/config/avr/avr-devices.c index ad58772b2a1..86006c8ba8a 100755 --- a/gcc/config/avr/avr-devices.c +++ b/gcc/config/avr/avr-devices.c @@ -23,7 +23,7 @@ #include "coretypes.h" #include "tm.h" -/* List of all known AVR MCU architectyres. */ +/* List of all known AVR MCU architectures. */ const struct base_arch_s avr_arch_types[] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, NULL, "avr2" }, /* unknown device specified */ @@ -67,15 +67,23 @@ const struct mcu_type_s avr_mcu_types[] = { { "attiny13", ARCH_AVR25, "__AVR_ATtiny13__", 1, 0x0060, "tn13" }, { "attiny13a", ARCH_AVR25, "__AVR_ATtiny13A__", 1, 0x0060, "tn13a" }, { "attiny2313", ARCH_AVR25, "__AVR_ATtiny2313__", 1, 0x0060, "tn2313" }, + { "attiny2313a", ARCH_AVR25, "__AVR_ATtiny2313A__", 1, 0x0060, "tn2313a" }, { "attiny24", ARCH_AVR25, "__AVR_ATtiny24__", 1, 0x0060, "tn24" }, + { "attiny24a", ARCH_AVR25, "__AVR_ATtiny24A__" 1, 0x0060, "tn24a" }, + { "attiny4313", ARCH_AVR25, "__AVR_ATtiny4313__" 1, 0x0060, "tn4313" }, { "attiny44", ARCH_AVR25, "__AVR_ATtiny44__", 0, 0x0060, "tn44" }, + { "attiny44a", ARCH_AVR25, "__AVR_ATtiny44A__" 0, 0x0060, "tn44a" }, { "attiny84", ARCH_AVR25, "__AVR_ATtiny84__", 0, 0x0060, "tn84" }, + { "attiny84a", ARCH_AVR25, "__AVR_ATtiny84A__" 0, 0x0060, "tn84" }, { "attiny25", ARCH_AVR25, "__AVR_ATtiny25__", 1, 0x0060, "tn25" }, { "attiny45", ARCH_AVR25, "__AVR_ATtiny45__", 0, 0x0060, "tn45" }, { "attiny85", ARCH_AVR25, "__AVR_ATtiny85__", 0, 0x0060, "tn85" }, { "attiny261", ARCH_AVR25, "__AVR_ATtiny261__", 1, 0x0060, "tn261" }, + { "attiny261a", ARCH_AVR25, "__AVR_ATtiny261A__" 1, 0x0060, "tn261a" }, { "attiny461", ARCH_AVR25, "__AVR_ATtiny461__", 0, 0x0060, "tn461" }, + { "attiny461a", ARCH_AVR25, "__AVR_ATtiny461A__" 0, 0x0060, "tn461a" }, { "attiny861", ARCH_AVR25, "__AVR_ATtiny861__", 0, 0x0060, "tn861" }, + { "attiny861a", ARCH_AVR25, "__AVR_ATtiny861A__" 0, 0x0060, "tn861a" }, { "attiny43u", ARCH_AVR25, "__AVR_ATtiny43U__", 0, 0x0060, "tn43u" }, { "attiny87", ARCH_AVR25, "__AVR_ATtiny87__", 0, 0x0100, "tn87" }, { "attiny48", ARCH_AVR25, "__AVR_ATtiny48__", 0, 0x0100, "tn48" }, @@ -97,21 +105,19 @@ const struct mcu_type_s avr_mcu_types[] = { { "atmega16u2", ARCH_AVR35, "__AVR_ATmega16U2__", 0, 0x0100, "m16u2" }, { "atmega32u2", ARCH_AVR35, "__AVR_ATmega32U2__", 0, 0x0100, "m32u2" }, { "attiny167", ARCH_AVR35, "__AVR_ATtiny167__", 0, 0x0100, "tn167" }, - { "attiny327", ARCH_AVR35, "__AVR_ATtiny327__", 0, 0x0100, "tn327" }, /* Enhanced, <= 8K. */ { "avr4", ARCH_AVR4, NULL, 0, 0x0060, "m8" }, { "atmega8", ARCH_AVR4, "__AVR_ATmega8__", 0, 0x0060, "m8" }, { "atmega48", ARCH_AVR4, "__AVR_ATmega48__", 0, 0x0100, "m48" }, + { "atmega48a", ARCH_AVR4, "__AVR_ATmega48A__" 0, 0x0100, "m48a" }, { "atmega48p", ARCH_AVR4, "__AVR_ATmega48P__", 0, 0x0100, "m48p" }, { "atmega88", ARCH_AVR4, "__AVR_ATmega88__", 0, 0x0100, "m88" }, + { "atmega88a", ARCH_AVR4, "__AVR_ATmega88A__" 0, 0x0100, "m88a" }, { "atmega88p", ARCH_AVR4, "__AVR_ATmega88P__", 0, 0x0100, "m88p" }, + { "atmega88pa", ARCH_AVR4, "__AVR_ATmega88PA__" 0, 0x0100, "m88pa" }, { "atmega8515", ARCH_AVR4, "__AVR_ATmega8515__", 0, 0x0060, "m8515" }, { "atmega8535", ARCH_AVR4, "__AVR_ATmega8535__", 0, 0x0060, "m8535" }, - { "atmega8c1", ARCH_AVR4, "__AVR_ATmega8C1__", 0, 0x0100, "m8c1" }, - { "atmega8m1", ARCH_AVR4, "__AVR_ATmega8M1__", 0, 0x0100, "m8m1" }, { "atmega8hva", ARCH_AVR4, "__AVR_ATmega8HVA__", 0, 0x0100, "m8hva" }, - { "atmega4hvd", ARCH_AVR4, "__AVR_ATmega4HVD__", 0, 0x0100, "m4hvd" }, - { "atmega8hvd", ARCH_AVR4, "__AVR_ATmega8HVD__", 0, 0x0100, "m8hvd" }, { "at90pwm1", ARCH_AVR4, "__AVR_AT90PWM1__", 0, 0x0100, "90pwm1" }, { "at90pwm2", ARCH_AVR4, "__AVR_AT90PWM2__", 0, 0x0100, "90pwm2" }, { "at90pwm2b", ARCH_AVR4, "__AVR_AT90PWM2B__", 0, 0x0100, "90pwm2b" }, @@ -121,45 +127,68 @@ const struct mcu_type_s avr_mcu_types[] = { /* Enhanced, > 8K, <= 64K. */ { "avr5", ARCH_AVR5, NULL, 0, 0x0060, "m16" }, { "atmega16", ARCH_AVR5, "__AVR_ATmega16__", 0, 0x0060, "m16" }, + { "atmega16a", ARCH_AVR5, "__AVR_ATmega16A__" 0, 0x0060, "m16a" }, { "atmega161", ARCH_AVR5, "__AVR_ATmega161__", 0, 0x0060, "m161" }, { "atmega162", ARCH_AVR5, "__AVR_ATmega162__", 0, 0x0100, "m162" }, { "atmega163", ARCH_AVR5, "__AVR_ATmega163__", 0, 0x0060, "m163" }, + { "atmega164a", ARCH_AVR5, "__AVR_ATmega164A__" 0, 0x0060, "m164a" }, { "atmega164p", ARCH_AVR5, "__AVR_ATmega164P__", 0, 0x0100, "m164p" }, { "atmega165", ARCH_AVR5, "__AVR_ATmega165__", 0, 0x0100, "m165" }, + { "atmega165a", ARCH_AVR5, "__AVR_ATmega165A__" 0, 0x0100, "m165a" }, { "atmega165p", ARCH_AVR5, "__AVR_ATmega165P__", 0, 0x0100, "m165p" }, { "atmega168", ARCH_AVR5, "__AVR_ATmega168__", 0, 0x0100, "m168" }, + { "atmega168a", ARCH_AVR5, "__AVR_ATmega168A__" 0, 0x0100, "m168a" }, { "atmega168p", ARCH_AVR5, "__AVR_ATmega168P__", 0, 0x0100, "m168p" }, { "atmega169", ARCH_AVR5, "__AVR_ATmega169__", 0, 0x0100, "m169" }, + { "atmega169a", ARCH_AVR5, "__AVR_ATmega169A__" 0, 0x0100, "m169a" }, { "atmega169p", ARCH_AVR5, "__AVR_ATmega169P__", 0, 0x0100, "m169p" }, + { "atmega169pa", ARCH_AVR5, "__AVR_ATmega169PA__" 0, 0x0100, "m169pa" }, { "atmega32", ARCH_AVR5, "__AVR_ATmega32__", 0, 0x0060, "m32" }, { "atmega323", ARCH_AVR5, "__AVR_ATmega323__", 0, 0x0060, "m323" }, + { "atmega324a", ARCH_AVR5, "__AVR_ATmega324A__" 0, 0x0100, "m324a" }, { "atmega324p", ARCH_AVR5, "__AVR_ATmega324P__", 0, 0x0100, "m324p" }, + { "atmega324pa", ARCH_AVR5, "__AVR_ATmega324PA__" 0, 0x0100, "m324pa" }, { "atmega325", ARCH_AVR5, "__AVR_ATmega325__", 0, 0x0100, "m325" }, + { "atmega325a", ARCH_AVR5, "__AVR_ATmega325A__" 0, 0x0100, "m325a" }, { "atmega325p", ARCH_AVR5, "__AVR_ATmega325P__", 0, 0x0100, "m325p" }, { "atmega3250", ARCH_AVR5, "__AVR_ATmega3250__", 0, 0x0100, "m3250" }, + { "atmega3250a", ARCH_AVR5, "__AVR_ATmega3250A__" 0, 0x0100, "m3250a" }, { "atmega3250p", ARCH_AVR5, "__AVR_ATmega3250P__", 0, 0x0100, "m3250p" }, + { "atmega328", ARCH_AVR5, "__AVR_ATmega328__" 0, 0x0100, "m328" }, { "atmega328p", ARCH_AVR5, "__AVR_ATmega328P__", 0, 0x0100, "m328p" }, { "atmega329", ARCH_AVR5, "__AVR_ATmega329__", 0, 0x0100, "m329" }, + { "atmega329a", ARCH_AVR5, "__AVR_ATmega329A__" 0, 0x0100, "m329a" }, { "atmega329p", ARCH_AVR5, "__AVR_ATmega329P__", 0, 0x0100, "m329p" }, + { "atmega329pa", ARCH_AVR5, "__AVR_ATmega329PA__" 0, 0x0100, "m329pa" }, { "atmega3290", ARCH_AVR5, "__AVR_ATmega3290__", 0, 0x0100, "m3290" }, + { "atmega3290a", ARCH_AVR5, "__AVR_ATmega3290A__" 0, 0x0100, "m3290a" }, { "atmega3290p", ARCH_AVR5, "__AVR_ATmega3290P__", 0, 0x0100, "m3290p" }, { "atmega406", ARCH_AVR5, "__AVR_ATmega406__", 0, 0x0100, "m406" }, { "atmega64", ARCH_AVR5, "__AVR_ATmega64__", 0, 0x0100, "m64" }, { "atmega640", ARCH_AVR5, "__AVR_ATmega640__", 0, 0x0200, "m640" }, { "atmega644", ARCH_AVR5, "__AVR_ATmega644__", 0, 0x0100, "m644" }, + { "atmega644a", ARCH_AVR5, "__AVR_ATmega644A__" 0, 0x0100, "m644a" }, { "atmega644p", ARCH_AVR5, "__AVR_ATmega644P__", 0, 0x0100, "m644p" }, + { "atmega644pa", ARCH_AVR5, "__AVR_ATmega644PA__" 0, 0x0100, "m644pa" }, { "atmega645", ARCH_AVR5, "__AVR_ATmega645__", 0, 0x0100, "m645" }, + { "atmega645a", ARCH_AVR5, "__AVR_ATmega645A__" 0, 0x0100, "m645a" }, + { "atmega645p", ARCH_AVR5, "__AVR_ATmega645P__" 0, 0x0100, "m645p" }, { "atmega6450", ARCH_AVR5, "__AVR_ATmega6450__", 0, 0x0100, "m6450" }, + { "atmega6450a", ARCH_AVR5, "__AVR_ATmega6450A__" 0, 0x0100, "m6450a" }, + { "atmega6450p", ARCH_AVR5, "__AVR_ATmega6450P__" 0, 0x0100, "m6450p" }, { "atmega649", ARCH_AVR5, "__AVR_ATmega649__", 0, 0x0100, "m649" }, + { "atmega649a", ARCH_AVR5, "__AVR_ATmega649A__" 0, 0x0100, "m649a" }, + { "atmega649p", ARCH_AVR5, "__AVR_ATmega649P__" 0, 0x0100, "m649p" }, { "atmega6490", ARCH_AVR5, "__AVR_ATmega6490__", 0, 0x0100, "m6490" }, { "atmega16hva", ARCH_AVR5, "__AVR_ATmega16HVA__", 0, 0x0100, "m16hva" }, + { "atmega16hva2", ARCH_AVR5, "__AVR_ATmega16HVA2__" 0, 0x0100, "m16hva2" }, { "atmega16hvb", ARCH_AVR5, "__AVR_ATmega16HVB__", 0, 0x0100, "m16hvb" }, - { "atmega32hvb", ARCH_AVR5, "__AVR_ATmega32HVB__", 0, 0x0100, "m23hvb" }, + { "atmega32hvb", ARCH_AVR5, "__AVR_ATmega32HVB__", 0, 0x0100, "m32hvb" }, + { "atmega64hve", ARCH_AVR5, "__AVR_ATmega64HVE__" 0, 0x0100, "m64hve" }, { "at90can32", ARCH_AVR5, "__AVR_AT90CAN32__", 0, 0x0100, "can32" }, { "at90can64", ARCH_AVR5, "__AVR_AT90CAN64__", 0, 0x0100, "can64" }, { "at90pwm216", ARCH_AVR5, "__AVR_AT90PWM216__", 0, 0x0100, "90pwm216" }, { "at90pwm316", ARCH_AVR5, "__AVR_AT90PWM316__", 0, 0x0100, "90pwm316" }, - { "atmega16c1", ARCH_AVR5, "__AVR_ATmega16C1__", 0, 0x0100, "m16c1" }, { "atmega32c1", ARCH_AVR5, "__AVR_ATmega32C1__", 0, 0x0100, "m32c1" }, { "atmega64c1", ARCH_AVR5, "__AVR_ATmega64C1__", 0, 0x0100, "m64c1" }, { "atmega16m1", ARCH_AVR5, "__AVR_ATmega16M1__", 0, 0x0100, "m16m1" }, @@ -172,6 +201,7 @@ const struct mcu_type_s avr_mcu_types[] = { { "at90usb646", ARCH_AVR5, "__AVR_AT90USB646__", 0, 0x0100, "usb646" }, { "at90usb647", ARCH_AVR5, "__AVR_AT90USB647__", 0, 0x0100, "usb647" }, { "at94k", ARCH_AVR5, "__AVR_AT94K__", 0, 0x0060, "at94k" }, + { "m3000", ARCH_AVR5, "__AVR_M3000__", 0, 0x1000, "m3000" }, /* Enhanced, == 128K. */ { "avr51", ARCH_AVR51, NULL, 0, 0x0100, "m128" }, { "atmega128", ARCH_AVR51, "__AVR_ATmega128__", 0, 0x0100, "m128" }, @@ -182,9 +212,6 @@ const struct mcu_type_s avr_mcu_types[] = { { "at90can128", ARCH_AVR51, "__AVR_AT90CAN128__", 0, 0x0100, "can128" }, { "at90usb1286", ARCH_AVR51, "__AVR_AT90USB1286__", 0, 0x0100, "usb1286" }, { "at90usb1287", ARCH_AVR51, "__AVR_AT90USB1287__", 0, 0x0100, "usb1286" }, - { "m3000f", ARCH_AVR51, "__AVR_M3000F__", 0, 0x1000, "m3000f" }, - { "m3000s", ARCH_AVR51, "__AVR_M3000S__", 0, 0x1000, "m3000f" }, - { "m3001b", ARCH_AVR51, "__AVR_M3001B__", 0, 0x1000, "m3000f" }, /* 3-Byte PC. */ { "avr6", ARCH_AVR6, NULL, 0, 0x0200, "m2561" }, { "atmega2560", ARCH_AVR6, "__AVR_ATmega2560__", 0, 0x0200, "m2561" }, diff --git a/gcc/config/avr/t-avr b/gcc/config/avr/t-avr index 91d1fe86fbc..1d57a0b3421 100644 --- a/gcc/config/avr/t-avr +++ b/gcc/config/avr/t-avr @@ -81,15 +81,23 @@ MULTILIB_MATCHES = \ mmcu?avr25=mmcu?attiny13 \ mmcu?avr25=mmcu?attiny13a \ mmcu?avr25=mmcu?attiny2313 \ + mmcu?avr25=mmcu?attiny2313a \ + mmcu?avr25=mmcu?attiny4313 \ mmcu?avr25=mmcu?attiny24 \ + mmcu?avr25=mmcu?attiny24a \ mmcu?avr25=mmcu?attiny44 \ + mmcu?avr25=mmcu?attiny44a \ mmcu?avr25=mmcu?attiny84 \ + mmcu?avr25=mmcu?attiny84a \ mmcu?avr25=mmcu?attiny25 \ mmcu?avr25=mmcu?attiny45 \ mmcu?avr25=mmcu?attiny85 \ mmcu?avr25=mmcu?attiny261 \ + mmcu?avr25=mmcu?attiny261a \ mmcu?avr25=mmcu?attiny461 \ + mmcu?avr25=mmcu?attiny461a \ mmcu?avr25=mmcu?attiny861 \ + mmcu?avr25=mmcu?attiny861a \ mmcu?avr25=mmcu?attiny43u \ mmcu?avr25=mmcu?attiny87 \ mmcu?avr25=mmcu?attiny48 \ @@ -105,19 +113,17 @@ MULTILIB_MATCHES = \ mmcu?avr35=mmcu?atmega16u2 \ mmcu?avr35=mmcu?atmega32u2 \ mmcu?avr35=mmcu?attiny167 \ - mmcu?avr35=mmcu?attiny327 \ mmcu?avr4=mmcu?atmega48 \ + mmcu?avr4=mmcu?atmega48a \ mmcu?avr4=mmcu?atmega48p \ mmcu?avr4=mmcu?atmega8 \ mmcu?avr4=mmcu?atmega8515 \ mmcu?avr4=mmcu?atmega8535 \ mmcu?avr4=mmcu?atmega88 \ + mmcu?avr4=mmcu?atmega88a \ mmcu?avr4=mmcu?atmega88p \ + mmcu?avr4=mmcu?atmega88pa \ mmcu?avr4=mmcu?atmega8hva \ - mmcu?avr4=mmcu?atmega4hvd \ - mmcu?avr4=mmcu?atmega8hvd \ - mmcu?avr4=mmcu?atmega8c1 \ - mmcu?avr4=mmcu?atmega8m1 \ mmcu?avr4=mmcu?at90pwm1 \ mmcu?avr4=mmcu?at90pwm2 \ mmcu?avr4=mmcu?at90pwm2b \ @@ -125,45 +131,70 @@ MULTILIB_MATCHES = \ mmcu?avr4=mmcu?at90pwm3b \ mmcu?avr4=mmcu?at90pwm81 \ mmcu?avr5=mmcu?atmega16 \ + mmcu?avr5=mmcu?atmega16a \ mmcu?avr5=mmcu?atmega161 \ mmcu?avr5=mmcu?atmega162 \ mmcu?avr5=mmcu?atmega163 \ + mmcu?avr5=mmcu?atmega164a \ mmcu?avr5=mmcu?atmega164p \ mmcu?avr5=mmcu?atmega165 \ + mmcu?avr5=mmcu?atmega165a \ mmcu?avr5=mmcu?atmega165p \ mmcu?avr5=mmcu?atmega168 \ + mmcu?avr5=mmcu?atmega168a \ mmcu?avr5=mmcu?atmega168p \ mmcu?avr5=mmcu?atmega169 \ + mmcu?avr5=mmcu?atmega169a \ mmcu?avr5=mmcu?atmega169p \ + mmcu?avr5=mmcu?atmega169pa \ mmcu?avr5=mmcu?atmega32 \ mmcu?avr5=mmcu?atmega323 \ + mmcu?avr5=mmcu?atmega324a \ mmcu?avr5=mmcu?atmega324p \ + mmcu?avr5=mmcu?atmega324pa \ mmcu?avr5=mmcu?atmega325 \ + mmcu?avr5=mmcu?atmega325a \ mmcu?avr5=mmcu?atmega325p \ mmcu?avr5=mmcu?atmega3250 \ + mmcu?avr5=mmcu?atmega3250a \ mmcu?avr5=mmcu?atmega3250p \ + mmcu?avr5=mmcu?atmega328 \ mmcu?avr5=mmcu?atmega328p \ mmcu?avr5=mmcu?atmega329 \ + mmcu?avr5=mmcu?atmega329a \ mmcu?avr5=mmcu?atmega329p \ + mmcu?avr5=mmcu?atmega329pa \ mmcu?avr5=mmcu?atmega3290 \ + mmcu?avr5=mmcu?atmega3290a \ mmcu?avr5=mmcu?atmega3290p \ mmcu?avr5=mmcu?atmega406 \ mmcu?avr5=mmcu?atmega64 \ mmcu?avr5=mmcu?atmega640 \ mmcu?avr5=mmcu?atmega644 \ + mmcu?avr5=mmcu?atmega644a \ mmcu?avr5=mmcu?atmega644p \ + mmcu?avr5=mmcu?atmega644pa \ mmcu?avr5=mmcu?atmega645 \ + mmcu?avr5=mmcu?atmega645a \ + mmcu?avr5=mmcu?atmega645p \ mmcu?avr5=mmcu?atmega6450 \ + mmcu?avr5=mmcu?atmega6450a \ + mmcu?avr5=mmcu?atmega6450p \ mmcu?avr5=mmcu?atmega649 \ + mmcu?avr5=mmcu?atmega649a \ + mmcu?avr5=mmcu?atmega649p \ mmcu?avr5=mmcu?atmega6490 \ + mmcu?avr5=mmcu?atmega6490a \ + mmcu?avr5=mmcu?atmega6490p \ mmcu?avr5=mmcu?atmega16hva \ + mmcu?avr5=mmcu?atmega16hva2 \ mmcu?avr5=mmcu?atmega16hvb \ mmcu?avr5=mmcu?atmega32hvb \ + mmcu?avr5=mmcu?atmega64hve \ mmcu?avr5=mmcu?at90can32 \ mmcu?avr5=mmcu?at90can64 \ mmcu?avr5=mmcu?at90pwm216 \ mmcu?avr5=mmcu?at90pwm316 \ - mmcu?avr5=mmcu?atmega16c1 \ mmcu?avr5=mmcu?atmega32c1 \ mmcu?avr5=mmcu?atmega64c1 \ mmcu?avr5=mmcu?atmega16m1 \ @@ -176,6 +207,7 @@ MULTILIB_MATCHES = \ mmcu?avr5=mmcu?at90usb646 \ mmcu?avr5=mmcu?at90usb647 \ mmcu?avr5=mmcu?at94k \ + mmcu?avr5=mmcu?m3000 \ mmcu?avr51=mmcu?atmega128 \ mmcu?avr51=mmcu?atmega1280 \ mmcu?avr51=mmcu?atmega1281 \ @@ -184,9 +216,6 @@ MULTILIB_MATCHES = \ mmcu?avr51=mmcu?at90can128 \ mmcu?avr51=mmcu?at90usb1286 \ mmcu?avr51=mmcu?at90usb1287 \ - mmcu?avr51=mmcu?m3000f \ - mmcu?avr51=mmcu?m3000s \ - mmcu?avr51=mmcu?m3001b \ mmcu?avr6=mmcu?atmega2560 \ mmcu?avr6=mmcu?atmega2561 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index b99fe2ae345..f91410a2d66 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -6790,7 +6790,6 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum) { rtx save_area, mem; rtx label; - rtx label_ref; rtx tmp_reg; rtx nsse_reg; alias_set_type set; @@ -6841,35 +6840,9 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum) SSE saves. We need some preparation work to get this working. */ label = gen_label_rtx (); - label_ref = gen_rtx_LABEL_REF (Pmode, label); - /* Compute address to jump to : - label - eax*4 + nnamed_sse_arguments*4 Or - label - eax*5 + nnamed_sse_arguments*5 for AVX. */ - tmp_reg = gen_reg_rtx (Pmode); nsse_reg = gen_reg_rtx (Pmode); emit_insn (gen_zero_extendqidi2 (nsse_reg, gen_rtx_REG (QImode, AX_REG))); - emit_insn (gen_rtx_SET (VOIDmode, tmp_reg, - gen_rtx_MULT (Pmode, nsse_reg, - GEN_INT (4)))); - - /* vmovaps is one byte longer than movaps. */ - if (TARGET_AVX) - emit_insn (gen_rtx_SET (VOIDmode, tmp_reg, - gen_rtx_PLUS (Pmode, tmp_reg, - nsse_reg))); - - if (cum->sse_regno) - emit_move_insn - (nsse_reg, - gen_rtx_CONST (DImode, - gen_rtx_PLUS (DImode, - label_ref, - GEN_INT (cum->sse_regno - * (TARGET_AVX ? 5 : 4))))); - else - emit_move_insn (nsse_reg, label_ref); - emit_insn (gen_subdi3 (nsse_reg, nsse_reg, tmp_reg)); /* Compute address of memory block we save into. We always use pointer pointing 127 bytes after first byte to store - this is needed to keep @@ -6882,11 +6855,12 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum) mem = gen_rtx_MEM (BLKmode, plus_constant (tmp_reg, -127)); MEM_NOTRAP_P (mem) = 1; set_mem_alias_set (mem, set); - set_mem_align (mem, BITS_PER_WORD); + set_mem_align (mem, 64); /* And finally do the dirty job! */ emit_insn (gen_sse_prologue_save (mem, nsse_reg, - GEN_INT (cum->sse_regno), label)); + GEN_INT (cum->sse_regno), label, + gen_reg_rtx (Pmode))); } } @@ -7047,7 +7021,7 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, int indirect_p = 0; tree ptrtype; enum machine_mode nat_mode; - int arg_boundary; + unsigned int arg_boundary; /* Only 64bit target needs something special. */ if (!TARGET_64BIT || is_va_list_char_pointer (TREE_TYPE (valist))) @@ -7279,6 +7253,8 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t, size_int (-align)); t = fold_convert (TREE_TYPE (ovf), t); + if (crtl->stack_alignment_needed < arg_boundary) + crtl->stack_alignment_needed = arg_boundary; } gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue); gimplify_assign (addr, t, pre_p); @@ -9381,6 +9357,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) rtx base_reg, index_reg; HOST_WIDE_INT scale = 1; rtx scale_rtx = NULL_RTX; + rtx tmp; int retval = 1; enum ix86_address_seg seg = SEG_DEFAULT; @@ -9416,6 +9393,19 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) scale_rtx = XEXP (op, 1); break; + case ASHIFT: + if (index) + return 0; + index = XEXP (op, 0); + tmp = XEXP (op, 1); + if (!CONST_INT_P (tmp)) + return 0; + scale = INTVAL (tmp); + if ((unsigned HOST_WIDE_INT) scale > 3) + return 0; + scale = 1 << scale; + break; + case UNSPEC: if (XINT (op, 1) == UNSPEC_TP && TARGET_TLS_DIRECT_SEG_REFS @@ -9456,8 +9446,6 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) } else if (GET_CODE (addr) == ASHIFT) { - rtx tmp; - /* We're called for lea too, which implements ashift on occasion. */ index = XEXP (addr, 0); tmp = XEXP (addr, 1); @@ -20099,10 +20087,26 @@ ix86_local_alignment (tree exp, enum machine_mode mode, } /* x86-64 ABI requires arrays greater than 16 bytes to be aligned - to 16byte boundary. */ - if (TARGET_64BIT) + to 16byte boundary. Exact wording is: + + An array uses the same alignment as its elements, except that a local or + global array variable of length at least 16 bytes or + a C99 variable-length array variable always has alignment of at least 16 bytes. + + This was added to allow use of aligned SSE instructions at arrays. This + rule is meant for static storage (where compiler can not do the analysis + by itself). We follow it for automatic variables only when convenient. + We fully control everything in the function compiled and functions from + other unit can not rely on the alignment. + + Exclude va_list type. It is the common case of local array where + we can not benefit from the alignment. */ + if (TARGET_64BIT && optimize_function_for_speed_p (cfun) + && TARGET_SSE) { if (AGGREGATE_TYPE_P (type) + && (TYPE_MAIN_VARIANT (type) + != TYPE_MAIN_VARIANT (va_list_type_node)) && TYPE_SIZE (type) && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 16 diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index d08a7ea1081..8249efd31fd 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -85,6 +85,7 @@ (UNSPEC_SET_RIP 16) (UNSPEC_SET_GOT_OFFSET 17) (UNSPEC_MEMORY_BLOCKAGE 18) + (UNSPEC_SSE_PROLOGUE_SAVE_LOW 19) ; TLS support (UNSPEC_TP 20) @@ -2379,11 +2380,13 @@ && !x86_64_immediate_operand (operands[1], DImode) && 1" [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) (match_dup 3))] - "split_di (&operands[1], 1, &operands[2], &operands[3]); - operands[1] = gen_lowpart (DImode, operands[2]); - operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, - GEN_INT (4))); - ") +{ + split_di (&operands[1], 1, &operands[2], &operands[3]); + + operands[1] = gen_lowpart (DImode, operands[2]); + operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, + GEN_INT (4))); +}) (define_split [(set (match_operand:DI 0 "push_operand" "") @@ -2394,11 +2397,13 @@ && !x86_64_immediate_operand (operands[1], DImode)" [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) (match_dup 3))] - "split_di (&operands[1], 1, &operands[2], &operands[3]); - operands[1] = gen_lowpart (DImode, operands[2]); - operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, - GEN_INT (4))); - ") +{ + split_di (&operands[1], 1, &operands[2], &operands[3]); + + operands[1] = gen_lowpart (DImode, operands[2]); + operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, + GEN_INT (4))); +}) (define_insn "*pushdi2_prologue_rex64" [(set (match_operand:DI 0 "push_operand" "=<") @@ -7926,7 +7931,7 @@ (use (match_dup 1)) (clobber (reg:CC FLAGS_REG))])] { - operands[5] = GEN_INT (GET_MODE_BITSIZE (mode) - 1); + operands[5] = GEN_INT (GET_MODE_BITSIZE (mode)-1); if (mode != HImode && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)) @@ -10318,8 +10323,10 @@ "shrd{l}\t{%s2%1, %0|%0, %1, %2}" [(set_attr "type" "ishift") (set_attr "prefix_0f" "1") + (set_attr "mode" "SI") (set_attr "pent_pair" "np") - (set_attr "mode" "SI")]) + (set_attr "athlon_decode" "vector") + (set_attr "amdfam10_decode" "vector")]) (define_insn "ashrdi3_cvt" [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") @@ -11532,6 +11539,7 @@ [(const_int 0)] { operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]); + ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3], operands[7], operands[4], operands[5], operands[6], NULL_RTX); @@ -11555,6 +11563,7 @@ { operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]); + ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3], operands[7], operands[4], operands[5], operands[6], operands[2]); @@ -12174,38 +12183,33 @@ "leave" [(set_attr "type" "leave")]) -(define_expand "ffssi2" - [(parallel - [(set (match_operand:SI 0 "register_operand" "") - (ffs:SI (match_operand:SI 1 "nonimmediate_operand" ""))) - (clobber (match_scratch:SI 2 "")) - (clobber (reg:CC FLAGS_REG))])] - "" -{ - if (TARGET_CMOVE) - { - emit_insn (gen_ffs_cmove (operands[0], operands[1])); - DONE; - } -}) +;; Bit manipulation instructions. -(define_expand "ffs_cmove" +(define_expand "ffs2" [(set (match_dup 2) (const_int -1)) (parallel [(set (reg:CCZ FLAGS_REG) - (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "") - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "") - (ctz:SI (match_dup 1)))]) - (set (match_dup 0) (if_then_else:SI + (compare:CCZ + (match_operand:SWI48 1 "nonimmediate_operand" "") + (const_int 0))) + (set (match_operand:SWI48 0 "register_operand" "") + (ctz:SWI48 (match_dup 1)))]) + (set (match_dup 0) (if_then_else:SWI48 (eq (reg:CCZ FLAGS_REG) (const_int 0)) (match_dup 2) (match_dup 0))) - (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) + (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1))) (clobber (reg:CC FLAGS_REG))])] - "TARGET_CMOVE" - "operands[2] = gen_reg_rtx (SImode);") + "" +{ + if (mode == SImode && !TARGET_CMOVE) + { + emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1])); + DONE; + } + operands[2] = gen_reg_rtx (mode); +}) -(define_insn_and_split "*ffs_no_cmove" +(define_insn_and_split "ffssi2_no_cmove" [(set (match_operand:SI 0 "register_operand" "=r") (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) (clobber (match_scratch:SI 2 "=&q")) @@ -12229,93 +12233,68 @@ ix86_expand_clear (operands[2]); }) -(define_insn "*ffssi_1" +(define_insn "*ffs_1" [(set (reg:CCZ FLAGS_REG) - (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm") + (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm") (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=r") - (ctz:SI (match_dup 1)))] + (set (match_operand:SWI48 0 "register_operand" "=r") + (ctz:SWI48 (match_dup 1)))] "" - "bsf{l}\t{%1, %0|%0, %1}" - [(set_attr "type" "alu1") - (set_attr "prefix_0f" "1") - (set_attr "mode" "SI")]) - -(define_expand "ffsdi2" - [(set (match_dup 2) (const_int -1)) - (parallel [(set (reg:CCZ FLAGS_REG) - (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "") - (const_int 0))) - (set (match_operand:DI 0 "register_operand" "") - (ctz:DI (match_dup 1)))]) - (set (match_dup 0) (if_then_else:DI - (eq (reg:CCZ FLAGS_REG) (const_int 0)) - (match_dup 2) - (match_dup 0))) - (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1))) - (clobber (reg:CC FLAGS_REG))])] - "TARGET_64BIT" - "operands[2] = gen_reg_rtx (DImode);") - -(define_insn "*ffsdi_1" - [(set (reg:CCZ FLAGS_REG) - (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm") - (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=r") - (ctz:DI (match_dup 1)))] - "TARGET_64BIT" - "bsf{q}\t{%1, %0|%0, %1}" + "bsf{}\t{%1, %0|%0, %1}" [(set_attr "type" "alu1") (set_attr "prefix_0f" "1") - (set_attr "mode" "DI")]) + (set_attr "mode" "")]) -(define_insn "ctzsi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) +(define_insn "ctz2" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) (clobber (reg:CC FLAGS_REG))] "" - "bsf{l}\t{%1, %0|%0, %1}" - [(set_attr "type" "alu1") - (set_attr "prefix_0f" "1") - (set_attr "mode" "SI")]) - -(define_insn "ctzdi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" - "bsf{q}\t{%1, %0|%0, %1}" + "bsf{}\t{%1, %0|%0, %1}" [(set_attr "type" "alu1") (set_attr "prefix_0f" "1") - (set_attr "mode" "DI")]) + (set_attr "mode" "")]) -(define_expand "clzsi2" +(define_expand "clz2" [(parallel - [(set (match_operand:SI 0 "register_operand" "") - (minus:SI (const_int 31) - (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))) + [(set (match_operand:SWI248 0 "register_operand" "") + (minus:SWI248 + (match_dup 2) + (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "")))) (clobber (reg:CC FLAGS_REG))]) (parallel - [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31))) + [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2))) (clobber (reg:CC FLAGS_REG))])] "" { if (TARGET_ABM) { - emit_insn (gen_clzsi2_abm (operands[0], operands[1])); + emit_insn (gen_clz2_abm (operands[0], operands[1])); DONE; } + operands[2] = GEN_INT (GET_MODE_BITSIZE (mode)-1); }) -(define_insn "clzsi2_abm" - [(set (match_operand:SI 0 "register_operand" "=r") - (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) +(define_insn "clz2_abm" + [(set (match_operand:SWI248 0 "register_operand" "=r") + (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) (clobber (reg:CC FLAGS_REG))] "TARGET_ABM" - "lzcnt{l}\t{%1, %0|%0, %1}" + "lzcnt{}\t{%1, %0|%0, %1}" [(set_attr "prefix_rep" "1") (set_attr "type" "bitmanip") - (set_attr "mode" "SI")]) + (set_attr "mode" "")]) + +(define_insn "bsr_rex64" + [(set (match_operand:DI 0 "register_operand" "=r") + (minus:DI (const_int 63) + (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "bsr{q}\t{%1, %0|%0, %1}" + [(set_attr "type" "alu1") + (set_attr "prefix_0f" "1") + (set_attr "mode" "DI")]) (define_insn "bsr" [(set (match_operand:SI 0 "register_operand" "=r") @@ -12328,6 +12307,17 @@ (set_attr "prefix_0f" "1") (set_attr "mode" "SI")]) +(define_insn "*bsrhi" + [(set (match_operand:HI 0 "register_operand" "=r") + (minus:HI (const_int 15) + (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))) + (clobber (reg:CC FLAGS_REG))] + "" + "bsr{w}\t{%1, %0|%0, %1}" + [(set_attr "type" "alu1") + (set_attr "prefix_0f" "1") + (set_attr "mode" "HI")]) + (define_insn "popcount2" [(set (match_operand:SWI248 0 "register_operand" "=r") (popcount:SWI248 @@ -12384,12 +12374,12 @@ (set_attr "type" "bitmanip") (set_attr "mode" "SI")]) -(define_expand "bswapsi2" - [(set (match_operand:SI 0 "register_operand" "") - (bswap:SI (match_operand:SI 1 "register_operand" "")))] +(define_expand "bswap2" + [(set (match_operand:SWI48 0 "register_operand" "") + (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))] "" { - if (!(TARGET_BSWAP || TARGET_MOVBE)) + if (mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE)) { rtx x = operands[0]; @@ -12401,28 +12391,29 @@ } }) -(define_insn "*bswapsi_movbe" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m") - (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))] - "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))" +(define_insn "*bswap2_movbe" + [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m") + (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))] + "TARGET_MOVBE + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ bswap\t%0 movbe\t{%1, %0|%0, %1} movbe\t{%1, %0|%0, %1}" - [(set_attr "type" "*,imov,imov") - (set_attr "modrm" "*,1,1") - (set_attr "prefix_0f" "1") + [(set_attr "type" "bitmanip,imov,imov") + (set_attr "modrm" "0,1,1") + (set_attr "prefix_0f" "*,1,1") (set_attr "prefix_extra" "*,1,1") - (set_attr "length" "2,*,*") - (set_attr "mode" "SI")]) + (set_attr "mode" "")]) -(define_insn "*bswapsi_1" - [(set (match_operand:SI 0 "register_operand" "=r") - (bswap:SI (match_operand:SI 1 "register_operand" "0")))] +(define_insn "*bswap2_1" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))] "TARGET_BSWAP" "bswap\t%0" - [(set_attr "prefix_0f" "1") - (set_attr "length" "2")]) + [(set_attr "type" "bitmanip") + (set_attr "modrm" "0") + (set_attr "mode" "")]) (define_insn "*bswaphi_lowpart_1" [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r")) @@ -12444,114 +12435,6 @@ [(set_attr "length" "4") (set_attr "mode" "HI")]) -(define_expand "bswapdi2" - [(set (match_operand:DI 0 "register_operand" "") - (bswap:DI (match_operand:DI 1 "register_operand" "")))] - "TARGET_64BIT" - "") - -(define_insn "*bswapdi_movbe" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m") - (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))] - "TARGET_64BIT && TARGET_MOVBE - && !(MEM_P (operands[0]) && MEM_P (operands[1]))" - "@ - bswap\t%0 - movbe\t{%1, %0|%0, %1} - movbe\t{%1, %0|%0, %1}" - [(set_attr "type" "*,imov,imov") - (set_attr "modrm" "*,1,1") - (set_attr "prefix_0f" "1") - (set_attr "prefix_extra" "*,1,1") - (set_attr "length" "3,*,*") - (set_attr "mode" "DI")]) - -(define_insn "*bswapdi_1" - [(set (match_operand:DI 0 "register_operand" "=r") - (bswap:DI (match_operand:DI 1 "register_operand" "0")))] - "TARGET_64BIT" - "bswap\t%0" - [(set_attr "prefix_0f" "1") - (set_attr "length" "3")]) - -(define_expand "clzdi2" - [(parallel - [(set (match_operand:DI 0 "register_operand" "") - (minus:DI (const_int 63) - (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))) - (clobber (reg:CC FLAGS_REG))]) - (parallel - [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63))) - (clobber (reg:CC FLAGS_REG))])] - "TARGET_64BIT" -{ - if (TARGET_ABM) - { - emit_insn (gen_clzdi2_abm (operands[0], operands[1])); - DONE; - } -}) - -(define_insn "clzdi2_abm" - [(set (match_operand:DI 0 "register_operand" "=r") - (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && TARGET_ABM" - "lzcnt{q}\t{%1, %0|%0, %1}" - [(set_attr "prefix_rep" "1") - (set_attr "type" "bitmanip") - (set_attr "mode" "DI")]) - -(define_insn "bsr_rex64" - [(set (match_operand:DI 0 "register_operand" "=r") - (minus:DI (const_int 63) - (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" - "bsr{q}\t{%1, %0|%0, %1}" - [(set_attr "type" "alu1") - (set_attr "prefix_0f" "1") - (set_attr "mode" "DI")]) - -(define_expand "clzhi2" - [(parallel - [(set (match_operand:HI 0 "register_operand" "") - (minus:HI (const_int 15) - (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))) - (clobber (reg:CC FLAGS_REG))]) - (parallel - [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15))) - (clobber (reg:CC FLAGS_REG))])] - "" -{ - if (TARGET_ABM) - { - emit_insn (gen_clzhi2_abm (operands[0], operands[1])); - DONE; - } -}) - -(define_insn "clzhi2_abm" - [(set (match_operand:HI 0 "register_operand" "=r") - (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_ABM" - "lzcnt{w}\t{%1, %0|%0, %1}" - [(set_attr "prefix_rep" "1") - (set_attr "type" "bitmanip") - (set_attr "mode" "HI")]) - -(define_insn "*bsrhi" - [(set (match_operand:HI 0 "register_operand" "=r") - (minus:HI (const_int 15) - (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))) - (clobber (reg:CC FLAGS_REG))] - "" - "bsr{w}\t{%1, %0|%0, %1}" - [(set_attr "type" "alu1") - (set_attr "prefix_0f" "1") - (set_attr "mode" "HI")]) - (define_expand "paritydi2" [(set (match_operand:DI 0 "register_operand" "") (parity:DI (match_operand:DI 1 "register_operand" "")))] @@ -12580,6 +12463,25 @@ DONE; }) +(define_expand "paritysi2" + [(set (match_operand:SI 0 "register_operand" "") + (parity:SI (match_operand:SI 1 "register_operand" "")))] + "! TARGET_POPCNT" +{ + rtx scratch = gen_reg_rtx (QImode); + rtx cond; + + emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1])); + + cond = gen_rtx_fmt_ee (ORDERED, QImode, + gen_rtx_REG (CCmode, FLAGS_REG), + const0_rtx); + emit_insn (gen_rtx_SET (VOIDmode, scratch, cond)); + + emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); + DONE; +}) + (define_insn_and_split "paritydi2_cmp" [(set (reg:CC FLAGS_REG) (parity:CC (match_operand:DI 3 "register_operand" "0"))) @@ -12610,25 +12512,6 @@ operands[1] = gen_highpart (SImode, operands[3]); }) -(define_expand "paritysi2" - [(set (match_operand:SI 0 "register_operand" "") - (parity:SI (match_operand:SI 1 "register_operand" "")))] - "! TARGET_POPCNT" -{ - rtx scratch = gen_reg_rtx (QImode); - rtx cond; - - emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1])); - - cond = gen_rtx_fmt_ee (ORDERED, QImode, - gen_rtx_REG (CCmode, FLAGS_REG), - const0_rtx); - emit_insn (gen_rtx_SET (VOIDmode, scratch, cond)); - - emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); - DONE; -}) - (define_insn_and_split "paritysi2_cmp" [(set (reg:CC FLAGS_REG) (parity:CC (match_operand:SI 2 "register_operand" "0"))) @@ -16783,8 +16666,10 @@ (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) (match_dup 7) (match_dup 8)))] - "split_di (&operands[2], 2, &operands[5], &operands[7]); - split_di (&operands[0], 1, &operands[2], &operands[3]);") +{ + split_di (&operands[2], 2, &operands[5], &operands[7]); + split_di (&operands[0], 1, &operands[2], &operands[3]); +}) (define_insn "*movxfcc_1" [(set (match_operand:XF 0 "register_operand" "=f,f") @@ -18441,15 +18326,24 @@ (reg:DI XMM5_REG) (reg:DI XMM6_REG) (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE)) - (use (match_operand:DI 1 "register_operand" "")) + (clobber (match_operand:DI 1 "register_operand" "")) (use (match_operand:DI 2 "immediate_operand" "")) - (use (label_ref:DI (match_operand 3 "" "")))])] + (use (label_ref:DI (match_operand 3 "" ""))) + (clobber (match_operand:DI 4 "register_operand" "")) + (use (match_dup 1))])] "TARGET_64BIT" "") -(define_insn "*sse_prologue_save_insn" +;; Pre-reload version of prologue save. Until after prologue generation we don't know +;; what the size of save instruction will be. +;; Operand 0+operand 6 is the memory save area +;; Operand 1 is number of registers to save (will get overwritten to operand 5) +;; Operand 2 is number of non-vaargs SSE arguments +;; Operand 3 is label starting the save block +;; Operand 4 is used for temporary computation of jump address +(define_insn "*sse_prologue_save_insn1" [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R") - (match_operand:DI 4 "const_int_operand" "n"))) + (match_operand:DI 6 "const_int_operand" "n"))) (unspec:BLK [(reg:DI XMM0_REG) (reg:DI XMM1_REG) (reg:DI XMM2_REG) @@ -18458,9 +18352,98 @@ (reg:DI XMM5_REG) (reg:DI XMM6_REG) (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE)) + (clobber (match_operand:DI 1 "register_operand" "=r")) + (use (match_operand:DI 2 "const_int_operand" "i")) + (use (label_ref:DI (match_operand 3 "" "X"))) + (clobber (match_operand:DI 4 "register_operand" "=&r")) + (use (match_operand:DI 5 "register_operand" "1"))] + "TARGET_64BIT + && INTVAL (operands[6]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128 + && INTVAL (operands[6]) + INTVAL (operands[2]) * 16 >= -128" + "#" + [(set_attr "type" "other") + (set_attr "memory" "store") + (set_attr "mode" "DI")]) + +;; We know size of save instruction; expand the computation of jump address +;; in the jumptable. +(define_split + [(parallel [(set (match_operand:BLK 0 "" "") + (unspec:BLK [(reg:DI XMM0_REG) + (reg:DI XMM1_REG) + (reg:DI XMM2_REG) + (reg:DI XMM3_REG) + (reg:DI XMM4_REG) + (reg:DI XMM5_REG) + (reg:DI XMM6_REG) + (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE)) + (clobber (match_operand:DI 1 "register_operand" "")) + (use (match_operand:DI 2 "const_int_operand" "")) + (use (match_operand 3 "" "")) + (clobber (match_operand:DI 4 "register_operand" "")) + (use (match_operand:DI 5 "register_operand" ""))])] + "reload_completed" + [(parallel [(set (match_dup 0) + (unspec:BLK [(reg:DI XMM0_REG) + (reg:DI XMM1_REG) + (reg:DI XMM2_REG) + (reg:DI XMM3_REG) + (reg:DI XMM4_REG) + (reg:DI XMM5_REG) + (reg:DI XMM6_REG) + (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW)) + (use (match_dup 1)) + (use (match_dup 2)) + (use (match_dup 3)) + (use (match_dup 5))])] +{ + /* Movaps is 4 bytes, AVX and movsd is 5 bytes. */ + int size = 4 + (TARGET_AVX || crtl->stack_alignment_needed < 128); + + /* Compute address to jump to: + label - eax*size + nnamed_sse_arguments*size. */ + if (size == 5) + emit_insn (gen_rtx_SET (VOIDmode, operands[4], + gen_rtx_PLUS + (Pmode, + gen_rtx_MULT (Pmode, operands[1], + GEN_INT (4)), + operands[1]))); + else if (size == 4) + emit_insn (gen_rtx_SET (VOIDmode, operands[4], + gen_rtx_MULT (Pmode, operands[1], + GEN_INT (4)))); + else + gcc_unreachable (); + if (INTVAL (operands[2])) + emit_move_insn + (operands[1], + gen_rtx_CONST (DImode, + gen_rtx_PLUS (DImode, + operands[3], + GEN_INT (INTVAL (operands[2]) + * size)))); + else + emit_move_insn (operands[1], operands[3]); + emit_insn (gen_subdi3 (operands[1], operands[1], operands[4])); + operands[5] = GEN_INT (size); +}) + +(define_insn "sse_prologue_save_insn" + [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R") + (match_operand:DI 4 "const_int_operand" "n"))) + (unspec:BLK [(reg:DI XMM0_REG) + (reg:DI XMM1_REG) + (reg:DI XMM2_REG) + (reg:DI XMM3_REG) + (reg:DI XMM4_REG) + (reg:DI XMM5_REG) + (reg:DI XMM6_REG) + (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW)) (use (match_operand:DI 1 "register_operand" "r")) (use (match_operand:DI 2 "const_int_operand" "i")) - (use (label_ref:DI (match_operand 3 "" "X")))] + (use (label_ref:DI (match_operand 3 "" "X"))) + (use (match_operand:DI 5 "const_int_operand" "i"))] "TARGET_64BIT && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128" @@ -18480,7 +18463,10 @@ PUT_MODE (operands[4], TImode); if (GET_CODE (XEXP (operands[0], 0)) != PLUS) output_asm_insn ("rex", operands); - output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands); + if (crtl->stack_alignment_needed < 128) + output_asm_insn ("%vmovsd\t{%5, %4|%4, %5}", operands); + else + output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands); } (*targetm.asm_out.internal_label) (asm_out_file, "L", CODE_LABEL_NUMBER (operands[3])); @@ -18489,11 +18475,11 @@ [(set_attr "type" "other") (set_attr "length_immediate" "0") (set_attr "length_address" "0") + ;; 2 bytes for jump and opernds[4] bytes for each save. (set (attr "length") - (if_then_else - (eq (symbol_ref "TARGET_AVX") (const_int 0)) - (const_string "34") - (const_string "42"))) + (plus (const_int 2) + (mult (symbol_ref ("INTVAL (operands[5])")) + (symbol_ref ("X86_64_SSE_REGPARM_MAX - INTVAL (operands[2])"))))) (set_attr "memory" "store") (set_attr "modrm" "0") (set_attr "prefix" "maybe_vex") diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index dc6ca524e60..983ecf40372 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -537,6 +537,9 @@ static const struct attribute_spec ia64_attribute_table[] = #undef TARGET_TRAMPOLINE_INIT #define TARGET_TRAMPOLINE_INIT ia64_trampoline_init +#undef TARGET_INVALID_WITHIN_DOLOOP +#define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_const_rtx_null + #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE ia64_override_options_after_change diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index 53bbda2b1ed..c019aa48184 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -416,7 +416,7 @@ while (0) /* Branch registers. */ \ 0, 0, 0, 0, 0, 0, 0, 0, \ /*FP CCV UNAT PFS LC EC */ \ - 1, 1, 1, 1, 0, 1 \ + 1, 1, 1, 1, 1, 1 \ } /* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered @@ -451,7 +451,7 @@ while (0) /* Branch registers. */ \ 1, 0, 0, 0, 0, 0, 1, 1, \ /*FP CCV UNAT PFS LC EC */ \ - 1, 1, 1, 1, 0, 1 \ + 1, 1, 1, 1, 1, 1 \ } /* Like `CALL_USED_REGISTERS' but used to overcome a historical diff --git a/gcc/config/rs6000/x-aix b/gcc/config/rs6000/x-aix index 11ccb932d4b..d40690f2da6 100644 --- a/gcc/config/rs6000/x-aix +++ b/gcc/config/rs6000/x-aix @@ -2,5 +2,5 @@ build/genautomata : override LDFLAGS += -Wl,-bmaxdata:0x20000000 # jc1 requires more than 256MB of data -jc1 : override LDFLAGS += -Wl,-bmaxdata:0x20000000 +$(COMPILERS) : override LDFLAGS += -Wl,-bmaxdata:0x40000000 diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index c3820e58012..858aac9f084 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -9539,11 +9539,25 @@ s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg, replace the symbol itself with the PLT stub. */ if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location)) { - addr_location = gen_rtx_UNSPEC (Pmode, - gen_rtvec (1, addr_location), - UNSPEC_PLT); - addr_location = gen_rtx_CONST (Pmode, addr_location); - plt_call = true; + if (retaddr_reg != NULL_RTX) + { + addr_location = gen_rtx_UNSPEC (Pmode, + gen_rtvec (1, addr_location), + UNSPEC_PLT); + addr_location = gen_rtx_CONST (Pmode, addr_location); + plt_call = true; + } + else + /* For -fpic code the PLT entries might use r12 which is + call-saved. Therefore we cannot do a sibcall when + calling directly using a symbol ref. When reaching + this point we decided (in s390_function_ok_for_sibcall) + to do a sibcall for a function pointer but one of the + optimizers was able to get rid of the function pointer + by propagating the symbol ref into the call. This + optimization is illegal for S/390 so we turn the direct + call into a indirect call again. */ + addr_location = force_reg (Pmode, addr_location); } /* Unless we can use the bras(l) insn, force the diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 04b98c1eb22..a3084b91a0b 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -4410,6 +4410,7 @@ find_barrier (int num_mova, rtx mova, rtx from) int hi_limit; rtx orig = from; rtx last_got = NULL_RTX; + rtx last_symoff = NULL_RTX; /* For HImode: range is 510, add 4 because pc counts from address of second instruction after this one, subtract 2 for the jump instruction @@ -4551,6 +4552,16 @@ find_barrier (int num_mova, rtx mova, rtx from) { switch (untangle_mova (&num_mova, &mova, from)) { + case 1: + if (flag_pic) + { + rtx src = SET_SRC (PATTERN (from)); + if (GET_CODE (src) == CONST + && GET_CODE (XEXP (src, 0)) == UNSPEC + && XINT (XEXP (src, 0), 1) == UNSPEC_SYMOFF) + last_symoff = from; + } + break; case 0: return find_barrier (0, 0, mova); case 2: { @@ -4654,6 +4665,12 @@ find_barrier (int num_mova, rtx mova, rtx from) so we'll make one. */ rtx label = gen_label_rtx (); + /* Don't emit a constant table in the middle of insns for + casesi_worker_2. This is a bit overkill but is enough + because casesi_worker_2 wouldn't appear so frequently. */ + if (last_symoff) + from = last_symoff; + /* If we exceeded the range, then we must back up over the last instruction we looked at. Otherwise, we just need to undo the NEXT_INSN at the end of the loop. */ diff --git a/gcc/config/stormy16/stormy16-lib2-ucmpsi2.c b/gcc/config/stormy16/stormy16-lib2-ucmpsi2.c new file mode 100644 index 00000000000..da1a3e70753 --- /dev/null +++ b/gcc/config/stormy16/stormy16-lib2-ucmpsi2.c @@ -0,0 +1,2 @@ +#define XSTORMY16_UCMPSI2 +#include "stormy16-lib2.c" diff --git a/gcc/config/stormy16/stormy16-lib2.c b/gcc/config/stormy16/stormy16-lib2.c index 0c99cdd3e90..edf8635e192 100644 --- a/gcc/config/stormy16/stormy16-lib2.c +++ b/gcc/config/stormy16/stormy16-lib2.c @@ -4,7 +4,7 @@ files. On this glorious day maybe this code can be integrated into it too. */ -/* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc. +/* Copyright (C) 2005, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -309,3 +309,26 @@ __ffshi2 (UHWtype u) return 16 - __builtin_clz (u & - u); } #endif + +#ifdef XSTORMY16_UCMPSI2 +/* Performs an unsigned comparison of two 32-bit values: A and B. + If A is less than B, then 0 is returned. If A is greater than B, + then 2 is returned. Otherwise A and B are equal and 1 is returned. */ + +word_type +__ucmpsi2 (USItype a, USItype b) +{ + word_type hi_a = (a >> 16); + word_type hi_b = (b >> 16); + + if (hi_a == hi_b) + { + word_type low_a = (a & 0xffff); + word_type low_b = (b & 0xffff); + + return low_a < low_b ? 0 : (low_a > low_b ? 2 : 1); + } + + return hi_a < hi_b ? 0 : 2; +} +#endif diff --git a/gcc/config/stormy16/stormy16.c b/gcc/config/stormy16/stormy16.c index 03e716f096e..c3627ca6e96 100644 --- a/gcc/config/stormy16/stormy16.c +++ b/gcc/config/stormy16/stormy16.c @@ -1561,7 +1561,7 @@ xstormy16_asm_output_aligned_common (FILE *stream, int align, int global) { - rtx mem = DECL_RTL (decl); + rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl); rtx symbol; if (mem != NULL_RTX diff --git a/gcc/config/stormy16/stormy16.h b/gcc/config/stormy16/stormy16.h index fa97e8becdc..cf6acf586c2 100644 --- a/gcc/config/stormy16/stormy16.h +++ b/gcc/config/stormy16/stormy16.h @@ -1,29 +1,28 @@ /* Xstormy16 cpu description. Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, - 2008, 2009 Free Software Foundation, Inc. + 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Red Hat, Inc. -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. -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ -/* Driver configuration */ +/* Driver configuration. */ -/* Defined in svr4.h. */ -#undef ASM_SPEC +#undef ASM_SPEC #define ASM_SPEC "" /* For xstormy16: @@ -31,41 +30,33 @@ along with GCC; see the file COPYING3. If not see - If -T is specified, that linker script is used, and it should provide appropriate libraries. - If neither is specified, everything is built as for the sim, but no - I/O support is assumed. - -*/ -#undef LIB_SPEC + I/O support is assumed. */ +#undef LIB_SPEC #define LIB_SPEC "-( -lc %{msim:-lsim}%{!msim:%{!T*:-lnosys}} -)" -/* Defined in svr4.h. */ -#undef STARTFILE_SPEC +#undef STARTFILE_SPEC #define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s" -/* Defined in svr4.h. */ -#undef ENDFILE_SPEC +#undef ENDFILE_SPEC #define ENDFILE_SPEC "crtend.o%s crtn.o%s" -/* Defined in svr4.h for host compilers. */ -/* #define MD_EXEC_PREFIX "" */ - -/* Defined in svr4.h for host compilers. */ -/* #define MD_STARTFILE_PREFIX "" */ - -/* Run-time target specifications */ +/* Run-time target specifications. */ -#define TARGET_CPU_CPP_BUILTINS() do { \ - builtin_define_std ("xstormy16"); \ - builtin_assert ("machine=xstormy16"); \ - builtin_assert ("cpu=xstormy16"); \ -} while (0) +#define TARGET_CPU_CPP_BUILTINS() \ + do \ + { \ + builtin_define_std ("xstormy16"); \ + builtin_assert ("machine=xstormy16"); \ + builtin_assert ("cpu=xstormy16"); \ + } \ + while (0) #define TARGET_VERSION fprintf (stderr, " (xstormy16 cpu core)"); #define CAN_DEBUG_WITHOUT_FP - -/* Storage Layout */ +/* Storage Layout. */ #define BITS_BIG_ENDIAN 1 @@ -75,12 +66,14 @@ along with GCC; see the file COPYING3. If not see #define UNITS_PER_WORD 2 -#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \ -do { \ - if (GET_MODE_CLASS (MODE) == MODE_INT \ - && GET_MODE_SIZE (MODE) < 2) \ - (MODE) = HImode; \ -} while (0) +#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \ + do \ + { \ + if (GET_MODE_CLASS (MODE) == MODE_INT \ + && GET_MODE_SIZE (MODE) < 2) \ + (MODE) = HImode; \ + } \ + while (0) #define PARM_BOUNDARY 16 @@ -90,9 +83,6 @@ do { \ #define BIGGEST_ALIGNMENT 16 -/* Defined in svr4.h. */ -/* #define MAX_OFILE_ALIGNMENT */ - #define DATA_ALIGNMENT(TYPE, ALIGN) \ (TREE_CODE (TYPE) == ARRAY_TYPE \ && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ @@ -104,10 +94,9 @@ do { \ #define STRICT_ALIGNMENT 1 -/* Defined in svr4.h. */ #define PCC_BITFIELD_TYPE_MATTERS 1 -/* Layout of Source Language Data Types */ +/* Layout of Source Language Data Types. */ #define INT_TYPE_SIZE 16 @@ -125,27 +114,15 @@ do { \ #define DEFAULT_SIGNED_CHAR 0 -/* Defined in svr4.h. */ #define SIZE_TYPE "unsigned int" -/* Defined in svr4.h. */ #define PTRDIFF_TYPE "int" -/* Defined in svr4.h, to "long int". */ -/* #define WCHAR_TYPE "long int" */ - -/* Defined in svr4.h. */ -#undef WCHAR_TYPE_SIZE +#undef WCHAR_TYPE_SIZE #define WCHAR_TYPE_SIZE 32 -/* Define this macro if the type of Objective-C selectors should be `int'. - - If this macro is not defined, then selectors should have the type `struct - objc_selector *'. */ -/* #define OBJC_INT_SELECTORS */ - -/* Register Basics */ +/* Register Basics. */ #define FIRST_PSEUDO_REGISTER 19 @@ -156,12 +133,12 @@ do { \ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1 } -/* Order of allocation of registers */ +/* Order of allocation of registers. */ #define REG_ALLOC_ORDER { 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 10, 11, 12, 13, 14, 15, 16 } -/* How Values Fit in Registers */ +/* How Values Fit in Registers. */ #define HARD_REGNO_NREGS(REGNO, MODE) \ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) @@ -178,7 +155,7 @@ do { \ #define MODES_TIEABLE_P(MODE1, MODE2) ((MODE1) != BImode && (MODE2) != BImode) -/* Register Classes */ +/* Register Classes. */ enum reg_class { @@ -199,7 +176,7 @@ enum reg_class #define IRA_COVER_CLASSES \ { \ - GENERAL_REGS, LIM_REG_CLASSES \ + GENERAL_REGS, LIM_REG_CLASSES \ } #define REG_CLASS_NAMES \ @@ -251,7 +228,7 @@ enum reg_class 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P' 'Q', 'R', 'S', 'T', 'U' 'V', 'X' - 'g', 'i', 'm', 'n', 'o', 'p', 'r', 's' */ + 'g', 'i', 'm', 'n', 'o', 'p', 'r', 's'. */ #define REG_CLASS_FROM_LETTER(CHAR) \ ( (CHAR) == 'a' ? R0_REGS \ @@ -267,7 +244,6 @@ enum reg_class #define REGNO_OK_FOR_INDEX_P(NUM) REGNO_OK_FOR_BASE_P (NUM) -/* This declaration must be present. */ #define PREFERRED_RELOAD_CLASS(X, CLASS) \ xstormy16_preferred_reload_class (X, CLASS) @@ -279,40 +255,9 @@ enum reg_class #define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) \ xstormy16_secondary_reload_class (CLASS, MODE, X) -/* Normally the compiler avoids choosing registers that have been explicitly - mentioned in the rtl as spill registers (these registers are normally those - used to pass parameters and return values). However, some machines have so - few registers of certain classes that there would not be enough registers to - use as spill registers if this were done. - - Define `SMALL_REGISTER_CLASSES' to be an expression with a nonzero value on - these machines. When this macro has a nonzero value, the compiler allows - registers explicitly used in the rtl to be used as spill registers but - avoids extending the lifetime of these registers. - - It is always safe to define this macro with a nonzero value, but if you - unnecessarily define it, you will reduce the amount of optimizations that - can be performed in some cases. If you do not define this macro with a - nonzero value when it is required, the compiler will run out of spill - registers and print a fatal error message. For most machines, you should - not define this macro at all. */ -/* #define SMALL_REGISTER_CLASSES */ - -/* This declaration is required. */ #define CLASS_MAX_NREGS(CLASS, MODE) \ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) -/* If defined, a C expression for a class that contains registers which the - compiler must always access in a mode that is the same size as the mode in - which it loaded the register. - - For the example, loading 32-bit integer or floating-point objects into - floating-point registers on the Alpha extends them to 64-bits. Therefore - loading a 64-bit object and then storing it as a 32-bit object does not - store the low-order 32-bits, as would be the case for a normal register. - Therefore, `alpha.h' defines this macro as `FLOAT_REGS'. */ -/* #define CLASS_CANNOT_CHANGE_SIZE */ - #define CONST_OK_FOR_LETTER_P(VALUE, C) \ ( (C) == 'I' ? (VALUE) >= 0 && (VALUE) <= 3 \ : (C) == 'J' ? exact_log2 (VALUE) != -1 \ @@ -330,7 +275,7 @@ enum reg_class xstormy16_extra_constraint_p (VALUE, C) -/* Basic Stack Layout */ +/* Basic Stack Layout. */ /* We want to use post-increment instructions to push things on the stack, because we don't have any pre-increment ones. */ @@ -365,7 +310,7 @@ enum reg_class #define ARG_POINTER_REGNUM 18 -/* Eliminating the Frame Pointer and the Arg Pointer */ +/* Eliminating the Frame Pointer and the Arg Pointer. */ #define ELIMINABLE_REGS \ { \ @@ -379,16 +324,16 @@ enum reg_class (OFFSET) = xstormy16_initial_elimination_offset (FROM, TO) -/* Passing Function Arguments on the Stack */ +/* Passing Function Arguments on the Stack. */ #define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1) #define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0 -/* Function Arguments in Registers */ +/* Function Arguments in Registers. */ -#define NUM_ARGUMENT_REGISTERS 6 +#define NUM_ARGUMENT_REGISTERS 6 #define FIRST_ARGUMENT_REGISTER 2 #define XSTORMY16_WORD_SIZE(TYPE, MODE) \ @@ -414,7 +359,7 @@ enum reg_class && (REGNO) < FIRST_ARGUMENT_REGISTER + NUM_ARGUMENT_REGISTERS) -/* How Scalar Function Values are Returned */ +/* How Scalar Function Values are Returned. */ /* The number of the hard register that is used to return a scalar value from a function call. */ @@ -428,7 +373,7 @@ enum reg_class #define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == RETURN_VALUE_REGNUM) -/* Function Entry and Exit */ +/* Function Entry and Exit. */ #define EPILOGUE_USES(REGNO) \ xstormy16_epilogue_uses (REGNO) @@ -442,81 +387,13 @@ enum reg_class #define FUNCTION_PROFILER(FILE, LABELNO) xstormy16_function_profiler () -/* If the target has particular reasons why a function cannot be inlined, - it may define the TARGET_CANNOT_INLINE_P. This macro takes one argument, - the DECL describing the function. The function should NULL if the function - *can* be inlined. Otherwise it should return a pointer to a string containing - a message describing why the function could not be inlined. The message will - displayed if the '-Winline' command line switch has been given. If the message - contains a '%s' sequence, this will be replaced by the name of the function. */ -/* #define TARGET_CANNOT_INLINE_P(FN_DECL) xstormy16_cannot_inline_p (FN_DECL) */ - /* Trampolines for Nested Functions. */ #define TRAMPOLINE_SIZE 8 #define TRAMPOLINE_ALIGNMENT 16 -/* Define this macro to override the type used by the library routines to pick - up arguments of type `float'. (By default, they use a union of `float' and - `int'.) - - The obvious choice would be `float'--but that won't work with traditional C - compilers that expect all arguments declared as `float' to arrive as - `double'. To avoid this conversion, the library routines ask for the value - as some other type and then treat it as a `float'. */ -/* #define FLOAT_ARG_TYPE */ - -/* Define this macro to override the way library routines redesignate a `float' - argument as a `float' instead of the type it was passed as. The default is - an expression which takes the `float' field of the union. */ -/* #define FLOATIFY(PASSED_VALUE) */ - -/* Define this macro to override the type used by the library routines to - return values that ought to have type `float'. (By default, they use - `int'.) - - The obvious choice would be `float'--but that won't work with traditional C - compilers gratuitously convert values declared as `float' into `double'. */ -/* #define FLOAT_VALUE_TYPE */ - -/* Define this macro to override the way the value of a `float'-returning - library routine should be packaged in order to return it. These functions - are actually declared to return type `FLOAT_VALUE_TYPE' (normally `int'). - - These values can't be returned as type `float' because traditional C - compilers would gratuitously convert the value to a `double'. - - A local variable named `intify' is always available when the macro `INTIFY' - is used. It is a union of a `float' field named `f' and a field named `i' - whose type is `FLOAT_VALUE_TYPE' or `int'. - If you don't define this macro, the default definition works by copying the - value through that union. */ -/* #define INTIFY(FLOAT_VALUE) */ - -/* Define this macro as the name of the data type corresponding to `SImode' in - the system's own C compiler. - - You need not define this macro if that type is `long int', as it usually is. */ -/* #define nongcc_SI_type */ - -/* Define this macro as the name of the data type corresponding to the - word_mode in the system's own C compiler. - - You need not define this macro if that type is `long int', as it usually is. */ -/* #define nongcc_word_type */ - -/* Define these macros to supply explicit C statements to carry out various - arithmetic operations on types `float' and `double' in the library routines - in `libgcc1.c'. See that file for a full list of these macros and their - arguments. - - On most machines, you don't need to define any of these macros, because the - C compiler that comes with the system takes care of doing them. */ -/* #define perform_... */ - - -/* Addressing Modes */ +/* Addressing Modes. */ #define HAVE_POST_INCREMENT 1 @@ -536,16 +413,15 @@ enum reg_class /* On this chip, this is true if the address is valid with an offset of 0 but not of 6, because in that case it cannot be used as an address for DImode or DFmode, or if the address is a post-increment - or pre-decrement address. -*/ + or pre-decrement address. */ #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \ - if (xstormy16_mode_dependent_address_p (ADDR)) \ + if (xstormy16_mode_dependent_address_p (ADDR)) \ goto LABEL #define LEGITIMATE_CONSTANT_P(X) 1 -/* Describing Relative Costs of Operations */ +/* Describing Relative Costs of Operations. */ #define REGISTER_MOVE_COST(MODE, FROM, TO) 2 @@ -602,64 +478,31 @@ enum reg_class /* Output and Generation of Labels. */ #define SYMBOL_FLAG_XSTORMY16_BELOW100 (SYMBOL_FLAG_MACH_DEP << 0) -#define ASM_OUTPUT_SYMBOL_REF(STREAM, SYMBOL) \ - do { \ - const char *rn = XSTR (SYMBOL, 0); \ - if (SYMBOL_REF_FUNCTION_P (SYMBOL)) \ - ASM_OUTPUT_LABEL_REF ((STREAM), rn); \ - else \ - assemble_name (STREAM, rn); \ - } while (0) +#define ASM_OUTPUT_SYMBOL_REF(STREAM, SYMBOL) \ + do \ + { \ + const char *rn = XSTR (SYMBOL, 0); \ + \ + if (SYMBOL_REF_FUNCTION_P (SYMBOL)) \ + ASM_OUTPUT_LABEL_REF ((STREAM), rn); \ + else \ + assemble_name (STREAM, rn); \ + } \ + while (0) #define ASM_OUTPUT_LABEL_REF(STREAM, NAME) \ -do { \ - fputs ("@fptr(", STREAM); \ - assemble_name (STREAM, NAME); \ - fputc (')', STREAM); \ -} while (0) + do \ + { \ + fputs ("@fptr(", STREAM); \ + assemble_name (STREAM, NAME); \ + fputc (')', STREAM); \ + } \ + while (0) /* Globalizing directive for a label. */ #define GLOBAL_ASM_OP "\t.globl " -/* Macros Controlling Initialization Routines. */ - -/* When you are using special sections for - initialization and termination functions, this macro also controls how - `crtstuff.c' and `libgcc2.c' arrange to run the initialization functions. - - Defined in svr4.h. */ -/* #define INIT_SECTION_ASM_OP */ - -/* Define this macro as a C statement to output on the stream STREAM the - assembler code to arrange to call the function named NAME at initialization - time. - - Assume that NAME is the name of a C function generated automatically by the - compiler. This function takes no arguments. Use the function - `assemble_name' to output the name NAME; this performs any system-specific - syntactic transformations such as adding an underscore. - - If you don't define this macro, nothing special is output to arrange to call - the function. This is correct when the function will be called in some - other manner--for example, by means of the `collect2' program, which looks - through the symbol table to find these functions by their names. - - Defined in svr4.h. */ -/* #define ASM_OUTPUT_CONSTRUCTOR(STREAM, NAME) */ - -/* This is like `ASM_OUTPUT_CONSTRUCTOR' but used for termination functions - rather than initialization functions. - - Defined in svr4.h. */ -/* #define ASM_OUTPUT_DESTRUCTOR(STREAM, NAME) */ - -/* Define this macro if the system uses ELF format object files. - - Defined in svr4.h. */ -/* #define OBJECT_FORMAT_ELF */ - - /* Output of Assembler Instructions. */ #define REGISTER_NAMES \ @@ -705,9 +548,7 @@ do { \ #define DWARF2_UNWIND_INFO 0 #define DWARF_CIE_DATA_ALIGNMENT 1 -/* Don't use __builtin_setjmp for unwinding, since it's tricky to get - at the high 16 bits of an address. */ -#define DONT_USE_BUILTIN_SETJMP +#undef DONT_USE_BUILTIN_SETJMP #define JMP_BUF_SIZE 8 /* Assembler Commands for Alignment. */ @@ -719,7 +560,7 @@ do { \ /* Macros Affecting all Debug Formats. */ /* Defined in svr4.h. */ -#undef PREFERRED_DEBUGGING_TYPE +#undef PREFERRED_DEBUGGING_TYPE #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG @@ -757,22 +598,4 @@ do { \ #define NO_IMPLICIT_EXTERN_C -/* Defined in svr4.h. */ #define HANDLE_SYSV_PRAGMA 1 - -/* Define this if the target system supports the function `atexit' from the - ANSI C standard. If this is not defined, and `INIT_SECTION_ASM_OP' is not - defined, a default `exit' function will be provided to support C++. - - Defined by svr4.h */ -/* #define HAVE_ATEXIT */ - -/* A C statement which is executed by the Haifa scheduler after it has scheduled - an insn from the ready list. FILE is either a null pointer, or a stdio stream - to write any debug output to. VERBOSE is the verbose level provided by - -fsched-verbose-. INSN is the instruction that was scheduled. MORE is the - number of instructions that can be issued in the current cycle. This macro - is responsible for updating the value of MORE (typically by (MORE)--). */ -/* #define MD_SCHED_VARIABLE_ISSUE (FILE, VERBOSE, INSN, MORE) */ - -/* End of xstormy16.h */ diff --git a/gcc/config/stormy16/stormy16.md b/gcc/config/stormy16/stormy16.md index 9c86d43e627..d8113420aba 100644 --- a/gcc/config/stormy16/stormy16.md +++ b/gcc/config/stormy16/stormy16.md @@ -759,21 +759,6 @@ DONE; }) -(define_expand "cbranchsi4" - [(set (pc) - (if_then_else (match_operator 0 "comparison_operator" - [(match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonmemory_operand" "")]) - (label_ref (match_operand 3 "" "")) - (pc))) - (clobber (reg:BI CARRY_REG))] - "" - { - xstormy16_emit_cbranch (GET_CODE (operands[0]), operands[1], operands[2], - operands[3]); - DONE; -}) - (define_insn "cbranchhi" [(set (pc) (if_then_else (match_operator:HI 1 "comparison_operator" @@ -827,24 +812,6 @@ [(set_attr "branch_class" "bcc8p2") (set_attr "psw_operand" "clobber")]) -(define_insn_and_split "*ineqbranchsi" - [(set (pc) - (if_then_else (match_operator:SI 1 "xstormy16_ineqsi_operator" - [(match_operand:SI 2 "register_operand" - "r") - (match_operand:SI 3 "nonmemory_operand" - "ri")]) - (label_ref (match_operand 0 "" "")) - (pc))) - (clobber (match_operand:SI 4 "register_operand" "=2")) - (clobber (reg:BI CARRY_REG))] - "" - "#" - "reload_completed" - [(pc)] - { xstormy16_split_cbranch (SImode, operands[0], operands[1], operands[2]); DONE; } - [(set_attr "length" "8")]) - (define_insn "*ineqbranch_1" [(set (pc) (if_then_else (match_operator:HI 4 "xstormy16_ineqsi_operator" diff --git a/gcc/config/stormy16/t-stormy16 b/gcc/config/stormy16/t-stormy16 index 8959e64ab5e..7ca26356cb7 100644 --- a/gcc/config/stormy16/t-stormy16 +++ b/gcc/config/stormy16/t-stormy16 @@ -1,6 +1,6 @@ # -*- makefile -*- # -# Copyright (C) 2001, 2004 Free Software Foundation, Inc. +# Copyright (C) 2001, 2004, 2010 Free Software Foundation, Inc. # # This file is part of GCC. # @@ -32,7 +32,8 @@ LIB2FUNCS_EXTRA = \ $(srcdir)/config/stormy16/stormy16-lib2-parityhi2.c \ $(srcdir)/config/stormy16/stormy16-lib2-clzhi2.c \ $(srcdir)/config/stormy16/stormy16-lib2-ctzhi2.c \ - $(srcdir)/config/stormy16/stormy16-lib2-ffshi2.c + $(srcdir)/config/stormy16/stormy16-lib2-ffshi2.c \ + $(srcdir)/config/stormy16/stormy16-lib2-ucmpsi2.c # Floating point emulation libraries. FPBIT = fp-bit.c diff --git a/gcc/configure b/gcc/configure index de9cc72db7f..53f5eb8e806 100755 --- a/gcc/configure +++ b/gcc/configure @@ -8458,12 +8458,12 @@ else int main() { return elf_getshstrndx (NULL, 0) == 0; -}, -$as_echo "#define HAVE_ELF_GETSHSTRNDX_GABI 1" >>confdefs.h - +} _ACEOF if ac_fn_c_try_run "$LINENO"; then : +$as_echo "#define HAVE_ELF_GETSHSTRNDX_GABI 1" >>confdefs.h + fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext diff --git a/gcc/configure.ac b/gcc/configure.ac index d256b62b104..2f571e6482d 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -1034,8 +1034,8 @@ AC_CHECK_FUNCS(elf_getshdrstrndx,, int main() { return elf_getshstrndx (NULL, 0) == 0; -}]]), AC_DEFINE(HAVE_ELF_GETSHSTRNDX_GABI, 1, - [Define if elf_getshstrndx has gABI conformant return values.])])])] +}]])], AC_DEFINE(HAVE_ELF_GETSHSTRNDX_GABI, 1, + [Define if elf_getshstrndx has gABI conformant return values.]))])] ) LIBS="$save_LIBS" CPPFLAGS="$save_CPPFLAGS" diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6a11a946300..6dec7c38cad 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,41 @@ +2010-04-20 Jason Merrill + + PR c++/9335 + * init.c (constant_value_1): Treat error_mark_node as a constant + if DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P is set. + * cvt.c (ocp_convert): Handle getting error_mark_node from + integral_constant_value. + * decl.c (compute_array_index_type): Likewise. + +2010-04-20 Dodji Seketeli + + PR c++/43800 + PR c++/43704 + * typeck.c (incompatible_dependent_types_p): If one of the + compared types if not a typedef then honour their main variant + equivalence. + +2010-04-20 Jakub Jelinek + + * cp-tree.h (TYPE_REF_IS_RVALUE): Remove. + +2010-04-19 Dodji Seketeli + + PR c++/43704 + * typeck.c (structural_comptypes): Test dependent typedefs + incompatibility before testing for their main variant based + equivalence. + +2010-04-19 Jakub Jelinek + + * cp-tree.h (SCOPED_ENUM_P, UNSCOPED_ENUM_P, SET_SCOPED_ENUM_P): Use + ENUM_IS_SCOPED bit instead of TYPE_LANG_FLAG_5. + +2010-04-18 Eric Botcazou + + * decl.c (cxx_init_decl_processing): Remove second argument in call to + build_common_tree_nodes. + 2010-04-14 Jason Merrill PR c++/36625 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8f74a29e072..5afa0ea66cd 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -74,7 +74,6 @@ framework extensions, you must include this file before toplev.h, not after. BASELINK_QUALIFIED_P (in BASELINK) TARGET_EXPR_IMPLICIT_P (in TARGET_EXPR) TEMPLATE_PARM_PARAMETER_PACK (in TEMPLATE_PARM_INDEX) - TYPE_REF_IS_RVALUE (in REFERENCE_TYPE) ATTR_IS_DEPENDENT (in the TREE_LIST for an attribute) CONSTRUCTOR_IS_DIRECT_INIT (in CONSTRUCTOR) LAMBDA_EXPR_CAPTURES_THIS_P (in LAMBDA_EXPR) @@ -121,7 +120,6 @@ framework extensions, you must include this file before toplev.h, not after. 3: TYPE_FOR_JAVA. 4: TYPE_HAS_NONTRIVIAL_DESTRUCTOR 5: CLASS_TYPE_P (in RECORD_TYPE and UNION_TYPE) - SCOPED_ENUM_P (in ENUMERAL_TYPE) 6: TYPE_DEPENDENT_P_VALID Usage of DECL_LANG_FLAG_?: @@ -3036,17 +3034,17 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) - The underlying type of the enum is well-defined. */ #define SCOPED_ENUM_P(TYPE) \ - (TREE_CODE (TYPE) == ENUMERAL_TYPE && TYPE_LANG_FLAG_5 (TYPE)) + (TREE_CODE (TYPE) == ENUMERAL_TYPE && ENUM_IS_SCOPED (TYPE)) /* Determine whether this is an unscoped enumeration type. */ #define UNSCOPED_ENUM_P(TYPE) \ - (TREE_CODE (TYPE) == ENUMERAL_TYPE && !TYPE_LANG_FLAG_5 (TYPE)) + (TREE_CODE (TYPE) == ENUMERAL_TYPE && !ENUM_IS_SCOPED (TYPE)) /* Set the flag indicating whether an ENUMERAL_TYPE is a C++0x scoped enumeration type (1) or a normal (unscoped) enumeration type (0). */ #define SET_SCOPED_ENUM_P(TYPE, VAL) \ - (TYPE_LANG_FLAG_5 (ENUMERAL_TYPE_CHECK (TYPE)) = (VAL)) + (ENUM_IS_SCOPED (TYPE) = (VAL)) /* Returns the underlying type of the given enumeration type. The underlying type is determined in different ways, depending on the @@ -3201,10 +3199,6 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define TYPE_REF_OBJ_P(NODE) \ (TREE_CODE (NODE) == REFERENCE_TYPE && TYPE_OBJ_P (TREE_TYPE (NODE))) -/* True if reference type NODE is an rvalue reference */ -#define TYPE_REF_IS_RVALUE(NODE) \ - TREE_LANG_FLAG_0 (REFERENCE_TYPE_CHECK (NODE)) - /* Returns true if NODE is a pointer to an object, or a pointer to void. Keep these checks in ascending tree code order. */ #define TYPE_PTROBV_P(NODE) \ diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 6fcb1f0a19a..1f87c5f8c26 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -610,6 +610,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags) } e = integral_constant_value (e); + if (error_operand_p (e)) + return error_mark_node; if (MAYBE_CLASS_TYPE_P (type) && (convtype & CONV_FORCE_TEMP)) /* We need a new temporary; don't take this shortcut. */; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 26383c8f458..3a42ce9c900 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3391,7 +3391,7 @@ cxx_init_decl_processing (void) tree void_ftype; tree void_ftype_ptr; - build_common_tree_nodes (flag_signed_char, false); + build_common_tree_nodes (flag_signed_char); /* Create all the identifiers we need. */ initialize_predefined_identifiers (); @@ -7352,6 +7352,8 @@ compute_array_index_type (tree name, tree size) /* It might be a const variable or enumeration constant. */ size = integral_constant_value (size); + if (error_operand_p (size)) + return error_mark_node; /* Normally, the array-bound will be a constant. */ if (TREE_CODE (size) == INTEGER_CST) diff --git a/gcc/cp/init.c b/gcc/cp/init.c index c1f1cbf4a38..e1dee1d10dc 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1658,7 +1658,14 @@ constant_value_1 (tree decl, bool integral_p) init = DECL_INITIAL (decl); } if (init == error_mark_node) - return decl; + { + if (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)) + /* Treat the error as a constant to avoid cascading errors on + excessively recursive template instantiation (c++/9335). */ + return init; + else + return decl; + } /* Initializers in templates are generally expanded during instantiation, so before that for const int i(2) INIT is a TREE_LIST with the actual initializer as diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 9947384976d..59c72149995 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1155,6 +1155,7 @@ static bool incompatible_dependent_types_p (tree t1, tree t2) { tree tparms1 = NULL_TREE, tparms2 = NULL_TREE; + bool t1_typedef_variant_p, t2_typedef_variant_p; if (!uses_template_parms (t1) || !uses_template_parms (t2)) return false; @@ -1167,10 +1168,22 @@ incompatible_dependent_types_p (tree t1, tree t2) return true; } + t1_typedef_variant_p = typedef_variant_p (t1); + t2_typedef_variant_p = typedef_variant_p (t2); + /* Either T1 or T2 must be a typedef. */ - if (!typedef_variant_p (t1) && !typedef_variant_p (t2)) + if (!t1_typedef_variant_p && !t2_typedef_variant_p) return false; + if (!t1_typedef_variant_p || !t2_typedef_variant_p) + /* Either T1 or T2 is not a typedef so we cannot compare the + the template parms of the typedefs of T1 and T2. + At this point, if the main variant type of T1 and T2 are equal + it means the two types can't be incompatible, from the perspective + of this function. */ + if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) + return false; + /* So if we reach this point, it means either T1 or T2 is a typedef variant. Let's compare their template parameters. */ @@ -1236,6 +1249,12 @@ structural_comptypes (tree t1, tree t2, int strict) if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2)) return false; + /* If T1 and T2 are dependent typedefs then check upfront that + the template parameters of their typedef DECLs match before + going down checking their subtypes. */ + if (incompatible_dependent_types_p (t1, t2)) + return false; + /* Allow for two different type nodes which have essentially the same definition. Note that we already checked for equality of the type qualifiers (just above). */ @@ -1244,11 +1263,6 @@ structural_comptypes (tree t1, tree t2, int strict) && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) return true; - /* If T1 and T2 are dependent typedefs then check upfront that - the template parameters of their typedef DECLs match before - going down checking their subtypes. */ - if (incompatible_dependent_types_p (t1, t2)) - return false; /* Compare the types. Break out if they could be the same. */ switch (TREE_CODE (t1)) diff --git a/gcc/df-problems.c b/gcc/df-problems.c index e0ec16778f0..fb899096e49 100644 --- a/gcc/df-problems.c +++ b/gcc/df-problems.c @@ -3745,9 +3745,22 @@ df_simulate_find_defs (rtx insn, bitmap defs) for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) { df_ref def = *def_rec; - /* If the def is to only part of the reg, it does - not kill the other defs that reach here. */ - if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) + bitmap_set_bit (defs, DF_REF_REGNO (def)); + } +} + +/* Find the set of real DEFs, which are not clobbers, for INSN. */ + +void +df_simulate_find_noclobber_defs (rtx insn, bitmap defs) +{ + df_ref *def_rec; + unsigned int uid = INSN_UID (insn); + + for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) + { + df_ref def = *def_rec; + if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))) bitmap_set_bit (defs, DF_REF_REGNO (def)); } } @@ -3939,7 +3952,7 @@ df_simulate_one_insn_forwards (basic_block bb, rtx insn, bitmap live) while here the scan is performed forwards! So, first assume that the def is live, and if this is not true REG_UNUSED notes will rectify the situation. */ - df_simulate_find_defs (insn, live); + df_simulate_find_noclobber_defs (insn, live); /* Clear all of the registers that go dead. */ for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) diff --git a/gcc/df.h b/gcc/df.h index 194cbcf2639..c73f00fe6ce 100644 --- a/gcc/df.h +++ b/gcc/df.h @@ -978,6 +978,7 @@ extern void df_note_add_problem (void); extern void df_md_add_problem (void); extern void df_md_simulate_artificial_defs_at_top (basic_block, bitmap); extern void df_md_simulate_one_insn (basic_block, rtx, bitmap); +extern void df_simulate_find_noclobber_defs (rtx, bitmap); extern void df_simulate_find_defs (rtx, bitmap); extern void df_simulate_defs (rtx, bitmap); extern void df_simulate_uses (rtx, bitmap); diff --git a/gcc/dojump.c b/gcc/dojump.c index c2ee427d7ac..d4ce6cfc458 100644 --- a/gcc/dojump.c +++ b/gcc/dojump.c @@ -163,7 +163,8 @@ prefer_and_bit_test (enum machine_mode mode, int bitnum) /* Fill in the integers. */ XEXP (and_test, 1) - = immed_double_const ((unsigned HOST_WIDE_INT) 1 << bitnum, 0, mode); + = immed_double_int_const (double_int_setbit (double_int_zero, bitnum), + mode); XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum); return (rtx_cost (and_test, IF_THEN_ELSE, optimize_insn_for_speed_p ()) diff --git a/gcc/double-int.c b/gcc/double-int.c index 2af97ba0c62..8e4a3f5e596 100644 --- a/gcc/double-int.c +++ b/gcc/double-int.c @@ -1013,6 +1013,18 @@ double_int_umod (double_int a, double_int b, unsigned code) return double_int_mod (a, b, true, code); } +/* Set BITPOS bit in A. */ +double_int +double_int_setbit (double_int a, unsigned bitpos) +{ + if (bitpos < HOST_BITS_PER_WIDE_INT) + a.low |= (unsigned HOST_WIDE_INT) 1 << bitpos; + else + a.high |= (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT); + + return a; +} + /* Shift A left by COUNT places keeping only PREC bits of result. Shift right if COUNT is negative. ARITH true specifies arithmetic shifting; otherwise use logical shift. */ diff --git a/gcc/double-int.h b/gcc/double-int.h index 682034859b9..47991ca41b8 100644 --- a/gcc/double-int.h +++ b/gcc/double-int.h @@ -130,6 +130,7 @@ double_int double_int_umod (double_int, double_int, unsigned); double_int double_int_divmod (double_int, double_int, bool, unsigned, double_int *); double_int double_int_sdivmod (double_int, double_int, unsigned, double_int *); double_int double_int_udivmod (double_int, double_int, unsigned, double_int *); +double_int double_int_setbit (double_int, unsigned); /* Logical operations. */ static inline double_int diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 5a9a3b89dc0..e7e2e8f9a72 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -3771,6 +3771,11 @@ output_call_frame_info (int for_eh) } dw2_asm_output_nstring (augmentation, -1, "CIE Augmentation"); + if (dw_cie_version >= 4) + { + dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "CIE Address Size"); + dw2_asm_output_data (1, 0, "CIE Segment Size"); + } dw2_asm_output_data_uleb128 (1, "CIE Code Alignment Factor"); dw2_asm_output_data_sleb128 (DWARF_CIE_DATA_ALIGNMENT, "CIE Data Alignment Factor"); @@ -5710,8 +5715,7 @@ static GTY(()) comdat_type_node *comdat_type_list; static GTY(()) limbo_die_node *limbo_die_list; /* A list of DIEs for which we may have to generate - DW_AT_MIPS_linkage_name once their DECL_ASSEMBLER_NAMEs are - set. */ + DW_AT_{,MIPS_}linkage_name once their DECL_ASSEMBLER_NAMEs are set. */ static GTY(()) limbo_die_node *deferred_asm_name; /* Filenames referenced by this compilation unit. */ @@ -5744,8 +5748,12 @@ struct GTY ((chain_next ("%h.next"))) var_loc_node { struct GTY (()) var_loc_list_def { struct var_loc_node * GTY (()) first; - /* Do not mark the last element of the chained list because - it is marked through the chain. */ + /* Pointer to the last but one or last element of the + chained list. If the list is empty, both first and + last are NULL, if the list contains just one node + or the last node certainly is not redundant, it points + to the last node, otherwise points to the last but one. + Do not mark it for GC because it is marked through the chain. */ struct var_loc_node * GTY ((skip ("%h"))) last; /* DECL_UID of the variable decl. */ @@ -5987,7 +5995,7 @@ static hashval_t decl_loc_table_hash (const void *); static int decl_loc_table_eq (const void *, const void *); static var_loc_list *lookup_decl_loc (const_tree); static void equate_decl_number_to_die (tree, dw_die_ref); -static struct var_loc_node *add_var_loc_to_decl (tree, rtx); +static struct var_loc_node *add_var_loc_to_decl (tree, rtx, const char *); static void print_spaces (FILE *); static void print_die (dw_die_ref, FILE *); static void print_dwarf_line_table (FILE *); @@ -6273,6 +6281,12 @@ static void gen_remaining_tmpl_value_param_die_attribute (void); #define DEBUG_MACINFO_SECTION_LABEL "Ldebug_macinfo" #endif +/* Mangled name attribute to use. This used to be a vendor extension + until DWARF 4 standardized it. */ +#define AT_linkage_name \ + (dwarf_version >= 4 ? DW_AT_linkage_name : DW_AT_MIPS_linkage_name) + + /* Definitions of defaults for formats and names of various special (artificial) labels which may be generated within this file (when the -g options is used and DWARF2_DEBUGGING_INFO is in effect. @@ -7745,7 +7759,7 @@ equate_decl_number_to_die (tree decl, dw_die_ref decl_die) /* Add a variable location node to the linked list for DECL. */ static struct var_loc_node * -add_var_loc_to_decl (tree decl, rtx loc_note) +add_var_loc_to_decl (tree decl, rtx loc_note, const char *label) { unsigned int decl_id = DECL_UID (decl); var_loc_list *temp; @@ -7764,23 +7778,62 @@ add_var_loc_to_decl (tree decl, rtx loc_note) if (temp->last) { + struct var_loc_node *last = temp->last, *unused = NULL; + if (last->next) + { + last = last->next; + gcc_assert (last->next == NULL); + } + /* TEMP->LAST here is either pointer to the last but one or + last element in the chained list, LAST is pointer to the + last element. */ + /* If the last note doesn't cover any instructions, remove it. */ + if (label && strcmp (last->label, label) == 0) + { + if (temp->last != last) + { + temp->last->next = NULL; + unused = last; + last = temp->last; + gcc_assert (strcmp (last->label, label) != 0); + } + else + { + gcc_assert (temp->first == temp->last); + memset (temp->last, '\0', sizeof (*temp->last)); + return temp->last; + } + } /* If the current location is the same as the end of the list, and either both or neither of the locations is uninitialized, we have nothing to do. */ - if ((!rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->last->var_loc_note), + if ((!rtx_equal_p (NOTE_VAR_LOCATION_LOC (last->var_loc_note), NOTE_VAR_LOCATION_LOC (loc_note))) - || ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note) + || ((NOTE_VAR_LOCATION_STATUS (last->var_loc_note) != NOTE_VAR_LOCATION_STATUS (loc_note)) - && ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note) + && ((NOTE_VAR_LOCATION_STATUS (last->var_loc_note) == VAR_INIT_STATUS_UNINITIALIZED) || (NOTE_VAR_LOCATION_STATUS (loc_note) == VAR_INIT_STATUS_UNINITIALIZED)))) { - /* Add LOC to the end of list and update LAST. */ - loc = GGC_CNEW (struct var_loc_node); - temp->last->next = loc; - temp->last = loc; + /* Add LOC to the end of list and update LAST. If the last + element of the list has been removed above, reuse its + memory for the new node, otherwise allocate a new one. */ + if (unused) + { + loc = unused; + memset (loc, '\0', sizeof (*loc)); + } + else + loc = GGC_CNEW (struct var_loc_node); + last->next = loc; + /* Ensure TEMP->LAST will point either to the new last but one + element of the chain, or to the last element in it. */ + if (last != temp->last) + temp->last = last; } + else if (unused) + ggc_free (unused); } else { @@ -8245,6 +8298,7 @@ attr_checksum_ordered (enum dwarf_tag tag, dw_attr_ref at, if ((at->dw_attr == DW_AT_type && (tag == DW_TAG_pointer_type || tag == DW_TAG_reference_type + || tag == DW_TAG_rvalue_reference_type || tag == DW_TAG_ptr_to_member_type)) || (at->dw_attr == DW_AT_friend && tag == DW_TAG_friend)) @@ -8959,6 +9013,7 @@ is_type_die (dw_die_ref die) case DW_TAG_enumeration_type: case DW_TAG_pointer_type: case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: case DW_TAG_string_type: case DW_TAG_structure_type: case DW_TAG_subroutine_type: @@ -8996,6 +9051,7 @@ is_comdat_die (dw_die_ref c) if (c->die_tag == DW_TAG_pointer_type || c->die_tag == DW_TAG_reference_type + || c->die_tag == DW_TAG_rvalue_reference_type || c->die_tag == DW_TAG_const_type || c->die_tag == DW_TAG_volatile_type) { @@ -9244,6 +9300,7 @@ should_move_die_to_comdat (dw_die_ref die) case DW_TAG_interface_type: case DW_TAG_pointer_type: case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: case DW_TAG_string_type: case DW_TAG_subroutine_type: case DW_TAG_ptr_to_member_type: @@ -9327,6 +9384,7 @@ clone_as_declaration (dw_die_ref die) case DW_AT_name: case DW_AT_type: case DW_AT_virtuality: + case DW_AT_linkage_name: case DW_AT_MIPS_linkage_name: add_dwarf_attr (clone, a); break; @@ -12192,7 +12250,11 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type, } else if (code == REFERENCE_TYPE) { - mod_type_die = new_die (DW_TAG_reference_type, comp_unit_die, type); + if (TYPE_REF_IS_RVALUE (type) && dwarf_version >= 4) + mod_type_die = new_die (DW_TAG_rvalue_reference_type, comp_unit_die, + type); + else + mod_type_die = new_die (DW_TAG_reference_type, comp_unit_die, type); add_AT_unsigned (mod_type_die, DW_AT_byte_size, simple_type_size_in_bits (type) / BITS_PER_UNIT); item_type = TREE_TYPE (type); @@ -15906,7 +15968,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, loc_list = lookup_decl_loc (decl); if (loc_list && loc_list->first - && loc_list->first == loc_list->last + && loc_list->first->next == NULL && NOTE_VAR_LOCATION (loc_list->first->var_loc_note) && NOTE_VAR_LOCATION_LOC (loc_list->first->var_loc_note)) { @@ -16335,6 +16397,7 @@ lower_bound_default (void) return 1; case DW_LANG_UPC: case DW_LANG_D: + case DW_LANG_Python: return dwarf_version >= 4 ? 0 : -1; case DW_LANG_Ada95: case DW_LANG_Ada83: @@ -16745,8 +16808,7 @@ add_name_and_src_coords_attributes (dw_die_ref die, tree decl) if ((TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL) && TREE_PUBLIC (decl) && !DECL_ABSTRACT (decl) - && !(TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl)) - && !is_fortran ()) + && !(TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl))) { /* Defer until we have an assembler name set. */ if (!DECL_ASSEMBLER_NAME_SET_P (decl)) @@ -16760,7 +16822,7 @@ add_name_and_src_coords_attributes (dw_die_ref die, tree decl) deferred_asm_name = asm_name; } else if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl)) - add_AT_string (die, DW_AT_MIPS_linkage_name, + add_AT_string (die, AT_linkage_name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); } } @@ -17385,6 +17447,9 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die) scope_die_for (type, context_die), type); equate_type_number_to_die (type, type_die); add_name_attribute (type_die, type_tag (type)); + if ((dwarf_version >= 4 || !dwarf_strict) + && ENUM_IS_SCOPED (type)) + add_AT_flag (type_die, DW_AT_enum_class, 1); } else if (! TYPE_SIZE (type)) return type_die; @@ -18630,8 +18695,12 @@ gen_pointer_type_die (tree type, dw_die_ref context_die) static void gen_reference_type_die (tree type, dw_die_ref context_die) { - dw_die_ref ref_die - = new_die (DW_TAG_reference_type, scope_die_for (type, context_die), type); + dw_die_ref ref_die, scope_die = scope_die_for (type, context_die); + + if (TYPE_REF_IS_RVALUE (type) && dwarf_version >= 4) + ref_die = new_die (DW_TAG_rvalue_reference_type, scope_die, type); + else + ref_die = new_die (DW_TAG_reference_type, scope_die, type); equate_type_number_to_die (type, ref_die); add_type_attribute (ref_die, TREE_TYPE (type), 0, 0, context_die); @@ -20357,22 +20426,33 @@ dwarf2out_var_location (rtx loc_note) if (next_real == NULL_RTX) return; + /* If there were any real insns between note we processed last time + and this note (or if it is the first note), clear + last_{,postcall_}label so that they are not reused this time. */ + if (last_var_location_insn == NULL_RTX + || last_var_location_insn != next_real + || last_in_cold_section_p != in_cold_section_p) + { + last_label = NULL; + last_postcall_label = NULL; + } + decl = NOTE_VAR_LOCATION_DECL (loc_note); - newloc = add_var_loc_to_decl (decl, loc_note); + newloc = add_var_loc_to_decl (decl, loc_note, + NOTE_DURING_CALL_P (loc_note) + ? last_postcall_label : last_label); if (newloc == NULL) return; /* If there were no real insns between note we processed last time - and this note, use the label we emitted last time. */ - if (last_var_location_insn == NULL_RTX - || last_var_location_insn != next_real - || last_in_cold_section_p != in_cold_section_p) + and this note, use the label we emitted last time. Otherwise + create a new label and emit it. */ + if (last_label == NULL) { ASM_GENERATE_INTERNAL_LABEL (loclabel, "LVL", loclabel_num); ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LVL", loclabel_num); loclabel_num++; last_label = ggc_strdup (loclabel); - last_postcall_label = NULL; } newloc->var_loc_note = loc_note; newloc->next = NULL; @@ -20903,6 +20983,7 @@ prune_unused_types_walk (dw_die_ref die) case DW_TAG_packed_type: case DW_TAG_pointer_type: case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: case DW_TAG_volatile_type: case DW_TAG_typedef: case DW_TAG_array_type: @@ -21122,7 +21203,7 @@ htab_ct_eq (const void *of1, const void *of2) DWARF_TYPE_SIGNATURE_SIZE)); } -/* Move a DW_AT_MIPS_linkage_name attribute just added to dw_die_ref +/* Move a DW_AT_{,MIPS_}linkage_name attribute just added to dw_die_ref to the location it would have been added, should we know its DECL_ASSEMBLER_NAME when we added other attributes. This will probably improve compactness of debug info, removing equivalent @@ -21135,7 +21216,7 @@ move_linkage_attr (dw_die_ref die) unsigned ix = VEC_length (dw_attr_node, die->die_attr); dw_attr_node linkage = *VEC_index (dw_attr_node, die->die_attr, ix - 1); - gcc_assert (linkage.dw_attr == DW_AT_MIPS_linkage_name); + gcc_assert (linkage.dw_attr == AT_linkage_name); while (--ix > 0) { @@ -21369,7 +21450,7 @@ dwarf2out_finish (const char *filename) tree decl = node->created_for; if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl)) { - add_AT_string (node->die, DW_AT_MIPS_linkage_name, + add_AT_string (node->die, AT_linkage_name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); move_linkage_attr (node->die); } diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index ab46195fcb9..d4ba5d706ed 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -1,6 +1,7 @@ /* Emit RTL for the GCC expander. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, + 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -517,6 +518,15 @@ const_fixed_from_fixed_value (FIXED_VALUE_TYPE value, enum machine_mode mode) return lookup_const_fixed (fixed); } +/* Return a CONST_DOUBLE or CONST_INT for a value specified as + a double_int. */ + +rtx +immed_double_int_const (double_int i, enum machine_mode mode) +{ + return immed_double_const (i.low, i.high, mode); +} + /* Return a CONST_DOUBLE or CONST_INT for a value specified as a pair of ints: I0 is the low-order word and I1 is the high-order word. Do not use this routine for non-integer modes; convert to diff --git a/gcc/expmed.c b/gcc/expmed.c index 44de4a6512e..07b1dc6d70d 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -1847,7 +1847,7 @@ mask_rtx (enum machine_mode mode, int bitpos, int bitsize, int complement) if (complement) mask = double_int_not (mask); - return immed_double_const (mask.low, mask.high, mode); + return immed_double_int_const (mask, mode); } /* Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value @@ -1861,7 +1861,7 @@ lshift_value (enum machine_mode mode, rtx value, int bitpos, int bitsize) val = double_int_zext (uhwi_to_double_int (INTVAL (value)), bitsize); val = double_int_lshift (val, bitpos, HOST_BITS_PER_DOUBLE_INT, false); - return immed_double_const (val.low, val.high, mode); + return immed_double_int_const (val, mode); } /* Extract a bit field that is split across two words @@ -3217,6 +3217,55 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, gcc_assert (op0); return op0; } + +/* Perform a widening multiplication and return an rtx for the result. + MODE is mode of value; OP0 and OP1 are what to multiply (rtx's); + TARGET is a suggestion for where to store the result (an rtx). + THIS_OPTAB is the optab we should use, it must be either umul_widen_optab + or smul_widen_optab. + + We check specially for a constant integer as OP1, comparing the + cost of a widening multiply against the cost of a sequence of shifts + and adds. */ + +rtx +expand_widening_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, + int unsignedp, optab this_optab) +{ + bool speed = optimize_insn_for_speed_p (); + + if (CONST_INT_P (op1) + && (INTVAL (op1) >= 0 + || GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)) + { + HOST_WIDE_INT coeff = INTVAL (op1); + int max_cost; + enum mult_variant variant; + struct algorithm algorithm; + + /* Special case powers of two. */ + if (EXACT_POWER_OF_2_OR_ZERO_P (coeff)) + { + op0 = convert_to_mode (mode, op0, this_optab == umul_widen_optab); + return expand_shift (LSHIFT_EXPR, mode, op0, + build_int_cst (NULL_TREE, floor_log2 (coeff)), + target, unsignedp); + } + + /* Exclude cost of op0 from max_cost to match the cost + calculation of the synth_mult. */ + max_cost = mul_widen_cost[speed][mode]; + if (choose_mult_variant (mode, coeff, &algorithm, &variant, + max_cost)) + { + op0 = convert_to_mode (mode, op0, this_optab == umul_widen_optab); + return expand_mult_const (mode, op0, coeff, target, + &algorithm, variant); + } + } + return expand_binop (mode, this_optab, op0, op1, target, + unsignedp, OPTAB_LIB_WIDEN); +} /* Return the smallest n such that 2**n >= X. */ diff --git a/gcc/expr.c b/gcc/expr.c index 930ee98a438..5448bbe2b8f 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -774,18 +774,13 @@ convert_modes (enum machine_mode mode, enum machine_mode oldmode, rtx x, int uns && GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT && CONST_INT_P (x) && INTVAL (x) < 0) { - HOST_WIDE_INT val = INTVAL (x); + double_int val = uhwi_to_double_int (INTVAL (x)); - if (oldmode != VOIDmode - && HOST_BITS_PER_WIDE_INT > GET_MODE_BITSIZE (oldmode)) - { - int width = GET_MODE_BITSIZE (oldmode); - - /* We need to zero extend VAL. */ - val &= ((HOST_WIDE_INT) 1 << width) - 1; - } + /* We need to zero extend VAL. */ + if (oldmode != VOIDmode) + val = double_int_zext (val, GET_MODE_BITSIZE (oldmode)); - return immed_double_const (val, (HOST_WIDE_INT) 0, mode); + return immed_double_int_const (val, mode); } /* We can do this with a gen_lowpart if both desired and current modes @@ -7217,7 +7212,6 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, optab this_optab; rtx subtarget, original_target; int ignore; - tree subexp0, subexp1; bool reduce_bit_field; gimple subexp0_def, subexp1_def; tree top0, top1; @@ -7672,13 +7666,7 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, goto binop2; - case MULT_EXPR: - /* If this is a fixed-point operation, then we cannot use the code - below because "expand_mult" doesn't support sat/no-sat fixed-point - multiplications. */ - if (ALL_FIXED_POINT_MODE_P (mode)) - goto binop; - + case WIDEN_MULT_EXPR: /* If first operand is constant, swap them. Thus the following special case checks need only check the second operand. */ @@ -7689,96 +7677,35 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, treeop1 = t1; } - /* Attempt to return something suitable for generating an - indexed address, for machines that support that. */ - - if (modifier == EXPAND_SUM && mode == ptr_mode - && host_integerp (treeop1, 0)) - { - tree exp1 = treeop1; - - op0 = expand_expr (treeop0, subtarget, VOIDmode, - EXPAND_SUM); - - if (!REG_P (op0)) - op0 = force_operand (op0, NULL_RTX); - if (!REG_P (op0)) - op0 = copy_to_mode_reg (mode, op0); - - return REDUCE_BIT_FIELD (gen_rtx_MULT (mode, op0, - gen_int_mode (tree_low_cst (exp1, 0), - TYPE_MODE (TREE_TYPE (exp1))))); - } - - if (modifier == EXPAND_STACK_PARM) - target = 0; - - /* Check for multiplying things that have been extended - from a narrower type. If this machine supports multiplying - in that narrower type with a result in the desired type, - do it that way, and avoid the explicit type-conversion. */ - - subexp0 = treeop0; - subexp1 = treeop1; - subexp0_def = get_def_for_expr (subexp0, NOP_EXPR); - subexp1_def = get_def_for_expr (subexp1, NOP_EXPR); - top0 = top1 = NULL_TREE; - /* First, check if we have a multiplication of one signed and one unsigned operand. */ - if (subexp0_def - && (top0 = gimple_assign_rhs1 (subexp0_def)) - && subexp1_def - && (top1 = gimple_assign_rhs1 (subexp1_def)) - && TREE_CODE (type) == INTEGER_TYPE - && (TYPE_PRECISION (TREE_TYPE (top0)) - < TYPE_PRECISION (TREE_TYPE (subexp0))) - && (TYPE_PRECISION (TREE_TYPE (top0)) - == TYPE_PRECISION (TREE_TYPE (top1))) - && (TYPE_UNSIGNED (TREE_TYPE (top0)) - != TYPE_UNSIGNED (TREE_TYPE (top1)))) + if (TREE_CODE (treeop1) != INTEGER_CST + && (TYPE_UNSIGNED (TREE_TYPE (treeop0)) + != TYPE_UNSIGNED (TREE_TYPE (treeop1)))) { - enum machine_mode innermode - = TYPE_MODE (TREE_TYPE (top0)); + enum machine_mode innermode = TYPE_MODE (TREE_TYPE (treeop0)); this_optab = usmul_widen_optab; - if (mode == GET_MODE_WIDER_MODE (innermode)) + if (mode == GET_MODE_2XWIDER_MODE (innermode)) { if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing) { - if (TYPE_UNSIGNED (TREE_TYPE (top0))) - expand_operands (top0, top1, NULL_RTX, &op0, &op1, + if (TYPE_UNSIGNED (TREE_TYPE (treeop0))) + expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL); else - expand_operands (top0, top1, NULL_RTX, &op1, &op0, + expand_operands (treeop0, treeop1, subtarget, &op1, &op0, EXPAND_NORMAL); - goto binop3; } } } - /* Check for a multiplication with matching signedness. If - valid, TOP0 and TOP1 were set in the previous if - condition. */ - else if (top0 - && TREE_CODE (type) == INTEGER_TYPE - && (TYPE_PRECISION (TREE_TYPE (top0)) - < TYPE_PRECISION (TREE_TYPE (subexp0))) - && ((TREE_CODE (subexp1) == INTEGER_CST - && int_fits_type_p (subexp1, TREE_TYPE (top0)) - /* Don't use a widening multiply if a shift will do. */ - && ((GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (subexp1))) - > HOST_BITS_PER_WIDE_INT) - || exact_log2 (TREE_INT_CST_LOW (subexp1)) < 0)) - || - (top1 - && (TYPE_PRECISION (TREE_TYPE (top1)) - == TYPE_PRECISION (TREE_TYPE (top0)) - /* If both operands are extended, they must either both - be zero-extended or both be sign-extended. */ - && (TYPE_UNSIGNED (TREE_TYPE (top1)) - == TYPE_UNSIGNED (TREE_TYPE (top0))))))) + /* Check for a multiplication with matching signedness. */ + else if ((TREE_CODE (treeop1) == INTEGER_CST + && int_fits_type_p (treeop1, TREE_TYPE (treeop0))) + || (TYPE_UNSIGNED (TREE_TYPE (treeop1)) + == TYPE_UNSIGNED (TREE_TYPE (treeop0)))) { - tree op0type = TREE_TYPE (top0); + tree op0type = TREE_TYPE (treeop0); enum machine_mode innermode = TYPE_MODE (op0type); bool zextend_p = TYPE_UNSIGNED (op0type); optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab; @@ -7788,24 +7715,22 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, { if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing) { - if (TREE_CODE (subexp1) == INTEGER_CST) - expand_operands (top0, subexp1, NULL_RTX, &op0, &op1, - EXPAND_NORMAL); - else - expand_operands (top0, top1, NULL_RTX, &op0, &op1, - EXPAND_NORMAL); - goto binop3; + expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, + EXPAND_NORMAL); + temp = expand_widening_mult (mode, op0, op1, target, + unsignedp, this_optab); + return REDUCE_BIT_FIELD (temp); } - else if (optab_handler (other_optab, mode)->insn_code != CODE_FOR_nothing - && innermode == word_mode) + if (optab_handler (other_optab, mode)->insn_code != CODE_FOR_nothing + && innermode == word_mode) { rtx htem, hipart; - op0 = expand_normal (top0); - if (TREE_CODE (subexp1) == INTEGER_CST) + op0 = expand_normal (treeop0); + if (TREE_CODE (treeop1) == INTEGER_CST) op1 = convert_modes (innermode, mode, - expand_normal (subexp1), unsignedp); + expand_normal (treeop1), unsignedp); else - op1 = expand_normal (top1); + op1 = expand_normal (treeop1); temp = expand_binop (mode, other_optab, op0, op1, target, unsignedp, OPTAB_LIB_WIDEN); hipart = gen_highpart (innermode, temp); @@ -7818,7 +7743,53 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, } } } - expand_operands (subexp0, subexp1, subtarget, &op0, &op1, EXPAND_NORMAL); + treeop0 = fold_build1 (CONVERT_EXPR, type, treeop0); + treeop1 = fold_build1 (CONVERT_EXPR, type, treeop1); + expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL); + return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp)); + + case MULT_EXPR: + /* If this is a fixed-point operation, then we cannot use the code + below because "expand_mult" doesn't support sat/no-sat fixed-point + multiplications. */ + if (ALL_FIXED_POINT_MODE_P (mode)) + goto binop; + + /* If first operand is constant, swap them. + Thus the following special case checks need only + check the second operand. */ + if (TREE_CODE (treeop0) == INTEGER_CST) + { + tree t1 = treeop0; + treeop0 = treeop1; + treeop1 = t1; + } + + /* Attempt to return something suitable for generating an + indexed address, for machines that support that. */ + + if (modifier == EXPAND_SUM && mode == ptr_mode + && host_integerp (treeop1, 0)) + { + tree exp1 = treeop1; + + op0 = expand_expr (treeop0, subtarget, VOIDmode, + EXPAND_SUM); + + if (!REG_P (op0)) + op0 = force_operand (op0, NULL_RTX); + if (!REG_P (op0)) + op0 = copy_to_mode_reg (mode, op0); + + return REDUCE_BIT_FIELD (gen_rtx_MULT (mode, op0, + gen_int_mode (tree_low_cst (exp1, 0), + TYPE_MODE (TREE_TYPE (exp1))))); + } + + if (modifier == EXPAND_STACK_PARM) + target = 0; + + expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL); return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp)); case TRUNC_DIV_EXPR: @@ -9686,15 +9657,8 @@ reduce_to_bit_field_precision (rtx exp, rtx target, tree type) } else if (TYPE_UNSIGNED (type)) { - rtx mask; - if (prec < HOST_BITS_PER_WIDE_INT) - mask = immed_double_const (((unsigned HOST_WIDE_INT) 1 << prec) - 1, 0, - GET_MODE (exp)); - else - mask = immed_double_const ((unsigned HOST_WIDE_INT) -1, - ((unsigned HOST_WIDE_INT) 1 - << (prec - HOST_BITS_PER_WIDE_INT)) - 1, - GET_MODE (exp)); + rtx mask = immed_double_int_const (double_int_mask (prec), + GET_MODE (exp)); return expand_and (GET_MODE (exp), exp, mask, target); } else @@ -10280,9 +10244,8 @@ const_vector_from_tree (tree exp) RTVEC_ELT (v, i) = CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (elt), inner); else - RTVEC_ELT (v, i) = immed_double_const (TREE_INT_CST_LOW (elt), - TREE_INT_CST_HIGH (elt), - inner); + RTVEC_ELT (v, i) = immed_double_int_const (tree_to_double_int (elt), + inner); } /* Initialize remaining elements to 0. */ diff --git a/gcc/fold-const.c b/gcc/fold-const.c index c1af8248a39..cdae661733c 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -8643,9 +8643,33 @@ fold_comparison (location_t loc, enum tree_code code, tree type, offset1 = TREE_OPERAND (arg1, 1); } + /* A local variable can never be pointed to by + the default SSA name of an incoming parameter. */ + if ((TREE_CODE (arg0) == ADDR_EXPR + && indirect_base0 + && TREE_CODE (base0) == VAR_DECL + && auto_var_in_fn_p (base0, current_function_decl) + && !indirect_base1 + && TREE_CODE (base1) == SSA_NAME + && TREE_CODE (SSA_NAME_VAR (base1)) == PARM_DECL + && SSA_NAME_IS_DEFAULT_DEF (base1)) + || (TREE_CODE (arg1) == ADDR_EXPR + && indirect_base1 + && TREE_CODE (base1) == VAR_DECL + && auto_var_in_fn_p (base1, current_function_decl) + && !indirect_base0 + && TREE_CODE (base0) == SSA_NAME + && TREE_CODE (SSA_NAME_VAR (base0)) == PARM_DECL + && SSA_NAME_IS_DEFAULT_DEF (base0))) + { + if (code == NE_EXPR) + return constant_boolean_node (1, type); + else if (code == EQ_EXPR) + return constant_boolean_node (0, type); + } /* If we have equivalent bases we might be able to simplify. */ - if (indirect_base0 == indirect_base1 - && operand_equal_p (base0, base1, 0)) + else if (indirect_base0 == indirect_base1 + && operand_equal_p (base0, base1, 0)) { /* We can fold this expression to a constant if the non-constant offset parts are equal. */ @@ -8695,24 +8719,19 @@ fold_comparison (location_t loc, enum tree_code code, tree type, && ((code == EQ_EXPR || code == NE_EXPR) || POINTER_TYPE_OVERFLOW_UNDEFINED)) { - tree signed_size_type_node; - signed_size_type_node = signed_type_for (size_type_node); - /* By converting to signed size type we cover middle-end pointer arithmetic which operates on unsigned pointer types of size type size and ARRAY_REF offsets which are properly sign or zero extended from their type in case it is narrower than size type. */ if (offset0 == NULL_TREE) - offset0 = build_int_cst (signed_size_type_node, 0); + offset0 = build_int_cst (ssizetype, 0); else - offset0 = fold_convert_loc (loc, signed_size_type_node, - offset0); + offset0 = fold_convert_loc (loc, ssizetype, offset0); if (offset1 == NULL_TREE) - offset1 = build_int_cst (signed_size_type_node, 0); + offset1 = build_int_cst (ssizetype, 0); else - offset1 = fold_convert_loc (loc, signed_size_type_node, - offset1); + offset1 = fold_convert_loc (loc, ssizetype, offset1); if (code != EQ_EXPR && code != NE_EXPR diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index b53aff9b83b..1c77717b4e8 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,61 @@ +2010-04-22 Richard Guenther + + PR fortran/43829 + * resolve.c (gfc_resolve_index): Wrap around ... + (gfc_resolve_index_1): ... this. Add parameter to allow + any integer kind index type. + (resolve_array_ref): Allow any integer kind for the start + index of an array ref. + +2010-04-21 Jakub Jelinek + + PR fortran/43836 + * f95-lang.c (gfc_define_builtin): Set TREE_NOTHROW on + the decl. + +2010-04-20 Harald Anlauf + + * intrinsic.c (sort_actual): Remove 'is' in error message. + +2010-04-20 Paul Thomas + + PR fortran/43227 + * resolve.c (resolve_fl_derived): If a component character + length has not been resolved, do so now. + (resolve_symbol): The same as above for a symbol character + length. + * trans-decl.c (gfc_create_module_variable): A 'length' decl is + not needed for a character valued, procedure pointer. + + PR fortran/43266 + * resolve.c (ensure_not_abstract_walker): If 'overriding' is + not found, return FAILURE rather than ICEing. + +2010-04-19 Jakub Jelinek + + PR fortran/43339 + * openmp.c (gfc_resolve_do_iterator): Only make iteration vars for + sequential loops private in the innermost containing task region. + +2010-04-18 Eric Botcazou + + * f95-lang.c (gfc_init_decl_processing): Remove second argument in call + to build_common_tree_nodes. + +2010-04-17 Steven G. Kargl + + PR fortran/31538 + * fortran/trans-array.c (gfc_conv_ss_startstride): Remove the use of + gfc_msg_bounds by using 'Array bound mismatch' directly. + (gfc_trans_dummy_array_bias): Remove the use of gfc_msg_bounds. Reword + error message to include the mismatch in the extent of array bound. + * fortran/trans.c: Remove gfc_msg_bounds. It is only used in one place. + * fortran/trans.h: Remove extern definition of gfc_msg_bounds. + +2010-04-17 Jerry DeLisle + + * gfortran.texi: Update information on temporary file locations. + 2010-04-16 Jakub Jelinek * trans-decl.c (gfc_build_qualified_array): Ensure diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c index 5d2846c8890..8efa6de679b 100644 --- a/gcc/fortran/f95-lang.c +++ b/gcc/fortran/f95-lang.c @@ -1,5 +1,5 @@ /* gfortran backend interface - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 Free Software Foundation, Inc. Contributed by Paul Brook. @@ -542,7 +542,7 @@ gfc_init_decl_processing (void) /* Build common tree nodes. char_type_node is unsigned because we only use it for actual characters, not for INTEGER(1). Also, we want double_type_node to actually have double precision. */ - build_common_tree_nodes (false, false); + build_common_tree_nodes (false); /* x86_64 mingw32 has a sizetype of "unsigned long long", most other hosts have a sizetype of "unsigned long". Therefore choose the correct size in mostly target independent way. */ @@ -608,6 +608,7 @@ gfc_define_builtin (const char *name, library_name, NULL_TREE); if (const_p) TREE_READONLY (decl) = 1; + TREE_NOTHROW (decl) = 1; built_in_decls[code] = decl; implicit_built_in_decls[code] = decl; diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index 6ab413cbc3c..8a89699fc49 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -635,8 +635,8 @@ error is used. If the first letter is @samp{n}, @samp{N} or This environment variable controls where scratch files are created. If this environment variable is missing, -GNU Fortran searches for the environment variable @env{TMP}. If -this is also missing, the default is @file{/tmp}. +GNU Fortran searches for the environment variable @env{TMP}, then @env{TEMP}. +If these are missing, the default is @file{/tmp}. @node GFORTRAN_UNBUFFERED_ALL @section @env{GFORTRAN_UNBUFFERED_ALL}---Don't buffer I/O on all units diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c index 470839af104..494b8165584 100644 --- a/gcc/fortran/intrinsic.c +++ b/gcc/fortran/intrinsic.c @@ -3292,7 +3292,7 @@ keywords: if (f->actual != NULL) { - gfc_error ("Argument '%s' is appears twice in call to '%s' at %L", + gfc_error ("Argument '%s' appears twice in call to '%s' at %L", f->name, name, where); return FAILURE; } diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index d60121c5929..c00e1b41e28 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -1,5 +1,5 @@ /* OpenMP directive matching and resolving. - Copyright (C) 2005, 2006, 2007, 2008 + Copyright (C) 2005, 2006, 2007, 2008, 2010 Free Software Foundation, Inc. Contributed by Jakub Jelinek @@ -1367,7 +1367,6 @@ gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns) void gfc_resolve_do_iterator (gfc_code *code, gfc_symbol *sym) { - struct omp_context *ctx; int i = omp_current_do_collapse; gfc_code *c = omp_current_do_code; @@ -1386,21 +1385,21 @@ gfc_resolve_do_iterator (gfc_code *code, gfc_symbol *sym) c = c->block->next; } - for (ctx = omp_current_ctx; ctx; ctx = ctx->previous) - { - if (pointer_set_contains (ctx->sharing_clauses, sym)) - continue; + if (omp_current_ctx == NULL) + return; - if (! pointer_set_insert (ctx->private_iterators, sym)) - { - gfc_omp_clauses *omp_clauses = ctx->code->ext.omp_clauses; - gfc_namelist *p; + if (pointer_set_contains (omp_current_ctx->sharing_clauses, sym)) + return; - p = gfc_get_namelist (); - p->sym = sym; - p->next = omp_clauses->lists[OMP_LIST_PRIVATE]; - omp_clauses->lists[OMP_LIST_PRIVATE] = p; - } + if (! pointer_set_insert (omp_current_ctx->private_iterators, sym)) + { + gfc_omp_clauses *omp_clauses = omp_current_ctx->code->ext.omp_clauses; + gfc_namelist *p; + + p = gfc_get_namelist (); + p->sym = sym; + p->next = omp_clauses->lists[OMP_LIST_PRIVATE]; + omp_clauses->lists[OMP_LIST_PRIVATE] = p; } } diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 2831149c757..aeccffb60ca 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -3978,8 +3978,9 @@ compare_spec_to_ref (gfc_array_ref *ar) /* Resolve one part of an array index. */ -gfc_try -gfc_resolve_index (gfc_expr *index, int check_scalar) +static gfc_try +gfc_resolve_index_1 (gfc_expr *index, int check_scalar, + int force_index_integer_kind) { gfc_typespec ts; @@ -4007,7 +4008,8 @@ gfc_resolve_index (gfc_expr *index, int check_scalar) &index->where) == FAILURE) return FAILURE; - if (index->ts.kind != gfc_index_integer_kind + if ((index->ts.kind != gfc_index_integer_kind + && force_index_integer_kind) || index->ts.type != BT_INTEGER) { gfc_clear_ts (&ts); @@ -4020,6 +4022,14 @@ gfc_resolve_index (gfc_expr *index, int check_scalar) return SUCCESS; } +/* Resolve one part of an array index. */ + +gfc_try +gfc_resolve_index (gfc_expr *index, int check_scalar) +{ + return gfc_resolve_index_1 (index, check_scalar, 1); +} + /* Resolve a dim argument to an intrinsic function. */ gfc_try @@ -4144,7 +4154,10 @@ resolve_array_ref (gfc_array_ref *ar) { check_scalar = ar->dimen_type[i] == DIMEN_RANGE; - if (gfc_resolve_index (ar->start[i], check_scalar) == FAILURE) + /* Do not force gfc_index_integer_kind for the start. We can + do fine with any integer kind. This avoids temporary arrays + created for indexing with a vector. */ + if (gfc_resolve_index_1 (ar->start[i], check_scalar, 0) == FAILURE) return FAILURE; if (gfc_resolve_index (ar->end[i], check_scalar) == FAILURE) return FAILURE; @@ -10617,7 +10630,9 @@ ensure_not_abstract_walker (gfc_symbol* sub, gfc_symtree* st) { gfc_symtree* overriding; overriding = gfc_find_typebound_proc (sub, NULL, st->name, true, NULL); - gcc_assert (overriding && overriding->n.tb); + if (!overriding) + return FAILURE; + gcc_assert (overriding->n.tb); if (overriding->n.tb->deferred) { gfc_error ("Derived-type '%s' declared at %L must be ABSTRACT because" @@ -10784,8 +10799,12 @@ resolve_fl_derived (gfc_symbol *sym) /* Copy char length. */ if (ifc->ts.type == BT_CHARACTER && ifc->ts.u.cl) { - c->ts.u.cl = gfc_new_charlen (sym->ns, ifc->ts.u.cl); - gfc_expr_replace_comp (c->ts.u.cl->length, c); + gfc_charlen *cl = gfc_new_charlen (sym->ns, ifc->ts.u.cl); + gfc_expr_replace_comp (cl->length, c); + if (cl->length && !cl->resolved + && gfc_resolve_expr (cl->length) == FAILURE) + return FAILURE; + c->ts.u.cl = cl; } } else if (c->ts.interface->name[0] != '\0') @@ -11298,6 +11317,9 @@ resolve_symbol (gfc_symbol *sym) { sym->ts.u.cl = gfc_new_charlen (sym->ns, ifc->ts.u.cl); gfc_expr_replace_symbols (sym->ts.u.cl->length, sym); + if (sym->ts.u.cl->length && !sym->ts.u.cl->resolved + && gfc_resolve_expr (sym->ts.u.cl->length) == FAILURE) + return; } } else if (sym->ts.interface->name[0] != '\0') diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index a880f0efe61..199eb23b6ac 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -2434,6 +2434,7 @@ gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i, gfc_conv_array_data (desc)); index = gfc_build_array_ref (data, index, NULL); index = gfc_evaluate_now (index, &se->pre); + index = fold_convert (gfc_array_index_type, index); /* Do any bounds checking on the final info->descriptor index. */ index = gfc_trans_array_bound_check (se, info->descriptor, @@ -3365,13 +3366,15 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) if (size[n]) { tmp3 = fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]); - asprintf (&msg, "%s, size mismatch for dimension %d " - "of array '%s' (%%ld/%%ld)", gfc_msg_bounds, + asprintf (&msg, "Array bound mismatch for dimension %d " + "of array '%s' (%%ld/%%ld)", info->dim[n]+1, ss->expr->symtree->name); + gfc_trans_runtime_check (true, false, tmp3, &inner, &ss->expr->where, msg, fold_convert (long_integer_type_node, tmp), fold_convert (long_integer_type_node, size[n])); + gfc_free (msg); } else @@ -4632,15 +4635,26 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body) { /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)). */ char * msg; + tree temp; - tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, - ubound, lbound); - stride2 = fold_build2 (MINUS_EXPR, gfc_array_index_type, + temp = fold_build2 (MINUS_EXPR, gfc_array_index_type, + ubound, lbound); + temp = fold_build2 (PLUS_EXPR, gfc_array_index_type, + gfc_index_one_node, temp); + + stride2 = fold_build2 (MINUS_EXPR, gfc_array_index_type, dubound, dlbound); - tmp = fold_build2 (NE_EXPR, gfc_array_index_type, tmp, stride2); - asprintf (&msg, "%s for dimension %d of array '%s'", - gfc_msg_bounds, n+1, sym->name); - gfc_trans_runtime_check (true, false, tmp, &block, &loc, msg); + stride2 = fold_build2 (PLUS_EXPR, gfc_array_index_type, + gfc_index_one_node, stride2); + + tmp = fold_build2 (NE_EXPR, gfc_array_index_type, temp, stride2); + asprintf (&msg, "Dimension %d of array '%s' has extent " + "%%ld instead of %%ld", n+1, sym->name); + + gfc_trans_runtime_check (true, false, tmp, &block, &loc, msg, + fold_convert (long_integer_type_node, temp), + fold_convert (long_integer_type_node, stride2)); + gfc_free (msg); } } diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 2545ad2a320..11a75b46033 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -3477,7 +3477,8 @@ gfc_create_module_variable (gfc_symbol * sym) tree length; length = sym->ts.u.cl->backend_decl; - if (!INTEGER_CST_P (length)) + gcc_assert (length || sym->attr.proc_pointer); + if (length && !INTEGER_CST_P (length)) { pushdecl (length); rest_of_decl_compilation (length, 1, 0); diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c index c1993f90ddd..21c56045a44 100644 --- a/gcc/fortran/trans.c +++ b/gcc/fortran/trans.c @@ -47,7 +47,6 @@ along with GCC; see the file COPYING3. If not see static gfc_file *gfc_current_backend_file; -const char gfc_msg_bounds[] = N_("Array bound mismatch"); const char gfc_msg_fault[] = N_("Array reference out of bounds"); const char gfc_msg_wrong_return[] = N_("Incorrect function return value"); diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 782ff1d9e78..91f1b7784d1 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -773,7 +773,6 @@ void gfc_apply_interface_mapping (gfc_interface_mapping *, /* Standard error messages used in all the trans-*.c files. */ -extern const char gfc_msg_bounds[]; extern const char gfc_msg_fault[]; extern const char gfc_msg_wrong_return[]; diff --git a/gcc/gcc.c b/gcc/gcc.c index d2190533796..a25077e24f7 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -7495,7 +7495,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" fuse_linker_plugin + strlen (fuse_linker_plugin), 0)) { linker_plugin_file_spec = find_a_file (&exec_prefixes, - "liblto_plugin.so", X_OK, + "liblto_plugin.so", R_OK, false); if (!linker_plugin_file_spec) fatal ("-fuse-linker-plugin, but liblto_plugin.so not found"); diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 270475c0c6c..ab076348be0 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -159,7 +159,7 @@ maybe_fold_offset_to_array_ref (location_t loc, tree base, tree offset, return NULL_TREE; /* Use signed size type for intermediate computation on the index. */ - idx_type = signed_type_for (size_type_node); + idx_type = ssizetype; /* If OFFSET and ELT_OFFSET are zero, we don't care about the size of the element type (so we can use the alignment if it's not constant). diff --git a/gcc/gimple.h b/gcc/gimple.h index 18ebbb1e560..3daaa9e3c40 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -964,6 +964,7 @@ extern bool gimple_ior_addresses_taken (bitmap, gimple); extern tree create_tmp_var_raw (tree, const char *); extern tree create_tmp_var_name (const char *); extern tree create_tmp_var (tree, const char *); +extern tree create_tmp_reg (tree, const char *); extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *); extern tree get_formal_tmp_var (tree, gimple_seq *); extern void declare_vars (tree, gimple, bool); diff --git a/gcc/gimplify.c b/gcc/gimplify.c index de3da28fa1c..ad101d52d00 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -508,6 +508,23 @@ create_tmp_var (tree type, const char *prefix) return tmp_var; } +/* Create a new temporary variable declaration of type TYPE by calling + create_tmp_var and if TYPE is a vector or a complex number, mark the new + temporary as gimple register. */ + +tree +create_tmp_reg (tree type, const char *prefix) +{ + tree tmp; + + tmp = create_tmp_var (type, prefix); + if (TREE_CODE (type) == COMPLEX_TYPE + || TREE_CODE (type) == VECTOR_TYPE) + DECL_GIMPLE_REG_P (tmp) = 1; + + return tmp; +} + /* Create a temporary with a name derived from VAL. Subroutine of lookup_tmp_var; nobody else should call this function. */ @@ -1219,10 +1236,7 @@ gimplify_return_expr (tree stmt, gimple_seq *pre_p) result = gimplify_ctxp->return_temp; else { - result = create_tmp_var (TREE_TYPE (result_decl), NULL); - if (TREE_CODE (TREE_TYPE (result)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (result)) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (result) = 1; + result = create_tmp_reg (TREE_TYPE (result_decl), NULL); /* ??? With complex control flow (usually involving abnormal edges), we can wind up warning about an uninitialized value for this. Due @@ -6351,9 +6365,7 @@ gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p) tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr))); tree tmp_load; - tmp_load = create_tmp_var (type, NULL); - if (TREE_CODE (type) == COMPLEX_TYPE || TREE_CODE (type) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (tmp_load) = 1; + tmp_load = create_tmp_reg (type, NULL); if (goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0) return GS_ERROR; @@ -7828,11 +7840,8 @@ gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p) } if (need_temp) { - tree temp = create_tmp_var (TREE_TYPE (lhs), NULL); + tree temp = create_tmp_reg (TREE_TYPE (lhs), NULL); - if (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (lhs)) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (temp) = 1; if (TREE_CODE (orig_lhs) == SSA_NAME) orig_lhs = SSA_NAME_VAR (orig_lhs); diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 1f4773a6d45..dcf44b8facf 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1440,8 +1440,9 @@ noce_try_cmove_arith (struct noce_if_info *if_info) if insn_rtx_cost can't be estimated. */ if (insn_a) { - insn_cost = insn_rtx_cost (PATTERN (insn_a), - optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn_a))); + insn_cost + = insn_rtx_cost (PATTERN (insn_a), + optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn_a))); if (insn_cost == 0 || insn_cost > COSTS_N_INSNS (if_info->branch_cost)) return FALSE; } @@ -1450,8 +1451,9 @@ noce_try_cmove_arith (struct noce_if_info *if_info) if (insn_b) { - insn_cost += insn_rtx_cost (PATTERN (insn_b), - optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn_b))); + insn_cost + += insn_rtx_cost (PATTERN (insn_b), + optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn_b))); if (insn_cost == 0 || insn_cost > COSTS_N_INSNS (if_info->branch_cost)) return FALSE; } @@ -2579,7 +2581,8 @@ noce_process_if_block (struct noce_if_info *if_info) REGS. COND is the condition we will test. */ static int -check_cond_move_block (basic_block bb, rtx *vals, VEC (int, heap) **regs, rtx cond) +check_cond_move_block (basic_block bb, rtx *vals, VEC (int, heap) **regs, + rtx cond) { rtx insn; @@ -2743,7 +2746,8 @@ cond_move_process_if_block (struct noce_if_info *if_info) /* Make sure the blocks are suitable. */ if (!check_cond_move_block (then_bb, then_vals, &then_regs, cond) - || (else_bb && !check_cond_move_block (else_bb, else_vals, &else_regs, cond))) + || (else_bb + && !check_cond_move_block (else_bb, else_vals, &else_regs, cond))) { VEC_free (int, heap, then_regs); VEC_free (int, heap, else_regs); @@ -2859,8 +2863,7 @@ cond_move_process_if_block (struct noce_if_info *if_info) Return TRUE if we were successful at converting the block. */ static int -noce_find_if_block (basic_block test_bb, - edge then_edge, edge else_edge, +noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge, int pass) { basic_block then_bb, else_bb, join_bb; @@ -2941,9 +2944,7 @@ noce_find_if_block (basic_block test_bb, return FALSE; /* If this is not a standard conditional jump, we can't parse it. */ - cond = noce_get_condition (jump, - &cond_earliest, - then_else_reversed); + cond = noce_get_condition (jump, &cond_earliest, then_else_reversed); if (!cond) return FALSE; @@ -3135,7 +3136,7 @@ find_if_header (basic_block test_bb, int pass) /* Otherwise this must be a multiway branch of some sort. */ return NULL; - memset (&ce_info, '\0', sizeof (ce_info)); + memset (&ce_info, 0, sizeof (ce_info)); ce_info.test_bb = test_bb; ce_info.then_bb = then_edge->dest; ce_info.else_bb = else_edge->dest; @@ -3145,11 +3146,12 @@ find_if_header (basic_block test_bb, int pass) IFCVT_INIT_EXTRA_FIELDS (&ce_info); #endif - if (! reload_completed + if (!reload_completed && noce_find_if_block (test_bb, then_edge, else_edge, pass)) goto success; - if (targetm.have_conditional_execution () && reload_completed + if (reload_completed + && targetm.have_conditional_execution () && cond_exec_find_if_block (&ce_info)) goto success; @@ -3159,7 +3161,7 @@ find_if_header (basic_block test_bb, int pass) goto success; if (dom_info_state (CDI_POST_DOMINATORS) >= DOM_NO_FAST_QUERY - && (! targetm.have_conditional_execution () || reload_completed)) + && (reload_completed || !targetm.have_conditional_execution ())) { if (find_if_case_1 (test_bb, then_edge, else_edge)) goto success; @@ -3265,8 +3267,8 @@ cond_exec_find_if_block (struct ce_if_block * ce_info) ce_info->last_test_bb = test_bb; /* We only ever should get here after reload, - and only if we have conditional execution. */ - gcc_assert (targetm.have_conditional_execution () && reload_completed); + and if we have conditional execution. */ + gcc_assert (reload_completed && targetm.have_conditional_execution ()); /* Discover if any fall through predecessors of the current test basic block were && tests (which jump to the else block) or || tests (which jump to @@ -3347,7 +3349,8 @@ cond_exec_find_if_block (struct ce_if_block * ce_info) if (EDGE_COUNT (then_bb->succs) > 0 && (!single_succ_p (then_bb) || (single_succ_edge (then_bb)->flags & EDGE_COMPLEX) - || (epilogue_completed && tablejump_p (BB_END (then_bb), NULL, NULL)))) + || (epilogue_completed + && tablejump_p (BB_END (then_bb), NULL, NULL)))) return FALSE; /* If the THEN block has no successors, conditional execution can still @@ -3393,8 +3396,9 @@ cond_exec_find_if_block (struct ce_if_block * ce_info) else if (single_succ_p (else_bb) && single_succ (then_bb) == single_succ (else_bb) && single_pred_p (else_bb) - && ! (single_succ_edge (else_bb)->flags & EDGE_COMPLEX) - && ! (epilogue_completed && tablejump_p (BB_END (else_bb), NULL, NULL))) + && !(single_succ_edge (else_bb)->flags & EDGE_COMPLEX) + && !(epilogue_completed + && tablejump_p (BB_END (else_bb), NULL, NULL))) join_bb = single_succ (else_bb); /* Otherwise it is not an IF-THEN or IF-THEN-ELSE combination. */ @@ -3990,7 +3994,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, that any registers modified are dead at the branch site. */ rtx insn, cond, prev; - bitmap merge_set, test_live, test_set; + bitmap merge_set, merge_set_noclobber, test_live, test_set; unsigned i, fail = 0; bitmap_iterator bi; @@ -4026,11 +4030,14 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, /* Collect: MERGE_SET = set of registers set in MERGE_BB + MERGE_SET_NOCLOBBER = like MERGE_SET, but only includes registers + that are really set, not just clobbered. TEST_LIVE = set of registers live at EARLIEST - TEST_SET = set of registers set between EARLIEST and the - end of the block. */ + TEST_SET = set of registers set between EARLIEST and the + end of the block. */ merge_set = BITMAP_ALLOC (®_obstack); + merge_set_noclobber = BITMAP_ALLOC (®_obstack); test_live = BITMAP_ALLOC (®_obstack); test_set = BITMAP_ALLOC (®_obstack); @@ -4047,13 +4054,8 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, { if (NONDEBUG_INSN_P (insn)) { - unsigned int uid = INSN_UID (insn); - df_ref *def_rec; - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) - { - df_ref def = *def_rec; - bitmap_set_bit (merge_set, DF_REF_REGNO (def)); - } + df_simulate_find_defs (insn, merge_set); + df_simulate_find_noclobber_defs (insn, merge_set_noclobber); } } @@ -4061,7 +4063,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, hard registers before reload. */ if (SMALL_REGISTER_CLASSES && ! reload_completed) { - EXECUTE_IF_SET_IN_BITMAP (merge_set, 0, i, bi) + EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi) { if (i < FIRST_PSEUDO_REGISTER && ! fixed_regs[i] @@ -4081,7 +4083,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, { if (INSN_P (insn)) { - df_simulate_find_defs (insn, test_set); + df_simulate_find_noclobber_defs (insn, test_set); df_simulate_one_insn_backwards (test_bb, insn, test_live); } prev = PREV_INSN (insn); @@ -4090,16 +4092,19 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, } /* We can perform the transformation if - MERGE_SET & (TEST_SET | TEST_LIVE) + MERGE_SET_NOCLOBBER & TEST_SET + and + MERGE_SET & TEST_LIVE) and TEST_SET & DF_LIVE_IN (merge_bb) are empty. */ - if (bitmap_intersect_p (test_set, merge_set) + if (bitmap_intersect_p (test_set, merge_set_noclobber) || bitmap_intersect_p (test_live, merge_set) || bitmap_intersect_p (test_set, df_get_live_in (merge_bb))) fail = 1; + BITMAP_FREE (merge_set_noclobber); BITMAP_FREE (merge_set); BITMAP_FREE (test_live); BITMAP_FREE (test_set); diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 527c0c42530..ca7c0e6b7c9 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1344,7 +1344,8 @@ struct ipa_opt_pass_d pass_ipa_cp = ipcp_generate_summary, /* generate_summary */ ipcp_write_summary, /* write_summary */ ipcp_read_summary, /* read_summary */ - NULL, /* function_read_summary */ + NULL, /* write_optimization_summary */ + NULL, /* read_optimization_summary */ lto_ipa_fixup_call_notes, /* stmt_fixup */ 0, /* TODOs */ NULL, /* function_transform */ diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 601695a3fda..fbd695d129c 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1024,8 +1024,9 @@ cgraph_decide_inlining_of_small_functions (void) " Estimated growth after inlined into all callees is %+i insns.\n" " Estimated badness is %i, frequency %.2f.\n", cgraph_node_name (edge->caller), - gimple_filename ((const_gimple) edge->call_stmt), - gimple_lineno ((const_gimple) edge->call_stmt), + flag_wpa ? "unknown" + : gimple_filename ((const_gimple) edge->call_stmt), + flag_wpa ? -1 : gimple_lineno ((const_gimple) edge->call_stmt), cgraph_estimate_growth (edge->callee), badness, edge->frequency / (double)CGRAPH_FREQ_BASE); @@ -1200,8 +1201,9 @@ cgraph_decide_inlining_of_small_functions (void) " Estimated growth after inlined into all callees is %+i insns.\n" " Estimated badness is %i, frequency %.2f.\n", cgraph_node_name (edge->caller), - gimple_filename ((const_gimple) edge->call_stmt), - gimple_lineno ((const_gimple) edge->call_stmt), + flag_wpa ? "unknown" + : gimple_filename ((const_gimple) edge->call_stmt), + flag_wpa ? -1 : gimple_lineno ((const_gimple) edge->call_stmt), cgraph_estimate_growth (edge->callee), badness, edge->frequency / (double)CGRAPH_FREQ_BASE); @@ -1416,13 +1418,14 @@ cgraph_decide_inlining (void) if (cgraph_check_inline_limits (node->callers->caller, node, &reason, false)) { + struct cgraph_node *caller = node->callers->caller; cgraph_mark_inline (node->callers); if (dump_file) fprintf (dump_file, " Inlined into %s which now has %i size" " for a net change of %+i size.\n", - cgraph_node_name (node->callers->caller), - node->callers->caller->global.size, + cgraph_node_name (caller), + caller->global.size, overall_size - old_size); } else @@ -1667,6 +1670,17 @@ cgraph_early_inlining (void) } else { + if (lookup_attribute ("flatten", + DECL_ATTRIBUTES (node->decl)) != NULL) + { + if (dump_file) + fprintf (dump_file, + "Flattening %s\n", cgraph_node_name (node)); + cgraph_flatten (node); + timevar_push (TV_INTEGRATION); + todo |= optimize_inline_calls (current_function_decl); + timevar_pop (TV_INTEGRATION); + } /* We iterate incremental inlining to get trivial cases of indirect inlining. */ while (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS) @@ -2121,7 +2135,8 @@ struct ipa_opt_pass_d pass_ipa_inline = inline_generate_summary, /* generate_summary */ inline_write_summary, /* write_summary */ inline_read_summary, /* read_summary */ - NULL, /* function_read_summary */ + NULL, /* write_optimization_summary */ + NULL, /* read_optimization_summary */ lto_ipa_fixup_call_notes, /* stmt_fixup */ 0, /* TODOs */ inline_transform, /* function_transform */ diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index c6d58b1d452..af00175124d 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -1260,6 +1260,10 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED) static void ipa_node_removal_hook (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) { + /* During IPA-CP updating we can be called on not-yet analyze clones. */ + if (VEC_length (ipa_node_params_t, ipa_node_params_vector) + <= (unsigned)node->uid) + return; ipa_free_node_params_substructures (IPA_NODE_REF (node)); } @@ -1700,7 +1704,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt, if (!useless_type_conversion_p (ptrtype, TREE_TYPE (expr))) expr = fold_convert (ptrtype, expr); expr = fold_build2 (POINTER_PLUS_EXPR, ptrtype, expr, - build_int_cst (size_type_node, + build_int_cst (sizetype, adj->offset / BITS_PER_UNIT)); if (!adj->by_ref) expr = fold_build1 (INDIRECT_REF, adj->type, expr); diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index 719bef6b768..4d0df50ac63 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -1104,7 +1104,8 @@ struct ipa_opt_pass_d pass_ipa_pure_const = generate_summary, /* generate_summary */ pure_const_write_summary, /* write_summary */ pure_const_read_summary, /* read_summary */ - NULL, /* function_read_summary */ + NULL, /* write_optimization_summary */ + NULL, /* read_optimization_summary */ NULL, /* stmt_fixup */ 0, /* TODOs */ NULL, /* function_transform */ diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c index 9eac3b10e82..7183e65a7fd 100644 --- a/gcc/ipa-reference.c +++ b/gcc/ipa-reference.c @@ -1514,7 +1514,8 @@ struct ipa_opt_pass_d pass_ipa_reference = generate_summary, /* generate_summary */ ipa_reference_write_summary, /* write_summary */ ipa_reference_read_summary, /* read_summary */ - NULL, /* function_read_summary */ + NULL, /* write_optimization_summary */ + NULL, /* read_optimization_summary */ NULL, /* stmt_fixup */ 0, /* TODOs */ NULL, /* function_transform */ diff --git a/gcc/ipa.c b/gcc/ipa.c index d559ab2f285..3a5ef16d2be 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -271,6 +271,8 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file) node->analyzed = false; node->local.inlinable = false; } + else + gcc_assert (!clone->in_other_partition); cgraph_node_remove_callees (node); if (node->prev_sibling_clone) node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone; @@ -574,7 +576,8 @@ struct ipa_opt_pass_d pass_ipa_whole_program_visibility = NULL, /* generate_summary */ NULL, /* write_summary */ NULL, /* read_summary */ - NULL, /* function_read_summary */ + NULL, /* write_optimization_summary */ + NULL, /* read_optimization_summary */ NULL, /* stmt_fixup */ 0, /* TODOs */ NULL, /* function_transform */ diff --git a/gcc/ira-color.c b/gcc/ira-color.c index f507db18aee..e01a6abdb47 100644 --- a/gcc/ira-color.c +++ b/gcc/ira-color.c @@ -2786,7 +2786,9 @@ allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs) int hard_regno; enum reg_class cover_class; int regno = ALLOCNO_REGNO (a); + HARD_REG_SET saved; + COPY_HARD_REG_SET (saved, ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a)); IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), forbidden_regs); if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0) IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), call_used_reg_set); @@ -2830,7 +2832,7 @@ allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs) } else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL) fprintf (ira_dump_file, "\n"); - + COPY_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), saved); return reg_renumber[regno] >= 0; } diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c index 09316b510f2..7ced1a7a73d 100644 --- a/gcc/ira-lives.c +++ b/gcc/ira-lives.c @@ -805,6 +805,9 @@ ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set) ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, p)); if (cl != NO_REGS + /* There is no register pressure problem if all of the + regs in this class are fixed. */ + && ira_available_class_regs[cl] != 0 && (ira_available_class_regs[cl] <= ira_reg_class_nregs[cl][mode])) IOR_HARD_REG_SET (*set, reg_class_contents[cl]); diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index f1a60807436..b88bd1974ed 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,8 @@ +2010-04-18 Eric Botcazou + + * decl.c (java_init_decl_processing): Remove argument in call to + initialize_sizetypes + 2010-04-07 Jakub Jelinek * exception.cc (_Jv_Throw): Avoid set but not used warning. diff --git a/gcc/java/decl.c b/gcc/java/decl.c index c593b53df5c..4cd4d9668dc 100644 --- a/gcc/java/decl.c +++ b/gcc/java/decl.c @@ -579,7 +579,7 @@ java_init_decl_processing (void) TREE_TYPE (error_mark_node) = error_mark_node; /* Create sizetype first - needed for other types. */ - initialize_sizetypes (false); + initialize_sizetypes (); byte_type_node = make_signed_type (8); pushdecl (build_decl (BUILTINS_LOCATION, diff --git a/gcc/lambda-code.c b/gcc/lambda-code.c index b3143da8e38..fff6ff800f3 100644 --- a/gcc/lambda-code.c +++ b/gcc/lambda-code.c @@ -150,6 +150,17 @@ static lambda_lattice lambda_lattice_compute_base (lambda_loopnest, static bool can_convert_to_perfect_nest (struct loop *); +/* Create a new lambda loop in LAMBDA_OBSTACK. */ + +static lambda_loop +lambda_loop_new (struct obstack * lambda_obstack) +{ + lambda_loop result = (lambda_loop) + obstack_alloc (lambda_obstack, sizeof (struct lambda_loop_s)); + memset (result, 0, sizeof (struct lambda_loop_s)); + return result; +} + /* Create a new lambda body vector. */ lambda_body_vector @@ -157,7 +168,8 @@ lambda_body_vector_new (int size, struct obstack * lambda_obstack) { lambda_body_vector ret; - ret = (lambda_body_vector)obstack_alloc (lambda_obstack, sizeof (*ret)); + ret = (lambda_body_vector) obstack_alloc (lambda_obstack, + sizeof (*ret)); LBV_COEFFICIENTS (ret) = lambda_vector_new (size); LBV_SIZE (ret) = size; LBV_DENOMINATOR (ret) = 1; @@ -367,9 +379,10 @@ lambda_lattice_new (int depth, int invariants, struct obstack * lambda_obstack) { lambda_lattice ret = (lambda_lattice)obstack_alloc (lambda_obstack, sizeof (*ret)); - LATTICE_BASE (ret) = lambda_matrix_new (depth, depth); + LATTICE_BASE (ret) = lambda_matrix_new (depth, depth, lambda_obstack); LATTICE_ORIGIN (ret) = lambda_vector_new (depth); - LATTICE_ORIGIN_INVARIANTS (ret) = lambda_matrix_new (depth, invariants); + LATTICE_ORIGIN_INVARIANTS (ret) = lambda_matrix_new (depth, invariants, + lambda_obstack); LATTICE_DIMENSION (ret) = depth; LATTICE_INVARIANTS (ret) = invariants; return ret; @@ -500,15 +513,15 @@ compute_nest_using_fourier_motzkin (int size, lambda_vector swapvector, a1; int newsize; - A1 = lambda_matrix_new (128, depth); - B1 = lambda_matrix_new (128, invariants); + A1 = lambda_matrix_new (128, depth, lambda_obstack); + B1 = lambda_matrix_new (128, invariants, lambda_obstack); a1 = lambda_vector_new (128); auxillary_nest = lambda_loopnest_new (depth, invariants, lambda_obstack); for (i = depth - 1; i >= 0; i--) { - loop = lambda_loop_new (); + loop = lambda_loop_new (lambda_obstack); LN_LOOPS (auxillary_nest)[i] = loop; LL_STEP (loop) = 1; @@ -654,12 +667,12 @@ lambda_compute_auxillary_space (lambda_loopnest nest, /* Unfortunately, we can't know the number of constraints we'll have ahead of time, but this should be enough even in ridiculous loop nest cases. We must not go over this limit. */ - A = lambda_matrix_new (128, depth); - B = lambda_matrix_new (128, invariants); + A = lambda_matrix_new (128, depth, lambda_obstack); + B = lambda_matrix_new (128, invariants, lambda_obstack); a = lambda_vector_new (128); - A1 = lambda_matrix_new (128, depth); - B1 = lambda_matrix_new (128, invariants); + A1 = lambda_matrix_new (128, depth, lambda_obstack); + B1 = lambda_matrix_new (128, invariants, lambda_obstack); a1 = lambda_vector_new (128); /* Store the bounds in the equation matrix A, constant vector a, and @@ -754,11 +767,11 @@ lambda_compute_auxillary_space (lambda_loopnest nest, /* Now compute the auxiliary space bounds by first inverting U, multiplying it by A1, then performing Fourier-Motzkin. */ - invertedtrans = lambda_matrix_new (depth, depth); + invertedtrans = lambda_matrix_new (depth, depth, lambda_obstack); /* Compute the inverse of U. */ lambda_matrix_inverse (LTM_MATRIX (trans), - invertedtrans, depth); + invertedtrans, depth, lambda_obstack); /* A = A1 inv(U). */ lambda_matrix_mult (A1, invertedtrans, A, size, depth, depth); @@ -795,18 +808,19 @@ lambda_compute_target_space (lambda_loopnest auxillary_nest, depth = LN_DEPTH (auxillary_nest); invariants = LN_INVARIANTS (auxillary_nest); - inverse = lambda_matrix_new (depth, depth); - determinant = lambda_matrix_inverse (LTM_MATRIX (H), inverse, depth); + inverse = lambda_matrix_new (depth, depth, lambda_obstack); + determinant = lambda_matrix_inverse (LTM_MATRIX (H), inverse, depth, + lambda_obstack); /* H1 is H excluding its diagonal. */ - H1 = lambda_matrix_new (depth, depth); + H1 = lambda_matrix_new (depth, depth, lambda_obstack); lambda_matrix_copy (LTM_MATRIX (H), H1, depth, depth); for (i = 0; i < depth; i++) H1[i][i] = 0; /* Computes the linear offsets of the loop bounds. */ - target = lambda_matrix_new (depth, depth); + target = lambda_matrix_new (depth, depth, lambda_obstack); lambda_matrix_mult (H1, inverse, target, depth, depth, depth); target_nest = lambda_loopnest_new (depth, invariants, lambda_obstack); @@ -815,7 +829,7 @@ lambda_compute_target_space (lambda_loopnest auxillary_nest, { /* Get a new loop structure. */ - target_loop = lambda_loop_new (); + target_loop = lambda_loop_new (lambda_obstack); LN_LOOPS (target_nest)[i] = target_loop; /* Computes the gcd of the coefficients of the linear part. */ @@ -982,7 +996,9 @@ lambda_compute_target_space (lambda_loopnest auxillary_nest, result. */ static lambda_vector -lambda_compute_step_signs (lambda_trans_matrix trans, lambda_vector stepsigns) +lambda_compute_step_signs (lambda_trans_matrix trans, + lambda_vector stepsigns, + struct obstack * lambda_obstack) { lambda_matrix matrix, H; int size; @@ -992,7 +1008,7 @@ lambda_compute_step_signs (lambda_trans_matrix trans, lambda_vector stepsigns) matrix = LTM_MATRIX (trans); size = LTM_ROWSIZE (trans); - H = lambda_matrix_new (size, size); + H = lambda_matrix_new (size, size, lambda_obstack); newsteps = lambda_vector_new (size); lambda_vector_copy (stepsigns, newsteps, size); @@ -1067,7 +1083,7 @@ lambda_loopnest_transform (lambda_loopnest nest, lambda_trans_matrix trans, /* Compute the lattice base. */ lattice = lambda_lattice_compute_base (nest, lambda_obstack); - trans1 = lambda_trans_matrix_new (depth, depth); + trans1 = lambda_trans_matrix_new (depth, depth, lambda_obstack); /* Multiply the transformation matrix by the lattice base. */ @@ -1075,25 +1091,27 @@ lambda_loopnest_transform (lambda_loopnest nest, lambda_trans_matrix trans, LTM_MATRIX (trans1), depth, depth, depth); /* Compute the Hermite normal form for the new transformation matrix. */ - H = lambda_trans_matrix_new (depth, depth); - U = lambda_trans_matrix_new (depth, depth); + H = lambda_trans_matrix_new (depth, depth, lambda_obstack); + U = lambda_trans_matrix_new (depth, depth, lambda_obstack); lambda_matrix_hermite (LTM_MATRIX (trans1), depth, LTM_MATRIX (H), LTM_MATRIX (U)); /* Compute the auxiliary loop nest's space from the unimodular portion. */ - auxillary_nest = lambda_compute_auxillary_space (nest, U, lambda_obstack); + auxillary_nest = lambda_compute_auxillary_space (nest, U, + lambda_obstack); /* Compute the loop step signs from the old step signs and the transformation matrix. */ - stepsigns = lambda_compute_step_signs (trans1, stepsigns); + stepsigns = lambda_compute_step_signs (trans1, stepsigns, + lambda_obstack); /* Compute the target loop nest space from the auxiliary nest and the lower triangular matrix H. */ target_nest = lambda_compute_target_space (auxillary_nest, H, stepsigns, lambda_obstack); origin = lambda_vector_new (depth); - origin_invariants = lambda_matrix_new (depth, invariants); + origin_invariants = lambda_matrix_new (depth, invariants, lambda_obstack); lambda_matrix_vector_mult (LTM_MATRIX (trans), depth, depth, LATTICE_ORIGIN (lattice), origin); lambda_matrix_mult (LTM_MATRIX (trans), LATTICE_ORIGIN_INVARIANTS (lattice), @@ -1424,7 +1442,7 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth, return NULL; } - lloop = lambda_loop_new (); + lloop = lambda_loop_new (lambda_obstack); LL_STEP (lloop) = stepint; LL_LOWER_BOUND (lloop) = lbound; LL_UPPER_BOUND (lloop) = ubound; @@ -1702,7 +1720,7 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest, tree oldiv; gimple_stmt_iterator bsi; - transform = lambda_trans_matrix_inverse (transform); + transform = lambda_trans_matrix_inverse (transform, lambda_obstack); if (dump_file) { @@ -2801,9 +2819,12 @@ av_for_af (tree access_fun, lambda_vector cy, struct access_matrix *am) static bool build_access_matrix (data_reference_p data_reference, - VEC (tree, heap) *parameters, VEC (loop_p, heap) *nest) + VEC (tree, heap) *parameters, + VEC (loop_p, heap) *nest, + struct obstack * lambda_obstack) { - struct access_matrix *am = GGC_NEW (struct access_matrix); + struct access_matrix *am = (struct access_matrix *) + obstack_alloc(lambda_obstack, sizeof (struct access_matrix)); unsigned i, ndim = DR_NUM_DIMENSIONS (data_reference); unsigned nivs = VEC_length (loop_p, nest); unsigned lambda_nb_columns; @@ -2835,13 +2856,14 @@ build_access_matrix (data_reference_p data_reference, bool lambda_compute_access_matrices (VEC (data_reference_p, heap) *datarefs, VEC (tree, heap) *parameters, - VEC (loop_p, heap) *nest) + VEC (loop_p, heap) *nest, + struct obstack * lambda_obstack) { data_reference_p dataref; unsigned ix; for (ix = 0; VEC_iterate (data_reference_p, datarefs, ix, dataref); ix++) - if (!build_access_matrix (dataref, parameters, nest)) + if (!build_access_matrix (dataref, parameters, nest, lambda_obstack)) return false; return true; diff --git a/gcc/lambda-mat.c b/gcc/lambda-mat.c index fb9098b20e1..50fdb699925 100644 --- a/gcc/lambda-mat.c +++ b/gcc/lambda-mat.c @@ -27,18 +27,16 @@ along with GCC; see the file COPYING3. If not see #include "tree-flow.h" #include "lambda.h" -static void lambda_matrix_get_column (lambda_matrix, int, int, - lambda_vector); - /* Allocate a matrix of M rows x N cols. */ lambda_matrix -lambda_matrix_new (int m, int n) +lambda_matrix_new (int m, int n, struct obstack * lambda_obstack) { lambda_matrix mat; int i; - mat = GGC_NEWVEC (lambda_vector, m); + mat = (lambda_matrix) obstack_alloc (lambda_obstack, + sizeof (lambda_vector *) * m); for (i = 0; i < m; i++) mat[i] = lambda_vector_new (n); @@ -165,19 +163,6 @@ lambda_matrix_mult (lambda_matrix mat1, lambda_matrix mat2, } } -/* Get column COL from the matrix MAT and store it in VEC. MAT has - N rows, so the length of VEC must be N. */ - -static void -lambda_matrix_get_column (lambda_matrix mat, int n, int col, - lambda_vector vec) -{ - int i; - - for (i = 0; i < n; i++) - vec[i] = mat[i][col]; -} - /* Delete rows r1 to r2 (not including r2). */ void @@ -307,10 +292,12 @@ lambda_matrix_col_mc (lambda_matrix mat, int m, int c1, int const1) When MAT is a 2 x 2 matrix, we don't go through the whole process, because it is easily inverted by inspection and it is a very common case. */ -static int lambda_matrix_inverse_hard (lambda_matrix, lambda_matrix, int); +static int lambda_matrix_inverse_hard (lambda_matrix, lambda_matrix, int, + struct obstack *); int -lambda_matrix_inverse (lambda_matrix mat, lambda_matrix inv, int n) +lambda_matrix_inverse (lambda_matrix mat, lambda_matrix inv, int n, + struct obstack * lambda_obstack) { if (n == 2) { @@ -335,20 +322,21 @@ lambda_matrix_inverse (lambda_matrix mat, lambda_matrix inv, int n) return det; } else - return lambda_matrix_inverse_hard (mat, inv, n); + return lambda_matrix_inverse_hard (mat, inv, n, lambda_obstack); } /* If MAT is not a special case, invert it the hard way. */ static int -lambda_matrix_inverse_hard (lambda_matrix mat, lambda_matrix inv, int n) +lambda_matrix_inverse_hard (lambda_matrix mat, lambda_matrix inv, int n, + struct obstack * lambda_obstack) { lambda_vector row; lambda_matrix temp; int i, j; int determinant; - temp = lambda_matrix_new (n, n); + temp = lambda_matrix_new (n, n, lambda_obstack); lambda_matrix_copy (mat, temp, n, n); lambda_matrix_id (inv, n); @@ -592,45 +580,6 @@ lambda_matrix_first_nz_vec (lambda_matrix mat, int rowsize, int colsize, return rowsize; } -/* Calculate the projection of E sub k to the null space of B. */ - -void -lambda_matrix_project_to_null (lambda_matrix B, int rowsize, - int colsize, int k, lambda_vector x) -{ - lambda_matrix M1, M2, M3, I; - int determinant; - - /* Compute c(I-B^T inv(B B^T) B) e sub k. */ - - /* M1 is the transpose of B. */ - M1 = lambda_matrix_new (colsize, colsize); - lambda_matrix_transpose (B, M1, rowsize, colsize); - - /* M2 = B * B^T */ - M2 = lambda_matrix_new (colsize, colsize); - lambda_matrix_mult (B, M1, M2, rowsize, colsize, rowsize); - - /* M3 = inv(M2) */ - M3 = lambda_matrix_new (colsize, colsize); - determinant = lambda_matrix_inverse (M2, M3, rowsize); - - /* M2 = B^T (inv(B B^T)) */ - lambda_matrix_mult (M1, M3, M2, colsize, rowsize, rowsize); - - /* M1 = B^T (inv(B B^T)) B */ - lambda_matrix_mult (M2, B, M1, colsize, rowsize, colsize); - lambda_matrix_negate (M1, M1, colsize, colsize); - - I = lambda_matrix_new (colsize, colsize); - lambda_matrix_id (I, colsize); - - lambda_matrix_add_mc (I, determinant, M1, 1, M2, colsize, colsize); - - lambda_matrix_get_column (M2, colsize, k - 1, x); - -} - /* Multiply a vector VEC by a matrix MAT. MAT is an M*N matrix, and VEC is a vector with length N. The result is stored in DEST which must be a vector of length M. */ diff --git a/gcc/lambda-trans.c b/gcc/lambda-trans.c index d34a63e2e86..0cf1db96fa6 100644 --- a/gcc/lambda-trans.c +++ b/gcc/lambda-trans.c @@ -31,12 +31,14 @@ along with GCC; see the file COPYING3. If not see /* Allocate a new transformation matrix. */ lambda_trans_matrix -lambda_trans_matrix_new (int colsize, int rowsize) +lambda_trans_matrix_new (int colsize, int rowsize, + struct obstack * lambda_obstack) { lambda_trans_matrix ret; - ret = GGC_NEW (struct lambda_trans_matrix_s); - LTM_MATRIX (ret) = lambda_matrix_new (rowsize, colsize); + ret = (lambda_trans_matrix) + obstack_alloc (lambda_obstack, sizeof (struct lambda_trans_matrix_s)); + LTM_MATRIX (ret) = lambda_matrix_new (rowsize, colsize, lambda_obstack); LTM_ROWSIZE (ret) = rowsize; LTM_COLSIZE (ret) = colsize; LTM_DENOMINATOR (ret) = 1; @@ -57,14 +59,16 @@ lambda_trans_matrix_id_p (lambda_trans_matrix mat) /* Compute the inverse of the transformation matrix MAT. */ lambda_trans_matrix -lambda_trans_matrix_inverse (lambda_trans_matrix mat) +lambda_trans_matrix_inverse (lambda_trans_matrix mat, + struct obstack * lambda_obstack) { lambda_trans_matrix inverse; int determinant; - inverse = lambda_trans_matrix_new (LTM_ROWSIZE (mat), LTM_COLSIZE (mat)); + inverse = lambda_trans_matrix_new (LTM_ROWSIZE (mat), LTM_COLSIZE (mat), + lambda_obstack); determinant = lambda_matrix_inverse (LTM_MATRIX (mat), LTM_MATRIX (inverse), - LTM_ROWSIZE (mat)); + LTM_ROWSIZE (mat), lambda_obstack); LTM_DENOMINATOR (inverse) = determinant; return inverse; } diff --git a/gcc/lambda.h b/gcc/lambda.h index 189c1fc50b3..c819027f582 100644 --- a/gcc/lambda.h +++ b/gcc/lambda.h @@ -156,11 +156,9 @@ struct loop; bool perfect_nest_p (struct loop *); void print_lambda_loopnest (FILE *, lambda_loopnest, char); -#define lambda_loop_new() (lambda_loop) ggc_alloc_cleared (sizeof (struct lambda_loop_s)) - void print_lambda_loop (FILE *, lambda_loop, int, int, char); -lambda_matrix lambda_matrix_new (int, int); +lambda_matrix lambda_matrix_new (int, int, struct obstack *); void lambda_matrix_id (lambda_matrix, int); bool lambda_matrix_id_p (lambda_matrix, int); @@ -182,7 +180,7 @@ void lambda_matrix_col_exchange (lambda_matrix, int, int, int); void lambda_matrix_col_add (lambda_matrix, int, int, int, int); void lambda_matrix_col_negate (lambda_matrix, int, int); void lambda_matrix_col_mc (lambda_matrix, int, int, int); -int lambda_matrix_inverse (lambda_matrix, lambda_matrix, int); +int lambda_matrix_inverse (lambda_matrix, lambda_matrix, int, struct obstack *); void lambda_matrix_hermite (lambda_matrix, int, lambda_matrix, lambda_matrix); void lambda_matrix_left_hermite (lambda_matrix, int, int, lambda_matrix, lambda_matrix); void lambda_matrix_right_hermite (lambda_matrix, int, int, lambda_matrix, lambda_matrix); @@ -191,13 +189,14 @@ void lambda_matrix_project_to_null (lambda_matrix, int, int, int, lambda_vector); void print_lambda_matrix (FILE *, lambda_matrix, int, int); -lambda_trans_matrix lambda_trans_matrix_new (int, int); +lambda_trans_matrix lambda_trans_matrix_new (int, int, struct obstack *); bool lambda_trans_matrix_nonsingular_p (lambda_trans_matrix); bool lambda_trans_matrix_fullrank_p (lambda_trans_matrix); int lambda_trans_matrix_rank (lambda_trans_matrix); lambda_trans_matrix lambda_trans_matrix_basis (lambda_trans_matrix); lambda_trans_matrix lambda_trans_matrix_padding (lambda_trans_matrix); -lambda_trans_matrix lambda_trans_matrix_inverse (lambda_trans_matrix); +lambda_trans_matrix lambda_trans_matrix_inverse (lambda_trans_matrix, + struct obstack *); void print_lambda_trans_matrix (FILE *, lambda_trans_matrix); void lambda_matrix_vector_mult (lambda_matrix, int, int, lambda_vector, lambda_vector); diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index e3deb9c8b06..cb87143e4ac 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -164,6 +164,23 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge, bitpack_delete (bp); } +/* Return true when node is reachable from other partition. */ + +static bool +reachable_from_other_partition_p (struct cgraph_node *node, cgraph_node_set set) +{ + struct cgraph_edge *e; + if (node->needed) + return true; + if (!node->analyzed) + return false; + if (node->global.inlined_to) + return false; + for (e = node->callers; e; e = e->next_caller) + if (!cgraph_node_in_set_p (e->caller, set)) + return true; + return false; +} /* Output the cgraph NODE to OB. ENCODER is used to find the reference number of NODE->inlined_to. SET is the set of nodes we @@ -183,6 +200,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, unsigned local, externally_visible, inlinable, analyzed; bool boundary_p, wrote_decl_p; intptr_t ref; + bool in_other_partition = false; boundary_p = !cgraph_node_in_set_p (node, set); wrote_decl_p = bitmap_bit_p (written_decls, DECL_UID (node->decl)); @@ -228,19 +246,17 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, local static nodes to prevent clashes with other local statics. */ if (boundary_p) { - /* Inline clones can not be part of boundary. */ - gcc_assert (!node->global.inlined_to); - local = 0; - externally_visible = 1; - inlinable = 0; + /* Inline clones can not be part of boundary. + gcc_assert (!node->global.inlined_to); + + FIXME: At the moment they can be, when partition contains an inline + clone that is clone of inline clone from outside partition. We can + reshape the clone tree and make other tree to be the root, but it + needs a bit extra work and will be promplty done by cgraph_remove_node + after reading back. */ + in_other_partition = 1; analyzed = 0; } - else if (lto_forced_extern_inline_p (node->decl)) - { - local = 1; - externally_visible = 0; - inlinable = 1; - } lto_output_uleb128_stream (ob->main_stream, wrote_decl_p); @@ -263,8 +279,10 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, bp_pack_value (bp, node->address_taken, 1); bp_pack_value (bp, node->abstract_and_needed, 1); bp_pack_value (bp, node->reachable, 1); + bp_pack_value (bp, analyzed && reachable_from_other_partition_p (node, set), 1); bp_pack_value (bp, node->lowered, 1); bp_pack_value (bp, analyzed, 1); + bp_pack_value (bp, in_other_partition, 1); bp_pack_value (bp, node->process, 1); bp_pack_value (bp, node->alias, 1); bp_pack_value (bp, node->finalized_by_frontend, 1); @@ -306,7 +324,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, lto_output_sleb128_stream (ob->main_stream, node->global.estimated_growth); lto_output_uleb128_stream (ob->main_stream, node->global.inlined); - if (node->same_comdat_group) + if (node->same_comdat_group && !boundary_p) { ref = lto_cgraph_encoder_lookup (encoder, node->same_comdat_group); gcc_assert (ref != LCC_NOT_FOUND); @@ -371,6 +389,15 @@ output_profile_summary (struct lto_simple_output_block *ob) lto_output_uleb128_stream (ob->main_stream, 0); } +/* Add NODE into encoder as well as nodes it is cloned from. + Do it in a way so clones appear first. */ +static void +add_node_to (lto_cgraph_encoder_t encoder, struct cgraph_node *node) +{ + if (node->clone_of) + add_node_to (encoder, node->clone_of); + lto_cgraph_encoder_encode (encoder, node); +} /* Output the part of the cgraph in SET. */ @@ -404,7 +431,7 @@ output_cgraph (cgraph_node_set set) for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi)) { node = csi_node (csi); - lto_cgraph_encoder_encode (encoder, node); + add_node_to (encoder, node); } /* Go over all the nodes again to include callees that are not in @@ -419,34 +446,14 @@ output_cgraph (cgraph_node_set set) { /* We should have moved all the inlines. */ gcc_assert (!callee->global.inlined_to); - lto_cgraph_encoder_encode (encoder, callee); - /* Also with each included function include all other functions - in the same comdat group. */ - if (callee->same_comdat_group) - { - struct cgraph_node *next; - for (next = callee->same_comdat_group; - next != callee; - next = next->same_comdat_group) - if (!cgraph_node_in_set_p (next, set)) - lto_cgraph_encoder_encode (encoder, next); - } + add_node_to (encoder, callee); } } - /* Also with each included function include all other functions - in the same comdat group. */ - if (node->same_comdat_group) - { - struct cgraph_node *next; - for (next = node->same_comdat_group; - next != node; - next = next->same_comdat_group) - if (!cgraph_node_in_set_p (next, set)) - lto_cgraph_encoder_encode (encoder, next); - } } - /* Write out the nodes. */ + /* Write out the nodes. We must first output a node and then its clones, + otherwise at a time reading back the node there would be nothing to clone + from. */ n_nodes = lto_cgraph_encoder_size (encoder); for (i = 0; i < n_nodes; i++) { @@ -530,8 +537,10 @@ input_overwrite_node (struct lto_file_decl_data *file_data, node->address_taken = bp_unpack_value (bp, 1); node->abstract_and_needed = bp_unpack_value (bp, 1); node->reachable = bp_unpack_value (bp, 1); + node->reachable_from_other_partition = bp_unpack_value (bp, 1); node->lowered = bp_unpack_value (bp, 1); node->analyzed = bp_unpack_value (bp, 1); + node->in_other_partition = bp_unpack_value (bp, 1); node->process = bp_unpack_value (bp, 1); node->alias = bp_unpack_value (bp, 1); node->finalized_by_frontend = bp_unpack_value (bp, 1); diff --git a/gcc/lto-section-in.c b/gcc/lto-section-in.c index 9277b12005f..4f2ae4ff37f 100644 --- a/gcc/lto-section-in.c +++ b/gcc/lto-section-in.c @@ -55,7 +55,6 @@ const char *lto_section_name[LTO_N_SECTION_TYPES] = "ipa_pure_const", "ipa_reference", "symtab", - "wpa_fixup", "opts" }; diff --git a/gcc/lto-section-out.c b/gcc/lto-section-out.c index 895394f3a1b..d603c069ed4 100644 --- a/gcc/lto-section-out.c +++ b/gcc/lto-section-out.c @@ -50,48 +50,6 @@ static VEC(lto_out_decl_state_ptr, heap) *decl_state_stack; generate the decl directory later. */ VEC(lto_out_decl_state_ptr, heap) *lto_function_decl_states; - -/* Bitmap indexed by DECL_UID to indicate if a function needs to be - forced extern inline. */ -static bitmap forced_extern_inline; - -/* Initialize states for determining which function decls to be ouput - as extern inline, regardless of the decls' own attributes. */ - -void -lto_new_extern_inline_states (void) -{ - forced_extern_inline = lto_bitmap_alloc (); -} - -/* Releasing resources use for states to determine which function decls - to be ouput as extern inline */ - -void -lto_delete_extern_inline_states (void) -{ - lto_bitmap_free (forced_extern_inline); - forced_extern_inline = NULL; -} - -/* Force all the functions in DECLS to be output as extern inline. - DECLS is a bitmap indexed by DECL_UID. */ - -void -lto_force_functions_extern_inline (bitmap decls) -{ - bitmap_ior_into (forced_extern_inline, decls); -} - -/* Return true if FN_DECL is a function which should be emitted as - extern inline. */ - -bool -lto_forced_extern_inline_p (tree fn_decl) -{ - return bitmap_bit_p (forced_extern_inline, DECL_UID (fn_decl)); -} - /* Returns a hash code for P. */ hashval_t diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index f375282beac..c9220254db9 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -2147,7 +2147,8 @@ struct ipa_opt_pass_d pass_ipa_lto_gimple_out = NULL, /* generate_summary */ lto_output, /* write_summary */ NULL, /* read_summary */ - NULL, /* function_read_summary */ + lto_output, /* write_optimization_summary */ + NULL, /* read_optimization_summary */ NULL, /* stmt_fixup */ 0, /* TODOs */ NULL, /* function_transform */ @@ -2565,7 +2566,8 @@ struct ipa_opt_pass_d pass_ipa_lto_finish_out = NULL, /* generate_summary */ produce_asm_for_decls, /* write_summary */ NULL, /* read_summary */ - NULL, /* function_read_summary */ + produce_asm_for_decls, /* write_optimization_summary */ + NULL, /* read_optimization_summary */ NULL, /* stmt_fixup */ 0, /* TODOs */ NULL, /* function_transform */ diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c index 0b44845bceb..46d61548e12 100644 --- a/gcc/lto-streamer.c +++ b/gcc/lto-streamer.c @@ -169,9 +169,6 @@ lto_get_section_name (int section_type, const char *name) case LTO_section_ipa_reference: return concat (LTO_SECTION_NAME_PREFIX, ".reference", NULL); - case LTO_section_wpa_fixup: - return concat (LTO_SECTION_NAME_PREFIX, ".wpa_fixup", NULL); - case LTO_section_opts: return concat (LTO_SECTION_NAME_PREFIX, ".opts", NULL); diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 6ac8ef8a2a8..a9544b5642a 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -770,10 +770,6 @@ extern void lto_push_out_decl_state (struct lto_out_decl_state *); extern struct lto_out_decl_state *lto_pop_out_decl_state (void); extern void lto_record_function_out_decl_state (tree, struct lto_out_decl_state *); -extern void lto_new_extern_inline_states (void); -extern void lto_delete_extern_inline_states (void); -extern void lto_force_functions_extern_inline (bitmap decls); -extern bool lto_forced_extern_inline_p (tree fn_decl); /* In lto-streamer.c. */ diff --git a/gcc/lto-wpa-fixup.c b/gcc/lto-wpa-fixup.c deleted file mode 100644 index 0839aa9df9a..00000000000 --- a/gcc/lto-wpa-fixup.c +++ /dev/null @@ -1,282 +0,0 @@ -/* Write and read any fix-up information generated by the WPA mode. - - Copyright 2009 Free Software Foundation, Inc. - Contributed by Doug Kwan - -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 -. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "toplev.h" -#include "tree.h" -#include "expr.h" -#include "flags.h" -#include "cgraph.h" -#include "function.h" -#include "diagnostic.h" -#include "vec.h" -#include "bitmap.h" -#include "timevar.h" -#include "tree-flow.h" -#include "tree-pass.h" -#include "lto-streamer.h" - -/* LTO fix-up. - - In WPA mode, LTO cannot access function bodies. Some modifications in - IR require additional updates in function bodies, which are not possible - in WPA mode. So we write out information about these modifications for - LTRANS to fix up the function bodies accordingly. */ - -/* The vectors records function DECLs having multiple copies with different - exception throwing attributes. We do not mark a DECL if all copies of it - have the same exception throwing attribute. */ -static bitmap lto_nothrow_fndecls; - -/* We need to fix up GIMPLE bodies due to changes in exception setting. - Consider this example: - - a.h: - class a { - public: - a(); - ~a(); - }; - - main.cc: - #include "a.h" - - int - main (int argc, char **argv) - { - a x; - return 0; - } - - a.cc: - #include "a.h" - a::a() {} - a::~a() {} - - When main.cc is compiled, gcc only sees the constructor declaration, so - the constructor and hence the call to it are marked as exception throwing. - When a.cc is compiled, the body of the constructor is available and is - obviously not exception throwing. Thus DECL of a::a in a.o has the NOTHROW - attribute. When LTO runs, two DECLs of a::a with different exception - attributes are merged. We want the merged DECL to be not exception - throwing for better generated code. To do that, we need to fix up any - function calls that have been marked as exception throwing. */ - -/* Fix up all the call statements whose target fndecls might have changed - to NOTHROW. Note that this problem is not WPA specific. We can also - run into this problem in normal LTO with multiple input files. */ - -void -lto_fixup_nothrow_decls (void) -{ - struct cgraph_node *node; - struct cgraph_edge *edge; - struct function *caller_function; - gimple call_stmt; - - /* Quit if we are in WPA mode or have not marked any DECLs. */ - if (flag_wpa || !lto_nothrow_fndecls) - return; - - /* For each node that has been marked, go over all call edges to it. */ - for (node = cgraph_nodes; node; node = node->next) - if (bitmap_bit_p (lto_nothrow_fndecls, DECL_UID (node->decl))) - { - gcc_assert (TREE_NOTHROW (node->decl)); - for (edge = node->callers; edge; edge = edge->next_caller) - { - caller_function = DECL_STRUCT_FUNCTION (edge->caller->decl); - call_stmt = edge->call_stmt; - gcc_assert (call_stmt); - if (lookup_stmt_eh_lp_fn (caller_function, call_stmt) != 0) - remove_stmt_from_eh_lp_fn (caller_function, call_stmt); - } - } -} - -/* Mark FNDECL as becoming not exception throwing. */ - -void -lto_mark_nothrow_fndecl (tree fndecl) -{ - gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL); - if (!lto_nothrow_fndecls) - lto_nothrow_fndecls = lto_bitmap_alloc (); - - bitmap_set_bit (lto_nothrow_fndecls, DECL_UID (fndecl)); -} - -/* Write out fix-up information. Currently the only WPA fix-up - information is the list of DECLs marked as not exception throwing. SET - is a cgraph node set whose fix-up information is to be written. */ - -static void -lto_output_wpa_fixup (cgraph_node_set set) -{ - struct lto_simple_output_block *ob; - cgraph_node_set_iterator csi; - tree fndecl; - bitmap seen_decls; - VEC(tree, heap) *decls = NULL; - unsigned HOST_WIDE_INT i, count; - - ob = lto_create_simple_output_block (LTO_section_wpa_fixup); - - /* Accumulate the DECLs to be written out. Since we do not want - duplicates, we need to use a bitmap and a vector to save the - DECLs we want. Note that we need to check if lto_nothrow_fndecls - is NULL. This happens when no DECL has been marked. */ - seen_decls = lto_bitmap_alloc (); - if (lto_nothrow_fndecls) - for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi)) - { - struct cgraph_edge *e; - struct cgraph_node *n; - - n = csi_node (csi); - fndecl = n->decl; - - /* Check if the N's function is in the set of nothrow functions. */ - if (!bitmap_bit_p (seen_decls, DECL_UID (fndecl))) - { - bitmap_set_bit (seen_decls, (DECL_UID (fndecl))); - if (bitmap_bit_p (lto_nothrow_fndecls, DECL_UID (fndecl))) - VEC_safe_push (tree, heap, decls, fndecl); - } - - /* Now check the callees and also add them if they are nothrow. This - is needed because node N may end up in a different partition than - its callees. In which case, when the file holding N is compiled, - the calls it makes to nothrow functions will not be fixed up, - causing verification issues. */ - for (e = n->callees; e; e = e->next_callee) - { - fndecl = e->callee->decl; - if (!bitmap_bit_p (seen_decls, DECL_UID (fndecl))) - { - bitmap_set_bit (seen_decls, (DECL_UID (fndecl))); - if (bitmap_bit_p (lto_nothrow_fndecls, DECL_UID (fndecl))) - VEC_safe_push (tree, heap, decls, fndecl); - } - } - } - - /* Write out number of DECLs, followed by the DECLs. */ - count = VEC_length (tree, decls); - lto_output_uleb128_stream (ob->main_stream, count); - for (i = 0; i < count; i++) - { - fndecl = VEC_index (tree, decls, i); - lto_output_fn_decl_index (ob->decl_state, ob->main_stream, fndecl); - } - - /* Release resources. */ - lto_destroy_simple_output_block (ob); - VEC_free(tree, heap, decls); - lto_bitmap_free (seen_decls); -} - -/* Read in WPA fix-up information from one file. FILE_DATA points to - DECL information of the file where as IB is the input block for the - WPA fix-up section. */ - -static void -lto_input_wpa_fixup_1 (struct lto_file_decl_data *file_data, - struct lto_input_block *ib) -{ - unsigned HOST_WIDE_INT i, count, decl_index; - tree fndecl; - - count = lto_input_uleb128 (ib); - for (i = 0; i < count; i++) - { - decl_index = lto_input_uleb128 (ib); - fndecl = lto_file_decl_data_get_fn_decl (file_data, decl_index); - lto_mark_nothrow_fndecl (fndecl); - } -} - -/* Read in WPA fix-up information. */ - -static void -lto_input_wpa_fixup (void) -{ - struct lto_file_decl_data ** file_data_vec - = lto_get_file_decl_data (); - struct lto_file_decl_data * file_data; - int i = 0; - - /* Fix up information is only used in LTRANS mode. */ - if (!flag_ltrans) - return; - - while ((file_data = file_data_vec[i++])) - { - const char *data; - size_t len; - struct lto_input_block *ib - = lto_create_simple_input_block (file_data, LTO_section_wpa_fixup, - &data, &len); - - lto_input_wpa_fixup_1 (file_data, ib); - lto_destroy_simple_input_block (file_data, LTO_section_wpa_fixup, ib, - data, len); - } -} - -/* Gate function for all lto streaming passes. */ - -static bool -gate_wpa_fixup (void) -{ - return (flag_wpa || flag_ltrans) && gate_lto_out (); -} - -struct ipa_opt_pass_d pass_ipa_lto_wpa_fixup = -{ - { - IPA_PASS, - "lto_wpa_fixup", /* name */ - gate_wpa_fixup, /* gate */ - NULL, /* execute */ - NULL, /* sub */ - NULL, /* next */ - 0, /* static_pass_number */ - TV_WHOPR_WPA_FIXUP, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ - }, - NULL, /* generate_summary */ - lto_output_wpa_fixup, /* write_summary */ - lto_input_wpa_fixup, /* read_summary */ - NULL, /* function_read_summary */ - NULL, /* stmt_fixup */ - 0, /* TODOs */ - NULL, /* function_transform */ - NULL /* variable_transform */ -}; - diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 20b89d69761..2ce58d742f3 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,31 @@ +2010-04-21 Jan Hubicka + + * lto.c (lto_fixup_tree): Do not call wpa fixup. + (materialize_cgraph): Likewise. + +2010-04-21 Jan Hubicka + + * lto.c (lto_wpa_write_files): Update. + (read_cgraph_and_symbols): Be more verbose. + (materialize_cgraph): Likewise. + (do_whole_program_analysis): Likewise. + +2010-04-21 Jan Hubicka + + * lto.c (globalize_cross_file_statics): When function has address taken, + it needs to be public. + +2010-04-20 Jan Hubicka + + * lto.c (lto_add_inline_clones): Do not track inlined_decls. + (lto_add_all_inlinees): Likewise. + (lto_wpa_write_files): Likewise. + +2010-04-18 Eric Botcazou + + * lto-lang.c (lto_init): Remove second argument in call to + build_common_tree_nodes. + 2010-04-16 Rainer Orth * lto-elf.c [!HAVE_ELF_GETSHDRSTRNDX] (elf_getshdrstrndx): New diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c index 05577a29371..aea5ab22d35 100644 --- a/gcc/lto/lto-lang.c +++ b/gcc/lto/lto-lang.c @@ -1039,7 +1039,7 @@ lto_init (void) linemap_add (line_table, LC_RENAME, 0, NULL, 0); /* Create the basic integer types. */ - build_common_tree_nodes (flag_signed_char, /*signed_sizetype=*/false); + build_common_tree_nodes (flag_signed_char); /* Share char_type_node with whatever would be the default for the target. char_type_node will be used for internal types such as diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index de53a09f87d..115d1cc5678 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -554,6 +554,10 @@ lto_1_to_1_map (void) for (node = cgraph_nodes; node; node = node->next) { + /* We will get proper partition based on function they are inlined to or + cloned from. */ + if (node->global.inlined_to || node->clone_of) + continue; /* We only need to partition the nodes that we read from the gimple bytecode files. */ file_data = node->local.lto_file_data; @@ -589,22 +593,19 @@ finish: static void lto_add_inline_clones (cgraph_node_set set, struct cgraph_node *node, - bitmap original_decls, bitmap inlined_decls) + bitmap original_decls) { struct cgraph_node *callee; struct cgraph_edge *edge; cgraph_node_set_add (set, node); - if (!bitmap_bit_p (original_decls, DECL_UID (node->decl))) - bitmap_set_bit (inlined_decls, DECL_UID (node->decl)); - /* Check to see if NODE has any inlined callee. */ for (edge = node->callees; edge != NULL; edge = edge->next_callee) { callee = edge->callee; if (callee->global.inlined_to != NULL) - lto_add_inline_clones (set, callee, original_decls, inlined_decls); + lto_add_inline_clones (set, callee, original_decls); } } @@ -612,14 +613,13 @@ lto_add_inline_clones (cgraph_node_set set, struct cgraph_node *node, information in the callgraph. Returns a bitmap of decls that have been inlined into SET indexed by UID. */ -static bitmap +static void lto_add_all_inlinees (cgraph_node_set set) { cgraph_node_set_iterator csi; struct cgraph_node *node; bitmap original_nodes = lto_bitmap_alloc (); bitmap original_decls = lto_bitmap_alloc (); - bitmap inlined_decls = lto_bitmap_alloc (); bool changed; /* We are going to iterate SET while adding to it, mark all original @@ -659,19 +659,17 @@ lto_add_all_inlinees (cgraph_node_set set) } while (changed); - /* Transitively add to SET all the inline clones for every node that - has been inlined. */ - for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi)) - { - node = csi_node (csi); - if (bitmap_bit_p (original_nodes, node->uid)) - lto_add_inline_clones (set, node, original_decls, inlined_decls); - } + /* Transitively add to SET all the inline clones for every node that + has been inlined. */ + for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi)) + { + node = csi_node (csi); + if (bitmap_bit_p (original_nodes, node->uid)) + lto_add_inline_clones (set, node, original_decls); + } lto_bitmap_free (original_nodes); lto_bitmap_free (original_decls); - - return inlined_decls; } /* Owing to inlining, we may need to promote a file-scope variable @@ -762,7 +760,8 @@ globalize_cross_file_statics (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, } else if (TREE_CODE (t) == FUNCTION_DECL && !TREE_PUBLIC (t)) { - if (!cgraph_node_in_set_p (cgraph_node (t), context->set)) + if (!cgraph_node_in_set_p (cgraph_node (t), context->set) + || cgraph_node (t)->address_taken) { /* This file-scope static function is reachable from a set which does not contain the function DECL. Make it global @@ -1000,8 +999,6 @@ lto_wpa_write_files (void) unsigned i, n_sets, last_out_file_ix, num_out_files; lto_file *file; cgraph_node_set set; - bitmap decls; - VEC(bitmap,heap) *inlined_decls = NULL; timevar_push (TV_WHOPR_WPA); @@ -1011,8 +1008,7 @@ lto_wpa_write_files (void) compiled by LTRANS. */ for (i = 0; VEC_iterate (cgraph_node_set, lto_cgraph_node_sets, i, set); i++) { - decls = lto_add_all_inlinees (set); - VEC_safe_push (bitmap, heap, inlined_decls, decls); + lto_add_all_inlinees (set); lto_stats.num_output_cgraph_nodes += VEC_length (cgraph_node_ptr, set->nodes); } @@ -1049,13 +1045,8 @@ lto_wpa_write_files (void) fatal_error ("lto_elf_file_open() failed"); lto_set_current_out_file (file); - lto_new_extern_inline_states (); - decls = VEC_index (bitmap, inlined_decls, i); - lto_force_functions_extern_inline (decls); - - ipa_write_summaries_of_cgraph_node_set (set); - lto_delete_extern_inline_states (); + ipa_write_optimization_summaries (set); lto_set_current_out_file (NULL); lto_elf_file_close (file); @@ -1068,10 +1059,6 @@ lto_wpa_write_files (void) output_files[last_out_file_ix] = NULL; - for (i = 0; VEC_iterate (bitmap, inlined_decls, i, decls); i++) - lto_bitmap_free (decls); - VEC_free (bitmap, heap, inlined_decls); - timevar_pop (TV_WHOPR_WPA_IO); return output_files; @@ -1574,28 +1561,6 @@ lto_fixup_tree (tree *tp, int *walk_subtrees, void *data) if (t != prevailing) { - if (TREE_CODE (t) == FUNCTION_DECL - && TREE_NOTHROW (prevailing) != TREE_NOTHROW (t)) - { - /* If the prevailing definition does not throw but the - declaration (T) was considered throwing, then we - simply add PREVAILING to the list of throwing - functions. However, if the opposite is true, then - the call to PREVAILING was generated assuming that - the function didn't throw, which means that CFG - cleanup may have removed surrounding try/catch - regions. - - Note that we currently accept these cases even when - they occur within a single file. It's certainly a - user error, but we silently allow the compiler to - remove surrounding try/catch regions. Perhaps we - could emit a warning here, instead of silently - accepting the conflicting declaration. */ - if (TREE_NOTHROW (prevailing)) - lto_mark_nothrow_fndecl (prevailing); - } - /* Also replace t with prevailing defintion. We don't want to insert the other defintion in the seen set as we want to replace all instances of it. */ @@ -1835,10 +1800,18 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames) gcc_assert (num_objects == nfiles); } + if (!quiet_flag) + fprintf (stderr, "Reading object files:"); + /* Read all of the object files specified on the command line. */ for (i = 0, last_file_ix = 0; i < nfiles; ++i) { struct lto_file_decl_data *file_data = NULL; + if (!quiet_flag) + { + fprintf (stderr, " %s", fnames[i]); + fflush (stderr); + } current_lto_file = lto_elf_file_open (fnames[i], false); if (!current_lto_file) @@ -1865,9 +1838,15 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames) /* Each pass will set the appropriate timer. */ timevar_pop (TV_IPA_LTO_DECL_IO); + if (!quiet_flag) + fprintf (stderr, "\nReading the callgraph\n"); + /* Read the callgraph. */ input_cgraph (); + if (!quiet_flag) + fprintf (stderr, "Merging declarations\n"); + /* Merge global decls. */ lto_symtab_merge_decls (); @@ -1875,25 +1854,21 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames) lto_fixup_decls (all_file_decl_data); free_gimple_type_tables (); + if (!quiet_flag) + fprintf (stderr, "Reading summaries\n"); + /* Read the IPA summary data. */ - ipa_read_summaries (); + if (flag_ltrans) + ipa_read_optimization_summaries (); + else + ipa_read_summaries (); /* Finally merge the cgraph according to the decl merging decisions. */ lto_symtab_merge_cgraph_nodes (); - /* Mark cgraph nodes needed in the merged cgraph - This normally happens in whole-program pass, but for - ltrans the pass was already run at WPA phase. - - FIXME: This is not valid way to do so; nodes can be needed - for non-obvious reasons. We should stream the flags from WPA - phase. */ if (flag_ltrans) for (node = cgraph_nodes; node; node = node->next) { - if (!node->global.inlined_to - && cgraph_decide_is_function_needed (node, node->decl)) - cgraph_mark_needed_node (node); /* FIXME: ipa_transforms_to_apply holds list of passes that have optimization summaries computed and needs to apply changes. At the moment WHOPR only supports inlining, so we can push it here by hand. In future we need to stream @@ -1932,6 +1907,11 @@ materialize_cgraph (void) unsigned i; timevar_id_t lto_timer; + if (!quiet_flag) + fprintf (stderr, + flag_wpa ? "Materializing decls:" : "Reading function bodies:"); + + /* Now that we have input the cgraph, we need to clear all of the aux nodes and read the functions if we are not running in WPA mode. */ timevar_push (TV_IPA_LTO_GIMPLE_IO); @@ -1950,6 +1930,7 @@ materialize_cgraph (void) if (node->local.lto_file_data && !DECL_IS_BUILTIN (node->decl)) { + announce_function (node->decl); lto_materialize_function (node); lto_stats.num_input_cgraph_nodes++; } @@ -1971,8 +1952,8 @@ materialize_cgraph (void) for (i = 0; VEC_iterate (tree, lto_global_var_decls, i, decl); i++) rest_of_decl_compilation (decl, 1, 0); - /* Fix up any calls to DECLs that have become not exception throwing. */ - lto_fixup_nothrow_decls (); + if (!quiet_flag) + fprintf (stderr, "\n"); timevar_pop (lto_timer); } @@ -1986,9 +1967,6 @@ do_whole_program_analysis (void) { char **output_files; size_t i; - struct cgraph_node *node; - - lto_1_to_1_map (); /* Note that since we are in WPA mode, materialize_cgraph will not actually read in all the function bodies. It only materializes @@ -1998,20 +1976,12 @@ do_whole_program_analysis (void) /* Reading in the cgraph uses different timers, start timing WPA now. */ timevar_push (TV_WHOPR_WPA); - /* FIXME lto. Hack. We should use the IPA passes. There are a - number of issues with this now. 1. There is no convenient way to - do this. 2. Some passes may depend on properties that requires - the function bodies to compute. */ cgraph_function_flags_ready = true; bitmap_obstack_initialize (NULL); ipa_register_cgraph_hooks (); + cgraph_state = CGRAPH_STATE_IPA_SSA; - /* Reset inlining information before running IPA inliner. */ - for (node = cgraph_nodes; node; node = node->next) - reset_inline_failed (node); - - /* FIXME lto. We should not call this function directly. */ - pass_ipa_inline.pass.execute (); + execute_ipa_pass_list (all_regular_ipa_passes); verify_cgraph (); bitmap_obstack_release (NULL); @@ -2019,7 +1989,16 @@ do_whole_program_analysis (void) /* We are about to launch the final LTRANS phase, stop the WPA timer. */ timevar_pop (TV_WHOPR_WPA); + lto_1_to_1_map (); + + if (!quiet_flag) + { + fprintf (stderr, "\nStreaming out"); + fflush (stderr); + } output_files = lto_wpa_write_files (); + if (!quiet_flag) + fprintf (stderr, "\n"); /* Show the LTO report before launching LTRANS. */ if (flag_lto_report) diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 9ab5c5294ab..cc36cb51bc5 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -1433,10 +1433,6 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) break; case OMP_CLAUSE_COPYPRIVATE: - if (ctx->outer) - scan_omp_op (&OMP_CLAUSE_DECL (c), ctx->outer); - /* FALLTHRU */ - case OMP_CLAUSE_COPYIN: decl = OMP_CLAUSE_DECL (c); by_ref = use_pointer_for_field (decl, NULL); @@ -2702,7 +2698,7 @@ lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist, for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c)) { - tree var, ref, x; + tree var, new_var, ref, x; bool by_ref; location_t clause_loc = OMP_CLAUSE_LOCATION (c); @@ -2713,17 +2709,29 @@ lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist, by_ref = use_pointer_for_field (var, NULL); ref = build_sender_ref (var, ctx); - x = lookup_decl_in_outer_ctx (var, ctx); - x = by_ref ? build_fold_addr_expr_loc (clause_loc, x) : x; + x = new_var = lookup_decl_in_outer_ctx (var, ctx); + if (by_ref) + { + x = build_fold_addr_expr_loc (clause_loc, new_var); + x = fold_convert_loc (clause_loc, TREE_TYPE (ref), x); + } gimplify_assign (ref, x, slist); - ref = build_receiver_ref (var, by_ref, ctx); + ref = build_receiver_ref (var, false, ctx); + if (by_ref) + { + ref = fold_convert_loc (clause_loc, + build_pointer_type (TREE_TYPE (new_var)), + ref); + ref = build_fold_indirect_ref_loc (clause_loc, ref); + } if (is_reference (var)) { + ref = fold_convert_loc (clause_loc, TREE_TYPE (new_var), ref); ref = build_fold_indirect_ref_loc (clause_loc, ref); - var = build_fold_indirect_ref_loc (clause_loc, var); + new_var = build_fold_indirect_ref_loc (clause_loc, new_var); } - x = lang_hooks.decls.omp_clause_assign_op (c, var, ref); + x = lang_hooks.decls.omp_clause_assign_op (c, new_var, ref); gimplify_and_add (x, rlist); } } diff --git a/gcc/optabs.c b/gcc/optabs.c index 555e2562a45..5a3e61092b9 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -2928,7 +2928,7 @@ expand_absneg_bit (enum rtx_code code, enum machine_mode mode, const struct real_format *fmt; int bitpos, word, nwords, i; enum machine_mode imode; - HOST_WIDE_INT hi, lo; + double_int mask; rtx temp, insns; /* The format has to have a simple sign bit. */ @@ -2964,18 +2964,9 @@ expand_absneg_bit (enum rtx_code code, enum machine_mode mode, nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD; } - if (bitpos < HOST_BITS_PER_WIDE_INT) - { - hi = 0; - lo = (HOST_WIDE_INT) 1 << bitpos; - } - else - { - hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT); - lo = 0; - } + mask = double_int_setbit (double_int_zero, bitpos); if (code == ABS) - lo = ~lo, hi = ~hi; + mask = double_int_not (mask); if (target == 0 || target == op0) target = gen_reg_rtx (mode); @@ -2993,7 +2984,7 @@ expand_absneg_bit (enum rtx_code code, enum machine_mode mode, { temp = expand_binop (imode, code == ABS ? and_optab : xor_optab, op0_piece, - immed_double_const (lo, hi, imode), + immed_double_int_const (mask, imode), targ_piece, 1, OPTAB_LIB_WIDEN); if (temp != targ_piece) emit_move_insn (targ_piece, temp); @@ -3011,7 +3002,7 @@ expand_absneg_bit (enum rtx_code code, enum machine_mode mode, { temp = expand_binop (imode, code == ABS ? and_optab : xor_optab, gen_lowpart (imode, op0), - immed_double_const (lo, hi, imode), + immed_double_int_const (mask, imode), gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN); target = lowpart_subreg_maybe_copy (mode, temp, imode); @@ -3562,7 +3553,7 @@ expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target, } else { - HOST_WIDE_INT hi, lo; + double_int mask; if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD) { @@ -3584,20 +3575,10 @@ expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target, op1 = operand_subword_force (op1, word, mode); } - if (bitpos < HOST_BITS_PER_WIDE_INT) - { - hi = 0; - lo = (HOST_WIDE_INT) 1 << bitpos; - } - else - { - hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT); - lo = 0; - } + mask = double_int_setbit (double_int_zero, bitpos); - sign = gen_reg_rtx (imode); sign = expand_binop (imode, and_optab, op1, - immed_double_const (lo, hi, imode), + immed_double_int_const (mask, imode), NULL_RTX, 1, OPTAB_LIB_WIDEN); } @@ -3641,7 +3622,7 @@ expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target, int bitpos, bool op0_is_abs) { enum machine_mode imode; - HOST_WIDE_INT hi, lo; + double_int mask; int word, nwords, i; rtx temp, insns; @@ -3665,16 +3646,7 @@ expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target, nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD; } - if (bitpos < HOST_BITS_PER_WIDE_INT) - { - hi = 0; - lo = (HOST_WIDE_INT) 1 << bitpos; - } - else - { - hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT); - lo = 0; - } + mask = double_int_setbit (double_int_zero, bitpos); if (target == 0 || target == op0 || target == op1) target = gen_reg_rtx (mode); @@ -3691,13 +3663,15 @@ expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target, if (i == word) { if (!op0_is_abs) - op0_piece = expand_binop (imode, and_optab, op0_piece, - immed_double_const (~lo, ~hi, imode), - NULL_RTX, 1, OPTAB_LIB_WIDEN); + op0_piece + = expand_binop (imode, and_optab, op0_piece, + immed_double_int_const (double_int_not (mask), + imode), + NULL_RTX, 1, OPTAB_LIB_WIDEN); op1 = expand_binop (imode, and_optab, operand_subword_force (op1, i, mode), - immed_double_const (lo, hi, imode), + immed_double_int_const (mask, imode), NULL_RTX, 1, OPTAB_LIB_WIDEN); temp = expand_binop (imode, ior_optab, op0_piece, op1, @@ -3717,13 +3691,14 @@ expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target, else { op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1), - immed_double_const (lo, hi, imode), + immed_double_int_const (mask, imode), NULL_RTX, 1, OPTAB_LIB_WIDEN); op0 = gen_lowpart (imode, op0); if (!op0_is_abs) op0 = expand_binop (imode, and_optab, op0, - immed_double_const (~lo, ~hi, imode), + immed_double_int_const (double_int_not (mask), + imode), NULL_RTX, 1, OPTAB_LIB_WIDEN); temp = expand_binop (imode, ior_optab, op0, op1, diff --git a/gcc/optabs.h b/gcc/optabs.h index 0161d3e6d3b..0b72a516274 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -771,6 +771,9 @@ extern void expand_fix (rtx, rtx, int); /* Generate code for float to integral conversion. */ extern bool expand_sfix_optab (rtx, rtx, convert_optab); +/* Generate code for a widening multiply. */ +extern rtx expand_widening_mult (enum machine_mode, rtx, rtx, rtx, int, optab); + /* Return tree if target supports vector operations for COND_EXPR. */ bool expand_vec_cond_expr_p (tree, enum machine_mode); diff --git a/gcc/opts.c b/gcc/opts.c index 19d56348e2e..ce45e1cb0d5 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -1120,6 +1120,15 @@ decode_options (unsigned int argc, const char **argv) if (!PARAM_SET_P (PARAM_STACK_FRAME_GROWTH)) PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) = 40; } + if (flag_wpa || flag_ltrans) + { + /* These passes are not WHOPR compatible yet. */ + flag_ipa_cp = 0; + flag_ipa_reference = 0; + flag_ipa_type_escape = 0; + flag_ipa_pta = 0; + flag_ipa_struct_reorg = 0; + } if (flag_lto || flag_whopr) { diff --git a/gcc/passes.c b/gcc/passes.c index cbd605fb430..a6e5af50841 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -814,7 +814,6 @@ init_optimization_passes (void) p = &all_lto_gen_passes; NEXT_PASS (pass_ipa_lto_gimple_out); - NEXT_PASS (pass_ipa_lto_wpa_fixup); NEXT_PASS (pass_ipa_lto_finish_out); /* This must be the last LTO pass. */ *p = NULL; @@ -944,6 +943,7 @@ init_optimization_passes (void) NEXT_PASS (pass_forwprop); NEXT_PASS (pass_phiopt); NEXT_PASS (pass_fold_builtins); + NEXT_PASS (pass_optimize_widening_mul); NEXT_PASS (pass_tail_calls); NEXT_PASS (pass_rename_ssa_copies); NEXT_PASS (pass_uncprop); @@ -1487,10 +1487,20 @@ execute_one_ipa_transform_pass (struct cgraph_node *node, void execute_all_ipa_transforms (void) { + enum cgraph_state old_state = cgraph_state; struct cgraph_node *node; if (!cfun) return; node = cgraph_node (current_function_decl); + + /* Statement verification skip verification of nothorw when + state is IPA_SSA because we do not modify function bodies + after setting the flag on function. Instead we leave it + to fixup_cfg to do such a transformation. We need to temporarily + change the cgraph state so statement verifier before + transform do not fire. */ + cgraph_state = CGRAPH_STATE_IPA_SSA; + if (node->ipa_transforms_to_apply) { unsigned int i; @@ -1504,6 +1514,7 @@ execute_all_ipa_transforms (void) VEC_free (ipa_opt_pass, heap, node->ipa_transforms_to_apply); node->ipa_transforms_to_apply = NULL; } + cgraph_state = old_state; } /* Execute PASS. */ @@ -1674,8 +1685,8 @@ ipa_write_summaries_1 (cgraph_node_set set) struct lto_out_decl_state *state = lto_new_out_decl_state (); lto_push_out_decl_state (state); - if (!flag_wpa) - ipa_write_summaries_2 (all_regular_ipa_passes, set, state); + gcc_assert (!flag_wpa); + ipa_write_summaries_2 (all_regular_ipa_passes, set, state); ipa_write_summaries_2 (all_lto_gen_passes, set, state); gcc_assert (lto_get_out_decl_state () == state); @@ -1695,7 +1706,6 @@ ipa_write_summaries (void) if (!flag_generate_lto || errorcount || sorrycount) return; - lto_new_extern_inline_states (); set = cgraph_node_set_new (); /* Create the callgraph set in the same order used in @@ -1726,21 +1736,63 @@ ipa_write_summaries (void) } ipa_write_summaries_1 (set); - lto_delete_extern_inline_states (); free (order); ggc_free (set); } +/* Same as execute_pass_list but assume that subpasses of IPA passes + are local passes. If SET is not NULL, write out optimization summaries of + only those node in SET. */ + +static void +ipa_write_optimization_summaries_1 (struct opt_pass *pass, cgraph_node_set set, + struct lto_out_decl_state *state) +{ + while (pass) + { + struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *)pass; + gcc_assert (!current_function_decl); + gcc_assert (!cfun); + gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS); + if (pass->type == IPA_PASS + && ipa_pass->write_optimization_summary + && (!pass->gate || pass->gate ())) + { + /* If a timevar is present, start it. */ + if (pass->tv_id) + timevar_push (pass->tv_id); + + ipa_pass->write_optimization_summary (set); + + /* If a timevar is present, start it. */ + if (pass->tv_id) + timevar_pop (pass->tv_id); + } + + if (pass->sub && pass->sub->type != GIMPLE_PASS) + ipa_write_optimization_summaries_1 (pass->sub, set, state); -/* Write all the summaries for the cgraph nodes in SET. If SET is + pass = pass->next; + } +} + +/* Write all the optimization summaries for the cgraph nodes in SET. If SET is NULL, write out all summaries of all nodes. */ void -ipa_write_summaries_of_cgraph_node_set (cgraph_node_set set) +ipa_write_optimization_summaries (cgraph_node_set set) { - if (flag_generate_lto && !(errorcount || sorrycount)) - ipa_write_summaries_1 (set); + struct lto_out_decl_state *state = lto_new_out_decl_state (); + lto_push_out_decl_state (state); + + gcc_assert (flag_wpa); + ipa_write_optimization_summaries_1 (all_regular_ipa_passes, set, state); + ipa_write_optimization_summaries_1 (all_lto_gen_passes, set, state); + + gcc_assert (lto_get_out_decl_state () == state); + lto_pop_out_decl_state (); + lto_delete_out_decl_state (state); } /* Same as execute_pass_list but assume that subpasses of IPA passes @@ -1785,13 +1837,57 @@ ipa_read_summaries_1 (struct opt_pass *pass) void ipa_read_summaries (void) { - if (!flag_ltrans) - ipa_read_summaries_1 (all_regular_ipa_passes); + ipa_read_summaries_1 (all_regular_ipa_passes); ipa_read_summaries_1 (all_lto_gen_passes); } /* Same as execute_pass_list but assume that subpasses of IPA passes are local passes. */ + +static void +ipa_read_optimization_summaries_1 (struct opt_pass *pass) +{ + while (pass) + { + struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *) pass; + + gcc_assert (!current_function_decl); + gcc_assert (!cfun); + gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS); + + if (pass->gate == NULL || pass->gate ()) + { + if (pass->type == IPA_PASS && ipa_pass->read_optimization_summary) + { + /* If a timevar is present, start it. */ + if (pass->tv_id) + timevar_push (pass->tv_id); + + ipa_pass->read_optimization_summary (); + + /* Stop timevar. */ + if (pass->tv_id) + timevar_pop (pass->tv_id); + } + + if (pass->sub && pass->sub->type != GIMPLE_PASS) + ipa_read_optimization_summaries_1 (pass->sub); + } + pass = pass->next; + } +} + +/* Read all the summaries for all_regular_ipa_passes and all_lto_gen_passes. */ + +void +ipa_read_optimization_summaries (void) +{ + ipa_read_optimization_summaries_1 (all_regular_ipa_passes); + ipa_read_optimization_summaries_1 (all_lto_gen_passes); +} + +/* Same as execute_pass_list but assume that subpasses of IPA passes + are local passes. */ void execute_ipa_pass_list (struct opt_pass *pass) { diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog index 143944e6d50..058c7461290 100644 --- a/gcc/po/ChangeLog +++ b/gcc/po/ChangeLog @@ -1,3 +1,11 @@ +2010-04-20 Joseph Myers + + * es.po: Update. + +2010-04-19 Joseph Myers + + * zh_CN.po: Update. + 2010-04-16 Joseph Myers * be.po, da.po, de.po, el.po, es.po, fi.po, fr.po, id.po, ja.po, diff --git a/gcc/po/es.po b/gcc/po/es.po index 3ea755a7810..38ff5f4795a 100644 --- a/gcc/po/es.po +++ b/gcc/po/es.po @@ -1,4 +1,4 @@ -# Mensajes en español para gcc-4.5-b20100204 +# Mensajes en español para gcc-4.5.0 # Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is distributed under the same license as the gcc package. # Cristian Othón Martínez Vera , 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 @@ -7,15 +7,16 @@ # msgid "" msgstr "" -"Project-Id-Version: gcc 4.5-b20100204\n" +"Project-Id-Version: gcc 4.5.0\n" "Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n" "POT-Creation-Date: 2010-04-06 14:11+0000\n" -"PO-Revision-Date: 2010-02-05 15:29-0600\n" +"PO-Revision-Date: 2010-04-16 11:29-0500\n" "Last-Translator: Cristian Othón Martínez Vera \n" "Language-Team: Spanish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" #: c-decl.c:4573 c-pretty-print.c:403 c-typeck.c:5590 toplev.c:1652 #: cp/error.c:581 cp/error.c:854 @@ -640,25 +641,25 @@ msgid "collect2 version %s" msgstr "collect2 versión %s" #: collect2.c:1823 -#, fuzzy, c-format +#, c-format msgid "%d constructor found\n" msgid_plural "%d constructors found\n" -msgstr[0] "se encuentra(n) %d constructor(es)\n" -msgstr[1] "se encuentra(n) %d constructor(es)\n" +msgstr[0] "se encontró %d constructor\n" +msgstr[1] "se encontraron %d constructores\n" #: collect2.c:1827 -#, fuzzy, c-format +#, c-format msgid "%d destructor found\n" msgid_plural "%d destructors found\n" -msgstr[0] "se encuentra(n) %d destructor(es)\n" -msgstr[1] "se encuentra(n) %d destructor(es)\n" +msgstr[0] "se encontró %d destructor\n" +msgstr[1] "se encontraron %d destructores\n" #: collect2.c:1831 -#, fuzzy, c-format +#, c-format msgid "%d frame table found\n" msgid_plural "%d frame tables found\n" -msgstr[0] "se encuentra(n) %d marcos de tabla(s)\n" -msgstr[1] "se encuentra(n) %d marcos de tabla(s)\n" +msgstr[0] "se encontró %d tabla de marco\n" +msgstr[1] "se encontraron %d tablas de marco\n" #: collect2.c:1985 lto-wrapper.c:175 #, c-format @@ -2520,9 +2521,8 @@ msgid "The maximum number of insns of a peeled loop that rolls only once" msgstr "El número máximo de insns en un ciclo pelado que se enrolla solamente una vez" #: params.def:272 -#, fuzzy msgid "The maximum depth of a loop nest we completely peel" -msgstr "El número máximo de insns en un ciclo completamente pelado" +msgstr "La profundidad máxima de un ciclo anidado que nosotros pelamos completamente" #: params.def:278 msgid "The maximum number of insns of an unswitched loop" @@ -2819,13 +2819,12 @@ msgid "size of tiles for loop blocking" msgstr "Tamaño de bloques para el bloqueo de ciclo" #: params.def:752 -#, fuzzy msgid "maximum number of parameters in a SCoP" -msgstr "el valor máximo del parámetro %qs es %u" +msgstr "número máximo de parámetros en un SCoP" #: params.def:759 msgid "maximum number of basic blocks per function to be analyzed by Graphite" -msgstr "" +msgstr "número máximo de bloques básicos por función para analizar con Graphite" #: params.def:766 msgid "Max basic blocks number in loop for loop invariant motion" @@ -2845,7 +2844,7 @@ msgstr "Tasa m #: params.def:790 msgid "Max. size of var tracking hash tables" -msgstr "" +msgstr "Tamaño máximo de las tablas de dispersión de rastreo de variables" #: params.def:797 msgid "The minimum UID to be used for a nondebug insn" @@ -4072,14 +4071,14 @@ msgid "%s:%d: instantiated from here" msgstr "%s:%d: instanciado desde aquí" #: cp/error.c:2794 -#, fuzzy, c-format +#, c-format msgid "%s:%d:%d: [ skipping %d instantiation contexts ]\n" -msgstr "%s:%d:%d: instanciado desde %qs\n" +msgstr "%s:%d:%d: [ se saltan %d contextos de instanciación ]\n" #: cp/error.c:2798 #, c-format msgid "%s:%d: [ skipping %d instantiation contexts ]\n" -msgstr "" +msgstr "%s:%d: [ se saltan %d contextos de instanciación ]\n" #: cp/g++spec.c:261 java/jvspec.c:403 #, c-format @@ -5329,9 +5328,8 @@ msgid "Allow arbitrary character line width in fixed mode" msgstr "Permite ancho de línea de carácter arbitrario en formato fijo" #: fortran/lang.opt:249 -#, fuzzy msgid "-ffixed-line-length-\tUse n as character line width in fixed mode" -msgstr "-ffixed-line-length-\t\tUsa n como ancho de línea de carácter en modo fijo" +msgstr "-ffixed-line-length-\tUsa n como ancho de línea de carácter en modo fijo" #: fortran/lang.opt:253 msgid "-ffpe-trap=[...]\tStop on following floating point exceptions" @@ -5346,9 +5344,8 @@ msgid "Allow arbitrary character line width in free mode" msgstr "Permite ancho de línea de carácter arbitrario en formato libre" #: fortran/lang.opt:265 -#, fuzzy msgid "-ffree-line-length-\tUse n as character line width in free mode" -msgstr "-ffree-line-length-\t\tUsa n como ancho de línea de carácter en modo libre" +msgstr "-ffree-line-length-\tUsa n como ancho de línea de carácter en modo libre" #: fortran/lang.opt:269 msgid "Specify that no implicit typing is allowed, unless overridden by explicit IMPLICIT statements" @@ -5403,9 +5400,8 @@ msgid "Try to lay out derived types as compactly as possible" msgstr "Trata de acomodar los tipos derivados tan compactos como sea posible" #: fortran/lang.opt:329 -#, fuzzy msgid "Protect parentheses in expressions" -msgstr "se sugieren paréntesis alrededor de la expresión %<>>%>" +msgstr "Protege paréntesis en las expresiones" #: fortran/lang.opt:333 msgid "Enable range checking during compilation" @@ -8958,9 +8954,8 @@ msgid "Warn for implicit type conversions that may change a value" msgstr "Avisa cuando hay conversiones de tipo implícitas que pueden cambiar un valor" #: c.opt:176 -#, fuzzy msgid "Warn for converting NULL from/to a non-pointer type" -msgstr "se convierte NULL a un tipo que no es puntero" +msgstr "Avisa cuando se convierte NULL de/a un tipo que no es puntero" #: c.opt:180 msgid "Warn for implicit type conversions between signed and unsigned integers" @@ -9503,9 +9498,8 @@ msgid "-ftabstop=\tDistance between tab stops for column reporting" msgstr "-ftabstop=\tDistancia entre topes de tabulador para reportes en columnas" #: c.opt:798 -#, fuzzy msgid "-ftemplate-depth=\tSpecify maximum template instantiation depth" -msgstr "-ftemplate-depth-\tEspecifica la profundidad máxima de instanciación de plantillas" +msgstr "-ftemplate-depth-\tEspecifica la profundidad máxima de instanciación de plantilla" #: c.opt:805 msgid "-fno-threadsafe-statics\tDo not generate thread-safe code for initializing local statics" @@ -9912,9 +9906,8 @@ msgid "-dumpbase \tSet the file basename to be used for dumps" msgstr "-dumpbase \tEstablece el nombre base de fichero a usar para los volcados" #: common.opt:258 -#, fuzzy msgid "-dumpdir \tSet the directory name to be used for dumps" -msgstr "-dumpdir \t\tEstablece el nombre del directorio a usar para los volcados" +msgstr "-dumpdir \tEstablece el nombre del directorio a usar para los volcados" #: common.opt:284 msgid "Align the start of functions" @@ -12487,9 +12480,9 @@ msgid "%qE undeclared (first use in this function)" msgstr "%qE no se declaró aquí (primer uso en esta función)" #: c-decl.c:2954 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "each undeclared identifier is reported only once for each function it appears in" -msgstr "(Cada identificador sin declarar es reportado sólo una vez para cada función en el que aparece.)" +msgstr "cada identificador sin declarar se reporta sólo una vez para cada función en el que aparece" #: c-decl.c:3004 cp/decl.c:2446 #, gcc-internal-format @@ -15190,9 +15183,9 @@ msgid "function with qualified void return type called" msgstr "se llamó a una función con tipo de devolución void calificado" #: c-typeck.c:2820 c-typeck.c:3047 cp/typeck.c:3315 cp/typeck.c:3429 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "declared here" -msgstr "%qD se declara aquí" +msgstr "se declara aquí" #: c-typeck.c:2855 #, gcc-internal-format @@ -16760,7 +16753,7 @@ msgstr "DW_LOC_OP %s no est #: dwarf2out.c:12859 #, gcc-internal-format msgid "non-delegitimized UNSPEC %d found in variable location" -msgstr "" +msgstr "se encontró UNSPEC %d que no está delegitimado la ubicación de variable" #: emit-rtl.c:2460 #, gcc-internal-format @@ -19334,12 +19327,12 @@ msgstr "Valor de perfil corrupto: %s la cuenta general del perfilador (%d) no co #: var-tracking.c:6051 #, gcc-internal-format msgid "variable tracking size limit exceeded with -fvar-tracking-assignments, retrying without" -msgstr "" +msgstr "se excedió el límite de tamaño de rastreo de variable con -fvar-track-assignments, reintente sin esa opción" #: var-tracking.c:6055 #, gcc-internal-format msgid "variable tracking size limit exceeded" -msgstr "" +msgstr "se excedió el límite de tamaño de rastreo de variable" #: varasm.c:580 #, gcc-internal-format @@ -19705,9 +19698,9 @@ msgid "bad value %qs for -mcpu switch" msgstr "valor %qs erróneo para el interruptor -mcpu" #: config/alpha/alpha.c:391 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "bad value %qs for -mtune switch" -msgstr "valor erróneo (%s) para la opción -mtune=" +msgstr "valor erróneo %qs para la opción -mtune" #: config/alpha/alpha.c:398 #, gcc-internal-format @@ -23387,24 +23380,24 @@ msgid "cannot convert %qE from type %qT to type %qT" msgstr "no se puede convertir %qE desde el tipo %qT al tipo %qT" #: cp/cvt.c:371 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "initialization of volatile reference type %q#T from rvalue of type %qT" -msgstr "inicialización inválida de una referencia que no es constante de tipo %qT desde un r-valor de tipo %qT" +msgstr "inicialización de un tipo de referencia volatile %q#T desde un r-valor de tipo %qT" #: cp/cvt.c:374 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "conversion to volatile reference type %q#T from rvalue of type %qT" -msgstr "inicialización inválida de una referencia que no es constante de tipo %qT desde un r-valor de tipo %qT" +msgstr "inicialización a un tipo de referencia volatile %q#T desde un r-valor de tipo %qT" #: cp/cvt.c:377 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "initialization of non-const reference type %q#T from rvalue of type %qT" -msgstr "inicialización inválida de una referencia que no es constante de tipo %qT desde un r-valor de tipo %qT" +msgstr "inicialización de un tipo de referencia que no es constante %q#T desde un r-valor de tipo %qT" #: cp/cvt.c:380 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "conversion to non-const reference type %q#T from rvalue of type %qT" -msgstr "inicialización inválida de una referencia que no es constante de tipo %qT desde un r-valor de tipo %qT" +msgstr "inicialización a un tipo de referencia que no es constante %q#T desde un r-valor de tipo %qT" #: cp/cvt.c:453 #, gcc-internal-format @@ -25565,9 +25558,9 @@ msgid "%qD is already defined in %qT" msgstr "%qD ya está definido en %qT" #: cp/decl2.c:917 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "invalid initializer for member function %qD" -msgstr "valor inicial inválido para el miembro %qE" +msgstr "inicializador inválido para la función miembro %qD" #: cp/decl2.c:923 #, gcc-internal-format @@ -25698,7 +25691,7 @@ msgstr "falta el argumento por defecto para el par #: cp/decl2.c:4017 #, gcc-internal-format msgid "converting lambda which uses %<...%> to function pointer" -msgstr "" +msgstr "se convierte lambda la cual usa %<...%> a un puntero de función" #: cp/decl2.c:4022 cp/search.c:1892 #, gcc-internal-format @@ -26209,7 +26202,7 @@ msgstr "el nombre revuelto de %qD cambiar #: cp/mangle.c:3071 #, gcc-internal-format msgid "-fabi-version=4 (or =0) avoids this error with a change in vector mangling" -msgstr "" +msgstr "-fabi-version=4 (o =0) evita este error con un cambio en el manejo de vectores" #: cp/method.c:396 #, gcc-internal-format @@ -26267,9 +26260,9 @@ msgid "function %q+D defaulted on its first declaration must not have an excepti msgstr "la función %q+D definida por defecto en su primera declaración no puede tener una especificación-de-excepción" #: cp/method.c:1081 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%qD declared virtual cannot be defaulted in the class body" -msgstr "%qD declarada explícitamente no se puede definir por defecto en el cuerpo de clase" +msgstr "%qD declarada virtual no se puede definir por defecto en el cuerpo de clase" #: cp/method.c:1130 #, gcc-internal-format @@ -26712,14 +26705,14 @@ msgid "typedef-name %qD used as destructor declarator" msgstr "se usa el nombre-de-definición-de-tipo %qD como un declarador de destructor" #: cp/parser.c:4552 cp/parser.c:6165 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in casts" -msgstr "no se pueden definir tipos nuevos en un tipo de devolución" +msgstr "los tipos no se pueden definir en conversiones" #: cp/parser.c:4615 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in a % expression" -msgstr "no se pueden definir tipos nuevos en un tipo de devolución" +msgstr "no se pueden definir tipos en una expresión %" #. Warn the user that a compound literal is not #. allowed in standard C++. @@ -26749,9 +26742,9 @@ msgid "try removing the parentheses around the type-id" msgstr "intente borrar los paréntesis alrededor del id-de-tipo" #: cp/parser.c:5852 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in a new-type-id" -msgstr "no se pueden definir tipos nuevos en un tipo de devolución" +msgstr "no se pueden definir tipos en un id-tipo-nuevo" #: cp/parser.c:5976 #, gcc-internal-format @@ -26804,9 +26797,9 @@ msgid "%<%T::%D%> names the constructor, not the type" msgstr "%<%T::%D%> nombra el constructor, no el tipo" #: cp/parser.c:8113 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in conditions" -msgstr "no se pueden definir tipos nuevos en un tipo de devolución" +msgstr "no se pueden definir tipos en condiciones" #. Issue a warning about this use of a GNU extension. #: cp/parser.c:8462 @@ -26852,9 +26845,9 @@ msgid "templates may not be %" msgstr "las plantillas no pueden ser %" #: cp/parser.c:9523 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in % expressions" -msgstr "no se pueden definir tipos nuevos en un tipo de devolución" +msgstr "no se pueden definir tipos en expresiones %" #: cp/parser.c:9778 #, gcc-internal-format @@ -27029,9 +27022,9 @@ msgid "invalid use of %" msgstr "uso inválido de %" #: cp/parser.c:15039 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in parameter types" -msgstr "no se pueden definir tipos nuevos en un tipo de devolución" +msgstr "no se pueden definir tipos en tipos de parámetro" #: cp/parser.c:15257 #, gcc-internal-format @@ -27114,14 +27107,14 @@ msgid "keyword % not allowed in this context (the base class is impli msgstr "no se permite la palabra clave % en este contexto (la clase base es implícitamente un tipo)" #: cp/parser.c:17229 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in an exception-specification" -msgstr "no se pueden definir tipos nuevos en un tipo de devolución" +msgstr "no se pueden definir tipos en una especificación de excepción" #: cp/parser.c:17410 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in exception-declarations" -msgstr "no se pueden definir tipos nuevos en un tipo de devolución" +msgstr "no se pueden definir tipos en declaraciones de excepción" #: cp/parser.c:18303 #, gcc-internal-format @@ -27480,11 +27473,11 @@ msgid "template argument %qE involves template parameter(s)" msgstr "el argumento de plantilla %qE involucra a el(los) parámetro(s) de plantilla" #: cp/pt.c:4022 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "type %qT of template argument %qE depends on a template parameter" msgid_plural "type %qT of template argument %qE depends on template parameters" -msgstr[0] "el tipo %qT del argumento de plantilla %qE depende de el(los) parámetro(s) de plantilla" -msgstr[1] "el tipo %qT del argumento de plantilla %qE depende de el(los) parámetro(s) de plantilla" +msgstr[0] "el tipo %qT del argumento de plantilla %qE depende de un parámetro de plantilla" +msgstr[1] "el tipo %qT del argumento de plantilla %qE depende de parámetros de plantilla" #: cp/pt.c:4129 #, gcc-internal-format @@ -27502,29 +27495,29 @@ msgid "parameter pack %qT must be at the end of the template parameter list" msgstr "el parámetro de paquete %qT debe estar al final de la lista de parámetros de plantilla" #: cp/pt.c:4190 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default template arguments may not be used in function template friend re-declaration" -msgstr "no se permiten los argumentos por defecto en la declaración de la especialización friend de la plantilla %qD" +msgstr "no se pueden usar los argumentos de plantilla por defecto en la re-declaración friend de la plantilla de función" #: cp/pt.c:4193 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default template arguments may not be used in function template friend declarations" -msgstr "no se permiten los argumentos por defecto en la declaración de la especialización friend de la plantilla %qD" +msgstr "no se pueden usar los argumentos de plantilla por defecto en las declaraciones friend de la plantilla de función" #: cp/pt.c:4196 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default template arguments may not be used in function templates without -std=c++0x or -std=gnu++0x" -msgstr "las funciones por defecto y borradas sólo están disponibles con -std=c++0x o -std=gnu++0x" +msgstr "los argumentos de plantilla por defecto no se pueden usar en las plantillas de función sin -std=c++0x o -std=gnu++0x" #: cp/pt.c:4199 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default template arguments may not be used in partial specializations" -msgstr "no se usan los parámetros de plantilla en la especialización parcial:" +msgstr "no se pueden usar los argumentos de plantilla por defecto en las especializaciones parciales" #: cp/pt.c:4202 cp/pt.c:4253 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default argument for template parameter for class enclosing %qD" -msgstr "el argumento por defecto para el parámetro del tipo %qT tiene el tipo %qT" +msgstr "argumento por defecto para el parámetro de plantilla para la clase incluyente %qD" #: cp/pt.c:4346 #, gcc-internal-format @@ -27595,18 +27588,18 @@ msgid "template specifiers not specified in declaration of %qD" msgstr "no se especificaron los especificadores de plantilla en la declaración de %qD" #: cp/pt.c:4693 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "redeclared with %d template parameter" msgid_plural "redeclared with %d template parameters" -msgstr[0] "se redeclaró con %d parámetro(s) de plantilla" -msgstr[1] "se redeclaró con %d parámetro(s) de plantilla" +msgstr[0] "se redeclaró con %d parámetro de plantilla" +msgstr[1] "se redeclaró con %d parámetros de plantilla" #: cp/pt.c:4697 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "previous declaration %q+D used %d template parameter" msgid_plural "previous declaration %q+D used %d template parameters" -msgstr[0] "la declaración previa de %q+#D usó %d parámetro(s) de plantilla" -msgstr[1] "la declaración previa de %q+#D usó %d parámetro(s) de plantilla" +msgstr[0] "la declaración previa de %q+#D usó %d parámetro de plantilla" +msgstr[1] "la declaración previa de %q+#D usó %d parámetros de plantilla" #: cp/pt.c:4734 #, gcc-internal-format @@ -27820,9 +27813,9 @@ msgid "for template declaration %q+D" msgstr "para la declaración de plantilla %q+D" #: cp/pt.c:7060 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "template instantiation depth exceeds maximum of %d (use -ftemplate-depth= to increase the maximum) instantiating %qD" -msgstr "la profundidad de instanciación de la plantilla excede el máximo de %d (use -ftemplate-depth-NN para incrementar el máximo) al instanciar %qD" +msgstr "la profundidad de instanciación de la plantilla excede el máximo de %d (use -ftemplate-depth= para incrementar el máximo) al instanciar %qD" #: cp/pt.c:8326 #, gcc-internal-format @@ -28105,9 +28098,9 @@ msgid "explicit instantiation of %qD but no definition available" msgstr "instanciación explícita de %qD pero no hay una definición disponible" #: cp/pt.c:16910 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "template instantiation depth exceeds maximum of %d instantiating %q+D, possibly from virtual table generation (use -ftemplate-depth= to increase the maximum)" -msgstr "la profundidad de instanciación de la plantilla excede el máximo de %d al instanciar %q+D, posiblemente de la generación de tabla virtual (use -ftemplate-depth-NN para incrementar el máximo)" +msgstr "la profundidad de instanciación de la plantilla excede el máximo de %d al instanciar %q+D, posiblemente de la generación de tabla virtual (use -ftemplate-depth= para incrementar el máximo)" #: cp/pt.c:17265 #, gcc-internal-format @@ -28120,9 +28113,9 @@ msgid "deducing from brace-enclosed initializer list requires #include " #: cp/pt.c:18315 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "variable %q#D with % type used in its own initializer" -msgstr "la variable %D de tipo % no debe ser inicializada" +msgstr "se usó la variable %q#D con tipo % en su propio inicializador" #: cp/pt.c:18337 #, gcc-internal-format @@ -28834,9 +28827,9 @@ msgid "%qE cannot be used as a function" msgstr "no se puede usar %qE como una función" #: cp/typeck.c:3312 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "too many arguments to %s %q#D" -msgstr "demasiados argumentos para %s %q+#D" +msgstr "demasiados argumentos para %s %q#D" #: cp/typeck.c:3318 #, gcc-internal-format @@ -28854,9 +28847,9 @@ msgid "parameter %P has incomplete type %qT" msgstr "el parámetro %P tiene el tipo incompleto %qT" #: cp/typeck.c:3426 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "too few arguments to %s %q#D" -msgstr "faltan argumentos para %s %q+#D" +msgstr "faltan argumentos para %s %q#D" #: cp/typeck.c:3432 #, gcc-internal-format @@ -34537,9 +34530,9 @@ msgid "The element in the derived type constructor at %L, for pointer component msgstr "El elemento en el constructor de tipo derivado en %L, para el componente puntero '%s', debe ser un POINTER o un TARGET" #: fortran/resolve.c:930 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Invalid expression in the derived type constructor for pointer component '%s' at %L in PURE procedure" -msgstr "El elemento en el constructor de tipo derivado en %L, para el componente puntero '%s', es %s pero debería ser %s" +msgstr "Expresión inválida en el constructor de tipo derivado para el componente puntero '%s' en %L en el procedimiento PURE" #: fortran/resolve.c:1052 #, gcc-internal-format @@ -35427,7 +35420,7 @@ msgstr "La etiqueta enlazante '%s' en %L colisiona con la entidad global '%s' en #: fortran/resolve.c:8587 #, gcc-internal-format msgid "CHARACTER variable at %L has negative length %d, the length has been set to zero" -msgstr "" +msgstr "La variable CHARACTER en %L tiene longitud negativa %d, la longitud se estableció a cero" #: fortran/resolve.c:8599 #, gcc-internal-format @@ -35462,7 +35455,7 @@ msgstr "El tipo '%s' no se puede asociar al anfitri #: fortran/resolve.c:8964 #, gcc-internal-format msgid "Fortran 2008: Implied SAVE for module variable '%s' at %L, needed due to the default initialization" -msgstr "" +msgstr "Fortran 2008: SAVE implícito para la variable de módulo '%s' en %L, se necesita por la inicialización por defecto" #: fortran/resolve.c:8975 #, gcc-internal-format diff --git a/gcc/po/zh_CN.po b/gcc/po/zh_CN.po index af1096aedaa..0b797938c44 100644 --- a/gcc/po/zh_CN.po +++ b/gcc/po/zh_CN.po @@ -5,10 +5,10 @@ # msgid "" msgstr "" -"Project-Id-Version: gcc 4.5-b20100204\n" +"Project-Id-Version: gcc 4.5.0\n" "Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n" "POT-Creation-Date: 2010-04-06 14:11+0000\n" -"PO-Revision-Date: 2010-03-09 14:42+0800\n" +"PO-Revision-Date: 2010-04-19 14:57+0800\n" "Last-Translator: Meng Jie \n" "Language-Team: Chinese (simplified) \n" "MIME-Version: 1.0\n" @@ -16,7 +16,8 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Chinese\n" "X-Poedit-Country: CHINA\n" -"X-Poedit-Basepath: C:\\MSYS\\source\\gcc-4.5-20091203\\gcc\n" +"X-Poedit-Basepath: C:\\MSYS\\source\\gcc-4.5.0\\gcc\n" +"Plural-Forms: nplurals=1; plural=0;\n" #: c-decl.c:4573 c-pretty-print.c:403 c-typeck.c:5590 toplev.c:1652 #: cp/error.c:581 cp/error.c:854 @@ -641,25 +642,22 @@ msgid "collect2 version %s" msgstr "collect2 版本 %s" #: collect2.c:1823 -#, fuzzy, c-format +#, c-format msgid "%d constructor found\n" msgid_plural "%d constructors found\n" msgstr[0] "找到 %d 个构造函数\n" -msgstr[1] "找到 %d 个构造函数\n" #: collect2.c:1827 -#, fuzzy, c-format +#, c-format msgid "%d destructor found\n" msgid_plural "%d destructors found\n" msgstr[0] "找到 %d 个析构函数\n" -msgstr[1] "找到 %d 个析构函数\n" #: collect2.c:1831 -#, fuzzy, c-format +#, c-format msgid "%d frame table found\n" msgid_plural "%d frame tables found\n" -msgstr[0] "找到了 %d 个框架表\n" -msgstr[1] "找到了 %d 个框架表\n" +msgstr[0] "找到 %d 个框架表\n" #: collect2.c:1985 lto-wrapper.c:175 #, c-format @@ -2508,9 +2506,8 @@ msgid "The maximum number of insns of a peeled loop that rolls only once" msgstr "被剥离后只卷绕一次的循环包含的最多指令数" #: params.def:272 -#, fuzzy msgid "The maximum depth of a loop nest we completely peel" -msgstr "一个完全剥离的循环所能有的最大指令数" +msgstr "一个完全剥离的循环嵌套所能有的最大深度" #: params.def:278 msgid "The maximum number of insns of an unswitched loop" @@ -2805,13 +2802,12 @@ msgid "size of tiles for loop blocking" msgstr "循环分块中每小块的大小" #: params.def:752 -#, fuzzy msgid "maximum number of parameters in a SCoP" -msgstr "参数%qs的最大值是 %u" +msgstr "一个静态控制部分(ScoP)中参数的最大数量" #: params.def:759 msgid "maximum number of basic blocks per function to be analyzed by Graphite" -msgstr "" +msgstr "Graphite 可分析的每函数所包含的基本块数量上限" #: params.def:766 msgid "Max basic blocks number in loop for loop invariant motion" @@ -2831,7 +2827,7 @@ msgstr "为循环启用预取时最小的指令/内存操作比" #: params.def:790 msgid "Max. size of var tracking hash tables" -msgstr "" +msgstr "变量跟踪散列表的最大尺寸" #: params.def:797 msgid "The minimum UID to be used for a nondebug insn" @@ -4058,14 +4054,14 @@ msgid "%s:%d: instantiated from here" msgstr "%s:%d:从此处实例化" #: cp/error.c:2794 -#, fuzzy, c-format +#, c-format msgid "%s:%d:%d: [ skipping %d instantiation contexts ]\n" -msgstr "%s:%d:%d:自%qs实例化\n" +msgstr "%s:%d:%d:[ 跳过 %d 个实例化上下文 ]\n" #: cp/error.c:2798 #, c-format msgid "%s:%d: [ skipping %d instantiation contexts ]\n" -msgstr "" +msgstr "%s:%d:[ 跳过 %d 个实例化上下文 ]\n" #: cp/g++spec.c:261 java/jvspec.c:403 #, c-format @@ -5314,9 +5310,8 @@ msgid "Allow arbitrary character line width in fixed mode" msgstr "在固定模式下允许任意的字符行宽" #: fortran/lang.opt:249 -#, fuzzy msgid "-ffixed-line-length-\tUse n as character line width in fixed mode" -msgstr "-ffixed-line-length-\t\t在固定模式下以 n 作为字符行宽" +msgstr "-ffixed-line-length-\t在固定模式下以 n 作为字符行宽" #: fortran/lang.opt:253 msgid "-ffpe-trap=[...]\tStop on following floating point exceptions" @@ -5331,9 +5326,8 @@ msgid "Allow arbitrary character line width in free mode" msgstr "在自由模式下允许任意的字符行宽" #: fortran/lang.opt:265 -#, fuzzy msgid "-ffree-line-length-\tUse n as character line width in free mode" -msgstr "-ffree-line-length-\t\t在自由模式下以 n 作为字符行宽" +msgstr "-ffree-line-length-\t在自由模式下以 n 作为字符行宽" #: fortran/lang.opt:269 msgid "Specify that no implicit typing is allowed, unless overridden by explicit IMPLICIT statements" @@ -5388,9 +5382,8 @@ msgid "Try to lay out derived types as compactly as possible" msgstr "为派生类型使用尽可能紧实的布局" #: fortran/lang.opt:329 -#, fuzzy msgid "Protect parentheses in expressions" -msgstr "建议%<>>%>表达式周围加上括号" +msgstr "尊重表达式中的括号" #: fortran/lang.opt:333 msgid "Enable range checking during compilation" @@ -8935,9 +8928,8 @@ msgid "Warn for implicit type conversions that may change a value" msgstr "当隐式类型转换可能改变值时给出警告" #: c.opt:176 -#, fuzzy msgid "Warn for converting NULL from/to a non-pointer type" -msgstr "将 NULL 转换为非指针类型" +msgstr "将 NULL 转换为非指针类型时给出警告" #: c.opt:180 msgid "Warn for implicit type conversions between signed and unsigned integers" @@ -9480,9 +9472,8 @@ msgid "-ftabstop=\tDistance between tab stops for column reporting" msgstr "-ftabstop=\t指定报告列号时制表位间的距离" #: c.opt:798 -#, fuzzy msgid "-ftemplate-depth=\tSpecify maximum template instantiation depth" -msgstr "-ftemplate-depth-\t指定模板实例化的最大深度" +msgstr "-ftemplate-depth=\t指定模板实例化的最大深度" #: c.opt:805 msgid "-fno-threadsafe-statics\tDo not generate thread-safe code for initializing local statics" @@ -9889,9 +9880,8 @@ msgid "-dumpbase \tSet the file basename to be used for dumps" msgstr "-dumpbase <文件>\t设定内存转储使用的文件基本名" #: common.opt:258 -#, fuzzy msgid "-dumpdir \tSet the directory name to be used for dumps" -msgstr "-dumpdir <目录>\t\t设定内存转储使用的目录名" +msgstr "-dumpdir <目录>\t设定内存转储使用的目录名" #: common.opt:284 msgid "Align the start of functions" @@ -12457,9 +12447,9 @@ msgid "%qE undeclared (first use in this function)" msgstr "%qE未声明(在此函数内第一次使用)" #: c-decl.c:2954 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "each undeclared identifier is reported only once for each function it appears in" -msgstr "(即使在一个函数内多次出现,每个未声明的标识符在其" +msgstr "每个未声明的标识符在其出现的函数内只报告一次" #: c-decl.c:3004 cp/decl.c:2446 #, gcc-internal-format @@ -15160,9 +15150,9 @@ msgid "function with qualified void return type called" msgstr "调用了有限定 void 返回类型的函数" #: c-typeck.c:2820 c-typeck.c:3047 cp/typeck.c:3315 cp/typeck.c:3429 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "declared here" -msgstr "%qD在此声明" +msgstr "在此声明" #: c-typeck.c:2855 #, gcc-internal-format @@ -16730,7 +16720,7 @@ msgstr "DW_LOC_OP %s 尚未实现" #: dwarf2out.c:12859 #, gcc-internal-format msgid "non-delegitimized UNSPEC %d found in variable location" -msgstr "" +msgstr "变量位置处发现未被非法化的 UNSPEC %d" #: emit-rtl.c:2460 #, gcc-internal-format @@ -19304,12 +19294,12 @@ msgstr "损坏的值取样:%s 取样总数(%d)与基本块数(%d)不匹配" #: var-tracking.c:6051 #, gcc-internal-format msgid "variable tracking size limit exceeded with -fvar-tracking-assignments, retrying without" -msgstr "" +msgstr "变量跟踪大小越限,请不带 -fvar-tracking-assignments 重试" #: var-tracking.c:6055 #, gcc-internal-format msgid "variable tracking size limit exceeded" -msgstr "" +msgstr "变量跟踪大小越限" #: varasm.c:580 #, gcc-internal-format @@ -19675,9 +19665,9 @@ msgid "bad value %qs for -mcpu switch" msgstr "-mcpu 开关的值%qs错误" #: config/alpha/alpha.c:391 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "bad value %qs for -mtune switch" -msgstr "-mcpu 开关的值%qs错误" +msgstr "-mtune 开关的值%qs错误" #: config/alpha/alpha.c:398 #, gcc-internal-format @@ -23355,24 +23345,24 @@ msgid "cannot convert %qE from type %qT to type %qT" msgstr "无法将%qE从类型%qT转换到类型%qT" #: cp/cvt.c:371 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "initialization of volatile reference type %q#T from rvalue of type %qT" -msgstr "用类型为%2$qT的右值初始化类型为%1$qT的非常量引用无效" +msgstr "用类型为%2$qT的右值初始化类型为%1$q#T的 volatile 引用" #: cp/cvt.c:374 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "conversion to volatile reference type %q#T from rvalue of type %qT" -msgstr "用类型为%2$qT的右值初始化类型为%1$qT的非常量引用无效" +msgstr "将类型为%2$qT的右值转换为%1$qT的 volatile 引用" #: cp/cvt.c:377 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "initialization of non-const reference type %q#T from rvalue of type %qT" -msgstr "用类型为%2$qT的右值初始化类型为%1$qT的非常量引用无效" +msgstr "用类型为%2$qT的右值初始化非常量引用类型%1$q#T" #: cp/cvt.c:380 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "conversion to non-const reference type %q#T from rvalue of type %qT" -msgstr "用类型为%2$qT的右值初始化类型为%1$qT的非常量引用无效" +msgstr "将类型为%2$qT的右值转换为非常量引用类型%1$q#T" #: cp/cvt.c:453 #, gcc-internal-format @@ -24209,7 +24199,7 @@ msgstr "%q+D声明为友元" #: cp/decl.c:6546 #, gcc-internal-format msgid "%q+D declared with an exception specification" -msgstr "%q+D声明时有异常指定" +msgstr "%q+D声明时带有异常规范" #: cp/decl.c:6580 #, gcc-internal-format @@ -25527,9 +25517,9 @@ msgid "%qD is already defined in %qT" msgstr "%qD已在%qT中定义过" #: cp/decl2.c:917 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "invalid initializer for member function %qD" -msgstr "成员%qE的初始值无效" +msgstr "成员函数%qD的初始值设定无效" #: cp/decl2.c:923 #, gcc-internal-format @@ -25660,7 +25650,7 @@ msgstr "%2$q+#D的第 %1$P 个形参缺少默认实参" #: cp/decl2.c:4017 #, gcc-internal-format msgid "converting lambda which uses %<...%> to function pointer" -msgstr "" +msgstr "将使用了%<...%>的 Lambda 转换为函数指针" #: cp/decl2.c:4022 cp/search.c:1892 #, gcc-internal-format @@ -26171,7 +26161,7 @@ msgstr "%qD修饰后的名字将在 GCC 的未来版本中有变化" #: cp/mangle.c:3071 #, gcc-internal-format msgid "-fabi-version=4 (or =0) avoids this error with a change in vector mangling" -msgstr "" +msgstr "-fabi-version=4 (or =0) 可以改变向量修饰来避免这个错误" #: cp/method.c:396 #, gcc-internal-format @@ -26229,9 +26219,9 @@ msgid "function %q+D defaulted on its first declaration must not have an excepti msgstr "首次声明时被默认化的函数%q+D不可以指定异常" #: cp/method.c:1081 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%qD declared virtual cannot be defaulted in the class body" -msgstr "声明为 explicit 的%qD不能在类体内被默认化" +msgstr "声明为 virtual 的%qD不能在类体内指定默认值" #: cp/method.c:1130 #, gcc-internal-format @@ -26674,14 +26664,14 @@ msgid "typedef-name %qD used as destructor declarator" msgstr "typedef 名%qD用于析构函数声明" #: cp/parser.c:4552 cp/parser.c:6165 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in casts" -msgstr "不能在返回类型中定义新类型" +msgstr "类型不能定义在类型转换中" #: cp/parser.c:4615 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in a % expression" -msgstr "不能在返回类型中定义新类型" +msgstr "类型不能定义在%表达式中" #. Warn the user that a compound literal is not #. allowed in standard C++. @@ -26711,9 +26701,9 @@ msgid "try removing the parentheses around the type-id" msgstr "请尝试删除类型标识符两边的括号" #: cp/parser.c:5852 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in a new-type-id" -msgstr "不能在返回类型中定义新类型" +msgstr "类型不能定义在 new-type-id 中" #: cp/parser.c:5976 #, gcc-internal-format @@ -26766,9 +26756,9 @@ msgid "%<%T::%D%> names the constructor, not the type" msgstr "%<%T::%D%>命名了一个构造函数而非类型" #: cp/parser.c:8113 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in conditions" -msgstr "不能在返回类型中定义新类型" +msgstr "类型不能定义在条件表达式中" #. Issue a warning about this use of a GNU extension. #: cp/parser.c:8462 @@ -26814,9 +26804,9 @@ msgid "templates may not be %" msgstr "模板不能是%的" #: cp/parser.c:9523 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in % expressions" -msgstr "不能在返回类型中定义新类型" +msgstr "类型不能定义在%中" #: cp/parser.c:9778 #, gcc-internal-format @@ -26991,9 +26981,9 @@ msgid "invalid use of %" msgstr "错误地使用了%" #: cp/parser.c:15039 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in parameter types" -msgstr "不能在返回类型中定义新类型" +msgstr "类型不能定义在参数类型中" #: cp/parser.c:15257 #, gcc-internal-format @@ -27076,14 +27066,14 @@ msgid "keyword % not allowed in this context (the base class is impli msgstr "关键字%不允许用在此上下文中(基类隐式地是一个类型)" #: cp/parser.c:17229 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in an exception-specification" -msgstr "不能在返回类型中定义新类型" +msgstr "类型不能定义在异常规范中" #: cp/parser.c:17410 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in exception-declarations" -msgstr "不能在返回类型中定义新类型" +msgstr "类型不能定义在异常声明中" #: cp/parser.c:18303 #, gcc-internal-format @@ -27442,11 +27432,10 @@ msgid "template argument %qE involves template parameter(s)" msgstr "模板实参%qE混杂了模板形参" #: cp/pt.c:4022 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "type %qT of template argument %qE depends on a template parameter" msgid_plural "type %qT of template argument %qE depends on template parameters" msgstr[0] "模板实参%2$qE的类型%1$qT取决于模板参数" -msgstr[1] "模板实参%2$qE的类型%1$qT取决于模板参数" #: cp/pt.c:4129 #, gcc-internal-format @@ -27464,29 +27453,29 @@ msgid "parameter pack %qT must be at the end of the template parameter list" msgstr "参数包%qT必须出现在模板形参表末尾" #: cp/pt.c:4190 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default template arguments may not be used in function template friend re-declaration" -msgstr "友元模板特例化%qD中不允许出现默认参数" +msgstr "默认参数不能用在函数模板友元重声明中" #: cp/pt.c:4193 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default template arguments may not be used in function template friend declarations" -msgstr "友元模板特例化%qD中不允许出现默认参数" +msgstr "默认参数不能用在函数模板友元重声明中" #: cp/pt.c:4196 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default template arguments may not be used in function templates without -std=c++0x or -std=gnu++0x" -msgstr "默认化和被删除的函数只在 -std=c++0x 或 -std=gnu++0x 下可用" +msgstr "只有指定了 -std=c++0x 或 -std=gnu++0x 时才能在函数模板中使用默认参数" #: cp/pt.c:4199 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default template arguments may not be used in partial specializations" -msgstr "部分特例化中未用到模板参数:" +msgstr "默认参数不能用在部分特例化中" #: cp/pt.c:4202 cp/pt.c:4253 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default argument for template parameter for class enclosing %qD" -msgstr "类型为%qT的形参的默认实参却有类型%qT" +msgstr "包含%qD的类的模板参数有默认参数" #: cp/pt.c:4346 #, gcc-internal-format @@ -27557,18 +27546,16 @@ msgid "template specifiers not specified in declaration of %qD" msgstr "%qD的声明中没有 template 限定" #: cp/pt.c:4693 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "redeclared with %d template parameter" msgid_plural "redeclared with %d template parameters" -msgstr[0] "重声明为具有%d个模板参数" -msgstr[1] "重声明为具有%d个模板参数" +msgstr[0] "重声明为具有 %d 个模板参数" #: cp/pt.c:4697 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "previous declaration %q+D used %d template parameter" msgid_plural "previous declaration %q+D used %d template parameters" -msgstr[0] "先前的声明%q+D使用了%d个模板参数" -msgstr[1] "先前的声明%q+D使用了%d个模板参数" +msgstr[0] "先前的声明%q+D使用了 %d 个模板参数" #: cp/pt.c:4734 #, gcc-internal-format @@ -27782,9 +27769,9 @@ msgid "for template declaration %q+D" msgstr "对于模板声明%q+D" #: cp/pt.c:7060 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "template instantiation depth exceeds maximum of %d (use -ftemplate-depth= to increase the maximum) instantiating %qD" -msgstr "模板实例化深度超过最大值 %d(使用 use -ftemplate-depth-NN 来增大最大值),在实例化%qD时" +msgstr "在实例化%2$qD时模板实例化深度超过最大值 %1$d(使用 use -ftemplate-depth= 来增大最大值)" #: cp/pt.c:8326 #, gcc-internal-format @@ -28067,9 +28054,9 @@ msgid "explicit instantiation of %qD but no definition available" msgstr "显式实例化%qD时没有可用的定义" #: cp/pt.c:16910 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "template instantiation depth exceeds maximum of %d instantiating %q+D, possibly from virtual table generation (use -ftemplate-depth= to increase the maximum)" -msgstr "模板实例化深度超过了最大值 %d,当实例化%q+D时,可能是由于生成虚函数表所致(使用 -ftemplate-depth-NN 来增大最大值)" +msgstr "在实例化%2$q+D时模板实例化深度超过了最大值 %1$d,可能是由于生成虚函数表所致(使用 -ftemplate-depth= 来增大最大值)" #: cp/pt.c:17265 #, gcc-internal-format @@ -28082,9 +28069,9 @@ msgid "deducing from brace-enclosed initializer list requires #include " #: cp/pt.c:18315 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "variable %q#D with % type used in its own initializer" -msgstr "类型为%的变量 %D 不能被初始化" +msgstr "变量‘%q#D’在其自身的初始值设定中使用了%类型" #: cp/pt.c:18337 #, gcc-internal-format @@ -28796,9 +28783,9 @@ msgid "%qE cannot be used as a function" msgstr "%qE不能用作函数" #: cp/typeck.c:3312 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "too many arguments to %s %q#D" -msgstr "给予 %s%q+#D的实参太多" +msgstr "给予 %s%q+#D的参数太多" #: cp/typeck.c:3318 #, gcc-internal-format @@ -28816,9 +28803,9 @@ msgid "parameter %P has incomplete type %qT" msgstr "形参 %P 的类型%qT不完全" #: cp/typeck.c:3426 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "too few arguments to %s %q#D" -msgstr "给予 %s%q+#D的实参太少" +msgstr "给予 %s%q+#D的参数太少" #: cp/typeck.c:3432 #, gcc-internal-format @@ -34490,9 +34477,9 @@ msgid "The element in the derived type constructor at %L, for pointer component msgstr "%L处指针组件‘%s’的派生类型构造函数中的元素应该是 POINTER 或 TARGET" #: fortran/resolve.c:930 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Invalid expression in the derived type constructor for pointer component '%s' at %L in PURE procedure" -msgstr "%L处指针组件‘%s’的派生类型构造函数中的元素是 %s 但应该是 %s" +msgstr "%2$L处指针组件‘%1$s’的派生类型构造函数中表达式无效" #: fortran/resolve.c:1052 #, gcc-internal-format @@ -35370,7 +35357,7 @@ msgstr "%2$L处的绑定标号‘%1$s’与 %4$L 处的全局实体‘%3$s’冲 #: fortran/resolve.c:8496 #, gcc-internal-format msgid "Binding label '%s' in interface body at %L collides with the global entity '%s' at %L" -msgstr "%2$L处的接口体‘%1$s’中的绑定标记‘%1$s’与%4$L处的全局实体‘%3$s’冲突" +msgstr "%2$L处的接口体中的绑定标记‘%1$s’与%4$L处的全局实体‘%3$s’冲突" #: fortran/resolve.c:8509 #, gcc-internal-format @@ -35380,7 +35367,7 @@ msgstr "%2$L处的捆绑标号‘%1$s’与 %4$L 处的全局实体‘%3$s’冲 #: fortran/resolve.c:8587 #, gcc-internal-format msgid "CHARACTER variable at %L has negative length %d, the length has been set to zero" -msgstr "" +msgstr "%L处的CHARACTER 变量有负的长度 %d,长度已经被设为零" #: fortran/resolve.c:8599 #, gcc-internal-format @@ -35415,7 +35402,7 @@ msgstr "‘%s’在%L处不能是主机相关的,因为它被在%L处声明的 #: fortran/resolve.c:8964 #, gcc-internal-format msgid "Fortran 2008: Implied SAVE for module variable '%s' at %L, needed due to the default initialization" -msgstr "" +msgstr "Fortran 2008:%2$L处模块变量‘%1$s’隐含使用了 SAVE,因为默认初始化有此需求" #: fortran/resolve.c:8975 #, gcc-internal-format diff --git a/gcc/reginfo.c b/gcc/reginfo.c index ee6c7ee6447..bf43d702da5 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -666,6 +666,8 @@ void reinit_regs (void) { init_regs (); + /* caller_save needs to be re-initialized. */ + caller_save_initialized_p = false; ira_init (); } diff --git a/gcc/rtl.h b/gcc/rtl.h index b8563b33d16..ccb3c1a044a 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1627,6 +1627,7 @@ extern void start_sequence (void); extern void push_to_sequence (rtx); extern void push_to_sequence2 (rtx, rtx); extern void end_sequence (void); +extern rtx immed_double_int_const (double_int, enum machine_mode); extern rtx immed_double_const (HOST_WIDE_INT, HOST_WIDE_INT, enum machine_mode); diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index d189d7066f2..fbbf7ad5e12 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -1770,44 +1770,42 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, if (SCALAR_INT_MODE_P (mode)) { - HOST_WIDE_INT coeff0h = 0, coeff1h = 0; - unsigned HOST_WIDE_INT coeff0l = 1, coeff1l = 1; + double_int coeff0, coeff1; rtx lhs = op0, rhs = op1; + coeff0 = double_int_one; + coeff1 = double_int_one; + if (GET_CODE (lhs) == NEG) { - coeff0l = -1; - coeff0h = -1; + coeff0 = double_int_minus_one; lhs = XEXP (lhs, 0); } else if (GET_CODE (lhs) == MULT && CONST_INT_P (XEXP (lhs, 1))) { - coeff0l = INTVAL (XEXP (lhs, 1)); - coeff0h = INTVAL (XEXP (lhs, 1)) < 0 ? -1 : 0; + coeff0 = shwi_to_double_int (INTVAL (XEXP (lhs, 1))); lhs = XEXP (lhs, 0); } else if (GET_CODE (lhs) == ASHIFT && CONST_INT_P (XEXP (lhs, 1)) - && INTVAL (XEXP (lhs, 1)) >= 0 + && INTVAL (XEXP (lhs, 1)) >= 0 && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT) { - coeff0l = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1)); - coeff0h = 0; + coeff0 = double_int_setbit (double_int_zero, + INTVAL (XEXP (lhs, 1))); lhs = XEXP (lhs, 0); } if (GET_CODE (rhs) == NEG) { - coeff1l = -1; - coeff1h = -1; + coeff1 = double_int_minus_one; rhs = XEXP (rhs, 0); } else if (GET_CODE (rhs) == MULT && CONST_INT_P (XEXP (rhs, 1))) { - coeff1l = INTVAL (XEXP (rhs, 1)); - coeff1h = INTVAL (XEXP (rhs, 1)) < 0 ? -1 : 0; + coeff1 = shwi_to_double_int (INTVAL (XEXP (rhs, 1))); rhs = XEXP (rhs, 0); } else if (GET_CODE (rhs) == ASHIFT @@ -1815,8 +1813,8 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, && INTVAL (XEXP (rhs, 1)) >= 0 && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT) { - coeff1l = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1)); - coeff1h = 0; + coeff1 = double_int_setbit (double_int_zero, + INTVAL (XEXP (rhs, 1))); rhs = XEXP (rhs, 0); } @@ -1824,12 +1822,11 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, { rtx orig = gen_rtx_PLUS (mode, op0, op1); rtx coeff; - unsigned HOST_WIDE_INT l; - HOST_WIDE_INT h; + double_int val; bool speed = optimize_function_for_speed_p (cfun); - add_double (coeff0l, coeff0h, coeff1l, coeff1h, &l, &h); - coeff = immed_double_const (l, h, mode); + val = double_int_add (coeff0, coeff1); + coeff = immed_double_int_const (val, mode); tem = simplify_gen_binary (MULT, mode, lhs, coeff); return rtx_cost (tem, SET, speed) <= rtx_cost (orig, SET, speed) @@ -1953,21 +1950,21 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, if (SCALAR_INT_MODE_P (mode)) { - HOST_WIDE_INT coeff0h = 0, negcoeff1h = -1; - unsigned HOST_WIDE_INT coeff0l = 1, negcoeff1l = -1; + double_int coeff0, negcoeff1; rtx lhs = op0, rhs = op1; + coeff0 = double_int_one; + negcoeff1 = double_int_minus_one; + if (GET_CODE (lhs) == NEG) { - coeff0l = -1; - coeff0h = -1; + coeff0 = double_int_minus_one; lhs = XEXP (lhs, 0); } else if (GET_CODE (lhs) == MULT && CONST_INT_P (XEXP (lhs, 1))) { - coeff0l = INTVAL (XEXP (lhs, 1)); - coeff0h = INTVAL (XEXP (lhs, 1)) < 0 ? -1 : 0; + coeff0 = shwi_to_double_int (INTVAL (XEXP (lhs, 1))); lhs = XEXP (lhs, 0); } else if (GET_CODE (lhs) == ASHIFT @@ -1975,22 +1972,20 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, && INTVAL (XEXP (lhs, 1)) >= 0 && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT) { - coeff0l = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1)); - coeff0h = 0; + coeff0 = double_int_setbit (double_int_zero, + INTVAL (XEXP (lhs, 1))); lhs = XEXP (lhs, 0); } if (GET_CODE (rhs) == NEG) { - negcoeff1l = 1; - negcoeff1h = 0; + negcoeff1 = double_int_one; rhs = XEXP (rhs, 0); } else if (GET_CODE (rhs) == MULT && CONST_INT_P (XEXP (rhs, 1))) { - negcoeff1l = -INTVAL (XEXP (rhs, 1)); - negcoeff1h = INTVAL (XEXP (rhs, 1)) <= 0 ? 0 : -1; + negcoeff1 = shwi_to_double_int (-INTVAL (XEXP (rhs, 1))); rhs = XEXP (rhs, 0); } else if (GET_CODE (rhs) == ASHIFT @@ -1998,8 +1993,9 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, && INTVAL (XEXP (rhs, 1)) >= 0 && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT) { - negcoeff1l = -(((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1))); - negcoeff1h = -1; + negcoeff1 = double_int_setbit (double_int_zero, + INTVAL (XEXP (rhs, 1))); + negcoeff1 = double_int_neg (negcoeff1); rhs = XEXP (rhs, 0); } @@ -2007,12 +2003,11 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, { rtx orig = gen_rtx_MINUS (mode, op0, op1); rtx coeff; - unsigned HOST_WIDE_INT l; - HOST_WIDE_INT h; + double_int val; bool speed = optimize_function_for_speed_p (cfun); - add_double (coeff0l, coeff0h, negcoeff1l, negcoeff1h, &l, &h); - coeff = immed_double_const (l, h, mode); + val = double_int_add (coeff0, negcoeff1); + coeff = immed_double_int_const (val, mode); tem = simplify_gen_binary (MULT, mode, lhs, coeff); return rtx_cost (tem, SET, speed) <= rtx_cost (orig, SET, speed) diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 46ac3339803..151092c06a4 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -2214,37 +2214,35 @@ make_accum_type (int precision, int unsignedp, int satp) value to enable integer types to be created. */ void -initialize_sizetypes (bool signed_p) +initialize_sizetypes (void) { tree t = make_node (INTEGER_TYPE); int precision = GET_MODE_BITSIZE (SImode); SET_TYPE_MODE (t, SImode); TYPE_ALIGN (t) = GET_MODE_ALIGNMENT (SImode); - TYPE_USER_ALIGN (t) = 0; TYPE_IS_SIZETYPE (t) = 1; - TYPE_UNSIGNED (t) = !signed_p; + TYPE_UNSIGNED (t) = 1; TYPE_SIZE (t) = build_int_cst (t, precision); TYPE_SIZE_UNIT (t) = build_int_cst (t, GET_MODE_SIZE (SImode)); TYPE_PRECISION (t) = precision; - /* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE. */ - set_min_and_max_values_for_integral_type (t, precision, !signed_p); + set_min_and_max_values_for_integral_type (t, precision, true); sizetype = t; bitsizetype = build_distinct_type_copy (t); } -/* Make sizetype a version of TYPE, and initialize *sizetype - accordingly. We do this by overwriting the stub sizetype and - bitsizetype nodes created by initialize_sizetypes. This makes sure - that (a) anything stubby about them no longer exists, (b) any - INTEGER_CSTs created with such a type, remain valid. */ +/* Make sizetype a version of TYPE, and initialize *sizetype accordingly. + We do this by overwriting the stub sizetype and bitsizetype nodes created + by initialize_sizetypes. This makes sure that (a) anything stubby about + them no longer exists and (b) any INTEGER_CSTs created with such a type, + remain valid. */ void set_sizetype (tree type) { - tree t; + tree t, max; int oprecision = TYPE_PRECISION (type); /* The *bitsizetype types use a precision that avoids overflows when calculating signed sizes / offsets in bits. However, when @@ -2257,11 +2255,11 @@ set_sizetype (tree type) if (precision > HOST_BITS_PER_WIDE_INT * 2) precision = HOST_BITS_PER_WIDE_INT * 2; - gcc_assert (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (sizetype)); + /* sizetype must be an unsigned type. */ + gcc_assert (TYPE_UNSIGNED (type)); t = build_distinct_type_copy (type); - /* We do want to use sizetype's cache, as we will be replacing that - type. */ + /* We want to use sizetype's cache, as we will be replacing that type. */ TYPE_CACHED_VALUES (t) = TYPE_CACHED_VALUES (sizetype); TYPE_CACHED_VALUES_P (t) = TYPE_CACHED_VALUES_P (sizetype); TREE_TYPE (TYPE_CACHED_VALUES (t)) = type; @@ -2273,10 +2271,17 @@ set_sizetype (tree type) TYPE_MAIN_VARIANT (sizetype) = sizetype; TYPE_CANONICAL (sizetype) = sizetype; + /* sizetype is unsigned but we need to fix TYPE_MAX_VALUE so that it is + sign-extended in a way consistent with force_fit_type. */ + max = TYPE_MAX_VALUE (sizetype); + TYPE_MAX_VALUE (sizetype) + = build_int_cst_wide_type (sizetype, + TREE_INT_CST_LOW (max), + TREE_INT_CST_HIGH (max)); + t = make_node (INTEGER_TYPE); TYPE_NAME (t) = get_identifier ("bit_size_type"); - /* We do want to use bitsizetype's cache, as we will be replacing that - type. */ + /* We want to use bitsizetype's cache, as we will be replacing that type. */ TYPE_CACHED_VALUES (t) = TYPE_CACHED_VALUES (bitsizetype); TYPE_CACHED_VALUES_P (t) = TYPE_CACHED_VALUES_P (bitsizetype); TYPE_PRECISION (t) = precision; @@ -2288,36 +2293,13 @@ set_sizetype (tree type) TYPE_MAIN_VARIANT (bitsizetype) = bitsizetype; TYPE_CANONICAL (bitsizetype) = bitsizetype; - if (TYPE_UNSIGNED (type)) - { - fixup_unsigned_type (bitsizetype); - ssizetype = make_signed_type (oprecision); - TYPE_IS_SIZETYPE (ssizetype) = 1; - sbitsizetype = make_signed_type (precision); - TYPE_IS_SIZETYPE (sbitsizetype) = 1; - } - else - { - fixup_signed_type (bitsizetype); - ssizetype = sizetype; - sbitsizetype = bitsizetype; - } - - /* If SIZETYPE is unsigned, we need to fix TYPE_MAX_VALUE so that - it is sign extended in a way consistent with force_fit_type. */ - if (TYPE_UNSIGNED (type)) - { - tree orig_max, new_max; + fixup_unsigned_type (bitsizetype); - orig_max = TYPE_MAX_VALUE (sizetype); - - /* Build a new node with the same values, but a different type. - Sign extend it to ensure consistency. */ - new_max = build_int_cst_wide_type (sizetype, - TREE_INT_CST_LOW (orig_max), - TREE_INT_CST_HIGH (orig_max)); - TYPE_MAX_VALUE (sizetype) = new_max; - } + /* Create the signed variants of *sizetype. */ + ssizetype = make_signed_type (oprecision); + TYPE_IS_SIZETYPE (ssizetype) = 1; + sbitsizetype = make_signed_type (precision); + TYPE_IS_SIZETYPE (sbitsizetype) = 1; } /* TYPE is an integral type, i.e., an INTEGRAL_TYPE, ENUMERAL_TYPE diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b58bb508e88..d057d15e267 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,191 @@ +2010-04-22 Uros Bizjak + + * gcc.dg/graphite/interchange-0.c: Fix dg-final directive. + +2010-04-22 Ira Rosen + + PR tree-optimization/43842 + * gcc.dg/vect/pr43842.c: New test. + +2010-04-22 Bernd Schmidt + + * gcc.target/i386/wmul-1.c: Add dg-require-effective-target ilp32. + * gcc.target/i386/wmul-2.c: Likewise. + +2010-04-22 Kaveh R. Ghazi + + * gcc.dg/torture/builtin-cproj-3.c: Rename and move ... + * gcc.dg/cproj-fails-with-broken-glibc.c: ... to here. + +2010-04-22 Alexander Monakov + + * gfortran.dg/reassoc_6.f: New testcase. + +2010-04-22 Bernd Schmidt + + PR middle-end/29274 + * gcc.target/arm/wmul-1.c: New test. + * gcc.target/arm/wmul-2.c: New test. + +2010-04-22 Richard Guenther + + PR tree-optimization/43845 + * gcc.c-torture/compile/pr43845.c: New testcase. + +2010-04-22 Bernd Schmidt + + PR middle-end/29274 + * gcc.target/i386/wmul-1.c: New test. + * gcc.target/i386/wmul-2.c: New test. + * gcc.target/bfin/wmul-1.c: New test. + * gcc.target/bfin/wmul-2.c: New test. + +2010-04-22 Richard Guenther + + PR fortran/43829 + * gfortran.dg/vector_subscript_6.f90: New testcase. + * gfortran.dg/assign_10.f90: Adjust. + +2010-04-21 Jakub Jelinek + + PR fortran/43836 + * gfortran.dg/gomp/pr43836.f90: New test. + +2010-04-21 Richard Guenther + + * gcc.dg/ipa/ipa-pta-11.c: Adjust. + +2010-04-21 Kaveh R. Ghazi + + * gcc.dg/torture/builtin-cproj-3.c: New. + +2010-04-20 Jason Merrill + + PR c++/9335 + * g++.dg/template/recurse2.C: New. + * g++.dg/parse/crash36.C: Adjust. + * g++.dg/other/fold1.C: Adjust. + * g++.dg/init/member1.C: Adjust. + * lib/prune.exp: Prune "skipping N instantiation contexts". + +2010-04-20 Kaveh R. Ghazi + + * gcc.dg/torture/builtin-cproj-1.c: Test more cases. + +2010-04-20 Kaveh R. Ghazi + + * gcc.dg/torture/builtin-cproj-1.c: New. + * gcc.dg/torture/builtin-cproj-2.c: New. + +2010-04-20 Dodji Seketeli + + PR c++/43800 + PR c++/43704 + * g++.dg/template/typedef32.C: Adjust. + * g++.dg/template/typedef33.C: New test. + +2010-04-20 Paul Thomas + + PR fortran/43227 + * gfortran.dg/proc_decl_23.f90: New test. + + PR fortran/43266 + * gfortran.dg/abstract_type_6.f03: New test. + +2010-04-20 Xinliang David Li + + * g++.dg/tree-ssa/fold-compare.C: New. + +2010-04-20 Richard Guenther + + PR tree-optimization/39417 + * g++.dg/torture/pr39417.C: New testcase. + +2010-04-20 Richard Guenther + + * gcc.dg/ipa/ipa-pta-14.c: New testcase. + +2010-04-20 Jakub Jelinek + + * g++.dg/debug/dwarf2/rv1.C: New test. + +2010-04-20 Andreas Krebbel + + PR target/43635 + * gcc.c-torture/compile/pr43635.c: New testcase. + +2010-04-19 Jakub Jelinek + + PR fortran/43339 + * gfortran.dg/gomp/sharing-2.f90: Adjust for iteration vars + of sequential loops being private only in the innermost containing + task region. + + PR middle-end/43337 + * gfortran.dg/gomp/pr43337.f90: New test. + +2010-04-19 Richard Guenther + + PR tree-optimization/43796 + * gfortran.dg/pr43796.f90: New testcase. + +2010-04-19 Richard Guenther + + PR tree-optimization/43783 + * gcc.c-torture/execute/pr43783.c: New testcase. + +2010-04-19 Uros Bizjak + + PR target/43766 + * gcc.target/i386/pr43766.c: New test. + +2010-04-19 Jie Zhang + + PR target/43662 + * gcc.target/i386/pr43662.c: New test. + +2010-04-19 Dodji Seketeli + + PR c++/43704 + * g++.dg/template/typedef32.C: New test. + +2010-04-19 Ira Rosen + + PR tree-optimization/37027 + * lib/target-supports.exp + (check_effective_target_vect_widen_sum_hi_to_si_pattern): New. + * gcc.dg/vect/pr37027.c: New test. + * gcc.dg/vect/slp-reduc-1.c, gcc.dg/vect/slp-reduc-2.c, + gcc.dg/vect/slp-reduc-3.c, gcc.dg/vect/slp-reduc-4.c, + gcc.dg/vect/slp-reduc-5.c, gcc.dg/vect/slp-reduc-6.c, + gcc.dg/vect/vect-complex-6.c: Likewise. + +2010-04-19 Jakub Jelinek + + * g++.dg/debug/dwarf2/enum1.C: New test. + +2010-04-18 Eric Botcazou + + * gnat.dg/rep_clause5.ad[sb]: New test. + * gnat.dg/rep_clause5_pkg.ads: New helper. + +2010-04-18 Ira Rosen + + PR tree-optimization/43771 + * g++.dg/vect/pr43771.cc: New test. + +2010-04-17 Steven G. Kargl + + PR fortran/31538 + * gfortran.dg/bounds_check_fail_4.f90: Adjust error message. + * gfortran.dg/bounds_check_fail_3.f90: Ditto. + +2010-04-17 Eric Botcazou + + * gnat.dg/sizetype.adb: Rename into... + * gnat.dg/sizetype1.adb: ...this. + * gnat.dg/sizetype2.adb: New test. + 2010-04-16 Richard Guenther PR tree-optimization/43572 @@ -2112,7 +2300,7 @@ * g++.dg/cpp0x/initlist-opt.C: Declare max_val inline. -2010-02-16 Ira Rosen +2010-02-16 Ira Rosen PR tree-optimization/43074 * gcc.dg/vect/fast-math-pr43074.c: New test. diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/enum1.C b/gcc/testsuite/g++.dg/debug/dwarf2/enum1.C new file mode 100644 index 00000000000..b5518ef18a0 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/enum1.C @@ -0,0 +1,19 @@ +// { dg-do compile } +// { dg-options "-g -dA -gno-strict-dwarf -std=c++0x" } +// { dg-final { scan-assembler-times "DIE\[^\n\r\]*DW_TAG_enumeration_type" 3 } } +// { dg-final { scan-assembler-times " DW_AT_enum_class" 2 } } + +enum A { a1, a2 } a; +enum struct B { b1, b2 } b; +enum class C { c1, c2 } c; + +void +foo () +{ + a = a1; + a = A::a2; + b = B::b1; + b = B::b2; + c = C::c1; + c = C::c2; +} diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/rv1.C b/gcc/testsuite/g++.dg/debug/dwarf2/rv1.C new file mode 100644 index 00000000000..c954daa91a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/rv1.C @@ -0,0 +1,15 @@ +// { dg-do compile } +// { dg-options "-g -dA -gdwarf-4 -std=c++0x" } +// { dg-final { scan-assembler-times "DIE\[^\n\r\]*DW_TAG_reference_type" 1 } } +// { dg-final { scan-assembler-times "DIE\[^\n\r\]*DW_TAG_rvalue_reference_type" 1 } } + +struct A { A (); ~A (); }; +struct B { B (); ~B (); }; + +void +foo () +{ + A v; + A &a = v; + B &&b = B (); +} diff --git a/gcc/testsuite/g++.dg/init/member1.C b/gcc/testsuite/g++.dg/init/member1.C index e2af0809c71..aededf23e7b 100644 --- a/gcc/testsuite/g++.dg/init/member1.C +++ b/gcc/testsuite/g++.dg/init/member1.C @@ -11,7 +11,7 @@ template struct B {}; template struct C { static const int i = A::i; // { dg-error "incomplete" } - static const int j = i; // { dg-error "non-constant expression" } + static const int j = i; B b; // { dg-error "not a valid template arg" } }; diff --git a/gcc/testsuite/g++.dg/other/fold1.C b/gcc/testsuite/g++.dg/other/fold1.C index b085a84f0dd..b075fc10c80 100644 --- a/gcc/testsuite/g++.dg/other/fold1.C +++ b/gcc/testsuite/g++.dg/other/fold1.C @@ -4,5 +4,5 @@ struct A { static const int i = i; // { dg-error "not declared" } - int x[i]; // { dg-error "integral constant-expression" } + int x[i]; }; diff --git a/gcc/testsuite/g++.dg/parse/crash36.C b/gcc/testsuite/g++.dg/parse/crash36.C index 6f5c86734a8..6116eb0f9eb 100644 --- a/gcc/testsuite/g++.dg/parse/crash36.C +++ b/gcc/testsuite/g++.dg/parse/crash36.C @@ -9,4 +9,4 @@ template struct A // { dg-warning "variadic templates" } static const int i = sizeof (++t); // { dg-error "was not declared in this scope" } }; -int x[A ::i]; // { dg-error "is not an integral constant-expression" } +int x[A ::i]; diff --git a/gcc/testsuite/g++.dg/template/recurse2.C b/gcc/testsuite/g++.dg/template/recurse2.C new file mode 100644 index 00000000000..cf085e0d553 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/recurse2.C @@ -0,0 +1,7 @@ +// PR c++/9335 +// We should not see an error about non-constant initialization. + +template struct X { + static const int value = X::value; // { dg-error "instantiation|incomplete" } +}; +template struct X<1000>; diff --git a/gcc/testsuite/g++.dg/template/typedef32.C b/gcc/testsuite/g++.dg/template/typedef32.C new file mode 100644 index 00000000000..b32e66c3f88 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef32.C @@ -0,0 +1,46 @@ +// Origin: PR c++/43704 +// { dg-do compile } + +template +struct if_ +{ + typedef T2 type; +}; + +template +struct iterator_restrict_traits +{ + struct iterator_category {}; +}; + +template +struct matrix +{ + struct ci {struct ic {};}; + class i {}; +}; + +template +struct triangular_adaptor +{ + typedef typename if_::type ty1; + class iterator2 : iterator_restrict_traits::iterator_category + { + }; +}; + +template +struct banded_adaptor +{ + typedef typename if_::type ty1; + class iterator1 : iterator_restrict_traits::iterator_category + { + }; +}; + +template +struct singular_decomposition +{ + banded_adaptor >::iterator1 it1; +}; + diff --git a/gcc/testsuite/g++.dg/template/typedef33.C b/gcc/testsuite/g++.dg/template/typedef33.C new file mode 100644 index 00000000000..1d2117b3a41 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef33.C @@ -0,0 +1,21 @@ +// Origin PR c++/43800 +// { dg-do compile } + +template +struct V +{ + typedef T t_type; +}; + +template +class J +{ + typedef typename V::t_type t_type; + const t_type& f(); // #0: +private: + t_type b; +}; + +template +const typename V::t_type& J::f() {return b;} // #1 + diff --git a/gcc/testsuite/g++.dg/torture/pr39417.C b/gcc/testsuite/g++.dg/torture/pr39417.C new file mode 100644 index 00000000000..b7bbb88b784 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr39417.C @@ -0,0 +1,56 @@ +// { dg-do run } + +#include + +std::vector +sequence(int l, int n) +{ + std::vector ret; + for(int i=n;i<=100;i++) + { + if(i%2==0) + { + if(l%i==i/2) + { + int init =l/i-i/2+1; + if(init>=0) + { + for(int j=0;j=0) + { + for(int j=0;j res = sequence(18, 2); + if (res.size () != 3 + || res[0] != 5 + || res[1] != 6 + || res[2] != 7) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/fold-compare.C b/gcc/testsuite/g++.dg/tree-ssa/fold-compare.C new file mode 100644 index 00000000000..2b4c41103ba --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/fold-compare.C @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +struct ExtentsBase { + ExtentsBase() : startx_(), endx_() { } + ExtentsBase(const ExtentsBase &b) { + *this = b; + } + + const ExtentsBase & operator=(const ExtentsBase &b) { + if (this != &b) { + startx_ = b.startx_; + } + return *this; + } + + int startx_; + int endx_; +}; + +int f(const ExtentsBase &e1) { + ExtentsBase my_extents = e1; + return my_extents.startx_; +} + +/* { dg-final { scan-tree-dump-not "&my_extents" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ + diff --git a/gcc/testsuite/g++.dg/vect/pr43771.cc b/gcc/testsuite/g++.dg/vect/pr43771.cc new file mode 100644 index 00000000000..1a2d09aae93 --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/pr43771.cc @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +void KWayNodeRefine__(int nparts, int *gpwgts, int *badminpwgt, int +*badmaxpwgt) +{ + int i; + + for (i=0; issd(); + return i_ssd; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr43783.c b/gcc/testsuite/gcc.c-torture/execute/pr43783.c new file mode 100644 index 00000000000..3880026c405 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr43783.c @@ -0,0 +1,21 @@ +typedef __attribute__((aligned(16))) +struct { + unsigned long long w[3]; +} UINT192; + +UINT192 bid_Kx192[32]; + +extern void abort (void); + +int main() +{ + int i = 0; + unsigned long x = 0; + for (i = 0; i < 32; ++i) + bid_Kx192[i].w[1] = i == 1; + for (i = 0; i < 32; ++i) + x += bid_Kx192[1].w[1]; + if (x != 32) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/cproj-fails-with-broken-glibc.c b/gcc/testsuite/gcc.dg/cproj-fails-with-broken-glibc.c new file mode 100644 index 00000000000..fe143b9ea5b --- /dev/null +++ b/gcc/testsuite/gcc.dg/cproj-fails-with-broken-glibc.c @@ -0,0 +1,25 @@ +/* Copyright (C) 2010 Free Software Foundation. + + Check the runtime behavior of the C library's cproj() function and + whether it follows the standard. Versions of GLIBC through 2.11.1 + had an incorrect implementation which will conflict with GCC's + builtin cproj(). GLIBC 2.12+ should be okay. + + Origin: Kaveh R. Ghazi, April 20, 2010. */ + +/* { dg-do run } */ +/* { dg-options "-fno-builtin-cproj" } */ +/* { dg-add-options c99_runtime } */ +/* { dg-require-effective-target c99_runtime } */ + +extern void abort(void); +extern void exit(int); +double _Complex cproj(double _Complex); + +int main (void) +{ + if (cproj (2+3i) != 2+3i) + abort(); + + exit(0); +} diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-0.c b/gcc/testsuite/gcc.dg/graphite/interchange-0.c index b6e382c0a6f..8bc6e132664 100644 --- a/gcc/testsuite/gcc.dg/graphite/interchange-0.c +++ b/gcc/testsuite/gcc.dg/graphite/interchange-0.c @@ -47,4 +47,4 @@ main (void) } /* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */ -/* { dg -final { cleanup-tree-dump "graphite" } } */ +/* { dg-final { cleanup-tree-dump "graphite" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c index 947ab816fc9..6ef7438dd6b 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c @@ -29,5 +29,5 @@ int main() /* It isn't clear if the escape if l is strictly necessary, if it were we should have i, r and s in ESCAPED as well. */ -/* { dg-final { scan-ipa-dump "ESCAPED = { ESCAPED NONLOCAL l k }" "pta" } } */ +/* { dg-final { scan-ipa-dump "ESCAPED = { l k }" "pta" } } */ /* { dg-final { cleanup-ipa-dump "pta" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c new file mode 100644 index 00000000000..ffe16ccc358 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c @@ -0,0 +1,32 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fipa-pta -fno-tree-sra -fdump-ipa-pta-details" } */ + +struct X { + int i; + void *p; +}; + +static void * __attribute__((noinline,noclone)) +foo(struct X *q, void *p) +{ + struct X b; + b.p = p; + *q = b; + return q->p; +} +extern void abort (void); +int main() +{ + struct X a, c; + void *p; + a.p = (void *)&c; + p = foo(&a, &a); + /* { dg-final { scan-ipa-dump "foo.result = { NULL a c }" "pta" { xfail *-*-* } } } */ + /* { dg-final { scan-ipa-dump "foo.result = { NULL a a\[^ \]* c }" "pta" } } */ + ((struct X *)p)->p = (void *)0; + if (a.p != (void *)0) + abort (); + return 0; +} + +/* { dg-final { cleanup-ipa-dump "pta" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c b/gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c new file mode 100644 index 00000000000..31cd5874ffb --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c @@ -0,0 +1,175 @@ +/* Copyright (C) 2010 Free Software Foundation. + + Verify that folding of built-in cproj is correctly performed by the + compiler. + + Origin: Kaveh R. Ghazi, April 9, 2010. */ + +/* { dg-do link } */ + +/* All references to link_error should go away at compile-time. The + argument is the __LINE__ number. It appears in the tree dump file + and aids in debugging should any of the tests fail. */ +extern void link_error(int); + +#define CPROJ(X) __builtin_cproj(X) +#define CPROJF(X) __builtin_cprojf(X) +#define CPROJL(X) __builtin_cprojl(X) +#define INF __builtin_inff() +#define I 1i +#define CPSGN(X,Y) __builtin_copysignf((X),(Y)) +#define CIMAG(X) __builtin_cimagf(X) +#define CREAL(X) __builtin_crealf(X) + +/* Check that the signs of the real and/or imaginary parts of two + complex numbers match. */ +#define CKSGN(X,Y) (CKSGN_R(X,Y) || CKSGN_I(X,Y)) +#define CKSGN_R(X,Y) (CPSGN(1,CREAL(X)) != CPSGN(1,CREAL(Y))) +#define CKSGN_I(X,Y) (CPSGN(1,CIMAG(X)) != CPSGN(1,CIMAG(Y))) + +/* Test that (cproj(X) == ZERO+Inf) and that the signs of the + imaginary parts match. ZERO is +/- 0i. */ +#define TEST_CST_INF(X,ZERO) do { \ + if (CPROJF(X) != ZERO+INF || CKSGN_I(CPROJF(X),ZERO+INF)) \ + link_error(__LINE__); \ + if (CPROJ(X) != ZERO+INF || CKSGN_I(CPROJ(X),ZERO+INF)) \ + link_error(__LINE__); \ + if (CPROJL(X) != ZERO+INF || CKSGN_I(CPROJL(X),ZERO+INF)) \ + link_error(__LINE__); \ +} while (0) + +/* Test that (cproj(X) == X) for all finite (X). */ +#define TEST_CST(X) do { \ + if (CPROJF(X) != (X) || CKSGN(CPROJF(X),(X))) \ + link_error(__LINE__); \ +} while (0) + +/* Test that cproj(X + I*INF) -> (ZERO + INF), where ZERO is +-0i. + NEG is either blank or a minus sign when ZERO is negative. */ +#define TEST_IMAG_INF(NEG,ZERO) do { \ + if (CPROJF(f+I*NEG INF) != ZERO+INF \ + || CKSGN_I (CPROJF(f+I*NEG INF), ZERO+INF)) \ + link_error(__LINE__); \ + if (CPROJ(d+I*NEG INF) != ZERO+INF \ + || CKSGN_I (CPROJ(d+I*NEG INF), ZERO+INF)) \ + link_error(__LINE__); \ + if (CPROJL(ld+I*NEG INF) != ZERO+INF \ + || CKSGN_I (CPROJL(ld+I*NEG INF), ZERO+INF)) \ + link_error(__LINE__); \ +} while (0) + +/* Like TEST_IMAG_INF, but check that side effects are honored. */ +#define TEST_IMAG_INF_SIDE_EFFECT(NEG,ZERO) do { \ + int side = 4; \ + if (CPROJF(++side+I*NEG INF) != ZERO+INF \ + || CKSGN_I (CPROJF(++side+I*NEG INF), ZERO+INF)) \ + link_error(__LINE__); \ + if (CPROJ(++side+I*NEG INF) != ZERO+INF \ + || CKSGN_I (CPROJ(++side+I*NEG INF), ZERO+INF)) \ + link_error(__LINE__); \ + if (CPROJL(++side+I*NEG INF) != ZERO+INF \ + || CKSGN_I (CPROJL(++side+I*NEG INF), ZERO+INF)) \ + link_error(__LINE__); \ + if (side != 10) \ + link_error(__LINE__); \ +} while (0) + +/* Test that cproj(INF, POSITIVE) -> INF+0i. NEG is either blank or a + minus sign to test negative INF. */ +#define TEST_REAL_INF(NEG) do { \ + __real cf = NEG INF; \ + __imag cf = (x ? 4 : 5); \ + if (CPROJF(cf) != INF \ + || CKSGN_I (CPROJF(cf), INF)) \ + link_error(__LINE__); \ + __real cd = NEG INF; \ + __imag cd = (x ? 4 : 5); \ + if (CPROJ(cd) != INF \ + || CKSGN_I (CPROJ(cd), INF)) \ + link_error(__LINE__); \ + __real cld = NEG INF; \ + __imag cld = (x ? 4 : 5); \ + if (CPROJL(cld) != INF \ + || CKSGN_I (CPROJL(cld), INF)) \ + link_error(__LINE__); \ +} while (0) + +/* Like TEST_REAL_INF, but check that side effects are honored. */ +#define TEST_REAL_INF_SIDE_EFFECT(NEG) do { \ + int side = -9; \ + __real cf = NEG INF; \ + __imag cf = (x ? 4 : 5); \ + if (CPROJF((++side,cf)) != INF \ + || CKSGN_I (CPROJF((++side,cf)), INF)) \ + link_error(__LINE__); \ + __real cd = NEG INF; \ + __imag cd = (x ? 4 : 5); \ + if (CPROJ((++side,cd)) != INF \ + || CKSGN_I (CPROJ((++side,cd)), INF)) \ + link_error(__LINE__); \ + __real cld = NEG INF; \ + __imag cld = (x ? 4 : 5); \ + if (CPROJL((++side,cld)) != INF \ + || CKSGN_I (CPROJL((++side,cld)), INF)) \ + link_error(__LINE__); \ + if (side != -3) \ + link_error(__LINE__); \ +} while (0) + +void foo (_Complex long double cld, _Complex double cd, _Complex float cf, + long double ld, double d, float f, int x) +{ + TEST_CST_INF (INF+0I, 0); + TEST_CST_INF (INF-0I, -0.FI); + TEST_CST_INF (INF+4I, 0); + TEST_CST_INF (INF-4I, -0.FI); + TEST_CST_INF (-INF+0I, 0); + TEST_CST_INF (-INF-0I, -0.FI); + TEST_CST_INF (-INF+4I, 0); + TEST_CST_INF (-INF-4I, -0.FI); + + TEST_CST_INF (0+I*INF, 0); + TEST_CST_INF (0-I*INF, -0.FI); + TEST_CST_INF (23+I*INF, 0); + TEST_CST_INF (23-I*INF, -0.FI); + TEST_CST_INF (-0.F+I*INF, 0); + TEST_CST_INF (-0.F-I*INF, -0.FI); + TEST_CST_INF (-23+I*INF, 0); + TEST_CST_INF (-23-I*INF, -0.FI); + + TEST_CST_INF (INF+I*INF, 0); + TEST_CST_INF (INF-I*INF, -0.FI); + TEST_CST_INF (-INF+I*INF, 0); + TEST_CST_INF (-INF-I*INF, -0.FI); + + TEST_CST (0); + TEST_CST (-0.F); + TEST_CST (0-0.FI); + TEST_CST (-0.F-0.FI); + + TEST_CST (22+3I); + TEST_CST (22-3I); + TEST_CST (-22+3I); + TEST_CST (-22-3I); + + TEST_IMAG_INF (,0.FI); + TEST_IMAG_INF (-,-0.FI); + +#ifdef __OPTIMIZE__ + TEST_REAL_INF( ); + TEST_REAL_INF(-); + + TEST_IMAG_INF_SIDE_EFFECT (,0.FI); + TEST_IMAG_INF_SIDE_EFFECT (-,-0.FI); + + TEST_REAL_INF_SIDE_EFFECT( ); + TEST_REAL_INF_SIDE_EFFECT(-); +#endif + + return; +} + +int main (void) +{ + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/builtin-cproj-2.c b/gcc/testsuite/gcc.dg/torture/builtin-cproj-2.c new file mode 100644 index 00000000000..39331651f19 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/builtin-cproj-2.c @@ -0,0 +1,46 @@ +/* Copyright (C) 2010 Free Software Foundation. + + Verify that folding of built-in cproj is correctly performed by the + compiler. With -ffinite-math-only all cproj calls should be + eliminated regardless of what the argument is, or what is known + about it. + + Origin: Kaveh R. Ghazi, April 9, 2010. */ + +/* { dg-do link } */ +/* { dg-options "-ffinite-math-only" } */ + +/* All references to link_error should go away at compile-time. The + argument is the __LINE__ number. It appears in the tree dump file + and aids in debugging should any of the tests fail. */ +extern void link_error(int); + +#define CPROJ(X) __builtin_cproj(X) +#define CPROJF(X) __builtin_cprojf(X) +#define CPROJL(X) __builtin_cprojl(X) + +/* Test that the supplied expressions eliminte the cproj call. */ +#define TEST_EXPRS(LD_EXPR, D_EXPR, F_EXPR) do { \ + if (CPROJF(F_EXPR) != (F_EXPR)) \ + link_error (__LINE__); \ + if (CPROJ(D_EXPR) != (D_EXPR)) \ + link_error (__LINE__); \ + if (CPROJL(LD_EXPR) != (LD_EXPR)) \ + link_error (__LINE__); \ +} while (0) + +void foo (_Complex long double cld, _Complex double cd, _Complex float cf) +{ +#ifdef __OPTIMIZE__ + TEST_EXPRS (cld, cd, cf); + TEST_EXPRS (cld*2, cd*2, cf*2); + TEST_EXPRS (cld*cld, cd*cd, cf*cf); +#endif + + return; +} + +int main (void) +{ + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr37027.c b/gcc/testsuite/gcc.dg/vect/pr37027.c new file mode 100644 index 00000000000..dcfed348d11 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr37027.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#include + +struct mystr +{ + int f1; + int f2; +}; + +struct mystr a[16]; +struct mystr b[16]; +int res1, res2; + + +void +foo (void) +{ + int i; + int sum1; + int sum2; + + for (i = 0; i < 16; i++) + { + sum1 += a[i].f1 + b[i].f1; + sum2 += a[i].f2 + b[i].f2; + } + + res1 = sum1; + res2 = sum2; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_int_add } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail vect_no_int_add } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr43842.c b/gcc/testsuite/gcc.dg/vect/pr43842.c new file mode 100644 index 00000000000..593404ffbcb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr43842.c @@ -0,0 +1,55 @@ +/* { dg-do compile } */ + +typedef char int8_t; +typedef short int int16_t; +typedef int int32_t; +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; + +static int16_t +safe_rshift_func_int16_t_s_u (int16_t left, unsigned int right) +{ + return left || right >= 1 * 8 ? left : left >> right; +} + +static int8_t +safe_rshift_func_int8_t_s_u (int8_t left, unsigned int right) +{ + return left || right >= 1 * 8 ? left : left >> right; +} + + +static uint32_t +safe_add_func_uint32_t_u_u (uint32_t ui1, uint16_t ui2) +{ + return ui1 + ui2; +} + +int16_t g_4; +int8_t g_4_8; +uint32_t g_9[1]; +uint32_t g_9_8[2]; +int161 (void) +{ + int32_t l_2; + + for (l_2 = -25; l_2; l_2 = safe_add_func_uint32_t_u_u (l_2, 1)) + g_9[0] ^= safe_rshift_func_int16_t_s_u (g_4, 1); +} + +int81 (void) +{ + int32_t l_2; + + for (l_2 = -25; l_2; l_2 = safe_add_func_uint32_t_u_u (l_2, 1)) + { + g_9[0] ^= safe_rshift_func_int8_t_s_u (g_4_8, 1); + g_9[1] ^= safe_rshift_func_int8_t_s_u (g_4_8, 1); + } + + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-1.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-1.c new file mode 100644 index 00000000000..95faba8e9d4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-1.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include +#include "tree-vect.h" + +#define N 16 + +unsigned int ub[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned int uc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +/* Vectorization of reduction using loop-aware SLP. */ + +__attribute__ ((noinline)) +int main1 (int n, int res0, int res1, int res2, int res3) +{ + int i; + unsigned int udiff0 = 5, udiff1 = 10, udiff2 = 20, udiff3 = 30; + + for (i = 0; i < n; i++) { + udiff3 += (ub[4*i + 3] - uc[4*i + 3]); + udiff2 += (ub[4*i + 2] - uc[4*i + 2]); + udiff1 += (ub[4*i + 1] - uc[4*i + 1]); + udiff0 += (ub[4*i] - uc[4*i]); + } + + /* Check results: */ + if (udiff0 != res0 + || udiff1 != res1 + || udiff2 != res2 + || udiff3 != res3) + abort (); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (N/4, 53, 66, 84, 102); + main1 (N/4 - 1, 29, 40, 56, 72); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_int_add } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail vect_no_int_add } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-2.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-2.c new file mode 100644 index 00000000000..cb59c8c07ea --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-2.c @@ -0,0 +1,44 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include +#include "tree-vect.h" + +#define N 16 + +unsigned int ub[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned int uc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +/* Vectorization of reduction using loop-aware SLP (with unrolling). */ + +__attribute__ ((noinline)) +int main1 (int n, int res0, int res1, int res2, int res3) +{ + int i; + unsigned int udiff0 = 5, udiff1 = 10; + + for (i = 0; i < n; i++) { + udiff1 += (ub[2*i + 1] - uc[2*i + 1]); + udiff0 += (ub[2*i] - uc[2*i]); + } + + /* Check results: */ + if (udiff0 != res0 + || udiff1 != res1) + abort (); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (N/2, 117, 138, 84, 102); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_int_add } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail vect_no_int_add } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-3.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-3.c new file mode 100644 index 00000000000..3220d3912ba --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-3.c @@ -0,0 +1,62 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" + +#define N 64 + +#define DOT1 21834 +#define DOT2 21876 + +unsigned short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned short Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +/* short->short->int dot product. + Not detected as a dot-product pattern. + Requires support for non-widneing multiplication and widening-summation. + Vectorized with loop-aware SLP. */ +__attribute__ ((noinline)) unsigned int +foo1(int len, int *result1, int *result2) +{ + int i; + unsigned int res1 = 10, res2 = 20; + unsigned short prod; + + for (i=0; i +#include +#include "tree-vect.h" + +#define N 128 + +unsigned int uc[N]; + +/* Vectorization of reduction using loop-aware SLP. */ + +__attribute__ ((noinline)) +int main1 (int n, int res0, int res1, int res2, int res3, int res4, int res5, int res6, int res7) +{ + int i; + unsigned int max0 = 5, max1 = 10, max2 = 20, max3 = 30, max4 = 2, max5 = 13, max6 = 7, max7 = 313; + + for (i = 0; i < n; i++) { + max2 = max2 < uc[8*i+2] ? uc[8*i+2] : max2; + max3 = max3 < uc[8*i+3] ? uc[8*i+3] : max3; + max1 = max1 < uc[8*i+1] ? uc[8*i+1] : max1; + max7 = max7 < uc[8*i+7] ? uc[8*i+7] : max7; + max6 = max6 < uc[8*i+6] ? uc[8*i+6] : max6; + max0 = max0 < uc[8*i] ? uc[8*i] : max0; + max4 = max4 < uc[8*i+4] ? uc[8*i+4] : max4; + max5 = max5 < uc[8*i+5] ? uc[8*i+5] : max5; + } + + /* Check results: */ + if (max0 != res0 + || max1 != res1 + || max2 != res2 + || max3 != res3 + || max4 != res4 + || max5 != res5 + || max6 != res6 + || max7 != res7) + abort (); + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + for (i = 0; i < N; i++) + uc[i] = i+3; + + main1 (N/8, 123, 124, 125, 126, 127, 128, 129, 313); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-5.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-5.c new file mode 100644 index 00000000000..0974b6642d8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-5.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include +#include "tree-vect.h" + +#define N 128 + +int c[N]; + +/* Vectorization of reduction using loop-aware SLP. */ + +__attribute__ ((noinline)) +int main1 (int n, int res0, int res1) +{ + int i; + int max0 = -100, max1 = -313; + + for (i = 0; i < n; i++) { + max1 = max1 < c[2*i+1] ? c[2*i+1] : max1; + max0 = max0 < c[2*i] ? c[2*i] : max0; + } + + /* Check results: */ + if (max0 != res0 + || max1 != res1) + abort (); + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + for (i = 0; i < N; i++) + c[i] = (i+3) * -1; + + c[0] = c[1] = -100; + main1 (N/2, -5, -6); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-6.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-6.c new file mode 100644 index 00000000000..c69251a76e2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-6.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include +#include "tree-vect.h" + +#define N 128 + +int a[N], b[N]; + +/* Vectorization of reduction. Loop-aware SLP is not possible, because of + different arrays. */ + +__attribute__ ((noinline)) +int main1 (int n, int res0, int res1) +{ + int i; + int sum0 = 0, sum1 = 0; + + for (i = 0; i < n; i++) { + sum1 += a[2*i]; + sum0 += b[2*i]; + } + + /* Check results: */ + if (sum0 != res0 + || sum1 != res1) + abort (); + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + for (i = 0; i < N; i++) + a[i] = b[i] = i; + + main1 (N/2, 4032, 4032); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail vect_no_int_add } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "different interleaving chains in one node" 1 "vect" { target { ! vect_no_int_add } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.target/arm/wmul-1.c b/gcc/testsuite/gcc.target/arm/wmul-1.c new file mode 100644 index 00000000000..df85e7cb285 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/wmul-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv6t2" } */ + +int mac(const short *a, const short *b, int sqr, int *sum) +{ + int i; + int dotp = *sum; + + for (i = 0; i < 150; i++) { + dotp += b[i] * a[i]; + sqr += b[i] * b[i]; + } + + *sum = dotp; + return sqr; +} + +/* { dg-final { scan-assembler-times "smulbb" 2 } } */ diff --git a/gcc/testsuite/gcc.target/arm/wmul-2.c b/gcc/testsuite/gcc.target/arm/wmul-2.c new file mode 100644 index 00000000000..0c092f10115 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/wmul-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv6t2" } */ + +void vec_mpy(int y[], const short x[], short scaler) +{ + int i; + + for (i = 0; i < 150; i++) + y[i] += ((scaler * x[i]) >> 31); +} + +/* { dg-final { scan-assembler-times "smulbb" 1 } } */ diff --git a/gcc/testsuite/gcc.target/bfin/wmul-1.c b/gcc/testsuite/gcc.target/bfin/wmul-1.c new file mode 100644 index 00000000000..f17fc199e8c --- /dev/null +++ b/gcc/testsuite/gcc.target/bfin/wmul-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int mac(const short *a, const short *b, int sqr, int *sum) +{ + int i; + int dotp = *sum; + + for (i = 0; i < 150; i++) { + dotp += b[i] * a[i]; + sqr += b[i] * b[i]; + } + + *sum = dotp; + return sqr; +} + +/* { dg-final { scan-assembler-times "\\(IS\\)" 2 } } */ diff --git a/gcc/testsuite/gcc.target/bfin/wmul-2.c b/gcc/testsuite/gcc.target/bfin/wmul-2.c new file mode 100644 index 00000000000..2f2d2527e69 --- /dev/null +++ b/gcc/testsuite/gcc.target/bfin/wmul-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +void vec_mpy(int y[], const short x[], short scaler) +{ + int i; + + for (i = 0; i < 150; i++) + y[i] += ((scaler * x[i]) >> 31); +} + +/* { dg-final { scan-assembler-times "\\(IS\\)" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr43662.c b/gcc/testsuite/gcc.target/i386/pr43662.c new file mode 100644 index 00000000000..246c8aafa6e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr43662.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O2" } */ + +void __attribute__ ((ms_abi)) foo (void) +{ +} + +typedef struct _IAVIStreamImpl +{ + int sInfo; + int has; +} IAVIStreamImpl; + +extern int __attribute__ ((ms_abi)) aso (void *); +extern int sre (void *); + +int AVIFILE_OpenCompressor (IAVIStreamImpl *This) +{ + if (This->has != 0) + aso (&This->has); + sre (&This->sInfo); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr43766.c b/gcc/testsuite/gcc.target/i386/pr43766.c new file mode 100644 index 00000000000..701be6ef6f8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr43766.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-options "-O2 -msse -mregparm=3" { target ilp32 } } */ + +void p (int *a, int i) +{ + __builtin_prefetch (&a[i]); +} + +/* { dg-final { scan-assembler-not "lea" } } */ diff --git a/gcc/testsuite/gcc.target/i386/wmul-1.c b/gcc/testsuite/gcc.target/i386/wmul-1.c new file mode 100644 index 00000000000..3497f71ce54 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/wmul-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target ilp32 } */ + +long long mac(const int *a, const int *b, long long sqr, long long *sum) +{ + int i; + long long dotp = *sum; + + for (i = 0; i < 150; i++) { + dotp += (long long)b[i] * a[i]; + sqr += (long long)b[i] * b[i]; + } + + *sum = dotp; + return sqr; +} + +/* { dg-final { scan-assembler-times "imull" 2 } } */ diff --git a/gcc/testsuite/gcc.target/i386/wmul-2.c b/gcc/testsuite/gcc.target/i386/wmul-2.c new file mode 100644 index 00000000000..51de26960de --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/wmul-2.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target ilp32 } */ + +void vec_mpy(int y[], const int x[], int scaler) +{ + int i; + + for (i = 0; i < 150; i++) + y[i] += (((long long)scaler * x[i]) >> 31); +} + +/* { dg-final { scan-assembler-times "imull" 1 } } */ diff --git a/gcc/testsuite/gfortran.dg/abstract_type_6.f03 b/gcc/testsuite/gfortran.dg/abstract_type_6.f03 new file mode 100644 index 00000000000..bc8e5437ad5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/abstract_type_6.f03 @@ -0,0 +1,53 @@ +! { dg-do "compile" } +! Test the fix for PR43266, in which an ICE followed correct error messages. +! +! Contributed by Tobias Burnus +! Reported in http://groups.google.ca/group/comp.lang.fortran/browse_thread/thread/f5ec99089ea72b79 +! +!---------------- +! library code + +module m +TYPE, ABSTRACT :: top +CONTAINS + PROCEDURE(xxx), DEFERRED :: proc_a ! { dg-error "must be a module procedure" } + ! some useful default behaviour + PROCEDURE :: proc_c => top_c ! { dg-error "must be a module procedure" } +END TYPE top + +! Concrete middle class with useful behaviour +TYPE, EXTENDS(top) :: middle +CONTAINS + ! do nothing, empty proc just to make middle concrete + PROCEDURE :: proc_a => dummy_middle_a ! { dg-error "must be a module procedure" } + ! some useful default behaviour + PROCEDURE :: proc_b => middle_b ! { dg-error "must be a module procedure" } +END TYPE middle + +!---------------- +! client code + +TYPE, EXTENDS(middle) :: bottom +CONTAINS + ! useful proc to satisfy deferred procedure in top. Because we've + ! extended middle we wouldn't get told off if we forgot this. + PROCEDURE :: proc_a => bottom_a + ! calls middle%proc_b and then provides extra behaviour + PROCEDURE :: proc_b => bottom_b + ! calls top_c and then provides extra behaviour + PROCEDURE :: proc_c => bottom_c +END TYPE bottom +contains +SUBROUTINE bottom_b(obj) + CLASS(Bottom) :: obj + CALL obj%middle%proc_b ! { dg-error "should be a SUBROUTINE" } + ! other stuff +END SUBROUTINE bottom_b + +SUBROUTINE bottom_c(obj) + CLASS(Bottom) :: obj + CALL top_c(obj) + ! other stuff +END SUBROUTINE bottom_c +end module +! { dg-final { cleanup-modules "m" } } diff --git a/gcc/testsuite/gfortran.dg/assign_10.f90 b/gcc/testsuite/gfortran.dg/assign_10.f90 index afe09d52c57..e52302556fe 100644 --- a/gcc/testsuite/gfortran.dg/assign_10.f90 +++ b/gcc/testsuite/gfortran.dg/assign_10.f90 @@ -19,10 +19,10 @@ if (any(p8 .ne. q8)) call abort () end ! Whichever is the default length for array indices will yield -! parm 9 times, because a temporary is not necessary. The other -! cases will all yield a temporary, so that atmp appears 27 times. +! parm 18 times, because a temporary is not necessary. The other +! cases will all yield a temporary, so that atmp appears 18 times. ! Note that it is the kind conversion that generates the temp. ! -! { dg-final { scan-tree-dump-times "parm" 9 "original" } } -! { dg-final { scan-tree-dump-times "atmp" 27 "original" } } +! { dg-final { scan-tree-dump-times "parm" 18 "original" } } +! { dg-final { scan-tree-dump-times "atmp" 18 "original" } } ! { dg-final { cleanup-tree-dump "original" } } diff --git a/gcc/testsuite/gfortran.dg/bounds_check_fail_3.f90 b/gcc/testsuite/gfortran.dg/bounds_check_fail_3.f90 index 0826b7d5efc..ce4d0368d57 100644 --- a/gcc/testsuite/gfortran.dg/bounds_check_fail_3.f90 +++ b/gcc/testsuite/gfortran.dg/bounds_check_fail_3.f90 @@ -9,4 +9,4 @@ if (any(x /= (/ 2, 2, 3, 4, 5, 6, 6, 8, 9, 10 /))) call abort() x(8:1:m) = x(5:2:n) end -! { dg-output "line 10 .* bound mismatch, .* dimension 1 .* array \'x\' \\\(3/2\\\)" } +! { dg-output "line 10 .* bound mismatch .* dimension 1 .* array \'x\' \\\(3/2\\\)" } diff --git a/gcc/testsuite/gfortran.dg/bounds_check_fail_4.f90 b/gcc/testsuite/gfortran.dg/bounds_check_fail_4.f90 index dee3ca8d66e..718d0058e49 100644 --- a/gcc/testsuite/gfortran.dg/bounds_check_fail_4.f90 +++ b/gcc/testsuite/gfortran.dg/bounds_check_fail_4.f90 @@ -9,4 +9,4 @@ if (any(x /= (/ 5, 2, 3, 6, 5, 6, 7, 8, 9, 10 /))) call abort() x(8:1:m) = x(1:3) + x(5:2:n) end -! { dg-output "line 10 .* bound mismatch, .* dimension 1 .* array \'x\' \\\(2/3\\\)" } +! { dg-output "line 10 .* bound mismatch .* dimension 1 .* array \'x\' \\\(2/3\\\)" } diff --git a/gcc/testsuite/gfortran.dg/gomp/pr43337.f90 b/gcc/testsuite/gfortran.dg/gomp/pr43337.f90 new file mode 100644 index 00000000000..f07ccb441be --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr43337.f90 @@ -0,0 +1,30 @@ +! PR middle-end/43337 +! { dg-do compile } +! { dg-options "-fopenmp -O2 -g" } + +subroutine pr43337 + integer :: a, b(10) + call foo (b) + call bar (b) +contains + subroutine foo (b) + integer :: b(10) +!$omp parallel if (.false.) +!$omp task if (.false.) shared(b) + do a = 1, 10 + b(a) = 1 + end do +!$omp end task +!$omp end parallel + end subroutine foo + subroutine bar (b) + integer :: b(10) +!$omp parallel if (.false.) +!$omp parallel if (.false.) + do a = 1, 10 + b(a) = 1 + end do +!$omp end parallel +!$omp end parallel + end subroutine bar +end subroutine pr43337 diff --git a/gcc/testsuite/gfortran.dg/gomp/pr43836.f90 b/gcc/testsuite/gfortran.dg/gomp/pr43836.f90 new file mode 100644 index 00000000000..cf86523f52b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr43836.f90 @@ -0,0 +1,10 @@ +! PR fortran/43836 +! { dg-do compile } +! { dg-options "-fopenmp -fexceptions -O2" } +subroutine foo +!$omp single +!$omp parallel + call bar +!$omp end parallel +!$omp end single +end subroutine foo diff --git a/gcc/testsuite/gfortran.dg/gomp/sharing-2.f90 b/gcc/testsuite/gfortran.dg/gomp/sharing-2.f90 index aede06c9c0f..b7d7e072975 100644 --- a/gcc/testsuite/gfortran.dg/gomp/sharing-2.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/sharing-2.f90 @@ -28,10 +28,10 @@ end do !$omp end single !$omp end parallel -!$omp parallel default (none) shared (a) - i = 1 - j = 1 - k = 1 +!$omp parallel default (none) shared (a) ! { dg-error "enclosing parallel" } + i = 1 ! { dg-error "not specified in" } + j = 1 ! { dg-error "not specified in" } + k = 1 ! { dg-error "not specified in" } !$omp parallel default (none) shared (a) i = 1 j = 1 @@ -68,8 +68,8 @@ a(i, 1) = i + 1 end do !$omp end parallel -!$omp parallel default (none) shared (a) - i = 1 +!$omp parallel default (none) shared (a) ! { dg-error "enclosing parallel" } + i = 1 ! { dg-error "not specified in" } !$omp parallel default (none) shared (a, i) i = 2 !$omp parallel default (none) shared (a) diff --git a/gcc/testsuite/gfortran.dg/pr43796.f90 b/gcc/testsuite/gfortran.dg/pr43796.f90 new file mode 100644 index 00000000000..2e98d7ca804 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr43796.f90 @@ -0,0 +1,51 @@ +! { dg-do compile } +! { dg-options "-O2 -fcheck=bounds" } + + FUNCTION F06FKFN(N,W,INCW,X,INCX) + IMPLICIT NONE + INTEGER, PARAMETER :: WP = KIND(0.0D0) + REAL (KIND=WP) :: F06FKFN + REAL (KIND=WP), PARAMETER :: ONE = 1.0E+0_WP + REAL (KIND=WP), PARAMETER :: ZERO = 0.0E+0_WP + INTEGER, INTENT (IN) :: INCW, INCX, N + REAL (KIND=WP), INTENT (IN) :: W(*), X(*) + REAL (KIND=WP) :: ABSYI, NORM, SCALE, SSQ + INTEGER :: I, IW, IX + REAL (KIND=WP), EXTERNAL :: F06BMFN + INTRINSIC ABS, SQRT + IF (N<1) THEN + NORM = ZERO + ELSE IF (N==1) THEN + NORM = SQRT(W(1))*ABS(X(1)) + ELSE + IF (INCW>0) THEN + IW = 1 + ELSE + IW = 1 - (N-1)*INCW + END IF + IF (INCX>0) THEN + IX = 1 + ELSE + IX = 1 - (N-1)*INCX + END IF + SCALE = ZERO + SSQ = ONE + DO I = 1, N + IF ((W(IW)/=ZERO) .AND. (X(IX)/=ZERO)) THEN + ABSYI = SQRT(W(IW))*ABS(X(IX)) + IF (SCALE +! +function char1 (s) result(res) + character, dimension(:), intent(in) :: s + character(len=size(s)) :: res + do i = 1, size(s) + res(i:i) = s(i) + end do +end function char1 + +module m_string + + procedure(string_to_char) :: char1 ! segfault + procedure(string_to_char), pointer :: char2 ! segfault + type t_string + procedure(string_to_char), pointer, nopass :: char3 ! segfault + end type t_string + +contains + + function string_to_char (s) result(res) + character, dimension(:), intent(in) :: s + character(len=size(s)) :: res + do i = 1, size(s) + res(i:i) = s(i) + end do + end function string_to_char + +end module m_string + + use m_string + type(t_string) :: t + print *, string_to_char (["a","b","c"]) + char2 => string_to_char + print *, char2 (["d","e","f"]) + t%char3 => string_to_char + print *, t%char3 (["g","h","i"]) + print *, char1 (["j","k","l"]) +end +! { dg-final { cleanup-tree-dump "m_string" } } diff --git a/gcc/testsuite/gfortran.dg/reassoc_6.f b/gcc/testsuite/gfortran.dg/reassoc_6.f new file mode 100644 index 00000000000..cbc36f5675b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/reassoc_6.f @@ -0,0 +1,20 @@ +! { dg-do compile } +! { dg-options "-O2 -fdump-tree-optimized" } + + subroutine test(nb,nx,r2) + implicit none + integer nb,nx,i,l + real*8 r2(nb,nx) + + + do i=1,nx + do l=1,nb + r2(l,i)=0.0d0 + enddo + enddo + + return + end +! Verify that offset of the first element is simplified +! { dg-final { scan-tree-dump-not "~" "optimized" } } +! { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/gfortran.dg/vector_subscript_6.f90 b/gcc/testsuite/gfortran.dg/vector_subscript_6.f90 new file mode 100644 index 00000000000..51613d11368 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vector_subscript_6.f90 @@ -0,0 +1,33 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } + +subroutine test0(esss,Ix, e_x) + real(kind=kind(1.0d0)), dimension(:), intent(out) :: esss + real(kind=kind(1.0d0)), dimension(:), intent(in) :: Ix + integer(kind=kind(1)), dimension(:), intent(in) :: e_x + esss = Ix(e_x) +end subroutine + +subroutine test1(esss,Ix, e_x) + real(kind=kind(1.0d0)), dimension(:), intent(out) :: esss + real(kind=kind(1.0d0)), dimension(:), intent(in) :: Ix + integer(kind=4), dimension(:), intent(in) :: e_x + esss = Ix(e_x) +end subroutine + +subroutine test2(esss,Ix, e_x) + real(kind=kind(1.0d0)), dimension(:), intent(out) :: esss + real(kind=kind(1.0d0)), dimension(:), intent(in) :: Ix + integer(kind=8), dimension(:), intent(in) :: e_x + esss = Ix(e_x) +end subroutine + +subroutine test3(esss,Ix,Iyz, e_x, ii_ivec) + real(kind=kind(1.0d0)), dimension(:), intent(out) :: esss + real(kind=kind(1.0d0)), dimension(:), intent(in) :: Ix,Iyz + integer(kind=kind(1)), dimension(:), intent(in) :: e_x,ii_ivec + esss = esss + Ix(e_x) * Iyz(ii_ivec) +end subroutine + +! { dg-final { scan-tree-dump-not "malloc" "original" } } +! { dg-final { cleanup-tree-dump "original" } } diff --git a/gcc/testsuite/gnat.dg/rep_clause5.adb b/gcc/testsuite/gnat.dg/rep_clause5.adb new file mode 100644 index 00000000000..7fdf264095a --- /dev/null +++ b/gcc/testsuite/gnat.dg/rep_clause5.adb @@ -0,0 +1,39 @@ +-- { dg-do compile } +-- { dg-options "-O" } + +package body Rep_Clause5 is + + function To_LNumber(S : String) return LNumber_Type is + V : VString; + LV : Long_Type; + LN : LNumber_Type; + begin + LV := To_Long(V, 10); + LN := LNumber_Type(LV); + return LN; + end; + + procedure Merge_Numbered(LNodes : in out LNodes_Ptr) is + T1 : Token_Type; + LNO : LNumber_Type; + begin + for X in LNodes.all'Range loop + T1 := LNodes(X).Line(0); + if T1.Token /= LEX_LF then + declare + S : String := Element(T1.SID); + begin + begin + LNO := To_LNumber(S); + exception + when Bad_Number => + LNO := 0; + when Too_Large => + LNO := 0; + end; + end; + end if; + end loop; + end; + +end Rep_Clause5; diff --git a/gcc/testsuite/gnat.dg/rep_clause5.ads b/gcc/testsuite/gnat.dg/rep_clause5.ads new file mode 100644 index 00000000000..986f893ecbb --- /dev/null +++ b/gcc/testsuite/gnat.dg/rep_clause5.ads @@ -0,0 +1,12 @@ +with Rep_Clause5_Pkg; use Rep_Clause5_Pkg; + +package Rep_Clause5 is + + Bad_Number : exception; + Too_Large : exception; + + type LNumber_Type is range 0..99999; + + procedure Merge_Numbered(LNodes : in out LNodes_Ptr); + +end Rep_Clause5; diff --git a/gcc/testsuite/gnat.dg/rep_clause5_pkg.ads b/gcc/testsuite/gnat.dg/rep_clause5_pkg.ads new file mode 100644 index 00000000000..e3496c4a2b7 --- /dev/null +++ b/gcc/testsuite/gnat.dg/rep_clause5_pkg.ads @@ -0,0 +1,383 @@ +package Rep_Clause5_Pkg is + + type ID_Type is mod 65536; + type String_ID is new ID_Type; + type LNumber_Type is range 0..99999; + subtype Long_Type is Integer; + + type Func_ID is (No_Func, FUN_SGN, FUN_EXP, FUN_LOG, FUN_LOG10); + + type Token_Kind is ( + No_Token, + LEX_BINARY, + LEX_SECTION, + LEX_003, + LEX_004, + LEX_005, + LEX_006, + LEX_007, + LEX_008, + LEX_009, + LEX_LF, + LEX_011, + LEX_012, + LEX_013, + LEX_014, + LEX_015, + LEX_016, + LEX_017, + LEX_018, + LEX_019, + LEX_020, + LEX_021, + LEX_022, + LEX_023, + LEX_024, + LEX_025, + LEX_026, + LEX_027, + LEX_028, + LEX_029, + LEX_030, + LEX_031, + LEX_032, + '!', + '"', + '#', + '$', + '%', + '&', + ''', + '(', + ')', + '*', + '+', + ',', + '-', + '.', + '/', + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + ':', + ';', + '<', + '=', + '>', + '?', + '@', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + '[', + '\', + ']', + '^', + '_', + '`', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + LEX_SFUN3, + LEX_SFUN2, + LEX_SFUN1, + LEX_SFUNN, + LEX_FUN3, + LEX_FUN2, + LEX_FUN1, + LEX_FUNN, + 'x', + 'y', + 'z', + '{', + '|', + '}', + '~', + LEX_CRTA, + LEX_ISNULL, + LEX_USING, + LEX_HANDLE, + LEX_CALLX, + LEX_COMPLEX, + LEX_FIXED, + LEX_ENV, + LEX_SPARSE, + LEX_SUBROUTINE, + LEX_CALL, + LEX_BOX, + LEX_VLINE, + LEX_HLINE, + LEX_MAXLENGTH, + LEX_DLENGTH, + LEX_INPUT, + LEX_INITIALIZE, + LEX_OUTPUT, + LEX_UNLINK, + LEX_SEEK, + LEX_EXIT, + LEX_NOT, + LEX_COMMON, + LEX_CHAIN, + LEX_DEF, + LEX_ARITY, + LEX_RESUME, + LEX_PIC_S, + LEX_BG, + LEX_FG, + LEX_PC, + LEX_CRT, + LEX_ENUM, + LEX_DECLARE, + LEX_CURSOR, + LEX_DROP, + LEX_CURRENT, + LEX_ISOLATION, + LEX_SET, + LEX_TRANSACTION, + LEX_COMMIT, + LEX_ABORT, + LEX_BEGIN, + LEX_PREVIOUS, + LEX_LAST, + LEX_FIRST, + LEX_KEY, + LEX_START, + LEX_REWRITE, + LEX_INDEX, + LEX_SECONDARY, + LEX_PRIMARY, + LEX_COLUMN, + LEX_TEMP, + LEX_TABLE, + LEX_CREATE, + LEX_HASH, + LEX_BTREE, + LEX_UPDATE, + LEX_ERROR, + LEX_ACCEPT, + LEX_AVG, + LEX_MAX, + LEX_MIN, + LEX_FIELD, + LEX_RESTORE, + LEX_END, + LEX_STEP, + LEX_NEXT, + LEX_FOR, + LEX_RETURN, + LEX_GOSUB, + LEX_RANGE, + LEX_EXPON, + LEX_XOR, + LEX_OR, + LEX_AND, + LEX_SHIFTR, + LEX_GE, + LEX_NE, + LEX_SHIFTL, + LEX_LE, + LEX_VARYING, + LEX_LENGTH, + LEX_PRINT, + LEX_IF, + LEX_GOTO, + LEX_ON, + LEX_THEN, + LEX_DELETE, + LEX_TO, + LEX_SEQUENCE, + LEX_NONUNIQUE, + LEX_UNIQUE, + LEX_FILE, + LEX_CLOSE, + LEX_OPEN, + LEX_DATABASE, + LEX_RECORD, + LEX_DATA, + LEX_WRITE, + LEX_READ, + LEX_STOP, + LEX_LET, + LEX_MOD, + LEX_LONG, + LEX_DIM, + LEX_SHORT, + LEX_REM, + LEX_SHELL, + LEX_TOKEN, + LEX_FLOAT, + LEX_SIDENT, + LEX_INLREM, + LEX_ENDLIT, + LEX_STRLIT, + LEX_IDENT, + LEX_LNUMBER, + LEX_HEX, + LEX_NUMBER, + LEX_EOF, + LEX_QUIT, + LEX_LIST, + LEX_REMOVE, + LEX_RENUMBER, + LEX_CONTINUE, + LEX_RUN, + LEX_MERGE, + LEX_ENTER, + LEX_NEW, + LEX_RESET, + LEX_SYMTAB, + LEX_CLS, + LEX_EDIT, + LEX_SAVE, + LEX_RESAVE, + LEX_LOAD, + LEX_NAME, + LEX_LISTP, + LEX_SHOW, + LEX_STACK, + LEX_STATUS, + LEX_CACHE, + LEX_INSPECT, + LEX_STOW, + LEX_PKGRUN, + LEX_POP, + LEX_CHECK, + LEX_INSERT, + LEX_INTO, + LEX_VALUES, + LEX_NULL, + LEX_WHERE, + LEX_FROM, + LEX_EXEC, + LEX_SELECT, + LEX_AS, + LEX_ALL, + LEX_BY, + LEX_CROSS, + LEX_DESC, + LEX_FULL, + LEX_GROUP, + LEX_INNER, + LEX_JOIN, + LEX_LEFT, + LEX_LIMIT, + LEX_NATURAL, + LEX_OFFSET, + LEX_ORDER, + LEX_OUTER, + LEX_RIGHT, + LEX_FETCH, + LEX_DISTINCT, + LEX_DEFAULT, + LEX_RETURNING, + LEX_LEVEL, + LEX_COMMITTED, + LEX_SERIALIZABLE, + LEX_ONLY, + LEX_HOLD, + LEX_FORWARD, + LEX_WITH, + LEX_PRIOR, + LEX_RELATIVE, + LEX_BACKWARD, + LEX_OF, + LEX_SCROLL, + LEX_NOWAIT, + LEX_HAVING, + LEX_END_TOKENS + ); + + type Aux_Kind is (No_Aux, SID_Aux, FID_Aux, LNO_Aux); + + type Token_Type(Aux : Aux_Kind := No_Aux) is + record + Token : Token_Kind := No_Token; + case Aux is + when SID_Aux => + SID : String_ID; + when FID_Aux => + FID : Func_ID; + when LNO_Aux => + LNO : LNumber_Type; + when No_Aux => + null; + end case; + end record; + + for Token_Type use + record + Aux at 0 range 0..2; + Token at 0 range 3..12; + SID at 0 range 16..31; + FID at 0 range 16..31; + LNO at 0 range 13..31; + end record; + + type Tokens_Index is range 0..999999; + type Token_Array is array(Tokens_Index range <>) of Token_Type; + type Token_Line is access all Token_Array; + + type Line_Node is + record + Line : Token_Line; + LNO : LNumber_Type := 0; + Numbered : Boolean := False; + end record; + + type Nodes_Index is range 0..999999; + type LNodes_Array is array(Nodes_Index range <>) of Line_Node; + type LNodes_Ptr is access all LNodes_Array; + + type VString is + record + Max_Length : Natural := 0; + Fixed : Boolean := False; + end record; + + function To_Long(Object : VString; Radix : Natural) return Long_Type; + + function Element (V : String_ID) return String; + +end Rep_Clause5_Pkg; diff --git a/gcc/testsuite/gnat.dg/sizetype.adb b/gcc/testsuite/gnat.dg/sizetype1.adb similarity index 91% rename from gcc/testsuite/gnat.dg/sizetype.adb rename to gcc/testsuite/gnat.dg/sizetype1.adb index acc2d6560bd..e5d12c61e09 100644 --- a/gcc/testsuite/gnat.dg/sizetype.adb +++ b/gcc/testsuite/gnat.dg/sizetype1.adb @@ -2,7 +2,7 @@ with Interfaces.C; use Interfaces.C; -procedure Sizetype is +procedure Sizetype1 is TC_String : String(1..8) := "abcdefgh"; TC_No_nul : constant char_array := To_C(TC_String, False); diff --git a/gcc/testsuite/gnat.dg/sizetype2.adb b/gcc/testsuite/gnat.dg/sizetype2.adb new file mode 100644 index 00000000000..4593936c826 --- /dev/null +++ b/gcc/testsuite/gnat.dg/sizetype2.adb @@ -0,0 +1,27 @@ +-- { dg-do run } + +procedure Sizetype2 is + + function Ident_Int (X : Integer) return Integer is + begin + return X; + end; + + type A is array (Integer range <>) of Boolean; + subtype T1 is A (Ident_Int (- 6) .. Ident_Int (Integer'Last - 4)); + subtype T2 is A (- 6 .. Ident_Int (Integer'Last - 4)); + subtype T3 is A (Ident_Int (- 6) .. Integer'Last - 4); + +begin + if T1'Size /= 17179869200 then + raise Program_Error; + end if; + + if T2'Size /= 17179869200 then + raise Program_Error; + end if; + + if T3'Size /= 17179869200 then + raise Program_Error; + end if; +end; diff --git a/gcc/testsuite/lib/prune.exp b/gcc/testsuite/lib/prune.exp index ef647d533ed..160f651b6e7 100644 --- a/gcc/testsuite/lib/prune.exp +++ b/gcc/testsuite/lib/prune.exp @@ -23,6 +23,7 @@ proc prune_gcc_output { text } { regsub -all "(^|\n)(\[^\n\]*: )?In ((static member |lambda )?function|member|method|(copy )?constructor|destructor|instantiation|program|subroutine|block-data)\[^\n\]*" $text "" text regsub -all "(^|\n)\[^\n\]*(: )?At (top level|global scope):\[^\n\]*" $text "" text regsub -all "(^|\n)\[^\n\]*: instantiated from \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: . skipping \[0-9\]* instantiation contexts \[^\n\]*" $text "" text regsub -all "(^|\n) inlined from \[^\n\]*" $text "" text regsub -all "(^|\n)collect2: ld returned \[^\n\]*" $text "" text regsub -all "(^|\n)collect: re(compiling|linking)\[^\n\]*" $text "" text diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 126ae380fe7..e91c0331516 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -2105,6 +2105,25 @@ proc check_effective_target_vect_perm { } { return $et_vect_perm_saved } +# Return 1 if the target plus current options supports a vector +# widening summation of *short* args into *int* result, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_sum_hi_to_si_pattern { } { + global et_vect_widen_sum_hi_to_si_pattern + + if [info exists et_vect_widen_sum_hi_to_si_pattern_saved] { + verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern: using cached result" 2 + } else { + set et_vect_widen_sum_hi_to_si_pattern_saved 0 + if { [istarget powerpc*-*-*] } { + set et_vect_widen_sum_hi_to_si_pattern_saved 1 + } + } + verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern: returning $et_vect_widen_sum_hi_to_si_pattern_saved" 2 + return $et_vect_widen_sum_hi_to_si_pattern_saved +} # Return 1 if the target plus current options supports a vector # widening summation of *short* args into *int* result, 0 otherwise. diff --git a/gcc/timevar.def b/gcc/timevar.def index 19dec149a28..63530b8e973 100644 --- a/gcc/timevar.def +++ b/gcc/timevar.def @@ -57,7 +57,6 @@ DEFTIMEVAR (TV_LTO , "lto") DEFTIMEVAR (TV_WHOPR_WPA , "whopr wpa") DEFTIMEVAR (TV_WHOPR_WPA_IO , "whopr wpa I/O") DEFTIMEVAR (TV_WHOPR_LTRANS , "whopr ltrans") -DEFTIMEVAR (TV_WHOPR_WPA_FIXUP , "whopr wpa fixup") DEFTIMEVAR (TV_WHOPR_WPA_LTRANS_EXEC , "whopr wpa->ltrans") DEFTIMEVAR (TV_IPA_REFERENCE , "ipa reference") DEFTIMEVAR (TV_IPA_PURE_CONST , "ipa pure const") diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 2a66d568b3c..03d118966fc 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -3455,8 +3455,13 @@ do_pointer_plus_expr_check: connected to the operand types. */ return verify_gimple_comparison (lhs_type, rhs1, rhs2); - case WIDEN_SUM_EXPR: case WIDEN_MULT_EXPR: + if (TREE_CODE (lhs_type) != INTEGER_TYPE) + return true; + return ((2 * TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (lhs_type)) + || (TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (rhs2_type))); + + case WIDEN_SUM_EXPR: case VEC_WIDEN_MULT_HI_EXPR: case VEC_WIDEN_MULT_LO_EXPR: case VEC_PACK_TRUNC_EXPR: diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index a89d151c261..9abb2a8422e 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -2176,6 +2176,7 @@ analyze_subscript_affine_affine (tree chrec_a, unsigned nb_vars_a, nb_vars_b, dim; HOST_WIDE_INT init_a, init_b, gamma, gcd_alpha_beta; lambda_matrix A, U, S; + struct obstack scratch_obstack; if (eq_evolutions_p (chrec_a, chrec_b)) { @@ -2203,10 +2204,12 @@ analyze_subscript_affine_affine (tree chrec_a, nb_vars_a = nb_vars_in_chrec (chrec_a); nb_vars_b = nb_vars_in_chrec (chrec_b); + gcc_obstack_init (&scratch_obstack); + dim = nb_vars_a + nb_vars_b; - U = lambda_matrix_new (dim, dim); - A = lambda_matrix_new (dim, 1); - S = lambda_matrix_new (dim, 1); + U = lambda_matrix_new (dim, dim, &scratch_obstack); + A = lambda_matrix_new (dim, 1, &scratch_obstack); + S = lambda_matrix_new (dim, 1, &scratch_obstack); init_a = int_cst_value (initialize_matrix_A (A, chrec_a, 0, 1)); init_b = int_cst_value (initialize_matrix_A (A, chrec_b, nb_vars_a, -1)); @@ -2420,6 +2423,7 @@ analyze_subscript_affine_affine (tree chrec_a, } end_analyze_subs_aa: + obstack_free (&scratch_obstack, NULL); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, " (overlaps_a = "); diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h index 678eb10cc18..eff53483116 100644 --- a/gcc/tree-data-ref.h +++ b/gcc/tree-data-ref.h @@ -584,7 +584,9 @@ bool lambda_transform_legal_p (lambda_trans_matrix, int, void lambda_collect_parameters (VEC (data_reference_p, heap) *, VEC (tree, heap) **); bool lambda_compute_access_matrices (VEC (data_reference_p, heap) *, - VEC (tree, heap) *, VEC (loop_p, heap) *); + VEC (tree, heap) *, + VEC (loop_p, heap) *, + struct obstack *); /* In tree-data-ref.c */ void split_constant_offset (tree , tree *, tree *); diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 5475d79254b..d5a56e5e299 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -193,11 +193,7 @@ renumber_gimple_stmt_uids_in_blocks (basic_block *blocks, int n_blocks) tree make_rename_temp (tree type, const char *prefix) { - tree t = create_tmp_var (type, prefix); - - if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (t) = 1; + tree t = create_tmp_reg (type, prefix); if (gimple_referenced_vars (cfun)) { diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 384e43c770c..fbab7db9676 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -227,12 +227,9 @@ build_size_arg_loc (location_t loc, tree nb_iter, tree op, gimple_seq *stmt_list) { gimple_seq stmts; - tree x; - - x = fold_build2_loc (loc, MULT_EXPR, size_type_node, - fold_convert_loc (loc, size_type_node, nb_iter), - fold_convert_loc (loc, size_type_node, - TYPE_SIZE_UNIT (TREE_TYPE (op)))); + tree x = size_binop_loc (loc, MULT_EXPR, + fold_convert_loc (loc, sizetype, nb_iter), + TYPE_SIZE_UNIT (TREE_TYPE (op))); x = force_gimple_operand (x, &stmts, true, NULL); gimple_seq_add_seq (stmt_list, stmts); diff --git a/gcc/tree-loop-linear.c b/gcc/tree-loop-linear.c index 04731c76820..047389c6e6a 100644 --- a/gcc/tree-loop-linear.c +++ b/gcc/tree-loop-linear.c @@ -358,14 +358,15 @@ linear_transform_loops (void) goto free_and_continue; lambda_collect_parameters (datarefs, &lambda_parameters); - if (!lambda_compute_access_matrices (datarefs, lambda_parameters, nest)) + if (!lambda_compute_access_matrices (datarefs, lambda_parameters, + nest, &lambda_obstack)) goto free_and_continue; if (dump_file && (dump_flags & TDF_DETAILS)) dump_ddrs (dump_file, dependence_relations); /* Build the transformation matrix. */ - trans = lambda_trans_matrix_new (depth, depth); + trans = lambda_trans_matrix_new (depth, depth, &lambda_obstack); lambda_matrix_id (LTM_MATRIX (trans), depth); trans = try_interchange_loops (trans, depth, dependence_relations, datarefs, loop_nest); diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index fb95088b648..a3aa6c4c384 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -1,5 +1,5 @@ /* Nested function decomposition for GIMPLE. - Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -1088,7 +1088,8 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) { bitmap_set_bit (new_suppress, DECL_UID (decl)); OMP_CLAUSE_DECL (clause) = get_nonlocal_debug_decl (info, decl); - need_chain = true; + if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_PRIVATE) + need_chain = true; } break; diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c index 135342d58b0..2892e84600c 100644 --- a/gcc/tree-object-size.c +++ b/gcc/tree-object-size.c @@ -1203,7 +1203,8 @@ compute_object_sizes (void) result = fold_convert (size_type_node, integer_minus_one_node); else if (object_size_type < 4) - result = size_zero_node; + result = fold_convert (size_type_node, + integer_zero_node); } } diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c index c4ac89b001a..69a0b659616 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -248,7 +248,7 @@ name_to_copy_elt_hash (const void *aa) in parallel). */ static bool -loop_parallel_p (struct loop *loop) +loop_parallel_p (struct loop *loop, struct obstack * parloop_obstack) { VEC (ddr_p, heap) * dependence_relations; VEC (data_reference_p, heap) *datarefs; @@ -273,7 +273,7 @@ loop_parallel_p (struct loop *loop) if (dump_file && (dump_flags & TDF_DETAILS)) dump_data_dependence_relations (dump_file, dependence_relations); - trans = lambda_trans_matrix_new (1, 1); + trans = lambda_trans_matrix_new (1, 1, parloop_obstack); LTM_MATRIX (trans)[0][0] = -1; if (lambda_transform_legal_p (trans, 1, dependence_relations)) @@ -1884,15 +1884,17 @@ parallelize_loops (void) struct tree_niter_desc niter_desc; loop_iterator li; htab_t reduction_list; + struct obstack parloop_obstack; HOST_WIDE_INT estimated; LOC loop_loc; - + /* Do not parallelize loops in the functions created by parallelization. */ if (parallelized_function_p (cfun->decl)) return false; if (cfun->has_nonlocal_label) return false; + gcc_obstack_init (&parloop_obstack); reduction_list = htab_create (10, reduction_info_hash, reduction_info_eq, free); init_stmt_vec_info_vec (); @@ -1950,7 +1952,8 @@ parallelize_loops (void) if (!try_create_reduction_list (loop, reduction_list)) continue; - if (!flag_loop_parallelize_all && !loop_parallel_p (loop)) + if (!flag_loop_parallelize_all + && !loop_parallel_p (loop, &parloop_obstack)) continue; changed = true; @@ -1975,6 +1978,7 @@ parallelize_loops (void) free_stmt_vec_info_vec (); htab_delete (reduction_list); + obstack_free (&parloop_obstack, NULL); /* Parallelization will cause new function calls to be inserted through which local variables will escape. Reset the points-to solution diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 019b9332b81..3d7798e4ca4 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -182,11 +182,15 @@ struct ipa_opt_pass_d /* This hook is used to serialize IPA summaries on disk. */ void (*write_summary) (struct cgraph_node_set_def *); - /* For most ipa passes, the information can only be deserialized in - one chunk. However, function bodies are read function at a time - as needed so both calls are necessary. */ + /* This hook is used to deserialize IPA summaries from disk. */ void (*read_summary) (void); - void (*function_read_summary) (struct cgraph_node *); + + /* This hook is used to serialize IPA optimization summaries on disk. */ + void (*write_optimization_summary) (struct cgraph_node_set_def *); + + /* This hook is used to deserialize IPA summaries from disk. */ + void (*read_optimization_summary) (void); + /* Hook to convert gimple stmt uids into true gimple statements. The second parameter is an array of statements indexed by their uid. */ void (*stmt_fixup) (struct cgraph_node *, gimple *); @@ -407,6 +411,7 @@ extern struct gimple_opt_pass pass_late_warn_uninitialized; extern struct gimple_opt_pass pass_cse_reciprocals; extern struct gimple_opt_pass pass_cse_sincos; extern struct gimple_opt_pass pass_optimize_bswap; +extern struct gimple_opt_pass pass_optimize_widening_mul; extern struct gimple_opt_pass pass_warn_function_return; extern struct gimple_opt_pass pass_warn_function_noreturn; extern struct gimple_opt_pass pass_cselim; @@ -601,9 +606,9 @@ extern const char *get_current_pass_name (void); extern void print_current_pass (FILE *); extern void debug_pass (void); extern void ipa_write_summaries (void); -extern void ipa_write_summaries_of_cgraph_node_set ( - struct cgraph_node_set_def *); +extern void ipa_write_optimization_summaries (struct cgraph_node_set_def *); extern void ipa_read_summaries (void); +extern void ipa_read_optimization_summaries (void); extern void register_one_dump_file (struct opt_pass *); extern bool function_called_by_processed_nodes_p (void); extern void register_pass (struct register_pass_info *); diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index 62708cd8523..41873cefb8c 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -1460,13 +1460,9 @@ static tree predcom_tmp_var (tree ref, unsigned i, bitmap tmp_vars) { tree type = TREE_TYPE (ref); - tree var = create_tmp_var (type, get_lsm_tmp_name (ref, i)); - /* We never access the components of the temporary variable in predictive commoning. */ - if (TREE_CODE (type) == COMPLEX_TYPE - || TREE_CODE (type) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (var) = 1; + tree var = create_tmp_reg (type, get_lsm_tmp_name (ref, i)); add_referenced_var (var); bitmap_set_bit (tmp_vars, DECL_UID (var)); @@ -2209,18 +2205,12 @@ reassociate_to_the_same_stmt (tree name1, tree name2) /* Insert the new statement combining NAME1 and NAME2 before S1, and combine it with the rhs of S1. */ - var = create_tmp_var (type, "predreastmp"); - if (TREE_CODE (type) == COMPLEX_TYPE - || TREE_CODE (type) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (var) = 1; + var = create_tmp_reg (type, "predreastmp"); add_referenced_var (var); new_name = make_ssa_name (var, NULL); new_stmt = gimple_build_assign_with_ops (code, new_name, name1, name2); - var = create_tmp_var (type, "predreastmp"); - if (TREE_CODE (type) == COMPLEX_TYPE - || TREE_CODE (type) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (var) = 1; + var = create_tmp_reg (type, "predreastmp"); add_referenced_var (var); tmp_name = make_ssa_name (var, NULL); diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 0a9b3df3b15..0635aa7f4a8 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -2537,10 +2537,7 @@ replace_uses_with_default_def_ssa_name (tree ssa) tree repl, decl = SSA_NAME_VAR (ssa); if (TREE_CODE (decl) == PARM_DECL) { - tree tmp = create_tmp_var (TREE_TYPE (decl), "SR"); - if (TREE_CODE (TREE_TYPE (tmp)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (tmp)) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (tmp) = 1; + tree tmp = create_tmp_reg (TREE_TYPE (decl), "SR"); get_var_ann (tmp); add_referenced_var (tmp); @@ -3733,10 +3730,7 @@ get_replaced_param_substitute (struct ipa_parm_adjustment *adj) { char *pretty_name = make_fancy_name (adj->base); - repl = create_tmp_var (TREE_TYPE (adj->base), "ISR"); - if (TREE_CODE (TREE_TYPE (repl)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (repl)) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (repl) = 1; + repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR"); DECL_NAME (repl) = get_identifier (pretty_name); obstack_free (&name_obstack, pretty_name); diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c index a2485c5efbc..f0cbdfee8c9 100644 --- a/gcc/tree-ssa-address.c +++ b/gcc/tree-ssa-address.c @@ -192,14 +192,12 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as, struct mem_addr_template *templ; if (addr->step && !integer_onep (addr->step)) - st = immed_double_const (TREE_INT_CST_LOW (addr->step), - TREE_INT_CST_HIGH (addr->step), address_mode); + st = immed_double_int_const (tree_to_double_int (addr->step), address_mode); else st = NULL_RTX; if (addr->offset && !integer_zerop (addr->offset)) - off = immed_double_const (TREE_INT_CST_LOW (addr->offset), - TREE_INT_CST_HIGH (addr->offset), address_mode); + off = immed_double_int_const (tree_to_double_int (addr->offset), address_mode); else off = NULL_RTX; diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index 2ca17c70dab..90ede52c4b7 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -1260,3 +1260,137 @@ struct gimple_opt_pass pass_optimize_bswap = 0 /* todo_flags_finish */ } }; + +/* Find integer multiplications where the operands are extended from + smaller types, and replace the MULT_EXPR with a WIDEN_MULT_EXPR + where appropriate. */ + +static unsigned int +execute_optimize_widening_mul (void) +{ + bool changed = false; + basic_block bb; + + FOR_EACH_BB (bb) + { + gimple_stmt_iterator gsi; + + for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple stmt = gsi_stmt (gsi); + gimple rhs1_stmt = NULL, rhs2_stmt = NULL; + tree type, type1 = NULL, type2 = NULL; + tree rhs1, rhs2, rhs1_convop = NULL, rhs2_convop = NULL; + enum tree_code rhs1_code, rhs2_code; + + if (!is_gimple_assign (stmt) + || gimple_assign_rhs_code (stmt) != MULT_EXPR) + continue; + + type = TREE_TYPE (gimple_assign_lhs (stmt)); + + if (TREE_CODE (type) != INTEGER_TYPE) + continue; + + rhs1 = gimple_assign_rhs1 (stmt); + rhs2 = gimple_assign_rhs2 (stmt); + + if (TREE_CODE (rhs1) == SSA_NAME) + { + rhs1_stmt = SSA_NAME_DEF_STMT (rhs1); + if (!is_gimple_assign (rhs1_stmt)) + continue; + rhs1_code = gimple_assign_rhs_code (rhs1_stmt); + if (!CONVERT_EXPR_CODE_P (rhs1_code)) + continue; + rhs1_convop = gimple_assign_rhs1 (rhs1_stmt); + type1 = TREE_TYPE (rhs1_convop); + if (TYPE_PRECISION (type1) * 2 != TYPE_PRECISION (type)) + continue; + } + else if (TREE_CODE (rhs1) != INTEGER_CST) + continue; + + if (TREE_CODE (rhs2) == SSA_NAME) + { + rhs2_stmt = SSA_NAME_DEF_STMT (rhs2); + if (!is_gimple_assign (rhs2_stmt)) + continue; + rhs2_code = gimple_assign_rhs_code (rhs2_stmt); + if (!CONVERT_EXPR_CODE_P (rhs2_code)) + continue; + rhs2_convop = gimple_assign_rhs1 (rhs2_stmt); + type2 = TREE_TYPE (rhs2_convop); + if (TYPE_PRECISION (type2) * 2 != TYPE_PRECISION (type)) + continue; + } + else if (TREE_CODE (rhs2) != INTEGER_CST) + continue; + + if (rhs1_stmt == NULL && rhs2_stmt == NULL) + continue; + + /* Verify that the machine can perform a widening multiply in this + mode/signedness combination, otherwise this transformation is + likely to pessimize code. */ + if ((rhs1_stmt == NULL || TYPE_UNSIGNED (type1)) + && (rhs2_stmt == NULL || TYPE_UNSIGNED (type2)) + && (optab_handler (umul_widen_optab, TYPE_MODE (type)) + ->insn_code == CODE_FOR_nothing)) + continue; + else if ((rhs1_stmt == NULL || !TYPE_UNSIGNED (type1)) + && (rhs2_stmt == NULL || !TYPE_UNSIGNED (type2)) + && (optab_handler (smul_widen_optab, TYPE_MODE (type)) + ->insn_code == CODE_FOR_nothing)) + continue; + else if (rhs1_stmt != NULL && rhs2_stmt != 0 + && (TYPE_UNSIGNED (type1) != TYPE_UNSIGNED (type2)) + && (optab_handler (usmul_widen_optab, TYPE_MODE (type)) + ->insn_code == CODE_FOR_nothing)) + continue; + + if ((rhs1_stmt == NULL && !int_fits_type_p (rhs1, type2)) + || (rhs2_stmt == NULL && !int_fits_type_p (rhs2, type1))) + continue; + + if (rhs1_stmt == NULL) + gimple_assign_set_rhs1 (stmt, fold_convert (type2, rhs1)); + else + gimple_assign_set_rhs1 (stmt, rhs1_convop); + if (rhs2_stmt == NULL) + gimple_assign_set_rhs2 (stmt, fold_convert (type1, rhs2)); + else + gimple_assign_set_rhs2 (stmt, rhs2_convop); + gimple_assign_set_rhs_code (stmt, WIDEN_MULT_EXPR); + update_stmt (stmt); + changed = true; + } + } + return (changed ? TODO_dump_func | TODO_update_ssa | TODO_verify_ssa + | TODO_verify_stmts : 0); +} + +static bool +gate_optimize_widening_mul (void) +{ + return flag_expensive_optimizations && optimize; +} + +struct gimple_opt_pass pass_optimize_widening_mul = +{ + { + GIMPLE_PASS, + "widening_mul", /* name */ + gate_optimize_widening_mul, /* gate */ + execute_optimize_widening_mul, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_NONE, /* tv_id */ + PROP_ssa, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0 /* todo_flags_finish */ + } +}; diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index b4a0aea9718..33e058c2275 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -1226,11 +1226,8 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, of the memory touched by the store, if we need to. */ if (!condstoretemp || TREE_TYPE (lhs) != TREE_TYPE (condstoretemp)) { - condstoretemp = create_tmp_var (TREE_TYPE (lhs), "cstore"); + condstoretemp = create_tmp_reg (TREE_TYPE (lhs), "cstore"); get_var_ann (condstoretemp); - if (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (lhs)) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (condstoretemp) = 1; } add_referenced_var (condstoretemp); diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c index fcd1d23bac8..799bb5a1e0b 100644 --- a/gcc/tree-ssa-phiprop.c +++ b/gcc/tree-ssa-phiprop.c @@ -190,11 +190,8 @@ phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt, { gcc_assert (TREE_CODE (old_arg) == ADDR_EXPR); old_arg = TREE_OPERAND (old_arg, 0); - new_var = create_tmp_var (TREE_TYPE (old_arg), NULL); + new_var = create_tmp_reg (TREE_TYPE (old_arg), NULL); tmp = gimple_build_assign (new_var, unshare_expr (old_arg)); - if (TREE_CODE (TREE_TYPE (old_arg)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (old_arg)) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (new_var) = 1; gcc_assert (is_gimple_reg (new_var)); add_referenced_var (new_var); new_var = make_ssa_name (new_var, tmp); diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index ae630df1b48..3a81f2c9316 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -1407,7 +1407,7 @@ get_representative_for (const pre_expr e) that we will return. */ if (!pretemp || exprtype != TREE_TYPE (pretemp)) { - pretemp = create_tmp_var (exprtype, "pretmp"); + pretemp = create_tmp_reg (exprtype, "pretmp"); get_var_ann (pretemp); } @@ -2631,31 +2631,46 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref, { case CALL_EXPR: { - tree folded, sc = currop->op1; + tree folded, sc = NULL_TREE; unsigned int nargs = 0; - tree *args = XNEWVEC (tree, VEC_length (vn_reference_op_s, - ref->operands) - 1); + tree fn, *args; + if (TREE_CODE (currop->op0) == FUNCTION_DECL) + fn = currop->op0; + else + { + pre_expr op0 = get_or_alloc_expr_for (currop->op0); + fn = find_or_generate_expression (block, op0, stmts, domstmt); + if (!fn) + return NULL_TREE; + } + if (currop->op1) + { + pre_expr scexpr = get_or_alloc_expr_for (currop->op1); + sc = find_or_generate_expression (block, scexpr, stmts, domstmt); + if (!sc) + return NULL_TREE; + } + args = XNEWVEC (tree, VEC_length (vn_reference_op_s, + ref->operands) - 1); while (*operand < VEC_length (vn_reference_op_s, ref->operands)) { args[nargs] = create_component_ref_by_pieces_1 (block, ref, operand, stmts, domstmt); + if (!args[nargs]) + { + free (args); + return NULL_TREE; + } nargs++; } folded = build_call_array (currop->type, - TREE_CODE (currop->op0) == FUNCTION_DECL - ? build_fold_addr_expr (currop->op0) - : currop->op0, + (TREE_CODE (fn) == FUNCTION_DECL + ? build_fold_addr_expr (fn) : fn), nargs, args); free (args); if (sc) - { - pre_expr scexpr = get_or_alloc_expr_for (sc); - sc = find_or_generate_expression (block, scexpr, stmts, domstmt); - if (!sc) - return NULL_TREE; - CALL_EXPR_STATIC_CHAIN (folded) = sc; - } + CALL_EXPR_STATIC_CHAIN (folded) = sc; return folded; } break; @@ -2779,22 +2794,37 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref, return NULL_TREE; if (genop2) { - op2expr = get_or_alloc_expr_for (genop2); - genop2 = find_or_generate_expression (block, op2expr, stmts, - domstmt); - if (!genop2) - return NULL_TREE; + /* Drop zero minimum index. */ + if (tree_int_cst_equal (genop2, integer_zero_node)) + genop2 = NULL_TREE; + else + { + op2expr = get_or_alloc_expr_for (genop2); + genop2 = find_or_generate_expression (block, op2expr, stmts, + domstmt); + if (!genop2) + return NULL_TREE; + } } if (genop3) { tree elmt_type = TREE_TYPE (TREE_TYPE (genop0)); - genop3 = size_binop (EXACT_DIV_EXPR, genop3, - size_int (TYPE_ALIGN_UNIT (elmt_type))); - op3expr = get_or_alloc_expr_for (genop3); - genop3 = find_or_generate_expression (block, op3expr, stmts, - domstmt); - if (!genop3) - return NULL_TREE; + /* We can't always put a size in units of the element alignment + here as the element alignment may be not visible. See + PR43783. Simply drop the element size for constant + sizes. */ + if (tree_int_cst_equal (genop3, TYPE_SIZE_UNIT (elmt_type))) + genop3 = NULL_TREE; + else + { + genop3 = size_binop (EXACT_DIV_EXPR, genop3, + size_int (TYPE_ALIGN_UNIT (elmt_type))); + op3expr = get_or_alloc_expr_for (genop3); + genop3 = find_or_generate_expression (block, op3expr, stmts, + domstmt); + if (!genop3) + return NULL_TREE; + } } return build4 (currop->opcode, currop->type, genop0, genop1, genop2, genop3); @@ -3073,17 +3103,13 @@ create_expression_by_pieces (basic_block block, pre_expr expr, that we will return. */ if (!pretemp || exprtype != TREE_TYPE (pretemp)) { - pretemp = create_tmp_var (exprtype, "pretmp"); + pretemp = create_tmp_reg (exprtype, "pretmp"); get_var_ann (pretemp); } temp = pretemp; add_referenced_var (temp); - if (TREE_CODE (exprtype) == COMPLEX_TYPE - || TREE_CODE (exprtype) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (temp) = 1; - newstmt = gimple_build_assign (temp, folded); name = make_ssa_name (temp, newstmt); gimple_assign_set_lhs (newstmt, name); diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 8d1c05c86e1..aa080855e5b 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -489,11 +489,11 @@ eliminate_duplicate_pair (enum tree_code opcode, static VEC(tree, heap) *plus_negates; -/* If OPCODE is PLUS_EXPR, CURR->OP is really a negate expression, - look in OPS for a corresponding positive operation to cancel it - out. If we find one, remove the other from OPS, replace - OPS[CURRINDEX] with 0, and return true. Otherwise, return - false. */ +/* If OPCODE is PLUS_EXPR, CURR->OP is a negate expression or a bitwise not + expression, look in OPS for a corresponding positive operation to cancel + it out. If we find one, remove the other from OPS, replace + OPS[CURRINDEX] with 0 or -1, respectively, and return true. Otherwise, + return false. */ static bool eliminate_plus_minus_pair (enum tree_code opcode, @@ -502,6 +502,7 @@ eliminate_plus_minus_pair (enum tree_code opcode, operand_entry_t curr) { tree negateop; + tree notop; unsigned int i; operand_entry_t oe; @@ -509,7 +510,8 @@ eliminate_plus_minus_pair (enum tree_code opcode, return false; negateop = get_unary_op (curr->op, NEGATE_EXPR); - if (negateop == NULL_TREE) + notop = get_unary_op (curr->op, BIT_NOT_EXPR); + if (negateop == NULL_TREE && notop == NULL_TREE) return false; /* Any non-negated version will have a rank that is one less than @@ -541,11 +543,32 @@ eliminate_plus_minus_pair (enum tree_code opcode, return true; } + else if (oe->op == notop) + { + tree op_type = TREE_TYPE (oe->op); + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Equivalence: "); + print_generic_expr (dump_file, notop, 0); + fprintf (dump_file, " + ~"); + print_generic_expr (dump_file, oe->op, 0); + fprintf (dump_file, " -> -1\n"); + } + + VEC_ordered_remove (operand_entry_t, *ops, i); + add_to_ops_vec (ops, build_int_cst_type (op_type, -1)); + VEC_ordered_remove (operand_entry_t, *ops, currindex); + reassociate_stats.ops_eliminated ++; + + return true; + } } /* CURR->OP is a negate expr in a plus expr: save it for later inspection in repropagate_negates(). */ - VEC_safe_push (tree, heap, plus_negates, curr->op); + if (negateop != NULL_TREE) + VEC_safe_push (tree, heap, plus_negates, curr->op); return false; } diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index ad4c10d3261..207cb178115 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -1706,7 +1706,8 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c, the set. Use ESCAPED as representative instead. */ else if (v->id == escaped_id) flag |= bitmap_set_bit (sol, escaped_id); - else if (add_graph_edge (graph, lhs, t)) + else if (v->may_have_pointers + && add_graph_edge (graph, lhs, t)) flag |= bitmap_ior_into (sol, get_varinfo (t)->solution); /* If the variable is not exactly at the requested offset @@ -1745,6 +1746,7 @@ do_ds_constraint (constraint_t c, bitmap delta) unsigned int j; bitmap_iterator bi; HOST_WIDE_INT loff = c->lhs.offset; + bool escaped_p = false; /* Our IL does not allow this. */ gcc_assert (c->rhs.offset == 0); @@ -1791,22 +1793,6 @@ do_ds_constraint (constraint_t c, bitmap delta) unsigned int t; HOST_WIDE_INT fieldoffset = v->offset + loff; - /* If v is a global variable then this is an escape point. */ - if (v->is_global_var) - { - t = find (escaped_id); - if (add_graph_edge (graph, t, rhs) - && bitmap_ior_into (get_varinfo (t)->solution, sol) - && !TEST_BIT (changed, t)) - { - SET_BIT (changed, t); - changed_count++; - } - } - - if (v->is_special_var) - continue; - if (v->is_full_var) fieldoffset = v->offset; else if (loff != 0) @@ -1819,6 +1805,25 @@ do_ds_constraint (constraint_t c, bitmap delta) { if (v->may_have_pointers) { + /* If v is a global variable then this is an escape point. */ + if (v->is_global_var + && !escaped_p) + { + t = find (escaped_id); + if (add_graph_edge (graph, t, rhs) + && bitmap_ior_into (get_varinfo (t)->solution, sol) + && !TEST_BIT (changed, t)) + { + SET_BIT (changed, t); + changed_count++; + } + /* Enough to let rhs escape once. */ + escaped_p = true; + } + + if (v->is_special_var) + break; + t = find (v->id); if (add_graph_edge (graph, t, rhs) && bitmap_ior_into (get_varinfo (t)->solution, sol) @@ -2885,6 +2890,16 @@ process_constraint (constraint_t t) /* ADDRESSOF on the lhs is invalid. */ gcc_assert (lhs.type != ADDRESSOF); + /* We shouldn't add constraints from things that cannot have pointers. + It's not completely trivial to avoid in the callers, so do it here. */ + if (rhs.type != ADDRESSOF + && !get_varinfo (rhs.var)->may_have_pointers) + return; + + /* Likewise adding to the solution of a non-pointer var isn't useful. */ + if (!get_varinfo (lhs.var)->may_have_pointers) + return; + /* This can happen in our IR with things like n->a = *p */ if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id) { @@ -3403,7 +3418,19 @@ do_structure_copy (tree lhsop, tree rhsop) if (lhsp->type == DEREF || (lhsp->type == ADDRESSOF && lhsp->var == anything_id) || rhsp->type == DEREF) - process_all_all_constraints (lhsc, rhsc); + { + if (lhsp->type == DEREF) + { + gcc_assert (VEC_length (ce_s, lhsc) == 1); + lhsp->offset = UNKNOWN_OFFSET; + } + if (rhsp->type == DEREF) + { + gcc_assert (VEC_length (ce_s, rhsc) == 1); + rhsp->offset = UNKNOWN_OFFSET; + } + process_all_all_constraints (lhsc, rhsc); + } else if (lhsp->type == SCALAR && (rhsp->type == SCALAR || rhsp->type == ADDRESSOF)) @@ -5910,13 +5937,7 @@ dump_sa_points_to_info (FILE *outfile) { varinfo_t vi = get_varinfo (i); if (!vi->may_have_pointers) - { - gcc_assert (find (i) == i - || !(vi = get_varinfo (find (i)))->may_have_pointers); - /* ??? See create_variable_info_for. - gcc_assert (bitmap_empty_p (vi->solution)); */ - continue; - } + continue; dump_solution_for_var (outfile, i); } } @@ -5955,6 +5976,8 @@ init_base_vars (void) var_nothing->size = ~0; var_nothing->fullsize = ~0; var_nothing->is_special_var = 1; + var_nothing->may_have_pointers = 0; + var_nothing->is_global_var = 0; /* Create the ANYTHING variable, used to represent that a variable points to some unknown piece of memory. */ diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index ca3dffadc75..4d2422aa623 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -575,13 +575,10 @@ adjust_return_value_with_ops (enum tree_code code, const char *label, { tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl)); - tree tmp = create_tmp_var (ret_type, label); + tree tmp = create_tmp_reg (ret_type, label); gimple stmt; tree result; - if (TREE_CODE (ret_type) == COMPLEX_TYPE - || TREE_CODE (ret_type) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (tmp) = 1; add_referenced_var (tmp); if (types_compatible_p (TREE_TYPE (acc), TREE_TYPE (op1))) @@ -908,12 +905,9 @@ static tree create_tailcall_accumulator (const char *label, basic_block bb, tree init) { tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl)); - tree tmp = create_tmp_var (ret_type, label); + tree tmp = create_tmp_reg (ret_type, label); gimple phi; - if (TREE_CODE (ret_type) == COMPLEX_TYPE - || TREE_CODE (ret_type) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (tmp) = 1; add_referenced_var (tmp); phi = create_phi_node (tmp, bb); /* RET_TYPE can be a float when -ffast-maths is enabled. */ diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 809f3e15a02..83b823d84bf 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -545,6 +545,11 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop) STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_reduction_def; STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) = vect_reduction_def; + /* Store the reduction cycles for possible vectorization in + loop-aware SLP. */ + VEC_safe_push (gimple, heap, + LOOP_VINFO_REDUCTIONS (loop_vinfo), + reduc_stmt); } } } @@ -745,6 +750,7 @@ new_loop_vec_info (struct loop *loop) VEC_alloc (ddr_p, heap, PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS)); LOOP_VINFO_STRIDED_STORES (res) = VEC_alloc (gimple, heap, 10); + LOOP_VINFO_REDUCTIONS (res) = VEC_alloc (gimple, heap, 10); LOOP_VINFO_SLP_INSTANCES (res) = VEC_alloc (slp_instance, heap, 10); LOOP_VINFO_SLP_UNROLLING_FACTOR (res) = 1; @@ -835,6 +841,7 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts) VEC_free (slp_instance, heap, LOOP_VINFO_SLP_INSTANCES (loop_vinfo)); VEC_free (gimple, heap, LOOP_VINFO_STRIDED_STORES (loop_vinfo)); + VEC_free (gimple, heap, LOOP_VINFO_REDUCTIONS (loop_vinfo)); free (loop_vinfo); loop->aux = NULL; @@ -1223,7 +1230,6 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo) if ((STMT_VINFO_RELEVANT_P (stmt_info) || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))) && !PURE_SLP_STMT (stmt_info)) - /* STMT needs both SLP and loop-based vectorization. */ only_slp_in_loop = false; } @@ -2860,28 +2866,33 @@ get_initial_def_for_reduction (gimple stmt, tree init_val, /* Function vect_create_epilog_for_reduction Create code at the loop-epilog to finalize the result of a reduction - computation. - - VECT_DEF is a vector of partial results. - REDUC_CODE is the tree-code for the epilog reduction. + computation. + + VECT_DEFS is list of vector of partial results, i.e., the lhs's of vector + reduction statements. + STMT is the scalar reduction stmt that is being vectorized. NCOPIES is > 1 in case the vectorization factor (VF) is bigger than the number of elements that we can fit in a vectype (nunits). In this case we have to generate more than one vector stmt - i.e - we need to "unroll" the vector stmt by a factor VF/nunits. For more details see documentation in vectorizable_operation. - STMT is the scalar reduction stmt that is being vectorized. - REDUCTION_PHI is the phi-node that carries the reduction computation. - REDUC_INDEX is the index of the operand in the right hand side of the + REDUC_CODE is the tree-code for the epilog reduction. + REDUCTION_PHIS is a list of the phi-nodes that carry the reduction + computation. + REDUC_INDEX is the index of the operand in the right hand side of the statement that is defined by REDUCTION_PHI. DOUBLE_REDUC is TRUE if double reduction phi nodes should be handled. + SLP_NODE is an SLP node containing a group of reduction statements. The + first one in this group is STMT. This function: - 1. Creates the reduction def-use cycle: sets the arguments for - REDUCTION_PHI: + 1. Creates the reduction def-use cycles: sets the arguments for + REDUCTION_PHIS: The loop-entry argument is the vectorized initial-value of the reduction. - The loop-latch argument is VECT_DEF - the vector of partial sums. - 2. "Reduces" the vector of partial results VECT_DEF into a single result, - by applying the operation specified by REDUC_CODE if available, or by + The loop-latch argument is taken from VECT_DEFS - the vector of partial + sums. + 2. "Reduces" each vector of partial results VECT_DEFS into a single result, + by applying the operation specified by REDUC_CODE if available, or by other means (whole-vector shifts or a scalar loop). The function also creates a new phi node at the loop exit to preserve loop-closed form, as illustrated below. @@ -2914,12 +2925,11 @@ get_initial_def_for_reduction (gimple stmt, tree init_val, */ static void -vect_create_epilog_for_reduction (tree vect_def, gimple stmt, - int ncopies, - enum tree_code reduc_code, - gimple reduction_phi, - int reduc_index, - bool double_reduc) +vect_create_epilog_for_reduction (VEC (tree, heap) *vect_defs, gimple stmt, + int ncopies, enum tree_code reduc_code, + VEC (gimple, heap) *reduction_phis, + int reduc_index, bool double_reduc, + slp_tree slp_node) { stmt_vec_info stmt_info = vinfo_for_stmt (stmt); stmt_vec_info prev_phi_info; @@ -2933,32 +2943,37 @@ vect_create_epilog_for_reduction (tree vect_def, gimple stmt, gimple new_phi = NULL, phi; gimple_stmt_iterator exit_gsi; tree vec_dest; - tree new_temp = NULL_TREE; - tree new_name; + tree new_temp = NULL_TREE, new_dest, new_name, new_scalar_dest; gimple epilog_stmt = NULL; - tree new_scalar_dest, new_dest; + enum tree_code code = gimple_assign_rhs_code (stmt); gimple exit_phi; tree bitsize, bitpos; - enum tree_code code = gimple_assign_rhs_code (stmt); - tree adjustment_def; - tree vec_initial_def, def; - tree orig_name; + tree adjustment_def = NULL; + tree vec_initial_def = NULL; + tree reduction_op, expr, def; + tree orig_name, scalar_result; imm_use_iterator imm_iter; use_operand_p use_p; bool extract_scalar_result = false; - tree reduction_op, expr; - gimple orig_stmt; - gimple use_stmt; + gimple use_stmt, orig_stmt, reduction_phi = NULL; bool nested_in_vect_loop = false; - VEC(gimple,heap) *phis = NULL; + VEC (gimple, heap) *new_phis = NULL; enum vect_def_type dt = vect_unknown_def_type; int j, i; + VEC (tree, heap) *scalar_results = NULL; + unsigned int group_size = 1, k, ratio; + VEC (tree, heap) *vec_initial_defs = NULL; + VEC (gimple, heap) *phis; + + if (slp_node) + group_size = VEC_length (gimple, SLP_TREE_SCALAR_STMTS (slp_node)); if (nested_in_vect_loop_p (loop, stmt)) { outer_loop = loop; loop = loop->inner; nested_in_vect_loop = true; + gcc_assert (!slp_node); } switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))) @@ -2983,47 +2998,80 @@ vect_create_epilog_for_reduction (tree vect_def, gimple stmt, gcc_assert (vectype); mode = TYPE_MODE (vectype); - /*** 1. Create the reduction def-use cycle ***/ + /* 1. Create the reduction def-use cycle: + Set the arguments of REDUCTION_PHIS, i.e., transform + + loop: + vec_def = phi # REDUCTION_PHI + VECT_DEF = vector_stmt # vectorized form of STMT + ... - /* For the case of reduction, vect_get_vec_def_for_operand returns - the scalar def before the loop, that defines the initial value - of the reduction variable. */ - vec_initial_def = vect_get_vec_def_for_operand (reduction_op, stmt, - &adjustment_def); + into: - phi = reduction_phi; - def = vect_def; - for (j = 0; j < ncopies; j++) + loop: + vec_def = phi # REDUCTION_PHI + VECT_DEF = vector_stmt # vectorized form of STMT + ... + + (in case of SLP, do it for all the phis). */ + + /* Get the loop-entry arguments. */ + if (slp_node) + vect_get_slp_defs (slp_node, &vec_initial_defs, NULL, reduc_index); + else { - /* 1.1 set the loop-entry arg of the reduction-phi: */ - add_phi_arg (phi, vec_initial_def, loop_preheader_edge (loop), - UNKNOWN_LOCATION); + vec_initial_defs = VEC_alloc (tree, heap, 1); + /* For the case of reduction, vect_get_vec_def_for_operand returns + the scalar def before the loop, that defines the initial value + of the reduction variable. */ + vec_initial_def = vect_get_vec_def_for_operand (reduction_op, stmt, + &adjustment_def); + VEC_quick_push (tree, vec_initial_defs, vec_initial_def); + } - /* 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), UNKNOWN_LOCATION); + /* Set phi nodes arguments. */ + for (i = 0; VEC_iterate (gimple, reduction_phis, i, phi); i++) + { + tree vec_init_def = VEC_index (tree, vec_initial_defs, i); + tree def = VEC_index (tree, vect_defs, i); + for (j = 0; j < ncopies; j++) + { + /* Set the loop-entry arg of the reduction-phi. */ + add_phi_arg (phi, vec_init_def, loop_preheader_edge (loop), + UNKNOWN_LOCATION); - if (vect_print_dump_info (REPORT_DETAILS)) - { - fprintf (vect_dump, "transform reduction: created def-use cycle: "); - print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM); - fprintf (vect_dump, "\n"); - print_gimple_stmt (vect_dump, SSA_NAME_DEF_STMT (def), 0, TDF_SLIM); - } + /* Set the loop-latch arg for the reduction-phi. */ + if (j > 0) + def = vect_get_vec_def_for_stmt_copy (vect_unknown_def_type, def); - phi = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (phi)); + add_phi_arg (phi, def, loop_latch_edge (loop), UNKNOWN_LOCATION); + + if (vect_print_dump_info (REPORT_DETAILS)) + { + fprintf (vect_dump, "transform reduction: created def-use" + " cycle: "); + print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM); + fprintf (vect_dump, "\n"); + print_gimple_stmt (vect_dump, SSA_NAME_DEF_STMT (def), 0, + TDF_SLIM); + } + + phi = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (phi)); + } } - /*** 2. Create epilog code - The reduction epilog code operates across the elements of the vector - of partial results computed by the vectorized loop. - The reduction epilog code consists of: - step 1: compute the scalar result in a vector (v_out2) - step 2: extract the scalar result (s_out3) from the vector (v_out2) - step 3: adjust the scalar result (s_out3) if needed. + VEC_free (tree, heap, vec_initial_defs); + + /* 2. Create epilog code. + The reduction epilog code operates across the elements of the vector + of partial results computed by the vectorized loop. + The reduction epilog code consists of: + + step 1: compute the scalar result in a vector (v_out2) + step 2: extract the scalar result (s_out3) from the vector (v_out2) + step 3: adjust the scalar result (s_out3) if needed. - Step 1 can be accomplished using one the following three schemes: + Step 1 can be accomplished using one the following three schemes: (scheme 1) using reduc_code, if available. (scheme 2) using whole-vector shifts, if available. (scheme 3) using a scalar loop. In this case steps 1+2 above are @@ -3038,29 +3086,33 @@ vect_create_epilog_for_reduction (tree vect_def, gimple stmt, s_out4 = adjust_result # step 3 (step 3 is optional, and steps 1 and 2 may be combined). - Lastly, the uses of s_out0 are replaced by s_out4. + Lastly, the uses of s_out0 are replaced by s_out4. */ - ***/ - /* 2.1 Create new loop-exit-phi to preserve loop-closed form: - v_out1 = phi */ + /* 2.1 Create new loop-exit-phis to preserve loop-closed form: + v_out1 = phi + Store them in NEW_PHIS. */ exit_bb = single_exit (loop)->dest; - def = vect_def; prev_phi_info = NULL; - for (j = 0; j < ncopies; j++) + new_phis = VEC_alloc (gimple, heap, VEC_length (tree, vect_defs)); + for (i = 0; VEC_iterate (tree, vect_defs, i, def); i++) { - phi = create_phi_node (SSA_NAME_VAR (vect_def), exit_bb); - set_vinfo_for_stmt (phi, new_stmt_vec_info (phi, loop_vinfo, NULL)); - if (j == 0) - new_phi = phi; - else - { - def = vect_get_vec_def_for_stmt_copy (dt, def); - STMT_VINFO_RELATED_STMT (prev_phi_info) = phi; - } - SET_PHI_ARG_DEF (phi, single_exit (loop)->dest_idx, def); - prev_phi_info = vinfo_for_stmt (phi); + for (j = 0; j < ncopies; j++) + { + phi = create_phi_node (SSA_NAME_VAR (def), exit_bb); + set_vinfo_for_stmt (phi, new_stmt_vec_info (phi, loop_vinfo, NULL)); + if (j == 0) + VEC_quick_push (gimple, new_phis, phi); + else + { + def = vect_get_vec_def_for_stmt_copy (dt, def); + STMT_VINFO_RELATED_STMT (prev_phi_info) = phi; + } + + SET_PHI_ARG_DEF (phi, single_exit (loop)->dest_idx, def); + prev_phi_info = vinfo_for_stmt (phi); + } } exit_gsi = gsi_after_labels (exit_bb); @@ -3089,16 +3141,17 @@ vect_create_epilog_for_reduction (tree vect_def, gimple stmt, } code = gimple_assign_rhs_code (orig_stmt); + /* For MINUS_EXPR the initial vector is [init_val,0,...,0], therefore, + partial results are added and not subtracted. */ + if (code == MINUS_EXPR) + code = PLUS_EXPR; + scalar_dest = gimple_assign_lhs (orig_stmt); scalar_type = TREE_TYPE (scalar_dest); + scalar_results = VEC_alloc (tree, heap, group_size); new_scalar_dest = vect_create_destination_var (scalar_dest, NULL); bitsize = TYPE_SIZE (scalar_type); - /* For MINUS_EXPR the initial vector is [init_val,0,...,0], therefore, - partial results are added and not subtracted. */ - if (code == MINUS_EXPR) - code = PLUS_EXPR; - /* In case this is a reduction in an inner-loop while vectorizing an outer loop - we don't need to extract a single scalar result at the end of the inner-loop (unless it is double reduction, i.e., the use of reduction is @@ -3108,28 +3161,21 @@ vect_create_epilog_for_reduction (tree vect_def, gimple stmt, if (nested_in_vect_loop && !double_reduc) goto vect_finalize_reduction; - /* The epilogue is created for the outer-loop, i.e., for the loop being - vectorized. */ - if (double_reduc) - loop = outer_loop; - - /* FORNOW */ - gcc_assert (ncopies == 1); - /* 2.3 Create the reduction code, using one of the three schemes described - above. */ - - if (reduc_code != ERROR_MARK) + above. In SLP we simply need to extract all the elements from the + vector (without reducing them), so we use scalar shifts. */ + if (reduc_code != ERROR_MARK && !slp_node) { tree tmp; /*** Case 1: Create: - v_out2 = reduc_expr */ + v_out2 = reduc_expr */ if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "Reduce using direct vector reduction."); + fprintf (vect_dump, "Reduce using direct vector reduction."); vec_dest = vect_create_destination_var (scalar_dest, vectype); + new_phi = VEC_index (gimple, new_phis, 0); tmp = build1 (reduc_code, vectype, PHI_RESULT (new_phi)); epilog_stmt = gimple_build_assign (vec_dest, tmp); new_temp = make_ssa_name (vec_dest, epilog_stmt); @@ -3148,142 +3194,182 @@ vect_create_epilog_for_reduction (tree vect_def, gimple stmt, tree vec_temp; if (optab_handler (vec_shr_optab, mode)->insn_code != CODE_FOR_nothing) - shift_code = VEC_RSHIFT_EXPR; + shift_code = VEC_RSHIFT_EXPR; else - have_whole_vector_shift = false; + have_whole_vector_shift = false; /* Regardless of whether we have a whole vector shift, if we're - emulating the operation via tree-vect-generic, we don't want - to use it. Only the first round of the reduction is likely - to still be profitable via emulation. */ + emulating the operation via tree-vect-generic, we don't want + to use it. Only the first round of the reduction is likely + to still be profitable via emulation. */ /* ??? It might be better to emit a reduction tree code here, so that - tree-vect-generic can expand the first round via bit tricks. */ + tree-vect-generic can expand the first round via bit tricks. */ if (!VECTOR_MODE_P (mode)) - have_whole_vector_shift = false; + have_whole_vector_shift = false; else - { - optab optab = optab_for_tree_code (code, vectype, optab_default); - if (optab_handler (optab, mode)->insn_code == CODE_FOR_nothing) - have_whole_vector_shift = false; - } - - if (have_whole_vector_shift) { - /*** Case 2: Create: - for (offset = VS/2; offset >= element_size; offset/=2) - { - Create: va' = vec_shift - Create: va = vop - } */ - - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "Reduce using vector shifts"); + optab optab = optab_for_tree_code (code, vectype, optab_default); + if (optab_handler (optab, mode)->insn_code == CODE_FOR_nothing) + have_whole_vector_shift = false; + } - vec_dest = vect_create_destination_var (scalar_dest, vectype); - new_temp = PHI_RESULT (new_phi); + if (have_whole_vector_shift && !slp_node) + { + /*** Case 2: Create: + for (offset = VS/2; offset >= element_size; offset/=2) + { + Create: va' = vec_shift + Create: va = vop + } */ - for (bit_offset = vec_size_in_bits/2; - bit_offset >= element_bitsize; - bit_offset /= 2) - { - tree bitpos = size_int (bit_offset); - - epilog_stmt = gimple_build_assign_with_ops (shift_code, vec_dest, - new_temp, bitpos); - new_name = make_ssa_name (vec_dest, epilog_stmt); - gimple_assign_set_lhs (epilog_stmt, new_name); - gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); - - epilog_stmt = gimple_build_assign_with_ops (code, vec_dest, - new_name, new_temp); - new_temp = make_ssa_name (vec_dest, epilog_stmt); - gimple_assign_set_lhs (epilog_stmt, new_temp); - gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); - } + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "Reduce using vector shifts"); + + vec_dest = vect_create_destination_var (scalar_dest, vectype); + new_phi = VEC_index (gimple, new_phis, 0); + new_temp = PHI_RESULT (new_phi); + for (bit_offset = vec_size_in_bits/2; + bit_offset >= element_bitsize; + bit_offset /= 2) + { + tree bitpos = size_int (bit_offset); + + epilog_stmt = gimple_build_assign_with_ops (shift_code, + vec_dest, new_temp, bitpos); + new_name = make_ssa_name (vec_dest, epilog_stmt); + gimple_assign_set_lhs (epilog_stmt, new_name); + gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); + + epilog_stmt = gimple_build_assign_with_ops (code, vec_dest, + new_name, new_temp); + new_temp = make_ssa_name (vec_dest, epilog_stmt); + gimple_assign_set_lhs (epilog_stmt, new_temp); + gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); + } - extract_scalar_result = true; - } + extract_scalar_result = true; + } else { - tree rhs; - - /*** Case 3: Create: - s = extract_field - for (offset = element_size; - offset < vector_size; - offset += element_size;) - { - Create: s' = extract_field - Create: s = op - } */ + tree rhs; + + /*** Case 3: Create: + s = extract_field + for (offset = element_size; + offset < vector_size; + offset += element_size;) + { + Create: s' = extract_field + Create: s = op // For non SLP cases + } */ - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "Reduce using scalar code. "); - - vec_temp = PHI_RESULT (new_phi); - vec_size_in_bits = tree_low_cst (TYPE_SIZE (vectype), 1); - rhs = build3 (BIT_FIELD_REF, scalar_type, vec_temp, bitsize, - bitsize_zero_node); - epilog_stmt = gimple_build_assign (new_scalar_dest, rhs); - new_temp = make_ssa_name (new_scalar_dest, epilog_stmt); - gimple_assign_set_lhs (epilog_stmt, new_temp); - gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); - - for (bit_offset = element_bitsize; - bit_offset < vec_size_in_bits; - bit_offset += element_bitsize) - { - tree bitpos = bitsize_int (bit_offset); - tree rhs = build3 (BIT_FIELD_REF, scalar_type, vec_temp, bitsize, - bitpos); - - epilog_stmt = gimple_build_assign (new_scalar_dest, rhs); - new_name = make_ssa_name (new_scalar_dest, epilog_stmt); - gimple_assign_set_lhs (epilog_stmt, new_name); - gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); - - epilog_stmt = gimple_build_assign_with_ops (code, - new_scalar_dest, - new_name, new_temp); - new_temp = make_ssa_name (new_scalar_dest, epilog_stmt); - gimple_assign_set_lhs (epilog_stmt, new_temp); - gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); - } + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "Reduce using scalar code. "); - extract_scalar_result = false; - } + vec_size_in_bits = tree_low_cst (TYPE_SIZE (vectype), 1); + for (i = 0; VEC_iterate (gimple, new_phis, i, new_phi); i++) + { + vec_temp = PHI_RESULT (new_phi); + rhs = build3 (BIT_FIELD_REF, scalar_type, vec_temp, bitsize, + bitsize_zero_node); + epilog_stmt = gimple_build_assign (new_scalar_dest, rhs); + new_temp = make_ssa_name (new_scalar_dest, epilog_stmt); + gimple_assign_set_lhs (epilog_stmt, new_temp); + gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); + + /* In SLP we don't need to apply reduction operation, so we just + collect s' values in SCALAR_RESULTS. */ + if (slp_node) + VEC_safe_push (tree, heap, scalar_results, new_temp); + + for (bit_offset = element_bitsize; + bit_offset < vec_size_in_bits; + bit_offset += element_bitsize) + { + tree bitpos = bitsize_int (bit_offset); + tree rhs = build3 (BIT_FIELD_REF, scalar_type, vec_temp, + bitsize, bitpos); + + epilog_stmt = gimple_build_assign (new_scalar_dest, rhs); + new_name = make_ssa_name (new_scalar_dest, epilog_stmt); + gimple_assign_set_lhs (epilog_stmt, new_name); + gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); + + if (slp_node) + { + /* In SLP we don't need to apply reduction operation, so + we just collect s' values in SCALAR_RESULTS. */ + new_temp = new_name; + VEC_safe_push (tree, heap, scalar_results, new_name); + } + else + { + epilog_stmt = gimple_build_assign_with_ops (code, + new_scalar_dest, new_name, new_temp); + new_temp = make_ssa_name (new_scalar_dest, epilog_stmt); + gimple_assign_set_lhs (epilog_stmt, new_temp); + gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); + } + } + } + + /* The only case where we need to reduce scalar results in SLP, is + unrolling. If the size of SCALAR_RESULTS is greater than + GROUP_SIZE, we reduce them combining elements modulo + GROUP_SIZE. */ + if (slp_node) + { + tree res, first_res, new_res; + gimple new_stmt; + + /* Reduce multiple scalar results in case of SLP unrolling. */ + for (j = group_size; VEC_iterate (tree, scalar_results, j, res); + j++) + { + first_res = VEC_index (tree, scalar_results, j % group_size); + new_stmt = gimple_build_assign_with_ops (code, + new_scalar_dest, first_res, res); + new_res = make_ssa_name (new_scalar_dest, new_stmt); + gimple_assign_set_lhs (new_stmt, new_res); + gsi_insert_before (&exit_gsi, new_stmt, GSI_SAME_STMT); + VEC_replace (tree, scalar_results, j % group_size, new_res); + } + } + else + /* Not SLP - we have one scalar to keep in SCALAR_RESULTS. */ + VEC_safe_push (tree, heap, scalar_results, new_temp); + + extract_scalar_result = false; + } } /* 2.4 Extract the final scalar result. Create: - s_out3 = extract_field */ + s_out3 = extract_field */ if (extract_scalar_result) { tree rhs; - gcc_assert (!nested_in_vect_loop || double_reduc); if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "extract scalar result"); + fprintf (vect_dump, "extract scalar result"); if (BYTES_BIG_ENDIAN) - bitpos = size_binop (MULT_EXPR, - bitsize_int (TYPE_VECTOR_SUBPARTS (vectype) - 1), - TYPE_SIZE (scalar_type)); + bitpos = size_binop (MULT_EXPR, + bitsize_int (TYPE_VECTOR_SUBPARTS (vectype) - 1), + TYPE_SIZE (scalar_type)); else - bitpos = bitsize_zero_node; + bitpos = bitsize_zero_node; rhs = build3 (BIT_FIELD_REF, scalar_type, new_temp, bitsize, bitpos); epilog_stmt = gimple_build_assign (new_scalar_dest, rhs); new_temp = make_ssa_name (new_scalar_dest, epilog_stmt); gimple_assign_set_lhs (epilog_stmt, new_temp); gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); + VEC_safe_push (tree, heap, scalar_results, new_temp); } - + vect_finalize_reduction: - if (double_reduc) - loop = loop->inner; - /* 2.5 Adjust the final result by the initial value of the reduction variable. (When such adjustment is not needed, then 'adjustment_def' is zero). For example, if code is PLUS we create: @@ -3291,14 +3377,17 @@ vect_finalize_reduction: if (adjustment_def) { + gcc_assert (!slp_node); if (nested_in_vect_loop) { + new_phi = VEC_index (gimple, new_phis, 0); gcc_assert (TREE_CODE (TREE_TYPE (adjustment_def)) == VECTOR_TYPE); expr = build2 (code, vectype, PHI_RESULT (new_phi), adjustment_def); new_dest = vect_create_destination_var (scalar_dest, vectype); } else { + new_temp = VEC_index (tree, scalar_results, 0); gcc_assert (TREE_CODE (TREE_TYPE (adjustment_def)) != VECTOR_TYPE); expr = build2 (code, scalar_type, new_temp, adjustment_def); new_dest = vect_create_destination_var (scalar_dest, scalar_type); @@ -3309,142 +3398,212 @@ vect_finalize_reduction: gimple_assign_set_lhs (epilog_stmt, new_temp); SSA_NAME_DEF_STMT (new_temp) = epilog_stmt; gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT); + if (nested_in_vect_loop) + { + set_vinfo_for_stmt (epilog_stmt, + new_stmt_vec_info (epilog_stmt, loop_vinfo, + NULL)); + STMT_VINFO_RELATED_STMT (vinfo_for_stmt (epilog_stmt)) = + STMT_VINFO_RELATED_STMT (vinfo_for_stmt (new_phi)); + + if (!double_reduc) + VEC_quick_push (tree, scalar_results, new_temp); + else + VEC_replace (tree, scalar_results, 0, new_temp); + } + else + VEC_replace (tree, scalar_results, 0, new_temp); + + VEC_replace (gimple, new_phis, 0, epilog_stmt); } + /* 2.6 Handle the loop-exit phis. Replace the uses of scalar loop-exit + phis with new adjusted scalar results, i.e., replace use + with use . + + Transform: + loop_exit: + s_out0 = phi # (scalar) EXIT_PHI + v_out1 = phi # NEW_EXIT_PHI + v_out2 = reduce + s_out3 = extract_field + s_out4 = adjust_result + use + use - /* 2.6 Handle the loop-exit phi */ + into: - /* Replace uses of s_out0 with uses of s_out3: - Find the loop-closed-use at the loop exit of the original scalar result. - (The reduction result is expected to have two immediate uses - one at the - latch block, and one at the loop exit). */ - phis = VEC_alloc (gimple, heap, 10); - FOR_EACH_IMM_USE_FAST (use_p, imm_iter, scalar_dest) + loop_exit: + s_out0 = phi # (scalar) EXIT_PHI + v_out1 = phi # NEW_EXIT_PHI + v_out2 = reduce + s_out3 = extract_field + s_out4 = adjust_result + use + use */ + + /* In SLP we may have several statements in NEW_PHIS and REDUCTION_PHIS (in + case that GROUP_SIZE is greater than vectorization factor). Therefore, we + need to match SCALAR_RESULTS with corresponding statements. The first + (GROUP_SIZE / number of new vector stmts) scalar results correspond to + the first vector stmt, etc. + (RATIO is equal to (GROUP_SIZE / number of new vector stmts)). */ + if (group_size > VEC_length (gimple, new_phis)) { - if (!flow_bb_inside_loop_p (loop, gimple_bb (USE_STMT (use_p)))) - { - exit_phi = USE_STMT (use_p); - VEC_quick_push (gimple, phis, exit_phi); - } + ratio = group_size / VEC_length (gimple, new_phis); + gcc_assert (!(group_size % VEC_length (gimple, new_phis))); } + else + ratio = 1; - /* We expect to have found an exit_phi because of loop-closed-ssa form. */ - gcc_assert (!VEC_empty (gimple, phis)); - - for (i = 0; VEC_iterate (gimple, phis, i, exit_phi); i++) + for (k = 0; k < group_size; k++) { - if (nested_in_vect_loop) - { - stmt_vec_info stmt_vinfo = vinfo_for_stmt (exit_phi); - gimple vect_phi; - - /* FORNOW. Currently not supporting the case that an inner-loop - reduction is not used in the outer-loop (but only outside the - outer-loop), unless it is double reduction. */ - gcc_assert ((STMT_VINFO_RELEVANT_P (stmt_vinfo) - && !STMT_VINFO_LIVE_P (stmt_vinfo)) || double_reduc); - - epilog_stmt = adjustment_def ? epilog_stmt : new_phi; - STMT_VINFO_VEC_STMT (stmt_vinfo) = epilog_stmt; - set_vinfo_for_stmt (epilog_stmt, - new_stmt_vec_info (epilog_stmt, loop_vinfo, - NULL)); - if (adjustment_def) - STMT_VINFO_RELATED_STMT (vinfo_for_stmt (epilog_stmt)) = - STMT_VINFO_RELATED_STMT (vinfo_for_stmt (new_phi)); - - if (!double_reduc - || STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_double_reduction_def) - continue; - - /* Handle double reduction: - - stmt1: s1 = phi - double reduction phi (outer loop) - stmt2: s3 = phi - (regular) reduction phi (inner loop) - stmt3: s4 = use (s3) - (regular) reduction stmt (inner loop) - stmt4: s2 = phi - double reduction stmt (outer loop) - - At that point the regular reduction (stmt2 and stmt3) is already - vectorized, as well as the exit phi node, stmt4. - Here we vectorize the phi node of double reduction, stmt1, and - update all relevant statements. */ - - /* Go through all the uses of s2 to find double reduction phi node, - i.e., stmt1 above. */ - orig_name = PHI_RESULT (exit_phi); - FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, orig_name) + if (k % ratio == 0) + { + epilog_stmt = VEC_index (gimple, new_phis, k / ratio); + reduction_phi = VEC_index (gimple, reduction_phis, k / ratio); + } + + if (slp_node) + { + gimple current_stmt = VEC_index (gimple, + SLP_TREE_SCALAR_STMTS (slp_node), k); + + orig_stmt = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (current_stmt)); + /* SLP statements can't participate in patterns. */ + gcc_assert (!orig_stmt); + scalar_dest = gimple_assign_lhs (current_stmt); + } + + phis = VEC_alloc (gimple, heap, 3); + /* Find the loop-closed-use at the loop exit of the original scalar + result. (The reduction result is expected to have two immediate uses - + one at the latch block, and one at the loop exit). */ + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, scalar_dest) + if (!flow_bb_inside_loop_p (loop, gimple_bb (USE_STMT (use_p)))) + VEC_safe_push (gimple, heap, phis, USE_STMT (use_p)); + + /* We expect to have found an exit_phi because of loop-closed-ssa + form. */ + gcc_assert (!VEC_empty (gimple, phis)); + + for (i = 0; VEC_iterate (gimple, phis, i, exit_phi); i++) + { + if (outer_loop) { - stmt_vec_info use_stmt_vinfo = vinfo_for_stmt (use_stmt); - stmt_vec_info new_phi_vinfo; - tree vect_phi_init, preheader_arg, vect_phi_res, init_def; - basic_block bb = gimple_bb (use_stmt); - gimple use; - - /* Check that USE_STMT is really double reduction phi node. */ - if (gimple_code (use_stmt) != GIMPLE_PHI - || gimple_phi_num_args (use_stmt) != 2 - || !use_stmt_vinfo - || STMT_VINFO_DEF_TYPE (use_stmt_vinfo) - != vect_double_reduction_def - || bb->loop_father != outer_loop) + stmt_vec_info exit_phi_vinfo = vinfo_for_stmt (exit_phi); + gimple vect_phi; + + /* FORNOW. Currently not supporting the case that an inner-loop + reduction is not used in the outer-loop (but only outside the + outer-loop), unless it is double reduction. */ + gcc_assert ((STMT_VINFO_RELEVANT_P (exit_phi_vinfo) + && !STMT_VINFO_LIVE_P (exit_phi_vinfo)) + || double_reduc); + + STMT_VINFO_VEC_STMT (exit_phi_vinfo) = epilog_stmt; + if (!double_reduc + || STMT_VINFO_DEF_TYPE (exit_phi_vinfo) + != vect_double_reduction_def) continue; - /* Create vector phi node for double reduction: - vs1 = phi - vs1 was created previously in this function by a call to - vect_get_vec_def_for_operand and is stored in vec_initial_def; - vs2 is defined by EPILOG_STMT, the vectorized EXIT_PHI; - vs0 is created here. */ + /* Handle double reduction: - /* Create vector phi node. */ - vect_phi = create_phi_node (vec_initial_def, bb); - new_phi_vinfo = new_stmt_vec_info (vect_phi, - loop_vec_info_for_loop (outer_loop), NULL); - set_vinfo_for_stmt (vect_phi, new_phi_vinfo); - - /* Create vs0 - initial def of the double reduction phi. */ - preheader_arg = PHI_ARG_DEF_FROM_EDGE (use_stmt, - loop_preheader_edge (outer_loop)); - init_def = get_initial_def_for_reduction (stmt, preheader_arg, - NULL); - vect_phi_init = vect_init_vector (use_stmt, init_def, vectype, - NULL); - - /* Update phi node arguments with vs0 and vs2. */ - add_phi_arg (vect_phi, vect_phi_init, - loop_preheader_edge (outer_loop), UNKNOWN_LOCATION); - add_phi_arg (vect_phi, PHI_RESULT (epilog_stmt), - loop_latch_edge (outer_loop), UNKNOWN_LOCATION); - if (vect_print_dump_info (REPORT_DETAILS)) - { - fprintf (vect_dump, "created double reduction phi node: "); - print_gimple_stmt (vect_dump, vect_phi, 0, TDF_SLIM); - } + stmt1: s1 = phi - double reduction phi (outer loop) + stmt2: s3 = phi - (regular) reduc phi (inner loop) + stmt3: s4 = use (s3) - (regular) reduc stmt (inner loop) + stmt4: s2 = phi - double reduction stmt (outer loop) - vect_phi_res = PHI_RESULT (vect_phi); + At that point the regular reduction (stmt2 and stmt3) is + already vectorized, as well as the exit phi node, stmt4. + Here we vectorize the phi node of double reduction, stmt1, and + update all relevant statements. */ - /* Replace the use, i.e., set the correct vs1 in the regular - reduction phi node. FORNOW, NCOPIES is always 1, so the loop - is redundant. */ - use = reduction_phi; - for (j = 0; j < ncopies; j++) + /* Go through all the uses of s2 to find double reduction phi + node, i.e., stmt1 above. */ + orig_name = PHI_RESULT (exit_phi); + FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, orig_name) { - edge pr_edge = loop_preheader_edge (loop); - SET_PHI_ARG_DEF (use, pr_edge->dest_idx, vect_phi_res); - use = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (use)); + stmt_vec_info use_stmt_vinfo = vinfo_for_stmt (use_stmt); + stmt_vec_info new_phi_vinfo; + tree vect_phi_init, preheader_arg, vect_phi_res, init_def; + basic_block bb = gimple_bb (use_stmt); + gimple use; + + /* Check that USE_STMT is really double reduction phi + node. */ + if (gimple_code (use_stmt) != GIMPLE_PHI + || gimple_phi_num_args (use_stmt) != 2 + || !use_stmt_vinfo + || STMT_VINFO_DEF_TYPE (use_stmt_vinfo) + != vect_double_reduction_def + || bb->loop_father != outer_loop) + continue; + + /* Create vector phi node for double reduction: + vs1 = phi + vs1 was created previously in this function by a call to + vect_get_vec_def_for_operand and is stored in + vec_initial_def; + vs2 is defined by EPILOG_STMT, the vectorized EXIT_PHI; + vs0 is created here. */ + + /* Create vector phi node. */ + vect_phi = create_phi_node (vec_initial_def, bb); + new_phi_vinfo = new_stmt_vec_info (vect_phi, + loop_vec_info_for_loop (outer_loop), NULL); + set_vinfo_for_stmt (vect_phi, new_phi_vinfo); + + /* Create vs0 - initial def of the double reduction phi. */ + preheader_arg = PHI_ARG_DEF_FROM_EDGE (use_stmt, + loop_preheader_edge (outer_loop)); + init_def = get_initial_def_for_reduction (stmt, + preheader_arg, NULL); + vect_phi_init = vect_init_vector (use_stmt, init_def, + vectype, NULL); + + /* Update phi node arguments with vs0 and vs2. */ + add_phi_arg (vect_phi, vect_phi_init, + loop_preheader_edge (outer_loop), + UNKNOWN_LOCATION); + add_phi_arg (vect_phi, PHI_RESULT (epilog_stmt), + loop_latch_edge (outer_loop), UNKNOWN_LOCATION); + if (vect_print_dump_info (REPORT_DETAILS)) + { + fprintf (vect_dump, "created double reduction phi " + "node: "); + print_gimple_stmt (vect_dump, vect_phi, 0, TDF_SLIM); + } + + vect_phi_res = PHI_RESULT (vect_phi); + + /* Replace the use, i.e., set the correct vs1 in the regular + reduction phi node. FORNOW, NCOPIES is always 1, so the + loop is redundant. */ + use = reduction_phi; + for (j = 0; j < ncopies; j++) + { + edge pr_edge = loop_preheader_edge (loop); + SET_PHI_ARG_DEF (use, pr_edge->dest_idx, vect_phi_res); + use = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (use)); + } } } - } - /* Replace the uses: */ - orig_name = PHI_RESULT (exit_phi); - FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, orig_name) - FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter) - SET_USE (use_p, new_temp); + /* Replace the uses: */ + orig_name = PHI_RESULT (exit_phi); + scalar_result = VEC_index (tree, scalar_results, k); + FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, orig_name) + FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter) + SET_USE (use_p, scalar_result); + } + + VEC_free (gimple, heap, phis); } - VEC_free (gimple, heap, phis); -} + VEC_free (tree, heap, scalar_results); + VEC_free (gimple, heap, new_phis); +} /* Function vectorizable_reduction. @@ -3489,7 +3648,7 @@ vect_finalize_reduction: bool vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, - gimple *vec_stmt) + gimple *vec_stmt, slp_tree slp_node) { tree vec_dest; tree scalar_dest; @@ -3517,7 +3676,6 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, int ncopies; int epilog_copies; stmt_vec_info prev_stmt_info, prev_phi_info; - gimple first_phi = NULL; bool single_defuse_cycle = false; tree reduc_def = NULL_TREE; gimple new_stmt = NULL; @@ -3532,6 +3690,10 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, struct loop * def_stmt_loop, *outer_loop = NULL; tree def_arg; gimple def_arg_stmt; + VEC (tree, heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL, *vect_defs = NULL; + VEC (gimple, heap) *phis = NULL; + int vec_num; + tree def0, def1; if (nested_in_vect_loop_p (loop, stmt)) { @@ -3540,10 +3702,6 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, nested_cycle = true; } - /* FORNOW: SLP not supported. */ - if (STMT_SLP_TYPE (stmt_info)) - return false; - /* 1. Is vectorizable reduction? */ /* Not supportable if the reduction variable is used in the loop. */ if (STMT_VINFO_RELEVANT (stmt_info) > vect_used_in_outer) @@ -3676,9 +3834,12 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, if (STMT_VINFO_LIVE_P (vinfo_for_stmt (reduc_def_stmt))) return false; + if (slp_node) + ncopies = 1; + else + ncopies = (LOOP_VINFO_VECT_FACTOR (loop_vinfo) + / TYPE_VECTOR_SUBPARTS (vectype_in)); - ncopies = (LOOP_VINFO_VECT_FACTOR (loop_vinfo) - / TYPE_VECTOR_SUBPARTS (vectype_in)); gcc_assert (ncopies >= 1); vec_mode = TYPE_MODE (vectype_in); @@ -3897,23 +4058,48 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, prev_stmt_info = NULL; prev_phi_info = NULL; + if (slp_node) + { + vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); + gcc_assert (TYPE_VECTOR_SUBPARTS (vectype_out) + == TYPE_VECTOR_SUBPARTS (vectype_in)); + } + else + { + vec_num = 1; + vec_oprnds0 = VEC_alloc (tree, heap, 1); + if (op_type == ternary_op) + vec_oprnds1 = VEC_alloc (tree, heap, 1); + } + + phis = VEC_alloc (gimple, heap, vec_num); + vect_defs = VEC_alloc (tree, heap, vec_num); + if (!slp_node) + VEC_quick_push (tree, vect_defs, NULL_TREE); + for (j = 0; j < ncopies; j++) { if (j == 0 || !single_defuse_cycle) { - /* Create the reduction-phi that defines the reduction-operand. */ - new_phi = create_phi_node (vec_dest, loop->header); - set_vinfo_for_stmt (new_phi, new_stmt_vec_info (new_phi, loop_vinfo, - NULL)); - /* Get the vector def for the reduction variable from the phi - node. */ - reduc_def = PHI_RESULT (new_phi); - } + for (i = 0; i < vec_num; i++) + { + /* Create the reduction-phi that defines the reduction + operand. */ + new_phi = create_phi_node (vec_dest, loop->header); + set_vinfo_for_stmt (new_phi, + new_stmt_vec_info (new_phi, loop_vinfo, + NULL)); + if (j == 0 || slp_node) + VEC_quick_push (gimple, phis, new_phi); + } + } if (code == COND_EXPR) { - first_phi = new_phi; - vectorizable_condition (stmt, gsi, vec_stmt, reduc_def, reduc_index); + gcc_assert (!slp_node); + vectorizable_condition (stmt, gsi, vec_stmt, + PHI_RESULT (VEC_index (gimple, phis, 0)), + reduc_index); /* Multiple types are not supported for condition. */ break; } @@ -3921,65 +4107,94 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, /* Handle uses. */ if (j == 0) { - loop_vec_def0 = vect_get_vec_def_for_operand (ops[!reduc_index], - stmt, NULL); - if (op_type == ternary_op) + if (slp_node) + vect_get_slp_defs (slp_node, &vec_oprnds0, &vec_oprnds1, -1); + else { - if (reduc_index == 0) - loop_vec_def1 = vect_get_vec_def_for_operand (ops[2], stmt, - NULL); - else - loop_vec_def1 = vect_get_vec_def_for_operand (ops[1], stmt, - NULL); + loop_vec_def0 = vect_get_vec_def_for_operand (ops[!reduc_index], + stmt, NULL); + VEC_quick_push (tree, vec_oprnds0, loop_vec_def0); + if (op_type == ternary_op) + { + if (reduc_index == 0) + loop_vec_def1 = vect_get_vec_def_for_operand (ops[2], stmt, + NULL); + else + loop_vec_def1 = vect_get_vec_def_for_operand (ops[1], stmt, + NULL); + + VEC_quick_push (tree, vec_oprnds1, loop_vec_def1); + } } - - /* Get the vector def for the reduction variable from the phi - node. */ - first_phi = new_phi; } else { - enum vect_def_type dt = vect_unknown_def_type; /* Dummy */ - loop_vec_def0 = vect_get_vec_def_for_stmt_copy (dt, loop_vec_def0); - if (op_type == ternary_op) - loop_vec_def1 = vect_get_vec_def_for_stmt_copy (dt, loop_vec_def1); + if (!slp_node) + { + enum vect_def_type dt = vect_unknown_def_type; /* Dummy */ + loop_vec_def0 = vect_get_vec_def_for_stmt_copy (dt, loop_vec_def0); + VEC_replace (tree, vec_oprnds0, 0, loop_vec_def0); + if (op_type == ternary_op) + { + loop_vec_def1 = vect_get_vec_def_for_stmt_copy (dt, + loop_vec_def1); + VEC_replace (tree, vec_oprnds1, 0, loop_vec_def1); + } + } - if (single_defuse_cycle) - reduc_def = gimple_assign_lhs (new_stmt); - else - reduc_def = PHI_RESULT (new_phi); + if (single_defuse_cycle) + reduc_def = gimple_assign_lhs (new_stmt); - STMT_VINFO_RELATED_STMT (prev_phi_info) = new_phi; + STMT_VINFO_RELATED_STMT (prev_phi_info) = new_phi; } - /* Arguments are ready. Create the new vector stmt. */ - if (op_type == binary_op) + for (i = 0; VEC_iterate (tree, vec_oprnds0, i, def0); i++) { - if (reduc_index == 0) - expr = build2 (code, vectype_out, reduc_def, loop_vec_def0); + if (slp_node) + reduc_def = PHI_RESULT (VEC_index (gimple, phis, i)); else - expr = build2 (code, vectype_out, loop_vec_def0, reduc_def); - } - else - { - if (reduc_index == 0) - expr = build3 (code, vectype_out, reduc_def, loop_vec_def0, - loop_vec_def1); + { + if (!single_defuse_cycle || j == 0) + reduc_def = PHI_RESULT (new_phi); + } + + def1 = ((op_type == ternary_op) + ? VEC_index (tree, vec_oprnds1, i) : NULL); + if (op_type == binary_op) + { + if (reduc_index == 0) + expr = build2 (code, vectype_out, reduc_def, def0); + else + expr = build2 (code, vectype_out, def0, reduc_def); + } else { - if (reduc_index == 1) - expr = build3 (code, vectype_out, loop_vec_def0, reduc_def, - loop_vec_def1); + if (reduc_index == 0) + expr = build3 (code, vectype_out, reduc_def, def0, def1); else - expr = build3 (code, vectype_out, loop_vec_def0, loop_vec_def1, - reduc_def); + { + if (reduc_index == 1) + expr = build3 (code, vectype_out, def0, reduc_def, def1); + else + expr = build3 (code, vectype_out, def0, def1, reduc_def); + } + } + + new_stmt = gimple_build_assign (vec_dest, expr); + new_temp = make_ssa_name (vec_dest, new_stmt); + gimple_assign_set_lhs (new_stmt, new_temp); + vect_finish_stmt_generation (stmt, new_stmt, gsi); + if (slp_node) + { + VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt); + VEC_quick_push (tree, vect_defs, new_temp); } + else + VEC_replace (tree, vect_defs, 0, new_temp); } - new_stmt = gimple_build_assign (vec_dest, expr); - new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_assign_set_lhs (new_stmt, new_temp); - vect_finish_stmt_generation (stmt, new_stmt, gsi); + if (slp_node) + continue; if (j == 0) STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt; @@ -3992,12 +4207,21 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, /* Finalize the reduction-phi (set its arguments) and create the epilog reduction code. */ - if (!single_defuse_cycle || code == COND_EXPR) - new_temp = gimple_assign_lhs (*vec_stmt); + if ((!single_defuse_cycle || code == COND_EXPR) && !slp_node) + { + new_temp = gimple_assign_lhs (*vec_stmt); + VEC_replace (tree, vect_defs, 0, new_temp); + } + + vect_create_epilog_for_reduction (vect_defs, stmt, epilog_copies, + epilog_reduc_code, phis, reduc_index, + double_reduc, slp_node); + + VEC_free (gimple, heap, phis); + VEC_free (tree, heap, vec_oprnds0); + if (vec_oprnds1) + VEC_free (tree, heap, vec_oprnds1); - vect_create_epilog_for_reduction (new_temp, stmt, epilog_copies, - epilog_reduc_code, first_phi, reduc_index, - double_reduc); return true; } diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 55b9d50cca0..ea827559195 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -670,6 +670,8 @@ vect_pattern_recog_1 ( tree pattern_vectype; tree type_in, type_out; enum tree_code code; + int i; + gimple next; pattern_stmt = (* vect_recog_func) (stmt, &type_in, &type_out); if (!pattern_stmt) @@ -735,7 +737,13 @@ vect_pattern_recog_1 ( STMT_VINFO_IN_PATTERN_P (stmt_info) = true; STMT_VINFO_RELATED_STMT (stmt_info) = pattern_stmt; - return; + /* Patterns cannot be vectorized using SLP, because they change the order of + computation. */ + for (i = 0; VEC_iterate (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo), i, + next); + i++) + if (next == stmt) + VEC_ordered_remove (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo), i); } diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index d25d34787e0..6949ebdf873 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -273,6 +273,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, break; case vect_internal_def: + case vect_reduction_def: if (i == 0) VEC_safe_push (gimple, heap, *def_stmts0, def_stmt); else @@ -332,7 +333,7 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, HOST_WIDE_INT dummy; bool permutation = false; unsigned int load_place; - gimple first_load; + gimple first_load, prev_first_load = NULL; /* For every stmt in NODE find its def stmt/s. */ for (i = 0; VEC_iterate (gimple, stmts, i, stmt); i++) @@ -485,42 +486,62 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, &pattern0, &pattern1)) return false; } - else - { - /* Load. */ - /* FORNOW: Check that there is no gap between the loads. */ - if ((DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) == stmt - && DR_GROUP_GAP (vinfo_for_stmt (stmt)) != 0) - || (DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) != stmt - && DR_GROUP_GAP (vinfo_for_stmt (stmt)) != 1)) - { - if (vect_print_dump_info (REPORT_SLP)) - { - fprintf (vect_dump, "Build SLP failed: strided " - "loads have gaps "); - print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); - } + else + { + /* Load. */ + /* FORNOW: Check that there is no gap between the loads. */ + if ((DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) == stmt + && DR_GROUP_GAP (vinfo_for_stmt (stmt)) != 0) + || (DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) != stmt + && DR_GROUP_GAP (vinfo_for_stmt (stmt)) != 1)) + { + if (vect_print_dump_info (REPORT_SLP)) + { + fprintf (vect_dump, "Build SLP failed: strided " + "loads have gaps "); + print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); + } - return false; - } - - /* Check that the size of interleaved loads group is not - greater than the SLP group size. */ - if (DR_GROUP_SIZE (vinfo_for_stmt (stmt)) - > ncopies * group_size) - { - if (vect_print_dump_info (REPORT_SLP)) - { - fprintf (vect_dump, "Build SLP failed: the number of " - "interleaved loads is greater than" - " the SLP group size "); - print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); - } + return false; + } - return false; - } + /* Check that the size of interleaved loads group is not + greater than the SLP group size. */ + if (DR_GROUP_SIZE (vinfo_for_stmt (stmt)) > ncopies * group_size) + { + if (vect_print_dump_info (REPORT_SLP)) + { + fprintf (vect_dump, "Build SLP failed: the number of " + "interleaved loads is greater than" + " the SLP group size "); + print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); + } + + return false; + } - first_load = DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)); + first_load = DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)); + if (prev_first_load) + { + /* Check that there are no loads from different interleaving + chains in the same node. The only exception is complex + numbers. */ + if (prev_first_load != first_load + && rhs_code != REALPART_EXPR + && rhs_code != IMAGPART_EXPR) + { + if (vect_print_dump_info (REPORT_SLP)) + { + fprintf (vect_dump, "Build SLP failed: different " + "interleaving chains in one node "); + print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); + } + + return false; + } + } + else + prev_first_load = first_load; if (first_load == stmt) { @@ -787,6 +808,39 @@ vect_supported_slp_permutation_p (slp_instance instance) } +/* Rearrange the statements of NODE according to PERMUTATION. */ + +static void +vect_slp_rearrange_stmts (slp_tree node, unsigned int group_size, + VEC (int, heap) *permutation) +{ + gimple stmt; + VEC (gimple, heap) *tmp_stmts; + unsigned int index, i; + + if (!node) + return; + + vect_slp_rearrange_stmts (SLP_TREE_LEFT (node), group_size, permutation); + vect_slp_rearrange_stmts (SLP_TREE_RIGHT (node), group_size, permutation); + + gcc_assert (group_size == VEC_length (gimple, SLP_TREE_SCALAR_STMTS (node))); + tmp_stmts = VEC_alloc (gimple, heap, group_size); + + for (i = 0; i < group_size; i++) + VEC_safe_push (gimple, heap, tmp_stmts, NULL); + + for (i = 0; VEC_iterate (gimple, SLP_TREE_SCALAR_STMTS (node), i, stmt); i++) + { + index = VEC_index (int, permutation, i); + VEC_replace (gimple, tmp_stmts, index, stmt); + } + + VEC_free (gimple, heap, SLP_TREE_SCALAR_STMTS (node)); + SLP_TREE_SCALAR_STMTS (node) = tmp_stmts; +} + + /* Check if the required load permutation is supported. LOAD_PERMUTATION contains a list of indices of the loads. In SLP this permutation is relative to the order of strided stores that are @@ -796,9 +850,11 @@ static bool vect_supported_load_permutation_p (slp_instance slp_instn, int group_size, VEC (int, heap) *load_permutation) { - int i = 0, j, prev = -1, next, k; - bool supported; + int i = 0, j, prev = -1, next, k, number_of_groups; + bool supported, bad_permutation = false; sbitmap load_index; + slp_tree node; + gimple stmt; /* FORNOW: permutations are only supported in SLP. */ if (!slp_instn) @@ -811,9 +867,72 @@ vect_supported_load_permutation_p (slp_instance slp_instn, int group_size, fprintf (vect_dump, "%d ", next); } + /* In case of reduction every load permutation is allowed, since the order + of the reduction statements is not important (as opposed to the case of + strided stores). The only condition we need to check is that all the + load nodes are of the same size and have the same permutation (and then + rearrange all the nodes of the SLP instance according to this + permutation). */ + + /* Check that all the load nodes are of the same size. */ + for (i = 0; + VEC_iterate (slp_tree, SLP_INSTANCE_LOADS (slp_instn), i, node); + i++) + if (VEC_length (gimple, SLP_TREE_SCALAR_STMTS (node)) + != (unsigned) group_size) + return false; + + node = SLP_INSTANCE_TREE (slp_instn); + stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (node), 0); + /* LOAD_PERMUTATION is a list of indices of all the loads of the SLP + instance, not all the loads belong to the same node or interleaving + group. Hence, we need to divide them into groups according to + GROUP_SIZE. */ + number_of_groups = VEC_length (int, load_permutation) / group_size; + + /* Reduction (there are no data-refs in the root). */ + if (!STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt))) + { + int first_group_load_index; + + /* Compare all the permutation sequences to the first one. */ + for (i = 1; i < number_of_groups; i++) + { + k = 0; + for (j = i * group_size; j < i * group_size + group_size; j++) + { + next = VEC_index (int, load_permutation, j); + first_group_load_index = VEC_index (int, load_permutation, k); + + if (next != first_group_load_index) + { + bad_permutation = true; + break; + } + + k++; + } + + if (bad_permutation) + break; + } + + if (!bad_permutation) + { + /* This permutaion is valid for reduction. Since the order of the + statements in the nodes is not important unless they are memory + accesses, we can rearrange the statements in all the nodes + according to the order of the loads. */ + vect_slp_rearrange_stmts (SLP_INSTANCE_TREE (slp_instn), group_size, + load_permutation); + VEC_free (int, heap, SLP_INSTANCE_LOAD_PERMUTATION (slp_instn)); + return true; + } + } + /* FORNOW: the only supported permutation is 0..01..1.. of length equal to GROUP_SIZE and where each sequence of same drs is of GROUP_SIZE length as - well. */ + well (unless it's reduction). */ if (VEC_length (int, load_permutation) != (unsigned int) (group_size * group_size)) return false; @@ -844,7 +963,11 @@ vect_supported_load_permutation_p (slp_instance slp_instn, int group_size, SET_BIT (load_index, prev); } - + + for (j = 0; j < group_size; j++) + if (!TEST_BIT (load_index, j)) + return false; + sbitmap_free (load_index); if (supported && i == group_size * group_size @@ -892,17 +1015,28 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, slp_tree node = XNEW (struct _slp_tree); unsigned int group_size = DR_GROUP_SIZE (vinfo_for_stmt (stmt)); unsigned int unrolling_factor = 1, nunits; - tree vectype, scalar_type; + tree vectype, scalar_type = NULL_TREE; gimple next; unsigned int vectorization_factor = 0; - int inside_cost = 0, outside_cost = 0, ncopies_for_cost; + int inside_cost = 0, outside_cost = 0, ncopies_for_cost, i; unsigned int max_nunits = 0; VEC (int, heap) *load_permutation; VEC (slp_tree, heap) *loads; + struct data_reference *dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt)); + + if (dr) + { + scalar_type = TREE_TYPE (DR_REF (dr)); + vectype = get_vectype_for_scalar_type (scalar_type); + group_size = DR_GROUP_SIZE (vinfo_for_stmt (stmt)); + } + else + { + gcc_assert (loop_vinfo); + vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt)); + group_size = VEC_length (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo)); + } - scalar_type = TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF ( - vinfo_for_stmt (stmt)))); - vectype = get_vectype_for_scalar_type (scalar_type); if (!vectype) { if (vect_print_dump_info (REPORT_SLP)) @@ -910,6 +1044,7 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, fprintf (vect_dump, "Build SLP failed: unsupported data-type "); print_generic_expr (vect_dump, scalar_type, TDF_SLIM); } + return false; } @@ -934,11 +1069,29 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, /* Create a node (a root of the SLP tree) for the packed strided stores. */ SLP_TREE_SCALAR_STMTS (node) = VEC_alloc (gimple, heap, group_size); next = stmt; - /* Collect the stores and store them in SLP_TREE_SCALAR_STMTS. */ - while (next) + if (dr) { - VEC_safe_push (gimple, heap, SLP_TREE_SCALAR_STMTS (node), next); - next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next)); + /* Collect the stores and store them in SLP_TREE_SCALAR_STMTS. */ + while (next) + { + VEC_safe_push (gimple, heap, SLP_TREE_SCALAR_STMTS (node), next); + next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next)); + } + } + else + { + /* Collect reduction statements. */ + for (i = 0; VEC_iterate (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo), i, + next); + i++) + { + VEC_safe_push (gimple, heap, SLP_TREE_SCALAR_STMTS (node), next); + if (vect_print_dump_info (REPORT_DETAILS)) + { + fprintf (vect_dump, "pushing reduction into node: "); + print_gimple_stmt (vect_dump, next, 0, TDF_SLIM); + } + } } SLP_TREE_VEC_STMTS (node) = NULL; @@ -1031,7 +1184,7 @@ bool vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) { unsigned int i; - VEC (gimple, heap) *strided_stores; + VEC (gimple, heap) *strided_stores, *reductions = NULL; gimple store; bool ok = false; @@ -1039,10 +1192,14 @@ vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) fprintf (vect_dump, "=== vect_analyze_slp ==="); if (loop_vinfo) - strided_stores = LOOP_VINFO_STRIDED_STORES (loop_vinfo); + { + strided_stores = LOOP_VINFO_STRIDED_STORES (loop_vinfo); + reductions = LOOP_VINFO_REDUCTIONS (loop_vinfo); + } else strided_stores = BB_VINFO_STRIDED_STORES (bb_vinfo); + /* Find SLP sequences starting from groups of strided stores. */ for (i = 0; VEC_iterate (gimple, strided_stores, i, store); i++) if (vect_analyze_slp_instance (loop_vinfo, bb_vinfo, store)) ok = true; @@ -1055,6 +1212,12 @@ vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) return false; } + /* Find SLP sequences starting from groups of reductions. */ + if (loop_vinfo && VEC_length (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo)) > 1 + && vect_analyze_slp_instance (loop_vinfo, bb_vinfo, + VEC_index (gimple, reductions, 0))) + ok = true; + return true; } @@ -1116,7 +1279,10 @@ vect_detect_hybrid_slp_stmts (slp_tree node) if ((stmt_vinfo = vinfo_for_stmt (use_stmt)) && !STMT_SLP_TYPE (stmt_vinfo) && (STMT_VINFO_RELEVANT (stmt_vinfo) - || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_vinfo)))) + || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_vinfo))) + && !(gimple_code (use_stmt) == GIMPLE_PHI + && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (use_stmt)) + == vect_reduction_def)) vect_mark_slp_stmts (node, hybrid, i); vect_detect_hybrid_slp_stmts (SLP_TREE_LEFT (node)); @@ -1425,11 +1591,14 @@ vect_update_slp_costs_according_to_vf (loop_vec_info loop_vinfo) /* For constant and loop invariant defs of SLP_NODE this function returns (vector) defs (VEC_OPRNDS) that will be used in the vectorized stmts. OP_NUM determines if we gather defs for operand 0 or operand 1 of the scalar - stmts. NUMBER_OF_VECTORS is the number of vector defs to create. */ + stmts. NUMBER_OF_VECTORS is the number of vector defs to create. + REDUC_INDEX is the index of the reduction operand in the statements, unless + it is -1. */ static void vect_get_constant_vectors (slp_tree slp_node, VEC(tree,heap) **vec_oprnds, - unsigned int op_num, unsigned int number_of_vectors) + unsigned int op_num, unsigned int number_of_vectors, + int reduc_index) { VEC (gimple, heap) *stmts = SLP_TREE_SCALAR_STMTS (slp_node); gimple stmt = VEC_index (gimple, stmts, 0); @@ -1445,6 +1614,50 @@ vect_get_constant_vectors (slp_tree slp_node, VEC(tree,heap) **vec_oprnds, int number_of_copies = 1; VEC (tree, heap) *voprnds = VEC_alloc (tree, heap, number_of_vectors); bool constant_p, is_store; + tree neutral_op = NULL; + + if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def) + { + enum tree_code code = gimple_assign_rhs_code (stmt); + if (reduc_index == -1) + { + VEC_free (tree, heap, *vec_oprnds); + return; + } + + op_num = reduc_index - 1; + op = gimple_op (stmt, op_num + 1); + /* For additional copies (see the explanation of NUMBER_OF_COPIES below) + we need either neutral operands or the original operands. See + get_initial_def_for_reduction() for details. */ + switch (code) + { + case WIDEN_SUM_EXPR: + case DOT_PROD_EXPR: + case PLUS_EXPR: + case MINUS_EXPR: + case BIT_IOR_EXPR: + case BIT_XOR_EXPR: + if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (op))) + neutral_op = build_real (TREE_TYPE (op), dconst0); + else + neutral_op = build_int_cst (TREE_TYPE (op), 0); + + break; + + case MULT_EXPR: + case BIT_AND_EXPR: + if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (op))) + neutral_op = build_real (TREE_TYPE (op), dconst1); + else + neutral_op = build_int_cst (TREE_TYPE (op), 1); + + break; + + default: + neutral_op = NULL; + } + } if (STMT_VINFO_DATA_REF (stmt_vinfo)) { @@ -1495,6 +1708,19 @@ vect_get_constant_vectors (slp_tree slp_node, VEC(tree,heap) **vec_oprnds, else op = gimple_op (stmt, op_num + 1); + if (reduc_index != -1) + { + struct loop *loop = (gimple_bb (stmt))->loop_father; + gimple def_stmt = SSA_NAME_DEF_STMT (op); + + gcc_assert (loop); + /* Get the def before the loop. */ + op = PHI_ARG_DEF_FROM_EDGE (def_stmt, + loop_preheader_edge (loop)); + if (j != (number_of_copies - 1) && neutral_op) + op = neutral_op; + } + /* Create 'vect_ = {op0,op1,...,opn}'. */ t = tree_cons (NULL_TREE, op, t); @@ -1532,8 +1758,25 @@ vect_get_constant_vectors (slp_tree slp_node, VEC(tree,heap) **vec_oprnds, to replicate the vectors. */ while (number_of_vectors > VEC_length (tree, *vec_oprnds)) { - for (i = 0; VEC_iterate (tree, *vec_oprnds, i, vop) && i < vec_num; i++) - VEC_quick_push (tree, *vec_oprnds, vop); + tree neutral_vec = NULL; + + if (neutral_op) + { + if (!neutral_vec) + { + t = NULL; + for (i = 0; i < (unsigned) nunits; i++) + t = tree_cons (NULL_TREE, neutral_op, t); + neutral_vec = build_vector (vector_type, t); + } + + VEC_quick_push (tree, *vec_oprnds, neutral_vec); + } + else + { + for (i = 0; VEC_iterate (tree, *vec_oprnds, i, vop) && i < vec_num; i++) + VEC_quick_push (tree, *vec_oprnds, vop); + } } } @@ -1572,7 +1815,7 @@ vect_get_slp_vect_defs (slp_tree slp_node, VEC (tree,heap) **vec_oprnds) void vect_get_slp_defs (slp_tree slp_node, VEC (tree,heap) **vec_oprnds0, - VEC (tree,heap) **vec_oprnds1) + VEC (tree,heap) **vec_oprnds1, int reduc_index) { gimple first_stmt; enum tree_code code; @@ -1603,19 +1846,26 @@ vect_get_slp_defs (slp_tree slp_node, VEC (tree,heap) **vec_oprnds0, *vec_oprnds0 = VEC_alloc (tree, heap, number_of_vects); /* SLP_NODE corresponds either to a group of stores or to a group of - unary/binary operations. We don't call this function for loads. */ - if (SLP_TREE_LEFT (slp_node)) + unary/binary operations. We don't call this function for loads. + For reduction defs we call vect_get_constant_vectors(), since we are + looking for initial loop invariant values. */ + if (SLP_TREE_LEFT (slp_node) && reduc_index == -1) /* The defs are already vectorized. */ vect_get_slp_vect_defs (SLP_TREE_LEFT (slp_node), vec_oprnds0); else /* Build vectors from scalar defs. */ - vect_get_constant_vectors (slp_node, vec_oprnds0, 0, number_of_vects); + vect_get_constant_vectors (slp_node, vec_oprnds0, 0, number_of_vects, + reduc_index); if (STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt))) /* Since we don't call this function with loads, this is a group of stores. */ return; + /* For reductions, we only need initial values. */ + if (reduc_index != -1) + return; + code = gimple_assign_rhs_code (first_stmt); if (get_gimple_rhs_class (code) != GIMPLE_BINARY_RHS || !vec_oprnds1) return; @@ -1634,7 +1884,7 @@ vect_get_slp_defs (slp_tree slp_node, VEC (tree,heap) **vec_oprnds0, vect_get_slp_vect_defs (SLP_TREE_RIGHT (slp_node), vec_oprnds1); else /* Build vectors from scalar defs. */ - vect_get_constant_vectors (slp_node, vec_oprnds1, 1, number_of_vects); + vect_get_constant_vectors (slp_node, vec_oprnds1, 1, number_of_vects, -1); } @@ -2023,22 +2273,7 @@ vect_schedule_slp_instance (slp_tree node, slp_instance instance, si = gsi_for_stmt (stmt); is_store = vect_transform_stmt (stmt, &si, &strided_store, node, instance); - if (is_store) - { - if (DR_GROUP_FIRST_DR (stmt_info)) - /* If IS_STORE is TRUE, the vectorization of the - interleaving chain was completed - free all the stores in - the chain. */ - vect_remove_stores (DR_GROUP_FIRST_DR (stmt_info)); - else - /* FORNOW: SLP originates only from strided stores. */ - gcc_unreachable (); - - return true; - } - - /* FORNOW: SLP originates only from strided stores. */ - return false; + return is_store; } @@ -2071,6 +2306,26 @@ vect_schedule_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) fprintf (vect_dump, "vectorizing stmts using SLP."); } + for (i = 0; VEC_iterate (slp_instance, slp_instances, i, instance); i++) + { + slp_tree root = SLP_INSTANCE_TREE (instance); + gimple store; + unsigned int j; + gimple_stmt_iterator gsi; + + for (j = 0; VEC_iterate (gimple, SLP_TREE_SCALAR_STMTS (root), j, store) + && j < SLP_INSTANCE_GROUP_SIZE (instance); j++) + { + if (!STMT_VINFO_DATA_REF (vinfo_for_stmt (store))) + break; + + /* Free the attached stmt_vec_info and remove the stmt. */ + gsi = gsi_for_stmt (store); + gsi_remove (&gsi, true); + free_stmt_vec_info (store); + } + } + return is_store; } diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 4868f73e684..988749b792f 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -1134,7 +1134,7 @@ vect_get_vec_defs (tree op0, tree op1, gimple stmt, slp_tree slp_node) { if (slp_node) - vect_get_slp_defs (slp_node, vec_oprnds0, vec_oprnds1); + vect_get_slp_defs (slp_node, vec_oprnds0, vec_oprnds1, -1); else { tree vec_oprnd; @@ -2519,7 +2519,7 @@ vectorizable_type_demotion (gimple stmt, gimple_stmt_iterator *gsi, { /* Handle uses. */ if (slp_node) - vect_get_slp_defs (slp_node, &vec_oprnds0, NULL); + vect_get_slp_defs (slp_node, &vec_oprnds0, NULL, -1); else { VEC_free (tree, heap, vec_oprnds0); @@ -2819,7 +2819,7 @@ vectorizable_type_promotion (gimple stmt, gimple_stmt_iterator *gsi, if (j == 0) { if (slp_node) - vect_get_slp_defs (slp_node, &vec_oprnds0, &vec_oprnds1); + vect_get_slp_defs (slp_node, &vec_oprnds0, &vec_oprnds1, -1); else { vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt, NULL); @@ -3105,7 +3105,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, if (slp) { /* Get vectorized arguments for SLP_NODE. */ - vect_get_slp_defs (slp_node, &vec_oprnds, NULL); + vect_get_slp_defs (slp_node, &vec_oprnds, NULL, -1); vec_oprnd = VEC_index (tree, vec_oprnds, 0); } @@ -4049,7 +4049,7 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node) || vectorizable_load (stmt, NULL, NULL, NULL, NULL) || vectorizable_call (stmt, NULL, NULL) || vectorizable_store (stmt, NULL, NULL, NULL) - || vectorizable_reduction (stmt, NULL, NULL) + || vectorizable_reduction (stmt, NULL, NULL, NULL) || vectorizable_condition (stmt, NULL, NULL, NULL, 0)); else { @@ -4201,8 +4201,7 @@ vect_transform_stmt (gimple stmt, gimple_stmt_iterator *gsi, break; case reduc_vec_info_type: - gcc_assert (!slp_node); - done = vectorizable_reduction (stmt, gsi, &vec_stmt); + done = vectorizable_reduction (stmt, gsi, &vec_stmt, slp_node); gcc_assert (done); break; diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 52b2a7ec59f..bd43a4bc173 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -242,6 +242,9 @@ typedef struct _loop_vec_info { /* The unrolling factor needed to SLP the loop. In case of that pure SLP is applied to the loop, i.e., no unrolling is needed, this is 1. */ unsigned slp_unrolling_factor; + + /* Reduction cycles detected in the loop. Used in loop-aware SLP. */ + VEC (gimple, heap) *reductions; } *loop_vec_info; /* Access Functions. */ @@ -266,6 +269,7 @@ typedef struct _loop_vec_info { #define LOOP_VINFO_STRIDED_STORES(L) (L)->strided_stores #define LOOP_VINFO_SLP_INSTANCES(L) (L)->slp_instances #define LOOP_VINFO_SLP_UNROLLING_FACTOR(L) (L)->slp_unrolling_factor +#define LOOP_VINFO_REDUCTIONS(L) (L)->reductions #define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \ VEC_length (gimple, (L)->may_misalign_stmts) > 0 @@ -844,7 +848,8 @@ extern void vect_transform_loop (loop_vec_info); extern loop_vec_info vect_analyze_loop_form (struct loop *); extern bool vectorizable_live_operation (gimple, gimple_stmt_iterator *, gimple *); -extern bool vectorizable_reduction (gimple, gimple_stmt_iterator *, gimple *); +extern bool vectorizable_reduction (gimple, gimple_stmt_iterator *, gimple *, + slp_tree); extern bool vectorizable_induction (gimple, gimple_stmt_iterator *, gimple *); extern int vect_estimate_min_profitable_iters (loop_vec_info); extern tree get_initial_def_for_reduction (gimple, tree, tree *); @@ -862,7 +867,7 @@ extern bool vect_analyze_slp (loop_vec_info, bb_vec_info); extern void vect_make_slp_decision (loop_vec_info); extern void vect_detect_hybrid_slp (loop_vec_info); extern void vect_get_slp_defs (slp_tree, VEC (tree,heap) **, - VEC (tree,heap) **); + VEC (tree,heap) **, int); extern LOC find_bb_location (basic_block); extern bb_vec_info vect_slp_analyze_bb (basic_block); extern void vect_slp_transform_bb (basic_block); diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 3b22948e39f..b23132ca043 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -3153,7 +3153,7 @@ static void adjust_range_with_scev (value_range_t *vr, struct loop *loop, gimple stmt, tree var) { - tree init, step, chrec, tmin, tmax, min, max, type; + tree init, step, chrec, tmin, tmax, min, max, type, tem; enum ev_direction dir; /* TODO. Don't adjust anti-ranges. An anti-range may provide @@ -3174,7 +3174,13 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, return; init = initial_condition_in_loop_num (chrec, loop->num); + tem = op_with_constant_singleton_value_range (init); + if (tem) + init = tem; step = evolution_part_in_loop_num (chrec, loop->num); + tem = op_with_constant_singleton_value_range (step); + if (tem) + step = tem; /* If STEP is symbolic, we can't know whether INIT will be the minimum or maximum value in the range. Also, unless INIT is @@ -6432,7 +6438,18 @@ vrp_visit_phi_node (gimple phi) /* If the new range is different than the previous value, keep iterating. */ if (update_value_range (lhs, &vr_result)) - return SSA_PROP_INTERESTING; + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Found new range for "); + print_generic_expr (dump_file, lhs, 0); + fprintf (dump_file, ": "); + dump_value_range (dump_file, &vr_result); + fprintf (dump_file, "\n\n"); + } + + return SSA_PROP_INTERESTING; + } /* Nothing changed, don't add outgoing edges. */ return SSA_PROP_NOT_INTERESTING; diff --git a/gcc/tree.c b/gcc/tree.c index 6ac13186675..0eab137863b 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -8747,12 +8747,12 @@ make_or_reuse_accum_type (unsigned size, int unsignedp, int satp) this function to select one of the types as sizetype. */ void -build_common_tree_nodes (bool signed_char, bool signed_sizetype) +build_common_tree_nodes (bool signed_char) { error_mark_node = make_node (ERROR_MARK); TREE_TYPE (error_mark_node) = error_mark_node; - initialize_sizetypes (signed_sizetype); + initialize_sizetypes (); /* Define both `signed char' and `unsigned char'. */ signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE); diff --git a/gcc/tree.h b/gcc/tree.h index 648358ff8e6..8e063b0c630 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -457,6 +457,9 @@ struct GTY(()) tree_common { CALL_CANNOT_INLINE_P in CALL_EXPR + + ENUM_IS_SCOPED in + ENUMERAL_TYPE public_flag: @@ -501,6 +504,9 @@ struct GTY(()) tree_common { OMP_CLAUSE_PRIVATE_OUTER_REF in OMP_CLAUSE_PRIVATE + TYPE_REF_IS_RVALUE in + REFERENCE_TYPE + protected_flag: TREE_PROTECTED in @@ -1162,6 +1168,9 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, /* Used to mark a CALL_EXPR as not suitable for inlining. */ #define CALL_CANNOT_INLINE_P(NODE) (CALL_EXPR_CHECK (NODE)->base.static_flag) +/* Used to mark scoped enums. */ +#define ENUM_IS_SCOPED(NODE) (ENUMERAL_TYPE_CHECK (NODE)->base.static_flag) + /* In an expr node (usually a conversion) this means the node was made implicitly and should not lead to any sort of warning. In a decl node, warnings concerning the decl should be suppressed. This is used at @@ -1341,6 +1350,10 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, /* Used in classes in C++. */ #define TREE_PROTECTED(NODE) ((NODE)->base.protected_flag) +/* True if reference type NODE is a C++ rvalue reference. */ +#define TYPE_REF_IS_RVALUE(NODE) \ + (REFERENCE_TYPE_CHECK (NODE)->base.private_flag) + /* Nonzero in a _DECL if the use of the name is defined as a deprecated feature by __attribute__((deprecated)). */ #define TREE_DEPRECATED(NODE) \ @@ -3972,7 +3985,7 @@ extern tree make_unsigned_type (int); extern tree signed_or_unsigned_type_for (int, tree); extern tree signed_type_for (tree); extern tree unsigned_type_for (tree); -extern void initialize_sizetypes (bool); +extern void initialize_sizetypes (void); extern void set_sizetype (tree); extern void fixup_unsigned_type (tree); extern tree build_pointer_type_for_mode (tree, enum machine_mode, bool); @@ -4986,7 +4999,7 @@ extern int real_onep (const_tree); extern int real_twop (const_tree); extern int real_minus_onep (const_tree); extern void init_ttree (void); -extern void build_common_tree_nodes (bool, bool); +extern void build_common_tree_nodes (bool); extern void build_common_tree_nodes_2 (int); extern void build_common_builtin_nodes (void); extern tree build_nonstandard_integer_type (unsigned HOST_WIDE_INT, int); diff --git a/gcc/unwind-dw2-fde.c b/gcc/unwind-dw2-fde.c index 60535cfd780..93d427165c4 100644 --- a/gcc/unwind-dw2-fde.c +++ b/gcc/unwind-dw2-fde.c @@ -1,6 +1,6 @@ /* Subroutines needed for unwinding stack frames for exception handling. */ /* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008, - 2009 Free Software Foundation, Inc. + 2009, 2010 Free Software Foundation, Inc. Contributed by Jason Merrill . This file is part of GCC. @@ -265,10 +265,18 @@ get_cie_encoding (const struct dwarf_cie *cie) _sleb128_t stmp; aug = cie->augmentation; + p = aug + strlen ((const char *)aug) + 1; /* Skip the augmentation string. */ + if (__builtin_expect (cie->version >= 4, 0)) + { + if (p[0] != sizeof (void *) || p[1] != 0) + return DW_EH_PE_omit; /* We are not prepared to handle unexpected + address sizes or segment selectors. */ + p += 2; /* Skip address size and segment size. */ + } + if (aug[0] != 'z') return DW_EH_PE_absptr; - p = aug + strlen ((const char *)aug) + 1; /* Skip the augmentation string. */ p = read_uleb128 (p, &utmp); /* Skip code alignment. */ p = read_sleb128 (p, &stmp); /* Skip data alignment. */ if (cie->version == 1) /* Skip return address column. */ @@ -614,6 +622,8 @@ classify_object_over_fdes (struct object *ob, const fde *this_fde) { last_cie = this_cie; encoding = get_cie_encoding (this_cie); + if (encoding == DW_EH_PE_omit) + return -1; base = base_from_object (encoding, ob); if (ob->s.b.encoding == DW_EH_PE_omit) ob->s.b.encoding = encoding; @@ -723,10 +733,26 @@ init_object (struct object* ob) { fde **p = ob->u.array; for (count = 0; *p; ++p) - count += classify_object_over_fdes (ob, *p); + { + size_t cur_count = classify_object_over_fdes (ob, *p); + if (cur_count == (size_t) -1) + goto unhandled_fdes; + count += cur_count; + } } else - count = classify_object_over_fdes (ob, ob->u.single); + { + count = classify_object_over_fdes (ob, ob->u.single); + if (count == (size_t) -1) + { + static const fde terminator; + unhandled_fdes: + ob->s.i = 0; + ob->s.b.encoding = DW_EH_PE_omit; + ob->u.single = &terminator; + return; + } + } /* The count field we have in the main struct object is somewhat limited, but should suffice for virtually all cases. If the diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c index 3cf3189bb4f..65d639d4301 100644 --- a/gcc/unwind-dw2.c +++ b/gcc/unwind-dw2.c @@ -356,7 +356,16 @@ extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context, aug += 2; } - /* Immediately following the augmentation are the code and + /* After the augmentation resp. pointer for "eh" augmentation + follows for CIE version >= 4 address size byte and + segment size byte. */ + if (__builtin_expect (cie->version >= 4, 0)) + { + if (p[0] != sizeof (void *) || p[1] != 0) + return NULL; + p += 2; + } + /* Immediately following this are the code and data alignment and return address column. */ p = read_uleb128 (p, &utmp); fs->code_align = (_Unwind_Word)utmp; diff --git a/gcc/varpool.c b/gcc/varpool.c index a13742d4957..40decfc867b 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -230,6 +230,12 @@ varpool_reset_queue (void) bool decide_is_variable_needed (struct varpool_node *node, tree decl) { + /* We do not track variable references at all and thus have no idea if the + variable was referenced in some other partition or not. + FIXME: We really need address taken edges in callgraph and varpool to + drive WPA and decide whether other partition might reference it or not. */ + if (flag_ltrans) + return true; /* If the user told us it is used, then it must be so. */ if ((node->externally_visible && !DECL_COMDAT (decl)) || node->force_output) diff --git a/include/ChangeLog b/include/ChangeLog index 938b5ba8440..5ba1afb33b9 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2010-04-20 Nick Clifton + + * sha1.h: Update copyright notice to use GPLv3. + 2010-04-14 Doug Evans * filenames.h (HAS_DRIVE_SPEC, STRIP_DRIVE_SPEC): New macros. diff --git a/include/sha1.h b/include/sha1.h index 0c2b76557e4..5473f91f412 100644 --- a/include/sha1.h +++ b/include/sha1.h @@ -1,11 +1,11 @@ /* Declarations of functions and data types used for SHA1 sum library functions. - Copyright (C) 2000, 2001, 2003, 2005, 2006, 2008 + Copyright (C) 2000, 2001, 2003, 2005, 2006, 2008, 2010 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 2, or (at your option) any + Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/libcpp/po/ChangeLog b/libcpp/po/ChangeLog index 82730a42664..ba62d0fe34e 100644 --- a/libcpp/po/ChangeLog +++ b/libcpp/po/ChangeLog @@ -1,3 +1,11 @@ +2010-04-19 Joseph Myers + + * zh_CN.po: Update. + +2010-04-18 Joseph Myers + + * es.po: Update. + 2010-04-16 Joseph Myers * sv.po: Update. diff --git a/libcpp/po/es.po b/libcpp/po/es.po index 41c7a92bf59..b64345718c6 100644 --- a/libcpp/po/es.po +++ b/libcpp/po/es.po @@ -1,14 +1,14 @@ -# Mensajes en español para cpplib-4.5-b20100204 +# Mensajes en español para cpplib-4.5.0 # Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. # This file is distributed under the same license as the gcc package. # Cristian Othón Martínez Vera , 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010. # msgid "" msgstr "" -"Project-Id-Version: cpplib 4.5-b20100204\n" +"Project-Id-Version: cpplib 4.5.0\n" "Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n" "POT-Creation-Date: 2010-04-06 14:10+0000\n" -"PO-Revision-Date: 2010-02-05 13:16-0600\n" +"PO-Revision-Date: 2010-04-18 03:46-0500\n" "Last-Translator: Cristian Othón Martínez Vera \n" "Language-Team: Spanish \n" "MIME-Version: 1.0\n" diff --git a/libcpp/po/zh_CN.po b/libcpp/po/zh_CN.po index 94accfb46bc..27e040480db 100644 --- a/libcpp/po/zh_CN.po +++ b/libcpp/po/zh_CN.po @@ -1,19 +1,21 @@ # Simplified Chinese translation for cpplib. # Copyright (C) 2005 Free Software Foundation, Inc. # This file is distributed under the same license as the gcc package. -# Meng Jie , 2005-2009. +# Meng Jie , 2005-2010. # msgid "" msgstr "" -"Project-Id-Version: cpplib 4.5-b20100204\n" +"Project-Id-Version: cpplib 4.5.0\n" "Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n" "POT-Creation-Date: 2010-04-06 14:10+0000\n" -"PO-Revision-Date: 2010-02-23 15:53+0800\n" +"PO-Revision-Date: 2010-04-19 14:55+0800\n" "Last-Translator: Meng Jie \n" "Language-Team: Chinese (simplified) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Chinese\n" +"X-Poedit-Country: CHINA\n" #: charset.c:674 #, c-format diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 5534cd6adaa..2b267e437a8 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,20 @@ +2010-04-21 Jakub Jelinek + + PR middle-end/43570 + * testsuite/libgomp.fortran/vla8.f90: New test. + +2010-04-20 Jakub Jelinek + + PR libgomp/43706 + * config/linux/affinity.c (gomp_init_affinity): Decrease + gomp_available_cpus if affinity mask confines the process to fewer + CPUs. + * config/linux/proc.c (get_num_procs): If gomp_cpu_affinity is + non-NULL, just return gomp_available_cpus. + + PR libgomp/43569 + * sections.c (gomp_sections_init): Initialize ws->mode. + 2010-04-14 Uros Bizjak * acinclude.m4 (LIBGOMP_CHECK_SYNC_BUILTINS): Remove set but diff --git a/libgomp/config/linux/affinity.c b/libgomp/config/linux/affinity.c index 40519e8896a..da9f3d8fdcb 100644 --- a/libgomp/config/linux/affinity.c +++ b/libgomp/config/linux/affinity.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +/* Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Jakub Jelinek . This file is part of the GNU OpenMP Library (libgomp). @@ -39,8 +39,9 @@ static unsigned int affinity_counter; void gomp_init_affinity (void) { - cpu_set_t cpuset; + cpu_set_t cpuset, cpusetnew; size_t idx, widx; + unsigned long cpus = 0; if (pthread_getaffinity_np (pthread_self (), sizeof (cpuset), &cpuset)) { @@ -51,10 +52,18 @@ gomp_init_affinity (void) return; } + CPU_ZERO (&cpusetnew); for (widx = idx = 0; idx < gomp_cpu_affinity_len; idx++) if (gomp_cpu_affinity[idx] < CPU_SETSIZE && CPU_ISSET (gomp_cpu_affinity[idx], &cpuset)) - gomp_cpu_affinity[widx++] = gomp_cpu_affinity[idx]; + { + if (! CPU_ISSET (gomp_cpu_affinity[idx], &cpusetnew)) + { + cpus++; + CPU_SET (gomp_cpu_affinity[idx], &cpusetnew); + } + gomp_cpu_affinity[widx++] = gomp_cpu_affinity[idx]; + } if (widx == 0) { @@ -66,6 +75,8 @@ gomp_init_affinity (void) } gomp_cpu_affinity_len = widx; + if (cpus < gomp_available_cpus) + gomp_available_cpus = cpus; CPU_ZERO (&cpuset); CPU_SET (gomp_cpu_affinity[0], &cpuset); pthread_setaffinity_np (pthread_self (), sizeof (cpuset), &cpuset); diff --git a/libgomp/config/linux/proc.c b/libgomp/config/linux/proc.c index dad6237e609..01f51dfa193 100644 --- a/libgomp/config/linux/proc.c +++ b/libgomp/config/linux/proc.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +/* Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. Contributed by Jakub Jelinek . This file is part of the GNU OpenMP Library (libgomp). @@ -104,26 +105,13 @@ get_num_procs (void) } else { - size_t idx; - static int affinity_cpus; - /* We can't use pthread_getaffinity_np in this case (we have changed it ourselves, it binds to just one CPU). Count instead the number of different CPUs we are - using. */ - CPU_ZERO (&cpuset); - if (affinity_cpus == 0) - { - int cpus = 0; - for (idx = 0; idx < gomp_cpu_affinity_len; idx++) - if (! CPU_ISSET (gomp_cpu_affinity[idx], &cpuset)) - { - cpus++; - CPU_SET (gomp_cpu_affinity[idx], &cpuset); - } - affinity_cpus = cpus; - } - return affinity_cpus; + using. gomp_init_affinity updated gomp_available_cpus to + the number of CPUs in the GOMP_AFFINITY mask that we are + allowed to use though. */ + return gomp_available_cpus; } #endif #ifdef _SC_NPROCESSORS_ONLN diff --git a/libgomp/sections.c b/libgomp/sections.c index 7acd441de53..c7f49b7c32a 100644 --- a/libgomp/sections.c +++ b/libgomp/sections.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc. +/* Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Richard Henderson . This file is part of the GNU OpenMP Library (libgomp). @@ -34,9 +34,25 @@ gomp_sections_init (struct gomp_work_share *ws, unsigned count) { ws->sched = GFS_DYNAMIC; ws->chunk_size = 1; - ws->end = count + 1; + ws->end = count + 1L; ws->incr = 1; ws->next = 1; +#ifdef HAVE_SYNC_BUILTINS + /* Prepare things to make each iteration faster. */ + if (sizeof (long) > sizeof (unsigned)) + ws->mode = 1; + else + { + struct gomp_thread *thr = gomp_thread (); + struct gomp_team *team = thr->ts.team; + long nthreads = team ? team->nthreads : 1; + + ws->mode = ((nthreads | ws->end) + < 1UL << (sizeof (long) * __CHAR_BIT__ / 2 - 1)); + } +#else + ws->mode = 0; +#endif } /* This routine is called when first encountering a sections construct diff --git a/libgomp/testsuite/libgomp.fortran/vla8.f90 b/libgomp/testsuite/libgomp.fortran/vla8.f90 new file mode 100644 index 00000000000..f66fe84a375 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/vla8.f90 @@ -0,0 +1,254 @@ +! { dg-do run } + + call test +contains + subroutine check (x, y, l) + integer :: x, y + logical :: l + l = l .or. x .ne. y + end subroutine check + + subroutine foo (c, d, e, f, g, h, i, j, k, n) + use omp_lib + integer :: n + character (len = *) :: c + character (len = n) :: d + integer, dimension (2, 3:5, n) :: e + integer, dimension (2, 3:n, n) :: f + character (len = *), dimension (5, 3:n) :: g + character (len = n), dimension (5, 3:n) :: h + real, dimension (:, :, :) :: i + double precision, dimension (3:, 5:, 7:) :: j + integer, dimension (:, :, :) :: k + logical :: l + integer :: p, q, r + character (len = n) :: s + integer, dimension (2, 3:5, n) :: t + integer, dimension (2, 3:n, n) :: u + character (len = n), dimension (5, 3:n) :: v + character (len = 2 * n + 24) :: w + integer :: x, z + character (len = 1) :: y + l = .false. +!$omp parallel default (none) private (c, d, e, f, g, h, i, j, k) & +!$omp & private (s, t, u, v) reduction (.or.:l) num_threads (6) & +!$omp private (p, q, r, w, x, y) shared (z) + x = omp_get_thread_num () + w = '' + if (x .eq. 0) w = 'thread0thr_number_0THREAD0THR_NUMBER_0' + if (x .eq. 1) w = 'thread1thr_number_1THREAD1THR_NUMBER_1' + if (x .eq. 2) w = 'thread2thr_number_2THREAD2THR_NUMBER_2' + if (x .eq. 3) w = 'thread3thr_number_3THREAD3THR_NUMBER_3' + if (x .eq. 4) w = 'thread4thr_number_4THREAD4THR_NUMBER_4' + if (x .eq. 5) w = 'thread5thr_number_5THREAD5THR_NUMBER_5' + c = w(8:19) + d = w(1:7) + forall (p = 1:2, q = 3:5, r = 1:7) e(p, q, r) = 5 * x + p + q + 2 * r + forall (p = 1:2, q = 3:7, r = 1:7) f(p, q, r) = 25 * x + p + q + 2 * r + forall (p = 1:5, q = 3:7, p + q .le. 8) g(p, q) = w(8:19) + forall (p = 1:5, q = 3:7, p + q .gt. 8) g(p, q) = w(27:38) + forall (p = 1:5, q = 3:7, p + q .le. 8) h(p, q) = w(1:7) + forall (p = 1:5, q = 3:7, p + q .gt. 8) h(p, q) = w(20:26) + forall (p = 3:5, q = 2:6, r = 1:7) i(p - 2, q - 1, r) = (7.5 + x) * p * q * r + forall (p = 3:5, q = 2:6, r = 1:7) j(p, q + 3, r + 6) = (9.5 + x) * p * q * r + forall (p = 1:5, q = 7:7, r = 4:6) k(p, q - 6, r - 3) = 19 + x + p + q + 3 * r + s = w(20:26) + forall (p = 1:2, q = 3:5, r = 1:7) t(p, q, r) = -10 + x + p - q + 2 * r + forall (p = 1:2, q = 3:7, r = 1:7) u(p, q, r) = 30 - x - p + q - 2 * r + forall (p = 1:5, q = 3:7, p + q .le. 8) v(p, q) = w(1:7) + forall (p = 1:5, q = 3:7, p + q .gt. 8) v(p, q) = w(20:26) +!$omp barrier + y = '' + if (x .eq. 0) y = '0' + if (x .eq. 1) y = '1' + if (x .eq. 2) y = '2' + if (x .eq. 3) y = '3' + if (x .eq. 4) y = '4' + if (x .eq. 5) y = '5' + l = l .or. w(7:7) .ne. y + l = l .or. w(19:19) .ne. y + l = l .or. w(26:26) .ne. y + l = l .or. w(38:38) .ne. y + l = l .or. c .ne. w(8:19) + l = l .or. d .ne. w(1:7) + l = l .or. s .ne. w(20:26) + do 103, p = 1, 2 + do 103, q = 3, 7 + do 103, r = 1, 7 + if (q .lt. 6) l = l .or. e(p, q, r) .ne. 5 * x + p + q + 2 * r + l = l .or. f(p, q, r) .ne. 25 * x + p + q + 2 * r + if (r .lt. 6 .and. q + r .le. 8) l = l .or. g(r, q) .ne. w(8:19) + if (r .lt. 6 .and. q + r .gt. 8) l = l .or. g(r, q) .ne. w(27:38) + if (r .lt. 6 .and. q + r .le. 8) l = l .or. h(r, q) .ne. w(1:7) + if (r .lt. 6 .and. q + r .gt. 8) l = l .or. h(r, q) .ne. w(20:26) + if (q .lt. 6) l = l .or. t(p, q, r) .ne. -10 + x + p - q + 2 * r + l = l .or. u(p, q, r) .ne. 30 - x - p + q - 2 * r + if (r .lt. 6 .and. q + r .le. 8) l = l .or. v(r, q) .ne. w(1:7) + if (r .lt. 6 .and. q + r .gt. 8) l = l .or. v(r, q) .ne. w(20:26) +103 continue + do 104, p = 3, 5 + do 104, q = 2, 6 + do 104, r = 1, 7 + l = l .or. i(p - 2, q - 1, r) .ne. (7.5 + x) * p * q * r + l = l .or. j(p, q + 3, r + 6) .ne. (9.5 + x) * p * q * r +104 continue + do 105, p = 1, 5 + do 105, q = 4, 6 + l = l .or. k(p, 1, q - 3) .ne. 19 + x + p + 7 + 3 * q +105 continue + call check (size (e, 1), 2, l) + call check (size (e, 2), 3, l) + call check (size (e, 3), 7, l) + call check (size (e), 42, l) + call check (size (f, 1), 2, l) + call check (size (f, 2), 5, l) + call check (size (f, 3), 7, l) + call check (size (f), 70, l) + call check (size (g, 1), 5, l) + call check (size (g, 2), 5, l) + call check (size (g), 25, l) + call check (size (h, 1), 5, l) + call check (size (h, 2), 5, l) + call check (size (h), 25, l) + call check (size (i, 1), 3, l) + call check (size (i, 2), 5, l) + call check (size (i, 3), 7, l) + call check (size (i), 105, l) + call check (size (j, 1), 4, l) + call check (size (j, 2), 5, l) + call check (size (j, 3), 7, l) + call check (size (j), 140, l) + call check (size (k, 1), 5, l) + call check (size (k, 2), 1, l) + call check (size (k, 3), 3, l) + call check (size (k), 15, l) +!$omp single + z = omp_get_thread_num () +!$omp end single copyprivate (c, d, e, f, g, h, i, j, k, s, t, u, v) + w = '' + x = z + if (x .eq. 0) w = 'thread0thr_number_0THREAD0THR_NUMBER_0' + if (x .eq. 1) w = 'thread1thr_number_1THREAD1THR_NUMBER_1' + if (x .eq. 2) w = 'thread2thr_number_2THREAD2THR_NUMBER_2' + if (x .eq. 3) w = 'thread3thr_number_3THREAD3THR_NUMBER_3' + if (x .eq. 4) w = 'thread4thr_number_4THREAD4THR_NUMBER_4' + if (x .eq. 5) w = 'thread5thr_number_5THREAD5THR_NUMBER_5' + y = '' + if (x .eq. 0) y = '0' + if (x .eq. 1) y = '1' + if (x .eq. 2) y = '2' + if (x .eq. 3) y = '3' + if (x .eq. 4) y = '4' + if (x .eq. 5) y = '5' + l = l .or. w(7:7) .ne. y + l = l .or. w(19:19) .ne. y + l = l .or. w(26:26) .ne. y + l = l .or. w(38:38) .ne. y + l = l .or. c .ne. w(8:19) + l = l .or. d .ne. w(1:7) + l = l .or. s .ne. w(20:26) + do 113, p = 1, 2 + do 113, q = 3, 7 + do 113, r = 1, 7 + if (q .lt. 6) l = l .or. e(p, q, r) .ne. 5 * x + p + q + 2 * r + l = l .or. f(p, q, r) .ne. 25 * x + p + q + 2 * r + if (r .lt. 6 .and. q + r .le. 8) l = l .or. g(r, q) .ne. w(8:19) + if (r .lt. 6 .and. q + r .gt. 8) l = l .or. g(r, q) .ne. w(27:38) + if (r .lt. 6 .and. q + r .le. 8) l = l .or. h(r, q) .ne. w(1:7) + if (r .lt. 6 .and. q + r .gt. 8) l = l .or. h(r, q) .ne. w(20:26) + if (q .lt. 6) l = l .or. t(p, q, r) .ne. -10 + x + p - q + 2 * r + l = l .or. u(p, q, r) .ne. 30 - x - p + q - 2 * r + if (r .lt. 6 .and. q + r .le. 8) l = l .or. v(r, q) .ne. w(1:7) + if (r .lt. 6 .and. q + r .gt. 8) l = l .or. v(r, q) .ne. w(20:26) +113 continue + do 114, p = 3, 5 + do 114, q = 2, 6 + do 114, r = 1, 7 + l = l .or. i(p - 2, q - 1, r) .ne. (7.5 + x) * p * q * r + l = l .or. j(p, q + 3, r + 6) .ne. (9.5 + x) * p * q * r +114 continue + do 115, p = 1, 5 + do 115, q = 4, 6 + l = l .or. k(p, 1, q - 3) .ne. 19 + x + p + 7 + 3 * q +115 continue + x = omp_get_thread_num () + w = '' + if (x .eq. 0) w = 'thread0thr_number_0THREAD0THR_NUMBER_0' + if (x .eq. 1) w = 'thread1thr_number_1THREAD1THR_NUMBER_1' + if (x .eq. 2) w = 'thread2thr_number_2THREAD2THR_NUMBER_2' + if (x .eq. 3) w = 'thread3thr_number_3THREAD3THR_NUMBER_3' + if (x .eq. 4) w = 'thread4thr_number_4THREAD4THR_NUMBER_4' + if (x .eq. 5) w = 'thread5thr_number_5THREAD5THR_NUMBER_5' + c = w(8:19) + d = w(1:7) + forall (p = 1:2, q = 3:5, r = 1:7) e(p, q, r) = 5 * x + p + q + 2 * r + forall (p = 1:2, q = 3:7, r = 1:7) f(p, q, r) = 25 * x + p + q + 2 * r + forall (p = 1:5, q = 3:7, p + q .le. 8) g(p, q) = w(8:19) + forall (p = 1:5, q = 3:7, p + q .gt. 8) g(p, q) = w(27:38) + forall (p = 1:5, q = 3:7, p + q .le. 8) h(p, q) = w(1:7) + forall (p = 1:5, q = 3:7, p + q .gt. 8) h(p, q) = w(20:26) + forall (p = 3:5, q = 2:6, r = 1:7) i(p - 2, q - 1, r) = (7.5 + x) * p * q * r + forall (p = 3:5, q = 2:6, r = 1:7) j(p, q + 3, r + 6) = (9.5 + x) * p * q * r + forall (p = 1:5, q = 7:7, r = 4:6) k(p, q - 6, r - 3) = 19 + x + p + q + 3 * r + s = w(20:26) + forall (p = 1:2, q = 3:5, r = 1:7) t(p, q, r) = -10 + x + p - q + 2 * r + forall (p = 1:2, q = 3:7, r = 1:7) u(p, q, r) = 30 - x - p + q - 2 * r + forall (p = 1:5, q = 3:7, p + q .le. 8) v(p, q) = w(1:7) + forall (p = 1:5, q = 3:7, p + q .gt. 8) v(p, q) = w(20:26) +!$omp barrier + y = '' + if (x .eq. 0) y = '0' + if (x .eq. 1) y = '1' + if (x .eq. 2) y = '2' + if (x .eq. 3) y = '3' + if (x .eq. 4) y = '4' + if (x .eq. 5) y = '5' + l = l .or. w(7:7) .ne. y + l = l .or. w(19:19) .ne. y + l = l .or. w(26:26) .ne. y + l = l .or. w(38:38) .ne. y + l = l .or. c .ne. w(8:19) + l = l .or. d .ne. w(1:7) + l = l .or. s .ne. w(20:26) + do 123, p = 1, 2 + do 123, q = 3, 7 + do 123, r = 1, 7 + if (q .lt. 6) l = l .or. e(p, q, r) .ne. 5 * x + p + q + 2 * r + l = l .or. f(p, q, r) .ne. 25 * x + p + q + 2 * r + if (r .lt. 6 .and. q + r .le. 8) l = l .or. g(r, q) .ne. w(8:19) + if (r .lt. 6 .and. q + r .gt. 8) l = l .or. g(r, q) .ne. w(27:38) + if (r .lt. 6 .and. q + r .le. 8) l = l .or. h(r, q) .ne. w(1:7) + if (r .lt. 6 .and. q + r .gt. 8) l = l .or. h(r, q) .ne. w(20:26) + if (q .lt. 6) l = l .or. t(p, q, r) .ne. -10 + x + p - q + 2 * r + l = l .or. u(p, q, r) .ne. 30 - x - p + q - 2 * r + if (r .lt. 6 .and. q + r .le. 8) l = l .or. v(r, q) .ne. w(1:7) + if (r .lt. 6 .and. q + r .gt. 8) l = l .or. v(r, q) .ne. w(20:26) +123 continue + do 124, p = 3, 5 + do 124, q = 2, 6 + do 124, r = 1, 7 + l = l .or. i(p - 2, q - 1, r) .ne. (7.5 + x) * p * q * r + l = l .or. j(p, q + 3, r + 6) .ne. (9.5 + x) * p * q * r +124 continue + do 125, p = 1, 5 + do 125, q = 4, 6 + l = l .or. k(p, 1, q - 3) .ne. 19 + x + p + 7 + 3 * q +125 continue +!$omp end parallel + if (l) call abort + end subroutine foo + + subroutine test + character (len = 12) :: c + character (len = 7) :: d + integer, dimension (2, 3:5, 7) :: e + integer, dimension (2, 3:7, 7) :: f + character (len = 12), dimension (5, 3:7) :: g + character (len = 7), dimension (5, 3:7) :: h + real, dimension (3:5, 2:6, 1:7) :: i + double precision, dimension (3:6, 2:6, 1:7) :: j + integer, dimension (1:5, 7:7, 4:6) :: k + integer :: p, q, r + call foo (c, d, e, f, g, h, i, j, k, 7) + end subroutine test +end diff --git a/libjava/ChangeLog b/libjava/ChangeLog index dd502d13c09..c986d1092c7 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,8 @@ +2010-04-19 Andrew Haley + + PR libgcj/40860 + * configure.ac: Handle --no-merge-exidx-entries. + 2010-04-07 Jakub Jelinek * exception.cc (_Jv_Throw): Avoid set but not used warning. diff --git a/libjava/configure b/libjava/configure index ca3329d3944..6be8109031a 100755 --- a/libjava/configure +++ b/libjava/configure @@ -20520,6 +20520,39 @@ arm*linux*eabi) ;; esac +# Check for --no-merge-exidx-entries, an ARM-specific linker option. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --no-merge-exidx-entries" >&5 +$as_echo_n "checking for --no-merge-exidx-entries... " >&6; } +if test "${libgcj_cv_exidx+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + saved_ldflags="$LDFLAGS" + LDFLAGS="${LDFLAGS} -Wl,--no-merge-exidx-entries" + if test x$gcc_no_link = xyes; then + as_fn_error "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main(void){ return 0;} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "libgcj_cv_exidx=yes" +else + eval "libgcj_cv_exidx=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="${saved_ldflags}" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcj_cv_exidx" >&5 +$as_echo "$libgcj_cv_exidx" >&6; } +if test "${libgcj_cv_exidx}" = "yes"; then + SYSTEMSPEC="${SYSTEMSPEC} --no-merge-exidx-entries" + extra_ldflags="${extra_ldflags} -Wl,--no-merge-exidx-entries" +fi + + diff --git a/libjava/configure.ac b/libjava/configure.ac index 255fb64595e..7f4befa830b 100644 --- a/libjava/configure.ac +++ b/libjava/configure.ac @@ -927,6 +927,21 @@ arm*linux*eabi) extra_ldflags_libjava=-liconv ;; esac + +# Check for --no-merge-exidx-entries, an ARM-specific linker option. +AC_CACHE_CHECK([for --no-merge-exidx-entries], [libgcj_cv_exidx], + [saved_ldflags="$LDFLAGS" + LDFLAGS="${LDFLAGS} -Wl,--no-merge-exidx-entries" + AC_LINK_IFELSE([int main(void){ return 0;} ], + [eval "libgcj_cv_exidx=yes"], + [eval "libgcj_cv_exidx=no"]) + LDFLAGS="${saved_ldflags}"] +) +if test "${libgcj_cv_exidx}" = "yes"; then + SYSTEMSPEC="${SYSTEMSPEC} --no-merge-exidx-entries" + extra_ldflags="${extra_ldflags} -Wl,--no-merge-exidx-entries" +fi + AC_SUBST(extra_ldflags_libjava) AC_SUBST(extra_ldflags) AC_SUBST(LIBSTDCXXSPEC) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index d34b55a8362..96d166fa225 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,20 @@ +2010-04-22 Johannes Singler + + * include/parallel/partition.h (__parallel_partition): + Improve scalability by: + -introducing new variables __leftold, __rightold, __dist, thus + -getting rid of omp lock by using atomic operations + -getting rid of two omp barriers + +2010-04-22 Jonathan Wakely + + * doc/xml/faq.xml: Link to manual. + * doc/xml/manual/using.xml: Expand dynamic libraries section. + * doc/xml/manual/strings.xml: Mention shrink_to_fit() member. + * doc/xml/manual/prerequisites.xml: Link to doxygen requirements. + * doc/xml/manual/appendix_contributing.xml: Update Bash version. + * doc/html/*: Regenerate. + 2010-04-13 Ian Lance Taylor * include/backward/hash_map: Don't #include "backward_warning.h" diff --git a/libstdc++-v3/doc/html/api.html b/libstdc++-v3/doc/html/api.html index 61ddda971a2..5a40764298d 100644 --- a/libstdc++-v3/doc/html/api.html +++ b/libstdc++-v3/doc/html/api.html @@ -1,24 +1,25 @@ -API and Source Level Documentation

API and Source Level Documentation

API Documentation


-The GNU C++ library sources have been specially formatted so that with the -proper invocation of another tool (Doxygen), a set of HTML pages -are generated from the sources files themselves. The resultant -documentation is referred to as Source Level Documentation, and is -useful for examining the signatures of public member functions for -the library classes, finding out what is in a particular include -file, looking at inheritance diagrams, etc. + The GNU C++ library sources have been specially formatted so that + with the proper invocation of another tool (Doxygen), a set of + indexed reference material can generated from the sources files + themselves. The resultant documentation is referred to as the API + documentation, and is useful for examining the signatures of public + member functions for the library classes, finding out what is in a + particular include file, looking at inheritance diagrams, etc.

-The source-level documentation for the most recent releases can be -viewed online: + The API documentation, rendered into HTML, can be viewed online:

  • for the 3.4 release @@ -39,16 +40,14 @@ viewed online: (For the main development tree; see the date on the first page.)

-This generated HTML collection, as above, is also available for download in the libstdc++ snapshots directory at + The rendered HTML, as above, is also available for download on the + gcc.org site in a directory located at <URL:ftp://gcc.gnu.org/pub/gcc/libstdc++/doxygen/>. You will almost certainly need to use one of the mirror sites to download - the tarball. After unpacking, simply load libstdc++-html-*/index.html + the tarball. After unpacking, simply load libstdc++-html-*/index.html into a browser.

-Documentation for older releases is available for download only, not -online viewing. -

-In addition, an initial set of man pages are also available in the -same place as the HTML collections. Start with C++Intro(3). + In addition, a rendered set of man pages are available in the same + location specified above. Start with C++Intro(3).

diff --git a/libstdc++-v3/doc/html/bk02.html b/libstdc++-v3/doc/html/bk02.html dissimilarity index 65% index f0dbebb2ac4..16ac5f094f6 100644 --- a/libstdc++-v3/doc/html/bk02.html +++ b/libstdc++-v3/doc/html/bk02.html @@ -1,3 +1,3 @@ - - - + + +

Table of Contents

API Documentation
diff --git a/libstdc++-v3/doc/html/bk03.html b/libstdc++-v3/doc/html/bk03.html dissimilarity index 68% index bc43c8d07bb..89beabfeb26 100644 --- a/libstdc++-v3/doc/html/bk03.html +++ b/libstdc++-v3/doc/html/bk03.html @@ -1,3 +1,3 @@ - - - + + + diff --git a/libstdc++-v3/doc/html/faq.html b/libstdc++-v3/doc/html/faq.html index 31ba54106aa..046cbb3bc83 100644 --- a/libstdc++-v3/doc/html/faq.html +++ b/libstdc++-v3/doc/html/faq.html @@ -4,7 +4,7 @@ 2008 FSF -



1. General Information
1.1. What is libstdc++?
1.2. Why should I use libstdc++? @@ -315,12 +315,15 @@ and ldconfig for more information. The dynamic linker has different names on different platforms but the man page is usually called something such as ld.so/rtld/dld.so. +

+ Using LD_LIBRARY_PATH is not always the best solution, Finding Dynamic or Shared + Libraries in the manual gives some alternatives.

3.5.

What's libsupc++?

If the only functions from libstdc++.a which you need are language support functions (those listed in - clause 18 of the + clause 18 of the standard, e.g., new and delete), then try linking against libsupc++.a, which is a subset of @@ -647,8 +650,9 @@ typo, or wrong visibility, or you just plain forgot, etc).

More information, including how to optionally enable/disable the - checks, is available - here. + checks, is available in the + Diagnostics. + chapter of the manual.

6.6.

Program crashes when using library code in a dynamically-loaded library @@ -685,7 +689,7 @@ list::size() is O(n)!

See - the Containers + the Containers chapter.

6.9.

Aw, that's easy to fix! @@ -869,6 +873,6 @@     

The copy will take O(n) time and the swap is constant time.

- See Shrink-to-fit + See Shrink-to-fit strings for a similar solution for strings.

diff --git a/libstdc++-v3/doc/html/manual/abi.html b/libstdc++-v3/doc/html/manual/abi.html index 25d0a568ee6..618da46367b 100644 --- a/libstdc++-v3/doc/html/manual/abi.html +++ b/libstdc++-v3/doc/html/manual/abi.html @@ -8,12 +8,12 @@ C++ applications often dependent on specific language support routines, say for throwing exceptions, or catching exceptions, and perhaps also dependent on features in the C++ Standard Library. -

+

The C++ Standard Library has many include files, types defined in those include files, specific named functions, and other behavior. The text of these behaviors, as written in source include files, is called the Application Programing Interface, or API. -

+

Furthermore, C++ source that is compiled into object files is transformed by the compiler: it arranges objects with specific alignment and in a particular layout, mangling names according to a @@ -32,7 +32,7 @@ -fno-exceptions, but include others: see the complete list in the GCC manual under the heading Options for Code Generation Conventions. -

+

The configure options used when building a specific libstdc++ version may also impact the resulting library ABI. The available configure options, and their impact on the library ABI, are @@ -240,11 +240,11 @@ int main() %g++ hello.cc -o hello.out %ldd hello.out - libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x00764000) - libm.so.6 => /lib/tls/libm.so.6 (0x004a8000) - libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x40016000) - libc.so.6 => /lib/tls/libc.so.6 (0x0036d000) - /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000) + libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x00764000) + libm.so.6 => /lib/tls/libm.so.6 (0x004a8000) + libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x40016000) + libc.so.6 => /lib/tls/libc.so.6 (0x0036d000) + /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000) %nm hello.out

@@ -273,7 +273,7 @@ class that would otherwise have implicit versions. This will change the way the compiler deals with this class in by-value return statements or parameters: instead of being passing instances of this class in registers, the compiler will be forced to use memory. See this part - of the C++ ABI documentation for further details. + of the C++ ABI documentation for further details.

Implementation

  1. Separation of interface and implementation

    @@ -298,7 +298,7 @@ class in registers, the compiler will be forced to use memory. See wchar_t instantiations, and includes basic_string, the locale facets, and the types in iostreams. -

+

In addition, these techniques have the additional benefit that they reduce binary size, which can increase runtime performance.

  • @@ -329,7 +329,7 @@ standard includes.

  • <

    Testing the C++ compiler ABI can be done various ways.

    - One. Intel ABI checker. + One. Intel ABI checker.

    Two. The second is yet unreleased, but has been announced on the gcc @@ -344,16 +344,16 @@ discussed on the gcc mailing lists.

    Testing the C++ library ABI can also be done various ways.

    -One. -(Brendan Kehoe, Jeff Law suggestion to run 'make check-c++' two ways, +One. +(Brendan Kehoe, Jeff Law suggestion to run 'make check-c++' two ways, one with a new compiler and an old library, and the other with an old compiler and a new library, and look for testsuite regressions)

    Details on how to set this kind of test up can be found here: http://gcc.gnu.org/ml/gcc/2002-08/msg00142.html

    -Two. -Use the 'make check-abi' rule in the libstdc++ Makefile. +Two. +Use the 'make check-abi' rule in the libstdc++ Makefile.

    This is a proactive check the library ABI. Currently, exported symbol names that are either weak or defined are checked against a last known @@ -372,7 +372,7 @@ machinery.

    This dataset is insufficient, yet a start. Also needed is a comprehensive check for all user-visible types part of the standard -library for sizeof() and alignof() changes. +library for sizeof() and alignof() changes.

    Verifying compatible layouts of objects is not even attempted. It should be possible to use sizeof, alignof, and offsetof to compute @@ -403,7 +403,7 @@ exceptions, locale, etc. %$bld/H-x86-gcc-3.4.0/bin/g++ -c a.cc -%ar cru libone.a a.o +%ar cru libone.a a.o

    And, libtwo is constructed as follows:

     %$bld/H-x86-gcc-3.3.3/bin/g++ -fPIC -DPIC -c b.cc
     
    @@ -413,24 +413,24 @@ exceptions, locale, etc.
     
     %$bld/H-x86-gcc-3.3.3/bin/g++ -c b.cc
     
    -%ar cru libtwo.a b.o 
    +%ar cru libtwo.a b.o
     

    ...with the resulting libraries looking like

     
     %ldd libone.so.1.0.0
    -        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x40016000)
    -        libm.so.6 => /lib/tls/libm.so.6 (0x400fa000)
    -        libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x4011c000)
    -        libc.so.6 => /lib/tls/libc.so.6 (0x40125000)
    -        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000)
    +	libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x40016000)
    +	libm.so.6 => /lib/tls/libm.so.6 (0x400fa000)
    +	libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x4011c000)
    +	libc.so.6 => /lib/tls/libc.so.6 (0x40125000)
    +	/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000)
     
     %ldd libtwo.so.1.0.0
    -        libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40027000)
    -        libm.so.6 => /lib/tls/libm.so.6 (0x400e1000)
    -        libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x40103000)
    -        libc.so.6 => /lib/tls/libc.so.6 (0x4010c000)
    -        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000)
    +	libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40027000)
    +	libm.so.6 => /lib/tls/libm.so.6 (0x400e1000)
    +	libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x40103000)
    +	libc.so.6 => /lib/tls/libc.so.6 (0x4010c000)
    +	/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000)
     
    -

    +

    Then, the "C" compiler is used to compile a source file that uses functions from each library.

    @@ -440,18 +440,18 @@ gcc test.c -g -O2 -L. -lone -ltwo /usr/lib/libstdc++.so.5 /usr/lib/libstdc++.so.
     

     
     %ldd a.out
    -        libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x00764000)
    -        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x40015000)
    -        libc.so.6 => /lib/tls/libc.so.6 (0x0036d000)
    -        libm.so.6 => /lib/tls/libm.so.6 (0x004a8000)
    -        libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x400e5000)
    -        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000)
    +	libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x00764000)
    +	libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x40015000)
    +	libc.so.6 => /lib/tls/libc.so.6 (0x0036d000)
    +	libm.so.6 => /lib/tls/libm.so.6 (0x004a8000)
    +	libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x400e5000)
    +	/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000)
     
     

    This resulting binary, when executed, will be able to safely use code from both liba, and the dependent libstdc++.so.6, and libb, with the dependent libstdc++.so.5. -

    Outstanding Issues

    +

    Outstanding Issues

    Some features in the C++ language make versioning especially difficult. In particular, compiler generated constructs such as implicit instantiations for templates, typeinfo information, and @@ -464,60 +464,71 @@ gcc test.c -g -O2 -L. -lone -ltwo /usr/lib/libstdc++.so.5 /usr/lib/libstdc++.so. 24660: versioning weak symbols in libstdc++

    19664: libstdc++ headers should have pop/push of the visibility around the declarations -

    Bibliography

    - ABIcheck, a vague idea of checking ABI compatibility - . +

    Bibliography

    - C++ ABI Reference - . + .

    - Intel® Compilers for Linux* -Compatibility with the GNU Compilers - . + .

    - Sun Solaris 2.9 : Linker and Libraries Guide (document 816-1386) - . + .

    - Sun Solaris 2.9 : C++ Migration Guide (document 816-2459) - . + .

    - How to Write Shared Libraries - . Ulrich Drepper. + .

    - C++ ABI for the ARM Architecture - . + . Ulrich Drepper.

    - Dynamic Shared Objects: Survey and Issues - . - ISO C++ J16/06-0046 - . Benjamin Kosnik. + .

    - Versioning With Namespaces - . - ISO C++ J16/06-0083 - . Benjamin Kosnik. + . + ISO C++ J16/06-0046 + . Benjamin Kosnik.

    - Binary Compatibility of Shared Libraries Implemented in C++ on GNU/Linux Systems - . -SYRCoSE 2009 - . Pavel Shved. Denis Silakov. + . + ISO C++ J16/06-0083 + . Benjamin Kosnik.

    + . + SYRCoSE 2009 + . Pavel Shved. Denis Silakov.

    diff --git a/libstdc++-v3/doc/html/manual/algorithms.html b/libstdc++-v3/doc/html/manual/algorithms.html dissimilarity index 86% index 6049cd8ec0e..3e5b3a5a86e 100644 --- a/libstdc++-v3/doc/html/manual/algorithms.html +++ b/libstdc++-v3/doc/html/manual/algorithms.html @@ -1,9 +1,61 @@ - - -Part IX.  Algorithms

    Part IX.  - Algorithms - -

    + + +Chapter 11.  Algorithms

    Chapter 11.  + Algorithms + +

    Table of Contents

    Mutating
    swap

    + The neatest accomplishment of the algorithms sect1 is that all the + work is done via iterators, not containers directly. This means two + important things: +

    1. + Anything that behaves like an iterator can be used in one of + these algorithms. Raw pointers make great candidates, thus + built-in arrays are fine containers, as well as your own + iterators. +

    2. + The algorithms do not (and cannot) affect the container as a + whole; only the things between the two iterator endpoints. If + you pass a range of iterators only enclosing the middle third of + a container, then anything outside that range is inviolate. +

    + Even strings can be fed through the algorithms here, although the + string class has specialized versions of many of these functions + (for example, string::find()). Most of the examples + on this page will use simple arrays of integers as a playground + for algorithms, just to keep things simple. The use of + N as a size in the examples is to keep things + easy to read but probably won't be valid code. You can use wrappers + such as those described in + the containers sect1 to keep + real code readable. +

    + The single thing that trips people up the most is the definition + of range used with iterators; the famous + "past-the-end" rule that everybody loves to hate. The + iterators sect1 of this + document has a complete explanation of this simple rule that seems + to cause so much confusion. Once you + get range into your head (it's not that hard, + honest!), then the algorithms are a cakewalk. +

    Mutating

    swap

    Specializations

    If you call std::swap(x,y); where x and y are standard + containers, then the call will automatically be replaced by a call to + x.swap(y); instead. +

    This allows member functions of each container class to take over, and + containers' swap functions should have O(1) complexity according to + the standard. (And while "should" allows implementations to + behave otherwise and remain compliant, this implementation does in + fact use constant-time swaps.) This should not be surprising, since + for two containers of the same type to swap contents, only some + internal pointers to storage need to be exchanged. +

    diff --git a/libstdc++-v3/doc/html/manual/api.html b/libstdc++-v3/doc/html/manual/api.html index 0b70a4cb1bc..a8b88b7d5a9 100644 --- a/libstdc++-v3/doc/html/manual/api.html +++ b/libstdc++-v3/doc/html/manual/api.html @@ -30,8 +30,8 @@ Removal of ext/tree, moved to backward/strstream.h.

    Allocator changes. Change __malloc_alloc to malloc_allocator and __new_alloc to new_allocator.

    For GCC releases from 2.95 through the 3.1 series, defining __USE_MALLOC on the gcc command line would change the default allocation strategy to instead use malloc and - free. (This same functionality is now spelled _GLIBCXX_FORCE_NEW, see - this page + free. (This same functionality is now spelled _GLIBCXX_FORCE_NEW, see + this page for details.

    Error handling in iostreams cleaned up, made consistent.

    3.3

    3.4

    @@ -75,11 +75,11 @@ _Alloc_traits have been removed. __alloc to select an underlying allocator that satisfied memory allocation requests. The selection of this underlying allocator was not user-configurable. -

    Table B.1. Extension Allocators

    Allocator (3.4)Header (3.4)Allocator (3.[0-3])Header (3.[0-3])
    __gnu_cxx::new_allocator<T>ext/new_allocator.hstd::__new_allocmemory
    __gnu_cxx::malloc_allocator<T>ext/malloc_allocator.hstd::__malloc_alloc_template<int>memory
    __gnu_cxx::debug_allocator<T>ext/debug_allocator.hstd::debug_alloc<T>memory
    __gnu_cxx::__pool_alloc<T>ext/pool_allocator.hstd::__default_alloc_template<bool,int>memory
    __gnu_cxx::__mt_alloc<T>ext/mt_allocator.h
    __gnu_cxx::bitmap_allocator<T>ext/bitmap_allocator.h

    Releases after gcc-3.4 have continued to add to the collection +

    Table B.1. Extension Allocators

    Allocator (3.4)Header (3.4)Allocator (3.[0-3])Header (3.[0-3])
    __gnu_cxx::new_allocator<T>ext/new_allocator.hstd::__new_allocmemory
    __gnu_cxx::malloc_allocator<T>ext/malloc_allocator.hstd::__malloc_alloc_template<int>memory
    __gnu_cxx::debug_allocator<T>ext/debug_allocator.hstd::debug_alloc<T>memory
    __gnu_cxx::__pool_alloc<T>ext/pool_allocator.hstd::__default_alloc_template<bool,int>memory
    __gnu_cxx::__mt_alloc<T>ext/mt_allocator.h
    __gnu_cxx::bitmap_allocator<T>ext/bitmap_allocator.h

    Releases after gcc-3.4 have continued to add to the collection of available allocators. All of these new allocators are standard-style. The following table includes details, along with the first released version of GCC that included the extension allocator. -

    Table B.2. Extension Allocators Continued

    AllocatorIncludeVersion
    __gnu_cxx::array_allocator<T>ext/array_allocator.h4.0.0
    __gnu_cxx::throw_allocator<T>ext/throw_allocator.h4.2.0

    +

    Table B.2. Extension Allocators Continued

    AllocatorIncludeVersion
    __gnu_cxx::array_allocator<T>ext/array_allocator.h4.0.0
    __gnu_cxx::throw_allocator<T>ext/throw_allocator.h4.2.0

    Debug mode first appears.

    Precompiled header support PCH support. @@ -143,13 +143,13 @@ Debug mode for unordered_map and tuple and - functional. + functional.

    Default what implementations give more elaborate exception strings for bad_cast, bad_typeid, bad_exception, and bad_alloc.

    -PCH binary files no longer installed. Instead, the source files are installed. +PCH binary files no longer installed. Instead, the source files are installed.

    Namespace pb_ds moved to __gnu_pb_ds.

    4.4

    @@ -227,7 +227,7 @@ C++0X features.

    Profile mode first appears.

    -Support for decimal floating-point arithmetic, including decimal32, decimal64, and decimal128. +Support for decimal floating-point arithmetic, including decimal32, decimal64, and decimal128.

    Python pretty-printers are added for use with appropriately-advanced versions of gdb.

    diff --git a/libstdc++-v3/doc/html/manual/appendix_contributing.html b/libstdc++-v3/doc/html/manual/appendix_contributing.html index 422b57a813e..467f7fd0988 100644 --- a/libstdc++-v3/doc/html/manual/appendix_contributing.html +++ b/libstdc++-v3/doc/html/manual/appendix_contributing.html @@ -1,17 +1,19 @@ -Appendix A.  Contributing

    The GNU C++ Library follows an open development model. Active contributors are assigned maintainer-ship responsibility, and given write access to the source repository. First time contributors should follow this procedure: -

    Contributor Checklist

    Reading

    • +

      Contributor Checklist

      Reading

      • Get and read the relevant sections of the C++ language specification. Copies of the full ISO 14882 standard are available on line via the ISO mirror site for committee @@ -21,29 +23,29 @@ the standard from their respective national standards organization. In the USA, this national standards organization is ANSI and their web-site is right - here. - (And if you've already registered with them, clicking this link will take you to directly to the place where you can + here. + (And if you've already registered with them, clicking this link will take you to directly to the place where you can buy the standard on-line.) -

      • +

      • The library working group bugs, and known defects, can be obtained here: http://www.open-std.org/jtc1/sc22/wg21 -

      • +

      • The newsgroup dedicated to standardization issues is comp.std.c++: this FAQ for this group is quite useful and can be found here . -

      • +

      • Peruse the GNU Coding Standards, and chuckle when you hit the part about Using Languages Other Than C. -

      • +

      • Be familiar with the extensions that preceded these general GNU rules. These style issues for libstdc++ can be found here. -

      • +

      • And last but certainly not least, read the library-specific information found here. @@ -51,8 +53,8 @@ Small changes can be accepted without a copyright assignment form on file. New code and additions to the library need completed copyright assignment form on file at the FSF. Note: your employer may be required - to fill out appropriate disclaimer forms as well. -

        + to fill out appropriate disclaimer forms as well. +

        Historically, the libstdc++ assignment form added the following question:

        @@ -64,7 +66,7 @@ While not strictly necessary, humoring the maintainers and answering this question would be appreciated.

        - For more information about getting a copyright assignment, please see + For more information about getting a copyright assignment, please see Legal Matters.

        @@ -81,22 +83,22 @@ Every patch must have several pieces of information before it can be properly evaluated. Ideally (and to ensure the fastest possible response from the maintainers) it would have all of these pieces: -

        • +

          • A description of the bug and how your patch fixes this bug. For new features a description of the feature and your - implementation. -

          • + implementation. +

          • A ChangeLog entry as plain text; see the various ChangeLog files for format and content. If you are using emacs as your editor, simply position the insertion point at the beginning of your change and hit CX-4a to bring up the appropriate ChangeLog entry. See--magic! Similar - functionality also exists for vi. -

          • + functionality also exists for vi. +

          • A testsuite submission or sample program that will easily and simply show the existing error or test new - functionality. -

          • + functionality. +

          • The patch itself. If you are accessing the SVN repository use svn update; svn diff NEW; else, use diff -cp OLD NEW ... If your @@ -105,9 +107,11 @@ diff. The SVN Tricks wiki page has information on customising the output of svn diff. -

          • +

          • When you have all these pieces, bundle them up in a mail message and send it to libstdc++@gcc.gnu.org. All patches and related discussion should be sent to the - libstdc++ mailing list. -

      + libstdc++ mailing list. +

    diff --git a/libstdc++-v3/doc/html/manual/appendix_free.html b/libstdc++-v3/doc/html/manual/appendix_free.html index dd77c972f07..bc6c37655ea 100644 --- a/libstdc++-v3/doc/html/manual/appendix_free.html +++ b/libstdc++-v3/doc/html/manual/appendix_free.html @@ -1,11 +1,13 @@ -Appendix C.  Free Software Needs Free Documentation

    Appendix C.  Free Software Needs Free Documentation - +

    The biggest deficiency in free operating systems is not in the software--it is the lack of good free manuals that we can include in @@ -35,7 +37,7 @@ restrict it so that we cannot use it.

    Given that writing good English is a rare skill among programmers, we can ill afford to lose manuals this way. -

    +

    Free documentation, like free software, is a matter of freedom, not price. The problem with these manuals was not that O'Reilly Associates charged a price for printed copies--that in itself is fine. @@ -119,6 +121,6 @@ prefer copylefted manuals to non-copylefted ones. that lists free books available from other publishers].

    Copyright © 2004, 2005, 2006, 2007 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA

    Verbatim copying and distribution of this entire article are permitted worldwide, without royalty, in any medium, provided this -notice is preserved.

    Report any problems or suggestions to .