summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Schwinge <thomas@codesourcery.com>2013-06-06 14:42:08 +0200
committerThomas Schwinge <thomas@codesourcery.com>2013-06-06 14:42:08 +0200
commit04b6e0b2481dea9739b3dd29a42c2e2bc5baa333 (patch)
treecafc8a33f5f2308f899755a45eae03a15f44f543
parenta488009075e657f7df544e4ced8cbd7af2b58403 (diff)
parent3a930d3fc68785662f5f3f4af02474cb21a62056 (diff)
downloadgcc-04b6e0b2481dea9739b3dd29a42c2e2bc5baa333.tar.gz
Merge commit 'refs/top-bases/baseline' into baseline
-rw-r--r--ChangeLog4
-rw-r--r--MAINTAINERS1
-rw-r--r--gcc/ChangeLog1077
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in8
-rw-r--r--gcc/ada/ChangeLog4
-rw-r--r--gcc/ada/gcc-interface/Makefile.in2
-rw-r--r--gcc/builtin-types.def2
-rw-r--r--gcc/builtins.c8
-rw-r--r--gcc/builtins.def7
-rw-r--r--gcc/c-family/ChangeLog21
-rw-r--r--gcc/c-family/array-notation-common.c76
-rw-r--r--gcc/c-family/c-common.c1
-rw-r--r--gcc/c-family/c-common.def7
-rw-r--r--gcc/c-family/c-common.h26
-rw-r--r--gcc/c-family/c-pretty-print.c12
-rw-r--r--gcc/c-family/c.opt4
-rw-r--r--gcc/c/ChangeLog75
-rw-r--r--gcc/c/Make-lang.in7
-rw-r--r--gcc/c/c-array-notation.c2891
-rw-r--r--gcc/c/c-parser.c312
-rw-r--r--gcc/c/c-tree.h3
-rw-r--r--gcc/c/c-typeck.c81
-rw-r--r--gcc/cgraph.c107
-rw-r--r--gcc/cgraph.h256
-rw-r--r--gcc/cgraphclones.c12
-rw-r--r--gcc/cgraphunit.c331
-rw-r--r--gcc/cilkplus.def59
-rw-r--r--gcc/common/config/rx/rx-common.c5
-rw-r--r--gcc/config.gcc46
-rw-r--r--gcc/config.in8
-rw-r--r--gcc/config/aarch64/aarch64-protos.h7
-rw-r--r--gcc/config/aarch64/aarch64-simd.md4
-rw-r--r--gcc/config/aarch64/aarch64.c369
-rw-r--r--gcc/config/aarch64/aarch64.md86
-rw-r--r--gcc/config/aarch64/constraints.md5
-rw-r--r--gcc/config/aarch64/predicates.md2
-rw-r--r--gcc/config/alpha/alpha.c12
-rw-r--r--gcc/config/arm/arm-protos.h3
-rw-r--r--gcc/config/arm/arm.c189
-rw-r--r--gcc/config/arm/arm.md96
-rw-r--r--gcc/config/arm/arm.opt4
-rw-r--r--gcc/config/arm/iterators.md8
-rw-r--r--gcc/config/arm/neon.md25
-rw-r--r--gcc/config/arm/predicates.md28
-rw-r--r--gcc/config/arm/t-arm4
-rw-r--r--gcc/config/i386/driver-i386.c10
-rw-r--r--gcc/config/i386/i386-c.c7
-rw-r--r--gcc/config/i386/i386.c510
-rw-r--r--gcc/config/i386/i386.h6
-rw-r--r--gcc/config/i386/i386.md27
-rw-r--r--gcc/config/i386/slm.md758
-rw-r--r--gcc/config/i386/t-cygming2
-rw-r--r--gcc/config/i386/t-interix2
-rw-r--r--gcc/config/i386/winnt.c42
-rw-r--r--gcc/config/ia64/ia64.c71
-rw-r--r--gcc/config/ia64/t-ia643
-rw-r--r--gcc/config/mips/mips-cpus.def3
-rw-r--r--gcc/config/mips/mips-tables.opt288
-rw-r--r--gcc/config/mips/mips.c68
-rw-r--r--gcc/config/mips/mips.h14
-rw-r--r--gcc/config/mips/mips.md5
-rw-r--r--gcc/config/mips/mips.opt4
-rw-r--r--gcc/config/mips/mti-linux.h2
-rw-r--r--gcc/config/mips/t-mti-elf33
-rw-r--r--gcc/config/mips/t-mti-linux19
-rw-r--r--gcc/config/rl78/rl78.md67
-rw-r--r--gcc/config/rs6000/altivec.h20
-rw-r--r--gcc/config/rs6000/altivec.md446
-rw-r--r--gcc/config/rs6000/predicates.md9
-rw-r--r--gcc/config/rs6000/rs6000-builtin.def56
-rw-r--r--gcc/config/rs6000/rs6000-c.c170
-rw-r--r--gcc/config/rs6000/rs6000-opts.h22
-rw-r--r--gcc/config/rs6000/rs6000.c72
-rw-r--r--gcc/config/rs6000/rs6000.md11
-rw-r--r--gcc/config/rs6000/vector.md14
-rw-r--r--gcc/config/rx/rx-opts.h3
-rw-r--r--gcc/config/rx/rx.c46
-rw-r--r--gcc/config/rx/rx.h20
-rw-r--r--gcc/config/rx/rx.md20
-rw-r--r--gcc/config/rx/rx.opt7
-rw-r--r--gcc/config/rx/t-rx2
-rw-r--r--gcc/config/sol2.c53
-rw-r--r--gcc/config/sparc/sparc.c8
-rw-r--r--gcc/config/sparc/sparc.md44
-rw-r--r--gcc/config/sparc/sparc.opt4
-rw-r--r--gcc/config/t-sol22
-rwxr-xr-xgcc/configure64
-rw-r--r--gcc/configure.ac1
-rw-r--r--gcc/cp/ChangeLog46
-rw-r--r--gcc/cp/class.c70
-rw-r--r--gcc/cp/cp-lang.c3
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl2.c48
-rw-r--r--gcc/cp/init.c64
-rw-r--r--gcc/cp/parser.c4
-rw-r--r--gcc/cp/semantics.c5
-rw-r--r--gcc/cp/tree.c2
-rw-r--r--gcc/dbxout.c2
-rw-r--r--gcc/doc/extend.texi164
-rw-r--r--gcc/doc/invoke.texi36
-rw-r--r--gcc/doc/md.texi10
-rw-r--r--gcc/doc/passes.texi31
-rw-r--r--gcc/doc/tm.texi4
-rw-r--r--gcc/doc/tm.texi.in2
-rw-r--r--gcc/dumpfile.c2
-rw-r--r--gcc/dwarf2out.c4
-rw-r--r--gcc/expmed.c12
-rw-r--r--gcc/fold-const.c4
-rw-r--r--gcc/fortran/ChangeLog124
-rw-r--r--gcc/fortran/class.c18
-rw-r--r--gcc/fortran/decl.c28
-rw-r--r--gcc/fortran/error.c44
-rw-r--r--gcc/fortran/expr.c1
-rw-r--r--gcc/fortran/gfortran.h1
-rw-r--r--gcc/fortran/interface.c116
-rw-r--r--gcc/fortran/intrinsic.c3
-rw-r--r--gcc/fortran/misc.c9
-rw-r--r--gcc/fortran/module.c19
-rw-r--r--gcc/fortran/parse.c20
-rw-r--r--gcc/fortran/resolve.c14
-rw-r--r--gcc/fortran/trans-array.c64
-rw-r--r--gcc/fortran/trans-array.h4
-rw-r--r--gcc/fortran/trans-decl.c3
-rw-r--r--gcc/fortran/trans-expr.c100
-rw-r--r--gcc/fortran/trans-openmp.c5
-rw-r--r--gcc/fortran/trans-stmt.c45
-rw-r--r--gcc/fortran/trans.c349
-rw-r--r--gcc/fortran/trans.h4
-rw-r--r--gcc/gdbinit.in1
-rw-r--r--gcc/gensupport.c15
-rw-r--r--gcc/gimple-fold.c4
-rw-r--r--gcc/gimple-ssa-strength-reduction.c8
-rw-r--r--gcc/ipa-cp.c17
-rw-r--r--gcc/ipa-inline-analysis.c12
-rw-r--r--gcc/ipa-inline-transform.c6
-rw-r--r--gcc/ipa-inline.c10
-rw-r--r--gcc/ipa-prop.c11
-rw-r--r--gcc/ipa-pure-const.c12
-rw-r--r--gcc/ipa-reference.c10
-rw-r--r--gcc/ipa-split.c40
-rw-r--r--gcc/ipa-utils.c2
-rw-r--r--gcc/ipa.c257
-rw-r--r--gcc/java/ChangeLog9
-rw-r--r--gcc/java/class.c2
-rw-r--r--gcc/java/decl.c2
-rw-r--r--gcc/lra-assigns.c6
-rw-r--r--gcc/lto-cgraph.c93
-rw-r--r--gcc/lto-streamer-out.c6
-rw-r--r--gcc/lto-streamer.h2
-rw-r--r--gcc/lto-symtab.c105
-rw-r--r--gcc/lto/ChangeLog18
-rw-r--r--gcc/lto/lto-partition.c18
-rw-r--r--gcc/lto/lto.c25
-rw-r--r--gcc/omp-low.c2
-rw-r--r--gcc/passes.c17
-rw-r--r--gcc/postreload.c215
-rw-r--r--gcc/rtl.def5
-rw-r--r--gcc/rtlanal.c1
-rw-r--r--gcc/sched-deps.c11
-rw-r--r--gcc/simplify-rtx.c5
-rw-r--r--gcc/symtab.c212
-rw-r--r--gcc/target.def15
-rw-r--r--gcc/targhooks.c6
-rw-r--r--gcc/targhooks.h1
-rw-r--r--gcc/testsuite/ChangeLog435
-rw-r--r--gcc/testsuite/ada/acats/floatstore.lst1
-rwxr-xr-xgcc/testsuite/ada/acats/run_all.sh4
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/an-if.c48
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/array_test1.c84
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/array_test2.c128
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/array_test_ND.c102
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_fn_custom.c68
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_fn_mutating.c68
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_func_double.c124
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_func_double2.c76
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/comma_exp.c55
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/conditional.c44
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c18
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c10
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/exec-once.c44
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/exec-once2.c87
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c20
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/fp_triplet_values.c28
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/gather-scatter-errors.c19
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/gather_scatter.c59
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/if_test.c306
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/if_test_errors.c56
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c112
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/n-ptr-test.c48
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors.c11
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors2.c11
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors3.c11
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors4.c11
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/pr57457-2.c15
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/pr57457.c39
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c17
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch2.c27
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch3.c19
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/sec_implicit.c11
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/sec_implicit2.c11
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/sec_implicit_ex.c33
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/sec_reduce_max_min_ind.c17
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/sec_reduce_return.c29
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/side-effects-1.c26
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/test_builtin_return.c73
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/test_sec_limits.c18
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/tst_lngth.c19
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/vla.c20
-rw-r--r--gcc/testsuite/g++.dg/abi/abi-tag5.C6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-debug-0.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/decltype54.C26
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted13.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted2.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted26.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted3.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/error1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/implicit1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/implicit11.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor13.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist47.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist9.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc2.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-local.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-union1.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-union2.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/sfinae46.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/union4.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/vla6.C14
-rw-r--r--gcc/testsuite/g++.dg/opt/pr57411.C23
-rw-r--r--gcc/testsuite/g++.dg/template/crash108.C2
-rw-r--r--gcc/testsuite/g++.dg/template/crash41.C2
-rw-r--r--gcc/testsuite/g++.dg/torture/pr54684.C1
-rw-r--r--gcc/testsuite/g++.dg/vect/slp-pr50413.cc2
-rw-r--r--gcc/testsuite/g++.dg/vect/slp-pr50819.cc2
-rw-r--r--gcc/testsuite/g++.dg/vect/slp-pr56812.cc2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/local.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility3.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb76.C1
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr57441.c26
-rw-r--r--gcc/testsuite/gcc.dg/builtin-bswap-8.c4
-rw-r--r--gcc/testsuite/gcc.dg/builtin-bswap-9.c2
-rw-r--r--gcc/testsuite/gcc.dg/cilk-plus/cilk-plus.exp45
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/discriminator.c12
-rw-r--r--gcc/testsuite/gcc.dg/fshort-wchar.c2
-rw-r--r--gcc/testsuite/gcc.dg/gomp/pr57412.c10
-rw-r--r--gcc/testsuite/gcc.dg/shrink-wrap-alloca.c11
-rw-r--r--gcc/testsuite/gcc.dg/shrink-wrap-pretend.c36
-rw-r--r--gcc/testsuite/gcc.dg/shrink-wrap-sibcall.c26
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57343.c22
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57417.c12
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57478.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/attr-alias.c28
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr42585.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr43491.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/reassoc-30.c13
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-10.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-11.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-13.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-14.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-15.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-16.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-17.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-18.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-19.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-20.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-21.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-22.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-23.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-24.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-25.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-26.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-27.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-28.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-29.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-30.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-31.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-32.c23
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-7.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-8.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-8a.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-8b.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-9.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr56787.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/insv_1.c84
-rw-r--r--gcc/testsuite/gcc.target/aarch64/movi_1.c13
-rw-r--r--gcc/testsuite/gcc.target/arm/iordi3-opt.c9
-rw-r--r--gcc/testsuite/gcc.target/arm/pr56184.C2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/e500-ord-1.c29
-rw-r--r--gcc/testsuite/gcc.target/powerpc/e500-ord-2.c29
-rw-r--r--gcc/testsuite/gcc.target/powerpc/e500-unord-1.c29
-rw-r--r--gcc/testsuite/gcc.target/powerpc/e500-unord-2.c29
-rw-r--r--gcc/testsuite/gcc.target/sparc/bmaskbshuf.c3
-rw-r--r--gcc/testsuite/gfortran.dg/alloc_comp_basics_1.f906
-rw-r--r--gcc/testsuite/gfortran.dg/alloc_comp_constructor_1.f907
-rw-r--r--gcc/testsuite/gfortran.dg/allocatable_scalar_9.f903
-rw-r--r--gcc/testsuite/gfortran.dg/assumed_rank_13.f9026
-rw-r--r--gcc/testsuite/gfortran.dg/assumed_size_1.f9017
-rw-r--r--gcc/testsuite/gfortran.dg/assumed_type_7.f9023
-rw-r--r--gcc/testsuite/gfortran.dg/auto_dealloc_2.f905
-rw-r--r--gcc/testsuite/gfortran.dg/bounds_check_7.f902
-rw-r--r--gcc/testsuite/gfortran.dg/class_19.f032
-rw-r--r--gcc/testsuite/gfortran.dg/class_array_16.f9071
-rw-r--r--gcc/testsuite/gfortran.dg/class_array_17.f9034
-rw-r--r--gcc/testsuite/gfortran.dg/coarray_lib_alloc_1.f901
-rw-r--r--gcc/testsuite/gfortran.dg/coarray_lib_alloc_2.f901
-rw-r--r--gcc/testsuite/gfortran.dg/coarray_poly_3.f904
-rw-r--r--gcc/testsuite/gfortran.dg/default_initialization_5.f902
-rw-r--r--gcc/testsuite/gfortran.dg/dummy_procedure_5.f902
-rw-r--r--gcc/testsuite/gfortran.dg/extends_14.f033
-rw-r--r--gcc/testsuite/gfortran.dg/finalize_11.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/finalize_12.f90175
-rw-r--r--gcc/testsuite/gfortran.dg/finalize_13.f90161
-rw-r--r--gcc/testsuite/gfortran.dg/finalize_14.f90220
-rw-r--r--gcc/testsuite/gfortran.dg/finalize_4.f033
-rw-r--r--gcc/testsuite/gfortran.dg/finalize_5.f033
-rw-r--r--gcc/testsuite/gfortran.dg/finalize_6.f909
-rw-r--r--gcc/testsuite/gfortran.dg/finalize_7.f033
-rw-r--r--gcc/testsuite/gfortran.dg/g77/f77-edit-s-out.f2
-rw-r--r--gcc/testsuite/gfortran.dg/g77/f77-edit-t-out.f4
-rw-r--r--gcc/testsuite/gfortran.dg/g77/f77-edit-x-out.f2
-rw-r--r--gcc/testsuite/gfortran.dg/init_flag_11.f902
-rw-r--r--gcc/testsuite/gfortran.dg/interface_26.f904
-rw-r--r--gcc/testsuite/gfortran.dg/io_real_boz_3.f902
-rw-r--r--gcc/testsuite/gfortran.dg/io_real_boz_4.f902
-rw-r--r--gcc/testsuite/gfortran.dg/io_real_boz_5.f902
-rw-r--r--gcc/testsuite/gfortran.dg/move_alloc_4.f903
-rw-r--r--gcc/testsuite/gfortran.dg/namelist_print_1.f2
-rw-r--r--gcc/testsuite/gfortran.dg/power_6.f9015
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_11.f906
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_15.f909
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_comp_20.f908
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_comp_33.f904
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_result_5.f902
-rw-r--r--gcc/testsuite/gfortran.dg/read_x_eor.f902
-rw-r--r--gcc/testsuite/gfortran.dg/repeat_1.f902
-rw-r--r--gcc/testsuite/gfortran.dg/spread_bounds_1.f902
-rw-r--r--gcc/testsuite/gfortran.dg/stfunc_8.f909
-rw-r--r--gcc/testsuite/gfortran.dg/string_length_2.f902
-rw-r--r--gcc/testsuite/gfortran.dg/transpose_2.f903
-rw-r--r--gcc/testsuite/gfortran.dg/typebound_override_1.f902
-rw-r--r--gcc/testsuite/gfortran.dg/typebound_override_4.f9034
-rw-r--r--gcc/testsuite/gfortran.dg/typebound_override_5.f9040
-rw-r--r--gcc/testsuite/gfortran.dg/typebound_override_6.f9039
-rw-r--r--gcc/testsuite/gfortran.dg/typebound_override_7.f9039
-rw-r--r--gcc/testsuite/gfortran.dg/typebound_proc_27.f032
-rw-r--r--gcc/testsuite/gfortran.dg/typebound_proc_6.f034
-rw-r--r--gcc/testsuite/gfortran.dg/use_29.f9015
-rw-r--r--gcc/testsuite/gnat.dg/fp_exception.adb24
-rw-r--r--gcc/toplev.c6
-rw-r--r--gcc/trans-mem.c29
-rw-r--r--gcc/tree-cfg.c68
-rw-r--r--gcc/tree-eh.c4
-rw-r--r--gcc/tree-emutls.c16
-rw-r--r--gcc/tree-inline.c14
-rw-r--r--gcc/tree-ssa-copy.c10
-rw-r--r--gcc/tree-ssa-dom.c17
-rw-r--r--gcc/tree-ssa-loop-niter.c20
-rw-r--r--gcc/tree-ssa-math-opts.c39
-rw-r--r--gcc/tree-ssa-reassoc.c31
-rw-r--r--gcc/tree-ssa-sccvn.c15
-rw-r--r--gcc/tree-ssa-structalias.c11
-rw-r--r--gcc/tree-streamer-out.c5
-rw-r--r--gcc/tree-streamer.c1
-rw-r--r--gcc/tree-vect-data-refs.c14
-rw-r--r--gcc/tree-vect-loop.c22
-rw-r--r--gcc/tree-vect-slp.c98
-rw-r--r--gcc/tree-vectorizer.c8
-rw-r--r--gcc/tsan.c2
-rw-r--r--gcc/varasm.c38
-rw-r--r--gcc/varpool.c126
-rw-r--r--libgcc/ChangeLog19
-rw-r--r--libgcc/config.host20
-rw-r--r--libgcc/config/i386/cpuinfo.c3
-rw-r--r--libgcc/config/i386/sol2-unwind.h7
-rw-r--r--libgcc/config/rs6000/ibm-ldouble.c6
-rw-r--r--libgcc/config/sparc/sol2-unwind.h7
-rw-r--r--libgfortran/ChangeLog40
-rw-r--r--libgfortran/io/write_float.def36
-rw-r--r--libgomp/ChangeLog7
-rw-r--r--libgomp/config/posix/ptrlock.h5
-rw-r--r--libgomp/configure.tgt5
-rw-r--r--libiberty/ChangeLog12
-rw-r--r--libiberty/Makefile.in24
-rwxr-xr-xlibiberty/configure56
-rw-r--r--libiberty/configure.ac46
-rw-r--r--libitm/ChangeLog12
-rw-r--r--libitm/local_atomic27
-rw-r--r--libsanitizer/ChangeLog5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_linux.cc4
-rw-r--r--libstdc++-v3/ChangeLog43
-rw-r--r--libstdc++-v3/config/abi/post/solaris2.10/sparcv9/baseline_symbols.txt1
-rw-r--r--libstdc++-v3/include/Makefile.am1
-rw-r--r--libstdc++-v3/include/Makefile.in1
-rw-r--r--libstdc++-v3/include/bits/basic_string.h37
-rw-r--r--libstdc++-v3/include/bits/move.h2
-rw-r--r--libstdc++-v3/include/bits/parse_numbers.h417
-rw-r--r--libstdc++-v3/include/std/chrono133
-rw-r--r--libstdc++-v3/include/std/tuple8
-rw-r--r--libstdc++-v3/src/c++11/compatibility-chrono.cc5
-rw-r--r--libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/literals/types.cc74
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/literals/values.cc69
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg1.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg2.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg3.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/literals/types.cc47
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/literals/values.cc50
-rw-r--r--libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc2
422 files changed, 15476 insertions, 2736 deletions
diff --git a/ChangeLog b/ChangeLog
index 5c36f005a82..22f80f0c6f1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-06-01 Dinar Temirbulatov <dinar@kugelworks.com>
+
+ * MAINTAINERS (Write After Approval): Add myself.
+
2013-05-17 David Malcolm <dmalcolm@redhat.com>
* MAINTAINERS (Write After Approval): Add myself.
diff --git a/MAINTAINERS b/MAINTAINERS
index 50672c9c0d4..1dae891b9c2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -530,6 +530,7 @@ Gabriele Svelto gabriele.svelto@st.com
Sriraman Tallam tmsriram@google.com
Chung-Lin Tang cltang@codesourcery.com
Samuel Tardieu sam@rfc1149.net
+Dinar Temirbulatov dinar@kugelworks.com
Kresten Krab Thorup krab@gcc.gnu.org
Caroline Tice ctice@apple.com
Kyrylo Tkachov kyrylo.tkachov@arm.com
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b31591245f9..7932819966f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,1057 @@
+2013-06-05 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.md (enabled_for_depr_it): New attribute.
+ (predicable_short_it): Likewise.
+ (predicated): Likewise.
+ (enabled): Handle above.
+ (define_cond_exec): Set predicated attribute to yes.
+
+2013-06-05 Mike Stump <mikestump@comcast.net>
+
+ * gdbinit.in (__FUNCTION__): Add.
+
+2013-06-05 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.c (alpha_emit_conditional_move): Swap all
+ GE, GT, GEU and GTU compares, modulo DImode compares with zero.
+
+2013-06-05 Jan Hubicka <jh@suse.cz>
+
+ * varasm.c (mark_decl_referenced): Revert the removal until targets
+ are fixed.
+
+2013-06-05 David Edelsohn <dje.gcc@gmail.com>
+
+ * config/rs6000/rs6000.c (print_operand, 'z'): Use DECL_PRESERVE_P
+ instead of mark_decl_referenced.
+
+2013-06-05 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_remove_node): Clear forced_by_abi.
+ (cgraph_node_cannot_be_local_p_1): Honnor symbol.forced_by_abi
+ and symtab_used_from_object_file_p.
+ (cgraph_make_node_local_1): Clear forced_by_abi.
+ (cgraph_can_remove_if_no_direct_calls_and): Use forced_by_abi
+ * cgraph.h (symtab_node_base): Add forced_by_abi.
+ (decide_is_variable_needed): Remove.
+ (varpool_can_remove_if_no_refs): Honnor symbol.forced_by_abi.
+ * cgraphunit.c (cgraph_decide_is_function_needed): Rename to ..
+ (decide_is_symbol_needed): ... this one; handle symbols in general;
+ always analyze virtuals; honnor forced_by_abi.
+ (cgraph_finalize_function): Update.
+ (varpool_finalize_decl): Update.
+ (symbol_defined_and_needed): Remove.
+ (analyze_functions): Update.
+ * lto-cgraph.c (lto_output_node, lto_output_varpool_node,
+ output_refs, input_overwrite_node): Handle forced_by_abi.
+ * ipa.c (cgraph_address_taken_from_non_vtable_p): Rename to ...
+ (address_taken_from_non_vtable_p): ... this one.
+ (comdat_can_be_unshared_p_1): New function.
+ (cgraph_comdat_can_be_unshared_p): Rename to ...
+ (comdat_can_be_unshared_p): ... this one; handle symbols in general.
+ (varpool_externally_visible_p): Use comdat_can_be_unshared_p.
+ (function_and_variable_visibility): Clear forced_by_abi as needed.
+ * trans-mem.c (ipa_tm_mark_forced_by_abi_node): New functoin.
+ (ipa_tm_create_version_alias, ipa_tm_create_version): Update.
+ * symtab.c (dump_symtab_base): Dump forced_by_abi.
+ * varpool.c (decide_is_variable_needed): Remove.
+
+2013-06-05 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.c (MAX_INSN_PER_IT_BLOCK): New macro.
+ (arm_option_override): Override arm_restrict_it where appropriate.
+ (thumb2_final_prescan_insn): Use MAX_INSN_PER_IT_BLOCK.
+ * config/arm/arm.opt (mrestrict-it): New command-line option.
+ * doc/invoke.texi: Document -mrestrict-it.
+
+2013-06-05 David Malcolm <dmalcolm@redhat.com>
+
+ * tsan.c (tsan_atomic_table): Make const.
+
+2013-06-05 Richard Biener <rguenther@suse.de>
+
+ * tree-streamer.c (streamer_tree_cache_insert_1): Update the
+ index associated with the tree we are supposed to replace.
+ * tree-streamer-out.c (pack_ts_base_value_fields): Output
+ TREE_ASM_WRITTEN as zero for everything but SSA names.
+
+2013-06-05 David Malcolm <dmalcolm@redhat.com>
+
+ * tree-ssa-structalias.c (call_stmt_vars): Make static.
+
+2013-06-04 Jan Hubicka <jh@suse.cz>
+
+ * lto-cgraph.c (get_alias_symbol): Remove weakref sanity check.
+ (input_node, input_varpool_node): Handle correctly external same
+ body aliases.
+ * ipa.c (symtab_remove_unreachable_nodes): Do not remove external
+ nodes at ltrans stage.
+
+2013-06-04 Jan Hubicka <jh@suse.cz>
+
+ * ipa-inline.c (update_caller_keys): Fix availability test.
+ (update_callee_keys): Likewise.
+ * symtab.c (symtab_alias_ultimate_target): Make availaiblity logic
+ to follow ELF standard.
+
+2013-06-04 Jürgen Urban <JuergenUrban@gmx.de>
+
+ * config.gcc (mipsr5900-*-elf*, mipsr5900el-*-elf*, mips64r5900-*-elf*)
+ (mips64r5900el-*-elf*): New configurations.
+ * config/mips/mips-cpus.def (r5900): New processor.
+ * config/mips/mips-tables.opt: Regenerate.
+ * config/mips/mips.c (mips_rtx_cost_data): Add an R5900 entry.
+ (mips_issue_rate): Handle PROCESSOR_R5900.
+ (mips_reorg_process_insns): Force reorder mode for the R5900.
+ * config/mips/mips.h (TARGET_MIPS5900): Define.
+ (ISA_HAS_CONDMOVE, ISA_HAS_PREFETCH, ISA_HAS_HILO_INTERLOCKS): Include
+ TARGET_MIPS5900.
+ (ISA_HAS_LOAD_DELAY, ISA_HAS_XFER_DELAY, ISA_HAS_FCMP_DELAY): Exclude
+ TARGET_MIPS5900.
+ * config/mips/mips.md (processor): Add r5900.
+ (MOVECC): Disallow CCmode conditions for TARGET_MIPS5900.
+
+2013-06-04 Ian Bolton <ian.bolton@arm.com>
+
+ * config/aarch64/aarch64.md (*mov<mode>_aarch64): Call
+ into function to generate MOVI instruction.
+ * config/aarch64/aarch64.c (aarch64_simd_container_mode): New function.
+ (aarch64_preferred_simd_mode): Turn into wrapper.
+ (aarch64_output_scalar_simd_mov_immediate): New function.
+ * config/aarch64/aarch64-protos.h: Add prototype for above.
+
+2013-06-04 Ian Bolton <ian.bolton@arm.com>
+
+ * config/aarch64/aarch64.c (simd_immediate_info): Remove
+ element_char member.
+ (sizetochar): Return signed char.
+ (aarch64_simd_valid_immediate): Remove elchar and other
+ unnecessary variables.
+ (aarch64_output_simd_mov_immediate): Take rtx instead of &rtx.
+ Calculate element_char as required.
+ * config/aarch64/aarch64-protos.h: Update and move prototype
+ for aarch64_output_simd_mov_immediate.
+ * config/aarch64/aarch64-simd.md (*aarch64_simd_mov<mode>):
+ Update arguments.
+
+2013-06-04 Ian Bolton <ian.bolton@arm.com>
+
+ * config/aarch64/aarch64.c (simd_immediate_info): Struct to hold
+ information completed by aarch64_simd_valid_immediate.
+ (aarch64_legitimate_constant_p): Update arguments.
+ (aarch64_simd_valid_immediate): Work with struct rather than many
+ pointers.
+ (aarch64_simd_scalar_immediate_valid_for_move): Update arguments.
+ (aarch64_simd_make_constant): Update arguments.
+ (aarch64_output_simd_mov_immediate): Work with struct rather than
+ many pointers. Output immediate directly rather than as operand.
+ * config/aarch64/aarch64-protos.h (aarch64_simd_valid_immediate):
+ Update prototype.
+ * config/aarch64/constraints.md (Dn): Update arguments.
+
+2013-06-04 Ian Bolton <ian.bolton@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_simd_valid_immediate): No
+ longer static.
+ (aarch64_simd_immediate_valid_for_move): Remove.
+ (aarch64_simd_scalar_immediate_valid_for_move): Update call.
+ (aarch64_simd_make_constant): Update call.
+ (aarch64_output_simd_mov_immediate): Update call.
+ * config/aarch64/aarch64-protos.h (aarch64_simd_valid_immediate):
+ Add prototype.
+ * config/aarch64/constraints.md (Dn): Update call.
+
+2013-06-04 Ian Bolton <ian.bolton@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_simd_valid_immediate): Change
+ return type to bool for prototype.
+ (aarch64_legitimate_constant_p): Check for true instead of not -1.
+ (aarch64_simd_valid_immediate): Fix up each return to return a bool.
+ (aarch64_simd_immediate_valid_for_move): Update retval for bool.
+
+2013-06-04 Catherine Moore <clm@codesourcery.com>
+
+ * config/mips/mips.opt (meva): New.
+ * config/mips/mips.h (TARGET_CPU_CPP_BUILTINS): Define __mips_eva.
+ (ASM_SPEC): Handle -meva.
+ * doc/invoke.texi (meva): Document.
+
+2013-06-04 Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/rs6000.c (output_toc): Correct little-endian float
+ constant output.
+
+2013-06-04 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * rtl.def: Add extra fourth optional field to define_cond_exec.
+ * gensupport.c (process_one_cond_exec): Process attributes from
+ define_cond_exec.
+ * doc/md.texi: Document fourth field in define_cond_exec.
+
+2013-06-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * expmed.c (extract_bit_field_1): In the larger-than-a-word case, factor
+ out the processing order as in store_bit_field_1.
+
+2013-06-04 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/57500
+ * cgraphunit.c (cgraph_process_same_body_aliases): Create
+ non-VAR_DECL node if it does not exist yet.
+
+2013-06-03 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config.gcc (mipsisa64sr71k-*-elf*, mipsisa64sb1-*-elf*)
+ (mipsisa64sb1el-*-elf*, mips64-*-elf*, mips64el-*-elf*)
+ (mips64orion-*-elf*, mips64orionel-*-elf*): Remove
+ target_cpu_default setting.
+
+2013-06-03 Teresa Johnson <tejohnson@google.com>
+
+ * dumpfile.c (opt_info_switch_p): Change -fopt-info
+ default to -fopt-info=optimized instead of all.
+ * doc/invoke.texi: Ditto.
+ * tree-vectorizer.c (vectorize_loops): Emit loop vectorization
+ success under MSG_OPTIMIZED_LOCATIONS, and use dump_printf_loc.
+ (execute_vect_slp): Emit BB vectorization success under
+ MSG_OPTIMIZED_LOCATIONS.
+ * tree-vect-slp.c (vect_slp_transform_bb): Change
+ MSG_OPTIMIZED_LOCATIONS to MSG_NOTE.
+ * tree-vect-loop.c (vect_transform_loop): Ditto.
+
+2013-06-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/57415
+ * config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin):
+ Use TARGET_EXPR for C++.
+
+2013-06-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/57268
+ * sched-deps.c (sched_analyze_2): Don't flush_pending_lists
+ if DEBUG_INSN_P (insn).
+
+ Reapply
+ 2013-05-31 Dinar Temirbulatov <dinar@kugelworks.com>
+
+ PR rtl-optimization/57268
+ * sched-deps.c (sched_analyze_2): Flush dependence lists if
+ the sum of the read and write lists exceeds MAX_PENDING_LIST_LENGTH.
+
+2013-06-03 Yuri Rumyantsev <yuri.s.rumyantsev@intel.com>
+
+ * config/i386/i386.c (ix86_lea_outperforms): Fix formatting.
+ (ix86_avoid_lea_for_addr): Likewise.
+ (exact_dependency_1): Likewise.
+ (ix86_adjust_cost): Likewise.
+ (swap_top_of_ready_list): Fix formatting and !reload_completed check
+ removed.
+ (do_reorder_for_imul): Fix typo, formatting and
+ !reload_completed check removed.
+ (ix86_sched_reorder): Fix typo and formatting.
+ (fold_builtin_cpu): Move M_INTEL_SLM at the end of processor types
+ list.
+
+2013-06-03 Sofiane Naci <sofiane.naci@arm.com>
+
+ * config/aarch64/aarch64.md (*movdi_aarch64): Define "simd" attribute.
+
+2013-06-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * varasm.c (output_constant) <CONSTRUCTOR>: Minor formatting tweak.
+ <STRING_CST>: Likewise.
+ <VECTOR_CST>: Likewise.
+
+2013-06-01 Janus Weil <janus@gcc.gnu.org>
+ Mikael Morin <mikael@gcc.gnu.org>
+
+ * configure.ac: Add AC_HEADER_TIOCGWINSZ macro.
+ * config.in: Regenerated.
+ * configure: Regenerated.
+
+2013-06-01 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/57366
+ * cgraphunit.c (compile): When weakref is not supported,
+ set up transparent aliases before final output pass.
+ * varasm.c (assemble_alias): Do not try to do it here.
+
+2013-06-01 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/57467
+ * passes.c (for_per_function): Skip unanalyzed functions.
+
+2013-06-01 Jan Hubicka <jh@suse.cz>
+
+ * lto-symtab.c (lto_symtab_merge_cgraph_nodes_1): Rename to ...
+ (lto_symtab_merge_symbols_1): ... this one.
+ (lto_symtab_merge_cgraph_nodes): Rename to ...
+ (lto_symtab_merge_symbols): ... this one; simplify.
+ * cgraph.c (same_body_aliases_done): Rename to ...
+ (cpp_implicit_aliases_done): ... this one.
+ (cgraph_create_function_alias): Update.
+ (cgraph_same_body_alias): Update.
+ (dump_cgraph_node): Remove alias dumping; simplify thunk dumping.
+ (verify_edge_corresponds_to_fndecl): Simplify.
+ * cgraph.h (symtab_node_base): Add cpp_implicit_alias, alias_target.
+ (cgraph_node): Remove same_body_alias.
+ (varpool_node): Remove alias_of and extra_name_alias.
+ (same_body_aliases_done): Rename to ..
+ (cpp_implicit_aliases_done): ... this one.
+ (symtab_alias_ultimate_target): Add default parameter.
+ (symtab_resolve_alias): New function.
+ (fixup_same_cpp_alias_visibility): Declare.
+ (cgraph_function_node): Add default parameter.
+ (cgraph_node_asm_name): Likewise.
+ (cgraph_function_or_thunk_node): Add default parameter; do
+ not ICE when it is NULL.
+ (varpool_variable_node): Likewise.
+ * tree-emutls.c (create_emultls_var): Update.
+ (ipa_lower_emutls): Update.
+ * cgraphunit.c (cgraph_decide_is_function_needed): Update.
+ (cgraph_reset_node): Reset alias info.
+ (cgraph_finalize_function): Update.
+ (fixup_same_cpp_alias_visibility): Move to symtab.c.
+ (analyze_function): Simplify.
+ (cgraph_process_same_body_aliases): Simplify.
+ (analyze_functions): Fixup same body aliases.
+ (handle_alias_pairs): Simplify.
+ (assemble_thunk): Update.
+ (assemble_thunks_and_aliases): Update.
+ (output_weakrefs): Rewrite.
+ * lto-cgraph.c (lto_output_node): Rewrite alias handling.
+ (lto_output_varpool_node): Likewise.
+ (compute_ltrans_boundary): Remve assert.
+ (get_alias_symbol): New functoin.
+ (input_node): Rewrite alias handling.
+ (input_varpool_node): Likewise.
+ * ipa-pure-const.c (propagate_pure_const): Fix formating.
+ * ipa.c (process_references): Handle weakrefs correctly.
+ (symtab_remove_unreachable_nodes): Likewise.
+ * trans-mem.c (get_cg_data): Update.
+ (ipa_tm_create_version_alias): Update.
+ (ipa_tm_execute): Update.
+ * symtab.c (dump_symtab_base): Dump aliases.
+ (verify_symtab_base): Verify aliases.
+ (symtab_node_availability): New function.
+ (symtab_alias_ultimate_target): Simplify.
+ (fixup_same_cpp_alias_visibility): Move here from cgraphunit.c;
+ handle all the fixup cases.
+ (symtab_resolve_alias): New function.
+ * passes.c (ipa_write_summaries): Handle weakrefs.
+ * varpool.c (varpool_analyze_node): Simplify.
+ (assemble_aliases): Update.
+ (varpool_create_variable_alias): Simplify.
+ (varpool_extra_name_alias): Simplify.
+ * lto-streamer.h (lto_symtab_merge_cgraph_nodes): Rename to...
+ (lto_symtab_merge_symbols): ... this one.
+
+2013-06-01 Dinar Temirbulatov <dinar@kugelworks.com>
+
+ Revert
+ PR rtl-optimization/57268
+ * sched-deps.c (sched_analyze_2): Flush dependence lists if
+ the sum of the read and write lists exceeds MAX_PENDING_LIST_LENGTH.
+
+2013-06-01 Tobias Burnus <burnus@net-b.de>
+
+ Partially reverted:
+ 2013-05-31 Tobias Burnus <burnus@net-b.de>
+
+ PR middle-end/57073
+ * tree-ssa-math-opts.c (execute_cse_sincos): Move check
+ further up.
+
+2013-05-31 Dinar Temirbulatov <dinar@kugelworks.com>
+
+ PR rtl-optimization/57268
+ * sched-deps.c (sched_analyze_2): Flush dependence lists if
+ the sum of the read and write lists exceeds MAX_PENDING_LIST_LENGTH.
+
+2013-05-31 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config/rs6000/predicates.md (rs6000_cbranch_operator): Accept some
+ unordered comparison operators when -fno-trapping-math is in effect
+ on the e500.
+ * config/rs6000/rs6000.c (rs6000_generate_compare): Remove dead code
+ and implement unordered comparison operators properly on the e500.
+
+2013-05-31 Eric Botcazou <ebotcazou@adacore.com>
+
+ * simplify-rtx.c (simplify_byte_swapping_operation): Use proper macro
+ for constant scalar integers.
+ (simplify_relational_operation_1): Likewise.
+
+2013-05-31 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/rs6000-opts.h (enum processor_type): Reorder.
+ * config/rs6000/rs6000.md (cpu): Reorder. Split long line.
+ Fix comment.
+
+2013-05-31 Yuri Rumyantsev <yuri.s.rumyantsev@intel.com>
+ Igor Zamyatin <igor.zamyatin@intel.com>
+
+ Silvermont (SLM) architecture performance tuning.
+ * config/i386/i386.h (enum ix86_tune_indices): Add
+ X86_TUNE_SPLIT_MEM_OPND_FOR_FP_CONVERTS.
+ (TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS): New define.
+
+ * config/i386/i386.c (initial_ix86_tune_features)
+ <X86_TUNE_SPLIT_MEM_OPND_FOR_FP_CONVERTS>: Initialize.
+ (ix86_lea_outperforms): Handle Silvermont tuning.
+ (ix86_avoid_lea_for_add): Add new argument to ix86_lea_outperforms
+ call.
+ (ix86_use_lea_for_mov): Likewise.
+ (ix86_avoid_lea_for_addr): Likewise.
+ (ix86_lea_for_add_ok): Likewise.
+ (exact_dependency_1): New function.
+ (exact_store_load_dependency): Likewise.
+ (ix86_adjust_cost): Handle Silvermont tuning.
+ (do_reoder_for_imul): Likewise.
+ (swap_top_of_ready_list): New function.
+ (ix86_sched_reorder): Changed to handle Silvermont tuning.
+
+ * config/i386/i386.md (peepholes that split memory operand in fp
+ converts): New.
+
+2013-05-31 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_load_symref_appropriately):
+ Remove un-necessary braces.
+
+2013-05-31 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_classify_symbol):
+ Use SYMBOL_TINY_ABSOLUTE for AARCH64_CMODEL_TINY_PIC.
+
+2013-05-31 Tobias Burnus <burnus@net-b.de>
+
+ PR middle-end/57073
+ * tree-ssa-math-opts.c (execute_cse_sincos): Move check further up.
+
+2013-05-31 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/56315
+ * config/arm/arm.c (const_ok_for_dimode_op): Handle IOR.
+ * config/arm/arm.md (*iordi3_insn): Change to insn_and_split.
+ * config/arm/neon.md (iordi3_neon): Remove.
+ (neon_vorr<mode>): Generate iordi3 instead of iordi3_neon.
+ * config/arm/predicates.md (imm_for_neon_logic_operand):
+ Move to earlier in the file.
+ (neon_logic_op2): Likewise.
+ (arm_iordi_operand_neon): New predicate.
+
+2013-05-31 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/57478
+ PR tree-optimization/57453
+ * tree-vect-slp.c (vect_bb_slp_scalar_cost): Uses in PHI nodes
+ are life as well.
+
+2013-05-31 Kaushik Phatak <kaushik.phatak@kpitcummins.com>
+
+ * config/rl78/rl78.md (mulqi3,mulhi3): New define_expands.
+ (*mulqi3_rl78,*mulhi3_rl78,*mulhi3_g13): New define_insns.
+
+2013-05-30 Tobias Burnus <burnus@net-b.de>
+ Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR middle-end/57073
+ * tree-ssa-math-opts.c (execute_cse_sincos): Optimize
+ powi (-1.0, k) to (k & 1) ? -1.0 : 1.0.
+
+2013-05-30 Steven Bosscher <steven@gcc.gnu.org>
+
+ * rtlanal.c (tablejump_p): Expect table and label to be adjacent.
+
+2013-05-30 Vladimir Makarov <vmakarov@redhat.com>
+
+ * target.def (register_usage_leveling_p): New hook.
+ * targhooks.c (default_register_usage_leveling_p): New.
+ * targhooks.h (default_register_usage_leveling_p): New prototype.
+ * lra-assigns.c (register_usage_leveling_p): Use the hook.
+ * doc/tm.texi.in (TARGET_REGISTER_USAGE_LEVELING_P): New hook.
+ * doc/tm.texi: Update.
+ * config/i386/i386.c (TARGET_REGISTER_USAGE_LEVELING_P): Define.
+
+2013-05-30 Ian Bolton <ian.bolton@arm.com>
+
+ * config/aarch64/aarch64.md (insv<mode>): New define_expand.
+ (*insv_reg<mode>): New define_insn.
+
+2013-05-30 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ PR rtl-optimization/57439
+ * postreload.c (move2add_valid_value_p): Check that we have
+ a zero subreg_regno_offset when accessing the register in
+ the requested mode.
+
+2013-05-30 Yuri Rumyantsev <yuri.s.rumyantsev@intel.com>
+ Igor Zamyatin <igor.zamyatin@intel.com>
+
+ Silvermont (SLM) architecture pipeline model, tuning and
+ insn selection.
+ * config.gcc: Add slm config options and target.
+
+ * config/i386/slm.md: New.
+
+ * config/i386/driver-i386.c (host_detect_local_cpu): Check movbe.
+
+ * gcc/config/i386/i386-c.c (ix86_target_macros_internal): New case
+ PROCESSOR_SLM.
+ (ix86_target_macros_internal): Likewise.
+
+ * gcc/config/i386/i386.c (slm_cost): New cost.
+ (m_SLM): New macro flag.
+ (initial_ix86_tune_features): Set m_SLM.
+ (x86_accumulate_outgoing_args): Likewise.
+ (x86_arch_always_fancy_math_387): Likewise.
+ (processor_target_table): Add slm cost.
+ (cpu_names): Add slm cpu name.
+ (x86_option_override_internal): Set SLM ISA.
+ (ix86_issue_rate): New case PROCESSOR_SLM.
+ (ia32_multipass_dfa_lookahead): Likewise.
+ (fold_builtin_cpu): Add slm.
+
+ * config/i386/i386.h (TARGET_SLM): New target macro.
+ (target_cpu_default): Add TARGET_CPU_DEFAULT_slm.
+ (processor_type): Add PROCESSOR_SLM.
+
+ * config/i386/i386.md (cpu): Add new value "slm".
+ (slm.md): Include slm.md.
+
+2013-05-30 Bernd Schmidt <bernds@codesourcery.com>
+ Zhenqiang Chen <zhenqiang.chen@linaro.org>
+
+ * config/arm/arm-protos.h: Add and update function protos.
+ * config/arm/arm.c (use_simple_return_p): New added.
+ (thumb2_expand_return): Check simple_return flag.
+ * config/arm/arm.md: Add simple_return and conditional simple_return.
+ * config/arm/iterators.md: Add iterator for return and simple_return.
+
+2013-05-30 Zhenqiang Chen <zhenqiang.chen@linaro.org>
+
+ * config/arm/arm.c (arm_add_cfa_adjust_cfa_note): New added.
+ (arm_emit_multi_reg_pop): Add REG_CFA_ADJUST_CFA notes.
+ (arm_emit_vfp_multi_reg_pop): Likewise.
+ (thumb2_emit_ldrd_pop): Likewise.
+ (arm_expand_epilogue): Add misc REG_CFA notes.
+ (arm_unwind_emit): Skip REG_CFA_ADJUST_CFA and REG_CFA_RESTORE.
+
+2013-05-29 Lawrence Crowl <crowl@google.com>
+
+ * config/arm/t-arm: Update for below.
+
+ * config/arm/arm.c (arm_libcall_uses_aapcs_base::libcall_htab):
+ Change type to hash_table. Update dependent calls and types.
+
+ * config/i386/t-cygming: Update for below.
+
+ * config/i386/t-interix: Update for below.
+
+ * config/i386/winnt.c (i386_pe_section_type_flags::htab):
+ Change type to hash_table. Update dependent calls and types.
+ (i386_find_on_wrapper_list::wrappers): Likewise.
+
+ * config/ia64/t-ia64: Update for below.
+
+ * config/ia64/ia64.c (bundle_state_table):
+ Change type to hash_table. Update dependent calls and types.
+
+ * config/mips/mips.c (mips_reorg_process_insns::htab):
+ Change type to hash_table. Update dependent calls and types.
+
+ * config/sol2.c (solaris_comdat_htab):
+ Change type to hash_table. Update dependent calls and types.
+
+ * config/t-sol2: Update for above.
+
+2013-05-29 Teresa Johnson <tejohnson@google.com>
+
+ * passes.c (dump_passes): Use FOR_EACH_FUNCTION since
+ functions are not yet marked as defined.
+
+2013-05-29 Michael Meissner <meissner@linux.vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
+
+ * config/rs6000/vector.md (VEC_I): Add support for new power8 V2DI
+ instructions.
+ (VEC_A): Likewise.
+ (VEC_C): Likewise.
+ (vrotl<mode>3): Likewise.
+ (vashl<mode>3): Likewise.
+ (vlshr<mode>3): Likewise.
+ (vashr<mode>3): Likewise.
+
+ * config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Add
+ support for power8 V2DI builtins.
+
+ * config/rs6000/rs6000-builtin.def (abs_v2di): Add support for
+ power8 V2DI builtins.
+ (vupkhsw): Likewise.
+ (vupklsw): Likewise.
+ (vaddudm): Likewise.
+ (vminsd): Likewise.
+ (vmaxsd): Likewise.
+ (vminud): Likewise.
+ (vmaxud): Likewise.
+ (vpkudum): Likewise.
+ (vpksdss): Likewise.
+ (vpkudus): Likewise.
+ (vpksdus): Likewise.
+ (vrld): Likewise.
+ (vsld): Likewise.
+ (vsrd): Likewise.
+ (vsrad): Likewise.
+ (vsubudm): Likewise.
+ (vcmpequd): Likewise.
+ (vcmpgtsd): Likewise.
+ (vcmpgtud): Likewise.
+ (vcmpequd_p): Likewise.
+ (vcmpgtsd_p): Likewise.
+ (vcmpgtud_p): Likewise.
+ (vupkhsw): Likewise.
+ (vupklsw): Likewise.
+ (vaddudm): Likewise.
+ (vmaxsd): Likewise.
+ (vmaxud): Likewise.
+ (vminsd): Likewise.
+ (vminud): Likewise.
+ (vpksdss): Likewise.
+ (vpksdus): Likewise.
+ (vpkudum): Likewise.
+ (vpkudus): Likewise.
+ (vrld): Likewise.
+ (vsld): Likewise.
+ (vsrad): Likewise.
+ (vsrd): Likewise.
+ (vsubudm): Likewise.
+
+ * config/rs6000/rs6000.c (rs6000_init_hard_regno_mode_ok): Add
+ support for power8 V2DI instructions.
+
+ * config/rs6000/altivec.md (UNSPEC_VPKUHUM): Add support for
+ power8 V2DI instructions. Combine pack and unpack insns to use an
+ iterator for each mode. Check whether a particular mode supports
+ Altivec instructions instead of just checking TARGET_ALTIVEC.
+ (UNSPEC_VPKUWUM): Likewise.
+ (UNSPEC_VPKSHSS): Likewise.
+ (UNSPEC_VPKSWSS): Likewise.
+ (UNSPEC_VPKUHUS): Likewise.
+ (UNSPEC_VPKSHUS): Likewise.
+ (UNSPEC_VPKUWUS): Likewise.
+ (UNSPEC_VPKSWUS): Likewise.
+ (UNSPEC_VPACK_SIGN_SIGN_SAT): Likewise.
+ (UNSPEC_VPACK_SIGN_UNS_SAT): Likewise.
+ (UNSPEC_VPACK_UNS_UNS_SAT): Likewise.
+ (UNSPEC_VPACK_UNS_UNS_MOD): Likewise.
+ (UNSPEC_VUPKHSB): Likewise.
+ (UNSPEC_VUNPACK_HI_SIGN): Likewise.
+ (UNSPEC_VUNPACK_LO_SIGN): Likewise.
+ (UNSPEC_VUPKHSH): Likewise.
+ (UNSPEC_VUPKLSB): Likewise.
+ (UNSPEC_VUPKLSH): Likewise.
+ (VI2): Likewise.
+ (VI_char): Likewise.
+ (VI_scalar): Likewise.
+ (VI_unit): Likewise.
+ (VP): Likewise.
+ (VP_small): Likewise.
+ (VP_small_lc): Likewise.
+ (VU_char): Likewise.
+ (add<mode>3): Likewise.
+ (altivec_vaddcuw): Likewise.
+ (altivec_vaddu<VI_char>s): Likewise.
+ (altivec_vadds<VI_char>s): Likewise.
+ (sub<mode>3): Likewise.
+ (altivec_vsubcuw): Likewise.
+ (altivec_vsubu<VI_char>s): Likewise.
+ (altivec_vsubs<VI_char>s): Likewise.
+ (altivec_vavgs<VI_char>): Likewise.
+ (altivec_vcmpbfp): Likewise.
+ (altivec_eq<mode>): Likewise.
+ (altivec_gt<mode>): Likewise.
+ (altivec_gtu<mode>): Likewise.
+ (umax<mode>3): Likewise.
+ (smax<mode>3): Likewise.
+ (umin<mode>3): Likewise.
+ (smin<mode>3): Likewise.
+ (altivec_vpkuhum): Likewise.
+ (altivec_vpkuwum): Likewise.
+ (altivec_vpkshss): Likewise.
+ (altivec_vpkswss): Likewise.
+ (altivec_vpkuhus): Likewise.
+ (altivec_vpkshus): Likewise.
+ (altivec_vpkuwus): Likewise.
+ (altivec_vpkswus): Likewise.
+ (altivec_vpks<VI_char>ss): Likewise.
+ (altivec_vpks<VI_char>us): Likewise.
+ (altivec_vpku<VI_char>us): Likewise.
+ (altivec_vpku<VI_char>um): Likewise.
+ (altivec_vrl<VI_char>): Likewise.
+ (altivec_vsl<VI_char>): Likewise.
+ (altivec_vsr<VI_char>): Likewise.
+ (altivec_vsra<VI_char>): Likewise.
+ (altivec_vsldoi_<mode>): Likewise.
+ (altivec_vupkhsb): Likewise.
+ (altivec_vupkhs<VU_char>): Likewise.
+ (altivec_vupkls<VU_char>): Likewise.
+ (altivec_vupkhsh): Likewise.
+ (altivec_vupklsb): Likewise.
+ (altivec_vupklsh): Likewise.
+ (altivec_vcmpequ<VI_char>_p): Likewise.
+ (altivec_vcmpgts<VI_char>_p): Likewise.
+ (altivec_vcmpgtu<VI_char>_p): Likewise.
+ (abs<mode>2): Likewise.
+ (vec_unpacks_hi_v16qi): Likewise.
+ (vec_unpacks_hi_v8hi): Likewise.
+ (vec_unpacks_lo_v16qi): Likewise.
+ (vec_unpacks_hi_<VP_small_lc>): Likewise.
+ (vec_unpacks_lo_v8hi): Likewise.
+ (vec_unpacks_lo_<VP_small_lc>): Likewise.
+ (vec_pack_trunc_v8h): Likewise.
+ (vec_pack_trunc_v4si): Likewise.
+ (vec_pack_trunc_<mode>): Likewise.
+
+ * config/rs6000/altivec.h (vec_vaddudm): Add defines for power8
+ V2DI builtins.
+ (vec_vmaxsd): Likewise.
+ (vec_vmaxud): Likewise.
+ (vec_vminsd): Likewise.
+ (vec_vminud): Likewise.
+ (vec_vpksdss): Likewise.
+ (vec_vpksdus): Likewise.
+ (vec_vpkudum): Likewise.
+ (vec_vpkudus): Likewise.
+ (vec_vrld): Likewise.
+ (vec_vsld): Likewise.
+ (vec_vsrad): Likewise.
+ (vec_vsrd): Likewise.
+ (vec_vsubudm): Likewise.
+ (vec_vupkhsw): Likewise.
+ (vec_vupklsw): Likewise.
+
+2013-05-29 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.h (symtab_node_base): Add definition, alias and analyzed
+ flags; reorder rest of fields in more consistent way.
+ (varpool_node): Remove analyzed, finalized and alias.
+ (cgraph_ndoe): Likewise.
+ (symtab_alias_ultimate_target): New function.
+ (cgraph_function_node): Move offline.
+ (cgraph_reset_node): Declare.
+ (cgraph_comdat_can_be_unshared_p): Remove.
+ (varpool_remove_initializer): Declare.
+ (varpool_first_defined_variable, varpool_next_defined_variable
+ cgraph_first_defined_function, cgraph_next_defined_function): Update.
+ (cgraph_function_with_gimple_body_p): Update.
+ (varpool_all_refs_explicit_p): Update.
+ (symtab_alias_target): New function.
+ (cgraph_alias_aliased_node, varpool_alias_aliased_node): Rename to ...
+ (cgraph_alias_target, varpool_alias_target): .. this one; simplify.
+ (cgraph_function_or_thunk_node): Simplify using
+ symtab_alias_ultimate_target.
+ (varpool_variable_node): Likewise.
+ * cgraph.c (cgraph_create_function_alias): Update.
+ (cgraph_add_thunk): Update.
+ (cgraph_remove_node): Update.
+ (dump_cgraph_node): Do not dump removed flags.
+ (cgraph_function_body_availability): Update.
+ (cgraph_propagate_frequency): Update.
+ (verify_cgraph_node): Check sanity of local flag.
+ (cgraph_function_node): Move here from cgraph.h; revamp for
+ cgraph_function_or_thunk_node.
+ * lto-symtab.c (lto_varpool_replace_node): Update.
+ (lto_symtab_resolve_can_prevail_p): Update.
+ (lto_symtab_merge_cgraph_nodes): Update.
+ * ipa-cp.c (determine_versionability, initialize_node_lattices,
+ propagate_constants_accross_call, devirtualization_time_bonus,
+ ipcp_propagate_stage): Update.
+ * tree-emutls.c (create_emultls_var, ipa_lower_emutls): Update.
+ * ipa-inline-transform.c (clone_inlined_nodes,
+ preserve_function_body_p): Update.
+ * ipa-reference.c (propagate): Update.
+ (write_node_summary_p): Update.
+ * toplev.c (wrapup_global_declaration_2): Update.
+ * cgraphunit.c (cgraph_analyze_function): Rename to ...
+ (analyze_function) ... this one.
+ (cgraph_process_new_functions): Update.
+ (cgraph_reset_node): Export.
+ (cgraph_finalize_function): Update.
+ (cgraph_add_new_function): Update.
+ (process_function_and_variable_attributes): Update.
+ (varpool_finalize_decl): Update.
+ (symbol_finalized): Remove.
+ (symbol_finalized_and_needed): Rename to ...
+ (symbol_defined_and_needed): ... update.
+ (cgraph_analyze_functions): Update.
+ (handle_alias_pairs): Update.
+ (mark_functions_to_output): Update.
+ (assemble_thunk): Update.
+ (output_in_order): Update.
+ (output_weakrefs): Update.
+ (finalize_compilation_unit): Update.
+ * lto-cgraph.c (reachable_from_other_partition_p, lto_output_node,
+ lto_output_varpool_node, compute_ltrans_boundary, input_overwrite_node,
+ input_node, input_varpool_node): Update.
+ * dbxout.c (dbxout_expand_expr): Update.
+ * cgraphclones.c (cgraph_clone_node): Update.
+ (cgraph_copy_node_for_versioning): Update.
+ (cgraph_materialize_clone): Update.
+ (cgraph_materialize_all_clones): Update.
+ * ipa-pure-const.c (analyze_function, pure_const_write_summary,
+ propagate_pure_const, propagate_nothrow): Update.
+ * lto-streamer-out.c (lto_output, write_symbol): Update.
+ * ipa-utils.c (ipa_reverse_postorder): Update.
+ * ipa-inline.c (can_inline_edge_p): Update.
+ (update_caller_keys, ipa_inline): Update.
+ * dwarf2out.c (reference_to_unused,
+ premark_types_used_by_global_vars_helper): Update.
+ * tree-eh.c (tree_could_trap_p): Update.
+ * ipa-split.c (consider_split, execute_split_functions): Update.
+ * ipa.c (cgraph_non_local_node_p_1, cgraph_local_node_p,
+ has_addr_references_p): Update; move ahead in file for better
+ readability.
+ (process_references): Simplify.
+ (symtab_remove_unreachable_nodes): Update; cleanup way function/var
+ bodies are removed.
+ (cgraph_comdat_can_be_unshared_p): Make static.
+ (cgraph_externally_visible_p): Update.
+ (varpool_externally_visible_p): Update.
+ (function_and_variable_visibility): Update.
+ * trans-mem.c (get_cg_data, ipa_tm_mayenterirr_function,
+ ipa_tm_mark_force_output_node): Update.
+ * ipa-inline-analysis.c (dump_inline_summary, initialize_inline_failed,
+ estimate_edge_devirt_benefit, inline_generate_summary,
+ inline_write_summary): Update.
+ * gimple-fold.c (can_refer_decl_in_current_unit_p): Update.
+ * ipa-prop.c (ipa_compute_jump_functions): Update.
+ (ipa_print_node_params, ipa_prop_read_section,
+ ipa_update_after_lto_read, read_replacements_section): Update.
+ * varasm.c (mark_decl_referenced): Update.
+ (assemble_alias, dump_tm_clone_pairs): Update.
+ * tree-inline.c (copy_bb): Update.
+ (estimate_num_insns, optimize_inline_calls, tree_function_versioning):
+ Update.
+ * symtab.c (dump_symtab_base): Print new flags.
+ (verify_symtab_base): Verify new flags.
+ (symtab_alias_ultimate_target): New function.
+ * tree-ssa-structalias.c (get_constraint_for_ssa_var,
+ create_variable_info_for, associate_varinfo_to_alias, ipa_pta_execute):
+ Update.
+ * passes.c (ipa_write_summaries, ipa_write_optimization_summaries):
+ Update.
+ * i386.c (ix86_get_function_versions_dispatcher,
+ ix86_generate_version_dispatcher_body): Update.
+ (fold_builtin_cpu): Use varpool_add_new_variable.
+ * varpool.c (varpool_remove_initializer): Break out from ...
+ (varpool_remove_node): ... this one.
+ (dump_varpool_node, varpool_node_for_asm,
+ cgraph_variable_initializer_availability, varpool_analyze_node,
+ varpool_assemble_decl, varpool_remove_unreferenced_decls,
+ varpool_finalize_named_section_flags, varpool_create_variable_alias):
+ Update.
+
+2013-05-29 Jan Hubicka <jh@suse.cz>
+
+ * passes.c (init_optimization_passes): Move OMP expansion into lowering.
+
+2013-05-29 Easwaran Raman <eraman@google.com>
+
+ PR tree-optimization/57442
+ * tree-ssa-reassoc.c (appears_later_in_bb): Return correct value
+ when control exits the main loop.
+
+2013-05-29 Sandeep Kumar Singh <Sandeep.Singh2@kpitcummins.com>
+
+ * rx/rx.h (TARGET_CPU_CPP_BUILTINS): Add macros for RX100, RX200,
+ and RX600.
+ * rx/rx.opt: Add macro for rx100 with string rx100 and value RX100.
+ * rx/rx-opts.h (rx_cpu_types): Add new cpu type rx100.
+ * rx/t-rx: Add rx100 under multi library matches option for nofpu
+ option.
+
+2013-05-29 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ PR tree-optimization/57441
+ * gimple-ssa-strength-reduction.c (analyze_candidates_and_replace):
+ Don't limit size of incr_vec to number of candidates.
+
+2013-05-29 Steve Ellcey <sellcey@imgtec.com>
+
+ * config/mips/mti-linux.h (SYSROOT_SUFFIX_SPEC): Add micromips
+ and mips16 directories.
+ * config/mips/t-mti-linux (MULTILIB_OPTIONS): Add micromips and mips16.
+ (MULTILIB_DIRNAMES): Ditto.
+ (MULTILIB_EXCEPTIONS): Add new exceptions.
+ * config/mips/t-mti-elf (MULTILIB_OPTIONS): Add micromips.
+ (MULTILIB_DIRNAMES): Ditto.
+ (MULTILIB_EXCEPTIONS): Add new exceptions.
+
+2012-05-29 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
+ Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * config/aarch64/aarch64-protos.h (aarch64_symbol_type): Define
+ SYMBOL_TINY_ABSOLUTE.
+ * config/aarch64/aarch64.c (aarch64_load_symref_appropriately): Handle
+ SYMBOL_TINY_ABSOLUTE.
+ (aarch64_expand_mov_immediate): Likewise.
+ (aarch64_classify_symbol): Likewise.
+ (aarch64_mov_operand_p): Remove ATTRIBUTE_UNUSED.
+ Permit SYMBOL_TINY_ABSOLUTE.
+ * config/aarch64/predicates.md (aarch64_mov_operand): Permit CONST.
+
+2013-05-29 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
+ Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_classify_symbol): Remove comment.
+ Refactor if/switch. Replace gcc_assert with if.
+
+2013-05-29 Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com>
+
+ * config/i386/i386.c (initial_ix86_tune_features): Enable
+ FP Reassociation for AMD bdver1 and bdver2.
+
+2013-05-29 Martin Jambor <mjambor@suse.cz>
+
+ * tree-cfg.c (verify_expr): Verify that BIT_FIELD_REF, REALPART_EXPR
+ and IMAGPART_EXPR do not occur within other handled_components.
+
+2013-05-29 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-slp.c (vect_bb_slp_scalar_cost): Guard vinfo
+ access on whether the use is in the BB we currently try to
+ vectorize.
+ (vect_bb_vectorization_profitable_p): Pass the BB we currently
+ vectorize to vect_bb_slp_scalar_cost.
+
+2013-05-29 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-slp.c (vect_bb_slp_scalar_cost): New function
+ computing scalar cost offsetted by stmts that are kept live
+ by scalar uses.
+ (vect_bb_vectorization_profitable_p): Use vect_bb_slp_scalar_cost
+ for computation of scalar cost.
+
+2013-05-28 Steve Ellcey <sellcey@mips.com>
+
+ * config/mips/mips-cpus.def (mips32r2): Change processor type.
+
+2013-05-28 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * doc/extend.texi (C Extensions): Added documentation about Cilk Plus
+ array notation built-in reduction functions.
+ * doc/passes.texi (Passes): Added documentation about changes done
+ for Cilk Plus.
+ * doc/invoke.texi (C Dialect Options): Added documentation about
+ the -fcilkplus flag.
+ * Makefile.in (C_COMMON_OBJS): Added c-family/array-notation-common.o.
+ (BUILTINS_DEF): Depend on cilkplus.def.
+ * builtins.def: Include cilkplus.def. Define DEF_CILKPLUS_BUILTIN.
+ * builtin-types.def: Define BT_FN_INT_PTR_PTR_PTR.
+ * cilkplus.def: New file.
+
+2013-05-28 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ PR rtl-optimization/57439
+ * postreload.c (move2add_use_add2_insn): Use gen_lowpart_common.
+
+2013-05-28 Easwaran Raman <eraman@google.com>
+
+ PR tree-optimization/57337
+ * tree-ssa-reassoc.c (appears_later_in_bb): New function.
+ (find_insert_point): Correctly identify the insertion point
+ when two statements with the same UID is compared.
+
+2013-05-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/56787
+ * tree-vect-data-refs.c (vect_analyze_data_refs): Drop clobbers
+ from the list of data references.
+ * tree-vect-loop.c (vect_determine_vectorization_factor): Skip
+ clobbers.
+ (vect_analyze_loop_operations): Likewise.
+ (vect_transform_loop): Remove clobbers.
+
+2013-05-28 Martin Jambor <mjambor@suse.cz>
+
+ * tree-cfg.c (verify_expr): Verify that BIT_FIELD_REFs, IMAGPART_EXPRs
+ and REALPART_EXPRs have scalar type.
+
+2013-05-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/57411
+ * tree-ssa-copy.c (may_propagate_copy): Cannot propagate
+ virtual operands.
+ * tree-ssa-dom.c (eliminate_const_or_copy): Special-case
+ virtual operand propagation.
+
+2013-05-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config/sparc/sparc.c (sparc_expand_vec_perm_bmask): Use %g0 as
+ destination register for bmasksi_vis.
+ (vector_init_bshuffle): Likewise.
+ * config/sparc/sparc.md (vec_perm_constv8qi): Likewise.
+
+2013-05-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * doc/invoke.texi (SPARC Options): Document -mfix-ut699.
+ * builtins.c (expand_builtin_mathfn) <BUILT_IN_SQRT>: Try to widen the
+ mode if the instruction isn't available in the original mode.
+ * config/sparc/sparc.opt (mfix-ut699): New option.
+ * config/sparc/sparc.md (muldf3_extend): Disable if -mfix-ut699.
+ (divdf3): Turn into expander.
+ (divdf3_nofix): New insn.
+ (divdf3_fix): Likewise.
+ (divsf3): Disable if -mfix-ut699.
+ (sqrtdf2): Turn into expander.
+ (sqrtdf2_nofix): New insn.
+ (sqrtdf2_fix): Likewise.
+ (sqrtsf2): Disable if -mfix-ut699.
+
+2013-05-27 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/57412
+ * omp-low.c (expand_omp_atomic_pipeline): Use the correct latch
+ block for the new loop.
+
+2013-05-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/57343
+ * tree-ssa-loop-niter.c (number_of_iterations_ne_max): Do not
+ use multiple_of_p if not TYPE_OVERFLOW_UNDEFINED.
+ (number_of_iterations_cond): Do not build the folded tree.
+
+2013-05-27 Richard Biener <rguenther@suse.de>
+
+ Revert
+ PR middle-end/57381
+ * fold-const.c (operand_equal_p): Compare FIELD_DECLs with
+ OEP_CONSTANT_ADDRESS_OF retained.
+
+ PR tree-optimization/57417
+ * tree-ssa-sccvn.c (vn_reference_fold_indirect): Fix test
+ for unchanged base.
+ (set_ssa_val_to): Compare addresses using
+ get_addr_base_and_unit_offset.
+
+2013-05-27 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ PR rtl-optimization/56833
+ * postreload.c (move2add_record_mode): New function.
+ (move2add_record_sym_value, move2add_valid_value_p): Likewise.
+ (move2add_use_add2_insn): Use move2add_record_sym_value.
+ (move2add_use_add3_insn): Likewise.
+ (reload_cse_move2add): Use move2add_valid_value_p and
+ move2add_record_mode. Invalidate call-clobbered and REG_INC
+ affected regs by setting reg_mode to VOIDmode.
+ (move2add_note_store): Don't pretend the inside of a SUBREG is
+ the actual destination. Invalidate single/leading registers by
+ setting reg_mode to VOIDmode.
+ Use move2add_record_sym_value, move2add_valid_value_p and
+ move2add_record_mode.
+
2013-05-27 Richard Biener <rguenther@suse.de>
PR tree-optimization/57396
@@ -58,7 +1112,7 @@
2013-05-24 Dehao Chen <dehao@google.com>
- * gcc/tree-cfg.c (locus_discrim_map): Fix the typo.
+ * tree-cfg.c (locus_discrim_map): Fix the typo.
(locus_discrim_hasher): Likewise.
(locus_discrim_hasher::hash): Likewise.
(locus_discrim_hasher::equal): Likewise.
@@ -79,22 +1133,21 @@
2013-05-24 Vladimir Makarov <vmakarov@redhat.com>
- * lra-constraints.c (emit_spill_move): Use smaller mode for
+ * lra-constraints.c (emit_spill_move): Use smaller mode for
mem-mem moves.
- (check_and_process_move): Consider mem-reg moves for secondary
+ (check_and_process_move): Consider mem-reg moves for secondary
too.
- (curr_insn_transform): Don't lose insns emitted before for
+ (curr_insn_transform): Don't lose insns emitted before for
secondary memory moves.
(inherit_in_ebb): Mark defined reg. Add usage only if it is not a
reg set up in the current insn.
2013-05-24 Dehao Chen <dehao@google.com>
- * gcc/testsuite/gcc.dg/debug/dwarf2/discriminator.c: New Testcase.
- * gcc/tree-cfg.c (locus_descrim_hasher::hash): Change discrminator
+ * tree-cfg.c (locus_descrim_hasher::hash): Change discriminator
hash function.
(locus_descrim_hasher::equal): Likewise.
- (build_gimple_cfg): New discrminator assignmnet algorithm
+ (build_gimple_cfg): New discriminator assignment algorithm.
(make_edges): Likewise.
(next_discriminator_for_locus): Likewise.
(same_line_p): Likewise.
@@ -407,8 +1460,8 @@
2013-05-21 Easwaran Raman <eraman@google.com>
PR tree-optimization/57322
- * (build_and_add_sum): If a BB is empty, set the UID of the statement
- added to the BB to be 1.
+ * tree-ssa-reassoc.c (build_and_add_sum): If a BB is empty, set the
+ UID of the statement added to the BB to be 1.
2013-05-21 Jakub Jelinek <jakub@redhat.com>
@@ -447,8 +1500,8 @@
2013-05-21 Christian Bruel <christian.bruel@st.com>
- * dwarf2out.c (multiple_reg_loc_descriptor): Use dbx_reg_number for
- spanning registers. LEAF_REG_REMAP is supported only for contiguous
+ * dwarf2out.c (multiple_reg_loc_descriptor): Use dbx_reg_number for
+ spanning registers. LEAF_REG_REMAP is supported only for contiguous
registers. Set register size out of the PARALLEL loop.
2013-05-20 Oleg Endo <olegendo@gcc.gnu.org>
@@ -1051,7 +2104,7 @@
* expmed.c (expand_shift_1): Canonicalize rotates by
constant bitsize / 2 to bitsize - 1.
- * simplify-rt.x (simplify_binary_operation_1) <case ROTATE,
+ * simplify-rtx.c (simplify_binary_operation_1) <case ROTATE,
case ROTATERT>: Likewise.
Revert:
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 67c582f59bd..b331a36d111 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20130527
+20130606
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 1a965c18836..e95dd63c7db 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -869,7 +869,7 @@ RTL_ERROR_H = rtl-error.h $(RTL_H) $(DIAGNOSTIC_CORE_H)
READ_MD_H = $(OBSTACK_H) $(HASHTAB_H) read-md.h
PARAMS_H = params.h params.def
BUILTINS_DEF = builtins.def sync-builtins.def omp-builtins.def \
- gtm-builtins.def sanitizer.def
+ gtm-builtins.def sanitizer.def cilkplus.def
INTERNAL_FN_DEF = internal-fn.def
INTERNAL_FN_H = internal-fn.h $(INTERNAL_FN_DEF)
TREE_H = coretypes.h tree.h all-tree.def tree.def c-family/c-common.def \
@@ -1149,7 +1149,8 @@ C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
c-family/c-format.o c-family/c-gimplify.o c-family/c-lex.o \
c-family/c-omp.o c-family/c-opts.o c-family/c-pch.o \
c-family/c-ppoutput.o c-family/c-pragma.o c-family/c-pretty-print.o \
- c-family/c-semantics.o c-family/c-ada-spec.o tree-mudflap.o
+ c-family/c-semantics.o c-family/c-ada-spec.o tree-mudflap.o \
+ c-family/array-notation-common.o
# Language-independent object files.
# We put the insn-*.o files first so that a parallel make will build
@@ -2014,6 +2015,9 @@ c-family/c-ada-spec.o : c-family/c-ada-spec.c c-family/c-ada-spec.h \
$(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(CPP_ID_DATA_H) $(TM_H) \
coretypes.h tree-iterator.h $(DUMPFILE_H)
+c-family/array-notation-common.o : c-family/array-notation-common.c $(TREE_H) \
+ $(SYSTEM_H) $(TREE_H) coretypes.h tree-iterator.h $(DIAGNOSTIC_CORE_H)
+
c-family/stub-objc.o : c-family/stub-objc.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TREE_H) $(C_COMMON_H) c-family/c-objc.h
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index b9d47e2fa1b..1a37786243a 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,7 @@
+2013-05-30 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/Makefile.in (arm% androideabi): Robustify.
+
2013-05-26 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c: (gnat_to_gnu_entity): In ASIS mode, do not
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index 04b5e55b205..6aa93c4655a 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -995,7 +995,7 @@ ifeq ($(strip $(filter-out mips% wrs vx%,$(targ))),)
EXTRA_LIBGNAT_OBJS+=vx_stack_info.o
endif
-ifeq ($(strip $(filter-out arm% linux-androideabi,$(arch) $(osys)-$(word 4,$(targ)))),)
+ifeq ($(strip $(filter-out arm% androideabi,$(arch) $(osys))),)
LIBGNAT_TARGET_PAIRS = \
a-intnam.ads<a-intnam-linux.ads \
s-inmaop.adb<s-inmaop-posix.adb \
diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index 3ef2d1bbf4a..2634eccabab 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -368,6 +368,8 @@ DEF_FUNCTION_TYPE_3 (BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG,
BT_INT, BT_CONST_STRING, BT_CONST_STRING, BT_VALIST_ARG)
DEF_FUNCTION_TYPE_3 (BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG,
BT_INT, BT_FILEPTR, BT_CONST_STRING, BT_VALIST_ARG)
+DEF_FUNCTION_TYPE_3 (BT_FN_INT_PTR_PTR_PTR,
+ BT_INT, BT_PTR, BT_PTR, BT_PTR)
DEF_FUNCTION_TYPE_3 (BT_FN_STRING_CONST_STRING_CONST_STRING_INT,
BT_STRING, BT_CONST_STRING, BT_CONST_STRING, BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT_FLOAT_FLOAT_FLOAT,
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 1fbd2f32edd..402bb1fb147 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -1961,6 +1961,7 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
tree fndecl = get_callee_fndecl (exp);
enum machine_mode mode;
bool errno_set = false;
+ bool try_widening = false;
tree arg;
if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
@@ -1972,6 +1973,7 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
{
CASE_FLT_FN (BUILT_IN_SQRT):
errno_set = ! tree_expr_nonnegative_p (arg);
+ try_widening = true;
builtin_optab = sqrt_optab;
break;
CASE_FLT_FN (BUILT_IN_EXP):
@@ -2028,8 +2030,10 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
if (! flag_errno_math || ! HONOR_NANS (mode))
errno_set = false;
- /* Before working hard, check whether the instruction is available. */
- if (optab_handler (builtin_optab, mode) != CODE_FOR_nothing
+ /* Before working hard, check whether the instruction is available, but try
+ to widen the mode for specific operations. */
+ if ((optab_handler (builtin_optab, mode) != CODE_FOR_nothing
+ || (try_widening && !excess_precision_type (TREE_TYPE (exp))))
&& (!errno_set || !optimize_insn_for_size_p ()))
{
rtx result = gen_reg_rtx (mode);
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 276f89c26e2..91879a64dc0 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -157,6 +157,11 @@ along with GCC; see the file COPYING3. If not see
true, true, true, ATTRS, true, \
(flag_asan || flag_tsan))
+#undef DEF_CILKPLUS_BUILTIN
+#define DEF_CILKPLUS_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
+ DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
+ false, false, true, ATTRS, false, flag_enable_cilkplus)
+
/* Define an attribute list for math functions that are normally
"impure" because some of them may write into global memory for
`errno'. If !flag_errno_math they are instead "const". */
@@ -837,3 +842,5 @@ DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST)
/* Sanitizer builtins. */
#include "sanitizer.def"
+/* Cilk Plus builtins. */
+#include "cilkplus.def"
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 840a10e973f..d434a2f8ad6 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,24 @@
+2013-05-28 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * c-common.c (c_define_builtins): When cilkplus is enabled, the
+ function array_notation_init_builtins is called.
+ (c_common_init_ts): Added ARRAY_NOTATION_REF as typed.
+ * c-common.def (ARRAY_NOTATION_REF): New tree.
+ * c-common.h (build_array_notation_expr): New function declaration.
+ (build_array_notation_ref): Likewise.
+ (extract_sec_implicit_index_arg): New extern declaration.
+ (is_sec_implicit_index_fn): Likewise.
+ (ARRAY_NOTATION_CHECK): New define.
+ (ARRAY_NOTATION_ARRAY): Likewise.
+ (ARRAY_NOTATION_START): Likewise.
+ (ARRAY_NOTATION_LENGTH): Likewise.
+ (ARRAY_NOTATION_STRIDE): Likewise.
+ * c-pretty-print.c (pp_c_postifix_expression): Added a new case for
+ ARRAY_NOTATION_REF.
+ (pp_c_expression): Likewise.
+ * c.opt (flag_enable_cilkplus): New flag.
+ * array-notation-common.c: New file.
+
2013-05-14 Jakub Jelinek <jakub@redhat.com>
PR c++/57274
diff --git a/gcc/c-family/array-notation-common.c b/gcc/c-family/array-notation-common.c
new file mode 100644
index 00000000000..1d288464eee
--- /dev/null
+++ b/gcc/c-family/array-notation-common.c
@@ -0,0 +1,76 @@
+/* This file is part of the Intel(R) Cilk(TM) Plus support
+ This file contains the builtin functions for Array
+ notations.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ Contributed by Balaji V. Iyer <balaji.v.iyer@intel.com>,
+ Intel Corporation
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "langhooks.h"
+#include "tree-iterator.h"
+#include "diagnostic-core.h"
+
+
+/* Returns true if the function call in FNDECL is __sec_implicit_index. */
+
+bool
+is_sec_implicit_index_fn (tree fndecl)
+{
+ if (TREE_CODE (fndecl) == ADDR_EXPR)
+ fndecl = TREE_OPERAND (fndecl, 0);
+
+ return
+ (TREE_CODE (fndecl) == FUNCTION_DECL
+ && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+ && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CILKPLUS_SEC_IMPLICIT_INDEX);
+}
+
+/* Returns the first and only argument for FN, which should be a
+ sec_implicit_index function. FN's location in the source file is as
+ indicated by LOCATION. The argument to FN must be a constant integer
+ expression, otherwise returns -1. */
+
+HOST_WIDE_INT
+extract_sec_implicit_index_arg (location_t location, tree fn)
+{
+ tree fn_arg;
+ HOST_WIDE_INT return_int = 0;
+
+ if (TREE_CODE (fn) == CALL_EXPR)
+ {
+ fn_arg = CALL_EXPR_ARG (fn, 0);
+ if (TREE_CODE (fn_arg) == INTEGER_CST)
+ return_int = int_cst_value (fn_arg);
+ else
+ {
+ /* If the location is unknown, and if fn has a location, then use that
+ information so that the user has a better idea where the error
+ could be. */
+ if (location == UNKNOWN_LOCATION && EXPR_HAS_LOCATION (fn))
+ location = EXPR_LOCATION (fn);
+ error_at (location, "__sec_implicit_index parameter must be an "
+ "integer constant expression");
+ return -1;
+ }
+ }
+ return return_int;
+}
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 7f5d3165b8b..dec887fb4c0 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -11424,6 +11424,7 @@ c_common_init_ts (void)
{
MARK_TS_TYPED (C_MAYBE_CONST_EXPR);
MARK_TS_TYPED (EXCESS_PRECISION_EXPR);
+ MARK_TS_TYPED (ARRAY_NOTATION_REF);
}
/* Build a user-defined numeric literal out of an integer constant type VALUE
diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def
index 13113afe587..fac50e23777 100644
--- a/gcc/c-family/c-common.def
+++ b/gcc/c-family/c-common.def
@@ -55,6 +55,13 @@ DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3)
or for the purpose of -Wsizeof-pointer-memaccess warning. */
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1)
+/* Array Notation expression.
+ Operand 0 is the array.
+ Operand 1 is the starting array index.
+ Operand 2 contains the number of elements you need to access.
+ Operand 3 is the stride. */
+DEFTREECODE (ARRAY_NOTATION_REF, "array_notation_ref", tcc_reference, 4)
+
/*
Local variables:
mode:c
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 4014651b876..d89982174bb 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -538,6 +538,10 @@ extern tree pushdecl_top_level (tree);
extern tree pushdecl (tree);
extern tree build_modify_expr (location_t, tree, tree, enum tree_code,
location_t, tree, tree);
+extern tree build_array_notation_expr (location_t, tree, tree, enum tree_code,
+ location_t, tree, tree);
+extern tree build_array_notation_ref (location_t, tree, tree, tree, tree, tree);
+extern bool find_rank (location_t, tree, tree, bool, size_t *);
extern tree build_indirect_ref (location_t, tree, ref_operator);
extern int field_decl_cmp (const void *, const void *);
@@ -1133,4 +1137,26 @@ enum stv_conv {
extern enum stv_conv scalar_to_vector (location_t loc, enum tree_code code,
tree op0, tree op1, bool);
+/* These #defines allow users to access different operands of the
+ array notation tree. */
+
+#define ARRAY_NOTATION_CHECK(NODE) TREE_CHECK (NODE, ARRAY_NOTATION_REF)
+#define ARRAY_NOTATION_ARRAY(NODE) \
+ TREE_OPERAND (ARRAY_NOTATION_CHECK (NODE), 0)
+#define ARRAY_NOTATION_START(NODE) \
+ TREE_OPERAND (ARRAY_NOTATION_CHECK (NODE), 1)
+#define ARRAY_NOTATION_LENGTH(NODE) \
+ TREE_OPERAND (ARRAY_NOTATION_CHECK (NODE), 2)
+#define ARRAY_NOTATION_STRIDE(NODE) \
+ TREE_OPERAND (ARRAY_NOTATION_CHECK (NODE), 3)
+
+extern int extract_sec_implicit_index_arg (location_t, tree);
+extern bool is_sec_implicit_index_fn (tree);
+extern void array_notation_init_builtins (void);
+extern struct c_expr fix_array_notation_expr (location_t, enum tree_code,
+ struct c_expr);
+extern bool contains_array_notation_expr (tree);
+extern tree expand_array_notation_exprs (tree);
+extern tree fix_conditional_array_notations (tree);
+extern tree find_correct_array_notation_type (tree);
#endif /* ! GCC_C_COMMON_H */
diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index 13dd613d84e..b8af90c053c 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/gcc/c-family/c-pretty-print.c
@@ -1476,6 +1476,17 @@ pp_c_postfix_expression (c_pretty_printer *pp, tree e)
pp_c_right_bracket (pp);
break;
+ case ARRAY_NOTATION_REF:
+ pp_postfix_expression (pp, ARRAY_NOTATION_ARRAY (e));
+ pp_c_left_bracket (pp);
+ pp_expression (pp, ARRAY_NOTATION_START (e));
+ pp_colon (pp);
+ pp_expression (pp, ARRAY_NOTATION_LENGTH (e));
+ pp_colon (pp);
+ pp_expression (pp, ARRAY_NOTATION_STRIDE (e));
+ pp_c_right_bracket (pp);
+ break;
+
case CALL_EXPR:
{
call_expr_arg_iterator iter;
@@ -2150,6 +2161,7 @@ pp_c_expression (c_pretty_printer *pp, tree e)
case POSTINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
case ARRAY_REF:
+ case ARRAY_NOTATION_REF:
case CALL_EXPR:
case COMPONENT_REF:
case BIT_FIELD_REF:
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 124c13986a8..857813474c9 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -843,6 +843,10 @@ fcanonical-system-headers
C ObjC C++ ObjC++
Where shorter, use canonicalized paths to systems headers.
+fcilkplus
+C ObjC C++ ObjC++ LTO Report Var(flag_enable_cilkplus) Init(0)
+Enable Cilk Plus
+
fcheck-new
C++ ObjC++ Var(flag_check_new)
Check the return value of new
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index e0fef1e164f..2543f5d6eb5 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,78 @@
+2013-06-05 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * c-typeck.c (convert_arguments): Moved checking of builtin cilkplus
+ reduction functions outside the for-loop. Added a check if the fundecl
+ is non-NULL. Finally, removed an unwanted if-statement, and made the
+ body unconditional.
+
+2013-06-03 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * c-typeck.c (c_finish_if_stmt): Added a check to see if the rank of the
+ condition of the if-statement matches the rank of else-block and then-
+ block when array notations are used.
+ * c-parser.c (c_parser_declaration_or_fndef): Expanded array notation
+ expression after the entire function body is parsed.
+ (c_parser_expr_no_commas): Delayed creating array notation expressions
+ to the end of function parsing.
+ * c-array-notation.c (fix_conditional_array_notations_1): Expanded the
+ whole if-statement instead of just the condition.
+ (expand_array_notation_exprs): Added MODIFY_EXPR case.
+
+2013-06-03 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ PR c/57474
+ * c-array-notation.c (build_array_notation_expr): Initialized rhs_length
+ array to NULL_TREE if they are unused. Also added a check for the
+ field to be NULL before its fields are used in future.
+
+2013-05-29 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ PR bootstrap/57450
+ * c-array-notation.c (length_mismatch_in_expr_p): Use absu_hwi.
+ (build_array_notation_expr): Likewise.
+
+2013-05-28 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * c-typeck.c (build_array_ref): Added a check to see if array's
+ index is greater than one. If true, then emit an error.
+ (build_function_call_vec): Exclude error reporting and checking
+ for builtin array-notation functions.
+ (convert_arguments): Likewise.
+ (c_finish_return): Added a check for array notations as a return
+ expression. If true, then emit an error.
+ (c_finish_loop): Added a check for array notations in a loop
+ condition. If true then emit an error.
+ (lvalue_p): Added a ARRAY_NOTATION_REF case.
+ (build_binary_op): Added a check for array notation expr inside
+ op1 and op0. If present, we call another function to find correct
+ type.
+ * Make-lang.in (C_AND_OBJC_OBJS): Added c-array-notation.o.
+ * c-parser.c (c_parser_compound_statement): Check if array
+ notation code is used in tree, if so, then transform them into
+ appropriate C code.
+ (c_parser_expr_no_commas): Check if array notation is used in LHS
+ or RHS, if so, then build array notation expression instead of
+ regular modify.
+ (c_parser_postfix_expression_after_primary): Added a check for
+ colon(s) after square braces, if so then handle it like an array
+ notation. Also, break up array notations in unary op if found.
+ (c_parser_direct_declarator_inner): Added a check for array
+ notation.
+ (c_parser_compound_statement): Added a check for array notation in
+ a stmt. If one is present, then expand array notation expr.
+ (c_parser_if_statement): Likewise.
+ (c_parser_switch_statement): Added a check for array notations in
+ a switch statement's condition. If true, then output an error.
+ (c_parser_while_statement): Similarly, but for a while.
+ (c_parser_do_statement): Similarly, but for a do-while.
+ (c_parser_for_statement): Similarly, but for a for-loop.
+ (c_parser_unary_expression): Check if array notation is used in a
+ pre-increment or pre-decrement expression. If true, then expand
+ them.
+ (c_parser_array_notation): New function.
+ * c-array-notation.c: New file.
+ * c-tree.h (is_cilkplus_reduce_builtin): Protoize.
+
2013-05-23 Mike Stump <mikestump@comcast.net>
* c-typeck.c (convert_for_assignment): Handle references to memory
diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in
index 47aa4cbef6f..1161742c274 100644
--- a/gcc/c/Make-lang.in
+++ b/gcc/c/Make-lang.in
@@ -56,7 +56,7 @@ c/gccspec.o: c/gccspec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) \
# Language-specific object files for C and Objective C.
C_AND_OBJC_OBJS = attribs.o c/c-errors.o c/c-decl.o c/c-typeck.o \
c/c-convert.o c/c-aux-info.o c/c-objc-common.o c/c-parser.o \
- $(C_COMMON_OBJS) $(C_TARGET_OBJS)
+ c/c-array-notation.o $(C_COMMON_OBJS) $(C_TARGET_OBJS)
# Language-specific object files for C.
C_OBJS = c/c-lang.o c-family/stub-objc.o $(C_AND_OBJC_OBJS)
@@ -192,3 +192,8 @@ c/c-typeck.o : c/c-typeck.c c/c-lang.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_
langhooks.h tree-iterator.h $(BITMAP_H) $(GIMPLE_H) \
c-family/c-objc.h c-family/c-common.h
+c/c-array-notation.o: c/c-array-notation.c c/c-lang.h $(CONFIG_H) \
+ $(SYSTEM_H) coretypes.h $(TREE_H) $(C_TREE_H) $(TARGET_H) \
+ intl.h output.h $(EXPR_H) langhooks.h tree-iterator.h $(BITMAP_H) \
+ $(GIMPLE_H) c-family/c-objc.h
+
diff --git a/gcc/c/c-array-notation.c b/gcc/c/c-array-notation.c
new file mode 100644
index 00000000000..bcd09224d0c
--- /dev/null
+++ b/gcc/c/c-array-notation.c
@@ -0,0 +1,2891 @@
+/* This file is part of the Intel(R) Cilk(TM) Plus support
+ This file contains routines to handle Array Notation expression
+ handling routines in the C Compiler.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ Contributed by Balaji V. Iyer <balaji.v.iyer@intel.com>,
+ Intel Corporation.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+/* The Array Notation Transformation Technique:
+
+ An array notation expression has 4 major components:
+ 1. The array name
+ 2. Start Index
+ 3. Number of elements we need to acess (we call it length)
+ 4. Stride
+
+ For example, A[0:5:2], implies that we are accessing A[0], A[2], A[4],
+ A[6] and A[8]. The user is responsible to make sure the access length does
+ not step outside the array's size.
+
+ In this section, I highlight the overall method on how array notations are
+ broken up into C/C++ code. Almost all the functions follows this overall
+ technique:
+
+ Let's say we have an array notation in a statement like this:
+
+ A[St1:Ln:Str1] = B[St2:Ln:Str2] + <NON ARRAY_NOTATION_STMT>
+
+ where St{1,2} = Starting index,
+ Ln = Number of elements we need to access,
+ and Str{1,2} = the stride.
+ Note: The length of both the array notation expressions must be the same.
+
+ The above expression is broken into the following
+ (with the help of c_finish_loop function from c-typeck.c):
+
+ Tmp_Var = 0;
+ goto compare_label:
+ body_label:
+
+ A[St1+Tmp_Var*Str1] = B[St1+Tmp_Var*Str2] + <NON ARRAY_NOTATION_STMT>;
+ Tmp_Var++;
+
+ compare_label:
+ if (Tmp_Var < Ln)
+ goto body_label;
+ else
+ goto exit_label;
+ exit_label:
+
+*/
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "c-tree.h"
+#include "tree-iterator.h"
+#include "opts.h"
+#include "c-family/c-common.h"
+
+static void replace_array_notations (tree *, bool, vec<tree, va_gc> *,
+ vec<tree, va_gc> *);
+static void extract_array_notation_exprs (tree, bool, vec<tree, va_gc> **);
+
+/* This structure holds all the scalar values and its appropriate variable
+ replacment. It is mainly used by the function that pulls all the invariant
+ parts that should be executed only once, which comes with array notation
+ expressions. */
+struct inv_list
+{
+ vec<tree, va_gc> *list_values;
+ vec<tree, va_gc> *replacement;
+};
+
+/* Returns true if there is length mismatch among expressions
+ on the same dimension and on the same side of the equal sign. The
+ expressions (or ARRAY_NOTATION lengths) are passed in through 2-D array
+ **LIST where X and Y indicate first and second dimension sizes of LIST,
+ respectively. */
+
+static bool
+length_mismatch_in_expr_p (location_t loc, tree **list, size_t x, size_t y)
+{
+ size_t ii, jj;
+ tree start = NULL_TREE;
+ HOST_WIDE_INT l_start, l_node;
+ for (jj = 0; jj < y; jj++)
+ {
+ start = NULL_TREE;
+ for (ii = 0; ii < x; ii++)
+ {
+ if (!start)
+ start = list[ii][jj];
+ else if (TREE_CODE (start) == INTEGER_CST)
+ {
+ /* If start is a INTEGER, and list[ii][jj] is an integer then
+ check if they are equal. If they are not equal then return
+ true. */
+ if (TREE_CODE (list[ii][jj]) == INTEGER_CST)
+ {
+ l_node = int_cst_value (list[ii][jj]);
+ l_start = int_cst_value (start);
+ if (absu_hwi (l_start) != absu_hwi (l_node))
+ {
+ error_at (loc, "length mismatch in expression");
+ return true;
+ }
+ }
+ }
+ else
+ /* We set the start node as the current node just in case it turns
+ out to be an integer. */
+ start = list[ii][jj];
+ }
+ }
+ return false;
+}
+
+
+/* Given an FNDECL of type FUNCTION_DECL or ADDR_EXPR, return the corresponding
+ BUILT_IN_CILKPLUS_SEC_REDUCE_* being called. If none, return
+ BUILT_IN_NONE. */
+
+enum built_in_function
+is_cilkplus_reduce_builtin (tree fndecl)
+{
+ if (TREE_CODE (fndecl) == ADDR_EXPR)
+ fndecl = TREE_OPERAND (fndecl, 0);
+
+ if (TREE_CODE (fndecl) == FUNCTION_DECL
+ && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ADD:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MUL:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING:
+ return DECL_FUNCTION_CODE (fndecl);
+ default:
+ break;
+ }
+
+ return BUILT_IN_NONE;
+}
+
+/* This function will recurse into EXPR finding any
+ ARRAY_NOTATION_EXPRs and calculate the overall rank of EXPR,
+ storing it in *RANK. LOC is the location of the original expression.
+
+ ORIG_EXPR is the original expression used to display if any rank
+ mismatch errors are found.
+
+ Upon entry, *RANK must be either 0, or the rank of a parent
+ expression that must have the same rank as the one being
+ calculated. It is illegal to have multiple array notation with different
+ rank in the same expression (see examples below for clarification).
+
+ If there were any rank mismatches while calculating the rank, an
+ error will be issued, and FALSE will be returned. Otherwise, TRUE
+ is returned.
+
+ If IGNORE_BUILTIN_FN is TRUE, ignore array notation specific
+ built-in functions (__sec_reduce_*, etc).
+
+ Here are some examples of array notations and their rank:
+
+ Expression RANK
+ 5 0
+ X (a variable) 0
+ *Y (a pointer) 0
+ A[5] 0
+ B[5][10] 0
+ A[:] 1
+ B[0:10] 1
+ C[0:10:2] 1
+ D[5][0:10:2] 1 (since D[5] is considered "scalar")
+ D[5][:][10] 1
+ E[:] + 5 1
+ F[:][:][:] + 5 + X 3
+ F[:][:][:] + E[:] + 5 + X RANKMISMATCH-ERROR since rank (E[:]) = 1 and
+ rank (F[:][:][:]) = 3. They must be equal
+ or have a rank of zero.
+ F[:][5][10] + E[:] * 5 + *Y 1
+
+ int func (int);
+ func (A[:]) 1
+ func (B[:][:][:][:]) 4
+
+ int func2 (int, int)
+ func2 (A[:], B[:][:][:][:]) RANKMISMATCH-ERROR -- Since Rank (A[:]) = 1
+ and Rank (B[:][:][:][:]) = 4
+
+ A[:] + func (B[:][:][:][:]) RANKMISMATCH-ERROR
+ func2 (A[:], B[:]) + func (A) 1
+
+ */
+
+bool
+find_rank (location_t loc, tree orig_expr, tree expr, bool ignore_builtin_fn,
+ size_t *rank)
+{
+ tree ii_tree;
+ size_t ii = 0, current_rank = 0;
+
+ if (TREE_CODE (expr) == ARRAY_NOTATION_REF)
+ {
+ ii_tree = expr;
+ while (ii_tree)
+ {
+ if (TREE_CODE (ii_tree) == ARRAY_NOTATION_REF)
+ {
+ current_rank++;
+ ii_tree = ARRAY_NOTATION_ARRAY (ii_tree);
+ }
+ else if (TREE_CODE (ii_tree) == ARRAY_REF)
+ ii_tree = TREE_OPERAND (ii_tree, 0);
+ else if (TREE_CODE (ii_tree) == PARM_DECL
+ || TREE_CODE (ii_tree) == VAR_DECL)
+ break;
+ }
+ if (*rank == 0)
+ /* In this case, all the expressions this function has encountered thus
+ far have been scalars or expressions with zero rank. Please see
+ header comment for examples of such expression. */
+ *rank = current_rank;
+ else if (*rank != current_rank)
+ {
+ /* In this case, find rank is being recursed through a set of
+ expression of the form A <OPERATION> B, where A and B both have
+ array notations in them and the rank of A is not equal to rank of
+ B.
+ A simple example of such case is the following: X[:] + Y[:][:] */
+ *rank = current_rank;
+ return false;
+ }
+ }
+ else if (TREE_CODE (expr) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator ii_tsi;
+ for (ii_tsi = tsi_start (expr); !tsi_end_p (ii_tsi);
+ tsi_next (&ii_tsi))
+ if (!find_rank (loc, orig_expr, *tsi_stmt_ptr (ii_tsi),
+ ignore_builtin_fn, rank))
+ return false;
+ }
+ else
+ {
+ if (TREE_CODE (expr) == CALL_EXPR)
+ {
+ tree func_name = CALL_EXPR_FN (expr);
+ tree prev_arg = NULL_TREE, arg;
+ call_expr_arg_iterator iter;
+ size_t prev_rank = 0;
+ if (TREE_CODE (func_name) == ADDR_EXPR)
+ if (!ignore_builtin_fn)
+ if (is_cilkplus_reduce_builtin (func_name))
+ /* If it is a built-in function, then we know it returns a
+ scalar. */
+ return true;
+ FOR_EACH_CALL_EXPR_ARG (arg, iter, expr)
+ {
+ if (!find_rank (loc, orig_expr, arg, ignore_builtin_fn, rank))
+ {
+ if (prev_arg && EXPR_HAS_LOCATION (prev_arg)
+ && prev_rank != *rank)
+ error_at (EXPR_LOCATION (prev_arg),
+ "rank mismatch between %qE and %qE", prev_arg,
+ arg);
+ else if (prev_arg && prev_rank != *rank)
+ /* Here the original expression is printed as a "heads-up"
+ to the programmer. This is because since there is no
+ location information for the offending argument, the
+ error could be in some internally generated code that is
+ not visible for the programmer. Thus, the correct fix
+ may lie in the original expression. */
+ error_at (loc, "rank mismatch in expression %qE",
+ orig_expr);
+ return false;
+ }
+ prev_arg = arg;
+ prev_rank = *rank;
+ }
+ }
+ else
+ {
+ tree prev_arg = NULL_TREE;
+ for (ii = 0; ii < TREE_CODE_LENGTH (TREE_CODE (expr)); ii++)
+ {
+ if (TREE_OPERAND (expr, ii)
+ && !find_rank (loc, orig_expr, TREE_OPERAND (expr, ii),
+ ignore_builtin_fn, rank))
+ {
+ if (prev_arg && EXPR_HAS_LOCATION (prev_arg))
+ error_at (EXPR_LOCATION (prev_arg),
+ "rank mismatch between %qE and %qE", prev_arg,
+ TREE_OPERAND (expr, ii));
+ else if (prev_arg)
+ error_at (loc, "rank mismatch in expression %qE",
+ orig_expr);
+ return false;
+ }
+ prev_arg = TREE_OPERAND (expr, ii);
+ }
+ }
+ }
+ return true;
+}
+
+/* Extracts all array notations in NODE and stores them in ARRAY_LIST. If
+ IGNORE_BUILTIN_FN is set, then array notations inside array notation
+ specific built-in functions are ignored. The NODE can be constants,
+ VAR_DECL, PARM_DECLS, STATEMENT_LISTS or full expressions. */
+
+static void
+extract_array_notation_exprs (tree node, bool ignore_builtin_fn,
+ vec<tree, va_gc> **array_list)
+{
+ size_t ii = 0;
+ if (TREE_CODE (node) == ARRAY_NOTATION_REF)
+ {
+ vec_safe_push (*array_list, node);
+ return;
+ }
+ else if (TREE_CODE (node) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator ii_tsi;
+ for (ii_tsi = tsi_start (node); !tsi_end_p (ii_tsi); tsi_next (&ii_tsi))
+ extract_array_notation_exprs (*tsi_stmt_ptr (ii_tsi),
+ ignore_builtin_fn, array_list);
+ }
+ else if (TREE_CODE (node) == CALL_EXPR)
+ {
+ tree arg;
+ call_expr_arg_iterator iter;
+ if (is_cilkplus_reduce_builtin (CALL_EXPR_FN (node)))
+ {
+ if (ignore_builtin_fn)
+ return;
+ else
+ {
+ vec_safe_push (*array_list, node);
+ return;
+ }
+ }
+ if (is_sec_implicit_index_fn (CALL_EXPR_FN (node)))
+ {
+ vec_safe_push (*array_list, node);
+ return;
+ }
+ FOR_EACH_CALL_EXPR_ARG (arg, iter, node)
+ extract_array_notation_exprs (arg, ignore_builtin_fn, array_list);
+ }
+ else
+ for (ii = 0; ii < TREE_CODE_LENGTH (TREE_CODE (node)); ii++)
+ if (TREE_OPERAND (node, ii))
+ extract_array_notation_exprs (TREE_OPERAND (node, ii),
+ ignore_builtin_fn, array_list);
+ return;
+}
+
+/* LIST contains all the array notations found in *ORIG and ARRAY_OPERAND
+ contains the expanded ARRAY_REF. E.g., if LIST[<some_index>] contains
+ an array_notation expression, then ARRAY_OPERAND[<some_index>] contains its
+ expansion. If *ORIG matches LIST[<some_index>] then *ORIG is set to
+ ARRAY_OPERAND[<some_index>]. This function recursively steps through
+ all the sub-trees of *ORIG, if it is larger than a single
+ ARRAY_NOTATION_REF. */
+
+static void
+replace_array_notations (tree *orig, bool ignore_builtin_fn,
+ vec<tree, va_gc> *list,
+ vec<tree, va_gc> *array_operand)
+{
+ size_t ii = 0;
+ tree node = NULL_TREE, node_replacement = NULL_TREE;
+
+ if (vec_safe_length (list) == 0)
+ return;
+
+ if (TREE_CODE (*orig) == ARRAY_NOTATION_REF)
+ {
+ for (ii = 0; vec_safe_iterate (list, ii, &node); ii++)
+ if (*orig == node)
+ {
+ node_replacement = (*array_operand)[ii];
+ *orig = node_replacement;
+ }
+ }
+ else if (TREE_CODE (*orig) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator ii_tsi;
+ for (ii_tsi = tsi_start (*orig); !tsi_end_p (ii_tsi); tsi_next (&ii_tsi))
+ replace_array_notations (tsi_stmt_ptr (ii_tsi), ignore_builtin_fn, list,
+ array_operand);
+ }
+ else if (TREE_CODE (*orig) == CALL_EXPR)
+ {
+ tree arg;
+ call_expr_arg_iterator iter;
+ if (is_cilkplus_reduce_builtin (CALL_EXPR_FN (*orig)))
+ {
+ if (!ignore_builtin_fn)
+ {
+ for (ii = 0; vec_safe_iterate (list, ii, &node); ii++)
+ if (*orig == node)
+ {
+ node_replacement = (*array_operand)[ii];
+ *orig = node_replacement;
+ }
+ }
+ return;
+ }
+ if (is_sec_implicit_index_fn (CALL_EXPR_FN (*orig)))
+ {
+ for (ii = 0; vec_safe_iterate (list, ii, &node); ii++)
+ if (*orig == node)
+ {
+ node_replacement = (*array_operand)[ii];
+ *orig = node_replacement;
+ }
+ return;
+ }
+ ii = 0;
+ FOR_EACH_CALL_EXPR_ARG (arg, iter, *orig)
+ {
+ replace_array_notations (&arg, ignore_builtin_fn, list,
+ array_operand);
+ CALL_EXPR_ARG (*orig, ii) = arg;
+ ii++;
+ }
+ }
+ else
+ {
+ for (ii = 0; ii < (size_t) TREE_CODE_LENGTH (TREE_CODE (*orig)); ii++)
+ if (TREE_OPERAND (*orig, ii))
+ replace_array_notations (&TREE_OPERAND (*orig, ii), ignore_builtin_fn,
+ list, array_operand);
+ }
+ return;
+}
+
+/* Callback for walk_tree. Find all the scalar expressions in *TP and push
+ them in DATA struct, typecasted to (void *). If *WALK_SUBTREES is set to 0
+ then do not go into the *TP's subtrees. Since this function steps through
+ all the subtrees, *TP and TP can be NULL_TREE and NULL, respectively. The
+ function returns NULL_TREE unconditionally. */
+
+static tree
+find_inv_trees (tree *tp, int *walk_subtrees, void *data)
+{
+ struct inv_list *i_list = (struct inv_list *) data;
+
+ if (!tp || !*tp)
+ return NULL_TREE;
+ if (TREE_CONSTANT (*tp))
+ return NULL_TREE; /* No need to save constant to a variable. */
+ if (TREE_CODE (*tp) != COMPOUND_EXPR && !contains_array_notation_expr (*tp))
+ {
+ vec_safe_push (i_list->list_values, *tp);
+ *walk_subtrees = 0;
+ }
+ else if (TREE_CODE (*tp) == ARRAY_NOTATION_REF
+ || TREE_CODE (*tp) == ARRAY_REF
+ || TREE_CODE (*tp) == CALL_EXPR)
+ /* No need to step through the internals of array notation. */
+ *walk_subtrees = 0;
+ else
+ *walk_subtrees = 1;
+ return NULL_TREE;
+}
+
+/* Callback for walk_tree. Replace all the scalar expressions in *TP with the
+ appropriate replacement stored in the struct *DATA (typecasted to void*).
+ The subtrees are not touched if *WALK_SUBTREES is set to zero. */
+
+static tree
+replace_inv_trees (tree *tp, int *walk_subtrees, void *data)
+{
+ size_t ii = 0;
+ tree t, r;
+ struct inv_list *i_list = (struct inv_list *) data;
+
+ if (vec_safe_length (i_list->list_values))
+ {
+ for (ii = 0; vec_safe_iterate (i_list->list_values, ii, &t); ii++)
+ if (simple_cst_equal (*tp, t) == 1)
+ {
+ vec_safe_iterate (i_list->replacement, ii, &r);
+ gcc_assert (r != NULL_TREE);
+ *tp = r;
+ *walk_subtrees = 0;
+ }
+ }
+ else
+ *walk_subtrees = 0;
+ return NULL_TREE;
+}
+
+/* Replaces all the scalar expressions in *NODE. Returns a STATEMENT_LIST that
+ holds the NODE along with variables that holds the results of the invariant
+ expressions. */
+
+tree
+replace_invariant_exprs (tree *node)
+{
+ size_t ix = 0;
+ tree node_list = NULL_TREE;
+ tree t = NULL_TREE, new_var = NULL_TREE, new_node;
+ struct inv_list data;
+
+ data.list_values = NULL;
+ data.replacement = NULL;
+ walk_tree (node, find_inv_trees, (void *)&data, NULL);
+
+ if (vec_safe_length (data.list_values))
+ {
+ node_list = push_stmt_list ();
+ for (ix = 0; vec_safe_iterate (data.list_values, ix, &t); ix++)
+ {
+ new_var = build_decl (EXPR_LOCATION (t), VAR_DECL, NULL_TREE,
+ TREE_TYPE (t));
+ gcc_assert (new_var != NULL_TREE && new_var != error_mark_node);
+ new_node = build2 (MODIFY_EXPR, TREE_TYPE (t), new_var, t);
+ add_stmt (new_node);
+ vec_safe_push (data.replacement, new_var);
+ }
+ walk_tree (node, replace_inv_trees, (void *)&data, NULL);
+ node_list = pop_stmt_list (node_list);
+ }
+ return node_list;
+}
+
+/* Given a CALL_EXPR to an array notation built-in function in
+ AN_BUILTIN_FN, replace the call with the appropriate loop and
+ computation. Return the computation in *NEW_VAR.
+
+ The return value in *NEW_VAR will always be a scalar. If the
+ built-in is __sec_reduce_mutating, *NEW_VAR is set to NULL_TREE. */
+
+static tree
+fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
+{
+ tree new_var_type = NULL_TREE, func_parm, new_expr, new_yes_expr, new_no_expr;
+ tree array_ind_value = NULL_TREE, new_no_ind, new_yes_ind, new_no_list;
+ tree new_yes_list, new_cond_expr, new_var_init = NULL_TREE;
+ tree new_exp_init = NULL_TREE;
+ vec<tree, va_gc> *array_list = NULL, *array_operand = NULL;
+ size_t list_size = 0, rank = 0, ii = 0, jj = 0;
+ int s_jj = 0;
+ tree **array_ops, *array_var, jj_tree, loop_init, array_op0;
+ tree **array_value, **array_stride, **array_length, **array_start;
+ tree *compare_expr, *expr_incr, *ind_init;
+ tree identity_value = NULL_TREE, call_fn = NULL_TREE, new_call_expr, body;
+ bool **count_down, **array_vector;
+ location_t location = UNKNOWN_LOCATION;
+ tree loop_with_init = alloc_stmt_list ();
+
+ enum built_in_function an_type =
+ is_cilkplus_reduce_builtin (CALL_EXPR_FN (an_builtin_fn));
+ if (an_type == BUILT_IN_NONE)
+ return NULL_TREE;
+
+ if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE
+ || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
+ {
+ call_fn = CALL_EXPR_ARG (an_builtin_fn, 2);
+ while (TREE_CODE (call_fn) == CONVERT_EXPR
+ || TREE_CODE (call_fn) == NOP_EXPR)
+ call_fn = TREE_OPERAND (call_fn, 0);
+ call_fn = TREE_OPERAND (call_fn, 0);
+
+ identity_value = CALL_EXPR_ARG (an_builtin_fn, 0);
+ while (TREE_CODE (identity_value) == CONVERT_EXPR
+ || TREE_CODE (identity_value) == NOP_EXPR)
+ identity_value = TREE_OPERAND (identity_value, 0);
+ func_parm = CALL_EXPR_ARG (an_builtin_fn, 1);
+ }
+ else
+ func_parm = CALL_EXPR_ARG (an_builtin_fn, 0);
+
+ while (TREE_CODE (func_parm) == CONVERT_EXPR
+ || TREE_CODE (func_parm) == EXCESS_PRECISION_EXPR
+ || TREE_CODE (func_parm) == NOP_EXPR)
+ func_parm = TREE_OPERAND (func_parm, 0);
+
+ location = EXPR_LOCATION (an_builtin_fn);
+
+ if (!find_rank (location, an_builtin_fn, an_builtin_fn, true, &rank))
+ return error_mark_node;
+
+ if (rank == 0)
+ return an_builtin_fn;
+ else if (rank > 1
+ && (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
+ || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND))
+ {
+ error_at (location, "__sec_reduce_min_ind or __sec_reduce_max_ind cannot"
+ " have arrays with dimension greater than 1");
+ return error_mark_node;
+ }
+
+ extract_array_notation_exprs (func_parm, true, &array_list);
+ list_size = vec_safe_length (array_list);
+ switch (an_type)
+ {
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ADD:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MUL:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN:
+ new_var_type = TREE_TYPE ((*array_list)[0]);
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO:
+ new_var_type = integer_type_node;
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
+ new_var_type = integer_type_node;
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE:
+ if (call_fn && identity_value)
+ new_var_type = TREE_TYPE ((*array_list)[0]);
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING:
+ new_var_type = NULL_TREE;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ array_ops = XNEWVEC (tree *, list_size);
+ for (ii = 0; ii < list_size; ii++)
+ array_ops[ii] = XNEWVEC (tree, rank);
+
+ array_vector = XNEWVEC (bool *, list_size);
+ for (ii = 0; ii < list_size; ii++)
+ array_vector[ii] = XNEWVEC (bool, rank);
+
+ array_value = XNEWVEC (tree *, list_size);
+ array_stride = XNEWVEC (tree *, list_size);
+ array_length = XNEWVEC (tree *, list_size);
+ array_start = XNEWVEC (tree *, list_size);
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ array_value[ii] = XNEWVEC (tree, rank);
+ array_stride[ii] = XNEWVEC (tree, rank);
+ array_length[ii] = XNEWVEC (tree, rank);
+ array_start[ii] = XNEWVEC (tree, rank);
+ }
+
+ compare_expr = XNEWVEC (tree, rank);
+ expr_incr = XNEWVEC (tree, rank);
+ ind_init = XNEWVEC (tree, rank);
+
+ count_down = XNEWVEC (bool *, list_size);
+ for (ii = 0; ii < list_size; ii++)
+ count_down[ii] = XNEWVEC (bool, rank);
+
+ array_var = XNEWVEC (tree, rank);
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ jj = 0;
+ for (jj_tree = (*array_list)[ii];
+ jj_tree && TREE_CODE (jj_tree) == ARRAY_NOTATION_REF;
+ jj_tree = ARRAY_NOTATION_ARRAY (jj_tree))
+ {
+ array_ops[ii][jj] = jj_tree;
+ jj++;
+ }
+ }
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ tree array_node = (*array_list)[ii];
+ if (TREE_CODE (array_node) == ARRAY_NOTATION_REF)
+ {
+ for (jj = 0; jj < rank; jj++)
+ {
+ if (TREE_CODE (array_ops[ii][jj]) == ARRAY_NOTATION_REF)
+ {
+ array_value[ii][jj] =
+ ARRAY_NOTATION_ARRAY (array_ops[ii][jj]);
+ array_start[ii][jj] =
+ ARRAY_NOTATION_START (array_ops[ii][jj]);
+ array_length[ii][jj] =
+ fold_build1 (CONVERT_EXPR, integer_type_node,
+ ARRAY_NOTATION_LENGTH (array_ops[ii][jj]));
+ array_stride[ii][jj] =
+ fold_build1 (CONVERT_EXPR, integer_type_node,
+ ARRAY_NOTATION_STRIDE (array_ops[ii][jj]));
+ array_vector[ii][jj] = true;
+
+ if (!TREE_CONSTANT (array_length[ii][jj]))
+ count_down[ii][jj] = false;
+ else if (tree_int_cst_lt
+ (array_length[ii][jj],
+ build_int_cst (TREE_TYPE (array_length[ii][jj]),
+ 0)))
+ count_down[ii][jj] = true;
+ else
+ count_down[ii][jj] = false;
+ }
+ else
+ array_vector[ii][jj] = false;
+ }
+ }
+ }
+
+ loop_init = alloc_stmt_list ();
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ array_var[ii] = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ ind_init[ii] =
+ build_modify_expr (location, array_var[ii],
+ TREE_TYPE (array_var[ii]), NOP_EXPR,
+ location,
+ build_int_cst (TREE_TYPE (array_var[ii]), 0),
+ TREE_TYPE (array_var[ii]));
+ }
+ for (ii = 0; ii < list_size; ii++)
+ {
+ if (array_vector[ii][0])
+ {
+ tree array_opr_node = array_value[ii][rank - 1];
+ for (s_jj = rank - 1; s_jj >= 0; s_jj--)
+ {
+ if (count_down[ii][s_jj])
+ {
+ /* Array[start_index - (induction_var * stride)] */
+ array_opr_node = build_array_ref
+ (location, array_opr_node,
+ build2 (MINUS_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_start[ii][s_jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_var[s_jj], array_stride[ii][s_jj])));
+ }
+ else
+ {
+ /* Array[start_index + (induction_var * stride)] */
+ array_opr_node = build_array_ref
+ (location, array_opr_node,
+ build2 (PLUS_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_start[ii][s_jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_var[s_jj], array_stride[ii][s_jj])));
+ }
+ }
+ vec_safe_push (array_operand, array_opr_node);
+ }
+ else
+ /* This is just a dummy node to make sure the list sizes for both
+ array list and array operand list are the same. */
+ vec_safe_push (array_operand, integer_one_node);
+ }
+ replace_array_notations (&func_parm, true, array_list, array_operand);
+ for (ii = 0; ii < rank; ii++)
+ expr_incr[ii] =
+ build2 (MODIFY_EXPR, void_type_node, array_var[ii],
+ build2 (PLUS_EXPR, TREE_TYPE (array_var[ii]), array_var[ii],
+ build_int_cst (TREE_TYPE (array_var[ii]), 1)));
+ for (jj = 0; jj < rank; jj++)
+ {
+ if (rank && expr_incr[jj])
+ {
+ if (count_down[0][jj])
+ compare_expr[jj] =
+ build2 (LT_EXPR, boolean_type_node, array_var[jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[jj]),
+ array_length[0][jj],
+ build_int_cst (TREE_TYPE (array_var[jj]), -1)));
+ else
+ compare_expr[jj] = build2 (LT_EXPR, boolean_type_node,
+ array_var[jj], array_length[0][jj]);
+ }
+ }
+
+ if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
+ {
+ *new_var = build_decl (location, VAR_DECL, NULL_TREE, new_var_type);
+ gcc_assert (*new_var && *new_var != error_mark_node);
+ }
+ else
+ *new_var = NULL_TREE;
+
+ if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
+ || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
+ array_ind_value = build_decl (location, VAR_DECL, NULL_TREE,
+ TREE_TYPE (func_parm));
+ array_op0 = (*array_operand)[0];
+ switch (an_type)
+ {
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ADD:
+ new_var_init = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, build_zero_cst (new_var_type), new_var_type);
+ new_expr = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), PLUS_EXPR,
+ location, func_parm, TREE_TYPE (func_parm));
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MUL:
+ new_var_init = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, build_one_cst (new_var_type), new_var_type);
+ new_expr = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), MULT_EXPR,
+ location, func_parm, TREE_TYPE (func_parm));
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO:
+ new_var_init = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, build_one_cst (new_var_type), new_var_type);
+ /* Initially you assume everything is zero, now if we find a case where
+ it is NOT true, then we set the result to false. Otherwise
+ we just keep the previous value. */
+ new_yes_expr = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, build_zero_cst (TREE_TYPE (*new_var)),
+ TREE_TYPE (*new_var));
+ new_no_expr = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, *new_var, TREE_TYPE (*new_var));
+ new_cond_expr = build2 (NE_EXPR, TREE_TYPE (func_parm), func_parm,
+ build_zero_cst (TREE_TYPE (func_parm)));
+ new_expr = build_conditional_expr
+ (location, new_cond_expr, false, new_yes_expr,
+ TREE_TYPE (new_yes_expr), new_no_expr, TREE_TYPE (new_no_expr));
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO:
+ new_var_init = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, build_one_cst (new_var_type), new_var_type);
+ /* Initially you assume everything is non-zero, now if we find a case
+ where it is NOT true, then we set the result to false. Otherwise
+ we just keep the previous value. */
+ new_yes_expr = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, build_zero_cst (TREE_TYPE (*new_var)),
+ TREE_TYPE (*new_var));
+ new_no_expr = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, *new_var, TREE_TYPE (*new_var));
+ new_cond_expr = build2 (EQ_EXPR, TREE_TYPE (func_parm), func_parm,
+ build_zero_cst (TREE_TYPE (func_parm)));
+ new_expr = build_conditional_expr
+ (location, new_cond_expr, false, new_yes_expr,
+ TREE_TYPE (new_yes_expr), new_no_expr, TREE_TYPE (new_no_expr));
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO:
+ new_var_init = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, build_zero_cst (new_var_type), new_var_type);
+ /* Initially we assume there are NO zeros in the list. When we find
+ a non-zero, we keep the previous value. If we find a zero, we
+ set the value to true. */
+ new_yes_expr = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, build_one_cst (new_var_type), new_var_type);
+ new_no_expr = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, *new_var, TREE_TYPE (*new_var));
+ new_cond_expr = build2 (EQ_EXPR, TREE_TYPE (func_parm), func_parm,
+ build_zero_cst (TREE_TYPE (func_parm)));
+ new_expr = build_conditional_expr
+ (location, new_cond_expr, false, new_yes_expr,
+ TREE_TYPE (new_yes_expr), new_no_expr, TREE_TYPE (new_no_expr));
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO:
+ new_var_init = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, build_zero_cst (new_var_type), new_var_type);
+ /* Initially we assume there are NO non-zeros in the list. When we find
+ a zero, we keep the previous value. If we find a non-zero, we set
+ the value to true. */
+ new_yes_expr = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, build_one_cst (new_var_type), new_var_type);
+ new_no_expr = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, *new_var, TREE_TYPE (*new_var));
+ new_cond_expr = build2 (NE_EXPR, TREE_TYPE (func_parm), func_parm,
+ build_zero_cst (TREE_TYPE (func_parm)));
+ new_expr = build_conditional_expr
+ (location, new_cond_expr, false, new_yes_expr,
+ TREE_TYPE (new_yes_expr), new_no_expr, TREE_TYPE (new_no_expr));
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX:
+ if (TYPE_MIN_VALUE (new_var_type))
+ new_var_init = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, TYPE_MIN_VALUE (new_var_type), new_var_type);
+ else
+ new_var_init = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, func_parm, new_var_type);
+ new_no_expr = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, *new_var, TREE_TYPE (*new_var));
+ new_yes_expr = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, func_parm, TREE_TYPE (*new_var));
+ new_expr = build_conditional_expr
+ (location,
+ build2 (LT_EXPR, TREE_TYPE (*new_var), *new_var, func_parm), false,
+ new_yes_expr, TREE_TYPE (*new_var), new_no_expr, TREE_TYPE (*new_var));
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN:
+ if (TYPE_MAX_VALUE (new_var_type))
+ new_var_init = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, TYPE_MAX_VALUE (new_var_type), new_var_type);
+ else
+ new_var_init = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, func_parm, new_var_type);
+ new_no_expr = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, *new_var, TREE_TYPE (*new_var));
+ new_yes_expr = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, func_parm, TREE_TYPE (*new_var));
+ new_expr = build_conditional_expr
+ (location,
+ build2 (GT_EXPR, TREE_TYPE (*new_var), *new_var, func_parm), false,
+ new_yes_expr, TREE_TYPE (*new_var), new_no_expr, TREE_TYPE (*new_var));
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
+ new_var_init = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, build_zero_cst (new_var_type), new_var_type);
+ new_exp_init = build_modify_expr
+ (location, array_ind_value, TREE_TYPE (array_ind_value),
+ NOP_EXPR, location, func_parm, TREE_TYPE (func_parm));
+ new_no_ind = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, *new_var, TREE_TYPE (*new_var));
+ new_no_expr = build_modify_expr
+ (location, array_ind_value, TREE_TYPE (array_ind_value),
+ NOP_EXPR,
+ location, array_ind_value, TREE_TYPE (array_ind_value));
+ if (list_size > 1)
+ {
+ new_yes_ind = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, array_var[0], TREE_TYPE (array_var[0]));
+ new_yes_expr = build_modify_expr
+ (location, array_ind_value, TREE_TYPE (array_ind_value),
+ NOP_EXPR,
+ location, func_parm, TREE_TYPE ((*array_operand)[0]));
+ }
+ else
+ {
+ new_yes_ind = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, TREE_OPERAND (array_op0, 1),
+ TREE_TYPE (TREE_OPERAND (array_op0, 1)));
+ new_yes_expr = build_modify_expr
+ (location, array_ind_value, TREE_TYPE (array_ind_value),
+ NOP_EXPR,
+ location, func_parm, TREE_OPERAND (array_op0, 1));
+ }
+ new_yes_list = alloc_stmt_list ();
+ append_to_statement_list (new_yes_ind, &new_yes_list);
+ append_to_statement_list (new_yes_expr, &new_yes_list);
+
+ new_no_list = alloc_stmt_list ();
+ append_to_statement_list (new_no_ind, &new_no_list);
+ append_to_statement_list (new_no_expr, &new_no_list);
+
+ new_expr = build_conditional_expr
+ (location,
+ build2 (LE_EXPR, TREE_TYPE (array_ind_value), array_ind_value,
+ func_parm),
+ false,
+ new_yes_list, TREE_TYPE (*new_var), new_no_list, TREE_TYPE (*new_var));
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
+ new_var_init = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, build_zero_cst (new_var_type), new_var_type);
+ new_exp_init = build_modify_expr
+ (location, array_ind_value, TREE_TYPE (array_ind_value),
+ NOP_EXPR, location, func_parm, TREE_TYPE (func_parm));
+ new_no_ind = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, *new_var, TREE_TYPE (*new_var));
+ new_no_expr = build_modify_expr
+ (location, array_ind_value, TREE_TYPE (array_ind_value),
+ NOP_EXPR,
+ location, array_ind_value, TREE_TYPE (array_ind_value));
+ if (list_size > 1)
+ {
+ new_yes_ind = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, array_var[0], TREE_TYPE (array_var[0]));
+ new_yes_expr = build_modify_expr
+ (location, array_ind_value, TREE_TYPE (array_ind_value),
+ NOP_EXPR,
+ location, func_parm, TREE_TYPE (array_op0));
+ }
+ else
+ {
+ new_yes_ind = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, TREE_OPERAND (array_op0, 1),
+ TREE_TYPE (TREE_OPERAND (array_op0, 1)));
+ new_yes_expr = build_modify_expr
+ (location, array_ind_value, TREE_TYPE (array_ind_value),
+ NOP_EXPR,
+ location, func_parm, TREE_OPERAND (array_op0, 1));
+ }
+ new_yes_list = alloc_stmt_list ();
+ append_to_statement_list (new_yes_ind, &new_yes_list);
+ append_to_statement_list (new_yes_expr, &new_yes_list);
+
+ new_no_list = alloc_stmt_list ();
+ append_to_statement_list (new_no_ind, &new_no_list);
+ append_to_statement_list (new_no_expr, &new_no_list);
+
+ new_expr = build_conditional_expr
+ (location,
+ build2 (GE_EXPR, TREE_TYPE (array_ind_value), array_ind_value,
+ func_parm),
+ false,
+ new_yes_list, TREE_TYPE (*new_var), new_no_list, TREE_TYPE (*new_var));
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE:
+ new_var_init = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, identity_value, new_var_type);
+ new_call_expr = build_call_expr (call_fn, 2, *new_var, func_parm);
+ new_expr = build_modify_expr
+ (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ location, new_call_expr, TREE_TYPE (*new_var));
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING:
+ new_expr = build_call_expr (call_fn, 2, identity_value, func_parm);
+ break;
+ default:
+ gcc_unreachable ();
+ break;
+ }
+
+ for (ii = 0; ii < rank; ii++)
+ append_to_statement_list (ind_init [ii], &loop_init);
+
+ if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
+ || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
+ append_to_statement_list (new_exp_init, &loop_init);
+ if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
+ append_to_statement_list (new_var_init, &loop_init);
+
+ append_to_statement_list_force (loop_init, &loop_with_init);
+ body = new_expr;
+ for (ii = 0; ii < rank; ii++)
+ {
+ tree new_loop = push_stmt_list ();
+ c_finish_loop (location, compare_expr[ii], expr_incr[ii], body, NULL_TREE,
+ NULL_TREE, true);
+ body = pop_stmt_list (new_loop);
+ }
+ append_to_statement_list_force (body, &loop_with_init);
+
+ XDELETEVEC (compare_expr);
+ XDELETEVEC (expr_incr);
+ XDELETEVEC (ind_init);
+ XDELETEVEC (array_var);
+ for (ii = 0; ii < list_size; ii++)
+ {
+ XDELETEVEC (count_down[ii]);
+ XDELETEVEC (array_value[ii]);
+ XDELETEVEC (array_stride[ii]);
+ XDELETEVEC (array_length[ii]);
+ XDELETEVEC (array_start[ii]);
+ XDELETEVEC (array_ops[ii]);
+ XDELETEVEC (array_vector[ii]);
+ }
+ XDELETEVEC (count_down);
+ XDELETEVEC (array_value);
+ XDELETEVEC (array_stride);
+ XDELETEVEC (array_length);
+ XDELETEVEC (array_start);
+ XDELETEVEC (array_ops);
+ XDELETEVEC (array_vector);
+
+ return loop_with_init;
+}
+
+/* Returns a loop with ARRAY_REF inside it with an appropriate modify expr.
+ The LHS and/or RHS will be array notation expressions that have a MODIFYCODE
+ Their locations are specified by LHS_LOC, RHS_LOC. The location of the
+ modify expression is location. The original type of LHS and RHS are passed
+ in LHS_ORIGTYPE and RHS_ORIGTYPE. */
+
+tree
+build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
+ enum tree_code modifycode, location_t rhs_loc,
+ tree rhs, tree rhs_origtype)
+{
+ bool **lhs_vector = NULL, **rhs_vector = NULL, found_builtin_fn = false;
+ tree **lhs_array = NULL, **rhs_array = NULL;
+ tree array_expr_lhs = NULL_TREE, array_expr_rhs = NULL_TREE;
+ tree array_expr = NULL_TREE;
+ tree **lhs_value = NULL, **rhs_value = NULL;
+ tree **lhs_stride = NULL, **lhs_length = NULL, **lhs_start = NULL;
+ tree **rhs_stride = NULL, **rhs_length = NULL, **rhs_start = NULL;
+ tree an_init = NULL_TREE, *lhs_var = NULL, *rhs_var = NULL;
+ tree *cond_expr = NULL;
+ tree body, loop_with_init = alloc_stmt_list();
+ tree scalar_mods = NULL_TREE;
+ tree *lhs_expr_incr = NULL, *rhs_expr_incr = NULL;
+ tree *lhs_ind_init = NULL, *rhs_ind_init = NULL;
+ bool **lhs_count_down = NULL, **rhs_count_down = NULL;
+ tree *lhs_compare = NULL, *rhs_compare = NULL;
+ vec<tree, va_gc> *rhs_array_operand = NULL, *lhs_array_operand = NULL;
+ size_t lhs_rank = 0, rhs_rank = 0;
+ size_t ii = 0, jj = 0;
+ int s_jj = 0;
+ tree ii_tree = NULL_TREE, new_modify_expr;
+ vec<tree, va_gc> *lhs_list = NULL, *rhs_list = NULL;
+ tree new_var = NULL_TREE, builtin_loop = NULL_TREE;
+ tree begin_var, lngth_var, strde_var;
+ size_t rhs_list_size = 0, lhs_list_size = 0;
+
+ /* If either of this is true, an error message must have been send out
+ already. Not necessary to send out multiple error messages. */
+ if (lhs == error_mark_node || rhs == error_mark_node)
+ return error_mark_node;
+
+ if (!find_rank (location, rhs, rhs, false, &rhs_rank))
+ return error_mark_node;
+
+ extract_array_notation_exprs (rhs, false, &rhs_list);
+ rhs_list_size = vec_safe_length (rhs_list);
+ an_init = push_stmt_list ();
+ if (rhs_rank)
+ {
+ scalar_mods = replace_invariant_exprs (&rhs);
+ if (scalar_mods)
+ add_stmt (scalar_mods);
+ }
+ for (ii = 0; ii < rhs_list_size; ii++)
+ {
+ tree rhs_node = (*rhs_list)[ii];
+ if (TREE_CODE (rhs_node) == CALL_EXPR)
+ {
+ builtin_loop = fix_builtin_array_notation_fn (rhs_node, &new_var);
+ if (builtin_loop == error_mark_node)
+ {
+ pop_stmt_list (an_init);
+ return error_mark_node;
+ }
+ else if (builtin_loop)
+ {
+ add_stmt (builtin_loop);
+ found_builtin_fn = true;
+ if (new_var)
+ {
+ vec<tree, va_gc> *rhs_sub_list = NULL, *new_var_list = NULL;
+ vec_safe_push (rhs_sub_list, rhs_node);
+ vec_safe_push (new_var_list, new_var);
+ replace_array_notations (&rhs, false, rhs_sub_list,
+ new_var_list);
+ }
+ }
+ }
+ }
+
+ lhs_rank = 0;
+ rhs_rank = 0;
+ if (!find_rank (location, lhs, lhs, true, &lhs_rank))
+ {
+ pop_stmt_list (an_init);
+ return error_mark_node;
+ }
+
+ if (!find_rank (location, rhs, rhs, true, &rhs_rank))
+ {
+ pop_stmt_list (an_init);
+ return error_mark_node;
+ }
+
+ if (lhs_rank == 0 && rhs_rank == 0)
+ {
+ if (found_builtin_fn)
+ {
+ new_modify_expr = build_modify_expr (location, lhs, lhs_origtype,
+ modifycode, rhs_loc, rhs,
+ rhs_origtype);
+ add_stmt (new_modify_expr);
+ pop_stmt_list (an_init);
+ return an_init;
+ }
+ else
+ {
+ pop_stmt_list (an_init);
+ return NULL_TREE;
+ }
+ }
+ rhs_list_size = 0;
+ rhs_list = NULL;
+ extract_array_notation_exprs (rhs, true, &rhs_list);
+ extract_array_notation_exprs (lhs, true, &lhs_list);
+ rhs_list_size = vec_safe_length (rhs_list);
+ lhs_list_size = vec_safe_length (lhs_list);
+
+ if (lhs_rank == 0 && rhs_rank != 0 && TREE_CODE (rhs) != CALL_EXPR)
+ {
+ tree rhs_base = rhs;
+ if (TREE_CODE (rhs_base) == ARRAY_NOTATION_REF)
+ {
+ for (ii = 0; ii < (size_t) rhs_rank; ii++)
+ rhs_base = ARRAY_NOTATION_ARRAY (rhs);
+
+ error_at (location, "%qE cannot be scalar when %qE is not", lhs,
+ rhs_base);
+ return error_mark_node;
+ }
+ else
+ {
+ error_at (location, "%qE cannot be scalar when %qE is not", lhs,
+ rhs_base);
+ return error_mark_node;
+ }
+ }
+ if (lhs_rank != 0 && rhs_rank != 0 && lhs_rank != rhs_rank)
+ {
+ tree lhs_base = lhs;
+ tree rhs_base = rhs;
+
+ for (ii = 0; ii < lhs_rank; ii++)
+ lhs_base = ARRAY_NOTATION_ARRAY (lhs_base);
+
+ while (rhs_base && TREE_CODE (rhs_base) != ARRAY_NOTATION_REF)
+ rhs_base = TREE_OPERAND (rhs_base, 0);
+ for (ii = 0; ii < rhs_rank; ii++)
+ rhs_base = ARRAY_NOTATION_ARRAY (rhs_base);
+
+ error_at (location, "rank mismatch between %qE and %qE", lhs, rhs);
+ pop_stmt_list (an_init);
+ return error_mark_node;
+ }
+
+ /* Here we assign the array notation components to variable so that we can
+ satisfy the exec once rule. */
+ for (ii = 0; ii < lhs_list_size; ii++)
+ {
+ tree array_node = (*lhs_list)[ii];
+ tree array_begin = ARRAY_NOTATION_START (array_node);
+ tree array_lngth = ARRAY_NOTATION_LENGTH (array_node);
+ tree array_strde = ARRAY_NOTATION_STRIDE (array_node);
+
+ if (TREE_CODE (array_begin) != INTEGER_CST)
+ {
+ begin_var = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ add_stmt (build_modify_expr (location, begin_var,
+ TREE_TYPE (begin_var),
+ NOP_EXPR, location, array_begin,
+ TREE_TYPE (array_begin)));
+ ARRAY_NOTATION_START (array_node) = begin_var;
+ }
+
+ if (TREE_CODE (array_lngth) != INTEGER_CST)
+ {
+ lngth_var = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ add_stmt (build_modify_expr (location, lngth_var,
+ TREE_TYPE (lngth_var),
+ NOP_EXPR, location, array_lngth,
+ TREE_TYPE (array_lngth)));
+ ARRAY_NOTATION_LENGTH (array_node) = lngth_var;
+ }
+ if (TREE_CODE (array_strde) != INTEGER_CST)
+ {
+ strde_var = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+
+ add_stmt (build_modify_expr (location, strde_var,
+ TREE_TYPE (strde_var),
+ NOP_EXPR, location, array_strde,
+ TREE_TYPE (array_strde)));
+ ARRAY_NOTATION_STRIDE (array_node) = strde_var;
+ }
+ }
+ for (ii = 0; ii < rhs_list_size; ii++)
+ {
+ tree array_node = (*rhs_list)[ii];
+ if (array_node && TREE_CODE (array_node) == ARRAY_NOTATION_REF)
+ {
+ tree array_begin = ARRAY_NOTATION_START (array_node);
+ tree array_lngth = ARRAY_NOTATION_LENGTH (array_node);
+ tree array_strde = ARRAY_NOTATION_STRIDE (array_node);
+
+ if (TREE_CODE (array_begin) != INTEGER_CST)
+ {
+ begin_var = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ add_stmt (build_modify_expr (location, begin_var,
+ TREE_TYPE (begin_var),
+ NOP_EXPR, location, array_begin,
+ TREE_TYPE (array_begin)));
+ ARRAY_NOTATION_START (array_node) = begin_var;
+ }
+ if (TREE_CODE (array_lngth) != INTEGER_CST)
+ {
+ lngth_var = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ add_stmt (build_modify_expr (location, lngth_var,
+ TREE_TYPE (lngth_var),
+ NOP_EXPR, location, array_lngth,
+ TREE_TYPE (array_lngth)));
+ ARRAY_NOTATION_LENGTH (array_node) = lngth_var;
+ }
+ if (TREE_CODE (array_strde) != INTEGER_CST)
+ {
+ strde_var = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+
+ add_stmt (build_modify_expr (location, strde_var,
+ TREE_TYPE (strde_var),
+ NOP_EXPR, location, array_strde,
+ TREE_TYPE (array_strde)));
+ ARRAY_NOTATION_STRIDE (array_node) = strde_var;
+ }
+ }
+ }
+
+ lhs_vector = XNEWVEC (bool *, lhs_list_size);
+ for (ii = 0; ii < lhs_list_size; ii++)
+ lhs_vector[ii] = XNEWVEC (bool, lhs_rank);
+
+ rhs_vector = XNEWVEC (bool *, rhs_list_size);
+ for (ii = 0; ii < rhs_list_size; ii++)
+ rhs_vector[ii] = XNEWVEC (bool, rhs_rank);
+
+ lhs_array = XNEWVEC (tree *, lhs_list_size);
+ for (ii = 0; ii < lhs_list_size; ii++)
+ lhs_array[ii] = XNEWVEC (tree, lhs_rank);
+
+ rhs_array = XNEWVEC (tree *, rhs_list_size);
+ for (ii = 0; ii < rhs_list_size; ii++)
+ rhs_array[ii] = XNEWVEC (tree, rhs_rank);
+
+ lhs_value = XNEWVEC (tree *, lhs_list_size);
+ for (ii = 0; ii < lhs_list_size; ii++)
+ lhs_value[ii] = XNEWVEC (tree, lhs_rank);
+
+ rhs_value = XNEWVEC (tree *, rhs_list_size);
+ for (ii = 0; ii < rhs_list_size; ii++)
+ rhs_value[ii] = XNEWVEC (tree, rhs_rank);
+
+ lhs_stride = XNEWVEC (tree *, lhs_list_size);
+ for (ii = 0; ii < lhs_list_size; ii++)
+ lhs_stride[ii] = XNEWVEC (tree, lhs_rank);
+
+ rhs_stride = XNEWVEC (tree *, rhs_list_size);
+ for (ii = 0; ii < rhs_list_size; ii++)
+ rhs_stride[ii] = XNEWVEC (tree, rhs_rank);
+
+ lhs_length = XNEWVEC (tree *, lhs_list_size);
+ for (ii = 0; ii < lhs_list_size; ii++)
+ lhs_length[ii] = XNEWVEC (tree, lhs_rank);
+
+ rhs_length = XNEWVEC (tree *, rhs_list_size);
+ for (ii = 0; ii < rhs_list_size; ii++)
+ rhs_length[ii] = XNEWVEC (tree, rhs_rank);
+
+ lhs_start = XNEWVEC (tree *, lhs_list_size);
+ for (ii = 0; ii < lhs_list_size; ii++)
+ lhs_start[ii] = XNEWVEC (tree, lhs_rank);
+
+ rhs_start = XNEWVEC (tree *, rhs_list_size);
+ for (ii = 0; ii < rhs_list_size; ii++)
+ rhs_start[ii] = XNEWVEC (tree, rhs_rank);
+
+ lhs_var = XNEWVEC (tree, lhs_rank);
+ rhs_var = XNEWVEC (tree, rhs_rank);
+ cond_expr = XNEWVEC (tree, MAX (lhs_rank, rhs_rank));
+
+ lhs_expr_incr = XNEWVEC (tree, lhs_rank);
+ rhs_expr_incr =XNEWVEC (tree, rhs_rank);
+
+ lhs_ind_init = XNEWVEC (tree, lhs_rank);
+ rhs_ind_init = XNEWVEC (tree, rhs_rank);
+
+ lhs_count_down = XNEWVEC (bool *, lhs_list_size);
+ for (ii = 0; ii < lhs_list_size; ii++)
+ lhs_count_down[ii] = XNEWVEC (bool, lhs_rank);
+
+ rhs_count_down = XNEWVEC (bool *, rhs_list_size);
+ for (ii = 0; ii < rhs_list_size; ii++)
+ rhs_count_down[ii] = XNEWVEC (bool, rhs_rank);
+
+ lhs_compare = XNEWVEC (tree, lhs_rank);
+ rhs_compare = XNEWVEC (tree, rhs_rank);
+
+ if (lhs_rank)
+ {
+ for (ii = 0; ii < lhs_list_size; ii++)
+ {
+ jj = 0;
+ ii_tree = (*lhs_list)[ii];
+ while (ii_tree)
+ {
+ if (TREE_CODE (ii_tree) == ARRAY_NOTATION_REF)
+ {
+ lhs_array[ii][jj] = ii_tree;
+ jj++;
+ ii_tree = ARRAY_NOTATION_ARRAY (ii_tree);
+ }
+ else if (TREE_CODE (ii_tree) == ARRAY_REF)
+ ii_tree = TREE_OPERAND (ii_tree, 0);
+ else if (TREE_CODE (ii_tree) == VAR_DECL
+ || TREE_CODE (ii_tree) == PARM_DECL)
+ break;
+ }
+ }
+ }
+ else
+ lhs_array[0][0] = NULL_TREE;
+
+ if (rhs_rank)
+ {
+ for (ii = 0; ii < rhs_list_size; ii++)
+ {
+ jj = 0;
+ ii_tree = (*rhs_list)[ii];
+ while (ii_tree)
+ {
+ if (TREE_CODE (ii_tree) == ARRAY_NOTATION_REF)
+ {
+ rhs_array[ii][jj] = ii_tree;
+ jj++;
+ ii_tree = ARRAY_NOTATION_ARRAY (ii_tree);
+ }
+ else if (TREE_CODE (ii_tree) == ARRAY_REF)
+ ii_tree = TREE_OPERAND (ii_tree, 0);
+ else if (TREE_CODE (ii_tree) == VAR_DECL
+ || TREE_CODE (ii_tree) == PARM_DECL
+ || TREE_CODE (ii_tree) == CALL_EXPR)
+ break;
+ }
+ }
+ }
+
+ for (ii = 0; ii < lhs_list_size; ii++)
+ {
+ tree lhs_node = (*lhs_list)[ii];
+ if (TREE_CODE (lhs_node) == ARRAY_NOTATION_REF)
+ {
+ for (jj = 0; jj < lhs_rank; jj++)
+ {
+ if (TREE_CODE (lhs_array[ii][jj]) == ARRAY_NOTATION_REF)
+ {
+ lhs_value[ii][jj] = ARRAY_NOTATION_ARRAY (lhs_array[ii][jj]);
+ lhs_start[ii][jj] = ARRAY_NOTATION_START (lhs_array[ii][jj]);
+ lhs_length[ii][jj] =
+ fold_build1 (CONVERT_EXPR, integer_type_node,
+ ARRAY_NOTATION_LENGTH (lhs_array[ii][jj]));
+ lhs_stride[ii][jj] =
+ fold_build1 (CONVERT_EXPR, integer_type_node,
+ ARRAY_NOTATION_STRIDE (lhs_array[ii][jj]));
+ lhs_vector[ii][jj] = true;
+ /* IF the stride value is variable (i.e. not constant) then
+ assume that the length is positive. */
+ if (!TREE_CONSTANT (lhs_length[ii][jj]))
+ lhs_count_down[ii][jj] = false;
+ else if (tree_int_cst_lt
+ (lhs_length[ii][jj],
+ build_zero_cst (TREE_TYPE (lhs_length[ii][jj]))))
+ lhs_count_down[ii][jj] = true;
+ else
+ lhs_count_down[ii][jj] = false;
+ }
+ else
+ lhs_vector[ii][jj] = false;
+ }
+ }
+ }
+ for (ii = 0; ii < rhs_list_size; ii++)
+ {
+ if (TREE_CODE ((*rhs_list)[ii]) == ARRAY_NOTATION_REF)
+ {
+ for (jj = 0; jj < rhs_rank; jj++)
+ {
+ if (TREE_CODE (rhs_array[ii][jj]) == ARRAY_NOTATION_REF)
+ {
+ rhs_value[ii][jj] = ARRAY_NOTATION_ARRAY (rhs_array[ii][jj]);
+ rhs_start[ii][jj] = ARRAY_NOTATION_START (rhs_array[ii][jj]);
+ rhs_length[ii][jj] =
+ fold_build1 (CONVERT_EXPR, integer_type_node,
+ ARRAY_NOTATION_LENGTH (rhs_array[ii][jj]));
+ rhs_stride[ii][jj] =
+ fold_build1 (CONVERT_EXPR, integer_type_node,
+ ARRAY_NOTATION_STRIDE (rhs_array[ii][jj]));
+ rhs_vector[ii][jj] = true;
+ /* If the stride value is variable (i.e. not constant) then
+ assume that the length is positive. */
+ if (!TREE_CONSTANT (rhs_length[ii][jj]))
+ rhs_count_down[ii][jj] = false;
+ else if (tree_int_cst_lt
+ (rhs_length[ii][jj],
+ build_int_cst (TREE_TYPE (rhs_length[ii][jj]), 0)))
+ rhs_count_down[ii][jj] = true;
+ else
+ rhs_count_down[ii][jj] = false;
+ }
+ else
+ rhs_vector[ii][jj] = false;
+ }
+ }
+ else
+ for (jj = 0; jj < rhs_rank; jj++)
+ {
+ rhs_vector[ii][jj] = false;
+ rhs_length[ii][jj] = NULL_TREE;
+ }
+ }
+
+ if (length_mismatch_in_expr_p (EXPR_LOCATION (lhs), lhs_length,
+ lhs_list_size, lhs_rank)
+ || length_mismatch_in_expr_p (EXPR_LOCATION (rhs), rhs_length,
+ rhs_list_size, rhs_rank))
+ {
+ pop_stmt_list (an_init);
+ return error_mark_node;
+ }
+
+ if (lhs_list_size > 0 && rhs_list_size > 0 && lhs_rank > 0 && rhs_rank > 0
+ && TREE_CODE (lhs_length[0][0]) == INTEGER_CST
+ && rhs_length[0][0]
+ && TREE_CODE (rhs_length[0][0]) == INTEGER_CST)
+ {
+ HOST_WIDE_INT l_length = int_cst_value (lhs_length[0][0]);
+ HOST_WIDE_INT r_length = int_cst_value (rhs_length[0][0]);
+ /* Length can be negative or positive. As long as the magnitude is OK,
+ then the array notation is valid. */
+ if (absu_hwi (l_length) != absu_hwi (r_length))
+ {
+ error_at (location, "length mismatch between LHS and RHS");
+ pop_stmt_list (an_init);
+ return error_mark_node;
+ }
+ }
+ for (ii = 0; ii < lhs_rank; ii++)
+ {
+ if (lhs_vector[0][ii])
+ {
+ lhs_var[ii] = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ lhs_ind_init[ii] = build_modify_expr
+ (location, lhs_var[ii], TREE_TYPE (lhs_var[ii]),
+ NOP_EXPR,
+ location, build_zero_cst (TREE_TYPE (lhs_var[ii])),
+ TREE_TYPE (lhs_var[ii]));
+ }
+ }
+
+ for (ii = 0; ii < rhs_rank; ii++)
+ {
+ /* When we have a polynomial, we assume that the indices are of type
+ integer. */
+ rhs_var[ii] = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ rhs_ind_init[ii] = build_modify_expr
+ (location, rhs_var[ii], TREE_TYPE (rhs_var[ii]),
+ NOP_EXPR,
+ location, build_int_cst (TREE_TYPE (rhs_var[ii]), 0),
+ TREE_TYPE (rhs_var[ii]));
+ }
+ if (lhs_rank)
+ {
+ for (ii = 0; ii < lhs_list_size; ii++)
+ {
+ if (lhs_vector[ii][0])
+ {
+ /* The last ARRAY_NOTATION element's ARRAY component should be
+ the array's base value. */
+ tree lhs_array_opr = lhs_value[ii][lhs_rank - 1];
+ for (s_jj = lhs_rank - 1; s_jj >= 0; s_jj--)
+ {
+ if (lhs_count_down[ii][s_jj])
+ /* Array[start_index + (induction_var * stride)]. */
+ lhs_array_opr = build_array_ref
+ (location, lhs_array_opr,
+ build2 (MINUS_EXPR, TREE_TYPE (lhs_var[s_jj]),
+ lhs_start[ii][s_jj],
+ build2 (MULT_EXPR, TREE_TYPE (lhs_var[s_jj]),
+ lhs_var[s_jj],
+ lhs_stride[ii][s_jj])));
+ else
+ lhs_array_opr = build_array_ref
+ (location, lhs_array_opr,
+ build2 (PLUS_EXPR, TREE_TYPE (lhs_var[s_jj]),
+ lhs_start[ii][s_jj],
+ build2 (MULT_EXPR, TREE_TYPE (lhs_var[s_jj]),
+ lhs_var[s_jj],
+ lhs_stride[ii][s_jj])));
+ }
+ vec_safe_push (lhs_array_operand, lhs_array_opr);
+ }
+ else
+ vec_safe_push (lhs_array_operand, integer_one_node);
+ }
+ replace_array_notations (&lhs, true, lhs_list, lhs_array_operand);
+ array_expr_lhs = lhs;
+ }
+
+ if (rhs_rank)
+ {
+ for (ii = 0; ii < rhs_list_size; ii++)
+ {
+ if (rhs_vector[ii][0])
+ {
+ tree rhs_array_opr = rhs_value[ii][rhs_rank - 1];
+ for (s_jj = rhs_rank - 1; s_jj >= 0; s_jj--)
+ {
+ if (rhs_count_down[ii][s_jj])
+ /* Array[start_index - (induction_var * stride)] */
+ rhs_array_opr = build_array_ref
+ (location, rhs_array_opr,
+ build2 (MINUS_EXPR, TREE_TYPE (rhs_var[s_jj]),
+ rhs_start[ii][s_jj],
+ build2 (MULT_EXPR, TREE_TYPE (rhs_var[s_jj]),
+ rhs_var[s_jj],
+ rhs_stride[ii][s_jj])));
+ else
+ /* Array[start_index + (induction_var * stride)] */
+ rhs_array_opr = build_array_ref
+ (location, rhs_array_opr,
+ build2 (PLUS_EXPR, TREE_TYPE (rhs_var[s_jj]),
+ rhs_start[ii][s_jj],
+ build2 (MULT_EXPR, TREE_TYPE (rhs_var[s_jj]),
+ rhs_var[s_jj],
+ rhs_stride[ii][s_jj])));
+ }
+ vec_safe_push (rhs_array_operand, rhs_array_opr);
+ }
+ else
+ /* This is just a dummy node to make sure the list sizes for both
+ array list and array operand list are the same. */
+ vec_safe_push (rhs_array_operand, integer_one_node);
+ }
+
+ for (ii = 0; ii < rhs_list_size; ii++)
+ {
+ tree rhs_node = (*rhs_list)[ii];
+ if (TREE_CODE (rhs_node) == CALL_EXPR)
+ {
+ int idx_value = 0;
+ tree func_name = CALL_EXPR_FN (rhs_node);
+ if (TREE_CODE (func_name) == ADDR_EXPR)
+ if (is_sec_implicit_index_fn (func_name))
+ {
+ idx_value =
+ extract_sec_implicit_index_arg (location, rhs_node);
+ if (idx_value == -1) /* This means we have an error. */
+ return error_mark_node;
+ else if (idx_value < (int) lhs_rank && idx_value >= 0)
+ vec_safe_push (rhs_array_operand, lhs_var[idx_value]);
+ else
+ {
+ size_t ee = 0;
+ tree lhs_base = (*lhs_list)[ii];
+ for (ee = 0; ee < lhs_rank; ee++)
+ lhs_base = ARRAY_NOTATION_ARRAY (lhs_base);
+ error_at (location, "__sec_implicit_index argument %d "
+ "must be less than rank of %qD", idx_value,
+ lhs_base);
+ return error_mark_node;
+ }
+ }
+ }
+ }
+ replace_array_notations (&rhs, true, rhs_list, rhs_array_operand);
+ array_expr_rhs = rhs;
+ }
+ else
+ {
+ for (ii = 0; ii < rhs_list_size; ii++)
+ {
+ tree rhs_node = (*rhs_list)[ii];
+ if (TREE_CODE (rhs_node) == CALL_EXPR)
+ {
+ int idx_value = 0;
+ tree func_name = CALL_EXPR_FN (rhs_node);
+ if (TREE_CODE (func_name) == ADDR_EXPR)
+ if (is_sec_implicit_index_fn (func_name))
+ {
+ idx_value =
+ extract_sec_implicit_index_arg (location, rhs_node);
+ if (idx_value == -1) /* This means we have an error. */
+ return error_mark_node;
+ else if (idx_value < (int) lhs_rank && idx_value >= 0)
+ vec_safe_push (rhs_array_operand, lhs_var[idx_value]);
+ else
+ {
+ size_t ee = 0;
+ tree lhs_base = (*lhs_list)[ii];
+ for (ee = 0; ee < lhs_rank; ee++)
+ lhs_base = ARRAY_NOTATION_ARRAY (lhs_base);
+ error_at (location, "__sec_implicit_index argument %d "
+ "must be less than rank of %qD", idx_value,
+ lhs_base);
+ return error_mark_node;
+ }
+ }
+ }
+ }
+ replace_array_notations (&rhs, true, rhs_list, rhs_array_operand);
+ array_expr_rhs = rhs;
+ rhs_expr_incr[0] = NULL_TREE;
+ }
+
+ for (ii = 0; ii < rhs_rank; ii++)
+ rhs_expr_incr[ii] = build2 (MODIFY_EXPR, void_type_node, rhs_var[ii],
+ build2
+ (PLUS_EXPR, TREE_TYPE (rhs_var[ii]),
+ rhs_var[ii],
+ build_one_cst (TREE_TYPE (rhs_var[ii]))));
+
+ for (ii = 0; ii < lhs_rank; ii++)
+ lhs_expr_incr[ii] = build2
+ (MODIFY_EXPR, void_type_node, lhs_var[ii],
+ build2 (PLUS_EXPR, TREE_TYPE (lhs_var[ii]), lhs_var[ii],
+ build_one_cst (TREE_TYPE (lhs_var[ii]))));
+
+ /* If array_expr_lhs is NULL, then we have function that returns void or
+ its return value is ignored. */
+ if (!array_expr_lhs)
+ array_expr_lhs = lhs;
+
+ array_expr = build_modify_expr (location, array_expr_lhs, lhs_origtype,
+ modifycode, rhs_loc, array_expr_rhs,
+ rhs_origtype);
+
+ for (jj = 0; jj < MAX (lhs_rank, rhs_rank); jj++)
+ {
+ if (rhs_rank && rhs_expr_incr[jj])
+ {
+ size_t iii = 0;
+ if (lhs_rank == 0)
+ lhs_compare[jj] = integer_one_node;
+ else if (lhs_count_down[0][jj])
+ lhs_compare[jj] = build2
+ (GT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
+ else
+ lhs_compare[jj] = build2
+ (LT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
+
+
+ /* The reason why we have this here is for the following case:
+ Array[:][:] = function_call(something) + Array2[:][:];
+
+ So, we will skip the first operand of RHS and then go to the
+ 2nd to find whether we should count up or down. */
+
+ for (iii = 0; iii < rhs_list_size; iii++)
+ if (rhs_vector[iii][jj])
+ break;
+
+ /* What we are doing here is this:
+ We always count up, so:
+ if (length is negative ==> which means we count down)
+ we multiply length by -1 and count up => ii < -LENGTH
+ else
+ we just count up, so we compare for ii < LENGTH
+ */
+ if (rhs_count_down[iii][jj])
+ /* We use iii for rhs_length because that is the correct countdown
+ we have to use. */
+ rhs_compare[jj] = build2
+ (LT_EXPR, boolean_type_node, rhs_var[jj],
+ build2 (MULT_EXPR, TREE_TYPE (rhs_var[jj]),
+ rhs_length[iii][jj],
+ build_int_cst (TREE_TYPE (rhs_var[jj]), -1)));
+ else
+ rhs_compare[jj] = build2 (LT_EXPR, boolean_type_node, rhs_var[jj],
+ rhs_length[iii][jj]);
+ if (lhs_compare[ii] != integer_one_node)
+ cond_expr[jj] = build2 (TRUTH_ANDIF_EXPR, void_type_node,
+ lhs_compare[jj], rhs_compare[jj]);
+ else
+ cond_expr[jj] = rhs_compare[jj];
+ }
+ else
+ {
+ if (lhs_count_down[0][jj])
+ cond_expr[jj] = build2
+ (GT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
+ else
+ cond_expr[jj] = build2
+ (LT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
+ }
+ }
+
+ an_init = pop_stmt_list (an_init);
+ append_to_statement_list_force (an_init, &loop_with_init);
+ body = array_expr;
+ for (ii = 0; ii < MAX (lhs_rank, rhs_rank); ii++)
+ {
+ tree incr_list = alloc_stmt_list ();
+ tree new_loop = push_stmt_list ();
+ if (lhs_rank)
+ add_stmt (lhs_ind_init[ii]);
+ if (rhs_rank)
+ add_stmt (rhs_ind_init[ii]);
+ if (lhs_rank)
+ append_to_statement_list_force (lhs_expr_incr[ii], &incr_list);
+ if (rhs_rank && rhs_expr_incr[ii])
+ append_to_statement_list_force (rhs_expr_incr[ii], &incr_list);
+ c_finish_loop (location, cond_expr[ii], incr_list, body, NULL_TREE,
+ NULL_TREE, true);
+ body = pop_stmt_list (new_loop);
+ }
+ append_to_statement_list_force (body, &loop_with_init);
+ return loop_with_init;
+}
+
+/* Helper function for fix_conditional_array_notations. Encloses the
+ conditional statement passed in STMT with a loop around it
+ and replaces the condition in STMT with a ARRAY_REF tree-node to the array.
+ The condition must have an ARRAY_NOTATION_REF tree. An expansion of array
+ notation in STMT is returned in a STATEMENT_LIST. */
+
+static tree
+fix_conditional_array_notations_1 (tree stmt)
+{
+ vec<tree, va_gc> *array_list = NULL, *array_operand = NULL;
+ size_t list_size = 0;
+ tree cond = NULL_TREE, builtin_loop = NULL_TREE, new_var = NULL_TREE;
+ size_t rank = 0, ii = 0, jj = 0;
+ int s_jj = 0;
+ tree **array_ops, *array_var, jj_tree, loop_init;
+ tree **array_value, **array_stride, **array_length, **array_start;
+ tree *compare_expr, *expr_incr, *ind_init;
+ bool **count_down, **array_vector;
+ tree begin_var, lngth_var, strde_var;
+ location_t location = EXPR_LOCATION (stmt);
+ tree body = NULL_TREE, loop_with_init = alloc_stmt_list ();
+ if (TREE_CODE (stmt) == COND_EXPR)
+ cond = COND_EXPR_COND (stmt);
+ else if (TREE_CODE (stmt) == SWITCH_EXPR)
+ cond = SWITCH_COND (stmt);
+ else
+ /* Otherwise dont even touch the statement. */
+ return stmt;
+
+ if (!find_rank (location, cond, cond, false, &rank))
+ return error_mark_node;
+
+ extract_array_notation_exprs (stmt, false, &array_list);
+ loop_init = push_stmt_list ();
+ for (ii = 0; ii < vec_safe_length (array_list); ii++)
+ {
+ tree array_node = (*array_list)[ii];
+ if (TREE_CODE (array_node) == CALL_EXPR)
+ {
+ builtin_loop = fix_builtin_array_notation_fn (array_node, &new_var);
+ if (builtin_loop == error_mark_node)
+ {
+ add_stmt (error_mark_node);
+ pop_stmt_list (loop_init);
+ return loop_init;
+ }
+ else if (builtin_loop)
+ {
+ vec <tree, va_gc>* sub_list = NULL, *new_var_list = NULL;
+ vec_safe_push (sub_list, array_node);
+ vec_safe_push (new_var_list, new_var);
+ add_stmt (builtin_loop);
+ replace_array_notations (&stmt, false, sub_list, new_var_list);
+ }
+ }
+ }
+
+ if (!find_rank (location, stmt, stmt, true, &rank))
+ {
+ pop_stmt_list (loop_init);
+ return error_mark_node;
+ }
+ if (rank == 0)
+ {
+ add_stmt (stmt);
+ pop_stmt_list (loop_init);
+ return loop_init;
+ }
+ extract_array_notation_exprs (stmt, true, &array_list);
+
+ if (vec_safe_length (array_list) == 0)
+ return stmt;
+
+ list_size = vec_safe_length (array_list);
+
+ array_ops = XNEWVEC (tree *, list_size);
+ for (ii = 0; ii < list_size; ii++)
+ array_ops[ii] = XNEWVEC (tree, rank);
+
+ array_vector = XNEWVEC (bool *, list_size);
+ for (ii = 0; ii < list_size; ii++)
+ array_vector[ii] = XNEWVEC (bool, rank);
+
+ array_value = XNEWVEC (tree *, list_size);
+ array_stride = XNEWVEC (tree *, list_size);
+ array_length = XNEWVEC (tree *, list_size);
+ array_start = XNEWVEC (tree *, list_size);
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ array_value[ii] = XNEWVEC (tree, rank);
+ array_stride[ii] = XNEWVEC (tree, rank);
+ array_length[ii] = XNEWVEC (tree, rank);
+ array_start[ii] = XNEWVEC (tree, rank);
+ }
+
+ compare_expr = XNEWVEC (tree, rank);
+ expr_incr = XNEWVEC (tree, rank);
+ ind_init = XNEWVEC (tree, rank);
+
+ count_down = XNEWVEC (bool *, list_size);
+ for (ii = 0; ii < list_size; ii++)
+ count_down[ii] = XNEWVEC (bool, rank);
+
+ array_var = XNEWVEC (tree, rank);
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ tree array_node = (*array_list)[ii];
+ if (array_node && TREE_CODE (array_node) == ARRAY_NOTATION_REF)
+ {
+ tree array_begin = ARRAY_NOTATION_START (array_node);
+ tree array_lngth = ARRAY_NOTATION_LENGTH (array_node);
+ tree array_strde = ARRAY_NOTATION_STRIDE (array_node);
+
+ if (TREE_CODE (array_begin) != INTEGER_CST)
+ {
+ begin_var = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ add_stmt (build_modify_expr (location, begin_var,
+ TREE_TYPE (begin_var),
+ NOP_EXPR, location, array_begin,
+ TREE_TYPE (array_begin)));
+ ARRAY_NOTATION_START (array_node) = begin_var;
+ }
+ if (TREE_CODE (array_lngth) != INTEGER_CST)
+ {
+ lngth_var = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ add_stmt (build_modify_expr (location, lngth_var,
+ TREE_TYPE (lngth_var),
+ NOP_EXPR, location, array_lngth,
+ TREE_TYPE (array_lngth)));
+ ARRAY_NOTATION_LENGTH (array_node) = lngth_var;
+ }
+ if (TREE_CODE (array_strde) != INTEGER_CST)
+ {
+ strde_var = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ add_stmt (build_modify_expr (location, strde_var,
+ TREE_TYPE (strde_var),
+ NOP_EXPR, location, array_strde,
+ TREE_TYPE (array_strde)));
+ ARRAY_NOTATION_STRIDE (array_node) = strde_var;
+ }
+ }
+ }
+ for (ii = 0; ii < list_size; ii++)
+ {
+ tree array_node = (*array_list)[ii];
+ jj = 0;
+ for (jj_tree = array_node;
+ jj_tree && TREE_CODE (jj_tree) == ARRAY_NOTATION_REF;
+ jj_tree = ARRAY_NOTATION_ARRAY (jj_tree))
+ {
+ array_ops[ii][jj] = jj_tree;
+ jj++;
+ }
+ }
+ for (ii = 0; ii < list_size; ii++)
+ {
+ tree array_node = (*array_list)[ii];
+ if (TREE_CODE (array_node) == ARRAY_NOTATION_REF)
+ {
+ for (jj = 0; jj < rank; jj++)
+ {
+ if (TREE_CODE (array_ops[ii][jj]) == ARRAY_NOTATION_REF)
+ {
+ array_value[ii][jj] =
+ ARRAY_NOTATION_ARRAY (array_ops[ii][jj]);
+ array_start[ii][jj] =
+ ARRAY_NOTATION_START (array_ops[ii][jj]);
+ array_length[ii][jj] =
+ fold_build1 (CONVERT_EXPR, integer_type_node,
+ ARRAY_NOTATION_LENGTH (array_ops[ii][jj]));
+ array_stride[ii][jj] =
+ fold_build1 (CONVERT_EXPR, integer_type_node,
+ ARRAY_NOTATION_STRIDE (array_ops[ii][jj]));
+ array_vector[ii][jj] = true;
+
+ if (!TREE_CONSTANT (array_length[ii][jj]))
+ count_down[ii][jj] = false;
+ else if (tree_int_cst_lt
+ (array_length[ii][jj],
+ build_int_cst (TREE_TYPE (array_length[ii][jj]),
+ 0)))
+ count_down[ii][jj] = true;
+ else
+ count_down[ii][jj] = false;
+ }
+ else
+ array_vector[ii][jj] = false;
+ }
+ }
+ }
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ array_var[ii] = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ ind_init[ii] =
+ build_modify_expr (location, array_var[ii],
+ TREE_TYPE (array_var[ii]), NOP_EXPR,
+ location,
+ build_int_cst (TREE_TYPE (array_var[ii]), 0),
+ TREE_TYPE (array_var[ii]));
+ }
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ if (array_vector[ii][0])
+ {
+ tree array_opr = array_value[ii][rank - 1];
+ for (s_jj = rank - 1; s_jj >= 0; s_jj--)
+ {
+ if (count_down[ii][s_jj])
+ /* Array[start_index - (induction_var * stride)] */
+ array_opr = build_array_ref
+ (location, array_opr,
+ build2 (MINUS_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_start[ii][s_jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_var[s_jj], array_stride[ii][s_jj])));
+ else
+ /* Array[start_index + (induction_var * stride)] */
+ array_opr = build_array_ref
+ (location, array_opr,
+ build2 (PLUS_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_start[ii][s_jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_var[s_jj], array_stride[ii][s_jj])));
+ }
+ vec_safe_push (array_operand, array_opr);
+ }
+ else
+ /* This is just a dummy node to make sure the list sizes for both
+ array list and array operand list are the same. */
+ vec_safe_push (array_operand, integer_one_node);
+ }
+ replace_array_notations (&stmt, true, array_list, array_operand);
+ for (ii = 0; ii < rank; ii++)
+ expr_incr[ii] = build2 (MODIFY_EXPR, void_type_node, array_var[ii],
+ build2 (PLUS_EXPR, TREE_TYPE (array_var[ii]),
+ array_var[ii],
+ build_int_cst (TREE_TYPE (array_var[ii]),
+ 1)));
+ for (jj = 0; jj < rank; jj++)
+ {
+ if (rank && expr_incr[jj])
+ {
+ if (count_down[0][jj])
+ compare_expr[jj] =
+ build2 (LT_EXPR, boolean_type_node, array_var[jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[jj]),
+ array_length[0][jj],
+ build_int_cst (TREE_TYPE (array_var[jj]), -1)));
+ else
+ compare_expr[jj] = build2 (LT_EXPR, boolean_type_node,
+ array_var[jj], array_length[0][jj]);
+ }
+ }
+
+ loop_init = pop_stmt_list (loop_init);
+ body = stmt;
+ append_to_statement_list_force (loop_init, &loop_with_init);
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ tree new_loop = push_stmt_list ();
+ add_stmt (ind_init[ii]);
+ c_finish_loop (location, compare_expr[ii], expr_incr[ii], body, NULL_TREE,
+ NULL_TREE, true);
+ body = pop_stmt_list (new_loop);
+ }
+ append_to_statement_list_force (body, &loop_with_init);
+ XDELETEVEC (expr_incr);
+ XDELETEVEC (ind_init);
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ XDELETEVEC (count_down[ii]);
+ XDELETEVEC (array_value[ii]);
+ XDELETEVEC (array_stride[ii]);
+ XDELETEVEC (array_length[ii]);
+ XDELETEVEC (array_start[ii]);
+ XDELETEVEC (array_ops[ii]);
+ XDELETEVEC (array_vector[ii]);
+ }
+
+ XDELETEVEC (count_down);
+ XDELETEVEC (array_value);
+ XDELETEVEC (array_stride);
+ XDELETEVEC (array_length);
+ XDELETEVEC (array_start);
+ XDELETEVEC (array_ops);
+ XDELETEVEC (array_vector);
+
+ return loop_with_init;
+}
+
+/* Top-level function to replace ARRAY_NOTATION_REF in a conditional statement
+ in STMT. An expansion of array notation in STMT is returned as a
+ STATEMENT_LIST. */
+
+tree
+fix_conditional_array_notations (tree stmt)
+{
+ if (TREE_CODE (stmt) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator tsi;
+ for (tsi = tsi_start (stmt); !tsi_end_p (tsi); tsi_next (&tsi))
+ {
+ tree single_stmt = *tsi_stmt_ptr (tsi);
+ *tsi_stmt_ptr (tsi) =
+ fix_conditional_array_notations_1 (single_stmt);
+ }
+ return stmt;
+ }
+ else
+ return fix_conditional_array_notations_1 (stmt);
+}
+
+/* Create a struct c_expr that contains a loop with ARRAY_REF expr at location
+ LOCATION with the tree_code CODE and the array notation expr is
+ passed in ARG. Returns the fixed c_expr in ARG itself. */
+
+struct c_expr
+fix_array_notation_expr (location_t location, enum tree_code code,
+ struct c_expr arg)
+{
+
+ vec<tree, va_gc> *array_list = NULL, *array_operand = NULL;
+ size_t list_size = 0, rank = 0, ii = 0, jj = 0;
+ int s_jj = 0;
+ tree **array_ops, *array_var, jj_tree, loop_init;
+ tree **array_value, **array_stride, **array_length, **array_start;
+ tree *compare_expr, *expr_incr, *ind_init;
+ tree body, loop_with_init = alloc_stmt_list ();
+ bool **count_down, **array_vector;
+
+ if (!find_rank (location, arg.value, arg.value, false, &rank))
+ {
+ /* If this function returns a NULL, we convert the tree value in the
+ structure to error_mark_node and the parser should take care of the
+ rest. */
+ arg.value = error_mark_node;
+ return arg;
+ }
+
+ if (rank == 0)
+ return arg;
+
+ extract_array_notation_exprs (arg.value, true, &array_list);
+
+ if (vec_safe_length (array_list) == 0)
+ return arg;
+
+ list_size = vec_safe_length (array_list);
+
+ array_ops = XNEWVEC (tree *, list_size);
+ for (ii = 0; ii < list_size; ii++)
+ array_ops[ii] = XNEWVEC (tree, rank);
+
+ array_vector = XNEWVEC (bool *, list_size);
+ for (ii = 0; ii < list_size; ii++)
+ array_vector[ii] = XNEWVEC (bool, rank);
+
+ array_value = XNEWVEC (tree *, list_size);
+ array_stride = XNEWVEC (tree *, list_size);
+ array_length = XNEWVEC (tree *, list_size);
+ array_start = XNEWVEC (tree *, list_size);
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ array_value[ii] = XNEWVEC (tree, rank);
+ array_stride[ii] = XNEWVEC (tree, rank);
+ array_length[ii] = XNEWVEC (tree, rank);
+ array_start[ii] = XNEWVEC (tree, rank);
+ }
+
+ compare_expr = XNEWVEC (tree, rank);
+ expr_incr = XNEWVEC (tree, rank);
+ ind_init = XNEWVEC (tree, rank);
+
+ count_down = XNEWVEC (bool *, list_size);
+ for (ii = 0; ii < list_size; ii++)
+ count_down[ii] = XNEWVEC (bool, rank);
+ array_var = XNEWVEC (tree, rank);
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ jj = 0;
+ for (jj_tree = (*array_list)[ii];
+ jj_tree && TREE_CODE (jj_tree) == ARRAY_NOTATION_REF;
+ jj_tree = ARRAY_NOTATION_ARRAY (jj_tree))
+ {
+ array_ops[ii][jj] = jj_tree;
+ jj++;
+ }
+ }
+
+ loop_init = push_stmt_list ();
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ tree array_node = (*array_list)[ii];
+ if (TREE_CODE (array_node) == ARRAY_NOTATION_REF)
+ {
+ for (jj = 0; jj < rank; jj++)
+ {
+ if (TREE_CODE (array_ops[ii][jj]) == ARRAY_NOTATION_REF)
+ {
+ array_value[ii][jj] =
+ ARRAY_NOTATION_ARRAY (array_ops[ii][jj]);
+ array_start[ii][jj] =
+ ARRAY_NOTATION_START (array_ops[ii][jj]);
+ array_length[ii][jj] =
+ fold_build1 (CONVERT_EXPR, integer_type_node,
+ ARRAY_NOTATION_LENGTH (array_ops[ii][jj]));
+ array_stride[ii][jj] =
+ fold_build1 (CONVERT_EXPR, integer_type_node,
+ ARRAY_NOTATION_STRIDE (array_ops[ii][jj]));
+ array_vector[ii][jj] = true;
+
+ if (!TREE_CONSTANT (array_length[ii][jj]))
+ count_down[ii][jj] = false;
+ else if (tree_int_cst_lt
+ (array_length[ii][jj],
+ build_int_cst (TREE_TYPE (array_length[ii][jj]),
+ 0)))
+ count_down[ii][jj] = true;
+ else
+ count_down[ii][jj] = false;
+ }
+ else
+ array_vector[ii][jj] = false;
+ }
+ }
+ }
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ array_var[ii] = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ ind_init[ii] =
+ build_modify_expr (location, array_var[ii],
+ TREE_TYPE (array_var[ii]), NOP_EXPR,
+ location,
+ build_int_cst (TREE_TYPE (array_var[ii]), 0),
+ TREE_TYPE (array_var[ii]));
+
+ }
+ for (ii = 0; ii < list_size; ii++)
+ {
+ if (array_vector[ii][0])
+ {
+ tree array_opr = array_value[ii][rank - 1];
+ for (s_jj = rank - 1; s_jj >= 0; s_jj--)
+ {
+ if (count_down[ii][s_jj])
+ /* Array[start_index - (induction_var * stride)] */
+ array_opr = build_array_ref
+ (location, array_opr,
+ build2 (MINUS_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_start[ii][s_jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_var[s_jj], array_stride[ii][s_jj])));
+ else
+ /* Array[start_index + (induction_var * stride)] */
+ array_opr = build_array_ref
+ (location, array_opr,
+ build2 (PLUS_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_start[ii][s_jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_var[s_jj], array_stride[ii][s_jj])));
+ }
+ vec_safe_push (array_operand, array_opr);
+ }
+ else
+ /* This is just a dummy node to make sure the list sizes for both
+ array list and array operand list are the same. */
+ vec_safe_push (array_operand, integer_one_node);
+ }
+ replace_array_notations (&arg.value, true, array_list, array_operand);
+
+ for (ii = 0; ii < rank; ii++)
+ expr_incr[ii] =
+ build2 (MODIFY_EXPR, void_type_node, array_var[ii],
+ build2 (PLUS_EXPR, TREE_TYPE (array_var[ii]), array_var[ii],
+ build_int_cst (TREE_TYPE (array_var[ii]), 1)));
+
+ for (jj = 0; jj < rank; jj++)
+ {
+ if (rank && expr_incr[jj])
+ {
+ if (count_down[0][jj])
+ compare_expr[jj] =
+ build2 (LT_EXPR, boolean_type_node, array_var[jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[jj]),
+ array_length[0][jj],
+ build_int_cst (TREE_TYPE (array_var[jj]), -1)));
+ else
+ compare_expr[jj] = build2 (LT_EXPR, boolean_type_node,
+ array_var[jj], array_length[0][jj]);
+ }
+ }
+
+ if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
+ {
+ arg = default_function_array_read_conversion (location, arg);
+ arg.value = build_unary_op (location, code, arg.value, 0);
+ }
+ else if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
+ {
+ arg = default_function_array_read_conversion (location, arg);
+ arg = parser_build_unary_op (location, code, arg);
+ }
+
+ loop_init = pop_stmt_list (loop_init);
+ append_to_statement_list_force (loop_init, &loop_with_init);
+ body = arg.value;
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ tree new_loop = push_stmt_list ();
+ add_stmt (ind_init[ii]);
+ c_finish_loop (location, compare_expr[ii], expr_incr[ii], body, NULL_TREE,
+ NULL_TREE, true);
+ body = pop_stmt_list (new_loop);
+ }
+ append_to_statement_list_force (body, &loop_with_init);
+ XDELETEVEC (expr_incr);
+ XDELETEVEC (ind_init);
+ XDELETEVEC (array_var);
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ XDELETEVEC (count_down[ii]);
+ XDELETEVEC (array_value[ii]);
+ XDELETEVEC (array_stride[ii]);
+ XDELETEVEC (array_length[ii]);
+ XDELETEVEC (array_start[ii]);
+ XDELETEVEC (array_ops[ii]);
+ XDELETEVEC (array_vector[ii]);
+ }
+
+ XDELETEVEC (count_down);
+ XDELETEVEC (array_value);
+ XDELETEVEC (array_stride);
+ XDELETEVEC (array_length);
+ XDELETEVEC (array_start);
+ XDELETEVEC (array_ops);
+ XDELETEVEC (array_vector);
+
+ arg.value = loop_with_init;
+ return arg;
+}
+
+/* Returns true if EXPR or any of its subtrees contain ARRAY_NOTATION_EXPR
+ node. */
+
+bool
+contains_array_notation_expr (tree expr)
+{
+ vec<tree, va_gc> *array_list = NULL;
+
+ if (!expr)
+ return false;
+ if (TREE_CODE (expr) == FUNCTION_DECL)
+ if (is_cilkplus_reduce_builtin (expr))
+ return true;
+
+ extract_array_notation_exprs (expr, false, &array_list);
+ if (vec_safe_length (array_list) == 0)
+ return false;
+ else
+ return true;
+}
+
+/* Replaces array notations in a void function call arguments in ARG and returns
+ a STATEMENT_LIST. */
+
+static tree
+fix_array_notation_call_expr (tree arg)
+{
+ vec<tree, va_gc> *array_list = NULL, *array_operand = NULL;
+ tree new_var = NULL_TREE;
+ size_t list_size = 0, rank = 0, ii = 0, jj = 0;
+ int s_jj = 0;
+ tree **array_ops, *array_var, jj_tree, loop_init;
+ tree **array_value, **array_stride, **array_length, **array_start;
+ tree body, loop_with_init = alloc_stmt_list ();
+ tree *compare_expr, *expr_incr, *ind_init;
+ bool **count_down, **array_vector;
+ tree begin_var, lngth_var, strde_var;
+ location_t location = UNKNOWN_LOCATION;
+
+ if (TREE_CODE (arg) == CALL_EXPR
+ && is_cilkplus_reduce_builtin (CALL_EXPR_FN (arg)))
+ {
+ loop_init = fix_builtin_array_notation_fn (arg, &new_var);
+ /* We are ignoring the new var because either the user does not want to
+ capture it OR he is using sec_reduce_mutating function. */
+ return loop_init;
+ }
+
+ if (!find_rank (location, arg, arg, false, &rank))
+ return error_mark_node;
+
+ if (rank == 0)
+ return arg;
+
+ extract_array_notation_exprs (arg, true, &array_list);
+ if (vec_safe_length (array_list) == 0)
+ return arg;
+
+ list_size = vec_safe_length (array_list);
+ location = EXPR_LOCATION (arg);
+
+ array_ops = XNEWVEC (tree *, list_size);
+ for (ii = 0; ii < list_size; ii++)
+ array_ops[ii] = XNEWVEC (tree, rank);
+
+ array_vector = XNEWVEC (bool *, list_size);
+ for (ii = 0; ii < list_size; ii++)
+ array_vector[ii] = (bool *) XNEWVEC (bool, rank);
+
+ array_value = XNEWVEC (tree *, list_size);
+ array_stride = XNEWVEC (tree *, list_size);
+ array_length = XNEWVEC (tree *, list_size);
+ array_start = XNEWVEC (tree *, list_size);
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ array_value[ii] = XNEWVEC (tree, rank);
+ array_stride[ii] = XNEWVEC (tree, rank);
+ array_length[ii] = XNEWVEC (tree, rank);
+ array_start[ii] = XNEWVEC (tree, rank);
+ }
+
+ compare_expr = XNEWVEC (tree, rank);
+ expr_incr = XNEWVEC (tree, rank);
+ ind_init = XNEWVEC (tree, rank);
+
+ count_down = XNEWVEC (bool *, list_size);
+ for (ii = 0; ii < list_size; ii++)
+ count_down[ii] = XNEWVEC (bool, rank);
+
+ array_var = XNEWVEC (tree, rank);
+
+ loop_init = push_stmt_list ();
+ for (ii = 0; ii < list_size; ii++)
+ {
+ tree array_node = (*array_list)[ii];
+ if (array_node && TREE_CODE (array_node) == ARRAY_NOTATION_REF)
+ {
+ tree array_begin = ARRAY_NOTATION_START (array_node);
+ tree array_lngth = ARRAY_NOTATION_LENGTH (array_node);
+ tree array_strde = ARRAY_NOTATION_STRIDE (array_node);
+
+ if (TREE_CODE (array_begin) != INTEGER_CST)
+ {
+ begin_var = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ add_stmt (build_modify_expr (location, begin_var,
+ TREE_TYPE (begin_var),
+ NOP_EXPR, location, array_begin,
+ TREE_TYPE (array_begin)));
+ ARRAY_NOTATION_START (array_node) = begin_var;
+ }
+ if (TREE_CODE (array_lngth) != INTEGER_CST)
+ {
+ lngth_var = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ add_stmt (build_modify_expr (location, lngth_var,
+ TREE_TYPE (lngth_var),
+ NOP_EXPR, location, array_lngth,
+ TREE_TYPE (array_lngth)));
+ ARRAY_NOTATION_LENGTH (array_node) = lngth_var;
+ }
+ if (TREE_CODE (array_strde) != INTEGER_CST)
+ {
+ strde_var = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ add_stmt (build_modify_expr (location, strde_var,
+ TREE_TYPE (strde_var),
+ NOP_EXPR, location, array_strde,
+ TREE_TYPE (array_strde)));
+ ARRAY_NOTATION_STRIDE (array_node) = strde_var;
+ }
+ }
+ }
+ for (ii = 0; ii < list_size; ii++)
+ {
+ jj = 0;
+ for (jj_tree = (*array_list)[ii];
+ jj_tree && TREE_CODE (jj_tree) == ARRAY_NOTATION_REF;
+ jj_tree = ARRAY_NOTATION_ARRAY (jj_tree))
+ {
+ array_ops[ii][jj] = jj_tree;
+ jj++;
+ }
+ }
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ tree array_node = (*array_list)[ii];
+ if (TREE_CODE (array_node) == ARRAY_NOTATION_REF)
+ {
+ for (jj = 0; jj < rank; jj++)
+ {
+ if (TREE_CODE (array_ops[ii][jj]) == ARRAY_NOTATION_REF)
+ {
+ array_value[ii][jj] =
+ ARRAY_NOTATION_ARRAY (array_ops[ii][jj]);
+ array_start[ii][jj] =
+ ARRAY_NOTATION_START (array_ops[ii][jj]);
+ array_length[ii][jj] =
+ fold_build1 (CONVERT_EXPR, integer_type_node,
+ ARRAY_NOTATION_LENGTH (array_ops[ii][jj]));
+ array_stride[ii][jj] =
+ fold_build1 (CONVERT_EXPR, integer_type_node,
+ ARRAY_NOTATION_STRIDE (array_ops[ii][jj]));
+ array_vector[ii][jj] = true;
+
+ if (!TREE_CONSTANT (array_length[ii][jj]))
+ count_down[ii][jj] = false;
+ else if (tree_int_cst_lt
+ (array_length[ii][jj],
+ build_int_cst (TREE_TYPE (array_length[ii][jj]),
+ 0)))
+ count_down[ii][jj] = true;
+ else
+ count_down[ii][jj] = false;
+ }
+ else
+ array_vector[ii][jj] = false;
+ }
+ }
+ }
+
+ if (length_mismatch_in_expr_p (location, array_length, list_size, rank))
+ {
+ pop_stmt_list (loop_init);
+ return error_mark_node;
+ }
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ array_var[ii] = build_decl (location, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ ind_init[ii] =
+ build_modify_expr (location, array_var[ii],
+ TREE_TYPE (array_var[ii]), NOP_EXPR,
+ location,
+ build_int_cst (TREE_TYPE (array_var[ii]), 0),
+ TREE_TYPE (array_var[ii]));
+
+ }
+ for (ii = 0; ii < list_size; ii++)
+ {
+ if (array_vector[ii][0])
+ {
+ tree array_opr_node = array_value[ii][rank - 1];
+ for (s_jj = rank - 1; s_jj >= 0; s_jj--)
+ {
+ if (count_down[ii][s_jj])
+ /* Array[start_index - (induction_var * stride)] */
+ array_opr_node = build_array_ref
+ (location, array_opr_node,
+ build2 (MINUS_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_start[ii][s_jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_var[s_jj], array_stride[ii][s_jj])));
+ else
+ /* Array[start_index + (induction_var * stride)] */
+ array_opr_node = build_array_ref
+ (location, array_opr_node,
+ build2 (PLUS_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_start[ii][s_jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
+ array_var[s_jj], array_stride[ii][s_jj])));
+ }
+ vec_safe_push (array_operand, array_opr_node);
+ }
+ else
+ /* This is just a dummy node to make sure the list sizes for both
+ array list and array operand list are the same. */
+ vec_safe_push (array_operand, integer_one_node);
+ }
+ replace_array_notations (&arg, true, array_list, array_operand);
+ for (ii = 0; ii < rank; ii++)
+ expr_incr[ii] =
+ build2 (MODIFY_EXPR, void_type_node, array_var[ii],
+ build2 (PLUS_EXPR, TREE_TYPE (array_var[ii]), array_var[ii],
+ build_int_cst (TREE_TYPE (array_var[ii]), 1)));
+
+ for (jj = 0; jj < rank; jj++)
+ {
+ if (rank && expr_incr[jj])
+ {
+ if (count_down[0][jj])
+ compare_expr[jj] =
+ build2 (LT_EXPR, boolean_type_node, array_var[jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[jj]),
+ array_length[0][jj],
+ build_int_cst (TREE_TYPE (array_var[jj]), -1)));
+ else
+ compare_expr[jj] = build2 (LT_EXPR, boolean_type_node,
+ array_var[jj], array_length[0][jj]);
+ }
+ }
+
+ loop_init = pop_stmt_list (loop_init);
+ append_to_statement_list_force (loop_init, &loop_with_init);
+ body = arg;
+ for (ii = 0; ii < rank; ii++)
+ {
+ tree new_loop = push_stmt_list ();
+ add_stmt (ind_init[ii]);
+ c_finish_loop (location, compare_expr[ii], expr_incr[ii], body, NULL_TREE,
+ NULL_TREE, true);
+ body = pop_stmt_list (new_loop);
+ }
+ append_to_statement_list_force (body, &loop_with_init);
+ XDELETEVEC (compare_expr);
+ XDELETEVEC (expr_incr);
+ XDELETEVEC (ind_init);
+ XDELETEVEC (array_var);
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ XDELETEVEC (count_down[ii]);
+ XDELETEVEC (array_value[ii]);
+ XDELETEVEC (array_stride[ii]);
+ XDELETEVEC (array_length[ii]);
+ XDELETEVEC (array_start[ii]);
+ XDELETEVEC (array_ops[ii]);
+ XDELETEVEC (array_vector[ii]);
+ }
+
+ XDELETEVEC (count_down);
+ XDELETEVEC (array_value);
+ XDELETEVEC (array_stride);
+ XDELETEVEC (array_length);
+ XDELETEVEC (array_start);
+ XDELETEVEC (array_ops);
+ XDELETEVEC (array_vector);
+
+ return loop_with_init;
+}
+
+/* Expands the built-in functions in a return. EXPR is a RETURN_EXPR with
+ a built-in reduction function. This function returns the expansion code for
+ the built-in function. */
+
+static tree
+fix_return_expr (tree expr)
+{
+ tree new_mod_list, new_var, new_mod, retval_expr, retval_type;
+ location_t loc = EXPR_LOCATION (expr);
+
+ new_mod_list = alloc_stmt_list ();
+ retval_expr = TREE_OPERAND (expr, 0);
+ retval_type = TREE_TYPE (TREE_OPERAND (retval_expr, 1));
+ new_var = build_decl (loc, VAR_DECL, NULL_TREE, TREE_TYPE (retval_expr));
+ new_mod = build_array_notation_expr (loc, new_var, TREE_TYPE (new_var),
+ NOP_EXPR, loc,
+ TREE_OPERAND (retval_expr, 1),
+ retval_type);
+ TREE_OPERAND (retval_expr, 1) = new_var;
+ TREE_OPERAND (expr, 0) = retval_expr;
+ append_to_statement_list_force (new_mod, &new_mod_list);
+ append_to_statement_list_force (expr, &new_mod_list);
+ return new_mod_list;
+}
+
+/* Walks through tree node T and find all the call-statements that do not return
+ anything and fix up any array notations they may carry. The return value
+ is the same type as T but with all array notations replaced with appropriate
+ STATEMENT_LISTS. */
+
+tree
+expand_array_notation_exprs (tree t)
+{
+ if (!contains_array_notation_expr (t))
+ return t;
+
+ switch (TREE_CODE (t))
+ {
+ case BIND_EXPR:
+ t = expand_array_notation_exprs (BIND_EXPR_BODY (t));
+ return t;
+ case COND_EXPR:
+ t = fix_conditional_array_notations (t);
+
+ /* After the expansion if they are still a COND_EXPR, we go into its
+ subtrees. */
+ if (TREE_CODE (t) == COND_EXPR)
+ {
+ if (COND_EXPR_THEN (t))
+ COND_EXPR_THEN (t) =
+ expand_array_notation_exprs (COND_EXPR_THEN (t));
+ if (COND_EXPR_ELSE (t))
+ COND_EXPR_ELSE (t) =
+ expand_array_notation_exprs (COND_EXPR_ELSE (t));
+ }
+ else
+ t = expand_array_notation_exprs (t);
+ return t;
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator ii_tsi;
+ for (ii_tsi = tsi_start (t); !tsi_end_p (ii_tsi); tsi_next (&ii_tsi))
+ *tsi_stmt_ptr (ii_tsi) =
+ expand_array_notation_exprs (*tsi_stmt_ptr (ii_tsi));
+ }
+ return t;
+ case MODIFY_EXPR:
+ {
+ location_t loc = EXPR_HAS_LOCATION (t) ? EXPR_LOCATION (t) :
+ UNKNOWN_LOCATION;
+ tree lhs = TREE_OPERAND (t, 0);
+ tree rhs = TREE_OPERAND (t, 1);
+ location_t rhs_loc = EXPR_HAS_LOCATION (rhs) ? EXPR_LOCATION (rhs) :
+ UNKNOWN_LOCATION;
+ t = build_array_notation_expr (loc, lhs, TREE_TYPE (lhs), NOP_EXPR,
+ rhs_loc, rhs, TREE_TYPE (rhs));
+ return t;
+ }
+ case CALL_EXPR:
+ t = fix_array_notation_call_expr (t);
+ return t;
+ case RETURN_EXPR:
+ if (contains_array_notation_expr (t))
+ t = fix_return_expr (t);
+ default:
+ return t;
+ }
+ return t;
+}
+
+/* This handles expression of the form "a[i:j:k]" or "a[:]" or "a[i:j]," which
+ denotes an array notation expression. If a is a variable or a member, then
+ we generate a ARRAY_NOTATION_REF front-end tree and return it.
+ This tree is broken down to ARRAY_REF toward the end of parsing.
+ ARRAY_NOTATION_REF tree holds the START_INDEX, LENGTH, STRIDE and the TYPE
+ of ARRAY_REF. Restrictions on START_INDEX, LENGTH and STRIDE is same as that
+ of the index field passed into ARRAY_REF. The only additional restriction
+ is that, unlike index in ARRAY_REF, stride, length and start_index cannot
+ contain ARRAY_NOTATIONS. */
+
+tree
+build_array_notation_ref (location_t loc, tree array, tree start_index,
+ tree length, tree stride, tree type)
+{
+ tree array_ntn_tree = NULL_TREE;
+ size_t stride_rank = 0, length_rank = 0, start_rank = 0;
+
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (start_index)))
+ {
+ error_at (loc,
+ "start-index of array notation triplet is not an integer");
+ return error_mark_node;
+ }
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (length)))
+ {
+ error_at (loc, "length of array notation triplet is not an integer");
+ return error_mark_node;
+ }
+
+ /* The stride is an optional field. */
+ if (stride && !INTEGRAL_TYPE_P (TREE_TYPE (stride)))
+ {
+ error_at (loc, "stride of array notation triplet is not an integer");
+ return error_mark_node;
+ }
+ if (!stride)
+ {
+ if (TREE_CONSTANT (start_index) && TREE_CONSTANT (length)
+ && tree_int_cst_lt (length, start_index))
+ stride = build_int_cst (TREE_TYPE (start_index), -1);
+ else
+ stride = build_int_cst (TREE_TYPE (start_index), 1);
+ }
+
+ if (!find_rank (loc, start_index, start_index, false, &start_rank))
+ return error_mark_node;
+ if (!find_rank (loc, length, length, false, &length_rank))
+ return error_mark_node;
+ if (!find_rank (loc, stride, stride, false, &stride_rank))
+ return error_mark_node;
+
+ if (start_rank != 0)
+ {
+ error_at (loc, "rank of an array notation triplet's start-index is not "
+ "zero");
+ return error_mark_node;
+ }
+ if (length_rank != 0)
+ {
+ error_at (loc, "rank of an array notation triplet's length is not zero");
+ return error_mark_node;
+ }
+ if (stride_rank != 0)
+ {
+ error_at (loc, "rank of array notation triplet's stride is not zero");
+ return error_mark_node;
+ }
+ array_ntn_tree = build4 (ARRAY_NOTATION_REF, NULL_TREE, NULL_TREE, NULL_TREE,
+ NULL_TREE, NULL_TREE);
+ ARRAY_NOTATION_ARRAY (array_ntn_tree) = array;
+ ARRAY_NOTATION_START (array_ntn_tree) = start_index;
+ ARRAY_NOTATION_LENGTH (array_ntn_tree) = length;
+ ARRAY_NOTATION_STRIDE (array_ntn_tree) = stride;
+ TREE_TYPE (array_ntn_tree) = type;
+
+ return array_ntn_tree;
+}
+
+/* This function will check if OP is a CALL_EXPR that is a built-in array
+ notation function. If so, then we will return its type to be the type of
+ the array notation inside. */
+
+tree
+find_correct_array_notation_type (tree op)
+{
+ tree fn_arg, return_type = NULL_TREE;
+
+ if (op)
+ {
+ return_type = TREE_TYPE (op); /* This is the default case. */
+ if (TREE_CODE (op) == CALL_EXPR)
+ if (is_cilkplus_reduce_builtin (CALL_EXPR_FN (op)))
+ {
+ fn_arg = CALL_EXPR_ARG (op, 0);
+ if (fn_arg)
+ return_type = TREE_TYPE (fn_arg);
+ }
+ }
+ return return_type;
+}
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index f60f1414eb4..d6a500e72b3 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -1216,6 +1216,8 @@ static void c_parser_objc_at_dynamic_declaration (c_parser *);
static bool c_parser_objc_diagnose_bad_element_prefix
(c_parser *, struct c_declspecs *);
+static tree c_parser_array_notation (location_t, c_parser *, tree, tree);
+
/* Parse a translation unit (C90 6.7, C99 6.9).
translation-unit:
@@ -1754,6 +1756,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
= c_parser_peek_token (parser)->location;
fnbody = c_parser_compound_statement (parser);
+ if (flag_enable_cilkplus && contains_array_notation_expr (fnbody))
+ fnbody = expand_array_notation_exprs (fnbody);
if (nested)
{
tree decl = current_function_decl;
@@ -3067,6 +3071,15 @@ c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
dimen = NULL_TREE;
star_seen = false;
}
+ else if (flag_enable_cilkplus
+ && c_parser_next_token_is (parser, CPP_COLON))
+ {
+ dimen = error_mark_node;
+ star_seen = false;
+ error_at (c_parser_peek_token (parser)->location,
+ "array notations cannot be used in declaration");
+ c_parser_consume_token (parser);
+ }
else if (c_parser_next_token_is (parser, CPP_MULT))
{
if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
@@ -3089,6 +3102,14 @@ c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
}
if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
c_parser_consume_token (parser);
+ else if (flag_enable_cilkplus
+ && c_parser_next_token_is (parser, CPP_COLON))
+ {
+ error_at (c_parser_peek_token (parser)->location,
+ "array notations cannot be used in declaration");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
+ return NULL;
+ }
else
{
c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
@@ -4071,6 +4092,10 @@ c_parser_compound_statement (c_parser *parser)
}
stmt = c_begin_compound_stmt (true);
c_parser_compound_statement_nostart (parser);
+
+ /* If the compound stmt contains array notations, then we expand them. */
+ if (flag_enable_cilkplus && contains_array_notation_expr (stmt))
+ stmt = expand_array_notation_exprs (stmt);
return c_end_compound_stmt (brace_loc, stmt, true);
}
@@ -4714,6 +4739,7 @@ c_parser_if_statement (c_parser *parser)
bool first_if = false;
tree first_body, second_body;
bool in_if_block;
+ tree if_stmt;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
c_parser_consume_token (parser);
@@ -4732,7 +4758,12 @@ c_parser_if_statement (c_parser *parser)
else
second_body = NULL_TREE;
c_finish_if_stmt (loc, cond, first_body, second_body, first_if);
- add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
+ if_stmt = c_end_compound_stmt (loc, block, flag_isoc99);
+
+ /* If the if statement contains array notations, then we expand them. */
+ if (flag_enable_cilkplus && contains_array_notation_expr (if_stmt))
+ if_stmt = fix_conditional_array_notations (if_stmt);
+ add_stmt (if_stmt);
}
/* Parse a switch statement (C90 6.6.4, C99 6.8.4).
@@ -4754,6 +4785,13 @@ c_parser_switch_statement (c_parser *parser)
{
switch_cond_loc = c_parser_peek_token (parser)->location;
expr = c_parser_expression (parser).value;
+ if (flag_enable_cilkplus && contains_array_notation_expr (expr))
+ {
+ error_at (switch_cond_loc,
+ "array notations cannot be used as a condition for switch "
+ "statement");
+ expr = error_mark_node;
+ }
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
}
else
@@ -4793,6 +4831,12 @@ c_parser_while_statement (c_parser *parser)
block = c_begin_compound_stmt (flag_isoc99);
loc = c_parser_peek_token (parser)->location;
cond = c_parser_paren_condition (parser);
+ if (flag_enable_cilkplus && contains_array_notation_expr (cond))
+ {
+ error_at (loc, "array notations cannot be used as a condition for while "
+ "statement");
+ cond = error_mark_node;
+ }
save_break = c_break_label;
c_break_label = NULL_TREE;
save_cont = c_cont_label;
@@ -4834,6 +4878,13 @@ c_parser_do_statement (c_parser *parser)
new_cont = c_cont_label;
c_cont_label = save_cont;
cond = c_parser_paren_condition (parser);
+ if (flag_enable_cilkplus && contains_array_notation_expr (cond))
+ {
+ error_at (loc, "array notations cannot be used as a condition for a "
+ "do-while statement");
+ cond = error_mark_node;
+ }
+
if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
c_parser_skip_to_end_of_block_or_statement (parser);
c_finish_loop (loc, cond, NULL, body, new_break, new_cont, false);
@@ -5009,7 +5060,14 @@ c_parser_for_statement (c_parser *parser)
else
{
cond = c_parser_condition (parser);
- c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
+ if (flag_enable_cilkplus && contains_array_notation_expr (cond))
+ {
+ error_at (loc, "array notations cannot be used in a "
+ "condition for a for-loop");
+ cond = error_mark_node;
+ }
+ c_parser_skip_until_found (parser, CPP_SEMICOLON,
+ "expected %<;%>");
}
}
/* Parse the increment expression (the third expression in a
@@ -5388,6 +5446,7 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after)
exp_location = c_parser_peek_token (parser)->location;
rhs = c_parser_expr_no_commas (parser, NULL);
rhs = default_function_array_read_conversion (exp_location, rhs);
+
ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
code, exp_location, rhs.value,
rhs.original_type);
@@ -5870,14 +5929,28 @@ c_parser_unary_expression (c_parser *parser)
c_parser_consume_token (parser);
exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_read_conversion (exp_loc, op);
- return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
+
+ /* If there is array notations in op, we expand them. */
+ if (flag_enable_cilkplus && TREE_CODE (op.value) == ARRAY_NOTATION_REF)
+ return fix_array_notation_expr (exp_loc, PREINCREMENT_EXPR, op);
+ else
+ {
+ op = default_function_array_read_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
+ }
case CPP_MINUS_MINUS:
c_parser_consume_token (parser);
exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_read_conversion (exp_loc, op);
- return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
+
+ /* If there is array notations in op, we expand them. */
+ if (flag_enable_cilkplus && TREE_CODE (op.value) == ARRAY_NOTATION_REF)
+ return fix_array_notation_expr (exp_loc, PREDECREMENT_EXPR, op);
+ else
+ {
+ op = default_function_array_read_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
+ }
case CPP_AND:
c_parser_consume_token (parser);
op = c_parser_cast_expression (parser, NULL);
@@ -6880,10 +6953,36 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
case CPP_OPEN_SQUARE:
/* Array reference. */
c_parser_consume_token (parser);
- idx = c_parser_expression (parser).value;
- c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
- "expected %<]%>");
- expr.value = build_array_ref (op_loc, expr.value, idx);
+ if (flag_enable_cilkplus
+ && c_parser_peek_token (parser)->type == CPP_COLON)
+ /* If we are here, then we have something like this:
+ Array [ : ]
+ */
+ expr.value = c_parser_array_notation (expr_loc, parser, NULL_TREE,
+ expr.value);
+ else
+ {
+ idx = c_parser_expression (parser).value;
+ /* Here we have 3 options:
+ 1. Array [EXPR] -- Normal Array call.
+ 2. Array [EXPR : EXPR] -- Array notation without stride.
+ 3. Array [EXPR : EXPR : EXPR] -- Array notation with stride.
+
+ For 1, we just handle it just like a normal array expression.
+ For 2 and 3 we handle it like we handle array notations. The
+ idx value we have above becomes the initial/start index.
+ */
+ if (flag_enable_cilkplus
+ && c_parser_peek_token (parser)->type == CPP_COLON)
+ expr.value = c_parser_array_notation (expr_loc, parser, idx,
+ expr.value);
+ else
+ {
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
+ "expected %<]%>");
+ expr.value = build_array_ref (op_loc, expr.value, idx);
+ }
+ }
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
break;
@@ -6991,18 +7090,32 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
case CPP_PLUS_PLUS:
/* Postincrement. */
c_parser_consume_token (parser);
- expr = default_function_array_read_conversion (expr_loc, expr);
- expr.value = build_unary_op (op_loc,
- POSTINCREMENT_EXPR, expr.value, 0);
+ /* If the expressions have array notations, we expand them. */
+ if (flag_enable_cilkplus
+ && TREE_CODE (expr.value) == ARRAY_NOTATION_REF)
+ expr = fix_array_notation_expr (expr_loc, POSTINCREMENT_EXPR, expr);
+ else
+ {
+ expr = default_function_array_read_conversion (expr_loc, expr);
+ expr.value = build_unary_op (op_loc,
+ POSTINCREMENT_EXPR, expr.value, 0);
+ }
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
break;
case CPP_MINUS_MINUS:
/* Postdecrement. */
c_parser_consume_token (parser);
- expr = default_function_array_read_conversion (expr_loc, expr);
- expr.value = build_unary_op (op_loc,
- POSTDECREMENT_EXPR, expr.value, 0);
+ /* If the expressions have array notations, we expand them. */
+ if (flag_enable_cilkplus
+ && TREE_CODE (expr.value) == ARRAY_NOTATION_REF)
+ expr = fix_array_notation_expr (expr_loc, POSTDECREMENT_EXPR, expr);
+ else
+ {
+ expr = default_function_array_read_conversion (expr_loc, expr);
+ expr.value = build_unary_op (op_loc,
+ POSTDECREMENT_EXPR, expr.value, 0);
+ }
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
break;
@@ -10888,4 +11001,171 @@ c_parse_file (void)
the_parser = NULL;
}
+/* This function parses Cilk Plus array notation. The starting index is
+ passed in INITIAL_INDEX and the array name is passes in ARRAY_VALUE. The
+ return value of this function is a tree_node called VALUE_TREE of type
+ ARRAY_NOTATION_REF. */
+
+static tree
+c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index,
+ tree array_value)
+{
+ c_token *token = NULL;
+ tree start_index = NULL_TREE, end_index = NULL_TREE, stride = NULL_TREE;
+ tree value_tree = NULL_TREE, type = NULL_TREE, array_type = NULL_TREE;
+ tree array_type_domain = NULL_TREE;
+
+ if (array_value == error_mark_node)
+ {
+ /* No need to continue. If either of these 2 were true, then an error
+ must be emitted already. Thus, no need to emit them twice. */
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
+ return error_mark_node;
+ }
+
+ array_type = TREE_TYPE (array_value);
+ gcc_assert (array_type);
+ type = TREE_TYPE (array_type);
+ token = c_parser_peek_token (parser);
+
+ if (token->type == CPP_EOF)
+ {
+ c_parser_error (parser, "expected %<:%> or numeral");
+ return value_tree;
+ }
+ else if (token->type == CPP_COLON)
+ {
+ if (!initial_index)
+ {
+ /* If we are here, then we have a case like this A[:]. */
+ c_parser_consume_token (parser);
+ if (TREE_CODE (array_type) == POINTER_TYPE)
+ {
+ error_at (loc, "start-index and length fields necessary for "
+ "using array notations in pointers");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
+ return error_mark_node;
+ }
+ if (TREE_CODE (array_type) == FUNCTION_TYPE)
+ {
+ error_at (loc, "array notations cannot be used with function "
+ "type");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
+ return error_mark_node;
+ }
+ if (TREE_CODE (array_type) == ARRAY_TYPE)
+ {
+ tree subtype = TREE_TYPE (array_type);
+ while (subtype && TREE_CODE (subtype) == POINTER_TYPE)
+ {
+ /* Now this could be a function pointer. Find them and
+ give out an error. */
+ subtype = TREE_TYPE (subtype);
+ if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE)
+ {
+ error_at (loc, "array notations cannot be used with "
+ "function pointer arrays");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
+ NULL);
+ return error_mark_node;
+ }
+ }
+ }
+ array_type_domain = TYPE_DOMAIN (array_type);
+
+ if (!array_type_domain)
+ {
+ error_at (loc, "start-index and length fields necessary for "
+ "using array notations in dimensionless arrays");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
+ return error_mark_node;
+ }
+
+ start_index = TYPE_MINVAL (array_type_domain);
+ start_index = fold_build1 (CONVERT_EXPR, ptrdiff_type_node,
+ start_index);
+ if (!TYPE_MAXVAL (array_type_domain)
+ || !TREE_CONSTANT (TYPE_MAXVAL (array_type_domain)))
+ {
+ error_at (loc, "start-index and length fields necessary for "
+ "using array notations in variable-length arrays");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
+ return error_mark_node;
+ }
+ end_index = TYPE_MAXVAL (array_type_domain);
+ end_index = fold_build2 (PLUS_EXPR, TREE_TYPE (end_index),
+ end_index, integer_one_node);
+ end_index = fold_build1 (CONVERT_EXPR, ptrdiff_type_node, end_index);
+ stride = build_int_cst (integer_type_node, 1);
+ stride = fold_build1 (CONVERT_EXPR, ptrdiff_type_node, stride);
+ }
+ else if (initial_index != error_mark_node)
+ {
+ /* If we are here, then there should be 2 possibilities:
+ 1. Array [EXPR : EXPR]
+ 2. Array [EXPR : EXPR : EXPR]
+ */
+ start_index = initial_index;
+
+ if (TREE_CODE (array_type) == FUNCTION_TYPE)
+ {
+ error_at (loc, "array notations cannot be used with function "
+ "type");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
+ return error_mark_node;
+ }
+ if (TREE_CODE (array_type) == ARRAY_TYPE
+ || TREE_CODE (array_type) == POINTER_TYPE)
+ {
+ tree subtype = TREE_TYPE (array_type);
+ while (subtype
+ && (TREE_CODE (subtype) == POINTER_TYPE
+ || TREE_CODE (subtype) == ARRAY_TYPE))
+ {
+ /* Now this could be a function pointer. Find them and
+ give out an error. */
+ subtype = TREE_TYPE (subtype);
+ if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE)
+ {
+ error_at (loc, "array notations cannot be used with "
+ "function pointer arrays");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
+ NULL);
+ return error_mark_node;
+ }
+ }
+ }
+ c_parser_consume_token (parser); /* consume the ':' */
+ end_index = c_parser_expression (parser).value;
+ if (!end_index || end_index == error_mark_node)
+ {
+ c_parser_skip_to_end_of_block_or_statement (parser);
+ return error_mark_node;
+ }
+ if (c_parser_peek_token (parser)->type == CPP_COLON)
+ {
+ c_parser_consume_token (parser);
+ stride = c_parser_expression (parser).value;
+ if (!stride || stride == error_mark_node)
+ {
+ c_parser_skip_to_end_of_block_or_statement (parser);
+ return error_mark_node;
+ }
+ }
+ }
+ else
+ c_parser_error (parser, "expected array notation expression");
+ }
+ else
+ c_parser_error (parser, "expected array notation expression");
+
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
+
+ value_tree = build_array_notation_ref (loc, array_value, start_index,
+ end_index, stride, type);
+ if (value_tree != error_mark_node)
+ SET_EXPR_LOCATION (value_tree, loc);
+ return value_tree;
+}
+
#include "gt-c-c-parser.h"
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index d1a871daa68..c8f673710e6 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -668,4 +668,7 @@ extern void c_write_global_declarations (void);
extern void pedwarn_c90 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
extern void pedwarn_c99 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
+/* In c-array-notation.c */
+enum built_in_function is_cilkplus_reduce_builtin (tree);
+
#endif /* ! GCC_C_TREE_H */
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 79386da59ad..3a923111429 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -2304,6 +2304,17 @@ build_array_ref (location_t loc, tree array, tree index)
|| TREE_TYPE (index) == error_mark_node)
return error_mark_node;
+ if (flag_enable_cilkplus && contains_array_notation_expr (index))
+ {
+ size_t rank = 0;
+ if (!find_rank (loc, index, index, true, &rank))
+ return error_mark_node;
+ if (rank > 1)
+ {
+ error_at (loc, "rank of the array's index is greater than 1");
+ return error_mark_node;
+ }
+ }
if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE
/* Allow vector[index] but not index[vector]. */
@@ -2722,6 +2733,10 @@ build_function_call_vec (location_t loc, tree function,
often rewritten and don't match the original parameter list. */
if (name && !strncmp (IDENTIFIER_POINTER (name), "__atomic_", 9))
origtypes = NULL;
+
+ if (flag_enable_cilkplus
+ && is_cilkplus_reduce_builtin (function))
+ origtypes = NULL;
}
if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE)
function = function_to_pointer_conversion (loc, function);
@@ -2927,6 +2942,8 @@ convert_arguments (tree typelist, vec<tree, va_gc> *values,
break;
}
}
+ if (flag_enable_cilkplus && fundecl && is_cilkplus_reduce_builtin (fundecl))
+ return vec_safe_length (values);
/* Scan the given expressions and types, producing individual
converted arguments. */
@@ -3875,6 +3892,7 @@ lvalue_p (const_tree ref)
case INDIRECT_REF:
case ARRAY_REF:
+ case ARRAY_NOTATION_REF:
case VAR_DECL:
case PARM_DECL:
case RESULT_DECL:
@@ -8640,11 +8658,25 @@ c_finish_return (location_t loc, tree retval, tree origtype)
tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl)), ret_stmt;
bool no_warning = false;
bool npc = false;
+ size_t rank = 0;
if (TREE_THIS_VOLATILE (current_function_decl))
warning_at (loc, 0,
"function declared %<noreturn%> has a %<return%> statement");
+ if (flag_enable_cilkplus && contains_array_notation_expr (retval))
+ {
+ /* Array notations are allowed in a return statement if it is inside a
+ built-in array notation reduction function. */
+ if (!find_rank (loc, retval, retval, false, &rank))
+ return error_mark_node;
+ if (rank >= 1)
+ {
+ error_at (loc, "array notation expression cannot be used as a "
+ "return value");
+ return error_mark_node;
+ }
+ }
if (retval)
{
tree semantic_type = NULL_TREE;
@@ -8936,6 +8968,34 @@ c_finish_if_stmt (location_t if_locus, tree cond, tree then_block,
{
tree stmt;
+ /* If the condition has array notations, then the rank of the then_block and
+ else_block must be either 0 or be equal to the rank of the condition. If
+ the condition does not have array notations then break them up as it is
+ broken up in a normal expression. */
+ if (flag_enable_cilkplus && contains_array_notation_expr (cond))
+ {
+ size_t then_rank = 0, cond_rank = 0, else_rank = 0;
+ if (!find_rank (if_locus, cond, cond, true, &cond_rank))
+ return;
+ if (then_block
+ && !find_rank (if_locus, then_block, then_block, true, &then_rank))
+ return;
+ if (else_block
+ && !find_rank (if_locus, else_block, else_block, true, &else_rank))
+ return;
+ if (cond_rank != then_rank && then_rank != 0)
+ {
+ error_at (if_locus, "rank-mismatch between if-statement%'s condition"
+ " and the then-block");
+ return;
+ }
+ else if (cond_rank != else_rank && else_rank != 0)
+ {
+ error_at (if_locus, "rank-mismatch between if-statement%'s condition"
+ " and the else-block");
+ return;
+ }
+ }
/* Diagnose an ambiguous else if if-then-else is nested inside if-then. */
if (warn_parentheses && nested_if && else_block == NULL)
{
@@ -8987,6 +9047,13 @@ c_finish_loop (location_t start_locus, tree cond, tree incr, tree body,
{
tree entry = NULL, exit = NULL, t;
+ if (flag_enable_cilkplus && contains_array_notation_expr (cond))
+ {
+ error_at (start_locus, "array notation expression cannot be used in a "
+ "loop%'s condition");
+ return;
+ }
+
/* If the condition is zero don't generate a loop construct. */
if (cond && integer_zerop (cond))
{
@@ -9493,8 +9560,18 @@ build_binary_op (location_t location, enum tree_code code,
op1 = default_conversion (op1);
}
- orig_type0 = type0 = TREE_TYPE (op0);
- orig_type1 = type1 = TREE_TYPE (op1);
+ /* When Cilk Plus is enabled and there are array notations inside op0, then
+ we check to see if there are builtin array notation functions. If
+ so, then we take on the type of the array notation inside it. */
+ if (flag_enable_cilkplus && contains_array_notation_expr (op0))
+ orig_type0 = type0 = find_correct_array_notation_type (op0);
+ else
+ orig_type0 = type0 = TREE_TYPE (op0);
+
+ if (flag_enable_cilkplus && contains_array_notation_expr (op1))
+ orig_type1 = type1 = find_correct_array_notation_type (op1);
+ else
+ orig_type1 = type1 = TREE_TYPE (op1);
/* The expression codes of the data types of the arguments tell us
whether the arguments are integers, floating, pointers, etc. */
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 2a2973bc6e4..7bcff203379 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -129,7 +129,7 @@ static GTY(()) struct cgraph_node *free_nodes;
static GTY(()) struct cgraph_edge *free_edges;
/* Did procss_same_body_aliases run? */
-bool same_body_aliases_done;
+bool cpp_implicit_aliases_done;
/* Map a cgraph_node to cgraph_function_version_info using this htab.
The cgraph_function_version_info has a THIS_NODE field that is the
@@ -556,17 +556,18 @@ cgraph_get_create_node (tree decl)
the function body is associated with (not necessarily cgraph_node (DECL). */
struct cgraph_node *
-cgraph_create_function_alias (tree alias, tree decl)
+cgraph_create_function_alias (tree alias, tree target)
{
struct cgraph_node *alias_node;
- gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
+ gcc_assert (TREE_CODE (target) == FUNCTION_DECL
+ || TREE_CODE (target) == IDENTIFIER_NODE);
gcc_assert (TREE_CODE (alias) == FUNCTION_DECL);
alias_node = cgraph_get_create_node (alias);
- gcc_assert (!alias_node->local.finalized);
- alias_node->thunk.alias = decl;
- alias_node->local.finalized = true;
- alias_node->alias = 1;
+ gcc_assert (!alias_node->symbol.definition);
+ alias_node->symbol.alias_target = target;
+ alias_node->symbol.definition = true;
+ alias_node->symbol.alias = true;
return alias_node;
}
@@ -589,10 +590,10 @@ cgraph_same_body_alias (struct cgraph_node *decl_node ATTRIBUTE_UNUSED, tree ali
return NULL;
n = cgraph_create_function_alias (alias, decl);
- n->same_body_alias = true;
- if (same_body_aliases_done)
- ipa_record_reference ((symtab_node)n, (symtab_node)cgraph_get_node (decl),
- IPA_REF_ALIAS, NULL);
+ n->symbol.cpp_implicit_alias = true;
+ if (cpp_implicit_aliases_done)
+ symtab_resolve_alias ((symtab_node)n,
+ (symtab_node)cgraph_get_node (decl));
return n;
}
@@ -613,8 +614,8 @@ cgraph_add_thunk (struct cgraph_node *decl_node ATTRIBUTE_UNUSED,
node = cgraph_get_node (alias);
if (node)
{
- gcc_assert (node->local.finalized);
- gcc_assert (!node->alias);
+ gcc_assert (node->symbol.definition);
+ gcc_assert (!node->symbol.alias);
gcc_assert (!node->thunk.thunk_p);
cgraph_remove_node (node);
}
@@ -629,7 +630,7 @@ cgraph_add_thunk (struct cgraph_node *decl_node ATTRIBUTE_UNUSED,
node->thunk.virtual_offset_p = virtual_offset != NULL;
node->thunk.alias = real_alias;
node->thunk.thunk_p = true;
- node->local.finalized = true;
+ node->symbol.definition = true;
return node;
}
@@ -1325,6 +1326,7 @@ cgraph_remove_node (struct cgraph_node *node)
/* Incremental inlining access removed nodes stored in the postorder list.
*/
node->symbol.force_output = false;
+ node->symbol.forced_by_abi = false;
for (n = node->nested; n; n = n->next_nested)
n->origin = NULL;
node->nested = NULL;
@@ -1384,7 +1386,7 @@ cgraph_remove_node (struct cgraph_node *node)
&& (cgraph_global_info_ready
&& (TREE_ASM_WRITTEN (n->symbol.decl)
|| DECL_EXTERNAL (n->symbol.decl)
- || !n->analyzed
+ || !n->symbol.analyzed
|| n->symbol.in_other_partition))))
cgraph_release_function_body (node);
@@ -1521,8 +1523,6 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
cgraph_availability_names [cgraph_function_body_availability (node)]);
fprintf (f, " Function flags:");
- if (node->analyzed)
- fprintf (f, " analyzed");
if (node->count)
fprintf (f, " executed "HOST_WIDEST_INT_PRINT_DEC"x",
(HOST_WIDEST_INT)node->count);
@@ -1534,16 +1534,12 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
fprintf (f, " process");
if (node->local.local)
fprintf (f, " local");
- if (node->local.finalized)
- fprintf (f, " finalized");
if (node->local.redefined_extern_inline)
fprintf (f, " redefined_extern_inline");
if (node->only_called_at_startup)
fprintf (f, " only_called_at_startup");
if (node->only_called_at_exit)
fprintf (f, " only_called_at_exit");
- else if (node->alias)
- fprintf (f, " alias");
if (node->tm_clone)
fprintf (f, " tm_clone");
@@ -1551,15 +1547,19 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
if (node->thunk.thunk_p)
{
- fprintf (f, " Thunk of %s (asm: %s) fixed offset %i virtual value %i has "
+ fprintf (f, " Thunk");
+ if (node->thunk.alias)
+ fprintf (f, " of %s (asm: %s)",
+ lang_hooks.decl_printable_name (node->thunk.alias, 2),
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->thunk.alias)));
+ fprintf (f, " fixed offset %i virtual value %i has "
"virtual offset %i)\n",
- lang_hooks.decl_printable_name (node->thunk.alias, 2),
- IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->thunk.alias)),
(int)node->thunk.fixed_offset,
(int)node->thunk.virtual_value,
(int)node->thunk.virtual_offset_p);
}
- if (node->alias && node->thunk.alias && DECL_P (node->thunk.alias))
+ if (node->symbol.alias && node->thunk.alias
+ && DECL_P (node->thunk.alias))
{
fprintf (f, " Alias of %s",
lang_hooks.decl_printable_name (node->thunk.alias, 2));
@@ -1676,7 +1676,7 @@ cgraph_function_body_availability (struct cgraph_node *node)
{
enum availability avail;
gcc_assert (cgraph_function_flags_ready);
- if (!node->analyzed)
+ if (!node->symbol.analyzed)
avail = AVAIL_NOT_AVAILABLE;
else if (node->local.local)
avail = AVAIL_LOCAL;
@@ -1713,6 +1713,8 @@ cgraph_node_cannot_be_local_p_1 (struct cgraph_node *node,
{
return !(!node->symbol.force_output
&& ((DECL_COMDAT (node->symbol.decl)
+ && !node->symbol.forced_by_abi
+ && !symtab_used_from_object_file_p ((symtab_node) node)
&& !node->symbol.same_comdat_group)
|| !node->symbol.externally_visible));
}
@@ -1805,6 +1807,7 @@ cgraph_make_node_local_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
symtab_make_decl_local (node->symbol.decl);
node->symbol.externally_visible = false;
+ node->symbol.forced_by_abi = false;
node->local.local = true;
node->symbol.unique_name = (node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
|| node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);
@@ -1983,7 +1986,7 @@ cgraph_propagate_frequency (struct cgraph_node *node)
if (!node->local.local)
return false;
- gcc_assert (node->analyzed);
+ gcc_assert (node->symbol.analyzed);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Processing frequency %s\n", cgraph_node_name (node));
@@ -2086,6 +2089,7 @@ cgraph_can_remove_if_no_direct_calls_and_refs_p (struct cgraph_node *node)
/* Only COMDAT functions can be removed if externally visible. */
if (node->symbol.externally_visible
&& (!DECL_COMDAT (node->symbol.decl)
+ || node->symbol.forced_by_abi
|| symtab_used_from_object_file_p ((symtab_node) node)))
return false;
return true;
@@ -2293,17 +2297,11 @@ verify_edge_corresponds_to_fndecl (struct cgraph_edge *e, tree decl)
return false;
node = cgraph_function_or_thunk_node (node, NULL);
- if ((e->callee->former_clone_of != node->symbol.decl
- && (!node->same_body_alias
- || e->callee->former_clone_of != node->thunk.alias))
+ if (e->callee->former_clone_of != node->symbol.decl
/* IPA-CP sometimes redirect edge to clone and then back to the former
function. This ping-pong has to go, eventually. */
&& (node != cgraph_function_or_thunk_node (e->callee, NULL))
- && !clone_of_p (node, e->callee)
- /* If decl is a same body alias of some other decl, allow e->callee to be
- a clone of a clone of that other decl too. */
- && (!node->same_body_alias
- || !clone_of_p (cgraph_get_node (node->thunk.alias), e->callee)))
+ && !clone_of_p (cgraph_function_or_thunk_node (node, NULL), e->callee))
return true;
else
return false;
@@ -2342,6 +2340,11 @@ verify_cgraph_node (struct cgraph_node *node)
error ("inline clone in same comdat group list");
error_found = true;
}
+ if (!node->symbol.definition && node->local.local)
+ {
+ error ("local symbols must be defined");
+ error_found = true;
+ }
if (node->global.inlined_to && node->symbol.externally_visible)
{
error ("externally visible inline clone");
@@ -2455,7 +2458,7 @@ verify_cgraph_node (struct cgraph_node *node)
error_found = true;
}
- if (node->analyzed && node->alias)
+ if (node->symbol.analyzed && node->symbol.alias)
{
bool ref_found = false;
int i;
@@ -2486,7 +2489,7 @@ verify_cgraph_node (struct cgraph_node *node)
error_found = true;
}
}
- if (node->analyzed && node->thunk.thunk_p)
+ if (node->symbol.analyzed && node->thunk.thunk_p)
{
if (!node->callees)
{
@@ -2504,7 +2507,7 @@ verify_cgraph_node (struct cgraph_node *node)
error_found = true;
}
}
- else if (node->analyzed && gimple_has_body_p (node->symbol.decl)
+ else if (node->symbol.analyzed && gimple_has_body_p (node->symbol.decl)
&& !TREE_ASM_WRITTEN (node->symbol.decl)
&& (!DECL_EXTERNAL (node->symbol.decl) || node->global.inlined_to)
&& !flag_wpa)
@@ -2653,4 +2656,32 @@ cgraph_get_create_real_symbol_node (tree decl)
node->symbol.order);
return node;
}
+
+
+/* Given NODE, walk the alias chain to return the function NODE is alias of.
+ Walk through thunk, too.
+ When AVAILABILITY is non-NULL, get minimal availability in the chain. */
+
+struct cgraph_node *
+cgraph_function_node (struct cgraph_node *node, enum availability *availability)
+{
+ do
+ {
+ node = cgraph_function_or_thunk_node (node, availability);
+ if (node->thunk.thunk_p)
+ {
+ node = node->callees->callee;
+ if (availability)
+ {
+ enum availability a;
+ a = cgraph_function_body_availability (node);
+ if (a < *availability)
+ *availability = a;
+ }
+ node = cgraph_function_or_thunk_node (node, availability);
+ }
+ } while (node && node->thunk.thunk_p);
+ return node;
+}
+
#include "gt-cgraph.h"
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index fcb9261ff62..dda4402e077 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-ref.h"
/* Symbol table consists of functions and variables.
- TODO: add labels, constant pool and aliases. */
+ TODO: add labels and CONST_DECLs. */
enum symtab_type
{
SYMTAB_SYMBOL,
@@ -48,47 +48,96 @@ struct GTY(()) symtab_node_base
/* The symbols resolution. */
ENUM_BITFIELD (ld_plugin_symbol_resolution) resolution : 8;
- /* Set when function has address taken.
- In current implementation it imply needed flag. */
- unsigned address_taken : 1;
+ /*** Flags representing the symbol type. ***/
+
+ /* True when symbol corresponds to a definition in current unit.
+ set via cgraph_finalize_function or varpool_finalize_decl */
+ unsigned definition : 1;
+ /* True when symbol is an alias.
+ Set by assemble_alias. */
+ unsigned alias : 1;
+ /* C++ frontend produce same body aliases and extra name aliases for
+ virutal functions and vtables that are obviously equivalent.
+ Those aliases are bit special, especially because C++ frontend
+ visibility code is so ugly it can not get them right at first time
+ and their visibility needs to be copied from their "masters" at
+ the end of parsing. */
+ unsigned cpp_implicit_alias : 1;
+ /* Set once the definition was analyzed. The list of references and
+ other properties are built during analysis. */
+ unsigned analyzed : 1;
+
+
+ /*** Visibility and linkage flags. ***/
+
+ /* Set when function is visible by other units. */
+ unsigned externally_visible : 1;
+ /* The symbol will be assumed to be used in an invisiable way (like
+ by an toplevel asm statement). */
+ unsigned force_output : 1;
+ /* Like FORCE_OUTPUT, but in the case it is ABI requiring the symbol to be
+ exported. Unlike FORCE_OUTPUT this flag gets cleared to symbols promoted
+ to static and it does not inhibit optimization. */
+ unsigned forced_by_abi : 1;
+ /* True when the name is known to be unique and thus it does not need mangling. */
+ unsigned unique_name : 1;
+
+
+ /*** WHOPR Partitioning flags.
+ These flags are used at ltrans stage when only part of the callgraph is
+ available. ***/
+
/* Set when variable is used from other LTRANS partition. */
unsigned used_from_other_partition : 1;
/* Set when function is available in the other LTRANS partition.
During WPA output it is used to mark nodes that are present in
multiple partitions. */
unsigned in_other_partition : 1;
- /* Set when function is visible by other units. */
- unsigned externally_visible : 1;
- /* Needed variables might become dead by optimization. This flag
- forces the variable to be output even if it appears dead otherwise. */
- unsigned force_output : 1;
- /* True when the name is known to be unique and thus it does not need mangling. */
- unsigned unique_name : 1;
- /* Ordering of all symtab entries. */
- int order;
- tree decl;
- /* Vectors of referring and referenced entities. */
- struct ipa_ref_list ref_list;
+ /*** other flags. ***/
- /* Circular list of nodes in the same comdat group if non-NULL. */
- symtab_node same_comdat_group;
+ /* Set when symbol has address taken. */
+ unsigned address_taken : 1;
- /* File stream where this node is being written to. */
- struct lto_file_decl_data * lto_file_data;
+
+ /* Ordering of all symtab entries. */
+ int order;
+
+ /* Declaration representing the symbol. */
+ tree decl;
/* Linked list of symbol table entries starting with symtab_nodes. */
symtab_node next;
symtab_node previous;
+
/* Linked list of symbols with the same asm name. There may be multiple
- entries for single symbol name in the case of LTO resolutions,
- existence of inline clones, or duplicated declaration. The last case
- is a long standing bug frontends and builtin handling. */
+ entries for single symbol name during LTO, because symbols are renamed
+ only after partitioning.
+
+ Because inline clones are kept in the assembler name has, they also produce
+ duplicate entries.
+
+ There are also several long standing bugs where frontends and builtin
+ code produce duplicated decls. */
symtab_node next_sharing_asm_name;
symtab_node previous_sharing_asm_name;
+ /* Circular list of nodes in the same comdat group if non-NULL. */
+ symtab_node same_comdat_group;
+
+ /* Vectors of referring and referenced entities. */
+ struct ipa_ref_list ref_list;
+
+ /* Alias target. May be either DECL pointer or ASSEMBLER_NAME pointer
+ depending to what was known to frontend on the creation time.
+ Once alias is resolved, this pointer become NULL. */
+ tree alias_target;
+
+ /* File stream where this node is being written to. */
+ struct lto_file_decl_data * lto_file_data;
+
PTR GTY ((skip)) aux;
};
@@ -142,9 +191,6 @@ struct GTY(()) cgraph_local_info {
and its address is never taken. */
unsigned local : 1;
- /* Set once it has been finalized so we consider it to be output. */
- unsigned finalized : 1;
-
/* False when there is something makes versioning impossible. */
unsigned versionable : 1;
@@ -260,13 +306,7 @@ struct GTY(()) cgraph_node {
unsigned lowered : 1;
/* Set once the function has been instantiated and its callee
lists created. */
- unsigned analyzed : 1;
- /* Set when function is scheduled to be processed by local passes. */
unsigned process : 1;
- /* Set for aliases once they got through assemble_alias. */
- unsigned alias : 1;
- /* Set for aliases created as C++ same body aliases. */
- unsigned same_body_alias : 1;
/* How commonly executed the node is. Initialized during branch
probabilities pass. */
ENUM_BITFIELD (node_frequency) frequency : 2;
@@ -452,20 +492,9 @@ typedef struct cgraph_edge *cgraph_edge_p;
struct GTY(()) varpool_node {
struct symtab_node_base symbol;
- /* For aliases points to declaration DECL is alias of. */
- tree alias_of;
- /* Set once the variable has been instantiated and its callee
- lists created. */
- unsigned analyzed : 1;
- /* Set once it has been finalized so we consider it to be output. */
- unsigned finalized : 1;
/* Set when variable is scheduled to be assembled. */
unsigned output : 1;
- /* Set for aliases once they got through assemble_alias. Also set for
- extra name aliases in varpool_extra_name_alias. */
- unsigned alias : 1;
- unsigned extra_name_alias : 1;
};
/* Every top level asm statement is put into a asm_node. */
@@ -535,7 +564,7 @@ extern cgraph_node_set cgraph_new_nodes;
extern GTY(()) struct asm_node *asm_nodes;
extern GTY(()) int symtab_order;
-extern bool same_body_aliases_done;
+extern bool cpp_implicit_aliases_done;
/* In symtab.c */
void symtab_register_node (symtab_node);
@@ -558,6 +587,10 @@ void verify_symtab_node (symtab_node);
bool verify_symtab_base (symtab_node);
bool symtab_used_from_object_file_p (symtab_node);
void symtab_make_decl_local (tree);
+symtab_node symtab_alias_ultimate_target (symtab_node,
+ enum availability *avail = NULL);
+bool symtab_resolve_alias (symtab_node node, symtab_node target);
+void fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target);
/* In cgraph.c */
void dump_cgraph (FILE *);
@@ -653,6 +686,8 @@ struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_ho
void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *);
gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *);
bool cgraph_propagate_frequency (struct cgraph_node *node);
+struct cgraph_node * cgraph_function_node (struct cgraph_node *,
+ enum availability *avail = NULL);
/* In cgraphunit.c */
struct asm_node *add_asm_node (tree);
@@ -663,10 +698,11 @@ void compile (void);
void init_cgraph (void);
bool cgraph_process_new_functions (void);
void cgraph_process_same_body_aliases (void);
-void fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias);
+void fixup_same_cpp_alias_visibility (symtab_node, symtab_node target, tree);
/* Initialize datastructures so DECL is a function in lowered gimple form.
IN_SSA is true if the gimple is in SSA. */
-basic_block init_lowered_empty_function (tree decl, bool in_ssa);
+basic_block init_lowered_empty_function (tree, bool);
+void cgraph_reset_node (struct cgraph_node *);
/* In cgraphclones.c */
@@ -728,7 +764,6 @@ void dump_varpool_node_set (FILE *, varpool_node_set);
void debug_varpool_node_set (varpool_node_set);
void free_varpool_node_set (varpool_node_set);
void ipa_discover_readonly_nonaddressable_vars (void);
-bool cgraph_comdat_can_be_unshared_p (struct cgraph_node *);
bool varpool_externally_visible_p (struct varpool_node *);
/* In predict.c */
@@ -744,7 +779,6 @@ void dump_varpool (FILE *);
void dump_varpool_node (FILE *, struct varpool_node *);
void varpool_finalize_decl (tree);
-bool decide_is_variable_needed (struct varpool_node *, tree);
enum availability cgraph_variable_initializer_availability (struct varpool_node *);
void cgraph_make_node_local (struct cgraph_node *);
bool cgraph_node_can_be_local_p (struct cgraph_node *);
@@ -765,6 +799,7 @@ bool varpool_for_node_and_aliases (struct varpool_node *,
void varpool_add_new_variable (tree);
void symtab_initialize_asm_name_hash (void);
void symtab_prevail_in_asm_name_hash (symtab_node node);
+void varpool_remove_initializer (struct varpool_node *);
/* Return callgraph node for given symbol and check it is a function. */
@@ -801,7 +836,7 @@ varpool_get_node (const_tree decl)
/* Return asm name of cgraph node. */
static inline const char *
-cgraph_node_asm_name(struct cgraph_node *node)
+cgraph_node_asm_name (struct cgraph_node *node)
{
return symtab_node_asm_name ((symtab_node)node);
}
@@ -900,7 +935,7 @@ varpool_first_defined_variable (void)
for (node = symtab_nodes; node; node = node->symbol.next)
{
varpool_node *vnode = dyn_cast <varpool_node> (node);
- if (vnode && vnode->analyzed)
+ if (vnode && vnode->symbol.definition)
return vnode;
}
return NULL;
@@ -914,7 +949,7 @@ varpool_next_defined_variable (struct varpool_node *node)
for (; node1; node1 = node1->symbol.next)
{
varpool_node *vnode1 = dyn_cast <varpool_node> (node1);
- if (vnode1 && vnode1->analyzed)
+ if (vnode1 && vnode1->symbol.definition)
return vnode1;
}
return NULL;
@@ -932,7 +967,7 @@ cgraph_first_defined_function (void)
for (node = symtab_nodes; node; node = node->symbol.next)
{
cgraph_node *cn = dyn_cast <cgraph_node> (node);
- if (cn && cn->analyzed)
+ if (cn && cn->symbol.definition)
return cn;
}
return NULL;
@@ -946,7 +981,7 @@ cgraph_next_defined_function (struct cgraph_node *node)
for (; node1; node1 = node1->symbol.next)
{
cgraph_node *cn1 = dyn_cast <cgraph_node> (node1);
- if (cn1 && cn1->analyzed)
+ if (cn1 && cn1->symbol.definition)
return cn1;
}
return NULL;
@@ -992,7 +1027,7 @@ cgraph_next_function (struct cgraph_node *node)
static inline bool
cgraph_function_with_gimple_body_p (struct cgraph_node *node)
{
- return node->analyzed && !node->thunk.thunk_p && !node->alias;
+ return node->symbol.definition && !node->thunk.thunk_p && !node->symbol.alias;
}
/* Return first function with body defined. */
@@ -1184,6 +1219,7 @@ varpool_can_remove_if_no_refs (struct varpool_node *node)
return true;
return (!node->symbol.force_output && !node->symbol.used_from_other_partition
&& ((DECL_COMDAT (node->symbol.decl)
+ && !node->symbol.forced_by_abi
&& !symtab_used_from_object_file_p ((symtab_node) node))
|| !node->symbol.externally_visible
|| DECL_HAS_VALUE_EXPR_P (node->symbol.decl)));
@@ -1197,7 +1233,7 @@ varpool_can_remove_if_no_refs (struct varpool_node *node)
static inline bool
varpool_all_refs_explicit_p (struct varpool_node *vnode)
{
- return (vnode->analyzed
+ return (vnode->symbol.definition
&& !vnode->symbol.externally_visible
&& !vnode->symbol.used_from_other_partition
&& !vnode->symbol.force_output);
@@ -1211,60 +1247,25 @@ htab_t constant_pool_htab (void);
/* Return node that alias N is aliasing. */
-static inline struct cgraph_node *
-cgraph_alias_aliased_node (struct cgraph_node *n)
+static inline symtab_node
+symtab_alias_target (symtab_node n)
{
struct ipa_ref *ref;
-
ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref);
gcc_checking_assert (ref->use == IPA_REF_ALIAS);
- if (is_a <cgraph_node> (ref->referred))
- return ipa_ref_node (ref);
- return NULL;
+ return ref->referred;
}
-/* Return node that alias N is aliasing. */
-
-static inline struct varpool_node *
-varpool_alias_aliased_node (struct varpool_node *n)
+static inline struct cgraph_node *
+cgraph_alias_target (struct cgraph_node *n)
{
- struct ipa_ref *ref;
-
- ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref);
- gcc_checking_assert (ref->use == IPA_REF_ALIAS);
- if (is_a <varpool_node> (ref->referred))
- return ipa_ref_varpool_node (ref);
- return NULL;
+ return dyn_cast <cgraph_node> (symtab_alias_target ((symtab_node) n));
}
-/* Given NODE, walk the alias chain to return the function NODE is alias of.
- Walk through thunk, too.
- When AVAILABILITY is non-NULL, get minimal availability in the chain. */
-
-static inline struct cgraph_node *
-cgraph_function_node (struct cgraph_node *node, enum availability *availability)
+static inline struct varpool_node *
+varpool_alias_target (struct varpool_node *n)
{
- if (availability)
- *availability = cgraph_function_body_availability (node);
- while (node)
- {
- if (node->alias && node->analyzed)
- node = cgraph_alias_aliased_node (node);
- else if (node->thunk.thunk_p)
- node = node->callees->callee;
- else
- return node;
- if (node && availability)
- {
- enum availability a;
- a = cgraph_function_body_availability (node);
- if (a < *availability)
- *availability = a;
- }
- }
- if (availability)
- *availability = AVAIL_NOT_AVAILABLE;
- return NULL;
+ return dyn_cast <varpool_node> (symtab_alias_target ((symtab_node) n));
}
/* Given NODE, walk the alias chain to return the function NODE is alias of.
@@ -1272,55 +1273,32 @@ cgraph_function_node (struct cgraph_node *node, enum availability *availability)
When AVAILABILITY is non-NULL, get minimal availability in the chain. */
static inline struct cgraph_node *
-cgraph_function_or_thunk_node (struct cgraph_node *node, enum availability *availability)
+cgraph_function_or_thunk_node (struct cgraph_node *node,
+ enum availability *availability = NULL)
{
- if (availability)
- *availability = cgraph_function_body_availability (node);
- while (node)
- {
- if (node->alias && node->analyzed)
- node = cgraph_alias_aliased_node (node);
- else
- return node;
- if (node && availability)
- {
- enum availability a;
- a = cgraph_function_body_availability (node);
- if (a < *availability)
- *availability = a;
- }
- }
- if (availability)
+ struct cgraph_node *n;
+
+ n = dyn_cast <cgraph_node> (symtab_alias_ultimate_target ((symtab_node)node,
+ availability));
+ if (!n && availability)
*availability = AVAIL_NOT_AVAILABLE;
- return NULL;
+ return n;
}
-
/* Given NODE, walk the alias chain to return the function NODE is alias of.
Do not walk through thunks.
When AVAILABILITY is non-NULL, get minimal availability in the chain. */
static inline struct varpool_node *
-varpool_variable_node (struct varpool_node *node, enum availability *availability)
+varpool_variable_node (struct varpool_node *node,
+ enum availability *availability = NULL)
{
- if (availability)
- *availability = cgraph_variable_initializer_availability (node);
- while (node)
- {
- if (node->alias && node->analyzed)
- node = varpool_alias_aliased_node (node);
- else
- return node;
- if (node && availability)
- {
- enum availability a;
- a = cgraph_variable_initializer_availability (node);
- if (a < *availability)
- *availability = a;
- }
- }
- if (availability)
+ struct varpool_node *n;
+
+ n = dyn_cast <varpool_node> (symtab_alias_ultimate_target ((symtab_node)node,
+ availability));
+ if (!n && availability)
*availability = AVAIL_NOT_AVAILABLE;
- return NULL;
+ return n;
}
/* Return true when the edge E represents a direct recursion. */
@@ -1355,7 +1333,7 @@ cgraph_mark_force_output_node (struct cgraph_node *node)
}
/* Return true when the symbol is real symbol, i.e. it is not inline clone
- or extern function kept around just for inlining. */
+ or abstract function kept for debug info purposes only. */
static inline bool
symtab_real_symbol_p (symtab_node node)
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index a002c689db9..d82eb371798 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -189,7 +189,8 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
new_node->next_nested = new_node->origin->nested;
new_node->origin->nested = new_node;
}
- new_node->analyzed = n->analyzed;
+ new_node->symbol.analyzed = n->symbol.analyzed;
+ new_node->symbol.definition = n->symbol.definition;
new_node->local = n->local;
new_node->symbol.externally_visible = false;
new_node->local.local = true;
@@ -638,10 +639,11 @@ cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
new_version = cgraph_create_node (new_decl);
- new_version->analyzed = old_version->analyzed;
+ new_version->symbol.analyzed = old_version->symbol.analyzed;
+ new_version->symbol.definition = old_version->symbol.definition;
new_version->local = old_version->local;
new_version->symbol.externally_visible = false;
- new_version->local.local = old_version->analyzed;
+ new_version->local.local = new_version->symbol.definition;
new_version->global = old_version->global;
new_version->rtl = old_version->rtl;
new_version->count = old_version->count;
@@ -791,7 +793,7 @@ cgraph_materialize_clone (struct cgraph_node *node)
node->clone_of->clones = node->next_sibling_clone;
node->next_sibling_clone = NULL;
node->prev_sibling_clone = NULL;
- if (!node->clone_of->analyzed && !node->clone_of->clones)
+ if (!node->clone_of->symbol.analyzed && !node->clone_of->clones)
{
cgraph_release_function_body (node->clone_of);
cgraph_node_remove_callees (node->clone_of);
@@ -874,7 +876,7 @@ cgraph_materialize_all_clones (void)
}
}
FOR_EACH_FUNCTION (node)
- if (!node->analyzed && node->callees)
+ if (!node->symbol.analyzed && node->callees)
cgraph_node_remove_callees (node);
if (cgraph_dump_file)
fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 6ebf8d4aa06..044bdf7b02b 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -202,7 +202,7 @@ cgraph_node_set cgraph_new_nodes;
static void expand_all_functions (void);
static void mark_functions_to_output (void);
static void expand_function (struct cgraph_node *);
-static void cgraph_analyze_function (struct cgraph_node *);
+static void analyze_function (struct cgraph_node *);
static void handle_alias_pairs (void);
FILE *cgraph_dump_file;
@@ -216,37 +216,45 @@ static GTY(()) struct asm_node *asm_last_node;
/* Used for vtable lookup in thunk adjusting. */
static GTY (()) tree vtable_entry_type;
-/* Determine if function DECL is trivially needed and should stay in the
- compilation unit. This is used at the symbol table construction time
- and differs from later logic removing unnecessary functions that can
- take into account results of analysis, whole program info etc. */
-
-static bool
-cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
+/* Determine if symbol DECL is needed. That is, visible to something
+ either outside this translation unit, something magic in the system
+ configury */
+bool
+decide_is_symbol_needed (symtab_node node)
{
- /* If the user told us it is used, then it must be so. */
- if (node->symbol.force_output)
- return true;
+ tree decl = node->symbol.decl;
/* Double check that no one output the function into assembly file
early. */
gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
- || (node->thunk.thunk_p || node->same_body_alias)
- || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
+ || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
+ if (!node->symbol.definition)
+ return false;
- /* Keep constructors, destructors and virtual functions. */
- if (DECL_STATIC_CONSTRUCTOR (decl)
- || DECL_STATIC_DESTRUCTOR (decl)
- || (DECL_VIRTUAL_P (decl)
- && optimize && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl))))
- return true;
+ /* Devirtualization may access these. */
+ if (DECL_VIRTUAL_P (decl) && optimize)
+ return true;
- /* Externally visible functions must be output. The exception is
- COMDAT functions that must be output only when they are needed. */
+ if (DECL_EXTERNAL (decl))
+ return false;
- if (TREE_PUBLIC (decl)
- && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
+ /* If the user told us it is used, then it must be so. */
+ if (node->symbol.force_output)
+ return true;
+
+ /* ABI forced symbols are needed when they are external. */
+ if (node->symbol.forced_by_abi && TREE_PUBLIC (decl))
+ return true;
+
+ /* Keep constructors, destructors and virtual functions. */
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl)))
+ return true;
+
+ /* Externally visible variables must be output. The exception is
+ COMDAT variables that must be output only when they are needed. */
+ if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
return true;
return false;
@@ -309,8 +317,8 @@ cgraph_process_new_functions (void)
cgraph but not on this function. */
gimple_register_cfg_hooks ();
- if (!node->analyzed)
- cgraph_analyze_function (node);
+ if (!node->symbol.analyzed)
+ analyze_function (node);
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
if ((cgraph_state == CGRAPH_STATE_IPA_SSA
&& !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
@@ -354,7 +362,7 @@ cgraph_process_new_functions (void)
??? It may make more sense to use one body for inlining and other
body for expanding the function but this is difficult to do. */
-static void
+void
cgraph_reset_node (struct cgraph_node *node)
{
/* If node->process is set, then we have already begun whole-unit analysis.
@@ -368,10 +376,13 @@ cgraph_reset_node (struct cgraph_node *node)
memset (&node->local, 0, sizeof (node->local));
memset (&node->global, 0, sizeof (node->global));
memset (&node->rtl, 0, sizeof (node->rtl));
- node->analyzed = false;
- node->local.finalized = false;
+ node->symbol.analyzed = false;
+ node->symbol.definition = false;
+ node->symbol.alias = false;
+ node->symbol.cpp_implicit_alias = false;
cgraph_node_remove_callees (node);
+ ipa_remove_all_references (&node->symbol.ref_list);
}
/* Return true when there are references to NODE. */
@@ -401,14 +412,14 @@ cgraph_finalize_function (tree decl, bool nested)
{
struct cgraph_node *node = cgraph_get_create_node (decl);
- if (node->local.finalized)
+ if (node->symbol.definition)
{
cgraph_reset_node (node);
node->local.redefined_extern_inline = true;
}
notice_global_symbol (decl);
- node->local.finalized = true;
+ node->symbol.definition = true;
node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
/* With -fkeep-inline-functions we are keeping all inline functions except
@@ -425,7 +436,7 @@ cgraph_finalize_function (tree decl, bool nested)
in the original implementation and it is unclear whether we want
to change the behavior here. */
if ((!optimize
- && !node->same_body_alias
+ && !node->symbol.cpp_implicit_alias
&& !DECL_DISREGARD_INLINE_LIMITS (decl)
&& !DECL_DECLARED_INLINE_P (decl)
&& !(DECL_CONTEXT (decl)
@@ -445,7 +456,7 @@ cgraph_finalize_function (tree decl, bool nested)
ggc_collect ();
if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
- && (cgraph_decide_is_function_needed (node, decl)
+ && (decide_is_symbol_needed ((symtab_node) node)
|| referred_to_p ((symtab_node)node)))
enqueue_node ((symtab_node)node);
}
@@ -488,7 +499,7 @@ cgraph_add_new_function (tree fndecl, bool lowered)
analyzing and compilation. */
node = cgraph_get_create_node (fndecl);
node->local.local = false;
- node->local.finalized = true;
+ node->symbol.definition = true;
node->symbol.force_output = true;
if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
{
@@ -515,7 +526,8 @@ cgraph_add_new_function (tree fndecl, bool lowered)
node = cgraph_create_node (fndecl);
if (lowered)
node->lowered = true;
- cgraph_analyze_function (node);
+ node->symbol.definition = true;
+ analyze_function (node);
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
gimple_register_cfg_hooks ();
bitmap_obstack_initialize (NULL);
@@ -571,63 +583,22 @@ output_asm_statements (void)
asm_nodes = NULL;
}
-/* C++ FE sometimes change linkage flags after producing same body aliases. */
-void
-fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias)
-{
- DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (alias);
- if (TREE_PUBLIC (node->symbol.decl))
- {
- DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (alias);
- DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (alias);
- DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (alias);
- if (DECL_ONE_ONLY (alias)
- && !node->symbol.same_comdat_group)
- symtab_add_to_same_comdat_group ((symtab_node)node, (symtab_node)target);
- }
-}
-
/* Analyze the function scheduled to be output. */
static void
-cgraph_analyze_function (struct cgraph_node *node)
+analyze_function (struct cgraph_node *node)
{
tree decl = node->symbol.decl;
location_t saved_loc = input_location;
input_location = DECL_SOURCE_LOCATION (decl);
- if (node->alias && node->thunk.alias)
- {
- struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
- struct cgraph_node *n;
-
- for (n = tgt; n && n->alias;
- n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
- if (n == node)
- {
- error ("function %q+D part of alias cycle", node->symbol.decl);
- node->alias = false;
- input_location = saved_loc;
- return;
- }
- if (!vec_safe_length (node->symbol.ref_list.references))
- ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
- IPA_REF_ALIAS, NULL);
- if (node->same_body_alias)
- {
- DECL_DECLARED_INLINE_P (node->symbol.decl)
- = DECL_DECLARED_INLINE_P (node->thunk.alias);
- DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
- = DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias);
- fixup_same_cpp_alias_visibility ((symtab_node) node, (symtab_node) tgt, node->thunk.alias);
- }
-
- if (node->symbol.address_taken)
- cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
- }
+ if (node->symbol.alias)
+ symtab_resolve_alias
+ ((symtab_node) node, (symtab_node) cgraph_get_node (node->symbol.alias_target));
else if (node->thunk.thunk_p)
{
cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
NULL, 0, CGRAPH_FREQ_BASE);
+ node->thunk.alias = NULL;
}
else if (node->dispatcher_function)
{
@@ -677,7 +648,7 @@ cgraph_analyze_function (struct cgraph_node *node)
pop_cfun ();
}
- node->analyzed = true;
+ node->symbol.analyzed = true;
input_location = saved_loc;
}
@@ -691,16 +662,15 @@ cgraph_analyze_function (struct cgraph_node *node)
void
cgraph_process_same_body_aliases (void)
{
- struct cgraph_node *node;
- FOR_EACH_FUNCTION (node)
- if (node->same_body_alias
- && !vec_safe_length (node->symbol.ref_list.references))
- {
- struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
- ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
- IPA_REF_ALIAS, NULL);
- }
- same_body_aliases_done = true;
+ symtab_node node;
+ FOR_EACH_SYMBOL (node)
+ if (node->symbol.cpp_implicit_alias && !node->symbol.analyzed)
+ symtab_resolve_alias
+ (node,
+ TREE_CODE (node->symbol.alias_target) == VAR_DECL
+ ? (symtab_node)varpool_node_for_decl (node->symbol.alias_target)
+ : (symtab_node)cgraph_get_create_node (node->symbol.alias_target));
+ cpp_implicit_aliases_done = true;
}
/* Process attributes common for vars and functions. */
@@ -766,7 +736,7 @@ process_function_and_variable_attributes (struct cgraph_node *first,
" attribute have effect only on public objects");
}
if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
- && (node->local.finalized && !node->alias))
+ && (node->symbol.definition && !node->symbol.alias))
{
warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
"%<weakref%> attribute ignored"
@@ -803,7 +773,7 @@ process_function_and_variable_attributes (struct cgraph_node *first,
" attribute have effect only on public objects");
}
if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
- && vnode->finalized
+ && vnode->symbol.definition
&& DECL_INITIAL (decl))
{
warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
@@ -828,10 +798,10 @@ varpool_finalize_decl (tree decl)
gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
- if (node->finalized)
+ if (node->symbol.definition)
return;
notice_global_symbol (decl);
- node->finalized = true;
+ node->symbol.definition = true;
if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
/* Traditionally we do not eliminate static variables when not
optimizing and when not doing toplevel reoder. */
@@ -840,7 +810,7 @@ varpool_finalize_decl (tree decl)
node->symbol.force_output = true;
if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
- && (decide_is_variable_needed (node, decl)
+ && (decide_is_symbol_needed ((symtab_node) node)
|| referred_to_p ((symtab_node)node)))
enqueue_node ((symtab_node)node);
if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
@@ -852,39 +822,11 @@ varpool_finalize_decl (tree decl)
}
-/* Determine if a symbol NODE is finalized and needed. */
-
-inline static bool
-symbol_finalized_and_needed (symtab_node node)
-{
- if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
- return cnode->local.finalized
- && cgraph_decide_is_function_needed (cnode, cnode->symbol.decl);
- if (varpool_node *vnode = dyn_cast <varpool_node> (node))
- return vnode->finalized
- && !DECL_EXTERNAL (vnode->symbol.decl)
- && decide_is_variable_needed (vnode, vnode->symbol.decl);
- return false;
-}
-
-/* Determine if a symbol NODE is finalized. */
-
-inline static bool
-symbol_finalized (symtab_node node)
-{
- if (cgraph_node *cnode= dyn_cast <cgraph_node> (node))
- return cnode->local.finalized;
- if (varpool_node *vnode = dyn_cast <varpool_node> (node))
- return vnode->finalized;
- return false;
-}
-
-
/* Discover all functions and variables that are trivially needed, analyze
them as well as all functions and variables referred by them */
static void
-cgraph_analyze_functions (void)
+analyze_functions (void)
{
/* Keep track of already processed nodes when called multiple times for
intermodule optimization. */
@@ -901,6 +843,13 @@ cgraph_analyze_functions (void)
bitmap_obstack_initialize (NULL);
cgraph_state = CGRAPH_STATE_CONSTRUCTION;
+ /* Ugly, but the fixup can not happen at a time same body alias is created;
+ C++ FE is confused about the COMDAT groups being right. */
+ if (cpp_implicit_aliases_done)
+ FOR_EACH_SYMBOL (node)
+ if (node->symbol.cpp_implicit_alias)
+ fixup_same_cpp_alias_visibility (node, symtab_alias_target (node));
+
/* Analysis adds static variables that in turn adds references to new functions.
So we need to iterate the process until it stabilize. */
while (changed)
@@ -914,7 +863,7 @@ cgraph_analyze_functions (void)
node != (symtab_node)first_analyzed
&& node != (symtab_node)first_analyzed_var; node = node->symbol.next)
{
- if (symbol_finalized_and_needed (node))
+ if (decide_is_symbol_needed (node))
{
enqueue_node (node);
if (!changed && cgraph_dump_file)
@@ -942,7 +891,7 @@ cgraph_analyze_functions (void)
node = first;
first = (symtab_node)first->symbol.aux;
cgraph_node *cnode = dyn_cast <cgraph_node> (node);
- if (cnode && cnode->local.finalized)
+ if (cnode && cnode->symbol.definition)
{
struct cgraph_edge *edge;
tree decl = cnode->symbol.decl;
@@ -951,7 +900,7 @@ cgraph_analyze_functions (void)
and later using weak alias attribute to kill its body.
See gcc.c-torture/compile/20011119-1.c */
if (!DECL_STRUCT_FUNCTION (decl)
- && (!cnode->alias || !cnode->thunk.alias)
+ && !cnode->symbol.alias
&& !cnode->thunk.thunk_p
&& !cnode->dispatcher_function)
{
@@ -960,11 +909,11 @@ cgraph_analyze_functions (void)
continue;
}
- if (!cnode->analyzed)
- cgraph_analyze_function (cnode);
+ if (!cnode->symbol.analyzed)
+ analyze_function (cnode);
for (edge = cnode->callees; edge; edge = edge->next_callee)
- if (edge->callee->local.finalized)
+ if (edge->callee->symbol.definition)
enqueue_node ((symtab_node)edge->callee);
/* If decl is a clone of an abstract function,
@@ -981,7 +930,7 @@ cgraph_analyze_functions (void)
else
{
varpool_node *vnode = dyn_cast <varpool_node> (node);
- if (vnode && vnode->finalized)
+ if (vnode && vnode->symbol.definition && !vnode->symbol.analyzed)
varpool_analyze_node (vnode);
}
@@ -994,7 +943,7 @@ cgraph_analyze_functions (void)
enqueue_node (next);
}
for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
- if (symbol_finalized (ref->referred))
+ if (ref->referred->symbol.definition)
enqueue_node (ref->referred);
cgraph_process_new_functions ();
}
@@ -1026,15 +975,15 @@ cgraph_analyze_functions (void)
{
tree decl = node->symbol.decl;
- if (cnode->local.finalized && !gimple_has_body_p (decl)
- && (!cnode->alias || !cnode->thunk.alias)
+ if (cnode->symbol.definition && !gimple_has_body_p (decl)
+ && !cnode->symbol.alias
&& !cnode->thunk.thunk_p)
cgraph_reset_node (cnode);
- gcc_assert (!cnode->local.finalized || cnode->thunk.thunk_p
- || cnode->alias
+ gcc_assert (!cnode->symbol.definition || cnode->thunk.thunk_p
+ || cnode->symbol.alias
|| gimple_has_body_p (decl));
- gcc_assert (cnode->analyzed == cnode->local.finalized);
+ gcc_assert (cnode->symbol.analyzed == cnode->symbol.definition);
}
node->symbol.aux = NULL;
}
@@ -1068,17 +1017,11 @@ handle_alias_pairs (void)
to later output the weakref pseudo op into asm file. */
if (!target_node && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
{
- if (TREE_CODE (p->decl) == FUNCTION_DECL)
- {
- struct cgraph_node *anode = cgraph_get_create_node (p->decl);
- anode->alias = true;
- anode->thunk.alias = p->target;
- }
- else
+ symtab_node node = symtab_get_node (p->decl);
+ if (node)
{
- struct varpool_node *anode = varpool_get_node (p->decl);
- anode->alias = true;
- anode->alias_of = p->target;
+ node->symbol.alias_target = p->target;
+ node->symbol.alias = true;
}
DECL_EXTERNAL (p->decl) = 1;
alias_pairs->unordered_remove (i);
@@ -1117,7 +1060,7 @@ handle_alias_pairs (void)
&& target_node && is_a <cgraph_node> (target_node))
{
struct cgraph_node *src_node = cgraph_get_node (p->decl);
- if (src_node && src_node->local.finalized)
+ if (src_node && src_node->symbol.definition)
cgraph_reset_node (src_node);
cgraph_create_function_alias (p->decl, target_node->symbol.decl);
alias_pairs->unordered_remove (i);
@@ -1165,9 +1108,9 @@ mark_functions_to_output (void)
/* We need to output all local functions that are used and not
always inlined, as well as those that are reachable from
outside the current compilation unit. */
- if (node->analyzed
+ if (node->symbol.analyzed
&& !node->thunk.thunk_p
- && !node->alias
+ && !node->symbol.alias
&& !node->global.inlined_to
&& !TREE_ASM_WRITTEN (decl)
&& !DECL_EXTERNAL (decl))
@@ -1179,7 +1122,7 @@ mark_functions_to_output (void)
for (next = cgraph (node->symbol.same_comdat_group);
next != node;
next = cgraph (next->symbol.same_comdat_group))
- if (!next->thunk.thunk_p && !next->alias)
+ if (!next->thunk.thunk_p && !next->symbol.alias)
next->process = 1;
}
}
@@ -1199,7 +1142,7 @@ mark_functions_to_output (void)
are inside partition, we can end up not removing the body since we no longer
have analyzed node pointing to it. */
&& !node->symbol.in_other_partition
- && !node->alias
+ && !node->symbol.alias
&& !node->clones
&& !DECL_EXTERNAL (decl))
{
@@ -1391,7 +1334,7 @@ assemble_thunk (struct cgraph_node *node)
HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
tree virtual_offset = NULL;
- tree alias = node->thunk.alias;
+ tree alias = node->callees->callee->symbol.decl;
tree thunk_fndecl = node->symbol.decl;
tree a = DECL_ARGUMENTS (thunk_fndecl);
@@ -1435,7 +1378,7 @@ assemble_thunk (struct cgraph_node *node)
set_cfun (NULL);
TREE_ASM_WRITTEN (thunk_fndecl) = 1;
node->thunk.thunk_p = false;
- node->analyzed = false;
+ node->symbol.analyzed = false;
}
else
{
@@ -1592,15 +1535,15 @@ assemble_thunks_and_aliases (struct cgraph_node *node)
if (ref->use == IPA_REF_ALIAS)
{
struct cgraph_node *alias = ipa_ref_referring_node (ref);
- bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias);
+ bool saved_written = TREE_ASM_WRITTEN (node->symbol.decl);
/* Force assemble_alias to really output the alias this time instead
of buffering it in same alias pairs. */
- TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
+ TREE_ASM_WRITTEN (node->symbol.decl) = 1;
do_assemble_alias (alias->symbol.decl,
- DECL_ASSEMBLER_NAME (alias->thunk.alias));
+ DECL_ASSEMBLER_NAME (node->symbol.decl));
assemble_thunks_and_aliases (alias);
- TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
+ TREE_ASM_WRITTEN (node->symbol.decl) = saved_written;
}
}
@@ -1800,7 +1743,7 @@ output_in_order (void)
FOR_EACH_DEFINED_FUNCTION (pf)
{
- if (pf->process && !pf->thunk.thunk_p && !pf->alias)
+ if (pf->process && !pf->thunk.thunk_p && !pf->symbol.alias)
{
i = pf->symbol.order;
gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
@@ -1940,22 +1883,32 @@ get_alias_symbol (tree decl)
static void
output_weakrefs (void)
{
- struct cgraph_node *node;
- struct varpool_node *vnode;
- FOR_EACH_FUNCTION (node)
- if (node->alias && DECL_EXTERNAL (node->symbol.decl)
+ symtab_node node;
+ FOR_EACH_SYMBOL (node)
+ if (node->symbol.alias && DECL_EXTERNAL (node->symbol.decl)
&& !TREE_ASM_WRITTEN (node->symbol.decl)
&& lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
- do_assemble_alias (node->symbol.decl,
- node->thunk.alias && DECL_P (node->thunk.alias) ? DECL_ASSEMBLER_NAME (node->thunk.alias)
- : get_alias_symbol (node->symbol.decl));
- FOR_EACH_VARIABLE (vnode)
- if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
- && !TREE_ASM_WRITTEN (vnode->symbol.decl)
- && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
- do_assemble_alias (vnode->symbol.decl,
- vnode->alias_of && DECL_P (vnode->alias_of) ? DECL_ASSEMBLER_NAME (vnode->alias_of)
- : get_alias_symbol (vnode->symbol.decl));
+ {
+ tree target;
+
+ /* Weakrefs are special by not requiring target definition in current
+ compilation unit. It is thus bit hard to work out what we want to
+ alias.
+ When alias target is defined, we need to fetch it from symtab reference,
+ otherwise it is pointed to by alias_target. */
+ if (node->symbol.alias_target)
+ target = (DECL_P (node->symbol.alias_target)
+ ? DECL_ASSEMBLER_NAME (node->symbol.alias_target)
+ : node->symbol.alias_target);
+ else if (node->symbol.analyzed)
+ target = DECL_ASSEMBLER_NAME (symtab_alias_target (node)->symbol.decl);
+ else
+ {
+ gcc_unreachable ();
+ target = get_alias_symbol (node->symbol.decl);
+ }
+ do_assemble_alias (node->symbol.decl, target);
+ }
}
/* Initialize callgraph dump file. */
@@ -2040,6 +1993,32 @@ compile (void)
bitmap_obstack_release (NULL);
mark_functions_to_output ();
+ /* When weakref support is missing, we autmatically translate all
+ references to NODE to references to its ultimate alias target.
+ The renaming mechanizm uses flag IDENTIFIER_TRANSPARENT_ALIAS and
+ TREE_CHAIN.
+
+ Set up this mapping before we output any assembler but once we are sure
+ that all symbol renaming is done.
+
+ FIXME: All this uglyness can go away if we just do renaming at gimple
+ level by physically rewritting the IL. At the moment we can only redirect
+ calls, so we need infrastructure for renaming references as well. */
+#ifndef ASM_OUTPUT_WEAKREF
+ symtab_node node;
+
+ FOR_EACH_SYMBOL (node)
+ if (node->symbol.alias
+ && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
+ {
+ IDENTIFIER_TRANSPARENT_ALIAS
+ (DECL_ASSEMBLER_NAME (node->symbol.decl)) = 1;
+ TREE_CHAIN (DECL_ASSEMBLER_NAME (node->symbol.decl))
+ = (node->symbol.alias_target ? node->symbol.alias_target
+ : DECL_ASSEMBLER_NAME (symtab_alias_target (node)->symbol.decl));
+ }
+#endif
+
cgraph_state = CGRAPH_STATE_EXPANSION;
if (!flag_toplevel_reorder)
output_in_order ();
@@ -2115,13 +2094,13 @@ finalize_compilation_unit (void)
/* Gimplify and lower all functions, compute reachability and
remove unreachable nodes. */
- cgraph_analyze_functions ();
+ analyze_functions ();
/* Mark alias targets necessary and emit diagnostics. */
handle_alias_pairs ();
/* Gimplify and lower thunks. */
- cgraph_analyze_functions ();
+ analyze_functions ();
/* Finally drive the pass manager. */
compile ();
diff --git a/gcc/cilkplus.def b/gcc/cilkplus.def
new file mode 100644
index 00000000000..cb3824f4ee6
--- /dev/null
+++ b/gcc/cilkplus.def
@@ -0,0 +1,59 @@
+/* This file contains the definitions and documentation for the
+ CilkPlus builtins used in the GNU compiler.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* Before including this file, you should define a macro:
+
+ DEF_CILKPLUS_BUILTIN (ENUM, NAME, TYPE, ATTRS)
+
+ See builtins.def for details. */
+
+DEF_CILKPLUS_BUILTIN (BUILT_IN_CILKPLUS_SEC_REDUCE_ADD,
+ "__sec_reduce_add", BT_FN_INT_PTR, ATTR_NULL)
+DEF_CILKPLUS_BUILTIN (BUILT_IN_CILKPLUS_SEC_REDUCE_MUL,
+ "__sec_reduce_mul", BT_FN_INT_PTR, ATTR_NULL)
+DEF_CILKPLUS_BUILTIN (BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO,
+ "__sec_reduce_all_zero", BT_FN_INT_PTR, ATTR_NULL)
+DEF_CILKPLUS_BUILTIN (BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO,
+ "__sec_reduce_any_zero", BT_FN_INT_PTR, ATTR_NULL)
+DEF_CILKPLUS_BUILTIN (BUILT_IN_CILKPLUS_SEC_REDUCE_MAX,
+ "__sec_reduce_max", BT_FN_INT_PTR, ATTR_NULL)
+DEF_CILKPLUS_BUILTIN (BUILT_IN_CILKPLUS_SEC_REDUCE_MIN,
+ "__sec_reduce_min", BT_FN_INT_PTR, ATTR_NULL)
+DEF_CILKPLUS_BUILTIN (BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND,
+ "__sec_reduce_min_ind", BT_FN_INT_PTR, ATTR_NULL)
+DEF_CILKPLUS_BUILTIN (BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND,
+ "__sec_reduce_max_ind", BT_FN_INT_PTR, ATTR_NULL)
+DEF_CILKPLUS_BUILTIN (BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO,
+ "__sec_reduce_any_nonzero", BT_FN_INT_PTR, ATTR_NULL)
+DEF_CILKPLUS_BUILTIN (BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO,
+ "__sec_reduce_all_nonzero", BT_FN_INT_PTR, ATTR_NULL)
+DEF_CILKPLUS_BUILTIN (BUILT_IN_CILKPLUS_SEC_REDUCE,
+ "__sec_reduce", BT_FN_INT_PTR_PTR_PTR, ATTR_NULL)
+DEF_CILKPLUS_BUILTIN (BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING,
+ "__sec_reduce_mutating", BT_FN_INT_PTR_PTR_PTR, ATTR_NULL)
+// FIXME: This probably needs to be rewritten as a keyword.
+DEF_CILKPLUS_BUILTIN (BUILT_IN_CILKPLUS_SEC_IMPLICIT_INDEX,
+ "__sec_implicit_index", BT_FN_INT_INT, ATTR_NULL)
+
+/*
+Local variables:
+mode:c
+End:
+*/
diff --git a/gcc/common/config/rx/rx-common.c b/gcc/common/config/rx/rx-common.c
index 946c93a499b..4186148318e 100644
--- a/gcc/common/config/rx/rx-common.c
+++ b/gcc/common/config/rx/rx-common.c
@@ -51,13 +51,16 @@ rx_handle_option (struct gcc_options *opts,
return value >= 0 && value <= 4;
case OPT_mcpu_:
- if ((enum rx_cpu_types) value == RX200)
+ if ((enum rx_cpu_types) value == RX200 ||
+ (enum rx_cpu_types) value == RX100)
opts->x_target_flags |= MASK_NO_USE_FPU;
break;
case OPT_fpu:
if (opts->x_rx_cpu_type == RX200)
error_at (loc, "the RX200 cpu does not have FPU hardware");
+ else if (opts->x_rx_cpu_type == RX100)
+ error_at (loc, "the RX100 cpu does not have FPU hardware");
break;
default:
diff --git a/gcc/config.gcc b/gcc/config.gcc
index ef75fa588ae..dcb6ee43681 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1293,7 +1293,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu | i
TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'`
need_64bit_isa=yes
case X"${with_cpu}" in
- Xgeneric|Xatom|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver3|Xbdver2|Xbdver1|Xbtver2|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
+ Xgeneric|Xatom|Xslm|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver3|Xbdver2|Xbdver1|Xbtver2|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
;;
X)
if test x$with_cpu_64 = x; then
@@ -1302,7 +1302,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu | i
;;
*)
echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
- echo "generic atom core2 corei7 corei7-avx nocona x86-64 bdver3 bdver2 bdver1 btver2 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
+ echo "generic atom slm core2 corei7 corei7-avx nocona x86-64 bdver3 bdver2 bdver1 btver2 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
exit 1
;;
esac
@@ -1414,7 +1414,7 @@ i[34567]86-*-solaris2* | x86_64-*-solaris2.1[0-9]*)
tmake_file="$tmake_file i386/t-sol2-64"
need_64bit_isa=yes
case X"${with_cpu}" in
- Xgeneric|Xatom|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver3|Xbdver2|Xbdver1|Xbtver2|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
+ Xgeneric|Xatom|Xslm|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver3|Xbdver2|Xbdver1|Xbtver2|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
;;
X)
if test x$with_cpu_64 = x; then
@@ -1423,7 +1423,7 @@ i[34567]86-*-solaris2* | x86_64-*-solaris2.1[0-9]*)
;;
*)
echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
- echo "generic atom core2 corei7 corei7-avx nocona x86-64 bdver3 bdver2 bdver1 btver2 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
+ echo "generic atom slm core2 corei7 corei7-avx nocona x86-64 bdver3 bdver2 bdver1 btver2 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
exit 1
;;
esac
@@ -1496,7 +1496,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*)
if test x$enable_targets = xall; then
tm_defines="${tm_defines} TARGET_BI_ARCH=1"
case X"${with_cpu}" in
- Xgeneric|Xatom|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver3|Xbdver2|Xbdver1|Xbtver2|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
+ Xgeneric|Xatom|Xslm|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver3|Xbdver2|Xbdver1|Xbtver2|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
;;
X)
if test x$with_cpu_64 = x; then
@@ -1505,7 +1505,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*)
;;
*)
echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
- echo "generic atom core2 corei7 Xcorei7-avx nocona x86-64 bdver3 bdver2 bdver1 btver2 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
+ echo "generic atom slm core2 corei7 Xcorei7-avx nocona x86-64 bdver3 bdver2 bdver1 btver2 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
exit 1
;;
esac
@@ -1928,23 +1928,25 @@ mipsisa64r2-*-elf* | mipsisa64r2el-*-elf*)
mipsisa64sr71k-*-elf*)
tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h"
tmake_file=mips/t-sr71k
- target_cpu_default="MASK_64BIT|MASK_FLOAT64"
tm_defines="${tm_defines} MIPS_ISA_DEFAULT=64 MIPS_CPU_STRING_DEFAULT=\\\"sr71000\\\" MIPS_ABI_DEFAULT=ABI_EABI"
;;
mipsisa64sb1-*-elf* | mipsisa64sb1el-*-elf*)
tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h"
tmake_file="mips/t-elf mips/t-sb1"
- target_cpu_default="MASK_64BIT|MASK_FLOAT64"
tm_defines="${tm_defines} MIPS_ISA_DEFAULT=64 MIPS_CPU_STRING_DEFAULT=\\\"sb1\\\" MIPS_ABI_DEFAULT=ABI_O64"
;;
-mips-*-elf* | mipsel-*-elf*)
+mips-*-elf* | mipsel-*-elf* | mipsr5900-*-elf* | mipsr5900el-*-elf*)
tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h"
tmake_file="mips/t-elf"
;;
+mips64r5900-*-elf* | mips64r5900el-*-elf*)
+ tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h"
+ tmake_file="mips/t-elf"
+ tm_defines="${tm_defines} MIPS_ISA_DEFAULT=3 MIPS_ABI_DEFAULT=ABI_N32"
+ ;;
mips64-*-elf* | mips64el-*-elf*)
tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h"
tmake_file="mips/t-elf"
- target_cpu_default="MASK_64BIT|MASK_FLOAT64"
tm_defines="${tm_defines} MIPS_ISA_DEFAULT=3 MIPS_ABI_DEFAULT=ABI_O64"
;;
mips64vr-*-elf* | mips64vrel-*-elf*)
@@ -1955,7 +1957,6 @@ mips64vr-*-elf* | mips64vrel-*-elf*)
mips64orion-*-elf* | mips64orionel-*-elf*)
tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elforion.h mips/elf.h"
tmake_file="mips/t-elf"
- target_cpu_default="MASK_64BIT|MASK_FLOAT64"
tm_defines="${tm_defines} MIPS_ISA_DEFAULT=3 MIPS_ABI_DEFAULT=ABI_O64"
;;
mips*-*-rtems*)
@@ -2848,6 +2849,10 @@ case ${target} in
arch=atom
cpu=atom
;;
+ slm-*)
+ arch=slm
+ cpu=slm
+ ;;
core2-*)
arch=core2
cpu=core2
@@ -2919,6 +2924,10 @@ case ${target} in
arch=atom
cpu=atom
;;
+ slm-*)
+ arch=slm
+ cpu=slm
+ ;;
core2-*)
arch=core2
cpu=core2
@@ -2973,6 +2982,19 @@ if test x$with_cpu = x ; then
;;
esac
;;
+ mips64r5900-*-* | mips64r5900el-*-* | mipsr5900-*-* | mipsr5900el-*-*)
+ with_arch=r5900
+ with_tune=r5900
+ if test x$with_llsc = x; then
+ # r5900 doesn't support ll, sc, lld and scd instructions:
+ with_llsc=no
+ fi
+ if test x$with_float = x; then
+ # r5900 doesn't support 64 bit float:
+ # 32 bit float doesn't comply with IEEE 754.
+ with_float=soft
+ fi
+ ;;
mips*-*-vxworks)
with_arch=mips2
;;
@@ -3422,7 +3444,7 @@ case "${target}" in
| k8 | k8-sse3 | athlon64 | athlon64-sse3 | opteron \
| opteron-sse3 | athlon-fx | bdver3 | bdver2 | bdver1 | btver2 \
| btver1 | amdfam10 | barcelona | nocona | core2 | corei7 \
- | corei7-avx | core-avx-i | core-avx2 | atom)
+ | corei7-avx | core-avx-i | core-avx2 | atom | slm)
# OK
;;
*)
diff --git a/gcc/config.in b/gcc/config.in
index f122d48579e..288c11f9377 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -199,6 +199,12 @@
#endif
+/* Define to 1 if `TIOCGWINSZ' requires <sys/ioctl.h>. */
+#ifndef USED_FOR_TARGET
+#undef GWINSZ_IN_SYS_IOCTL
+#endif
+
+
/* mcontext_t fields start with __ */
#ifndef USED_FOR_TARGET
#undef HAS_MCONTEXT_T_UNDERSCORES
@@ -1247,7 +1253,7 @@
#endif
-/* Define if your AIX linker supports a large TOC. */
+/* Define if your PowerPC64 linker supports a large TOC. */
#ifndef USED_FOR_TARGET
#undef HAVE_LD_LARGE_TOC
#endif
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 91fcde80cf6..8e099bf7f91 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -81,6 +81,7 @@ enum aarch64_symbol_type
SYMBOL_SMALL_TLSDESC,
SYMBOL_SMALL_GOTTPREL,
SYMBOL_SMALL_TPREL,
+ SYMBOL_TINY_ABSOLUTE,
SYMBOL_FORCE_TO_MEM
};
@@ -148,6 +149,8 @@ bool aarch64_legitimate_pic_operand_p (rtx);
bool aarch64_move_imm (HOST_WIDE_INT, enum machine_mode);
bool aarch64_mov_operand_p (rtx, enum aarch64_symbol_context,
enum machine_mode);
+char *aarch64_output_scalar_simd_mov_immediate (rtx, enum machine_mode);
+char *aarch64_output_simd_mov_immediate (rtx, enum machine_mode, unsigned);
bool aarch64_pad_arg_upward (enum machine_mode, const_tree);
bool aarch64_pad_reg_upward (enum machine_mode, const_tree, bool);
bool aarch64_regno_ok_for_base_p (int, bool);
@@ -156,6 +159,8 @@ bool aarch64_simd_imm_scalar_p (rtx x, enum machine_mode mode);
bool aarch64_simd_imm_zero_p (rtx, enum machine_mode);
bool aarch64_simd_scalar_immediate_valid_for_move (rtx, enum machine_mode);
bool aarch64_simd_shift_imm_p (rtx, enum machine_mode, bool);
+bool aarch64_simd_valid_immediate (rtx, enum machine_mode, bool,
+ struct simd_immediate_info *);
bool aarch64_symbolic_address_p (rtx);
bool aarch64_symbolic_constant_p (rtx, enum aarch64_symbol_context,
enum aarch64_symbol_type *);
@@ -256,6 +261,4 @@ extern void aarch64_split_combinev16qi (rtx operands[3]);
extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
extern bool
aarch64_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel);
-
-char* aarch64_output_simd_mov_immediate (rtx *, enum machine_mode, unsigned);
#endif /* GCC_AARCH64_PROTOS_H */
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 04fbdbd5837..e5990d4141e 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -409,7 +409,7 @@
case 4: return "ins\t%0.d[0], %1";
case 5: return "mov\t%0, %1";
case 6:
- return aarch64_output_simd_mov_immediate (&operands[1],
+ return aarch64_output_simd_mov_immediate (operands[1],
<MODE>mode, 64);
default: gcc_unreachable ();
}
@@ -440,7 +440,7 @@
case 5:
return "#";
case 6:
- return aarch64_output_simd_mov_immediate (&operands[1], <MODE>mode, 128);
+ return aarch64_output_simd_mov_immediate (operands[1], <MODE>mode, 128);
default:
gcc_unreachable ();
}
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index e580a1bcafc..4471ee1be1b 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -87,6 +87,14 @@ struct aarch64_address_info {
enum aarch64_symbol_type symbol_type;
};
+struct simd_immediate_info
+{
+ rtx value;
+ int shift;
+ int element_width;
+ bool mvn;
+};
+
/* The current code model. */
enum aarch64_code_model aarch64_cmodel;
@@ -103,8 +111,6 @@ static bool aarch64_vfp_is_call_or_return_candidate (enum machine_mode,
static void aarch64_elf_asm_constructor (rtx, int) ATTRIBUTE_UNUSED;
static void aarch64_elf_asm_destructor (rtx, int) ATTRIBUTE_UNUSED;
static void aarch64_override_options_after_change (void);
-static int aarch64_simd_valid_immediate (rtx, enum machine_mode, int, rtx *,
- int *, unsigned char *, int *, int *);
static bool aarch64_vector_mode_supported_p (enum machine_mode);
static unsigned bit_count (unsigned HOST_WIDE_INT);
static bool aarch64_const_vec_all_same_int_p (rtx,
@@ -524,13 +530,15 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
return;
}
+ case SYMBOL_TINY_ABSOLUTE:
+ emit_insn (gen_rtx_SET (Pmode, dest, imm));
+ return;
+
case SYMBOL_SMALL_GOT:
{
rtx tmp_reg = dest;
if (can_create_pseudo_p ())
- {
- tmp_reg = gen_reg_rtx (Pmode);
- }
+ tmp_reg = gen_reg_rtx (Pmode);
emit_move_insn (tmp_reg, gen_rtx_HIGH (Pmode, imm));
emit_insn (gen_ldr_got_small (dest, tmp_reg, imm));
return;
@@ -826,6 +834,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
case SYMBOL_SMALL_TPREL:
case SYMBOL_SMALL_ABSOLUTE:
+ case SYMBOL_TINY_ABSOLUTE:
aarch64_load_symref_appropriately (dest, imm, sty);
return;
@@ -5016,6 +5025,7 @@ aarch64_classify_tls_symbol (rtx x)
/* Return the method that should be used to access SYMBOL_REF or
LABEL_REF X in context CONTEXT. */
+
enum aarch64_symbol_type
aarch64_classify_symbol (rtx x,
enum aarch64_symbol_context context ATTRIBUTE_UNUSED)
@@ -5029,6 +5039,8 @@ aarch64_classify_symbol (rtx x,
case AARCH64_CMODEL_TINY_PIC:
case AARCH64_CMODEL_TINY:
+ return SYMBOL_TINY_ABSOLUTE;
+
case AARCH64_CMODEL_SMALL_PIC:
case AARCH64_CMODEL_SMALL:
return SYMBOL_SMALL_ABSOLUTE;
@@ -5038,48 +5050,42 @@ aarch64_classify_symbol (rtx x,
}
}
- gcc_assert (GET_CODE (x) == SYMBOL_REF);
-
- switch (aarch64_cmodel)
+ if (GET_CODE (x) == SYMBOL_REF)
{
- case AARCH64_CMODEL_LARGE:
- return SYMBOL_FORCE_TO_MEM;
-
- case AARCH64_CMODEL_TINY:
- case AARCH64_CMODEL_SMALL:
-
- /* This is needed to get DFmode, TImode constants to be loaded off
- the constant pool. Is it necessary to dump TImode values into
- the constant pool. We don't handle TImode constant loads properly
- yet and hence need to use the constant pool. */
- if (CONSTANT_POOL_ADDRESS_P (x))
+ if (aarch64_cmodel == AARCH64_CMODEL_LARGE
+ || CONSTANT_POOL_ADDRESS_P (x))
return SYMBOL_FORCE_TO_MEM;
if (aarch64_tls_symbol_p (x))
return aarch64_classify_tls_symbol (x);
- if (SYMBOL_REF_WEAK (x))
- return SYMBOL_FORCE_TO_MEM;
-
- return SYMBOL_SMALL_ABSOLUTE;
-
- case AARCH64_CMODEL_TINY_PIC:
- case AARCH64_CMODEL_SMALL_PIC:
-
- if (CONSTANT_POOL_ADDRESS_P (x))
- return SYMBOL_FORCE_TO_MEM;
+ switch (aarch64_cmodel)
+ {
+ case AARCH64_CMODEL_TINY:
+ if (SYMBOL_REF_WEAK (x))
+ return SYMBOL_FORCE_TO_MEM;
+ return SYMBOL_TINY_ABSOLUTE;
- if (aarch64_tls_symbol_p (x))
- return aarch64_classify_tls_symbol (x);
+ case AARCH64_CMODEL_SMALL:
+ if (SYMBOL_REF_WEAK (x))
+ return SYMBOL_FORCE_TO_MEM;
+ return SYMBOL_SMALL_ABSOLUTE;
- if (!aarch64_symbol_binds_local_p (x))
- return SYMBOL_SMALL_GOT;
+ case AARCH64_CMODEL_TINY_PIC:
+ if (!aarch64_symbol_binds_local_p (x))
+ return SYMBOL_SMALL_GOT;
+ return SYMBOL_TINY_ABSOLUTE;
- return SYMBOL_SMALL_ABSOLUTE;
+ case AARCH64_CMODEL_SMALL_PIC:
+ if (!aarch64_symbol_binds_local_p (x))
+ return SYMBOL_SMALL_GOT;
+ return SYMBOL_SMALL_ABSOLUTE;
- default:
- gcc_unreachable ();
+ default:
+ gcc_unreachable ();
+ }
}
+
/* By default push everything into the constant pool. */
return SYMBOL_FORCE_TO_MEM;
}
@@ -5152,8 +5158,7 @@ aarch64_legitimate_constant_p (enum machine_mode mode, rtx x)
/* This could probably go away because
we now decompose CONST_INTs according to expand_mov_immediate. */
if ((GET_CODE (x) == CONST_VECTOR
- && aarch64_simd_valid_immediate (x, mode, false,
- NULL, NULL, NULL, NULL, NULL) != -1)
+ && aarch64_simd_valid_immediate (x, mode, false, NULL))
|| CONST_INT_P (x) || aarch64_valid_floating_const (mode, x))
return !targetm.cannot_force_const_mem (mode, x);
@@ -5984,32 +5989,57 @@ aarch64_vector_mode_supported_p (enum machine_mode mode)
return false;
}
-/* Return quad mode as the preferred SIMD mode. */
+/* Return appropriate SIMD container
+ for MODE within a vector of WIDTH bits. */
static enum machine_mode
-aarch64_preferred_simd_mode (enum machine_mode mode)
+aarch64_simd_container_mode (enum machine_mode mode, unsigned width)
{
+ gcc_assert (width == 64 || width == 128);
if (TARGET_SIMD)
- switch (mode)
- {
- case DFmode:
- return V2DFmode;
- case SFmode:
- return V4SFmode;
- case SImode:
- return V4SImode;
- case HImode:
- return V8HImode;
- case QImode:
- return V16QImode;
- case DImode:
- return V2DImode;
- break;
-
- default:;
- }
+ {
+ if (width == 128)
+ switch (mode)
+ {
+ case DFmode:
+ return V2DFmode;
+ case SFmode:
+ return V4SFmode;
+ case SImode:
+ return V4SImode;
+ case HImode:
+ return V8HImode;
+ case QImode:
+ return V16QImode;
+ case DImode:
+ return V2DImode;
+ default:
+ break;
+ }
+ else
+ switch (mode)
+ {
+ case SFmode:
+ return V2SFmode;
+ case SImode:
+ return V2SImode;
+ case HImode:
+ return V4HImode;
+ case QImode:
+ return V8QImode;
+ default:
+ break;
+ }
+ }
return word_mode;
}
+/* Return 128-bit container as the preferred SIMD mode for MODE. */
+static enum machine_mode
+aarch64_preferred_simd_mode (enum machine_mode mode)
+{
+ return aarch64_simd_container_mode (mode, 128);
+}
+
/* Return the bitmask of possible vector sizes for the vectorizer
to iterate over. */
static unsigned int
@@ -6097,7 +6127,7 @@ aarch64_mangle_type (const_tree type)
}
/* Return the equivalent letter for size. */
-static unsigned char
+static char
sizetochar (int size)
{
switch (size)
@@ -6144,15 +6174,10 @@ aarch64_vect_float_const_representable_p (rtx x)
return aarch64_float_const_representable_p (x0);
}
-/* TODO: This function returns values similar to those
- returned by neon_valid_immediate in gcc/config/arm/arm.c
- but the API here is different enough that these magic numbers
- are not used. It should be sufficient to return true or false. */
-static int
-aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, int inverse,
- rtx *modconst, int *elementwidth,
- unsigned char *elementchar,
- int *mvn, int *shift)
+/* Return true for valid and false for invalid. */
+bool
+aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, bool inverse,
+ struct simd_immediate_info *info)
{
#define CHECK(STRIDE, ELSIZE, CLASS, TEST, SHIFT, NEG) \
matches = 1; \
@@ -6163,7 +6188,6 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, int inverse,
{ \
immtype = (CLASS); \
elsize = (ELSIZE); \
- elchar = sizetochar (elsize); \
eshift = (SHIFT); \
emvn = (NEG); \
break; \
@@ -6172,36 +6196,25 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, int inverse,
unsigned int i, elsize = 0, idx = 0, n_elts = CONST_VECTOR_NUNITS (op);
unsigned int innersize = GET_MODE_SIZE (GET_MODE_INNER (mode));
unsigned char bytes[16];
- unsigned char elchar = 0;
int immtype = -1, matches;
unsigned int invmask = inverse ? 0xff : 0;
int eshift, emvn;
if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
{
- bool simd_imm_zero = aarch64_simd_imm_zero_p (op, mode);
- int elem_width = GET_MODE_BITSIZE (GET_MODE (CONST_VECTOR_ELT (op, 0)));
-
- if (!(simd_imm_zero
- || aarch64_vect_float_const_representable_p (op)))
- return -1;
-
- if (modconst)
- *modconst = CONST_VECTOR_ELT (op, 0);
-
- if (elementwidth)
- *elementwidth = elem_width;
-
- if (elementchar)
- *elementchar = sizetochar (elem_width);
+ if (! (aarch64_simd_imm_zero_p (op, mode)
+ || aarch64_vect_float_const_representable_p (op)))
+ return false;
- if (shift)
- *shift = 0;
+ if (info)
+ {
+ info->value = CONST_VECTOR_ELT (op, 0);
+ info->element_width = GET_MODE_BITSIZE (GET_MODE (info->value));
+ info->mvn = false;
+ info->shift = 0;
+ }
- if (simd_imm_zero)
- return 19;
- else
- return 18;
+ return true;
}
/* Splat vector constant out into a byte vector. */
@@ -6299,23 +6312,14 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, int inverse,
if (immtype == -1
|| (immtype >= 12 && immtype <= 15)
|| immtype == 18)
- return -1;
-
-
- if (elementwidth)
- *elementwidth = elsize;
-
- if (elementchar)
- *elementchar = elchar;
-
- if (mvn)
- *mvn = emvn;
-
- if (shift)
- *shift = eshift;
+ return false;
- if (modconst)
+ if (info)
{
+ info->element_width = elsize;
+ info->mvn = emvn != 0;
+ info->shift = eshift;
+
unsigned HOST_WIDE_INT imm = 0;
/* Un-invert bytes of recognized vector, if necessary. */
@@ -6332,68 +6336,27 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, int inverse,
imm |= (unsigned HOST_WIDE_INT) (bytes[i] ? 0xff : 0)
<< (i * BITS_PER_UNIT);
- *modconst = GEN_INT (imm);
- }
- else
- {
- unsigned HOST_WIDE_INT imm = 0;
- for (i = 0; i < elsize / BITS_PER_UNIT; i++)
- imm |= (unsigned HOST_WIDE_INT) bytes[i] << (i * BITS_PER_UNIT);
+ info->value = GEN_INT (imm);
+ }
+ else
+ {
+ for (i = 0; i < elsize / BITS_PER_UNIT; i++)
+ imm |= (unsigned HOST_WIDE_INT) bytes[i] << (i * BITS_PER_UNIT);
/* Construct 'abcdefgh' because the assembler cannot handle
- generic constants. */
- gcc_assert (shift != NULL && mvn != NULL);
- if (*mvn)
+ generic constants. */
+ if (info->mvn)
imm = ~imm;
- imm = (imm >> *shift) & 0xff;
- *modconst = GEN_INT (imm);
- }
+ imm = (imm >> info->shift) & 0xff;
+ info->value = GEN_INT (imm);
+ }
}
- return immtype;
+ return true;
#undef CHECK
}
-/* Return TRUE if rtx X is legal for use as either a AdvSIMD MOVI instruction
- (or, implicitly, MVNI) immediate. Write back width per element
- to *ELEMENTWIDTH, and a modified constant (whatever should be output
- for a MOVI instruction) in *MODCONST. */
-int
-aarch64_simd_immediate_valid_for_move (rtx op, enum machine_mode mode,
- rtx *modconst, int *elementwidth,
- unsigned char *elementchar,
- int *mvn, int *shift)
-{
- rtx tmpconst;
- int tmpwidth;
- unsigned char tmpwidthc;
- int tmpmvn = 0, tmpshift = 0;
- int retval = aarch64_simd_valid_immediate (op, mode, 0, &tmpconst,
- &tmpwidth, &tmpwidthc,
- &tmpmvn, &tmpshift);
-
- if (retval == -1)
- return 0;
-
- if (modconst)
- *modconst = tmpconst;
-
- if (elementwidth)
- *elementwidth = tmpwidth;
-
- if (elementchar)
- *elementchar = tmpwidthc;
-
- if (mvn)
- *mvn = tmpmvn;
-
- if (shift)
- *shift = tmpshift;
-
- return 1;
-}
-
static bool
aarch64_const_vec_all_same_int_p (rtx x,
HOST_WIDE_INT minval,
@@ -6457,10 +6420,9 @@ aarch64_simd_imm_scalar_p (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
bool
aarch64_mov_operand_p (rtx x,
- enum aarch64_symbol_context context ATTRIBUTE_UNUSED,
+ enum aarch64_symbol_context context,
enum machine_mode mode)
{
-
if (GET_CODE (x) == HIGH
&& aarch64_valid_symref (XEXP (x, 0), GET_MODE (XEXP (x, 0))))
return true;
@@ -6471,7 +6433,8 @@ aarch64_mov_operand_p (rtx x,
if (GET_CODE (x) == SYMBOL_REF && mode == DImode && CONSTANT_ADDRESS_P (x))
return true;
- return false;
+ return aarch64_classify_symbolic_expression (x, context)
+ == SYMBOL_TINY_ABSOLUTE;
}
/* Return a const_int vector of VAL. */
@@ -6498,9 +6461,7 @@ aarch64_simd_scalar_immediate_valid_for_move (rtx op, enum machine_mode mode)
gcc_assert (!VECTOR_MODE_P (mode));
vmode = aarch64_preferred_simd_mode (mode);
rtx op_v = aarch64_simd_gen_const_vector_dup (vmode, INTVAL (op));
- int retval = aarch64_simd_immediate_valid_for_move (op_v, vmode, 0,
- NULL, NULL, NULL, NULL);
- return retval;
+ return aarch64_simd_valid_immediate (op_v, vmode, false, NULL);
}
/* Construct and return a PARALLEL RTX vector. */
@@ -6728,8 +6689,7 @@ aarch64_simd_make_constant (rtx vals)
gcc_unreachable ();
if (const_vec != NULL_RTX
- && aarch64_simd_immediate_valid_for_move (const_vec, mode, NULL, NULL,
- NULL, NULL, NULL))
+ && aarch64_simd_valid_immediate (const_vec, mode, false, NULL))
/* Load using MOVI/MVNI. */
return const_vec;
else if ((const_dup = aarch64_simd_dup_constant (vals)) != NULL_RTX)
@@ -7287,49 +7247,78 @@ aarch64_float_const_representable_p (rtx x)
}
char*
-aarch64_output_simd_mov_immediate (rtx *const_vector,
+aarch64_output_simd_mov_immediate (rtx const_vector,
enum machine_mode mode,
unsigned width)
{
- int is_valid;
- unsigned char widthc;
- int lane_width_bits;
+ bool is_valid;
static char templ[40];
- int shift = 0, mvn = 0;
const char *mnemonic;
unsigned int lane_count = 0;
+ char element_char;
- is_valid =
- aarch64_simd_immediate_valid_for_move (*const_vector, mode,
- const_vector, &lane_width_bits,
- &widthc, &mvn, &shift);
+ struct simd_immediate_info info;
+
+ /* This will return true to show const_vector is legal for use as either
+ a AdvSIMD MOVI instruction (or, implicitly, MVNI) immediate. It will
+ also update INFO to show how the immediate should be generated. */
+ is_valid = aarch64_simd_valid_immediate (const_vector, mode, false, &info);
gcc_assert (is_valid);
+ element_char = sizetochar (info.element_width);
+ lane_count = width / info.element_width;
+
mode = GET_MODE_INNER (mode);
if (mode == SFmode || mode == DFmode)
{
- bool zero_p =
- aarch64_float_const_zero_rtx_p (*const_vector);
- gcc_assert (shift == 0);
- mnemonic = zero_p ? "movi" : "fmov";
+ gcc_assert (info.shift == 0 && ! info.mvn);
+ if (aarch64_float_const_zero_rtx_p (info.value))
+ info.value = GEN_INT (0);
+ else
+ {
+#define buf_size 20
+ REAL_VALUE_TYPE r;
+ REAL_VALUE_FROM_CONST_DOUBLE (r, info.value);
+ char float_buf[buf_size] = {'\0'};
+ real_to_decimal_for_mode (float_buf, &r, buf_size, buf_size, 1, mode);
+#undef buf_size
+
+ if (lane_count == 1)
+ snprintf (templ, sizeof (templ), "fmov\t%%d0, %s", float_buf);
+ else
+ snprintf (templ, sizeof (templ), "fmov\t%%0.%d%c, %s",
+ lane_count, element_char, float_buf);
+ return templ;
+ }
}
- else
- mnemonic = mvn ? "mvni" : "movi";
- gcc_assert (lane_width_bits != 0);
- lane_count = width / lane_width_bits;
+ mnemonic = info.mvn ? "mvni" : "movi";
if (lane_count == 1)
- snprintf (templ, sizeof (templ), "%s\t%%d0, %%1", mnemonic);
- else if (shift)
- snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, %%1, lsl %d",
- mnemonic, lane_count, widthc, shift);
+ snprintf (templ, sizeof (templ), "%s\t%%d0, " HOST_WIDE_INT_PRINT_HEX,
+ mnemonic, UINTVAL (info.value));
+ else if (info.shift)
+ snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX
+ ", lsl %d", mnemonic, lane_count, element_char,
+ UINTVAL (info.value), info.shift);
else
- snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, %%1",
- mnemonic, lane_count, widthc);
+ snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX,
+ mnemonic, lane_count, element_char, UINTVAL (info.value));
return templ;
}
+char*
+aarch64_output_scalar_simd_mov_immediate (rtx immediate,
+ enum machine_mode mode)
+{
+ enum machine_mode vmode;
+
+ gcc_assert (!VECTOR_MODE_P (mode));
+ vmode = aarch64_simd_container_mode (mode, 64);
+ rtx v_op = aarch64_simd_gen_const_vector_dup (vmode, INTVAL (immediate));
+ return aarch64_output_simd_mov_immediate (v_op, vmode, 64);
+}
+
/* Split operands into moves from op[1] + op[2] into op[0]. */
void
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 2bdbfa90bf7..e88e5be894e 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -774,17 +774,34 @@
(match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
"(register_operand (operands[0], <MODE>mode)
|| aarch64_reg_or_zero (operands[1], <MODE>mode))"
- "@
- mov\\t%w0, %w1
- mov\\t%w0, %1
- movi\\t%0.<Vallxd>, %1
- ldr<size>\\t%w0, %1
- ldr\\t%<size>0, %1
- str<size>\\t%w1, %0
- str\\t%<size>1, %0
- umov\\t%w0, %1.<v>[0]
- dup\\t%0.<Vallxd>, %w1
- dup\\t%0, %1.<v>[0]"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "mov\t%w0, %w1";
+ case 1:
+ return "mov\t%w0, %1";
+ case 2:
+ return aarch64_output_scalar_simd_mov_immediate (operands[1],
+ <MODE>mode);
+ case 3:
+ return "ldr<size>\t%w0, %1";
+ case 4:
+ return "ldr\t%<size>0, %1";
+ case 5:
+ return "str<size>\t%w1, %0";
+ case 6:
+ return "str\t%<size>1, %0";
+ case 7:
+ return "umov\t%w0, %1.<v>[0]";
+ case 8:
+ return "dup\t%0.<Vallxd>, %w1";
+ case 9:
+ return "dup\t%0, %1.<v>[0]";
+ default:
+ gcc_unreachable ();
+ }
+}
[(set_attr "v8type" "move,alu,alu,load1,load1,store1,store1,*,*,*")
(set_attr "simd_type" "*,*,simd_move_imm,*,*,*,*,simd_movgp,simd_dupgp,simd_dup")
(set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")
@@ -850,7 +867,8 @@
movi\\t%d0, %1"
[(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov,fmov")
(set_attr "mode" "DI")
- (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,yes")]
+ (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
+ (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
)
(define_insn "insv_imm<mode>"
@@ -3163,6 +3181,50 @@
(set_attr "mode" "<MODE>")]
)
+;; Bitfield Insert (insv)
+(define_expand "insv<mode>"
+ [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
+ (match_operand 1 "const_int_operand")
+ (match_operand 2 "const_int_operand"))
+ (match_operand:GPI 3 "general_operand"))]
+ ""
+{
+ unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
+ unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
+ rtx value = operands[3];
+
+ if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
+ FAIL;
+
+ if (CONST_INT_P (value))
+ {
+ unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
+
+ /* Prefer AND/OR for inserting all zeros or all ones. */
+ if ((UINTVAL (value) & mask) == 0
+ || (UINTVAL (value) & mask) == mask)
+ FAIL;
+
+ /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
+ if (width == 16 && (pos % 16) == 0)
+ DONE;
+ }
+ operands[3] = force_reg (<MODE>mode, value);
+})
+
+(define_insn "*insv_reg<mode>"
+ [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
+ (match_operand 1 "const_int_operand" "n")
+ (match_operand 2 "const_int_operand" "n"))
+ (match_operand:GPI 3 "register_operand" "r"))]
+ "!(UINTVAL (operands[1]) == 0
+ || (UINTVAL (operands[2]) + UINTVAL (operands[1])
+ > GET_MODE_BITSIZE (<MODE>mode)))"
+ "bfi\\t%<w>0, %<w>3, %2, %1"
+ [(set_attr "v8type" "bfm")
+ (set_attr "mode" "<MODE>")]
+)
+
(define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
[(set (match_operand:GPI 0 "register_operand" "=r")
(ashift:GPI (ANY_EXTEND:GPI
diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md
index d9c18e692ea..7cafc08fdd9 100644
--- a/gcc/config/aarch64/constraints.md
+++ b/gcc/config/aarch64/constraints.md
@@ -143,9 +143,8 @@
"@internal
A constraint that matches vector of immediates."
(and (match_code "const_vector")
- (match_test "aarch64_simd_immediate_valid_for_move (op, GET_MODE (op),
- NULL, NULL, NULL,
- NULL, NULL) != 0")))
+ (match_test "aarch64_simd_valid_immediate (op, GET_MODE (op),
+ false, NULL)")))
(define_constraint "Dh"
"@internal
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 16c4385e845..3248f610da0 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -166,7 +166,7 @@
})
(define_predicate "aarch64_mov_operand"
- (and (match_code "reg,subreg,mem,const_int,symbol_ref,high")
+ (and (match_code "reg,subreg,mem,const,const_int,symbol_ref,label_ref,high")
(ior (match_operand 0 "register_operand")
(ior (match_operand 0 "memory_operand")
(match_test "aarch64_mov_operand_p (op, SYMBOL_CONTEXT_ADR, mode)")))))
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 096ef3b1f56..26706701350 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -2700,12 +2700,12 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
break;
case GE: case GT: case GEU: case GTU:
- /* These must be swapped. */
- if (op1 != CONST0_RTX (cmp_mode))
- {
- code = swap_condition (code);
- tem = op0, op0 = op1, op1 = tem;
- }
+ /* These normally need swapping, but for integer zero we have
+ special patterns that recognize swapped operands. */
+ if (cmp_mode == DImode && op1 == const0_rtx)
+ break;
+ code = swap_condition (code);
+ tem = op0, op0 = op1, op1 = tem;
break;
default:
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index c791341f69b..04284177c96 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -24,12 +24,13 @@
extern enum unwind_info_type arm_except_unwind_info (struct gcc_options *);
extern int use_return_insn (int, rtx);
+extern bool use_simple_return_p (void);
extern enum reg_class arm_regno_class (int);
extern void arm_load_pic_register (unsigned long);
extern int arm_volatile_func (void);
extern void arm_expand_prologue (void);
extern void arm_expand_epilogue (bool);
-extern void thumb2_expand_return (void);
+extern void thumb2_expand_return (bool);
extern const char *arm_strip_name_encoding (const char *);
extern void arm_asm_output_labelref (FILE *, const char *);
extern void thumb2_asm_output_opcode (FILE *);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 43dfe2772f6..63eb2b76089 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -23,6 +23,7 @@
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tm.h"
#include "rtl.h"
#include "tree.h"
@@ -661,6 +662,10 @@ static const struct attribute_spec arm_attribute_table[] =
#undef TARGET_ASAN_SHADOW_OFFSET
#define TARGET_ASAN_SHADOW_OFFSET arm_asan_shadow_offset
+#undef MAX_INSN_PER_IT_BLOCK
+#define MAX_INSN_PER_IT_BLOCK (arm_restrict_it ? 1 : 4)
+
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Obstack for minipool constant handling. */
@@ -1870,6 +1875,11 @@ arm_option_override (void)
arm_arch_thumb_hwdiv = (insn_flags & FL_THUMB_DIV) != 0;
arm_arch_arm_hwdiv = (insn_flags & FL_ARM_DIV) != 0;
arm_tune_cortex_a9 = (arm_tune == cortexa9) != 0;
+ if (arm_restrict_it == 2)
+ arm_restrict_it = arm_arch8 && TARGET_THUMB2;
+
+ if (!TARGET_THUMB2)
+ arm_restrict_it = 0;
/* If we are not using the default (ARM mode) section anchor offset
ranges, then set the correct ranges now. */
@@ -2168,6 +2178,14 @@ arm_option_override (void)
global_options.x_param_values,
global_options_set.x_param_values);
+ /* Disable shrink-wrap when optimizing function for size, since it tends to
+ generate additional returns. */
+ if (optimize_function_for_size_p (cfun) && TARGET_THUMB2)
+ flag_shrink_wrap = false;
+ /* TBD: Dwarf info for apcs frame is not handled yet. */
+ if (TARGET_APCS_FRAME)
+ flag_shrink_wrap = false;
+
/* Register global variables with the garbage collector. */
arm_add_gc_roots ();
}
@@ -2517,6 +2535,18 @@ use_return_insn (int iscond, rtx sibling)
return 1;
}
+/* Return TRUE if we should try to use a simple_return insn, i.e. perform
+ shrink-wrapping if possible. This is the case if we need to emit a
+ prologue, which we can test by looking at the offsets. */
+bool
+use_simple_return_p (void)
+{
+ arm_stack_offsets *offsets;
+
+ offsets = arm_get_frame_offsets ();
+ return offsets->outgoing_args != 0;
+}
+
/* Return TRUE if int I is a valid immediate ARM constant. */
int
@@ -2656,6 +2686,7 @@ const_ok_for_dimode_op (HOST_WIDE_INT i, enum rtx_code code)
switch (code)
{
case AND:
+ case IOR:
return (const_ok_for_op (hi_val, code) || hi_val == 0xFFFFFFFF)
&& (const_ok_for_op (lo_val, code) || lo_val == 0xFFFFFFFF);
case PLUS:
@@ -3816,36 +3847,48 @@ arm_function_value(const_tree type, const_tree func,
return arm_libcall_value_1 (mode);
}
-static int
-libcall_eq (const void *p1, const void *p2)
+/* libcall hashtable helpers. */
+
+struct libcall_hasher : typed_noop_remove <rtx_def>
+{
+ typedef rtx_def value_type;
+ typedef rtx_def compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+
+inline bool
+libcall_hasher::equal (const value_type *p1, const compare_type *p2)
{
- return rtx_equal_p ((const_rtx) p1, (const_rtx) p2);
+ return rtx_equal_p (p1, p2);
}
-static hashval_t
-libcall_hash (const void *p1)
+inline hashval_t
+libcall_hasher::hash (const value_type *p1)
{
- return hash_rtx ((const_rtx) p1, VOIDmode, NULL, NULL, FALSE);
+ return hash_rtx (p1, VOIDmode, NULL, NULL, FALSE);
}
+typedef hash_table <libcall_hasher> libcall_table_type;
+
static void
-add_libcall (htab_t htab, rtx libcall)
+add_libcall (libcall_table_type htab, rtx libcall)
{
- *htab_find_slot (htab, libcall, INSERT) = libcall;
+ *htab.find_slot (libcall, INSERT) = libcall;
}
static bool
arm_libcall_uses_aapcs_base (const_rtx libcall)
{
static bool init_done = false;
- static htab_t libcall_htab;
+ static libcall_table_type libcall_htab;
if (!init_done)
{
init_done = true;
- libcall_htab = htab_create (31, libcall_hash, libcall_eq,
- NULL);
+ libcall_htab.create (31);
add_libcall (libcall_htab,
convert_optab_libfunc (sfloat_optab, SFmode, SImode));
add_libcall (libcall_htab,
@@ -3904,7 +3947,7 @@ arm_libcall_uses_aapcs_base (const_rtx libcall)
DFmode));
}
- return libcall && htab_find (libcall_htab, libcall) != NULL;
+ return libcall && libcall_htab.find (libcall) != NULL;
}
static rtx
@@ -17122,6 +17165,19 @@ emit_multi_reg_push (unsigned long mask)
return par;
}
+/* Add a REG_CFA_ADJUST_CFA REG note to INSN.
+ SIZE is the offset to be adjusted.
+ DEST and SRC might be stack_pointer_rtx or hard_frame_pointer_rtx. */
+static void
+arm_add_cfa_adjust_cfa_note (rtx insn, int size, rtx dest, rtx src)
+{
+ rtx dwarf;
+
+ RTX_FRAME_RELATED_P (insn) = 1;
+ dwarf = gen_rtx_SET (VOIDmode, dest, plus_constant (Pmode, src, size));
+ add_reg_note (insn, REG_CFA_ADJUST_CFA, dwarf);
+}
+
/* Generate and emit an insn pattern that we will recognize as a pop_multi.
SAVED_REGS_MASK shows which registers need to be restored.
@@ -17212,6 +17268,9 @@ arm_emit_multi_reg_pop (unsigned long saved_regs_mask)
par = emit_insn (par);
REG_NOTES (par) = dwarf;
+ if (!return_in_pc)
+ arm_add_cfa_adjust_cfa_note (par, UNITS_PER_WORD * num_regs,
+ stack_pointer_rtx, stack_pointer_rtx);
}
/* Generate and emit an insn pattern that we will recognize as a pop_multi
@@ -17282,6 +17341,9 @@ arm_emit_vfp_multi_reg_pop (int first_reg, int num_regs, rtx base_reg)
par = emit_insn (par);
REG_NOTES (par) = dwarf;
+
+ arm_add_cfa_adjust_cfa_note (par, 2 * UNITS_PER_WORD * num_regs,
+ base_reg, base_reg);
}
/* Generate and emit a pattern that will be recognized as LDRD pattern. If even
@@ -17357,6 +17419,7 @@ thumb2_emit_ldrd_pop (unsigned long saved_regs_mask)
pattern can be emitted now. */
par = emit_insn (par);
REG_NOTES (par) = dwarf;
+ RTX_FRAME_RELATED_P (par) = 1;
}
i++;
@@ -17373,7 +17436,12 @@ thumb2_emit_ldrd_pop (unsigned long saved_regs_mask)
stack_pointer_rtx,
plus_constant (Pmode, stack_pointer_rtx, 4 * i));
RTX_FRAME_RELATED_P (tmp) = 1;
- emit_insn (tmp);
+ tmp = emit_insn (tmp);
+ if (!return_in_pc)
+ {
+ arm_add_cfa_adjust_cfa_note (tmp, UNITS_PER_WORD * i,
+ stack_pointer_rtx, stack_pointer_rtx);
+ }
dwarf = NULL_RTX;
@@ -17407,9 +17475,11 @@ thumb2_emit_ldrd_pop (unsigned long saved_regs_mask)
else
{
par = emit_insn (tmp);
+ REG_NOTES (par) = dwarf;
+ arm_add_cfa_adjust_cfa_note (par, UNITS_PER_WORD,
+ stack_pointer_rtx, stack_pointer_rtx);
}
- REG_NOTES (par) = dwarf;
}
else if ((num_regs % 2) == 1 && return_in_pc)
{
@@ -19532,7 +19602,7 @@ thumb2_final_prescan_insn (rtx insn)
break;
/* Allow up to 4 conditionally executed instructions in a block. */
n = get_attr_ce_count (insn);
- if (arm_condexec_masklen + n > 4)
+ if (arm_condexec_masklen + n > MAX_INSN_PER_IT_BLOCK)
break;
predicate = COND_EXEC_TEST (body);
@@ -23995,7 +24065,7 @@ thumb1_expand_prologue (void)
all we really need to check here is if single register is to be
returned, or multiple register return. */
void
-thumb2_expand_return (void)
+thumb2_expand_return (bool simple_return)
{
int i, num_regs;
unsigned long saved_regs_mask;
@@ -24008,7 +24078,7 @@ thumb2_expand_return (void)
if (saved_regs_mask & (1 << i))
num_regs++;
- if (saved_regs_mask)
+ if (!simple_return && saved_regs_mask)
{
if (num_regs == 1)
{
@@ -24286,6 +24356,7 @@ arm_expand_epilogue (bool really_return)
if (frame_pointer_needed)
{
+ rtx insn;
/* Restore stack pointer if necessary. */
if (TARGET_ARM)
{
@@ -24296,9 +24367,12 @@ arm_expand_epilogue (bool really_return)
/* Force out any pending memory operations that reference stacked data
before stack de-allocation occurs. */
emit_insn (gen_blockage ());
- emit_insn (gen_addsi3 (stack_pointer_rtx,
- hard_frame_pointer_rtx,
- GEN_INT (amount)));
+ insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
+ hard_frame_pointer_rtx,
+ GEN_INT (amount)));
+ arm_add_cfa_adjust_cfa_note (insn, amount,
+ stack_pointer_rtx,
+ hard_frame_pointer_rtx);
/* Emit USE(stack_pointer_rtx) to ensure that stack adjustment is not
deleted. */
@@ -24308,16 +24382,25 @@ arm_expand_epilogue (bool really_return)
{
/* In Thumb-2 mode, the frame pointer points to the last saved
register. */
- amount = offsets->locals_base - offsets->saved_regs;
- if (amount)
- emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
- hard_frame_pointer_rtx,
- GEN_INT (amount)));
+ amount = offsets->locals_base - offsets->saved_regs;
+ if (amount)
+ {
+ insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
+ hard_frame_pointer_rtx,
+ GEN_INT (amount)));
+ arm_add_cfa_adjust_cfa_note (insn, amount,
+ hard_frame_pointer_rtx,
+ hard_frame_pointer_rtx);
+ }
/* Force out any pending memory operations that reference stacked data
before stack de-allocation occurs. */
emit_insn (gen_blockage ());
- emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
+ insn = emit_insn (gen_movsi (stack_pointer_rtx,
+ hard_frame_pointer_rtx));
+ arm_add_cfa_adjust_cfa_note (insn, 0,
+ stack_pointer_rtx,
+ hard_frame_pointer_rtx);
/* Emit USE(stack_pointer_rtx) to ensure that stack adjustment is not
deleted. */
emit_insn (gen_force_register_use (stack_pointer_rtx));
@@ -24330,12 +24413,15 @@ arm_expand_epilogue (bool really_return)
amount = offsets->outgoing_args - offsets->saved_regs;
if (amount)
{
+ rtx tmp;
/* Force out any pending memory operations that reference stacked data
before stack de-allocation occurs. */
emit_insn (gen_blockage ());
- emit_insn (gen_addsi3 (stack_pointer_rtx,
- stack_pointer_rtx,
- GEN_INT (amount)));
+ tmp = emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+ GEN_INT (amount)));
+ arm_add_cfa_adjust_cfa_note (tmp, amount,
+ stack_pointer_rtx, stack_pointer_rtx);
/* Emit USE(stack_pointer_rtx) to ensure that stack adjustment is
not deleted. */
emit_insn (gen_force_register_use (stack_pointer_rtx));
@@ -24388,6 +24474,8 @@ arm_expand_epilogue (bool really_return)
REG_NOTES (insn) = alloc_reg_note (REG_CFA_RESTORE,
gen_rtx_REG (V2SImode, i),
NULL_RTX);
+ arm_add_cfa_adjust_cfa_note (insn, UNITS_PER_WORD,
+ stack_pointer_rtx, stack_pointer_rtx);
}
if (saved_regs_mask)
@@ -24435,6 +24523,9 @@ arm_expand_epilogue (bool really_return)
REG_NOTES (insn) = alloc_reg_note (REG_CFA_RESTORE,
gen_rtx_REG (SImode, i),
NULL_RTX);
+ arm_add_cfa_adjust_cfa_note (insn, UNITS_PER_WORD,
+ stack_pointer_rtx,
+ stack_pointer_rtx);
}
}
}
@@ -24459,9 +24550,33 @@ arm_expand_epilogue (bool really_return)
}
if (crtl->args.pretend_args_size)
- emit_insn (gen_addsi3 (stack_pointer_rtx,
- stack_pointer_rtx,
- GEN_INT (crtl->args.pretend_args_size)));
+ {
+ int i, j;
+ rtx dwarf = NULL_RTX;
+ rtx tmp = emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+ GEN_INT (crtl->args.pretend_args_size)));
+
+ RTX_FRAME_RELATED_P (tmp) = 1;
+
+ if (cfun->machine->uses_anonymous_args)
+ {
+ /* Restore pretend args. Refer arm_expand_prologue on how to save
+ pretend_args in stack. */
+ int num_regs = crtl->args.pretend_args_size / 4;
+ saved_regs_mask = (0xf0 >> num_regs) & 0xf;
+ for (j = 0, i = 0; j < num_regs; i++)
+ if (saved_regs_mask & (1 << i))
+ {
+ rtx reg = gen_rtx_REG (SImode, i);
+ dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
+ j++;
+ }
+ REG_NOTES (tmp) = dwarf;
+ }
+ arm_add_cfa_adjust_cfa_note (tmp, crtl->args.pretend_args_size,
+ stack_pointer_rtx, stack_pointer_rtx);
+ }
if (!really_return)
return;
@@ -26129,9 +26244,17 @@ arm_unwind_emit (FILE * asm_out_file, rtx insn)
handled_one = true;
break;
+ /* The INSN is generated in epilogue. It is set as RTX_FRAME_RELATED_P
+ to get correct dwarf information for shrink-wrap. We should not
+ emit unwind information for it because these are used either for
+ pretend arguments or notes to adjust sp and restore registers from
+ stack. */
+ case REG_CFA_ADJUST_CFA:
+ case REG_CFA_RESTORE:
+ return;
+
case REG_CFA_DEF_CFA:
case REG_CFA_EXPRESSION:
- case REG_CFA_ADJUST_CFA:
case REG_CFA_OFFSET:
/* ??? Only handling here what we actually emit. */
gcc_unreachable ();
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 4b45c984bf4..5370efab8d7 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -93,6 +93,15 @@
; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
(define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
+; We use this attribute to disable alternatives that can produce 32-bit
+; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
+; that contain 32-bit instructions.
+(define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
+
+; This attribute is used to disable a predicated alternative when we have
+; arm_restrict_it.
+(define_attr "predicable_short_it" "no,yes" (const_string "yes"))
+
;; Operand number of an input operand that is shifted. Zero if the
;; given instruction does not shift one of its input operands.
(define_attr "shift" "" (const_int 0))
@@ -103,6 +112,8 @@
(define_attr "fpu" "none,vfp"
(const (symbol_ref "arm_fpu_attr")))
+(define_attr "predicated" "yes,no" (const_string "no"))
+
; LENGTH of an instruction (in bytes)
(define_attr "length" ""
(const_int 4))
@@ -190,6 +201,15 @@
(cond [(eq_attr "insn_enabled" "no")
(const_string "no")
+ (and (eq_attr "predicable_short_it" "no")
+ (and (eq_attr "predicated" "yes")
+ (match_test "arm_restrict_it")))
+ (const_string "no")
+
+ (and (eq_attr "enabled_for_depr_it" "no")
+ (match_test "arm_restrict_it"))
+ (const_string "no")
+
(eq_attr "arch_enabled" "no")
(const_string "no")
@@ -2997,14 +3017,47 @@
""
)
-(define_insn "*iordi3_insn"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (match_operand:DI 1 "s_register_operand" "%0,r")
- (match_operand:DI 2 "s_register_operand" "r,r")))]
- "TARGET_32BIT && !TARGET_IWMMXT && !TARGET_NEON"
- "#"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")]
+(define_insn_and_split "*iordi3_insn"
+ [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
+ (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
+ (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,De,De,w ,Dl")))]
+ "TARGET_32BIT && !TARGET_IWMMXT"
+ {
+ switch (which_alternative)
+ {
+ case 0: /* fall through */
+ case 6: return "vorr\t%P0, %P1, %P2";
+ case 1: /* fall through */
+ case 7: return neon_output_logic_immediate ("vorr", &operands[2],
+ DImode, 0, VALID_NEON_QREG_MODE (DImode));
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ return "#";
+ default: gcc_unreachable ();
+ }
+ }
+ "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
+ && !(IS_VFP_REGNUM (REGNO (operands[0])))"
+ [(set (match_dup 3) (match_dup 4))
+ (set (match_dup 5) (match_dup 6))]
+ "
+ {
+ operands[3] = gen_lowpart (SImode, operands[0]);
+ operands[5] = gen_highpart (SImode, operands[0]);
+
+ operands[4] = simplify_gen_binary (IOR, SImode,
+ gen_lowpart (SImode, operands[1]),
+ gen_lowpart (SImode, operands[2]));
+ operands[6] = simplify_gen_binary (IOR, SImode,
+ gen_highpart (SImode, operands[1]),
+ gen_highpart_mode (SImode, DImode, operands[2]));
+
+ }"
+ [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,*,*,neon_int_1,neon_int_1")
+ (set_attr "length" "*,*,8,8,8,8,8,8")
+ (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
)
(define_insn "*iordi_zesidi_di"
@@ -9276,17 +9329,17 @@
[(set_attr "type" "call")]
)
-(define_expand "return"
- [(return)]
+(define_expand "<return_str>return"
+ [(returns)]
"(TARGET_ARM || (TARGET_THUMB2
&& ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
&& !IS_STACKALIGN (arm_current_func_type ())))
- && USE_RETURN_INSN (FALSE)"
+ <return_cond_false>"
"
{
if (TARGET_THUMB2)
{
- thumb2_expand_return ();
+ thumb2_expand_return (<return_simple_p>);
DONE;
}
}
@@ -9311,13 +9364,13 @@
(set_attr "predicable" "yes")]
)
-(define_insn "*cond_return"
+(define_insn "*cond_<return_str>return"
[(set (pc)
(if_then_else (match_operator 0 "arm_comparison_operator"
[(match_operand 1 "cc_register" "") (const_int 0)])
- (return)
+ (returns)
(pc)))]
- "TARGET_ARM && USE_RETURN_INSN (TRUE)"
+ "TARGET_ARM <return_cond_true>"
"*
{
if (arm_ccfsm_state == 2)
@@ -9325,20 +9378,21 @@
arm_ccfsm_state += 2;
return \"\";
}
- return output_return_instruction (operands[0], true, false, false);
+ return output_return_instruction (operands[0], true, false,
+ <return_simple_p>);
}"
[(set_attr "conds" "use")
(set_attr "length" "12")
(set_attr "type" "load1")]
)
-(define_insn "*cond_return_inverted"
+(define_insn "*cond_<return_str>return_inverted"
[(set (pc)
(if_then_else (match_operator 0 "arm_comparison_operator"
[(match_operand 1 "cc_register" "") (const_int 0)])
(pc)
- (return)))]
- "TARGET_ARM && USE_RETURN_INSN (TRUE)"
+ (returns)))]
+ "TARGET_ARM <return_cond_true>"
"*
{
if (arm_ccfsm_state == 2)
@@ -9346,7 +9400,8 @@
arm_ccfsm_state += 2;
return \"\";
}
- return output_return_instruction (operands[0], true, true, false);
+ return output_return_instruction (operands[0], true, true,
+ <return_simple_p>);
}"
[(set_attr "conds" "use")
(set_attr "length" "12")
@@ -12095,6 +12150,7 @@
(const_int 0)])]
"TARGET_32BIT"
""
+[(set_attr "predicated" "yes")]
)
(define_insn "force_register_use"
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index afb42421c06..b9ae2b09682 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -239,6 +239,10 @@ mword-relocations
Target Report Var(target_word_relocations) Init(TARGET_DEFAULT_WORD_RELOCATIONS)
Only generate absolute relocations on word sized values.
+mrestrict-it
+Target Report Var(arm_restrict_it) Init(2)
+Generate IT blocks appropriate for ARMv8.
+
mfix-cortex-m3-ldrd
Target Report Var(fix_cm3_ldrd) Init(2)
Avoid overlapping destination and address registers on LDRD instructions
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index b3ad42b376f..d84929f3d1f 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -496,3 +496,11 @@
(define_int_attr nvrint_variant [(UNSPEC_NVRINTZ "z") (UNSPEC_NVRINTP "p")
(UNSPEC_NVRINTA "a") (UNSPEC_NVRINTM "m")
(UNSPEC_NVRINTX "x") (UNSPEC_NVRINTN "n")])
+;; Both kinds of return insn.
+(define_code_iterator returns [return simple_return])
+(define_code_attr return_str [(return "") (simple_return "simple_")])
+(define_code_attr return_simple_p [(return "false") (simple_return "true")])
+(define_code_attr return_cond_false [(return " && USE_RETURN_INSN (FALSE)")
+ (simple_return " && use_simple_return_p ()")])
+(define_code_attr return_cond_true [(return " && USE_RETURN_INSN (TRUE)")
+ (simple_return " && use_simple_return_p ()")])
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index f91a6f7d08b..1697008531e 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -679,29 +679,6 @@
[(set_attr "neon_type" "neon_int_1")]
)
-(define_insn "iordi3_neon"
- [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r,?w,?w")
- (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r,w,0")
- (match_operand:DI 2 "neon_logic_op2" "w,Dl,r,r,w,Dl")))]
- "TARGET_NEON"
-{
- switch (which_alternative)
- {
- case 0: /* fall through */
- case 4: return "vorr\t%P0, %P1, %P2";
- case 1: /* fall through */
- case 5: return neon_output_logic_immediate ("vorr", &operands[2],
- DImode, 0, VALID_NEON_QREG_MODE (DImode));
- case 2: return "#";
- case 3: return "#";
- default: gcc_unreachable ();
- }
-}
- [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,neon_int_1,neon_int_1")
- (set_attr "length" "*,*,8,8,*,*")
- (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
-)
-
;; The concrete forms of the Neon immediate-logic instructions are vbic and
;; vorr. We support the pseudo-instruction vand instead, because that
;; corresponds to the canonical form the middle-end expects to use for
@@ -5617,7 +5594,7 @@
(match_operand:SI 3 "immediate_operand" "")]
"TARGET_NEON"
{
- emit_insn (gen_ior<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
+ emit_insn (gen_ior<mode>3 (operands[0], operands[1], operands[2]));
DONE;
})
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index 92de9fe8bd9..3cec5690193 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -42,6 +42,17 @@
(ior (match_operand 0 "imm_for_neon_inv_logic_operand")
(match_operand 0 "s_register_operand")))
+(define_predicate "imm_for_neon_logic_operand"
+ (match_code "const_vector")
+{
+ return (TARGET_NEON
+ && neon_immediate_valid_for_logic (op, mode, 0, NULL, NULL));
+})
+
+(define_predicate "neon_logic_op2"
+ (ior (match_operand 0 "imm_for_neon_logic_operand")
+ (match_operand 0 "s_register_operand")))
+
;; Any hard register.
(define_predicate "arm_hard_register_operand"
(match_code "reg")
@@ -162,6 +173,12 @@
(match_test "const_ok_for_dimode_op (INTVAL (op), AND)"))
(match_operand 0 "neon_inv_logic_op2")))
+(define_predicate "arm_iordi_operand_neon"
+ (ior (match_operand 0 "s_register_operand")
+ (and (match_code "const_int")
+ (match_test "const_ok_for_dimode_op (INTVAL (op), IOR)"))
+ (match_operand 0 "neon_logic_op2")))
+
(define_predicate "arm_adddi_operand"
(ior (match_operand 0 "s_register_operand")
(and (match_code "const_int")
@@ -535,17 +552,6 @@
(ior (match_operand 0 "s_register_operand")
(match_operand 0 "imm_for_neon_rshift_operand")))
-(define_predicate "imm_for_neon_logic_operand"
- (match_code "const_vector")
-{
- return (TARGET_NEON
- && neon_immediate_valid_for_logic (op, mode, 0, NULL, NULL));
-})
-
-(define_predicate "neon_logic_op2"
- (ior (match_operand 0 "imm_for_neon_logic_operand")
- (match_operand 0 "s_register_operand")))
-
;; Predicates for named expanders that overlap multiple ISAs.
(define_predicate "cmpdi_operand"
diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm
index fe075e5862a..246f0f5b540 100644
--- a/gcc/config/arm/t-arm
+++ b/gcc/config/arm/t-arm
@@ -78,8 +78,8 @@ $(srcdir)/config/arm/arm-tables.opt: $(srcdir)/config/arm/genopt.sh \
$(SHELL) $(srcdir)/config/arm/genopt.sh $(srcdir)/config/arm > \
$(srcdir)/config/arm/arm-tables.opt
-arm.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(RTL_H) $(TREE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \
+arm.o: $(srcdir)/config/arm/arm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \
insn-config.h conditions.h output.h dumpfile.h \
$(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \
$(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \
diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c
index e28f098b03a..249c4cd1d53 100644
--- a/gcc/config/i386/driver-i386.c
+++ b/gcc/config/i386/driver-i386.c
@@ -674,8 +674,14 @@ const char *host_detect_local_cpu (int argc, const char **argv)
/* Assume Sandy Bridge. */
cpu = "corei7-avx";
else if (has_sse4_2)
- /* Assume Core i7. */
- cpu = "corei7";
+ {
+ if (has_movbe)
+ /* Assume SLM. */
+ cpu = "slm";
+ else
+ /* Assume Core i7. */
+ cpu = "corei7";
+ }
else if (has_ssse3)
{
if (has_movbe)
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index 51fec844bdf..ef1e1eb3c62 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -149,6 +149,10 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
def_or_undef (parse_in, "__atom");
def_or_undef (parse_in, "__atom__");
break;
+ case PROCESSOR_SLM:
+ def_or_undef (parse_in, "__slm");
+ def_or_undef (parse_in, "__slm__");
+ break;
/* use PROCESSOR_max to not set/unset the arch macro. */
case PROCESSOR_max:
break;
@@ -241,6 +245,9 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
case PROCESSOR_ATOM:
def_or_undef (parse_in, "__tune_atom__");
break;
+ case PROCESSOR_SLM:
+ def_or_undef (parse_in, "__tune_slm__");
+ break;
case PROCESSOR_GENERIC32:
case PROCESSOR_GENERIC64:
break;
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 20163b1a8a1..77962c14521 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1482,6 +1482,79 @@ struct processor_costs atom_cost = {
1, /* cond_not_taken_branch_cost. */
};
+static const
+struct processor_costs slm_cost = {
+ COSTS_N_INSNS (1), /* cost of an add instruction */
+ COSTS_N_INSNS (1) + 1, /* cost of a lea instruction */
+ COSTS_N_INSNS (1), /* variable shift costs */
+ COSTS_N_INSNS (1), /* constant shift costs */
+ {COSTS_N_INSNS (3), /* cost of starting multiply for QI */
+ COSTS_N_INSNS (4), /* HI */
+ COSTS_N_INSNS (3), /* SI */
+ COSTS_N_INSNS (4), /* DI */
+ COSTS_N_INSNS (2)}, /* other */
+ 0, /* cost of multiply per each bit set */
+ {COSTS_N_INSNS (18), /* cost of a divide/mod for QI */
+ COSTS_N_INSNS (26), /* HI */
+ COSTS_N_INSNS (42), /* SI */
+ COSTS_N_INSNS (74), /* DI */
+ COSTS_N_INSNS (74)}, /* other */
+ COSTS_N_INSNS (1), /* cost of movsx */
+ COSTS_N_INSNS (1), /* cost of movzx */
+ 8, /* "large" insn */
+ 17, /* MOVE_RATIO */
+ 4, /* cost for loading QImode using movzbl */
+ {4, 4, 4}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {4, 4, 4}, /* cost of storing integer registers */
+ 4, /* cost of reg,reg fld/fst */
+ {12, 12, 12}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {6, 6, 8}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 2, /* cost of moving MMX register */
+ {8, 8}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {8, 8}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, /* cost of moving SSE register */
+ {8, 8, 8}, /* cost of loading SSE registers
+ in SImode, DImode and TImode */
+ {8, 8, 8}, /* cost of storing SSE registers
+ in SImode, DImode and TImode */
+ 5, /* MMX or SSE register to integer */
+ 32, /* size of l1 cache. */
+ 256, /* size of l2 cache. */
+ 64, /* size of prefetch block */
+ 6, /* number of parallel prefetches */
+ 3, /* Branch cost */
+ COSTS_N_INSNS (8), /* cost of FADD and FSUB insns. */
+ COSTS_N_INSNS (8), /* cost of FMUL instruction. */
+ COSTS_N_INSNS (20), /* cost of FDIV instruction. */
+ COSTS_N_INSNS (8), /* cost of FABS instruction. */
+ COSTS_N_INSNS (8), /* cost of FCHS instruction. */
+ COSTS_N_INSNS (40), /* cost of FSQRT instruction. */
+ {{libcall, {{11, loop, false}, {-1, rep_prefix_4_byte, false}}},
+ {libcall, {{32, loop, false}, {64, rep_prefix_4_byte, false},
+ {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}},
+ {{libcall, {{8, loop, false}, {15, unrolled_loop, false},
+ {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ {libcall, {{24, loop, false}, {32, unrolled_loop, false},
+ {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}},
+ 1, /* scalar_stmt_cost. */
+ 1, /* scalar load_cost. */
+ 1, /* scalar_store_cost. */
+ 1, /* vec_stmt_cost. */
+ 1, /* vec_to_scalar_cost. */
+ 1, /* scalar_to_vec_cost. */
+ 1, /* vec_align_load_cost. */
+ 2, /* vec_unalign_load_cost. */
+ 1, /* vec_store_cost. */
+ 3, /* cond_taken_branch_cost. */
+ 1, /* cond_not_taken_branch_cost. */
+};
+
/* Generic64 should produce code tuned for Nocona and K8. */
static const
struct processor_costs generic64_cost = {
@@ -1735,6 +1808,7 @@ const struct processor_costs *ix86_cost = &pentium_cost;
#define m_HASWELL (1<<PROCESSOR_HASWELL)
#define m_CORE_ALL (m_CORE2 | m_COREI7 | m_HASWELL)
#define m_ATOM (1<<PROCESSOR_ATOM)
+#define m_SLM (1<<PROCESSOR_SLM)
#define m_GEODE (1<<PROCESSOR_GEODE)
#define m_K6 (1<<PROCESSOR_K6)
@@ -1778,7 +1852,7 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
m_486 | m_PENT,
/* X86_TUNE_UNROLL_STRLEN */
- m_486 | m_PENT | m_PPRO | m_ATOM | m_CORE_ALL | m_K6 | m_AMD_MULTIPLE | m_GENERIC,
+ m_486 | m_PENT | m_PPRO | m_ATOM | m_SLM | m_CORE_ALL | m_K6 | m_AMD_MULTIPLE | m_GENERIC,
/* X86_TUNE_BRANCH_PREDICTION_HINTS: Branch hints were put in P4 based
on simulation result. But after P4 was made, no performance benefit
@@ -1790,11 +1864,11 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
~m_386,
/* X86_TUNE_USE_SAHF */
- m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_K6_GEODE | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER | m_GENERIC,
+ m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER | m_GENERIC,
/* X86_TUNE_MOVX: Enable to zero extend integer registers to avoid
partial dependencies. */
- m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_GEODE | m_AMD_MULTIPLE | m_GENERIC,
+ m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_GEODE | m_AMD_MULTIPLE | m_GENERIC,
/* X86_TUNE_PARTIAL_REG_STALL: We probably ought to watch for partial
register stalls on Generic32 compilation setting as well. However
@@ -1817,13 +1891,13 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
m_386 | m_486 | m_K6_GEODE,
/* X86_TUNE_USE_SIMODE_FIOP */
- ~(m_PENT | m_PPRO | m_CORE_ALL | m_ATOM | m_AMD_MULTIPLE | m_GENERIC),
+ ~(m_PENT | m_PPRO | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC),
/* X86_TUNE_USE_MOV0 */
m_K6,
/* X86_TUNE_USE_CLTD */
- ~(m_PENT | m_ATOM | m_K6),
+ ~(m_PENT | m_ATOM | m_SLM | m_K6),
/* X86_TUNE_USE_XCHGB: Use xchgb %rh,%rl instead of rolw/rorw $8,rx. */
m_PENT4,
@@ -1838,7 +1912,7 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
~(m_PENT | m_PPRO),
/* X86_TUNE_PROMOTE_QIMODE */
- m_386 | m_486 | m_PENT | m_CORE_ALL | m_ATOM | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC,
+ m_386 | m_486 | m_PENT | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC,
/* X86_TUNE_FAST_PREFIX */
~(m_386 | m_486 | m_PENT),
@@ -1879,10 +1953,10 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
/* X86_TUNE_INTEGER_DFMODE_MOVES: Enable if integer moves are preferred
for DFmode copies */
- ~(m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_GEODE | m_AMD_MULTIPLE | m_ATOM | m_GENERIC),
+ ~(m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_GEODE | m_AMD_MULTIPLE | m_GENERIC),
/* X86_TUNE_PARTIAL_REG_DEPENDENCY */
- m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_AMD_MULTIPLE | m_GENERIC,
+ m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC,
/* X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY: In the Generic model we have a
conflict here in between PPro/Pentium4 based chips that thread 128bit
@@ -1893,13 +1967,13 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
shows that disabling this option on P4 brings over 20% SPECfp regression,
while enabling it on K8 brings roughly 2.4% regression that can be partly
masked by careful scheduling of moves. */
- m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_AMDFAM10 | m_BDVER | m_GENERIC,
+ m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMDFAM10 | m_BDVER | m_GENERIC,
/* X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL */
- m_COREI7 | m_AMDFAM10 | m_BDVER | m_BTVER,
+ m_COREI7 | m_AMDFAM10 | m_BDVER | m_BTVER | m_SLM,
/* X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL */
- m_COREI7 | m_BDVER,
+ m_COREI7 | m_BDVER | m_SLM,
/* X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL */
m_BDVER ,
@@ -1917,7 +1991,7 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
m_PPRO | m_P4_NOCONA,
/* X86_TUNE_MEMORY_MISMATCH_STALL */
- m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_AMD_MULTIPLE | m_GENERIC,
+ m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC,
/* X86_TUNE_PROLOGUE_USING_MOVE */
m_PPRO | m_ATHLON_K8,
@@ -1942,16 +2016,16 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
/* X86_TUNE_FOUR_JUMP_LIMIT: Some CPU cores are not able to predict more
than 4 branch instructions in the 16 byte window. */
- m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_AMD_MULTIPLE | m_GENERIC,
+ m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC,
/* X86_TUNE_SCHEDULE */
- m_PENT | m_PPRO | m_CORE_ALL | m_ATOM | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC,
+ m_PENT | m_PPRO | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC,
/* X86_TUNE_USE_BT */
- m_CORE_ALL | m_ATOM | m_AMD_MULTIPLE | m_GENERIC,
+ m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC,
/* X86_TUNE_USE_INCDEC */
- ~(m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_GENERIC),
+ ~(m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_GENERIC),
/* X86_TUNE_PAD_RETURNS */
m_CORE_ALL | m_AMD_MULTIPLE | m_GENERIC,
@@ -1960,7 +2034,7 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
m_ATOM,
/* X86_TUNE_EXT_80387_CONSTANTS */
- m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_K6_GEODE | m_ATHLON_K8 | m_GENERIC,
+ m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE | m_ATHLON_K8 | m_GENERIC,
/* X86_TUNE_AVOID_VECTOR_DECODE */
m_CORE_ALL | m_K8 | m_GENERIC64,
@@ -2005,7 +2079,7 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
/* X86_TUNE_OPT_AGU: Optimize for Address Generation Unit. This flag
will impact LEA instruction selection. */
- m_ATOM,
+ m_ATOM | m_SLM,
/* X86_TUNE_VECTORIZE_DOUBLE: Enable double precision vector
instructions. */
@@ -2026,7 +2100,7 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
/* X86_TUNE_REASSOC_FP_TO_PARALLEL: Try to produce parallel computations
during reassociation of fp computation. */
- m_ATOM | m_HASWELL,
+ m_ATOM | m_SLM | m_HASWELL | m_BDVER1 | m_BDVER2,
/* X86_TUNE_GENERAL_REGS_SSE_SPILL: Try to spill general regs to SSE
regs instead of memory. */
@@ -2034,7 +2108,12 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
/* X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE: Try to avoid memory operands for
a conditional move. */
- m_ATOM
+ m_ATOM,
+
+ /* X86_TUNE_SPLIT_MEM_OPND_FOR_FP_CONVERTS: Try to split memory operand for
+ fp converts to destination register. */
+ m_SLM
+
};
/* Feature tests against the various architecture variations. */
@@ -2060,10 +2139,10 @@ static unsigned int initial_ix86_arch_features[X86_ARCH_LAST] = {
};
static const unsigned int x86_accumulate_outgoing_args
- = m_PPRO | m_P4_NOCONA | m_ATOM | m_CORE_ALL | m_AMD_MULTIPLE | m_GENERIC;
+ = m_PPRO | m_P4_NOCONA | m_ATOM | m_SLM | m_CORE_ALL | m_AMD_MULTIPLE | m_GENERIC;
static const unsigned int x86_arch_always_fancy_math_387
- = m_PENT | m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_AMD_MULTIPLE | m_GENERIC;
+ = m_PENT | m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC;
static const unsigned int x86_avx256_split_unaligned_load
= m_COREI7 | m_GENERIC;
@@ -2458,7 +2537,8 @@ static const struct ptt processor_target_table[PROCESSOR_max] =
{&bdver3_cost, 16, 10, 16, 7, 11},
{&btver1_cost, 16, 10, 16, 7, 11},
{&btver2_cost, 16, 10, 16, 7, 11},
- {&atom_cost, 16, 15, 16, 7, 16}
+ {&atom_cost, 16, 15, 16, 7, 16},
+ {&slm_cost, 16, 15, 16, 7, 16}
};
static const char *const cpu_names[TARGET_CPU_DEFAULT_max] =
@@ -2479,6 +2559,7 @@ static const char *const cpu_names[TARGET_CPU_DEFAULT_max] =
"corei7",
"core-avx2",
"atom",
+ "slm",
"geode",
"k6",
"k6-2",
@@ -2940,6 +3021,10 @@ ix86_option_override_internal (bool main_args_p)
{"atom", PROCESSOR_ATOM, CPU_ATOM,
PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
| PTA_SSSE3 | PTA_CX16 | PTA_MOVBE | PTA_FXSR},
+ {"slm", PROCESSOR_SLM, CPU_SLM,
+ PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
+ | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_CX16 | PTA_MOVBE
+ | PTA_FXSR},
{"geode", PROCESSOR_GEODE, CPU_GEODE,
PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_PREFETCH_SSE | PTA_PRFCHW},
{"k6", PROCESSOR_K6, CPU_K6, PTA_MMX},
@@ -17312,10 +17397,24 @@ distance_agu_use (unsigned int regno0, rtx insn)
static bool
ix86_lea_outperforms (rtx insn, unsigned int regno0, unsigned int regno1,
- unsigned int regno2, int split_cost)
+ unsigned int regno2, int split_cost, bool has_scale)
{
int dist_define, dist_use;
+ /* For Silvermont if using a 2-source or 3-source LEA for
+ non-destructive destination purposes, or due to wanting
+ ability to use SCALE, the use of LEA is justified. */
+ if (ix86_tune == PROCESSOR_SLM)
+ {
+ if (has_scale)
+ return true;
+ if (split_cost < 1)
+ return false;
+ if (regno0 == regno1 || regno0 == regno2)
+ return false;
+ return true;
+ }
+
dist_define = distance_non_agu_define (regno1, regno2, insn);
dist_use = distance_agu_use (regno0, insn);
@@ -17404,7 +17503,7 @@ ix86_avoid_lea_for_add (rtx insn, rtx operands[])
if (regno0 == regno1 || regno0 == regno2)
return false;
else
- return !ix86_lea_outperforms (insn, regno0, regno1, regno2, 1);
+ return !ix86_lea_outperforms (insn, regno0, regno1, regno2, 1, false);
}
/* Return true if we should emit lea instruction instead of mov
@@ -17426,7 +17525,7 @@ ix86_use_lea_for_mov (rtx insn, rtx operands[])
regno0 = true_regnum (operands[0]);
regno1 = true_regnum (operands[1]);
- return ix86_lea_outperforms (insn, regno0, regno1, INVALID_REGNUM, 0);
+ return ix86_lea_outperforms (insn, regno0, regno1, INVALID_REGNUM, 0, false);
}
/* Return true if we need to split lea into a sequence of
@@ -17505,7 +17604,8 @@ ix86_avoid_lea_for_addr (rtx insn, rtx operands[])
split_cost -= 1;
}
- return !ix86_lea_outperforms (insn, regno0, regno1, regno2, split_cost);
+ return !ix86_lea_outperforms (insn, regno0, regno1, regno2, split_cost,
+ parts.scale > 1);
}
/* Emit x86 binary operand CODE in mode MODE, where the first operand
@@ -17690,7 +17790,7 @@ ix86_lea_for_add_ok (rtx insn, rtx operands[])
if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
return false;
- return ix86_lea_outperforms (insn, regno0, regno1, regno2, 0);
+ return ix86_lea_outperforms (insn, regno0, regno1, regno2, 0, false);
}
/* Return true if destination reg of SET_BODY is shift count of
@@ -24199,6 +24299,7 @@ ix86_issue_rate (void)
{
case PROCESSOR_PENTIUM:
case PROCESSOR_ATOM:
+ case PROCESSOR_SLM:
case PROCESSOR_K6:
case PROCESSOR_BTVER2:
return 2;
@@ -24287,6 +24388,73 @@ ix86_agi_dependent (rtx set_insn, rtx use_insn)
return false;
}
+/* Helper function for exact_store_load_dependency.
+ Return true if addr is found in insn. */
+static bool
+exact_dependency_1 (rtx addr, rtx insn)
+{
+ enum rtx_code code;
+ const char *format_ptr;
+ int i, j;
+
+ code = GET_CODE (insn);
+ switch (code)
+ {
+ case MEM:
+ if (rtx_equal_p (addr, insn))
+ return true;
+ break;
+ case REG:
+ CASE_CONST_ANY:
+ case SYMBOL_REF:
+ case CODE_LABEL:
+ case PC:
+ case CC0:
+ case EXPR_LIST:
+ return false;
+ default:
+ break;
+ }
+
+ format_ptr = GET_RTX_FORMAT (code);
+ for (i = 0; i < GET_RTX_LENGTH (code); i++)
+ {
+ switch (*format_ptr++)
+ {
+ case 'e':
+ if (exact_dependency_1 (addr, XEXP (insn, i)))
+ return true;
+ break;
+ case 'E':
+ for (j = 0; j < XVECLEN (insn, i); j++)
+ if (exact_dependency_1 (addr, XVECEXP (insn, i, j)))
+ return true;
+ break;
+ }
+ }
+ return false;
+}
+
+/* Return true if there exists exact dependency for store & load, i.e.
+ the same memory address is used in them. */
+static bool
+exact_store_load_dependency (rtx store, rtx load)
+{
+ rtx set1, set2;
+
+ set1 = single_set (store);
+ if (!set1)
+ return false;
+ if (!MEM_P (SET_DEST (set1)))
+ return false;
+ set2 = single_set (load);
+ if (!set2)
+ return false;
+ if (exact_dependency_1 (SET_DEST (set1), SET_SRC (set2)))
+ return true;
+ return false;
+}
+
static int
ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
{
@@ -24438,6 +24606,39 @@ ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
else
cost = 0;
}
+ break;
+
+ case PROCESSOR_SLM:
+ if (!reload_completed)
+ return cost;
+
+ /* Increase cost of integer loads. */
+ memory = get_attr_memory (dep_insn);
+ if (memory == MEMORY_LOAD || memory == MEMORY_BOTH)
+ {
+ enum attr_unit unit = get_attr_unit (dep_insn);
+ if (unit == UNIT_INTEGER && cost == 1)
+ {
+ if (memory == MEMORY_LOAD)
+ cost = 3;
+ else
+ {
+ /* Increase cost of ld/st for short int types only
+ because of store forwarding issue. */
+ rtx set = single_set (dep_insn);
+ if (set && (GET_MODE (SET_DEST (set)) == QImode
+ || GET_MODE (SET_DEST (set)) == HImode))
+ {
+ /* Increase cost of store/load insn if exact
+ dependence exists and it is load insn. */
+ enum attr_memory insn_memory = get_attr_memory (insn);
+ if (insn_memory == MEMORY_LOAD
+ && exact_store_load_dependency (dep_insn, insn))
+ cost = 3;
+ }
+ }
+ }
+ }
default:
break;
@@ -24466,6 +24667,7 @@ ia32_multipass_dfa_lookahead (void)
case PROCESSOR_COREI7:
case PROCESSOR_HASWELL:
case PROCESSOR_ATOM:
+ case PROCESSOR_SLM:
/* Generally, we want haifa-sched:max_issue() to look ahead as far
as many instructions can be executed on a cycle, i.e.,
issue_rate. I wonder why tuning for many CPUs does not do this. */
@@ -24483,110 +24685,204 @@ ia32_multipass_dfa_lookahead (void)
execution. It is applied if
(1) IMUL instruction is on the top of list;
(2) There exists the only producer of independent IMUL instruction in
- ready list;
- (3) Put found producer on the top of ready list.
- Returns issue rate. */
-
+ ready list.
+ Return index of IMUL producer if it was found and -1 otherwise. */
static int
-ix86_sched_reorder(FILE *dump, int sched_verbose, rtx *ready, int *pn_ready,
- int clock_var ATTRIBUTE_UNUSED)
+do_reorder_for_imul (rtx *ready, int n_ready)
{
- static int issue_rate = -1;
- int n_ready = *pn_ready;
- rtx insn, insn1, insn2;
- int i;
+ rtx insn, set, insn1, insn2;
sd_iterator_def sd_it;
dep_t dep;
int index = -1;
+ int i;
- /* Set up issue rate. */
- issue_rate = ix86_issue_rate();
-
- /* Do reodering for Atom only. */
if (ix86_tune != PROCESSOR_ATOM)
- return issue_rate;
- /* Do not perform ready list reodering for pre-reload schedule pass. */
- if (!reload_completed)
- return issue_rate;
- /* Nothing to do if ready list contains only 1 instruction. */
- if (n_ready <= 1)
- return issue_rate;
+ return index;
/* Check that IMUL instruction is on the top of ready list. */
insn = ready[n_ready - 1];
- if (!NONDEBUG_INSN_P (insn))
- return issue_rate;
- insn = PATTERN (insn);
- if (GET_CODE (insn) == PARALLEL)
- insn = XVECEXP (insn, 0, 0);
- if (GET_CODE (insn) != SET)
- return issue_rate;
- if (!(GET_CODE (SET_SRC (insn)) == MULT
- && GET_MODE (SET_SRC (insn)) == SImode))
- return issue_rate;
+ set = single_set (insn);
+ if (!set)
+ return index;
+ if (!(GET_CODE (SET_SRC (set)) == MULT
+ && GET_MODE (SET_SRC (set)) == SImode))
+ return index;
/* Search for producer of independent IMUL instruction. */
- for (i = n_ready - 2; i>= 0; i--)
+ for (i = n_ready - 2; i >= 0; i--)
{
insn = ready[i];
if (!NONDEBUG_INSN_P (insn))
- continue;
+ continue;
/* Skip IMUL instruction. */
insn2 = PATTERN (insn);
if (GET_CODE (insn2) == PARALLEL)
- insn2 = XVECEXP (insn2, 0, 0);
+ insn2 = XVECEXP (insn2, 0, 0);
if (GET_CODE (insn2) == SET
- && GET_CODE (SET_SRC (insn2)) == MULT
- && GET_MODE (SET_SRC (insn2)) == SImode)
- continue;
+ && GET_CODE (SET_SRC (insn2)) == MULT
+ && GET_MODE (SET_SRC (insn2)) == SImode)
+ continue;
FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
- {
- rtx con;
+ {
+ rtx con;
con = DEP_CON (dep);
if (!NONDEBUG_INSN_P (con))
continue;
- insn1 = PATTERN (con);
- if (GET_CODE (insn1) == PARALLEL)
- insn1 = XVECEXP (insn1, 0, 0);
-
- if (GET_CODE (insn1) == SET
- && GET_CODE (SET_SRC (insn1)) == MULT
- && GET_MODE (SET_SRC (insn1)) == SImode)
- {
- sd_iterator_def sd_it1;
- dep_t dep1;
- /* Check if there is no other dependee for IMUL. */
- index = i;
- FOR_EACH_DEP (con, SD_LIST_BACK, sd_it1, dep1)
- {
- rtx pro;
- pro = DEP_PRO (dep1);
+ insn1 = PATTERN (con);
+ if (GET_CODE (insn1) == PARALLEL)
+ insn1 = XVECEXP (insn1, 0, 0);
+
+ if (GET_CODE (insn1) == SET
+ && GET_CODE (SET_SRC (insn1)) == MULT
+ && GET_MODE (SET_SRC (insn1)) == SImode)
+ {
+ sd_iterator_def sd_it1;
+ dep_t dep1;
+ /* Check if there is no other dependee for IMUL. */
+ index = i;
+ FOR_EACH_DEP (con, SD_LIST_BACK, sd_it1, dep1)
+ {
+ rtx pro;
+ pro = DEP_PRO (dep1);
if (!NONDEBUG_INSN_P (pro))
continue;
- if (pro != insn)
- index = -1;
- }
- if (index >= 0)
- break;
- }
- }
+ if (pro != insn)
+ index = -1;
+ }
+ if (index >= 0)
+ break;
+ }
+ }
if (index >= 0)
- break;
+ break;
}
- if (index < 0)
- return issue_rate; /* Didn't find IMUL producer. */
+ return index;
+}
- if (sched_verbose > 1)
- fprintf(dump, ";;\tatom sched_reorder: swap %d and %d insns\n",
- INSN_UID (ready[index]), INSN_UID (ready[n_ready - 1]));
+/* Try to find the best candidate on the top of ready list if two insns
+ have the same priority - candidate is best if its dependees were
+ scheduled earlier. Applied for Silvermont only.
+ Return true if top 2 insns must be interchanged. */
+static bool
+swap_top_of_ready_list (rtx *ready, int n_ready)
+{
+ rtx top = ready[n_ready - 1];
+ rtx next = ready[n_ready - 2];
+ rtx set;
+ sd_iterator_def sd_it;
+ dep_t dep;
+ int clock1 = -1;
+ int clock2 = -1;
+ #define INSN_TICK(INSN) (HID (INSN)->tick)
+
+ if (ix86_tune != PROCESSOR_SLM)
+ return false;
+
+ if (!NONDEBUG_INSN_P (top))
+ return false;
+ if (!NONJUMP_INSN_P (top))
+ return false;
+ if (!NONDEBUG_INSN_P (next))
+ return false;
+ if (!NONJUMP_INSN_P (next))
+ return false;
+ set = single_set (top);
+ if (!set)
+ return false;
+ set = single_set (next);
+ if (!set)
+ return false;
+
+ if (INSN_PRIORITY_KNOWN (top) && INSN_PRIORITY_KNOWN (next))
+ {
+ if (INSN_PRIORITY (top) != INSN_PRIORITY (next))
+ return false;
+ /* Determine winner more precise. */
+ FOR_EACH_DEP (top, SD_LIST_RES_BACK, sd_it, dep)
+ {
+ rtx pro;
+ pro = DEP_PRO (dep);
+ if (!NONDEBUG_INSN_P (pro))
+ continue;
+ if (INSN_TICK (pro) > clock1)
+ clock1 = INSN_TICK (pro);
+ }
+ FOR_EACH_DEP (next, SD_LIST_RES_BACK, sd_it, dep)
+ {
+ rtx pro;
+ pro = DEP_PRO (dep);
+ if (!NONDEBUG_INSN_P (pro))
+ continue;
+ if (INSN_TICK (pro) > clock2)
+ clock2 = INSN_TICK (pro);
+ }
+
+ if (clock1 == clock2)
+ {
+ /* Determine winner - load must win. */
+ enum attr_memory memory1, memory2;
+ memory1 = get_attr_memory (top);
+ memory2 = get_attr_memory (next);
+ if (memory2 == MEMORY_LOAD && memory1 != MEMORY_LOAD)
+ return true;
+ }
+ return (bool) (clock2 < clock1);
+ }
+ return false;
+ #undef INSN_TICK
+}
+
+/* Perform possible reodering of ready list for Atom/Silvermont only.
+ Return issue rate. */
+static int
+ix86_sched_reorder (FILE *dump, int sched_verbose, rtx *ready, int *pn_ready,
+ int clock_var)
+{
+ int issue_rate = -1;
+ int n_ready = *pn_ready;
+ int i;
+ rtx insn;
+ int index = -1;
+
+ /* Set up issue rate. */
+ issue_rate = ix86_issue_rate ();
+
+ /* Do reodering for Atom/SLM only. */
+ if (ix86_tune != PROCESSOR_ATOM && ix86_tune != PROCESSOR_SLM)
+ return issue_rate;
- /* Put IMUL producer (ready[index]) at the top of ready list. */
- insn1= ready[index];
- for (i = index; i < n_ready - 1; i++)
- ready[i] = ready[i + 1];
- ready[n_ready - 1] = insn1;
+ /* Nothing to do if ready list contains only 1 instruction. */
+ if (n_ready <= 1)
+ return issue_rate;
+
+ /* Do reodering for post-reload scheduler only. */
+ if (!reload_completed)
+ return issue_rate;
+
+ if ((index = do_reorder_for_imul (ready, n_ready)) >= 0)
+ {
+ if (sched_verbose > 1)
+ fprintf (dump, ";;\tatom sched_reorder: put %d insn on top\n",
+ INSN_UID (ready[index]));
+ /* Put IMUL producer (ready[index]) at the top of ready list. */
+ insn = ready[index];
+ for (i = index; i < n_ready - 1; i++)
+ ready[i] = ready[i + 1];
+ ready[n_ready - 1] = insn;
+ return issue_rate;
+ }
+ if (clock_var != 0 && swap_top_of_ready_list (ready, n_ready))
+ {
+ if (sched_verbose > 1)
+ fprintf (dump, ";;\tslm sched_reorder: swap %d and %d insns\n",
+ INSN_UID (ready[n_ready - 1]), INSN_UID (ready[n_ready - 2]));
+ /* Swap 2 top elements of ready list. */
+ insn = ready[n_ready - 1];
+ ready[n_ready - 1] = ready[n_ready - 2];
+ ready[n_ready - 2] = insn;
+ }
return issue_rate;
}
@@ -29468,7 +29764,7 @@ ix86_get_function_versions_dispatcher (void *decl)
dispatcher_version_info
= insert_new_cgraph_node_version (dispatcher_node);
dispatcher_version_info->next = default_version_info;
- dispatcher_node->local.finalized = 1;
+ dispatcher_node->symbol.definition = 1;
/* Set the dispatcher for all the versions. */
it_v = default_version_info;
@@ -29623,7 +29919,7 @@ ix86_generate_version_dispatcher_body (void *node_p)
default_ver_decl = node_version_info->next->this_node->symbol.decl;
/* node is going to be an alias, so remove the finalized bit. */
- node->local.finalized = false;
+ node->symbol.definition = false;
resolver_decl = make_resolver_func (default_ver_decl,
node->symbol.decl, &empty_bb);
@@ -29756,6 +30052,7 @@ fold_builtin_cpu (tree fndecl, tree *args)
M_INTEL_COREI7,
M_AMDFAM10H,
M_AMDFAM15H,
+ M_INTEL_SLM,
M_CPU_SUBTYPE_START,
M_INTEL_COREI7_NEHALEM,
M_INTEL_COREI7_WESTMERE,
@@ -29778,6 +30075,7 @@ fold_builtin_cpu (tree fndecl, tree *args)
{"amd", M_AMD},
{"intel", M_INTEL},
{"atom", M_INTEL_ATOM},
+ {"slm", M_INTEL_SLM},
{"core2", M_INTEL_CORE2},
{"corei7", M_INTEL_COREI7},
{"nehalem", M_INTEL_COREI7_NEHALEM},
@@ -29817,6 +30115,9 @@ fold_builtin_cpu (tree fndecl, tree *args)
tree __cpu_model_var = make_var_decl (__processor_model_type,
"__cpu_model");
+
+ varpool_add_new_variable (__cpu_model_var);
+
gcc_assert ((args != NULL) && (*args != NULL));
param_string_cst = *args;
@@ -42725,6 +43026,9 @@ ix86_memmodel_check (unsigned HOST_WIDE_INT val)
#undef TARGET_REGISTER_PRIORITY
#define TARGET_REGISTER_PRIORITY ix86_register_priority
+#undef TARGET_REGISTER_USAGE_LEVELING_P
+#define TARGET_REGISTER_USAGE_LEVELING_P hook_bool_void_true
+
#undef TARGET_LEGITIMATE_CONSTANT_P
#define TARGET_LEGITIMATE_CONSTANT_P ix86_legitimate_constant_p
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 6055b99a55b..5dcd69f621d 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -257,6 +257,7 @@ extern const struct processor_costs ix86_size_cost;
#define TARGET_BTVER1 (ix86_tune == PROCESSOR_BTVER1)
#define TARGET_BTVER2 (ix86_tune == PROCESSOR_BTVER2)
#define TARGET_ATOM (ix86_tune == PROCESSOR_ATOM)
+#define TARGET_SLM (ix86_tune == PROCESSOR_SLM)
/* Feature tests against the various tunings. */
enum ix86_tune_indices {
@@ -332,6 +333,7 @@ enum ix86_tune_indices {
X86_TUNE_REASSOC_FP_TO_PARALLEL,
X86_TUNE_GENERAL_REGS_SSE_SPILL,
X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE,
+ X86_TUNE_SPLIT_MEM_OPND_FOR_FP_CONVERTS,
X86_TUNE_LAST
};
@@ -442,6 +444,8 @@ extern unsigned char ix86_tune_features[X86_TUNE_LAST];
ix86_tune_features[X86_TUNE_GENERAL_REGS_SSE_SPILL]
#define TARGET_AVOID_MEM_OPND_FOR_CMOVE \
ix86_tune_features[X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE]
+#define TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS \
+ ix86_tune_features[X86_TUNE_SPLIT_MEM_OPND_FOR_FP_CONVERTS]
/* Feature tests against the various architecture variations. */
enum ix86_arch_indices {
@@ -623,6 +627,7 @@ enum target_cpu_default
TARGET_CPU_DEFAULT_corei7,
TARGET_CPU_DEFAULT_haswell,
TARGET_CPU_DEFAULT_atom,
+ TARGET_CPU_DEFAULT_slm,
TARGET_CPU_DEFAULT_geode,
TARGET_CPU_DEFAULT_k6,
@@ -2131,6 +2136,7 @@ enum processor_type
PROCESSOR_BTVER1,
PROCESSOR_BTVER2,
PROCESSOR_ATOM,
+ PROCESSOR_SLM,
PROCESSOR_max
};
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index ce77f15f009..018678dc850 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -323,7 +323,7 @@
;; Processor type.
(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
- atom,generic64,amdfam10,bdver1,bdver2,bdver3,btver1,btver2"
+ atom,slm,generic64,amdfam10,bdver1,bdver2,bdver3,btver1,btver2"
(const (symbol_ref "ix86_schedule")))
;; A basic instruction type. Refinements due to arguments to be
@@ -964,6 +964,7 @@
(include "btver2.md")
(include "geode.md")
(include "atom.md")
+(include "slm.md")
(include "core2.md")
@@ -3624,6 +3625,18 @@
CONST0_RTX (V4SFmode), operands[1]));
})
+;; It's more profitable to split and then extend in the same register.
+(define_peephole2
+ [(set (match_operand:DF 0 "register_operand")
+ (float_extend:DF
+ (match_operand:SF 1 "memory_operand")))]
+ "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
+ && optimize_insn_for_speed_p ()
+ && SSE_REG_P (operands[0])"
+ [(set (match_dup 2) (match_dup 1))
+ (set (match_dup 0) (float_extend:DF (match_dup 2)))]
+ "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
+
(define_insn "*extendsfdf2_mixed"
[(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
(float_extend:DF
@@ -3765,6 +3778,18 @@
CONST0_RTX (V2DFmode), operands[1]));
})
+;; It's more profitable to split and then extend in the same register.
+(define_peephole2
+ [(set (match_operand:SF 0 "register_operand")
+ (float_truncate:SF
+ (match_operand:DF 1 "memory_operand")))]
+ "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
+ && optimize_insn_for_speed_p ()
+ && SSE_REG_P (operands[0])"
+ [(set (match_dup 2) (match_dup 1))
+ (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
+ "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
+
(define_expand "truncdfsf2_with_temp"
[(parallel [(set (match_operand:SF 0)
(float_truncate:SF (match_operand:DF 1)))
diff --git a/gcc/config/i386/slm.md b/gcc/config/i386/slm.md
new file mode 100644
index 00000000000..3ac919e372c
--- /dev/null
+++ b/gcc/config/i386/slm.md
@@ -0,0 +1,758 @@
+;; Slivermont(SLM) Scheduling
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+;;
+;; Silvermont has 2 out-of-order IEC, 2 in-order FEC and 1 in-order MEC.
+
+
+(define_automaton "slm")
+
+;; EU: Execution Unit
+;; Silvermont EUs are connected by port 0 or port 1.
+
+;; SLM has two ports: port 0 and port 1 connecting to all execution units
+(define_cpu_unit "slm-port-0,slm-port-1" "slm")
+
+(define_cpu_unit "slm-ieu-0, slm-ieu-1,
+ slm-imul, slm-feu-0, slm-feu-1"
+ "slm")
+
+(define_reservation "slm-all-ieu" "(slm-ieu-0 + slm-ieu-1 + slm-imul)")
+(define_reservation "slm-all-feu" "(slm-feu-0 + slm-feu-1)")
+(define_reservation "slm-all-eu" "(slm-all-ieu + slm-all-feu)")
+(define_reservation "slm-fp-0" "(slm-port-0 + slm-feu-0)")
+
+;; Some EUs have duplicated copied and can be accessed via either
+;; port 0 or port 1
+;; (define_reservation "slm-port-either" "(slm-port-0 | slm-port-1)"
+(define_reservation "slm-port-dual" "(slm-port-0 + slm-port-1)")
+
+;;; fmul insn can have 4 or 5 cycles latency
+(define_reservation "slm-fmul-5c"
+ "(slm-port-0 + slm-feu-0), slm-feu-0, nothing*3")
+(define_reservation "slm-fmul-4c" "(slm-port-0 + slm-feu-0), nothing*3")
+
+;;; fadd can has 3 cycles latency depends on instruction forms
+(define_reservation "slm-fadd-3c" "(slm-port-1 + slm-feu-1), nothing*2")
+(define_reservation "slm-fadd-4c"
+ "(slm-port-1 + slm-feu-1), slm-feu-1, nothing*2")
+
+;;; imul insn has 3 cycles latency for SI operands
+(define_reservation "slm-imul-32"
+ "(slm-port-1 + slm-imul), nothing*2")
+(define_reservation "slm-imul-mem-32"
+ "(slm-port-1 + slm-imul + slm-port-0), nothing*2")
+;;; imul has 4 cycles latency for DI operands with 1/2 tput
+(define_reservation "slm-imul-64"
+ "(slm-port-1 + slm-imul), slm-imul, nothing*2")
+
+;;; dual-execution instructions can have 1,2,4,5 cycles latency depends on
+;;; instruction forms
+(define_reservation "slm-dual-1c" "(slm-port-dual + slm-all-eu)")
+(define_reservation "slm-dual-2c"
+ "(slm-port-dual + slm-all-eu, nothing)")
+
+;;; Most of simple ALU instructions have 1 cycle latency. Some of them
+;;; issue in port 0, some in port 0 and some in either port.
+(define_reservation "slm-simple-0" "(slm-port-0 + slm-ieu-0)")
+(define_reservation "slm-simple-1" "(slm-port-1 + slm-ieu-1)")
+(define_reservation "slm-simple-either" "(slm-simple-0 | slm-simple-1)")
+
+;;; Complex macro-instruction has variants of latency, and uses both ports.
+(define_reservation "slm-complex" "(slm-port-dual + slm-all-eu)")
+
+(define_insn_reservation "slm_other" 9
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "other")
+ (eq_attr "atom_unit" "!jeu")))
+ "slm-complex, slm-all-eu*8")
+
+;; return has type "other" with atom_unit "jeu"
+(define_insn_reservation "slm_other_2" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "other")
+ (eq_attr "atom_unit" "jeu")))
+ "slm-dual-1c")
+
+(define_insn_reservation "slm_multi" 9
+ (and (eq_attr "cpu" "slm")
+ (eq_attr "type" "multi"))
+ "slm-complex, slm-all-eu*8")
+
+;; Normal alu insns without carry
+(define_insn_reservation "slm_alu" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "alu")
+ (and (eq_attr "memory" "none")
+ (eq_attr "use_carry" "0"))))
+ "slm-simple-either")
+
+;; Normal alu insns without carry, but use MEC.
+(define_insn_reservation "slm_alu_mem" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "alu")
+ (and (eq_attr "memory" "!none")
+ (eq_attr "use_carry" "0"))))
+ "slm-simple-either")
+
+;; Alu insn consuming CF, such as add/sbb
+(define_insn_reservation "slm_alu_carry" 2
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "alu")
+ (and (eq_attr "memory" "none")
+ (eq_attr "use_carry" "1"))))
+ "slm-simple-either, nothing")
+
+;; Alu insn consuming CF, such as add/sbb
+(define_insn_reservation "slm_alu_carry_mem" 2
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "alu")
+ (and (eq_attr "memory" "!none")
+ (eq_attr "use_carry" "1"))))
+ "slm-simple-either, nothing")
+
+(define_insn_reservation "slm_alu1" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "alu1")
+ (eq_attr "memory" "none") (eq_attr "prefix_0f" "0")))
+ "slm-simple-either")
+
+;; bsf and bsf insn
+(define_insn_reservation "slm_alu1_1" 10
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "alu1")
+ (eq_attr "memory" "none") (eq_attr "prefix_0f" "1")))
+ "slm-simple-1, slm-ieu-1*9")
+
+(define_insn_reservation "slm_alu1_mem" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "alu1")
+ (eq_attr "memory" "!none")))
+ "slm-simple-either")
+
+(define_insn_reservation "slm_negnot" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "negnot")
+ (eq_attr "memory" "none")))
+ "slm-simple-either")
+
+(define_insn_reservation "slm_negnot_mem" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "negnot")
+ (eq_attr "memory" "!none")))
+ "slm-simple-either")
+
+(define_insn_reservation "slm_imov" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "imov")
+ (eq_attr "memory" "none")))
+ "slm-simple-either")
+
+(define_insn_reservation "slm_imov_mem" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "imov")
+ (eq_attr "memory" "!none")))
+ "slm-simple-0")
+
+;; 16<-16, 32<-32
+(define_insn_reservation "slm_imovx" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "imovx")
+ (and (eq_attr "memory" "none")
+ (ior (and (match_operand:HI 0 "register_operand")
+ (match_operand:HI 1 "general_operand"))
+ (and (match_operand:SI 0 "register_operand")
+ (match_operand:SI 1 "general_operand"))))))
+ "slm-simple-either")
+
+;; 16<-16, 32<-32, mem
+(define_insn_reservation "slm_imovx_mem" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "imovx")
+ (and (eq_attr "memory" "!none")
+ (ior (and (match_operand:HI 0 "register_operand")
+ (match_operand:HI 1 "general_operand"))
+ (and (match_operand:SI 0 "register_operand")
+ (match_operand:SI 1 "general_operand"))))))
+ "slm-simple-either")
+
+;; 32<-16, 32<-8, 64<-16, 64<-8, 64<-32, 8<-8
+(define_insn_reservation "slm_imovx_2" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "imovx")
+ (and (eq_attr "memory" "none")
+ (ior (match_operand:QI 0 "register_operand")
+ (ior (and (match_operand:SI 0 "register_operand")
+ (not (match_operand:SI 1 "general_operand")))
+ (match_operand:DI 0 "register_operand"))))))
+ "slm-simple-either")
+
+;; 32<-16, 32<-8, 64<-16, 64<-8, 64<-32, 8<-8, mem
+(define_insn_reservation "slm_imovx_2_mem" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "imovx")
+ (and (eq_attr "memory" "!none")
+ (ior (match_operand:QI 0 "register_operand")
+ (ior (and (match_operand:SI 0 "register_operand")
+ (not (match_operand:SI 1 "general_operand")))
+ (match_operand:DI 0 "register_operand"))))))
+ "slm-simple-0")
+
+;; 16<-8
+(define_insn_reservation "slm_imovx_3" 3
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "imovx")
+ (and (match_operand:HI 0 "register_operand")
+ (match_operand:QI 1 "general_operand"))))
+ "slm-simple-0, nothing*2")
+
+(define_insn_reservation "slm_lea" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "lea")
+ (eq_attr "mode" "!HI")))
+ "slm-simple-either")
+
+;; lea 16bit address is complex insn
+(define_insn_reservation "slm_lea_2" 2
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "lea")
+ (eq_attr "mode" "HI")))
+ "slm-complex, slm-all-eu")
+
+(define_insn_reservation "slm_incdec" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "incdec")
+ (eq_attr "memory" "none")))
+ "slm-simple-0")
+
+(define_insn_reservation "slm_incdec_mem" 3
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "incdec")
+ (eq_attr "memory" "!none")))
+ "slm-simple-0, nothing*2")
+
+;; simple shift instruction use SHIFT eu, none memory
+(define_insn_reservation "slm_ishift" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ishift")
+ (and (eq_attr "memory" "none") (eq_attr "prefix_0f" "0"))))
+ "slm-simple-0")
+
+;; simple shift instruction use SHIFT eu, memory
+(define_insn_reservation "slm_ishift_mem" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ishift")
+ (and (eq_attr "memory" "!none") (eq_attr "prefix_0f" "0"))))
+ "slm-simple-0")
+
+;; DF shift (prefixed with 0f) is complex insn with latency of 4 cycles
+(define_insn_reservation "slm_ishift_3" 4
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ishift")
+ (eq_attr "prefix_0f" "1")))
+ "slm-complex, slm-all-eu*3")
+
+(define_insn_reservation "slm_ishift1" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ishift1")
+ (eq_attr "memory" "none")))
+ "slm-simple-0")
+
+(define_insn_reservation "slm_ishift1_mem" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ishift1")
+ (eq_attr "memory" "!none")))
+ "slm-simple-0")
+
+(define_insn_reservation "slm_rotate" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "rotate")
+ (eq_attr "memory" "none")))
+ "slm-simple-0")
+
+(define_insn_reservation "slm_rotate_mem" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "rotate")
+ (eq_attr "memory" "!none")))
+ "slm-simple-0")
+
+(define_insn_reservation "slm_rotate1" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "rotate1")
+ (eq_attr "memory" "none")))
+ "slm-simple-0")
+
+(define_insn_reservation "slm_rotate1_mem" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "rotate1")
+ (eq_attr "memory" "!none")))
+ "slm-simple-0")
+
+(define_insn_reservation "slm_imul" 3
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "imul")
+ (and (eq_attr "memory" "none") (eq_attr "mode" "SI"))))
+ "slm-imul-32")
+
+(define_insn_reservation "slm_imul_mem" 3
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "imul")
+ (and (eq_attr "memory" "!none") (eq_attr "mode" "SI"))))
+ "slm-imul-mem-32")
+
+;; latency set to 4 as common 64x64 imul with 1/2 tput
+(define_insn_reservation "slm_imul_3" 4
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "imul")
+ (eq_attr "mode" "!SI")))
+ "slm-imul-64")
+
+(define_insn_reservation "slm_idiv" 33
+ (and (eq_attr "cpu" "slm")
+ (eq_attr "type" "idiv"))
+ "slm-complex, slm-all-eu*16, nothing*16")
+
+(define_insn_reservation "slm_icmp" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "icmp")
+ (eq_attr "memory" "none")))
+ "slm-simple-either")
+
+(define_insn_reservation "slm_icmp_mem" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "icmp")
+ (eq_attr "memory" "!none")))
+ "slm-simple-either")
+
+(define_insn_reservation "slm_test" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "test")
+ (eq_attr "memory" "none")))
+ "slm-simple-either")
+
+(define_insn_reservation "slm_test_mem" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "test")
+ (eq_attr "memory" "!none")))
+ "slm-simple-either")
+
+(define_insn_reservation "slm_ibr" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ibr")
+ (eq_attr "memory" "!load")))
+ "slm-simple-1")
+
+;; complex if jump target is from address
+(define_insn_reservation "slm_ibr_2" 2
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ibr")
+ (eq_attr "memory" "load")))
+ "slm-complex, slm-all-eu")
+
+(define_insn_reservation "slm_setcc" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "setcc")
+ (eq_attr "memory" "!store")))
+ "slm-simple-either")
+
+;; 2 cycles complex if target is in memory
+(define_insn_reservation "slm_setcc_2" 2
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "setcc")
+ (eq_attr "memory" "store")))
+ "slm-complex, slm-all-eu")
+
+(define_insn_reservation "slm_icmov" 2
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "icmov")
+ (eq_attr "memory" "none")))
+ "slm-simple-either, nothing")
+
+(define_insn_reservation "slm_icmov_mem" 2
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "icmov")
+ (eq_attr "memory" "!none")))
+ "slm-simple-0, nothing")
+
+;; UCODE if segreg, ignored
+(define_insn_reservation "slm_push" 2
+ (and (eq_attr "cpu" "slm")
+ (eq_attr "type" "push"))
+ "slm-dual-2c")
+
+;; pop r64 is 1 cycle. UCODE if segreg, ignored
+(define_insn_reservation "slm_pop" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "pop")
+ (eq_attr "mode" "DI")))
+ "slm-dual-1c")
+
+;; pop non-r64 is 2 cycles. UCODE if segreg, ignored
+(define_insn_reservation "slm_pop_2" 2
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "pop")
+ (eq_attr "mode" "!DI")))
+ "slm-dual-2c")
+
+;; UCODE if segreg, ignored
+(define_insn_reservation "slm_call" 1
+ (and (eq_attr "cpu" "slm")
+ (eq_attr "type" "call"))
+ "slm-dual-1c")
+
+(define_insn_reservation "slm_callv" 1
+ (and (eq_attr "cpu" "slm")
+ (eq_attr "type" "callv"))
+ "slm-dual-1c")
+
+(define_insn_reservation "slm_leave" 3
+ (and (eq_attr "cpu" "slm")
+ (eq_attr "type" "leave"))
+ "slm-complex, slm-all-eu*2")
+
+(define_insn_reservation "slm_str" 3
+ (and (eq_attr "cpu" "slm")
+ (eq_attr "type" "str"))
+ "slm-complex, slm-all-eu*2")
+
+(define_insn_reservation "slm_sselog" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sselog")
+ (eq_attr "memory" "none")))
+ "slm-simple-either")
+
+(define_insn_reservation "slm_sselog_mem" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sselog")
+ (eq_attr "memory" "!none")))
+ "slm-simple-either")
+
+(define_insn_reservation "slm_sselog1" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sselog1")
+ (eq_attr "memory" "none")))
+ "slm-simple-0")
+
+(define_insn_reservation "slm_sselog1_mem" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sselog1")
+ (eq_attr "memory" "!none")))
+ "slm-simple-0")
+
+;; not pmad, not psad
+(define_insn_reservation "slm_sseiadd" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sseiadd")
+ (and (not (match_operand:V2DI 0 "register_operand"))
+ (and (eq_attr "atom_unit" "!simul")
+ (eq_attr "atom_unit" "!complex")))))
+ "slm-simple-either")
+
+;; pmad, psad and 64
+(define_insn_reservation "slm_sseiadd_2" 4
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sseiadd")
+ (and (not (match_operand:V2DI 0 "register_operand"))
+ (and (eq_attr "atom_unit" "simul" )
+ (eq_attr "mode" "DI")))))
+ "slm-fmul-4c")
+
+;; pmad, psad and 128
+(define_insn_reservation "slm_sseiadd_3" 5
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sseiadd")
+ (and (not (match_operand:V2DI 0 "register_operand"))
+ (and (eq_attr "atom_unit" "simul" )
+ (eq_attr "mode" "TI")))))
+ "slm-fmul-5c")
+
+;; if paddq(64 bit op), phadd/phsub
+(define_insn_reservation "slm_sseiadd_4" 4
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sseiadd")
+ (ior (match_operand:V2DI 0 "register_operand")
+ (eq_attr "atom_unit" "complex"))))
+ "slm-fadd-4c")
+
+;; if immediate op.
+(define_insn_reservation "slm_sseishft" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sseishft")
+ (and (eq_attr "atom_unit" "!sishuf")
+ (match_operand 2 "immediate_operand"))))
+ "slm-simple-either")
+
+;; if palignr or psrldq
+(define_insn_reservation "slm_sseishft_2" 1
+ (and (eq_attr "cpu" "slm")
+ (ior (eq_attr "type" "sseishft1")
+ (and (eq_attr "type" "sseishft")
+ (and (eq_attr "atom_unit" "sishuf")
+ (match_operand 2 "immediate_operand")))))
+ "slm-simple-0")
+
+;; if reg/mem op
+(define_insn_reservation "slm_sseishft_3" 2
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sseishft")
+ (not (match_operand 2 "immediate_operand"))))
+ "slm-complex, slm-all-eu")
+
+(define_insn_reservation "slm_sseimul" 5
+ (and (eq_attr "cpu" "slm")
+ (eq_attr "type" "sseimul"))
+ "slm-fmul-5c")
+
+;; rcpss or rsqrtss
+(define_insn_reservation "slm_sse" 4
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sse")
+ (and (eq_attr "atom_sse_attr" "rcp") (eq_attr "mode" "SF"))))
+ "slm-fmul-4c")
+
+;; movshdup, movsldup. Suggest to type sseishft
+(define_insn_reservation "slm_sse_2" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sse")
+ (eq_attr "atom_sse_attr" "movdup")))
+ "slm-simple-0")
+
+;; lfence
+(define_insn_reservation "slm_sse_3" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sse")
+ (eq_attr "atom_sse_attr" "lfence")))
+ "slm-simple-either")
+
+;; sfence,clflush,mfence, prefetch
+(define_insn_reservation "slm_sse_4" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sse")
+ (ior (eq_attr "atom_sse_attr" "fence")
+ (eq_attr "atom_sse_attr" "prefetch"))))
+ "slm-simple-0")
+
+;; rcpps, rsqrtss, sqrt, ldmxcsr
+(define_insn_reservation "slm_sse_5" 9
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sse")
+ (ior (ior (eq_attr "atom_sse_attr" "sqrt")
+ (eq_attr "atom_sse_attr" "mxcsr"))
+ (and (eq_attr "atom_sse_attr" "rcp")
+ (eq_attr "mode" "V4SF")))))
+ "slm-complex, slm-all-eu*7, nothing")
+
+;; xmm->xmm
+(define_insn_reservation "slm_ssemov" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ssemov")
+ (and (match_operand 0 "register_operand" "xy")
+ (match_operand 1 "register_operand" "xy"))))
+ "slm-simple-either")
+
+;; reg->xmm
+(define_insn_reservation "slm_ssemov_2" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ssemov")
+ (and (match_operand 0 "register_operand" "xy")
+ (match_operand 1 "register_operand" "r"))))
+ "slm-simple-0")
+
+;; xmm->reg
+(define_insn_reservation "slm_ssemov_3" 3
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ssemov")
+ (and (match_operand 0 "register_operand" "r")
+ (match_operand 1 "register_operand" "xy"))))
+ "slm-simple-0, nothing*2")
+
+;; mov mem
+(define_insn_reservation "slm_ssemov_4" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ssemov")
+ (and (eq_attr "movu" "0") (eq_attr "memory" "!none"))))
+ "slm-simple-0")
+
+;; movu mem
+(define_insn_reservation "slm_ssemov_5" 2
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ssemov")
+ (ior (eq_attr "movu" "1") (eq_attr "memory" "!none"))))
+ "slm-simple-0, nothing")
+
+;; no memory simple
+(define_insn_reservation "slm_sseadd" 3
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sseadd")
+ (and (eq_attr "memory" "none")
+ (and (eq_attr "mode" "!V2DF")
+ (eq_attr "atom_unit" "!complex")))))
+ "slm-fadd-3c")
+
+;; memory simple
+(define_insn_reservation "slm_sseadd_mem" 3
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sseadd")
+ (and (eq_attr "memory" "!none")
+ (and (eq_attr "mode" "!V2DF")
+ (eq_attr "atom_unit" "!complex")))))
+ "slm-fadd-3c")
+
+;; maxps, minps, *pd, hadd, hsub
+(define_insn_reservation "slm_sseadd_3" 4
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sseadd")
+ (ior (eq_attr "mode" "V2DF") (eq_attr "atom_unit" "complex"))))
+ "slm-fadd-4c")
+
+;; Except dppd/dpps
+(define_insn_reservation "slm_ssemul" 5
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ssemul")
+ (eq_attr "mode" "!SF")))
+ "slm-fmul-5c")
+
+;; Except dppd/dpps, 4 cycle if mulss
+(define_insn_reservation "slm_ssemul_2" 4
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ssemul")
+ (eq_attr "mode" "SF")))
+ "slm-fmul-4c")
+
+(define_insn_reservation "slm_ssecmp" 1
+ (and (eq_attr "cpu" "slm")
+ (eq_attr "type" "ssecmp"))
+ "slm-simple-either")
+
+(define_insn_reservation "slm_ssecomi" 1
+ (and (eq_attr "cpu" "slm")
+ (eq_attr "type" "ssecomi"))
+ "slm-simple-0")
+
+;; no memory and cvtpi2ps, cvtps2pi, cvttps2pi
+(define_insn_reservation "slm_ssecvt" 5
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ssecvt")
+ (ior (and (match_operand:V2SI 0 "register_operand")
+ (match_operand:V4SF 1 "register_operand"))
+ (and (match_operand:V4SF 0 "register_operand")
+ (match_operand:V2SI 1 "register_operand")))))
+ "slm-fp-0, slm-feu-0, nothing*3")
+
+;; memory and cvtpi2ps, cvtps2pi, cvttps2pi
+(define_insn_reservation "slm_ssecvt_mem" 5
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ssecvt")
+ (ior (and (match_operand:V2SI 0 "register_operand")
+ (match_operand:V4SF 1 "memory_operand"))
+ (and (match_operand:V4SF 0 "register_operand")
+ (match_operand:V2SI 1 "memory_operand")))))
+"slm-fp-0, slm-feu-0, nothing*3")
+
+;; cvtpd2pi, cvtpi2pd
+(define_insn_reservation "slm_ssecvt_1" 2
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ssecvt")
+ (ior (and (match_operand:V2DF 0 "register_operand")
+ (match_operand:V2SI 1 "register_operand"))
+ (and (match_operand:V2SI 0 "register_operand")
+ (match_operand:V2DF 1 "register_operand")))))
+ "slm-fp-0, slm-feu-0")
+
+;; memory and cvtpd2pi, cvtpi2pd
+(define_insn_reservation "slm_ssecvt_1_mem" 2
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ssecvt")
+ (ior (and (match_operand:V2DF 0 "register_operand")
+ (match_operand:V2SI 1 "memory_operand"))
+ (and (match_operand:V2SI 0 "register_operand")
+ (match_operand:V2DF 1 "memory_operand")))))
+ "slm-fp-0, slm-feu-0")
+
+;; otherwise. 4 cycles average for cvtss2sd
+(define_insn_reservation "slm_ssecvt_3" 4
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "ssecvt")
+ (not (ior (and (match_operand:V2SI 0 "register_operand")
+ (match_operand:V4SF 1 "nonimmediate_operand"))
+ (and (match_operand:V4SF 0 "register_operand")
+ (match_operand:V2SI 1 "nonimmediate_operand"))))))
+ "slm-fp-0, nothing*3")
+
+;; memory and cvtsi2sd
+(define_insn_reservation "slm_sseicvt" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sseicvt")
+ (and (match_operand:V2DF 0 "register_operand")
+ (match_operand:SI 1 "nonimmediate_operand"))))
+ "slm-fp-0")
+
+;; otherwise. 8 cycles average for cvtsd2si
+(define_insn_reservation "slm_sseicvt_2" 4
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "sseicvt")
+ (not (and (match_operand:V2DF 0 "register_operand")
+ (match_operand:SI 1 "memory_operand")))))
+ "slm-fp-0, nothing*3")
+
+(define_insn_reservation "slm_ssediv" 13
+ (and (eq_attr "cpu" "slm")
+ (eq_attr "type" "ssediv"))
+ "slm-fp-0, slm-feu-0*10, nothing*2")
+
+;; simple for fmov
+(define_insn_reservation "slm_fmov" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "fmov")
+ (eq_attr "memory" "none")))
+ "slm-simple-either")
+
+;; simple for fmov
+(define_insn_reservation "slm_fmov_mem" 1
+ (and (eq_attr "cpu" "slm")
+ (and (eq_attr "type" "fmov")
+ (eq_attr "memory" "!none")))
+ "slm-simple-either")
+
+;; Define bypass here
+
+;; There will be 0 cycle stall from cmp/test to jcc
+
+;; There will be 1 cycle stall from flag producer to cmov and adc/sbb
+(define_bypass 2 "slm_icmp, slm_test, slm_alu, slm_alu_carry,
+ slm_alu1, slm_negnot, slm_incdec, slm_ishift,
+ slm_ishift1, slm_rotate, slm_rotate1"
+ "slm_icmov, slm_alu_carry")
+
+;; lea to shift source stall is 1 cycle
+(define_bypass 2 "slm_lea"
+ "slm_ishift, slm_ishift1, slm_rotate, slm_rotate1"
+ "!ix86_dep_by_shift_count")
+
+;; non-lea to shift count stall is 1 cycle
+(define_bypass 2 "slm_alu_carry,
+ slm_alu,slm_alu1,slm_negnot,slm_imov,slm_imovx,
+ slm_incdec,slm_ishift,slm_ishift1,slm_rotate,
+ slm_rotate1, slm_setcc, slm_icmov, slm_pop,
+ slm_alu_mem, slm_alu_carry_mem, slm_alu1_mem,
+ slm_imovx_mem, slm_imovx_2_mem,
+ slm_imov_mem, slm_icmov_mem, slm_fmov_mem"
+ "slm_ishift, slm_ishift1, slm_rotate, slm_rotate1,
+ slm_ishift_mem, slm_ishift1_mem,
+ slm_rotate_mem, slm_rotate1_mem"
+ "ix86_dep_by_shift_count")
diff --git a/gcc/config/i386/t-cygming b/gcc/config/i386/t-cygming
index f615ad7a2af..ba076a7f49a 100644
--- a/gcc/config/i386/t-cygming
+++ b/gcc/config/i386/t-cygming
@@ -22,7 +22,7 @@ LIMITS_H_TEST = true
winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
- $(TM_P_H) $(HASHTAB_H) $(GGC_H) $(LTO_STREAMER_H)
+ $(TM_P_H) $(HASH_TABLE_H) $(GGC_H) $(LTO_STREAMER_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/i386/winnt.c
diff --git a/gcc/config/i386/t-interix b/gcc/config/i386/t-interix
index 43443e72a45..4d7b5987037 100644
--- a/gcc/config/i386/t-interix
+++ b/gcc/config/i386/t-interix
@@ -18,7 +18,7 @@
winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
- $(TM_P_H) $(HASHTAB_H) $(GGC_H)
+ $(TM_P_H) $(HASH_TABLE_H) $(GGC_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/i386/winnt.c
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index f0f972c56d9..c9e3aa98a37 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "tm_p.h"
#include "diagnostic-core.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "langhooks.h"
#include "ggc.h"
#include "target.h"
@@ -449,7 +449,7 @@ i386_pe_reloc_rw_mask (void)
unsigned int
i386_pe_section_type_flags (tree decl, const char *name, int reloc)
{
- static htab_t htab;
+ static hash_table <pointer_hash <unsigned int> > htab;
unsigned int flags;
unsigned int **slot;
@@ -460,8 +460,8 @@ i386_pe_section_type_flags (tree decl, const char *name, int reloc)
/* The names we put in the hashtable will always be the unique
versions given to us by the stringtable, so we can just use
their addresses as the keys. */
- if (!htab)
- htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
+ if (!htab.is_created ())
+ htab.create (31);
if (decl && TREE_CODE (decl) == FUNCTION_DECL)
flags = SECTION_CODE;
@@ -480,7 +480,7 @@ i386_pe_section_type_flags (tree decl, const char *name, int reloc)
flags |= SECTION_LINKONCE;
/* See if we already have an entry for this section. */
- slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
+ slot = htab.find_slot ((unsigned int *)name, INSERT);
if (!*slot)
{
*slot = (unsigned int *) xmalloc (sizeof (unsigned int));
@@ -714,12 +714,29 @@ i386_pe_record_stub (const char *name)
#ifdef CXX_WRAP_SPEC_LIST
+/* Hashtable helpers. */
+
+struct wrapped_symbol_hasher : typed_noop_remove <char>
+{
+ typedef char value_type;
+ typedef char compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+
+inline hashval_t
+wrapped_symbol_hasher::hash (const value_type *v)
+{
+ return htab_hash_string (v);
+}
+
/* Hash table equality helper function. */
-static int
-wrapper_strcmp (const void *x, const void *y)
+inline bool
+wrapped_symbol_hasher::equal (const value_type *x, const compare_type *y)
{
- return !strcmp ((const char *) x, (const char *) y);
+ return !strcmp (x, y);
}
/* Search for a function named TARGET in the list of library wrappers
@@ -733,7 +750,7 @@ static const char *
i386_find_on_wrapper_list (const char *target)
{
static char first_time = 1;
- static htab_t wrappers;
+ static hash_table <wrapped_symbol_hasher> wrappers;
if (first_time)
{
@@ -746,8 +763,7 @@ i386_find_on_wrapper_list (const char *target)
char *bufptr;
/* Breaks up the char array into separated strings
strings and enter them into the hash table. */
- wrappers = htab_create_alloc (8, htab_hash_string, wrapper_strcmp,
- 0, xcalloc, free);
+ wrappers.create (8);
for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr)
{
char *found = NULL;
@@ -760,12 +776,12 @@ i386_find_on_wrapper_list (const char *target)
if (*bufptr)
*bufptr = 0;
if (found)
- *htab_find_slot (wrappers, found, INSERT) = found;
+ *wrappers.find_slot (found, INSERT) = found;
}
first_time = 0;
}
- return (const char *) htab_find (wrappers, target);
+ return wrappers.find (target);
}
#endif /* CXX_WRAP_SPEC_LIST */
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index ee8ee5be3df..a128b19c7ca 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -47,7 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "target-def.h"
#include "common/common-target.h"
#include "tm_p.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "langhooks.h"
#include "gimple.h"
#include "intl.h"
@@ -257,8 +257,6 @@ static struct bundle_state *get_free_bundle_state (void);
static void free_bundle_state (struct bundle_state *);
static void initiate_bundle_states (void);
static void finish_bundle_states (void);
-static unsigned bundle_state_hash (const void *);
-static int bundle_state_eq_p (const void *, const void *);
static int insert_bundle_state (struct bundle_state *);
static void initiate_bundle_state_table (void);
static void finish_bundle_state_table (void);
@@ -8526,18 +8524,21 @@ finish_bundle_states (void)
}
}
-/* Hash table of the bundle states. The key is dfa_state and insn_num
- of the bundle states. */
+/* Hashtable helpers. */
-static htab_t bundle_state_table;
+struct bundle_state_hasher : typed_noop_remove <bundle_state>
+{
+ typedef bundle_state value_type;
+ typedef bundle_state compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
/* The function returns hash of BUNDLE_STATE. */
-static unsigned
-bundle_state_hash (const void *bundle_state)
+inline hashval_t
+bundle_state_hasher::hash (const value_type *state)
{
- const struct bundle_state *const state
- = (const struct bundle_state *) bundle_state;
unsigned result, i;
for (result = i = 0; i < dfa_state_size; i++)
@@ -8548,19 +8549,20 @@ bundle_state_hash (const void *bundle_state)
/* The function returns nonzero if the bundle state keys are equal. */
-static int
-bundle_state_eq_p (const void *bundle_state_1, const void *bundle_state_2)
+inline bool
+bundle_state_hasher::equal (const value_type *state1,
+ const compare_type *state2)
{
- const struct bundle_state *const state1
- = (const struct bundle_state *) bundle_state_1;
- const struct bundle_state *const state2
- = (const struct bundle_state *) bundle_state_2;
-
return (state1->insn_num == state2->insn_num
&& memcmp (state1->dfa_state, state2->dfa_state,
dfa_state_size) == 0);
}
+/* Hash table of the bundle states. The key is dfa_state and insn_num
+ of the bundle states. */
+
+static hash_table <bundle_state_hasher> bundle_state_table;
+
/* The function inserts the BUNDLE_STATE into the hash table. The
function returns nonzero if the bundle has been inserted into the
table. The table contains the best bundle state with given key. */
@@ -8568,39 +8570,35 @@ bundle_state_eq_p (const void *bundle_state_1, const void *bundle_state_2)
static int
insert_bundle_state (struct bundle_state *bundle_state)
{
- void **entry_ptr;
+ struct bundle_state **entry_ptr;
- entry_ptr = htab_find_slot (bundle_state_table, bundle_state, INSERT);
+ entry_ptr = bundle_state_table.find_slot (bundle_state, INSERT);
if (*entry_ptr == NULL)
{
bundle_state->next = index_to_bundle_states [bundle_state->insn_num];
index_to_bundle_states [bundle_state->insn_num] = bundle_state;
- *entry_ptr = (void *) bundle_state;
+ *entry_ptr = bundle_state;
return TRUE;
}
- else if (bundle_state->cost < ((struct bundle_state *) *entry_ptr)->cost
- || (bundle_state->cost == ((struct bundle_state *) *entry_ptr)->cost
- && (((struct bundle_state *)*entry_ptr)->accumulated_insns_num
+ else if (bundle_state->cost < (*entry_ptr)->cost
+ || (bundle_state->cost == (*entry_ptr)->cost
+ && ((*entry_ptr)->accumulated_insns_num
> bundle_state->accumulated_insns_num
- || (((struct bundle_state *)
- *entry_ptr)->accumulated_insns_num
+ || ((*entry_ptr)->accumulated_insns_num
== bundle_state->accumulated_insns_num
- && (((struct bundle_state *)
- *entry_ptr)->branch_deviation
+ && ((*entry_ptr)->branch_deviation
> bundle_state->branch_deviation
- || (((struct bundle_state *)
- *entry_ptr)->branch_deviation
+ || ((*entry_ptr)->branch_deviation
== bundle_state->branch_deviation
- && ((struct bundle_state *)
- *entry_ptr)->middle_bundle_stops
+ && (*entry_ptr)->middle_bundle_stops
> bundle_state->middle_bundle_stops))))))
{
struct bundle_state temp;
- temp = *(struct bundle_state *) *entry_ptr;
- *(struct bundle_state *) *entry_ptr = *bundle_state;
- ((struct bundle_state *) *entry_ptr)->next = temp.next;
+ temp = **entry_ptr;
+ **entry_ptr = *bundle_state;
+ (*entry_ptr)->next = temp.next;
*bundle_state = temp;
}
return FALSE;
@@ -8611,8 +8609,7 @@ insert_bundle_state (struct bundle_state *bundle_state)
static void
initiate_bundle_state_table (void)
{
- bundle_state_table = htab_create (50, bundle_state_hash, bundle_state_eq_p,
- (htab_del) 0);
+ bundle_state_table.create (50);
}
/* Finish work with the hash table. */
@@ -8620,7 +8617,7 @@ initiate_bundle_state_table (void)
static void
finish_bundle_state_table (void)
{
- htab_delete (bundle_state_table);
+ bundle_state_table.dispose ();
}
diff --git a/gcc/config/ia64/t-ia64 b/gcc/config/ia64/t-ia64
index 5c3ac644be3..b009cdf2bc5 100644
--- a/gcc/config/ia64/t-ia64
+++ b/gcc/config/ia64/t-ia64
@@ -24,4 +24,5 @@ ia64-c.o: $(srcdir)/config/ia64/ia64-c.c $(CONFIG_H) $(SYSTEM_H) \
# genattrtab generates very long string literals.
insn-attrtab.o-warn = -Wno-error
-ia64.o: debug.h $(PARAMS_H) sel-sched.h reload.h $(OPTS_H) dumpfile.h
+ia64.o: $(srcdir)/config/ia64/ia64.c debug.h $(PARAMS_H) sel-sched.h reload.h \
+ $(OPTS_H) dumpfile.h $(HASH_TABLE_H)
diff --git a/gcc/config/mips/mips-cpus.def b/gcc/config/mips/mips-cpus.def
index 9e5fd162189..d7db0ba96d6 100644
--- a/gcc/config/mips/mips-cpus.def
+++ b/gcc/config/mips/mips-cpus.def
@@ -43,7 +43,7 @@ MIPS_CPU ("mips4", PROCESSOR_R8000, 4, 0)
that to a recommendation to avoid the instructions in code that
isn't tuned to a specific processor. */
MIPS_CPU ("mips32", PROCESSOR_4KC, 32, PTF_AVOID_BRANCHLIKELY)
-MIPS_CPU ("mips32r2", PROCESSOR_M4K, 33, PTF_AVOID_BRANCHLIKELY)
+MIPS_CPU ("mips32r2", PROCESSOR_74KF2_1, 33, PTF_AVOID_BRANCHLIKELY)
MIPS_CPU ("mips64", PROCESSOR_5KC, 64, PTF_AVOID_BRANCHLIKELY)
/* ??? For now just tune the generic MIPS64r2 for 5KC as well. */
MIPS_CPU ("mips64r2", PROCESSOR_5KC, 65, PTF_AVOID_BRANCHLIKELY)
@@ -68,6 +68,7 @@ MIPS_CPU ("r4600", PROCESSOR_R4600, 3, 0)
MIPS_CPU ("orion", PROCESSOR_R4600, 3, 0)
MIPS_CPU ("r4650", PROCESSOR_R4650, 3, 0)
MIPS_CPU ("r4700", PROCESSOR_R4700, 3, 0)
+MIPS_CPU ("r5900", PROCESSOR_R5900, 3, 0)
/* ST Loongson 2E/2F processors. */
MIPS_CPU ("loongson2e", PROCESSOR_LOONGSON_2E, 3, PTF_AVOID_BRANCHLIKELY)
MIPS_CPU ("loongson2f", PROCESSOR_LOONGSON_2F, 3, PTF_AVOID_BRANCHLIKELY)
diff --git a/gcc/config/mips/mips-tables.opt b/gcc/config/mips/mips-tables.opt
index 0d7fa26510d..8ed412cc15e 100644
--- a/gcc/config/mips/mips-tables.opt
+++ b/gcc/config/mips/mips-tables.opt
@@ -208,425 +208,431 @@ EnumValue
Enum(mips_arch_opt_value) String(4700) Value(22)
EnumValue
-Enum(mips_arch_opt_value) String(loongson2e) Value(23) Canonical
+Enum(mips_arch_opt_value) String(r5900) Value(23) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(loongson2f) Value(24) Canonical
+Enum(mips_arch_opt_value) String(5900) Value(23)
EnumValue
-Enum(mips_arch_opt_value) String(r8000) Value(25) Canonical
+Enum(mips_arch_opt_value) String(loongson2e) Value(24) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r8k) Value(25)
+Enum(mips_arch_opt_value) String(loongson2f) Value(25) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(8000) Value(25)
+Enum(mips_arch_opt_value) String(r8000) Value(26) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(8k) Value(25)
+Enum(mips_arch_opt_value) String(r8k) Value(26)
EnumValue
-Enum(mips_arch_opt_value) String(r10000) Value(26) Canonical
+Enum(mips_arch_opt_value) String(8000) Value(26)
EnumValue
-Enum(mips_arch_opt_value) String(r10k) Value(26)
+Enum(mips_arch_opt_value) String(8k) Value(26)
EnumValue
-Enum(mips_arch_opt_value) String(10000) Value(26)
+Enum(mips_arch_opt_value) String(r10000) Value(27) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(10k) Value(26)
+Enum(mips_arch_opt_value) String(r10k) Value(27)
EnumValue
-Enum(mips_arch_opt_value) String(r12000) Value(27) Canonical
+Enum(mips_arch_opt_value) String(10000) Value(27)
EnumValue
-Enum(mips_arch_opt_value) String(r12k) Value(27)
+Enum(mips_arch_opt_value) String(10k) Value(27)
EnumValue
-Enum(mips_arch_opt_value) String(12000) Value(27)
+Enum(mips_arch_opt_value) String(r12000) Value(28) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(12k) Value(27)
+Enum(mips_arch_opt_value) String(r12k) Value(28)
EnumValue
-Enum(mips_arch_opt_value) String(r14000) Value(28) Canonical
+Enum(mips_arch_opt_value) String(12000) Value(28)
EnumValue
-Enum(mips_arch_opt_value) String(r14k) Value(28)
+Enum(mips_arch_opt_value) String(12k) Value(28)
EnumValue
-Enum(mips_arch_opt_value) String(14000) Value(28)
+Enum(mips_arch_opt_value) String(r14000) Value(29) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(14k) Value(28)
+Enum(mips_arch_opt_value) String(r14k) Value(29)
EnumValue
-Enum(mips_arch_opt_value) String(r16000) Value(29) Canonical
+Enum(mips_arch_opt_value) String(14000) Value(29)
EnumValue
-Enum(mips_arch_opt_value) String(r16k) Value(29)
+Enum(mips_arch_opt_value) String(14k) Value(29)
EnumValue
-Enum(mips_arch_opt_value) String(16000) Value(29)
+Enum(mips_arch_opt_value) String(r16000) Value(30) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(16k) Value(29)
+Enum(mips_arch_opt_value) String(r16k) Value(30)
EnumValue
-Enum(mips_arch_opt_value) String(vr5000) Value(30) Canonical
+Enum(mips_arch_opt_value) String(16000) Value(30)
EnumValue
-Enum(mips_arch_opt_value) String(vr5k) Value(30)
+Enum(mips_arch_opt_value) String(16k) Value(30)
EnumValue
-Enum(mips_arch_opt_value) String(5000) Value(30)
+Enum(mips_arch_opt_value) String(vr5000) Value(31) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(5k) Value(30)
+Enum(mips_arch_opt_value) String(vr5k) Value(31)
EnumValue
-Enum(mips_arch_opt_value) String(r5000) Value(30)
+Enum(mips_arch_opt_value) String(5000) Value(31)
EnumValue
-Enum(mips_arch_opt_value) String(r5k) Value(30)
+Enum(mips_arch_opt_value) String(5k) Value(31)
EnumValue
-Enum(mips_arch_opt_value) String(vr5400) Value(31) Canonical
+Enum(mips_arch_opt_value) String(r5000) Value(31)
EnumValue
-Enum(mips_arch_opt_value) String(5400) Value(31)
+Enum(mips_arch_opt_value) String(r5k) Value(31)
EnumValue
-Enum(mips_arch_opt_value) String(r5400) Value(31)
+Enum(mips_arch_opt_value) String(vr5400) Value(32) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(vr5500) Value(32) Canonical
+Enum(mips_arch_opt_value) String(5400) Value(32)
EnumValue
-Enum(mips_arch_opt_value) String(5500) Value(32)
+Enum(mips_arch_opt_value) String(r5400) Value(32)
EnumValue
-Enum(mips_arch_opt_value) String(r5500) Value(32)
+Enum(mips_arch_opt_value) String(vr5500) Value(33) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(rm7000) Value(33) Canonical
+Enum(mips_arch_opt_value) String(5500) Value(33)
EnumValue
-Enum(mips_arch_opt_value) String(rm7k) Value(33)
+Enum(mips_arch_opt_value) String(r5500) Value(33)
EnumValue
-Enum(mips_arch_opt_value) String(7000) Value(33)
+Enum(mips_arch_opt_value) String(rm7000) Value(34) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(7k) Value(33)
+Enum(mips_arch_opt_value) String(rm7k) Value(34)
EnumValue
-Enum(mips_arch_opt_value) String(r7000) Value(33)
+Enum(mips_arch_opt_value) String(7000) Value(34)
EnumValue
-Enum(mips_arch_opt_value) String(r7k) Value(33)
+Enum(mips_arch_opt_value) String(7k) Value(34)
EnumValue
-Enum(mips_arch_opt_value) String(rm9000) Value(34) Canonical
+Enum(mips_arch_opt_value) String(r7000) Value(34)
EnumValue
-Enum(mips_arch_opt_value) String(rm9k) Value(34)
+Enum(mips_arch_opt_value) String(r7k) Value(34)
EnumValue
-Enum(mips_arch_opt_value) String(9000) Value(34)
+Enum(mips_arch_opt_value) String(rm9000) Value(35) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(9k) Value(34)
+Enum(mips_arch_opt_value) String(rm9k) Value(35)
EnumValue
-Enum(mips_arch_opt_value) String(r9000) Value(34)
+Enum(mips_arch_opt_value) String(9000) Value(35)
EnumValue
-Enum(mips_arch_opt_value) String(r9k) Value(34)
+Enum(mips_arch_opt_value) String(9k) Value(35)
EnumValue
-Enum(mips_arch_opt_value) String(4kc) Value(35) Canonical
+Enum(mips_arch_opt_value) String(r9000) Value(35)
EnumValue
-Enum(mips_arch_opt_value) String(r4kc) Value(35)
+Enum(mips_arch_opt_value) String(r9k) Value(35)
EnumValue
-Enum(mips_arch_opt_value) String(4km) Value(36) Canonical
+Enum(mips_arch_opt_value) String(4kc) Value(36) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r4km) Value(36)
+Enum(mips_arch_opt_value) String(r4kc) Value(36)
EnumValue
-Enum(mips_arch_opt_value) String(4kp) Value(37) Canonical
+Enum(mips_arch_opt_value) String(4km) Value(37) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r4kp) Value(37)
+Enum(mips_arch_opt_value) String(r4km) Value(37)
EnumValue
-Enum(mips_arch_opt_value) String(4ksc) Value(38) Canonical
+Enum(mips_arch_opt_value) String(4kp) Value(38) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r4ksc) Value(38)
+Enum(mips_arch_opt_value) String(r4kp) Value(38)
EnumValue
-Enum(mips_arch_opt_value) String(m4k) Value(39) Canonical
+Enum(mips_arch_opt_value) String(4ksc) Value(39) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(m14kc) Value(40) Canonical
+Enum(mips_arch_opt_value) String(r4ksc) Value(39)
EnumValue
-Enum(mips_arch_opt_value) String(m14k) Value(41) Canonical
+Enum(mips_arch_opt_value) String(m4k) Value(40) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(4kec) Value(42) Canonical
+Enum(mips_arch_opt_value) String(m14kc) Value(41) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r4kec) Value(42)
+Enum(mips_arch_opt_value) String(m14k) Value(42) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(4kem) Value(43) Canonical
+Enum(mips_arch_opt_value) String(4kec) Value(43) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r4kem) Value(43)
+Enum(mips_arch_opt_value) String(r4kec) Value(43)
EnumValue
-Enum(mips_arch_opt_value) String(4kep) Value(44) Canonical
+Enum(mips_arch_opt_value) String(4kem) Value(44) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r4kep) Value(44)
+Enum(mips_arch_opt_value) String(r4kem) Value(44)
EnumValue
-Enum(mips_arch_opt_value) String(4ksd) Value(45) Canonical
+Enum(mips_arch_opt_value) String(4kep) Value(45) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r4ksd) Value(45)
+Enum(mips_arch_opt_value) String(r4kep) Value(45)
EnumValue
-Enum(mips_arch_opt_value) String(24kc) Value(46) Canonical
+Enum(mips_arch_opt_value) String(4ksd) Value(46) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r24kc) Value(46)
+Enum(mips_arch_opt_value) String(r4ksd) Value(46)
EnumValue
-Enum(mips_arch_opt_value) String(24kf2_1) Value(47) Canonical
+Enum(mips_arch_opt_value) String(24kc) Value(47) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r24kf2_1) Value(47)
+Enum(mips_arch_opt_value) String(r24kc) Value(47)
EnumValue
-Enum(mips_arch_opt_value) String(24kf) Value(48) Canonical
+Enum(mips_arch_opt_value) String(24kf2_1) Value(48) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r24kf) Value(48)
+Enum(mips_arch_opt_value) String(r24kf2_1) Value(48)
EnumValue
-Enum(mips_arch_opt_value) String(24kf1_1) Value(49) Canonical
+Enum(mips_arch_opt_value) String(24kf) Value(49) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r24kf1_1) Value(49)
+Enum(mips_arch_opt_value) String(r24kf) Value(49)
EnumValue
-Enum(mips_arch_opt_value) String(24kfx) Value(50) Canonical
+Enum(mips_arch_opt_value) String(24kf1_1) Value(50) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r24kfx) Value(50)
+Enum(mips_arch_opt_value) String(r24kf1_1) Value(50)
EnumValue
-Enum(mips_arch_opt_value) String(24kx) Value(51) Canonical
+Enum(mips_arch_opt_value) String(24kfx) Value(51) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r24kx) Value(51)
+Enum(mips_arch_opt_value) String(r24kfx) Value(51)
EnumValue
-Enum(mips_arch_opt_value) String(24kec) Value(52) Canonical
+Enum(mips_arch_opt_value) String(24kx) Value(52) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r24kec) Value(52)
+Enum(mips_arch_opt_value) String(r24kx) Value(52)
EnumValue
-Enum(mips_arch_opt_value) String(24kef2_1) Value(53) Canonical
+Enum(mips_arch_opt_value) String(24kec) Value(53) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r24kef2_1) Value(53)
+Enum(mips_arch_opt_value) String(r24kec) Value(53)
EnumValue
-Enum(mips_arch_opt_value) String(24kef) Value(54) Canonical
+Enum(mips_arch_opt_value) String(24kef2_1) Value(54) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r24kef) Value(54)
+Enum(mips_arch_opt_value) String(r24kef2_1) Value(54)
EnumValue
-Enum(mips_arch_opt_value) String(24kef1_1) Value(55) Canonical
+Enum(mips_arch_opt_value) String(24kef) Value(55) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r24kef1_1) Value(55)
+Enum(mips_arch_opt_value) String(r24kef) Value(55)
EnumValue
-Enum(mips_arch_opt_value) String(24kefx) Value(56) Canonical
+Enum(mips_arch_opt_value) String(24kef1_1) Value(56) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r24kefx) Value(56)
+Enum(mips_arch_opt_value) String(r24kef1_1) Value(56)
EnumValue
-Enum(mips_arch_opt_value) String(24kex) Value(57) Canonical
+Enum(mips_arch_opt_value) String(24kefx) Value(57) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r24kex) Value(57)
+Enum(mips_arch_opt_value) String(r24kefx) Value(57)
EnumValue
-Enum(mips_arch_opt_value) String(34kc) Value(58) Canonical
+Enum(mips_arch_opt_value) String(24kex) Value(58) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r34kc) Value(58)
+Enum(mips_arch_opt_value) String(r24kex) Value(58)
EnumValue
-Enum(mips_arch_opt_value) String(34kf2_1) Value(59) Canonical
+Enum(mips_arch_opt_value) String(34kc) Value(59) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r34kf2_1) Value(59)
+Enum(mips_arch_opt_value) String(r34kc) Value(59)
EnumValue
-Enum(mips_arch_opt_value) String(34kf) Value(60) Canonical
+Enum(mips_arch_opt_value) String(34kf2_1) Value(60) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r34kf) Value(60)
+Enum(mips_arch_opt_value) String(r34kf2_1) Value(60)
EnumValue
-Enum(mips_arch_opt_value) String(34kf1_1) Value(61) Canonical
+Enum(mips_arch_opt_value) String(34kf) Value(61) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r34kf1_1) Value(61)
+Enum(mips_arch_opt_value) String(r34kf) Value(61)
EnumValue
-Enum(mips_arch_opt_value) String(34kfx) Value(62) Canonical
+Enum(mips_arch_opt_value) String(34kf1_1) Value(62) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r34kfx) Value(62)
+Enum(mips_arch_opt_value) String(r34kf1_1) Value(62)
EnumValue
-Enum(mips_arch_opt_value) String(34kx) Value(63) Canonical
+Enum(mips_arch_opt_value) String(34kfx) Value(63) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r34kx) Value(63)
+Enum(mips_arch_opt_value) String(r34kfx) Value(63)
EnumValue
-Enum(mips_arch_opt_value) String(34kn) Value(64) Canonical
+Enum(mips_arch_opt_value) String(34kx) Value(64) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r34kn) Value(64)
+Enum(mips_arch_opt_value) String(r34kx) Value(64)
EnumValue
-Enum(mips_arch_opt_value) String(74kc) Value(65) Canonical
+Enum(mips_arch_opt_value) String(34kn) Value(65) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r74kc) Value(65)
+Enum(mips_arch_opt_value) String(r34kn) Value(65)
EnumValue
-Enum(mips_arch_opt_value) String(74kf2_1) Value(66) Canonical
+Enum(mips_arch_opt_value) String(74kc) Value(66) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r74kf2_1) Value(66)
+Enum(mips_arch_opt_value) String(r74kc) Value(66)
EnumValue
-Enum(mips_arch_opt_value) String(74kf) Value(67) Canonical
+Enum(mips_arch_opt_value) String(74kf2_1) Value(67) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r74kf) Value(67)
+Enum(mips_arch_opt_value) String(r74kf2_1) Value(67)
EnumValue
-Enum(mips_arch_opt_value) String(74kf1_1) Value(68) Canonical
+Enum(mips_arch_opt_value) String(74kf) Value(68) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r74kf1_1) Value(68)
+Enum(mips_arch_opt_value) String(r74kf) Value(68)
EnumValue
-Enum(mips_arch_opt_value) String(74kfx) Value(69) Canonical
+Enum(mips_arch_opt_value) String(74kf1_1) Value(69) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r74kfx) Value(69)
+Enum(mips_arch_opt_value) String(r74kf1_1) Value(69)
EnumValue
-Enum(mips_arch_opt_value) String(74kx) Value(70) Canonical
+Enum(mips_arch_opt_value) String(74kfx) Value(70) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r74kx) Value(70)
+Enum(mips_arch_opt_value) String(r74kfx) Value(70)
EnumValue
-Enum(mips_arch_opt_value) String(74kf3_2) Value(71) Canonical
+Enum(mips_arch_opt_value) String(74kx) Value(71) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r74kf3_2) Value(71)
+Enum(mips_arch_opt_value) String(r74kx) Value(71)
EnumValue
-Enum(mips_arch_opt_value) String(1004kc) Value(72) Canonical
+Enum(mips_arch_opt_value) String(74kf3_2) Value(72) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r1004kc) Value(72)
+Enum(mips_arch_opt_value) String(r74kf3_2) Value(72)
EnumValue
-Enum(mips_arch_opt_value) String(1004kf2_1) Value(73) Canonical
+Enum(mips_arch_opt_value) String(1004kc) Value(73) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r1004kf2_1) Value(73)
+Enum(mips_arch_opt_value) String(r1004kc) Value(73)
EnumValue
-Enum(mips_arch_opt_value) String(1004kf) Value(74) Canonical
+Enum(mips_arch_opt_value) String(1004kf2_1) Value(74) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r1004kf) Value(74)
+Enum(mips_arch_opt_value) String(r1004kf2_1) Value(74)
EnumValue
-Enum(mips_arch_opt_value) String(1004kf1_1) Value(75) Canonical
+Enum(mips_arch_opt_value) String(1004kf) Value(75) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r1004kf1_1) Value(75)
+Enum(mips_arch_opt_value) String(r1004kf) Value(75)
EnumValue
-Enum(mips_arch_opt_value) String(5kc) Value(76) Canonical
+Enum(mips_arch_opt_value) String(1004kf1_1) Value(76) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r5kc) Value(76)
+Enum(mips_arch_opt_value) String(r1004kf1_1) Value(76)
EnumValue
-Enum(mips_arch_opt_value) String(5kf) Value(77) Canonical
+Enum(mips_arch_opt_value) String(5kc) Value(77) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r5kf) Value(77)
+Enum(mips_arch_opt_value) String(r5kc) Value(77)
EnumValue
-Enum(mips_arch_opt_value) String(20kc) Value(78) Canonical
+Enum(mips_arch_opt_value) String(5kf) Value(78) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r20kc) Value(78)
+Enum(mips_arch_opt_value) String(r5kf) Value(78)
EnumValue
-Enum(mips_arch_opt_value) String(sb1) Value(79) Canonical
+Enum(mips_arch_opt_value) String(20kc) Value(79) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(sb1a) Value(80) Canonical
+Enum(mips_arch_opt_value) String(r20kc) Value(79)
EnumValue
-Enum(mips_arch_opt_value) String(sr71000) Value(81) Canonical
+Enum(mips_arch_opt_value) String(sb1) Value(80) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(sr71k) Value(81)
+Enum(mips_arch_opt_value) String(sb1a) Value(81) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(xlr) Value(82) Canonical
+Enum(mips_arch_opt_value) String(sr71000) Value(82) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(loongson3a) Value(83) Canonical
+Enum(mips_arch_opt_value) String(sr71k) Value(82)
EnumValue
-Enum(mips_arch_opt_value) String(octeon) Value(84) Canonical
+Enum(mips_arch_opt_value) String(xlr) Value(83) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(octeon+) Value(85) Canonical
+Enum(mips_arch_opt_value) String(loongson3a) Value(84) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(octeon2) Value(86) Canonical
+Enum(mips_arch_opt_value) String(octeon) Value(85) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(xlp) Value(87) Canonical
+Enum(mips_arch_opt_value) String(octeon+) Value(86) Canonical
+
+EnumValue
+Enum(mips_arch_opt_value) String(octeon2) Value(87) Canonical
+
+EnumValue
+Enum(mips_arch_opt_value) String(xlp) Value(88) Canonical
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index c9383ea3408..ff316449812 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -43,7 +43,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h"
#include "ggc.h"
#include "gstab.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "debug.h"
#include "target.h"
#include "target-def.h"
@@ -1029,6 +1029,19 @@ static const struct mips_rtx_cost_data
1, /* branch_cost */
4 /* memory_latency */
},
+ { /* R5900 */
+ COSTS_N_INSNS (4), /* fp_add */
+ COSTS_N_INSNS (4), /* fp_mult_sf */
+ COSTS_N_INSNS (256), /* fp_mult_df */
+ COSTS_N_INSNS (8), /* fp_div_sf */
+ COSTS_N_INSNS (256), /* fp_div_df */
+ COSTS_N_INSNS (4), /* int_mult_si */
+ COSTS_N_INSNS (256), /* int_mult_di */
+ COSTS_N_INSNS (37), /* int_div_si */
+ COSTS_N_INSNS (256), /* int_div_di */
+ 1, /* branch_cost */
+ 4 /* memory_latency */
+ },
{ /* R7000 */
/* The only costs that are changed here are
integer multiplication. */
@@ -13005,6 +13018,7 @@ mips_issue_rate (void)
case PROCESSOR_R4130:
case PROCESSOR_R5400:
case PROCESSOR_R5500:
+ case PROCESSOR_R5900:
case PROCESSOR_R7000:
case PROCESSOR_R9000:
case PROCESSOR_OCTEON:
@@ -15806,30 +15820,43 @@ mips_hash_base (rtx base)
return hash_rtx (base, GET_MODE (base), &do_not_record_p, NULL, false);
}
+/* Hashtable helpers. */
+
+struct mips_lo_sum_offset_hasher : typed_free_remove <mips_lo_sum_offset>
+{
+ typedef mips_lo_sum_offset value_type;
+ typedef rtx_def compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
/* Hash-table callbacks for mips_lo_sum_offsets. */
-static hashval_t
-mips_lo_sum_offset_hash (const void *entry)
+inline hashval_t
+mips_lo_sum_offset_hasher::hash (const value_type *entry)
{
- return mips_hash_base (((const struct mips_lo_sum_offset *) entry)->base);
+ return mips_hash_base (entry->base);
}
-static int
-mips_lo_sum_offset_eq (const void *entry, const void *value)
+inline bool
+mips_lo_sum_offset_hasher::equal (const value_type *entry,
+ const compare_type *value)
{
- return rtx_equal_p (((const struct mips_lo_sum_offset *) entry)->base,
- (const_rtx) value);
+ return rtx_equal_p (entry->base, value);
}
+typedef hash_table <mips_lo_sum_offset_hasher> mips_offset_table;
+
/* Look up symbolic constant X in HTAB, which is a hash table of
mips_lo_sum_offsets. If OPTION is NO_INSERT, return true if X can be
paired with a recorded LO_SUM, otherwise record X in the table. */
static bool
-mips_lo_sum_offset_lookup (htab_t htab, rtx x, enum insert_option option)
+mips_lo_sum_offset_lookup (mips_offset_table htab, rtx x,
+ enum insert_option option)
{
rtx base, offset;
- void **slot;
+ mips_lo_sum_offset **slot;
struct mips_lo_sum_offset *entry;
/* Split X into a base and offset. */
@@ -15838,7 +15865,7 @@ mips_lo_sum_offset_lookup (htab_t htab, rtx x, enum insert_option option)
base = UNSPEC_ADDRESS (base);
/* Look up the base in the hash table. */
- slot = htab_find_slot_with_hash (htab, base, mips_hash_base (base), option);
+ slot = htab.find_slot_with_hash (base, mips_hash_base (base), option);
if (slot == NULL)
return false;
@@ -15868,7 +15895,8 @@ static int
mips_record_lo_sum (rtx *loc, void *data)
{
if (GET_CODE (*loc) == LO_SUM)
- mips_lo_sum_offset_lookup ((htab_t) data, XEXP (*loc, 1), INSERT);
+ mips_lo_sum_offset_lookup (*(mips_offset_table*) data,
+ XEXP (*loc, 1), INSERT);
return 0;
}
@@ -15877,7 +15905,7 @@ mips_record_lo_sum (rtx *loc, void *data)
LO_SUMs in the current function. */
static bool
-mips_orphaned_high_part_p (htab_t htab, rtx insn)
+mips_orphaned_high_part_p (mips_offset_table htab, rtx insn)
{
enum mips_symbol_type type;
rtx x, set;
@@ -15985,7 +16013,7 @@ mips_reorg_process_insns (void)
{
rtx insn, last_insn, subinsn, next_insn, lo_reg, delayed_reg;
int hilo_delay;
- htab_t htab;
+ mips_offset_table htab;
/* Force all instructions to be split into their final form. */
split_all_insns_noflow ();
@@ -16011,8 +16039,9 @@ mips_reorg_process_insns (void)
cfun->machine->all_noreorder_p = false;
/* Code compiled with -mfix-vr4120 or -mfix-24k can't be all noreorder
- because we rely on the assembler to work around some errata. */
- if (TARGET_FIX_VR4120 || TARGET_FIX_24K)
+ because we rely on the assembler to work around some errata.
+ The r5900 too has several bugs. */
+ if (TARGET_FIX_VR4120 || TARGET_FIX_24K || TARGET_MIPS5900)
cfun->machine->all_noreorder_p = false;
/* The same is true for -mfix-vr4130 if we might generate MFLO or
@@ -16022,14 +16051,13 @@ mips_reorg_process_insns (void)
if (TARGET_FIX_VR4130 && !ISA_HAS_MACCHI)
cfun->machine->all_noreorder_p = false;
- htab = htab_create (37, mips_lo_sum_offset_hash,
- mips_lo_sum_offset_eq, free);
+ htab.create (37);
/* Make a first pass over the instructions, recording all the LO_SUMs. */
for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
FOR_EACH_SUBINSN (subinsn, insn)
if (USEFUL_INSN_P (subinsn))
- for_each_rtx (&PATTERN (subinsn), mips_record_lo_sum, htab);
+ for_each_rtx (&PATTERN (subinsn), mips_record_lo_sum, &htab);
last_insn = 0;
hilo_delay = 2;
@@ -16086,7 +16114,7 @@ mips_reorg_process_insns (void)
}
}
- htab_delete (htab);
+ htab.dispose ();
}
/* Return true if the function has a long branch instruction. */
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index a8cf1dbedc7..48a8b42f5bc 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -222,6 +222,7 @@ struct mips_cpu_info {
#define TARGET_MIPS4130 (mips_arch == PROCESSOR_R4130)
#define TARGET_MIPS5400 (mips_arch == PROCESSOR_R5400)
#define TARGET_MIPS5500 (mips_arch == PROCESSOR_R5500)
+#define TARGET_MIPS5900 (mips_arch == PROCESSOR_R5900)
#define TARGET_MIPS7000 (mips_arch == PROCESSOR_R7000)
#define TARGET_MIPS9000 (mips_arch == PROCESSOR_R9000)
#define TARGET_OCTEON (mips_arch == PROCESSOR_OCTEON \
@@ -399,6 +400,9 @@ struct mips_cpu_info {
if (TARGET_MCU) \
builtin_define ("__mips_mcu"); \
\
+ if (TARGET_EVA) \
+ builtin_define ("__mips_eva"); \
+ \
if (TARGET_DSP) \
{ \
builtin_define ("__mips_dsp"); \
@@ -833,7 +837,9 @@ struct mips_cpu_info {
/* ISA has the integer conditional move instructions introduced in mips4 and
ST Loongson 2E/2F. */
-#define ISA_HAS_CONDMOVE (ISA_HAS_FP_CONDMOVE || TARGET_LOONGSON_2EF)
+#define ISA_HAS_CONDMOVE (ISA_HAS_FP_CONDMOVE \
+ || TARGET_MIPS5900 \
+ || TARGET_LOONGSON_2EF)
/* ISA has LDC1 and SDC1. */
#define ISA_HAS_LDC1_SDC1 (!ISA_MIPS1 && !TARGET_MIPS16)
@@ -946,6 +952,7 @@ struct mips_cpu_info {
/* ISA has data prefetch instructions. This controls use of 'pref'. */
#define ISA_HAS_PREFETCH ((ISA_MIPS4 \
|| TARGET_LOONGSON_2EF \
+ || TARGET_MIPS5900 \
|| ISA_MIPS32 \
|| ISA_MIPS32R2 \
|| ISA_MIPS64 \
@@ -1007,15 +1014,18 @@ struct mips_cpu_info {
and "addiu $4,$4,1". */
#define ISA_HAS_LOAD_DELAY (ISA_MIPS1 \
&& !TARGET_MIPS3900 \
+ && !TARGET_MIPS5900 \
&& !TARGET_MIPS16 \
&& !TARGET_MICROMIPS)
/* Likewise mtc1 and mfc1. */
#define ISA_HAS_XFER_DELAY (mips_isa <= 3 \
+ && !TARGET_MIPS5900 \
&& !TARGET_LOONGSON_2EF)
/* Likewise floating-point comparisons. */
#define ISA_HAS_FCMP_DELAY (mips_isa <= 3 \
+ && !TARGET_MIPS5900 \
&& !TARGET_LOONGSON_2EF)
/* True if mflo and mfhi can be immediately followed by instructions
@@ -1035,6 +1045,7 @@ struct mips_cpu_info {
|| ISA_MIPS64 \
|| ISA_MIPS64R2 \
|| TARGET_MIPS5500 \
+ || TARGET_MIPS5900 \
|| TARGET_LOONGSON_2EF)
/* ISA includes synci, jr.hb and jalr.hb. */
@@ -1125,6 +1136,7 @@ struct mips_cpu_info {
%{mdsp} %{mno-dsp} \
%{mdspr2} %{mno-dspr2} \
%{mmcu} %{mno-mcu} \
+%{meva} %{mno-eva} \
%{msmartmips} %{mno-smartmips} \
%{mmt} %{mno-mt} \
%{mfix-vr4120} %{mfix-vr4130} \
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 6f6484b0d8c..2fdc79d2211 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -55,6 +55,7 @@
r5000
r5400
r5500
+ r5900
r7000
r8000
r9000
@@ -755,7 +756,9 @@
;; This mode iterator allows :MOVECC to be used anywhere that a
;; conditional-move-type condition is needed.
(define_mode_iterator MOVECC [SI (DI "TARGET_64BIT")
- (CC "TARGET_HARD_FLOAT && !TARGET_LOONGSON_2EF")])
+ (CC "TARGET_HARD_FLOAT
+ && !TARGET_LOONGSON_2EF
+ && !TARGET_MIPS5900")])
;; 32-bit integer moves for which we provide move patterns.
(define_mode_iterator IMOVE32
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index e11710db3c0..08ab29b1810 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -141,6 +141,10 @@ membedded-data
Target Report Var(TARGET_EMBEDDED_DATA)
Use ROM instead of RAM
+meva
+Target Report Var(TARGET_EVA)
+Use Enhanced Virtual Addressing instructions
+
mexplicit-relocs
Target Report Mask(EXPLICIT_RELOCS)
Use NewABI-style %reloc() assembly operators
diff --git a/gcc/config/mips/mti-linux.h b/gcc/config/mips/mti-linux.h
index a3fb48976bd..45bc0b88107 100644
--- a/gcc/config/mips/mti-linux.h
+++ b/gcc/config/mips/mti-linux.h
@@ -20,7 +20,7 @@ along with GCC; see the file COPYING3. If not see
/* This target is a multilib target, specify the sysroot paths. */
#undef SYSROOT_SUFFIX_SPEC
#define SYSROOT_SUFFIX_SPEC \
- "%{mips32:/mips32}%{mips64:/mips64}%{mips64r2:/mips64r2}%{mabi=64:/64}%{mel|EL:/el}%{msoft-float:/sof}"
+ "%{mips32:/mips32}%{mips64:/mips64}%{mips64r2:/mips64r2}%{mips16:/mips16}%{mmicromips:/micromips}%{mabi=64:/64}%{mel|EL:/el}%{msoft-float:/sof}"
#undef DRIVER_SELF_SPECS
#define DRIVER_SELF_SPECS \
diff --git a/gcc/config/mips/t-mti-elf b/gcc/config/mips/t-mti-elf
index 3f0868fb856..bce8f063452 100644
--- a/gcc/config/mips/t-mti-elf
+++ b/gcc/config/mips/t-mti-elf
@@ -16,20 +16,29 @@
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
-MULTILIB_OPTIONS = mips32/mips64/mips64r2 mips16 mabi=64 EL msoft-float
-MULTILIB_DIRNAMES = mips32 mips64 mips64r2 mips16 64 el sof
-MULTILIB_MATCHES = EL=mel EB=meb
+# The default build is mips32r2, hard-float big-endian. Add mips32,
+# soft-float, and little-endian variations.
-# We do not want to build mips16 versions of mips64* architectures.
-MULTILIB_EXCEPTIONS += *mips64*/*mips16*
+MULTILIB_OPTIONS = mips32/mips64/mips64r2 mips16 mmicromips mabi=64 EL msoft-float
+MULTILIB_DIRNAMES = mips32 mips64 mips64r2 mips16 micromips 64 el sof
+MULTILIB_MATCHES = EL=mel EB=meb
-# 64 bit ABI is not supported on mips32 architecture.
+# The 64 bit ABI is not supported on the mips32 architecture.
MULTILIB_EXCEPTIONS += *mips32*/*mabi=64*
-# The 64 bit ABI is not supported on the mips32r2 bit architecture.
-# Because mips32r2 is the default the exception list is a little messy.
-# Basically we are saying any list that doesn't specify mips32, mips64,
-# or mips64r2 but does specify mabi=64 is not allowed because that
-# would be defaulting to the mips32r2 architecture.
+# The 64 bit ABI is not supported on the mips32r2 architecture.
+# Because mips32r2 is the default we can't use that flag to trigger
+# the exception so we check for mabi=64 with no specific mips
+# architecture flag instead.
MULTILIB_EXCEPTIONS += mabi=64*
-MULTILIB_EXCEPTIONS += mips16/mabi=64*
+
+# We do not want to build mips16 versions of mips64* architectures.
+MULTILIB_EXCEPTIONS += *mips64*/*mips16*
+MULTILIB_EXCEPTIONS += *mips16/mabi=64*
+
+# We only want micromips for mips32r2 architecture and we do not want
+# it used in conjunction with -mips16.
+MULTILIB_EXCEPTIONS += *mips16/mmicromips*
+MULTILIB_EXCEPTIONS += *mips64*/mmicromips*
+MULTILIB_EXCEPTIONS += *mips32/mmicromips*
+MULTILIB_EXCEPTIONS += *mmicromips/mabi=64*
diff --git a/gcc/config/mips/t-mti-linux b/gcc/config/mips/t-mti-linux
index 775a68d9dae..bce8f063452 100644
--- a/gcc/config/mips/t-mti-linux
+++ b/gcc/config/mips/t-mti-linux
@@ -19,8 +19,8 @@
# The default build is mips32r2, hard-float big-endian. Add mips32,
# soft-float, and little-endian variations.
-MULTILIB_OPTIONS = mips32/mips64/mips64r2 mabi=64 EL msoft-float
-MULTILIB_DIRNAMES = mips32 mips64 mips64r2 64 el sof
+MULTILIB_OPTIONS = mips32/mips64/mips64r2 mips16 mmicromips mabi=64 EL msoft-float
+MULTILIB_DIRNAMES = mips32 mips64 mips64r2 mips16 micromips 64 el sof
MULTILIB_MATCHES = EL=mel EB=meb
# The 64 bit ABI is not supported on the mips32 architecture.
@@ -28,6 +28,17 @@ MULTILIB_EXCEPTIONS += *mips32*/*mabi=64*
# The 64 bit ABI is not supported on the mips32r2 architecture.
# Because mips32r2 is the default we can't use that flag to trigger
-# the exception so we check for mabi=64 with no specific mips flag
-# instead.
+# the exception so we check for mabi=64 with no specific mips
+# architecture flag instead.
MULTILIB_EXCEPTIONS += mabi=64*
+
+# We do not want to build mips16 versions of mips64* architectures.
+MULTILIB_EXCEPTIONS += *mips64*/*mips16*
+MULTILIB_EXCEPTIONS += *mips16/mabi=64*
+
+# We only want micromips for mips32r2 architecture and we do not want
+# it used in conjunction with -mips16.
+MULTILIB_EXCEPTIONS += *mips16/mmicromips*
+MULTILIB_EXCEPTIONS += *mips64*/mmicromips*
+MULTILIB_EXCEPTIONS += *mips32/mmicromips*
+MULTILIB_EXCEPTIONS += *mmicromips/mabi=64*
diff --git a/gcc/config/rl78/rl78.md b/gcc/config/rl78/rl78.md
index b3cfe6d1bbc..1bcfc84fdb9 100644
--- a/gcc/config/rl78/rl78.md
+++ b/gcc/config/rl78/rl78.md
@@ -235,6 +235,24 @@
[(set_attr "valloc" "macax")]
)
+(define_expand "mulqi3"
+ [(set (match_operand:QI 0 "register_operand" "")
+ (mult:QI (match_operand:QI 1 "general_operand" "")
+ (match_operand:QI 2 "nonmemory_operand" "")))
+ ]
+ "" ; mulu supported by all targets
+ ""
+)
+
+(define_expand "mulhi3"
+ [(set (match_operand:HI 0 "register_operand" "")
+ (mult:HI (match_operand:HI 1 "general_operand" "")
+ (match_operand:HI 2 "nonmemory_operand" "")))
+ ]
+ "! RL78_MUL_NONE"
+ ""
+)
+
(define_expand "mulsi3"
[(set (match_operand:SI 0 "register_operand" "=&v")
(mult:SI (match_operand:SI 1 "nonmemory_operand" "vi")
@@ -244,6 +262,55 @@
""
)
+(define_insn "*mulqi3_rl78"
+ [(set (match_operand:QI 0 "register_operand" "=&v")
+ (mult:QI (match_operand:QI 1 "general_operand" "+viU")
+ (match_operand:QI 2 "general_operand" "vi")))
+ ]
+ "" ; mulu supported by all targets
+ "; mulqi macro %0 = %1 * %2
+ mov a, %h1
+ mov x, a
+ mov a, %h2
+ mulu x ; ax = a * x
+ mov a, x
+ mov %h0, a
+ ; end of mulqi macro"
+)
+
+(define_insn "*mulhi3_rl78"
+ [(set (match_operand:HI 0 "register_operand" "=&v")
+ (mult:HI (match_operand:HI 1 "general_operand" "+viU")
+ (match_operand:HI 2 "general_operand" "vi")))
+ ]
+ "RL78_MUL_RL78"
+ "; mulhi macro %0 = %1 * %2
+ movw ax, %h1
+ movw bc, %h2
+ mulhu ; bcax = bc * ax
+ movw %h0, ax
+ ; end of mulhi macro"
+)
+
+(define_insn "*mulhi3_g13"
+ [(set (match_operand:HI 0 "register_operand" "=&v")
+ (mult:HI (match_operand:HI 1 "general_operand" "+viU")
+ (match_operand:HI 2 "general_operand" "vi")))
+ ]
+ "RL78_MUL_G13"
+ "; mulhi macro %0 = %1 * %2
+ mov a, #0x00
+ mov !0xf00e8, a ; MDUC
+ movw ax, %h1
+ movw 0xffff0, ax ; MDAL
+ movw ax, %h2
+ movw 0xffff2, ax ; MDAH
+ nop ; mdb = mdal * mdah
+ movw ax, 0xffff6 ; MDBL
+ movw %h0, ax
+ ; end of mulhi macro"
+)
+
;; 0xFFFF0 is MACR(L). 0xFFFF2 is MACR(H) but we don't care about it
;; because we're only using the lower 16 bits (which is the upper 16
;; bits of the result).
diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h
index fd6d07f50ff..19a4ae9297d 100644
--- a/gcc/config/rs6000/altivec.h
+++ b/gcc/config/rs6000/altivec.h
@@ -321,6 +321,26 @@
#define vec_vsx_st __builtin_vec_vsx_st
#endif
+#ifdef _ARCH_PWR8
+/* Vector additions added in ISA 2.07. */
+#define vec_vaddudm __builtin_vec_vaddudm
+#define vec_vmaxsd __builtin_vec_vmaxsd
+#define vec_vmaxud __builtin_vec_vmaxud
+#define vec_vminsd __builtin_vec_vminsd
+#define vec_vminud __builtin_vec_vminud
+#define vec_vpksdss __builtin_vec_vpksdss
+#define vec_vpksdus __builtin_vec_vpksdus
+#define vec_vpkudum __builtin_vec_vpkudum
+#define vec_vpkudus __builtin_vec_vpkudus
+#define vec_vrld __builtin_vec_vrld
+#define vec_vsld __builtin_vec_vsld
+#define vec_vsrad __builtin_vec_vsrad
+#define vec_vsrd __builtin_vec_vsrd
+#define vec_vsubudm __builtin_vec_vsubudm
+#define vec_vupkhsw __builtin_vec_vupkhsw
+#define vec_vupklsw __builtin_vec_vupklsw
+#endif
+
/* Predicates.
For C++, we use templates in order to allow non-parenthesized arguments.
For C, instead, we use macros since non-parenthesized arguments were
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 1b0b5c3fb13..78d29001440 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -41,15 +41,11 @@
UNSPEC_VMULOSB
UNSPEC_VMULOUH
UNSPEC_VMULOSH
- UNSPEC_VPKUHUM
- UNSPEC_VPKUWUM
UNSPEC_VPKPX
- UNSPEC_VPKSHSS
- UNSPEC_VPKSWSS
- UNSPEC_VPKUHUS
- UNSPEC_VPKSHUS
- UNSPEC_VPKUWUS
- UNSPEC_VPKSWUS
+ UNSPEC_VPACK_SIGN_SIGN_SAT
+ UNSPEC_VPACK_SIGN_UNS_SAT
+ UNSPEC_VPACK_UNS_UNS_SAT
+ UNSPEC_VPACK_UNS_UNS_MOD
UNSPEC_VSLV4SI
UNSPEC_VSLO
UNSPEC_VSR
@@ -71,12 +67,10 @@
UNSPEC_VLOGEFP
UNSPEC_VEXPTEFP
UNSPEC_VLSDOI
- UNSPEC_VUPKHSB
+ UNSPEC_VUNPACK_HI_SIGN
+ UNSPEC_VUNPACK_LO_SIGN
UNSPEC_VUPKHPX
- UNSPEC_VUPKHSH
- UNSPEC_VUPKLSB
UNSPEC_VUPKLPX
- UNSPEC_VUPKLSH
UNSPEC_DST
UNSPEC_DSTT
UNSPEC_DSTST
@@ -146,6 +140,8 @@
;; Vec int modes
(define_mode_iterator VI [V4SI V8HI V16QI])
+;; Like VI, but add ISA 2.07 integer vector ops
+(define_mode_iterator VI2 [V4SI V8HI V16QI V2DI])
;; Short vec in modes
(define_mode_iterator VIshort [V8HI V16QI])
;; Vec float modes
@@ -159,8 +155,18 @@
;; Like VM, except don't do TImode
(define_mode_iterator VM2 [V4SI V8HI V16QI V4SF V2DF V2DI])
-(define_mode_attr VI_char [(V4SI "w") (V8HI "h") (V16QI "b")])
-(define_mode_attr VI_scalar [(V4SI "SI") (V8HI "HI") (V16QI "QI")])
+(define_mode_attr VI_char [(V2DI "d") (V4SI "w") (V8HI "h") (V16QI "b")])
+(define_mode_attr VI_scalar [(V2DI "DI") (V4SI "SI") (V8HI "HI") (V16QI "QI")])
+(define_mode_attr VI_unit [(V16QI "VECTOR_UNIT_ALTIVEC_P (V16QImode)")
+ (V8HI "VECTOR_UNIT_ALTIVEC_P (V8HImode)")
+ (V4SI "VECTOR_UNIT_ALTIVEC_P (V4SImode)")
+ (V2DI "VECTOR_UNIT_P8_VECTOR_P (V2DImode)")])
+
+;; Vector pack/unpack
+(define_mode_iterator VP [V2DI V4SI V8HI])
+(define_mode_attr VP_small [(V2DI "V4SI") (V4SI "V8HI") (V8HI "V16QI")])
+(define_mode_attr VP_small_lc [(V2DI "v4si") (V4SI "v8hi") (V8HI "v16qi")])
+(define_mode_attr VU_char [(V2DI "w") (V4SI "h") (V8HI "b")])
;; Vector move instructions.
(define_insn "*altivec_mov<mode>"
@@ -378,10 +384,10 @@
;; add
(define_insn "add<mode>3"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (plus:VI (match_operand:VI 1 "register_operand" "v")
- (match_operand:VI 2 "register_operand" "v")))]
- "TARGET_ALTIVEC"
+ [(set (match_operand:VI2 0 "register_operand" "=v")
+ (plus:VI2 (match_operand:VI2 1 "register_operand" "v")
+ (match_operand:VI2 2 "register_operand" "v")))]
+ "<VI_unit>"
"vaddu<VI_char>m %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -398,17 +404,17 @@
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")]
UNSPEC_VADDCUW))]
- "TARGET_ALTIVEC"
+ "VECTOR_UNIT_ALTIVEC_P (V4SImode)"
"vaddcuw %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "altivec_vaddu<VI_char>s"
[(set (match_operand:VI 0 "register_operand" "=v")
(unspec:VI [(match_operand:VI 1 "register_operand" "v")
- (match_operand:VI 2 "register_operand" "v")]
+ (match_operand:VI 2 "register_operand" "v")]
UNSPEC_VADDU))
(set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
- "TARGET_ALTIVEC"
+ "<VI_unit>"
"vaddu<VI_char>s %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -418,16 +424,16 @@
(match_operand:VI 2 "register_operand" "v")]
UNSPEC_VADDS))
(set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
- "TARGET_ALTIVEC"
+ "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
"vadds<VI_char>s %0,%1,%2"
[(set_attr "type" "vecsimple")])
;; sub
(define_insn "sub<mode>3"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (minus:VI (match_operand:VI 1 "register_operand" "v")
- (match_operand:VI 2 "register_operand" "v")))]
- "TARGET_ALTIVEC"
+ [(set (match_operand:VI2 0 "register_operand" "=v")
+ (minus:VI2 (match_operand:VI2 1 "register_operand" "v")
+ (match_operand:VI2 2 "register_operand" "v")))]
+ "<VI_unit>"
"vsubu<VI_char>m %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -444,7 +450,7 @@
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")]
UNSPEC_VSUBCUW))]
- "TARGET_ALTIVEC"
+ "VECTOR_UNIT_ALTIVEC_P (V4SImode)"
"vsubcuw %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -454,7 +460,7 @@
(match_operand:VI 2 "register_operand" "v")]
UNSPEC_VSUBU))
(set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
- "TARGET_ALTIVEC"
+ "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
"vsubu<VI_char>s %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -464,7 +470,7 @@
(match_operand:VI 2 "register_operand" "v")]
UNSPEC_VSUBS))
(set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
- "TARGET_ALTIVEC"
+ "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
"vsubs<VI_char>s %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -483,7 +489,7 @@
(unspec:VI [(match_operand:VI 1 "register_operand" "v")
(match_operand:VI 2 "register_operand" "v")]
UNSPEC_VAVGS))]
- "TARGET_ALTIVEC"
+ "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
"vavgs<VI_char> %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -492,31 +498,31 @@
(unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")]
UNSPEC_VCMPBFP))]
- "TARGET_ALTIVEC"
+ "VECTOR_UNIT_ALTIVEC_P (V4SImode)"
"vcmpbfp %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "*altivec_eq<mode>"
- [(set (match_operand:VI 0 "altivec_register_operand" "=v")
- (eq:VI (match_operand:VI 1 "altivec_register_operand" "v")
- (match_operand:VI 2 "altivec_register_operand" "v")))]
- "TARGET_ALTIVEC"
+ [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
+ (eq:VI2 (match_operand:VI2 1 "altivec_register_operand" "v")
+ (match_operand:VI2 2 "altivec_register_operand" "v")))]
+ "<VI_unit>"
"vcmpequ<VI_char> %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "*altivec_gt<mode>"
- [(set (match_operand:VI 0 "altivec_register_operand" "=v")
- (gt:VI (match_operand:VI 1 "altivec_register_operand" "v")
- (match_operand:VI 2 "altivec_register_operand" "v")))]
- "TARGET_ALTIVEC"
+ [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
+ (gt:VI2 (match_operand:VI2 1 "altivec_register_operand" "v")
+ (match_operand:VI2 2 "altivec_register_operand" "v")))]
+ "<VI_unit>"
"vcmpgts<VI_char> %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "*altivec_gtu<mode>"
- [(set (match_operand:VI 0 "altivec_register_operand" "=v")
- (gtu:VI (match_operand:VI 1 "altivec_register_operand" "v")
- (match_operand:VI 2 "altivec_register_operand" "v")))]
- "TARGET_ALTIVEC"
+ [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
+ (gtu:VI2 (match_operand:VI2 1 "altivec_register_operand" "v")
+ (match_operand:VI2 2 "altivec_register_operand" "v")))]
+ "<VI_unit>"
"vcmpgtu<VI_char> %0,%1,%2"
[(set_attr "type" "veccmp")])
@@ -744,18 +750,18 @@
;; max
(define_insn "umax<mode>3"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (umax:VI (match_operand:VI 1 "register_operand" "v")
- (match_operand:VI 2 "register_operand" "v")))]
- "TARGET_ALTIVEC"
+ [(set (match_operand:VI2 0 "register_operand" "=v")
+ (umax:VI2 (match_operand:VI2 1 "register_operand" "v")
+ (match_operand:VI2 2 "register_operand" "v")))]
+ "<VI_unit>"
"vmaxu<VI_char> %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "smax<mode>3"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (smax:VI (match_operand:VI 1 "register_operand" "v")
- (match_operand:VI 2 "register_operand" "v")))]
- "TARGET_ALTIVEC"
+ [(set (match_operand:VI2 0 "register_operand" "=v")
+ (smax:VI2 (match_operand:VI2 1 "register_operand" "v")
+ (match_operand:VI2 2 "register_operand" "v")))]
+ "<VI_unit>"
"vmaxs<VI_char> %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -768,18 +774,18 @@
[(set_attr "type" "veccmp")])
(define_insn "umin<mode>3"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (umin:VI (match_operand:VI 1 "register_operand" "v")
- (match_operand:VI 2 "register_operand" "v")))]
- "TARGET_ALTIVEC"
+ [(set (match_operand:VI2 0 "register_operand" "=v")
+ (umin:VI2 (match_operand:VI2 1 "register_operand" "v")
+ (match_operand:VI2 2 "register_operand" "v")))]
+ "<VI_unit>"
"vminu<VI_char> %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "smin<mode>3"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (smin:VI (match_operand:VI 1 "register_operand" "v")
- (match_operand:VI 2 "register_operand" "v")))]
- "TARGET_ALTIVEC"
+ [(set (match_operand:VI2 0 "register_operand" "=v")
+ (smin:VI2 (match_operand:VI2 1 "register_operand" "v")
+ (match_operand:VI2 2 "register_operand" "v")))]
+ "<VI_unit>"
"vmins<VI_char> %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -1058,24 +1064,6 @@
"vandc %0,%1,%2"
[(set_attr "type" "vecsimple")])
-(define_insn "altivec_vpkuhum"
- [(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
- (match_operand:V8HI 2 "register_operand" "v")]
- UNSPEC_VPKUHUM))]
- "TARGET_ALTIVEC"
- "vpkuhum %0,%1,%2"
- [(set_attr "type" "vecperm")])
-
-(define_insn "altivec_vpkuwum"
- [(set (match_operand:V8HI 0 "register_operand" "=v")
- (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
- (match_operand:V4SI 2 "register_operand" "v")]
- UNSPEC_VPKUWUM))]
- "TARGET_ALTIVEC"
- "vpkuwum %0,%1,%2"
- [(set_attr "type" "vecperm")])
-
(define_insn "altivec_vpkpx"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
@@ -1085,71 +1073,47 @@
"vpkpx %0,%1,%2"
[(set_attr "type" "vecperm")])
-(define_insn "altivec_vpkshss"
- [(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
- (match_operand:V8HI 2 "register_operand" "v")]
- UNSPEC_VPKSHSS))
- (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
- "TARGET_ALTIVEC"
- "vpkshss %0,%1,%2"
- [(set_attr "type" "vecperm")])
-
-(define_insn "altivec_vpkswss"
- [(set (match_operand:V8HI 0 "register_operand" "=v")
- (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
- (match_operand:V4SI 2 "register_operand" "v")]
- UNSPEC_VPKSWSS))
- (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
- "TARGET_ALTIVEC"
- "vpkswss %0,%1,%2"
- [(set_attr "type" "vecperm")])
-
-(define_insn "altivec_vpkuhus"
- [(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
- (match_operand:V8HI 2 "register_operand" "v")]
- UNSPEC_VPKUHUS))
- (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
- "TARGET_ALTIVEC"
- "vpkuhus %0,%1,%2"
+(define_insn "altivec_vpks<VI_char>ss"
+ [(set (match_operand:<VP_small> 0 "register_operand" "=v")
+ (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
+ (match_operand:VP 2 "register_operand" "v")]
+ UNSPEC_VPACK_SIGN_SIGN_SAT))]
+ "<VI_unit>"
+ "vpks<VI_char>ss %0,%1,%2"
[(set_attr "type" "vecperm")])
-(define_insn "altivec_vpkshus"
- [(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
- (match_operand:V8HI 2 "register_operand" "v")]
- UNSPEC_VPKSHUS))
- (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
- "TARGET_ALTIVEC"
- "vpkshus %0,%1,%2"
+(define_insn "altivec_vpks<VI_char>us"
+ [(set (match_operand:<VP_small> 0 "register_operand" "=v")
+ (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
+ (match_operand:VP 2 "register_operand" "v")]
+ UNSPEC_VPACK_SIGN_UNS_SAT))]
+ "<VI_unit>"
+ "vpks<VI_char>us %0,%1,%2"
[(set_attr "type" "vecperm")])
-(define_insn "altivec_vpkuwus"
- [(set (match_operand:V8HI 0 "register_operand" "=v")
- (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
- (match_operand:V4SI 2 "register_operand" "v")]
- UNSPEC_VPKUWUS))
- (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
- "TARGET_ALTIVEC"
- "vpkuwus %0,%1,%2"
+(define_insn "altivec_vpku<VI_char>us"
+ [(set (match_operand:<VP_small> 0 "register_operand" "=v")
+ (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
+ (match_operand:VP 2 "register_operand" "v")]
+ UNSPEC_VPACK_UNS_UNS_SAT))]
+ "<VI_unit>"
+ "vpku<VI_char>us %0,%1,%2"
[(set_attr "type" "vecperm")])
-(define_insn "altivec_vpkswus"
- [(set (match_operand:V8HI 0 "register_operand" "=v")
- (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
- (match_operand:V4SI 2 "register_operand" "v")]
- UNSPEC_VPKSWUS))
- (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
- "TARGET_ALTIVEC"
- "vpkswus %0,%1,%2"
+(define_insn "altivec_vpku<VI_char>um"
+ [(set (match_operand:<VP_small> 0 "register_operand" "=v")
+ (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
+ (match_operand:VP 2 "register_operand" "v")]
+ UNSPEC_VPACK_UNS_UNS_MOD))]
+ "<VI_unit>"
+ "vpku<VI_char>um %0,%1,%2"
[(set_attr "type" "vecperm")])
(define_insn "*altivec_vrl<VI_char>"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (rotate:VI (match_operand:VI 1 "register_operand" "v")
- (match_operand:VI 2 "register_operand" "v")))]
- "TARGET_ALTIVEC"
+ [(set (match_operand:VI2 0 "register_operand" "=v")
+ (rotate:VI2 (match_operand:VI2 1 "register_operand" "v")
+ (match_operand:VI2 2 "register_operand" "v")))]
+ "<VI_unit>"
"vrl<VI_char> %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -1172,26 +1136,26 @@
[(set_attr "type" "vecperm")])
(define_insn "*altivec_vsl<VI_char>"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (ashift:VI (match_operand:VI 1 "register_operand" "v")
- (match_operand:VI 2 "register_operand" "v")))]
- "TARGET_ALTIVEC"
+ [(set (match_operand:VI2 0 "register_operand" "=v")
+ (ashift:VI2 (match_operand:VI2 1 "register_operand" "v")
+ (match_operand:VI2 2 "register_operand" "v")))]
+ "<VI_unit>"
"vsl<VI_char> %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "*altivec_vsr<VI_char>"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (lshiftrt:VI (match_operand:VI 1 "register_operand" "v")
- (match_operand:VI 2 "register_operand" "v")))]
- "TARGET_ALTIVEC"
+ [(set (match_operand:VI2 0 "register_operand" "=v")
+ (lshiftrt:VI2 (match_operand:VI2 1 "register_operand" "v")
+ (match_operand:VI2 2 "register_operand" "v")))]
+ "<VI_unit>"
"vsr<VI_char> %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "*altivec_vsra<VI_char>"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (ashiftrt:VI (match_operand:VI 1 "register_operand" "v")
- (match_operand:VI 2 "register_operand" "v")))]
- "TARGET_ALTIVEC"
+ [(set (match_operand:VI2 0 "register_operand" "=v")
+ (ashiftrt:VI2 (match_operand:VI2 1 "register_operand" "v")
+ (match_operand:VI2 2 "register_operand" "v")))]
+ "<VI_unit>"
"vsra<VI_char> %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -1476,12 +1440,20 @@
"vsldoi %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
-(define_insn "altivec_vupkhsb"
- [(set (match_operand:V8HI 0 "register_operand" "=v")
- (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
- UNSPEC_VUPKHSB))]
- "TARGET_ALTIVEC"
- "vupkhsb %0,%1"
+(define_insn "altivec_vupkhs<VU_char>"
+ [(set (match_operand:VP 0 "register_operand" "=v")
+ (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
+ UNSPEC_VUNPACK_HI_SIGN))]
+ "<VI_unit>"
+ "vupkhs<VU_char> %0,%1"
+ [(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vupkls<VU_char>"
+ [(set (match_operand:VP 0 "register_operand" "=v")
+ (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
+ UNSPEC_VUNPACK_LO_SIGN))]
+ "<VI_unit>"
+ "vupkls<VU_char> %0,%1"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vupkhpx"
@@ -1492,22 +1464,6 @@
"vupkhpx %0,%1"
[(set_attr "type" "vecperm")])
-(define_insn "altivec_vupkhsh"
- [(set (match_operand:V4SI 0 "register_operand" "=v")
- (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
- UNSPEC_VUPKHSH))]
- "TARGET_ALTIVEC"
- "vupkhsh %0,%1"
- [(set_attr "type" "vecperm")])
-
-(define_insn "altivec_vupklsb"
- [(set (match_operand:V8HI 0 "register_operand" "=v")
- (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
- UNSPEC_VUPKLSB))]
- "TARGET_ALTIVEC"
- "vupklsb %0,%1"
- [(set_attr "type" "vecperm")])
-
(define_insn "altivec_vupklpx"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
@@ -1516,49 +1472,41 @@
"vupklpx %0,%1"
[(set_attr "type" "vecperm")])
-(define_insn "altivec_vupklsh"
- [(set (match_operand:V4SI 0 "register_operand" "=v")
- (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
- UNSPEC_VUPKLSH))]
- "TARGET_ALTIVEC"
- "vupklsh %0,%1"
- [(set_attr "type" "vecperm")])
-
;; Compare vectors producing a vector result and a predicate, setting CR6 to
;; indicate a combined status
(define_insn "*altivec_vcmpequ<VI_char>_p"
[(set (reg:CC 74)
- (unspec:CC [(eq:CC (match_operand:VI 1 "register_operand" "v")
- (match_operand:VI 2 "register_operand" "v"))]
+ (unspec:CC [(eq:CC (match_operand:VI2 1 "register_operand" "v")
+ (match_operand:VI2 2 "register_operand" "v"))]
UNSPEC_PREDICATE))
- (set (match_operand:VI 0 "register_operand" "=v")
- (eq:VI (match_dup 1)
- (match_dup 2)))]
- "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
+ (set (match_operand:VI2 0 "register_operand" "=v")
+ (eq:VI2 (match_dup 1)
+ (match_dup 2)))]
+ "<VI_unit>"
"vcmpequ<VI_char>. %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "*altivec_vcmpgts<VI_char>_p"
[(set (reg:CC 74)
- (unspec:CC [(gt:CC (match_operand:VI 1 "register_operand" "v")
- (match_operand:VI 2 "register_operand" "v"))]
+ (unspec:CC [(gt:CC (match_operand:VI2 1 "register_operand" "v")
+ (match_operand:VI2 2 "register_operand" "v"))]
UNSPEC_PREDICATE))
- (set (match_operand:VI 0 "register_operand" "=v")
- (gt:VI (match_dup 1)
- (match_dup 2)))]
- "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
+ (set (match_operand:VI2 0 "register_operand" "=v")
+ (gt:VI2 (match_dup 1)
+ (match_dup 2)))]
+ "<VI_unit>"
"vcmpgts<VI_char>. %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "*altivec_vcmpgtu<VI_char>_p"
[(set (reg:CC 74)
- (unspec:CC [(gtu:CC (match_operand:VI 1 "register_operand" "v")
- (match_operand:VI 2 "register_operand" "v"))]
+ (unspec:CC [(gtu:CC (match_operand:VI2 1 "register_operand" "v")
+ (match_operand:VI2 2 "register_operand" "v"))]
UNSPEC_PREDICATE))
- (set (match_operand:VI 0 "register_operand" "=v")
- (gtu:VI (match_dup 1)
- (match_dup 2)))]
- "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
+ (set (match_operand:VI2 0 "register_operand" "=v")
+ (gtu:VI2 (match_dup 1)
+ (match_dup 2)))]
+ "<VI_unit>"
"vcmpgtu<VI_char>. %0,%1,%2"
[(set_attr "type" "veccmp")])
@@ -1779,20 +1727,28 @@
[(set_attr "type" "vecstore")])
;; Generate
-;; vspltis? SCRATCH0,0
+;; xxlxor/vxor SCRATCH0,SCRATCH0,SCRATCH0
;; vsubu?m SCRATCH2,SCRATCH1,%1
;; vmaxs? %0,%1,SCRATCH2"
(define_expand "abs<mode>2"
- [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
- (set (match_dup 3)
- (minus:VI (match_dup 2)
- (match_operand:VI 1 "register_operand" "v")))
- (set (match_operand:VI 0 "register_operand" "=v")
- (smax:VI (match_dup 1) (match_dup 3)))]
- "TARGET_ALTIVEC"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 4)
+ (minus:VI2 (match_dup 2)
+ (match_operand:VI2 1 "register_operand" "v")))
+ (set (match_operand:VI2 0 "register_operand" "=v")
+ (smax:VI2 (match_dup 1) (match_dup 4)))]
+ "<VI_unit>"
{
- operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
- operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
+ int i, n_elt = GET_MODE_NUNITS (<MODE>mode);
+ rtvec v = rtvec_alloc (n_elt);
+
+ /* Create an all 0 constant. */
+ for (i = 0; i < n_elt; ++i)
+ RTVEC_ELT (v, i) = const0_rtx;
+
+ operands[2] = gen_reg_rtx (<MODE>mode);
+ operands[3] = gen_rtx_CONST_VECTOR (<MODE>mode, v);
+ operands[4] = gen_reg_rtx (<MODE>mode);
})
;; Generate
@@ -1950,49 +1906,19 @@
DONE;
}")
-(define_expand "vec_unpacks_hi_v16qi"
- [(set (match_operand:V8HI 0 "register_operand" "=v")
- (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
- UNSPEC_VUPKHSB))]
- "TARGET_ALTIVEC"
- "
-{
- emit_insn (gen_altivec_vupkhsb (operands[0], operands[1]));
- DONE;
-}")
-
-(define_expand "vec_unpacks_hi_v8hi"
- [(set (match_operand:V4SI 0 "register_operand" "=v")
- (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
- UNSPEC_VUPKHSH))]
- "TARGET_ALTIVEC"
- "
-{
- emit_insn (gen_altivec_vupkhsh (operands[0], operands[1]));
- DONE;
-}")
-
-(define_expand "vec_unpacks_lo_v16qi"
- [(set (match_operand:V8HI 0 "register_operand" "=v")
- (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
- UNSPEC_VUPKLSB))]
- "TARGET_ALTIVEC"
- "
-{
- emit_insn (gen_altivec_vupklsb (operands[0], operands[1]));
- DONE;
-}")
+(define_expand "vec_unpacks_hi_<VP_small_lc>"
+ [(set (match_operand:VP 0 "register_operand" "=v")
+ (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
+ UNSPEC_VUNPACK_HI_SIGN))]
+ "<VI_unit>"
+ "")
-(define_expand "vec_unpacks_lo_v8hi"
- [(set (match_operand:V4SI 0 "register_operand" "=v")
- (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
- UNSPEC_VUPKLSH))]
- "TARGET_ALTIVEC"
- "
-{
- emit_insn (gen_altivec_vupklsh (operands[0], operands[1]));
- DONE;
-}")
+(define_expand "vec_unpacks_lo_<VP_small_lc>"
+ [(set (match_operand:VP 0 "register_operand" "=v")
+ (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
+ UNSPEC_VUNPACK_LO_SIGN))]
+ "<VI_unit>"
+ "")
(define_insn "vperm_v8hiv4si"
[(set (match_operand:V4SI 0 "register_operand" "=v")
@@ -2291,29 +2217,13 @@
DONE;
}")
-(define_expand "vec_pack_trunc_v8hi"
- [(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
- (match_operand:V8HI 2 "register_operand" "v")]
- UNSPEC_VPKUHUM))]
- "TARGET_ALTIVEC"
- "
-{
- emit_insn (gen_altivec_vpkuhum (operands[0], operands[1], operands[2]));
- DONE;
-}")
-
-(define_expand "vec_pack_trunc_v4si"
- [(set (match_operand:V8HI 0 "register_operand" "=v")
- (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
- (match_operand:V4SI 2 "register_operand" "v")]
- UNSPEC_VPKUWUM))]
- "TARGET_ALTIVEC"
- "
-{
- emit_insn (gen_altivec_vpkuwum (operands[0], operands[1], operands[2]));
- DONE;
-}")
+(define_expand "vec_pack_trunc_<mode>"
+ [(set (match_operand:<VP_small> 0 "register_operand" "=v")
+ (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
+ (match_operand:VP 2 "register_operand" "v")]
+ UNSPEC_VPACK_UNS_UNS_MOD))]
+ "<VI_unit>"
+ "")
(define_expand "altivec_negv4sf2"
[(use (match_operand:V4SF 0 "register_operand" ""))
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 078c9387350..7fdf7d1b6cb 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -1121,9 +1121,16 @@
GET_MODE (XEXP (op, 0))),
1"))))
+;; Return 1 if OP is a valid comparison operator for "cbranch" instructions.
+;; If we're assuming that FP operations cannot generate user-visible traps,
+;; then on e500 we can use the ordered-signaling instructions to implement
+;; the unordered-quiet FP comparison predicates modulo a reversal.
(define_predicate "rs6000_cbranch_operator"
(if_then_else (match_test "TARGET_HARD_FLOAT && !TARGET_FPRS")
- (match_operand 0 "ordered_comparison_operator")
+ (if_then_else (match_test "flag_trapping_math")
+ (match_operand 0 "ordered_comparison_operator")
+ (ior (match_operand 0 "ordered_comparison_operator")
+ (match_code ("unlt,unle,ungt,unge"))))
(match_operand 0 "comparison_operator")))
;; Return 1 if OP is a comparison operation that is valid for an SCC insn --
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index b41f53314c6..7a80eff8924 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -30,7 +30,7 @@
RS6000_BUILTIN_A -- ABS builtins
RS6000_BUILTIN_D -- DST builtins
RS6000_BUILTIN_E -- SPE EVSEL builtins.
- RS6000_BUILTIN_P -- Altivec, VSX, Power8 vector predicate builtins
+ RS6000_BUILTIN_P -- Altivec, VSX, ISA 2.07 vector predicate builtins
RS6000_BUILTIN_Q -- Paired floating point VSX predicate builtins
RS6000_BUILTIN_S -- SPE predicate builtins
RS6000_BUILTIN_X -- special builtins
@@ -301,7 +301,7 @@
| RS6000_BTC_SPECIAL), \
CODE_FOR_nothing) /* ICODE */
-/* Power8 vector convenience macros. */
+/* ISA 2.07 (power8) vector convenience macros. */
/* For the instructions that are encoded as altivec instructions use
__builtin_altivec_ as the builtin name. */
#define BU_P8V_AV_1(ENUM, NAME, ATTR, ICODE) \
@@ -1234,6 +1234,58 @@ BU_VSX_OVERLOAD_2 (XXSPLTW, "xxspltw")
BU_VSX_OVERLOAD_X (LD, "ld")
BU_VSX_OVERLOAD_X (ST, "st")
+/* 1 argument altivec instructions added in ISA 2.07. */
+BU_P8V_AV_1 (ABS_V2DI, "abs_v2di", CONST, absv2di2)
+BU_P8V_AV_1 (VUPKHSW, "vupkhsw", CONST, altivec_vupkhsw)
+BU_P8V_AV_1 (VUPKLSW, "vupklsw", CONST, altivec_vupklsw)
+
+/* 2 argument altivec instructions added in ISA 2.07. */
+BU_P8V_AV_2 (VADDUDM, "vaddudm", CONST, addv2di3)
+BU_P8V_AV_2 (VMINSD, "vminsd", CONST, sminv2di3)
+BU_P8V_AV_2 (VMAXSD, "vmaxsd", CONST, smaxv2di3)
+BU_P8V_AV_2 (VMINUD, "vminud", CONST, uminv2di3)
+BU_P8V_AV_2 (VMAXUD, "vmaxud", CONST, umaxv2di3)
+BU_P8V_AV_2 (VPKUDUM, "vpkudum", CONST, altivec_vpkudum)
+BU_P8V_AV_2 (VPKSDSS, "vpksdss", CONST, altivec_vpksdss)
+BU_P8V_AV_2 (VPKUDUS, "vpkudus", CONST, altivec_vpkudus)
+BU_P8V_AV_2 (VPKSDUS, "vpksdus", CONST, altivec_vpkswus)
+BU_P8V_AV_2 (VRLD, "vrld", CONST, vrotlv2di3)
+BU_P8V_AV_2 (VSLD, "vsld", CONST, vashlv2di3)
+BU_P8V_AV_2 (VSRD, "vsrd", CONST, vlshrv2di3)
+BU_P8V_AV_2 (VSRAD, "vsrad", CONST, vashrv2di3)
+BU_P8V_AV_2 (VSUBUDM, "vsubudm", CONST, subv2di3)
+
+/* Vector comparison instructions added in ISA 2.07. */
+BU_P8V_AV_2 (VCMPEQUD, "vcmpequd", CONST, vector_eqv2di)
+BU_P8V_AV_2 (VCMPGTSD, "vcmpgtsd", CONST, vector_gtv2di)
+BU_P8V_AV_2 (VCMPGTUD, "vcmpgtud", CONST, vector_gtuv2di)
+
+/* Vector comparison predicate instructions added in ISA 2.07. */
+BU_P8V_AV_P (VCMPEQUD_P, "vcmpequd_p", CONST, vector_eq_v2di_p)
+BU_P8V_AV_P (VCMPGTSD_P, "vcmpgtsd_p", CONST, vector_gt_v2di_p)
+BU_P8V_AV_P (VCMPGTUD_P, "vcmpgtud_p", CONST, vector_gtu_v2di_p)
+
+/* ISA 2.07 vector overloaded 1 argument functions. */
+BU_P8V_OVERLOAD_1 (VUPKHSW, "vupkhsw")
+BU_P8V_OVERLOAD_1 (VUPKLSW, "vupklsw")
+
+/* ISA 2.07 vector overloaded 2 argument functions. */
+BU_P8V_OVERLOAD_2 (VADDUDM, "vaddudm")
+BU_P8V_OVERLOAD_2 (VMAXSD, "vmaxsd")
+BU_P8V_OVERLOAD_2 (VMAXUD, "vmaxud")
+BU_P8V_OVERLOAD_2 (VMINSD, "vminsd")
+BU_P8V_OVERLOAD_2 (VMINUD, "vminud")
+BU_P8V_OVERLOAD_2 (VPKSDSS, "vpksdss")
+BU_P8V_OVERLOAD_2 (VPKSDUS, "vpksdus")
+BU_P8V_OVERLOAD_2 (VPKUDUM, "vpkudum")
+BU_P8V_OVERLOAD_2 (VPKUDUS, "vpkudus")
+BU_P8V_OVERLOAD_2 (VRLD, "vrld")
+BU_P8V_OVERLOAD_2 (VSLD, "vsld")
+BU_P8V_OVERLOAD_2 (VSRAD, "vsrad")
+BU_P8V_OVERLOAD_2 (VSRD, "vsrd")
+BU_P8V_OVERLOAD_2 (VSUBUDM, "vsubudm")
+
+
/* 1 argument crypto functions. */
BU_CRYPTO_1 (VSBOX, "vsbox", CONST, crypto_vsbox)
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index c6c584d8183..50ff8d39eee 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -511,6 +511,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V4SI,
RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 },
+ { ALTIVEC_BUILTIN_VEC_ABS, P8V_BUILTIN_ABS_V2DI,
+ RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V4SF,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_ABS, VSX_BUILTIN_XVABSDP,
@@ -583,12 +585,24 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V8HI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHSH,
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V8HI, 0, 0 },
+ { ALTIVEC_BUILTIN_VEC_UNPACKH, P8V_BUILTIN_VUPKHSW,
+ RS6000_BTI_V2DI, RS6000_BTI_V4SI, 0, 0 },
+ { ALTIVEC_BUILTIN_VEC_UNPACKH, P8V_BUILTIN_VUPKHSW,
+ RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V4SI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHPX,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_pixel_V8HI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_VUPKHSH, ALTIVEC_BUILTIN_VUPKHSH,
RS6000_BTI_V4SI, RS6000_BTI_V8HI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_VUPKHSH, ALTIVEC_BUILTIN_VUPKHSH,
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V8HI, 0, 0 },
+ { ALTIVEC_BUILTIN_VEC_UNPACKH, P8V_BUILTIN_VUPKHSW,
+ RS6000_BTI_V2DI, RS6000_BTI_V4SI, 0, 0 },
+ { ALTIVEC_BUILTIN_VEC_UNPACKH, P8V_BUILTIN_VUPKHSW,
+ RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V4SI, 0, 0 },
+ { ALTIVEC_BUILTIN_VEC_VUPKHSH, P8V_BUILTIN_VUPKHSW,
+ RS6000_BTI_V2DI, RS6000_BTI_V4SI, 0, 0 },
+ { ALTIVEC_BUILTIN_VEC_VUPKHSH, P8V_BUILTIN_VUPKHSW,
+ RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V4SI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_VUPKHPX, ALTIVEC_BUILTIN_VUPKHPX,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_VUPKHPX, ALTIVEC_BUILTIN_VUPKHPX,
@@ -607,6 +621,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V8HI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_UNPACKL, ALTIVEC_BUILTIN_VUPKLSH,
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V8HI, 0, 0 },
+ { ALTIVEC_BUILTIN_VEC_UNPACKL, P8V_BUILTIN_VUPKLSW,
+ RS6000_BTI_V2DI, RS6000_BTI_V4SI, 0, 0 },
+ { ALTIVEC_BUILTIN_VEC_UNPACKL, P8V_BUILTIN_VUPKLSW,
+ RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V4SI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_VUPKLPX, ALTIVEC_BUILTIN_VUPKLPX,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_VUPKLPX, ALTIVEC_BUILTIN_VUPKLPX,
@@ -657,6 +675,18 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUWM,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
+ { ALTIVEC_BUILTIN_VEC_ADD, P8V_BUILTIN_VADDUDM,
+ RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_ADD, P8V_BUILTIN_VADDUDM,
+ RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_ADD, P8V_BUILTIN_VADDUDM,
+ RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_ADD, P8V_BUILTIN_VADDUDM,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_ADD, P8V_BUILTIN_VADDUDM,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_ADD, P8V_BUILTIN_VADDUDM,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_ADD, VSX_BUILTIN_XVADDDP,
@@ -943,6 +973,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUW,
RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
+ { ALTIVEC_BUILTIN_VEC_CMPEQ, P8V_BUILTIN_VCMPEQUD,
+ RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_CMPEQ, P8V_BUILTIN_VCMPEQUD,
+ RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQFP,
RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPEQ, VSX_BUILTIN_XVCMPEQDP,
@@ -981,6 +1015,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTSW,
RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
+ { ALTIVEC_BUILTIN_VEC_CMPGT, P8V_BUILTIN_VCMPGTUD,
+ RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_CMPGT, P8V_BUILTIN_VCMPGTSD,
+ RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTFP,
RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPGT, VSX_BUILTIN_XVCMPGTDP,
@@ -1027,6 +1065,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTSW,
RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
+ { ALTIVEC_BUILTIN_VEC_CMPLT, P8V_BUILTIN_VCMPGTUD,
+ RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_CMPLT, P8V_BUILTIN_VCMPGTSD,
+ RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTFP,
RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPLT, VSX_BUILTIN_XVCMPGTDP,
@@ -1424,6 +1466,18 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSW,
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
+ { ALTIVEC_BUILTIN_VEC_MAX, P8V_BUILTIN_VMAXUD,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_MAX, P8V_BUILTIN_VMAXUD,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_MAX, P8V_BUILTIN_VMAXUD,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_MAX, P8V_BUILTIN_VMAXSD,
+ RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_MAX, P8V_BUILTIN_VMAXSD,
+ RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_MAX, P8V_BUILTIN_VMAXSD,
+ RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_MAX, VSX_BUILTIN_XVMAXDP,
@@ -1610,6 +1664,18 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSW,
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
+ { ALTIVEC_BUILTIN_VEC_MIN, P8V_BUILTIN_VMINUD,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_MIN, P8V_BUILTIN_VMINUD,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_MIN, P8V_BUILTIN_VMINUD,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_MIN, P8V_BUILTIN_VMINSD,
+ RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_MIN, P8V_BUILTIN_VMINSD,
+ RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_MIN, P8V_BUILTIN_VMINSD,
+ RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_MIN, VSX_BUILTIN_XVMINDP,
@@ -1792,6 +1858,12 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_PACK, ALTIVEC_BUILTIN_VPKUWUM,
RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 },
+ { ALTIVEC_BUILTIN_VEC_PACK, P8V_BUILTIN_VPKUDUM,
+ RS6000_BTI_V4SI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_PACK, P8V_BUILTIN_VPKUDUM,
+ RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_PACK, P8V_BUILTIN_VPKUDUM,
+ RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_VPKUWUM, ALTIVEC_BUILTIN_VPKUWUM,
RS6000_BTI_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_VPKUWUM, ALTIVEC_BUILTIN_VPKUWUM,
@@ -1818,6 +1890,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_VPKUWUS, ALTIVEC_BUILTIN_VPKUWUS,
RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
+ { ALTIVEC_BUILTIN_VEC_PACKS, P8V_BUILTIN_VPKUDUS,
+ RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_PACKS, P8V_BUILTIN_VPKSDSS,
+ RS6000_BTI_V4SI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_VPKSHSS, ALTIVEC_BUILTIN_VPKSHSS,
RS6000_BTI_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 },
{ ALTIVEC_BUILTIN_VEC_VPKUHUS, ALTIVEC_BUILTIN_VPKUHUS,
@@ -1830,6 +1906,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_PACKSU, ALTIVEC_BUILTIN_VPKSWUS,
RS6000_BTI_unsigned_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
+ { ALTIVEC_BUILTIN_VEC_PACKSU, P8V_BUILTIN_VPKSDUS,
+ RS6000_BTI_unsigned_V4SI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_VPKSWUS, ALTIVEC_BUILTIN_VPKSWUS,
RS6000_BTI_unsigned_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_VPKSHUS, ALTIVEC_BUILTIN_VPKSHUS,
@@ -1850,6 +1928,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLW,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
+ { ALTIVEC_BUILTIN_VEC_RL, P8V_BUILTIN_VRLD,
+ RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_RL, P8V_BUILTIN_VRLD,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_VRLW, ALTIVEC_BUILTIN_VRLW,
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_VRLW, ALTIVEC_BUILTIN_VRLW,
@@ -1874,6 +1956,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLW,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
+ { ALTIVEC_BUILTIN_VEC_SL, P8V_BUILTIN_VSLD,
+ RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_SL, P8V_BUILTIN_VSLD,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_SQRT, VSX_BUILTIN_XVSQRTDP,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_SQRT, VSX_BUILTIN_XVSQRTSP,
@@ -2038,6 +2124,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_SR, ALTIVEC_BUILTIN_VSRW,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
+ { ALTIVEC_BUILTIN_VEC_SR, P8V_BUILTIN_VSRD,
+ RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_SR, P8V_BUILTIN_VSRD,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_VSRW, ALTIVEC_BUILTIN_VSRW,
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_VSRW, ALTIVEC_BUILTIN_VSRW,
@@ -2062,6 +2152,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_SRA, ALTIVEC_BUILTIN_VSRAW,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
+ { ALTIVEC_BUILTIN_VEC_SRA, P8V_BUILTIN_VSRAD,
+ RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_SRA, P8V_BUILTIN_VSRD,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_VSRAW, ALTIVEC_BUILTIN_VSRAW,
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_VSRAW, ALTIVEC_BUILTIN_VSRAW,
@@ -2202,6 +2296,18 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUWM,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
+ { ALTIVEC_BUILTIN_VEC_SUB, P8V_BUILTIN_VSUBUDM,
+ RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_SUB, P8V_BUILTIN_VSUBUDM,
+ RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_SUB, P8V_BUILTIN_VSUBUDM,
+ RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_SUB, P8V_BUILTIN_VSUBUDM,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_SUB, P8V_BUILTIN_VSUBUDM,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 },
+ { ALTIVEC_BUILTIN_VEC_SUB, P8V_BUILTIN_VSUBUDM,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_SUB, VSX_BUILTIN_XVSUBDP,
@@ -3333,6 +3439,20 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI },
{ ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUW_P,
RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI },
+ { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, P8V_BUILTIN_VCMPEQUD_P,
+ RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI },
+ { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, P8V_BUILTIN_VCMPEQUD_P,
+ RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI },
+ { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, P8V_BUILTIN_VCMPEQUD_P,
+ RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI },
+ { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, P8V_BUILTIN_VCMPEQUD_P,
+ RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI },
+ { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, P8V_BUILTIN_VCMPEQUD_P,
+ RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI },
+ { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, P8V_BUILTIN_VCMPEQUD_P,
+ RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DI, RS6000_BTI_V2DI },
+ { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, P8V_BUILTIN_VCMPEQUD_P,
+ RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI },
{ ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQFP_P,
RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF },
{ ALTIVEC_BUILTIN_VEC_VCMPEQ_P, VSX_BUILTIN_XVCMPEQDP_P,
@@ -3378,6 +3498,18 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI },
{ ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSW_P,
RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI },
+ { ALTIVEC_BUILTIN_VEC_VCMPGE_P, P8V_BUILTIN_VCMPGTUD_P,
+ RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI },
+ { ALTIVEC_BUILTIN_VEC_VCMPGE_P, P8V_BUILTIN_VCMPGTUD_P,
+ RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI },
+ { ALTIVEC_BUILTIN_VEC_VCMPGE_P, P8V_BUILTIN_VCMPGTUD_P,
+ RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI },
+ { ALTIVEC_BUILTIN_VEC_VCMPGE_P, P8V_BUILTIN_VCMPGTSD_P,
+ RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI },
+ { ALTIVEC_BUILTIN_VEC_VCMPGE_P, P8V_BUILTIN_VCMPGTSD_P,
+ RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI },
+ { ALTIVEC_BUILTIN_VEC_VCMPGE_P, P8V_BUILTIN_VCMPGTSD_P,
+ RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DI, RS6000_BTI_V2DI },
{ ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGEFP_P,
RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF },
{ ALTIVEC_BUILTIN_VEC_VCMPGE_P, VSX_BUILTIN_XVCMPGEDP_P,
@@ -3690,11 +3822,20 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
TREE_USED (decl) = 1;
TREE_TYPE (decl) = arg1_type;
TREE_READONLY (decl) = TYPE_READONLY (arg1_type);
- DECL_INITIAL (decl) = arg1;
- stmt = build1 (DECL_EXPR, arg1_type, decl);
- TREE_ADDRESSABLE (decl) = 1;
- SET_EXPR_LOCATION (stmt, loc);
- stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt);
+ if (c_dialect_cxx ())
+ {
+ stmt = build4 (TARGET_EXPR, arg1_type, decl, arg1,
+ NULL_TREE, NULL_TREE);
+ SET_EXPR_LOCATION (stmt, loc);
+ }
+ else
+ {
+ DECL_INITIAL (decl) = arg1;
+ stmt = build1 (DECL_EXPR, arg1_type, decl);
+ TREE_ADDRESSABLE (decl) = 1;
+ SET_EXPR_LOCATION (stmt, loc);
+ stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt);
+ }
innerptrtype = build_pointer_type (arg1_inner_type);
@@ -3769,11 +3910,20 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
TREE_USED (decl) = 1;
TREE_TYPE (decl) = arg1_type;
TREE_READONLY (decl) = TYPE_READONLY (arg1_type);
- DECL_INITIAL (decl) = arg1;
- stmt = build1 (DECL_EXPR, arg1_type, decl);
- TREE_ADDRESSABLE (decl) = 1;
- SET_EXPR_LOCATION (stmt, loc);
- stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt);
+ if (c_dialect_cxx ())
+ {
+ stmt = build4 (TARGET_EXPR, arg1_type, decl, arg1,
+ NULL_TREE, NULL_TREE);
+ SET_EXPR_LOCATION (stmt, loc);
+ }
+ else
+ {
+ DECL_INITIAL (decl) = arg1;
+ stmt = build1 (DECL_EXPR, arg1_type, decl);
+ TREE_ADDRESSABLE (decl) = 1;
+ SET_EXPR_LOCATION (stmt, loc);
+ stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt);
+ }
innerptrtype = build_pointer_type (arg1_inner_type);
diff --git a/gcc/config/rs6000/rs6000-opts.h b/gcc/config/rs6000/rs6000-opts.h
index e143a4ca203..d528a4fd87a 100644
--- a/gcc/config/rs6000/rs6000-opts.h
+++ b/gcc/config/rs6000/rs6000-opts.h
@@ -30,21 +30,22 @@
/* Processor type. Order must match cpu attribute in MD file. */
enum processor_type
{
- PROCESSOR_RS64A,
- PROCESSOR_MPCCORE,
- PROCESSOR_PPC403,
- PROCESSOR_PPC405,
- PROCESSOR_PPC440,
- PROCESSOR_PPC476,
PROCESSOR_PPC601,
PROCESSOR_PPC603,
PROCESSOR_PPC604,
PROCESSOR_PPC604e,
PROCESSOR_PPC620,
PROCESSOR_PPC630,
+
PROCESSOR_PPC750,
PROCESSOR_PPC7400,
PROCESSOR_PPC7450,
+
+ PROCESSOR_PPC403,
+ PROCESSOR_PPC405,
+ PROCESSOR_PPC440,
+ PROCESSOR_PPC476,
+
PROCESSOR_PPC8540,
PROCESSOR_PPC8548,
PROCESSOR_PPCE300C2,
@@ -53,16 +54,21 @@ enum processor_type
PROCESSOR_PPCE500MC64,
PROCESSOR_PPCE5500,
PROCESSOR_PPCE6500,
+
PROCESSOR_POWER4,
PROCESSOR_POWER5,
PROCESSOR_POWER6,
PROCESSOR_POWER7,
+ PROCESSOR_POWER8,
+
+ PROCESSOR_RS64A,
+ PROCESSOR_MPCCORE,
PROCESSOR_CELL,
PROCESSOR_PPCA2,
- PROCESSOR_TITAN,
- PROCESSOR_POWER8
+ PROCESSOR_TITAN
};
+
/* FP processor type. */
enum fpu_type_t
{
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 7963bf4d5c2..d7fae3d8d1d 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -2226,12 +2226,13 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
}
}
- /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
- Altivec doesn't have 64-bit support. */
+ /* V2DImode, full mode depends on ISA 2.07 vector mode. Allow under VSX to
+ do insert/splat/extract. Altivec doesn't have 64-bit integer support. */
if (TARGET_VSX)
{
rs6000_vector_mem[V2DImode] = VECTOR_VSX;
- rs6000_vector_unit[V2DImode] = VECTOR_NONE;
+ rs6000_vector_unit[V2DImode]
+ = (TARGET_P8_VECTOR) ? VECTOR_P8_VECTOR : VECTOR_NONE;
rs6000_vector_align[V2DImode] = align64;
}
@@ -15676,7 +15677,7 @@ print_operand (FILE *file, rtx x, int code)
/* Mark the decl as referenced so that cgraph will output the
function. */
if (SYMBOL_REF_DECL (x))
- mark_decl_referenced (SYMBOL_REF_DECL (x));
+ DECL_PRESERVE_P (SYMBOL_REF_DECL (x)) = 1;
/* For macho, check to see if we need a stub. */
if (TARGET_MACHO)
@@ -16086,16 +16087,41 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
{
rtx cmp, or_result, compare_result2;
enum machine_mode op_mode = GET_MODE (op0);
+ bool reverse_p;
if (op_mode == VOIDmode)
op_mode = GET_MODE (op1);
+ /* First reverse the condition codes that aren't directly supported. */
+ switch (code)
+ {
+ case NE:
+ case UNLT:
+ case UNLE:
+ case UNGT:
+ case UNGE:
+ code = reverse_condition_maybe_unordered (code);
+ reverse_p = true;
+ break;
+
+ case EQ:
+ case LT:
+ case LE:
+ case GT:
+ case GE:
+ reverse_p = false;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
/* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
This explains the following mess. */
switch (code)
{
- case EQ: case UNEQ: case NE: case LTGT:
+ case EQ:
switch (op_mode)
{
case SFmode:
@@ -16121,7 +16147,8 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
}
break;
- case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
+ case GT:
+ case GE:
switch (op_mode)
{
case SFmode:
@@ -16147,7 +16174,8 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
}
break;
- case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
+ case LT:
+ case LE:
switch (op_mode)
{
case SFmode:
@@ -16172,24 +16200,16 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
gcc_unreachable ();
}
break;
+
default:
gcc_unreachable ();
}
/* Synthesize LE and GE from LT/GT || EQ. */
- if (code == LE || code == GE || code == LEU || code == GEU)
+ if (code == LE || code == GE)
{
emit_insn (cmp);
- switch (code)
- {
- case LE: code = LT; break;
- case GE: code = GT; break;
- case LEU: code = LT; break;
- case GEU: code = GT; break;
- default: gcc_unreachable ();
- }
-
compare_result2 = gen_reg_rtx (CCFPmode);
/* Do the EQ. */
@@ -16216,23 +16236,18 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
default:
gcc_unreachable ();
}
+
emit_insn (cmp);
/* OR them together. */
or_result = gen_reg_rtx (CCFPmode);
cmp = gen_e500_cr_ior_compare (or_result, compare_result,
- compare_result2);
+ compare_result2);
compare_result = or_result;
- code = EQ;
- }
- else
- {
- if (code == NE || code == LTGT)
- code = NE;
- else
- code = EQ;
}
+ code = reverse_p ? NE : EQ;
+
emit_insn (cmp);
}
else
@@ -22559,7 +22574,10 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
fputs (DOUBLE_INT_ASM_OP, file);
else
fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
- fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
+ if (WORDS_BIG_ENDIAN)
+ fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
+ else
+ fprintf (file, "0x%lx\n", l & 0xffffffff);
return;
}
else
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 013a0e38551..6be05a4f0f7 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -166,9 +166,14 @@
(const_int 4)))
;; Processor type -- this attribute must exactly match the processor_type
-;; enumeration in rs6000.h.
-
-(define_attr "cpu" "rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,power4,power5,power6,power7,cell,ppca2,titan,power8"
+;; enumeration in rs6000-opts.h.
+(define_attr "cpu"
+ "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
+ ppc750,ppc7400,ppc7450,
+ ppc403,ppc405,ppc440,ppc476,
+ ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
+ power4,power5,power6,power7,power8,
+ rs64a,mpccore,cell,ppca2,titan"
(const (symbol_ref "rs6000_cpu_attr")))
diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md
index c1d00ca2a9b..8b8b3427454 100644
--- a/gcc/config/rs6000/vector.md
+++ b/gcc/config/rs6000/vector.md
@@ -24,13 +24,13 @@
;; Vector int modes
-(define_mode_iterator VEC_I [V16QI V8HI V4SI])
+(define_mode_iterator VEC_I [V16QI V8HI V4SI V2DI])
;; Vector float modes
(define_mode_iterator VEC_F [V4SF V2DF])
;; Vector arithmetic modes
-(define_mode_iterator VEC_A [V16QI V8HI V4SI V4SF V2DF])
+(define_mode_iterator VEC_A [V16QI V8HI V4SI V2DI V4SF V2DF])
;; Vector modes that need alginment via permutes
(define_mode_iterator VEC_K [V16QI V8HI V4SI V4SF])
@@ -45,7 +45,7 @@
(define_mode_iterator VEC_N [V4SI V4SF V2DI V2DF])
;; Vector comparison modes
-(define_mode_iterator VEC_C [V16QI V8HI V4SI V4SF V2DF])
+(define_mode_iterator VEC_C [V16QI V8HI V4SI V2DI V4SF V2DF])
;; Vector init/extract modes
(define_mode_iterator VEC_E [V16QI V8HI V4SI V2DI V4SF V2DF])
@@ -1074,7 +1074,7 @@
[(set (match_operand:VEC_I 0 "vint_operand" "")
(rotate:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
(match_operand:VEC_I 2 "vint_operand" "")))]
- "TARGET_ALTIVEC"
+ "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"")
;; Expanders for arithmetic shift left on each vector element
@@ -1082,7 +1082,7 @@
[(set (match_operand:VEC_I 0 "vint_operand" "")
(ashift:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
(match_operand:VEC_I 2 "vint_operand" "")))]
- "TARGET_ALTIVEC"
+ "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"")
;; Expanders for logical shift right on each vector element
@@ -1090,7 +1090,7 @@
[(set (match_operand:VEC_I 0 "vint_operand" "")
(lshiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
(match_operand:VEC_I 2 "vint_operand" "")))]
- "TARGET_ALTIVEC"
+ "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"")
;; Expanders for arithmetic shift right on each vector element
@@ -1098,7 +1098,7 @@
[(set (match_operand:VEC_I 0 "vint_operand" "")
(ashiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
(match_operand:VEC_I 2 "vint_operand" "")))]
- "TARGET_ALTIVEC"
+ "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"")
;; Vector reduction expanders for VSX
diff --git a/gcc/config/rx/rx-opts.h b/gcc/config/rx/rx-opts.h
index f00de76a901..4d5455e8d8d 100644
--- a/gcc/config/rx/rx-opts.h
+++ b/gcc/config/rx/rx-opts.h
@@ -24,7 +24,8 @@ enum rx_cpu_types
{
RX600,
RX610,
- RX200
+ RX200,
+ RX100
};
#endif
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index 15d5359ea1d..d781bb73d28 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -975,6 +975,8 @@ rx_gen_move_template (rtx * operands, bool is_movu)
loading an immediate into a register. */
extension = ".W";
break;
+ case DFmode:
+ case DImode:
case SFmode:
case SImode:
extension = ".L";
@@ -988,19 +990,44 @@ rx_gen_move_template (rtx * operands, bool is_movu)
}
if (MEM_P (src) && rx_pid_data_operand (XEXP (src, 0)) == PID_UNENCODED)
- src_template = "(%A1-__pid_base)[%P1]";
+ {
+ gcc_assert (GET_MODE (src) != DImode);
+ gcc_assert (GET_MODE (src) != DFmode);
+
+ src_template = "(%A1 - __pid_base)[%P1]";
+ }
else if (MEM_P (src) && rx_small_data_operand (XEXP (src, 0)))
- src_template = "%%gp(%A1)[%G1]";
+ {
+ gcc_assert (GET_MODE (src) != DImode);
+ gcc_assert (GET_MODE (src) != DFmode);
+
+ src_template = "%%gp(%A1)[%G1]";
+ }
else
src_template = "%1";
if (MEM_P (dest) && rx_small_data_operand (XEXP (dest, 0)))
- dst_template = "%%gp(%A0)[%G0]";
+ {
+ gcc_assert (GET_MODE (dest) != DImode);
+ gcc_assert (GET_MODE (dest) != DFmode);
+
+ dst_template = "%%gp(%A0)[%G0]";
+ }
else
dst_template = "%0";
- sprintf (out_template, "%s%s\t%s, %s", is_movu ? "movu" : "mov",
- extension, src_template, dst_template);
+ if (GET_MODE (dest) == DImode || GET_MODE (dest) == DFmode)
+ {
+ gcc_assert (! is_movu);
+
+ if (REG_P (src) && REG_P (dest) && (REGNO (dest) == REGNO (src) + 1))
+ sprintf (out_template, "mov.L\t%H1, %H0 | mov.L\t%1, %0");
+ else
+ sprintf (out_template, "mov.L\t%1, %0 | mov.L\t%H1, %H0");
+ }
+ else
+ sprintf (out_template, "%s%s\t%s, %s", is_movu ? "movu" : "mov",
+ extension, src_template, dst_template);
return out_template;
}
@@ -3240,6 +3267,12 @@ rx_ok_to_inline (tree caller, tree callee)
|| lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (callee)) != NULL_TREE;
}
+static bool
+rx_enable_lra (void)
+{
+ return TARGET_ENABLE_LRA || 1;
+}
+
#undef TARGET_NARROW_VOLATILE_BITFIELD
#define TARGET_NARROW_VOLATILE_BITFIELD rx_narrow_volatile_bitfield
@@ -3391,6 +3424,9 @@ rx_ok_to_inline (tree caller, tree callee)
#undef TARGET_WARN_FUNC_RETURN
#define TARGET_WARN_FUNC_RETURN rx_warn_func_return
+#undef TARGET_LRA_P
+#define TARGET_LRA_P rx_enable_lra
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-rx.h"
diff --git a/gcc/config/rx/rx.h b/gcc/config/rx/rx.h
index 092fd7659a2..72aee2fe214 100644
--- a/gcc/config/rx/rx.h
+++ b/gcc/config/rx/rx.h
@@ -29,9 +29,22 @@
builtin_define ("__RX610__"); \
builtin_assert ("machine=RX610"); \
} \
- else \
- builtin_assert ("machine=RX600"); \
- \
+ else if (rx_cpu_type == RX100) \
+ { \
+ builtin_define ("__RX100__"); \
+ builtin_assert ("machine=RX100"); \
+ } \
+ else if (rx_cpu_type == RX200) \
+ { \
+ builtin_define ("__RX200__"); \
+ builtin_assert ("machine=RX200"); \
+ } \
+ else if (rx_cpu_type == RX600) \
+ { \
+ builtin_define ("__RX600__"); \
+ builtin_assert ("machine=RX600"); \
+ } \
+ \
if (TARGET_BIG_ENDIAN_DATA) \
builtin_define ("__RX_BIG_ENDIAN__"); \
else \
@@ -60,6 +73,7 @@
#undef CC1_SPEC
#define CC1_SPEC "\
%{mas100-syntax:%{gdwarf*:%e-mas100-syntax is incompatible with -gdwarf}} \
+ %{mcpu=rx100:%{fpu:%erx100 cpu does not have FPU hardware}} \
%{mcpu=rx200:%{fpu:%erx200 cpu does not have FPU hardware}}"
#undef STARTFILE_SPEC
diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md
index 3a95567a43f..692b7d220a3 100644
--- a/gcc/config/rx/rx.md
+++ b/gcc/config/rx/rx.md
@@ -30,7 +30,7 @@
;; then all operations on doubles have to be handled by
;; library functions.
(define_mode_iterator register_modes
- [(SF "ALLOW_RX_FPU_INSNS") (SI "") (HI "") (QI "")])
+ [(SF "") (SI "") (HI "") (QI "")])
(define_constants
[
@@ -2621,3 +2621,21 @@
""
""
)
+
+(define_insn "movdi"
+ [(set:DI (match_operand:DI 0 "nonimmediate_operand" "=rm")
+ (match_operand:DI 1 "general_operand" "rmi"))]
+ "TARGET_ENABLE_LRA || 1"
+ { return rx_gen_move_template (operands, false); }
+ [(set_attr "length" "16")
+ (set_attr "timings" "22")]
+)
+
+(define_insn "movdf"
+ [(set:DF (match_operand:DF 0 "nonimmediate_operand" "=rm")
+ (match_operand:DF 1 "general_operand" "rmi"))]
+ "TARGET_ENABLE_LRA || 1"
+ { return rx_gen_move_template (operands, false); }
+ [(set_attr "length" "16")
+ (set_attr "timings" "22")]
+)
diff --git a/gcc/config/rx/rx.opt b/gcc/config/rx/rx.opt
index 09d93c3e5f1..12312cfef6b 100644
--- a/gcc/config/rx/rx.opt
+++ b/gcc/config/rx/rx.opt
@@ -61,6 +61,9 @@ Enum(rx_cpu_types) String(rx200) Value(RX200)
EnumValue
Enum(rx_cpu_types) String(rx600) Value(RX600)
+EnumValue
+Enum(rx_cpu_types) String(rx100) Value(RX100)
+
;---------------------------------------------------
mbig-endian-data
@@ -132,3 +135,7 @@ Enable the use of the old, broken, ABI where all stacked function arguments are
mrx-abi
Target RejectNegative Report InverseMask(GCC_ABI)
Enable the use the standard RX ABI where all stacked function arguments are naturally aligned. This is the default.
+
+mlra
+Target Report Mask(ENABLE_LRA)
+Enable the use of the LRA register allocator.
diff --git a/gcc/config/rx/t-rx b/gcc/config/rx/t-rx
index 97079859240..41a3d3a98dc 100644
--- a/gcc/config/rx/t-rx
+++ b/gcc/config/rx/t-rx
@@ -28,7 +28,7 @@ MULTILIB_DIRNAMES = 64-bit-double no-fpu-libs big-endian-data pid
# MULTILIB_OPTIONS += mgcc-abi
# MULTILIB_DIRNAMES += gcc-abi
-MULTILIB_MATCHES = nofpu=mnofpu nofpu=mcpu?rx200
+MULTILIB_MATCHES = nofpu=mnofpu nofpu=mcpu?rx200 nofpu=mcpu?rx100
MULTILIB_EXCEPTIONS =
MULTILIB_EXTRA_OPTS =
diff --git a/gcc/config/sol2.c b/gcc/config/sol2.c
index 718134e2b90..7c7c429db3d 100644
--- a/gcc/config/sol2.c
+++ b/gcc/config/sol2.c
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h"
#include "diagnostic-core.h"
#include "ggc.h"
-#include "hashtab.h"
+#include "hash-table.h"
tree solaris_pending_aligns, solaris_pending_inits, solaris_pending_finis;
@@ -157,10 +157,6 @@ solaris_assemble_visibility (tree decl, int vis ATTRIBUTE_UNUSED)
#endif
}
-/* Hash table of group signature symbols. */
-
-static htab_t solaris_comdat_htab;
-
/* Group section information entry stored in solaris_comdat_htab. */
typedef struct comdat_entry
@@ -171,25 +167,34 @@ typedef struct comdat_entry
const char *sig;
} comdat_entry;
-/* Helper routines for maintaining solaris_comdat_htab. */
+/* Helpers for maintaining solaris_comdat_htab. */
-static hashval_t
-comdat_hash (const void *p)
+struct comdat_entry_hasher : typed_noop_remove <comdat_entry>
+{
+ typedef comdat_entry value_type;
+ typedef comdat_entry compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+
+inline hashval_t
+comdat_entry_hasher::hash (const value_type *entry)
{
- const comdat_entry *entry = (const comdat_entry *) p;
-
return htab_hash_string (entry->sig);
}
-static int
-comdat_eq (const void *p1, const void *p2)
+inline bool
+comdat_entry_hasher::equal (const value_type *entry1,
+ const compare_type *entry2)
{
- const comdat_entry *entry1 = (const comdat_entry *) p1;
- const comdat_entry *entry2 = (const comdat_entry *) p2;
-
return strcmp (entry1->sig, entry2->sig) == 0;
}
+/* Hash table of group signature symbols. */
+
+static hash_table <comdat_entry_hasher> solaris_comdat_htab;
+
/* Output assembly to switch to COMDAT group section NAME with attributes
FLAGS and group signature symbol DECL, using Sun as syntax. */
@@ -229,12 +234,11 @@ solaris_elf_asm_comdat_section (const char *name, unsigned int flags, tree decl)
identify the missing ones without changing the affected frontents,
remember the signature symbols and emit those not marked
TREE_SYMBOL_REFERENCED in solaris_file_end. */
- if (solaris_comdat_htab == NULL)
- solaris_comdat_htab = htab_create_alloc (37, comdat_hash, comdat_eq, NULL,
- xcalloc, free);
+ if (!solaris_comdat_htab.is_created ())
+ solaris_comdat_htab.create (37);
entry.sig = signature;
- slot = (comdat_entry **) htab_find_slot (solaris_comdat_htab, &entry, INSERT);
+ slot = solaris_comdat_htab.find_slot (&entry, INSERT);
if (*slot == NULL)
{
@@ -250,10 +254,11 @@ solaris_elf_asm_comdat_section (const char *name, unsigned int flags, tree decl)
/* Define unreferenced COMDAT group signature symbol corresponding to SLOT. */
-static int
-solaris_define_comdat_signature (void **slot, void *aux ATTRIBUTE_UNUSED)
+int
+solaris_define_comdat_signature (comdat_entry **slot,
+ void *aux ATTRIBUTE_UNUSED)
{
- comdat_entry *entry = *(comdat_entry **) slot;
+ comdat_entry *entry = *slot;
tree decl = entry->decl;
if (TREE_CODE (decl) != IDENTIFIER_NODE)
@@ -277,10 +282,10 @@ solaris_define_comdat_signature (void **slot, void *aux ATTRIBUTE_UNUSED)
void
solaris_file_end (void)
{
- if (solaris_comdat_htab == NULL)
+ if (!solaris_comdat_htab.is_created ())
return;
- htab_traverse (solaris_comdat_htab, solaris_define_comdat_signature, NULL);
+ solaris_comdat_htab.traverse <void *, solaris_define_comdat_signature> (NULL);
}
void
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 1dc4e3600a8..d473d6fdd7f 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -11527,7 +11527,7 @@ sparc_expand_vec_perm_bmask (enum machine_mode vmode, rtx sel)
}
/* Always perform the final addition/merge within the bmask insn. */
- emit_insn (gen_bmasksi_vis (gen_reg_rtx (SImode), sel, t_1));
+ emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, t_1));
}
/* Implement TARGET_FRAME_POINTER_REQUIRED. */
@@ -11766,7 +11766,7 @@ static void
vector_init_bshuffle (rtx target, rtx elt, enum machine_mode mode,
enum machine_mode inner_mode)
{
- rtx t1, final_insn;
+ rtx t1, final_insn, sel;
int bmask;
t1 = gen_reg_rtx (mode);
@@ -11792,8 +11792,8 @@ vector_init_bshuffle (rtx target, rtx elt, enum machine_mode mode,
gcc_unreachable ();
}
- emit_insn (gen_bmasksi_vis (gen_reg_rtx (SImode), CONST0_RTX (SImode),
- force_reg (SImode, GEN_INT (bmask))));
+ sel = force_reg (SImode, GEN_INT (bmask));
+ emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, const0_rtx));
emit_insn (final_insn);
}
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 292cb205271..7f8d4250502 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -5499,7 +5499,7 @@
[(set (match_operand:DF 0 "register_operand" "=e")
(mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
(float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
- "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
+ "(TARGET_V8 || TARGET_V9) && TARGET_FPU && !sparc_fix_ut699"
"fsmuld\t%1, %2, %0"
[(set_attr "type" "fpmul")
(set_attr "fptype" "double")])
@@ -5528,20 +5528,37 @@
"fdivq\t%1, %2, %0"
[(set_attr "type" "fpdivd")])
-(define_insn "divdf3"
+(define_expand "divdf3"
[(set (match_operand:DF 0 "register_operand" "=e")
(div:DF (match_operand:DF 1 "register_operand" "e")
(match_operand:DF 2 "register_operand" "e")))]
"TARGET_FPU"
+ "")
+
+(define_insn "*divdf3_nofix"
+ [(set (match_operand:DF 0 "register_operand" "=e")
+ (div:DF (match_operand:DF 1 "register_operand" "e")
+ (match_operand:DF 2 "register_operand" "e")))]
+ "TARGET_FPU && !sparc_fix_ut699"
"fdivd\t%1, %2, %0"
[(set_attr "type" "fpdivd")
(set_attr "fptype" "double")])
+(define_insn "*divdf3_fix"
+ [(set (match_operand:DF 0 "register_operand" "=e")
+ (div:DF (match_operand:DF 1 "register_operand" "e")
+ (match_operand:DF 2 "register_operand" "e")))]
+ "TARGET_FPU && sparc_fix_ut699"
+ "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]"
+ [(set_attr "type" "fpdivd")
+ (set_attr "fptype" "double")
+ (set_attr "length" "2")])
+
(define_insn "divsf3"
[(set (match_operand:SF 0 "register_operand" "=f")
(div:SF (match_operand:SF 1 "register_operand" "f")
(match_operand:SF 2 "register_operand" "f")))]
- "TARGET_FPU"
+ "TARGET_FPU && !sparc_fix_ut699"
"fdivs\t%1, %2, %0"
[(set_attr "type" "fpdivs")])
@@ -5742,18 +5759,33 @@
"fsqrtq\t%1, %0"
[(set_attr "type" "fpsqrtd")])
-(define_insn "sqrtdf2"
+(define_expand "sqrtdf2"
[(set (match_operand:DF 0 "register_operand" "=e")
(sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
"TARGET_FPU"
+ "")
+
+(define_insn "*sqrtdf2_nofix"
+ [(set (match_operand:DF 0 "register_operand" "=e")
+ (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
+ "TARGET_FPU && !sparc_fix_ut699"
"fsqrtd\t%1, %0"
[(set_attr "type" "fpsqrtd")
(set_attr "fptype" "double")])
+(define_insn "*sqrtdf2_fix"
+ [(set (match_operand:DF 0 "register_operand" "=e")
+ (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
+ "TARGET_FPU && sparc_fix_ut699"
+ "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]"
+ [(set_attr "type" "fpsqrtd")
+ (set_attr "fptype" "double")
+ (set_attr "length" "2")])
+
(define_insn "sqrtsf2"
[(set (match_operand:SF 0 "register_operand" "=f")
(sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
- "TARGET_FPU"
+ "TARGET_FPU && !sparc_fix_ut699"
"fsqrts\t%1, %0"
[(set_attr "type" "fpsqrts")])
@@ -8557,7 +8589,7 @@
mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
sel = force_reg (SImode, gen_int_mode (mask, SImode));
- emit_insn (gen_bmasksi_vis (gen_reg_rtx (SImode), sel, const0_rtx));
+ emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, const0_rtx));
emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
DONE;
})
diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
index 764c652e837..3b50c6c21f9 100644
--- a/gcc/config/sparc/sparc.opt
+++ b/gcc/config/sparc/sparc.opt
@@ -201,6 +201,10 @@ Target Report RejectNegative Var(sparc_fix_at697f)
Enable workaround for single erratum of AT697F processor
(corresponding to erratum #13 of AT697E processor)
+mfix-ut699
+Target Report RejectNegative Var(sparc_fix_ut699)
+Enable workarounds for the FP errata of the UT699 processor
+
Mask(LONG_DOUBLE_128)
;; Use 128-bit long double
diff --git a/gcc/config/t-sol2 b/gcc/config/t-sol2
index 25b825017f6..142de89de95 100644
--- a/gcc/config/t-sol2
+++ b/gcc/config/t-sol2
@@ -34,5 +34,5 @@ sol2-stubs.o: $(srcdir)/config/sol2-stubs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h
# Solaris-specific attributes
sol2.o: $(srcdir)/config/sol2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- tree.h output.h $(TM_H) $(TARGET_H) $(TM_P_H) $(GGC_H)
+ tree.h output.h $(TM_H) $(TARGET_H) $(TM_P_H) $(GGC_H) $(HASH_TABLE_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
diff --git a/gcc/configure b/gcc/configure
index 1f03eac6e27..8c221078102 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -8293,6 +8293,66 @@ $as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether termios.h defines TIOCGWINSZ" >&5
+$as_echo_n "checking whether termios.h defines TIOCGWINSZ... " >&6; }
+if test "${ac_cv_sys_tiocgwinsz_in_termios_h+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <termios.h>
+#ifdef TIOCGWINSZ
+ yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "yes" >/dev/null 2>&1; then :
+ ac_cv_sys_tiocgwinsz_in_termios_h=yes
+else
+ ac_cv_sys_tiocgwinsz_in_termios_h=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_tiocgwinsz_in_termios_h" >&5
+$as_echo "$ac_cv_sys_tiocgwinsz_in_termios_h" >&6; }
+
+if test $ac_cv_sys_tiocgwinsz_in_termios_h != yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sys/ioctl.h defines TIOCGWINSZ" >&5
+$as_echo_n "checking whether sys/ioctl.h defines TIOCGWINSZ... " >&6; }
+if test "${ac_cv_sys_tiocgwinsz_in_sys_ioctl_h+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#ifdef TIOCGWINSZ
+ yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "yes" >/dev/null 2>&1; then :
+ ac_cv_sys_tiocgwinsz_in_sys_ioctl_h=yes
+else
+ ac_cv_sys_tiocgwinsz_in_sys_ioctl_h=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_tiocgwinsz_in_sys_ioctl_h" >&5
+$as_echo "$ac_cv_sys_tiocgwinsz_in_sys_ioctl_h" >&6; }
+
+ if test $ac_cv_sys_tiocgwinsz_in_sys_ioctl_h = yes; then
+
+$as_echo "#define GWINSZ_IN_SYS_IOCTL 1" >>confdefs.h
+
+ fi
+fi
+
for ac_header in limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \
fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
sys/resource.h sys/param.h sys/times.h sys/stat.h \
@@ -17834,7 +17894,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 17837 "configure"
+#line 17897 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -17940,7 +18000,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 17943 "configure"
+#line 18003 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 855affdf152..41b64c78736 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -939,6 +939,7 @@ AC_HEADER_STDC
AC_HEADER_TIME
ACX_HEADER_STRING
AC_HEADER_SYS_WAIT
+AC_HEADER_TIOCGWINSZ
AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \
fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
sys/resource.h sys/param.h sys/times.h sys/stat.h \
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ed1d4796624..f8bacf5d42b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,49 @@
+2013-06-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51908
+ * parser.c (cp_parser_postfix_expression [RID_*CAST]): Set
+ parser->in_type_id_in_expr_p before calling cp_parser_type_id.
+
+2013-06-03 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (maybe_make_one_only): Use forced_by_abi instead of
+ mark_decl_referenced.
+ (mark_needed): Likewise.
+
+2013-06-03 Jason Merrill <jason@redhat.com>
+
+ * class.c (mark_type_abi_tags): New.
+ (check_abi_tags): Use it.
+
+2013-06-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57419
+ * decl2.c (mark_used): Add overload taking a tsubst_flags_t too.
+ * semantics.c (finish_qualified_id_expr): Use it.
+ * cp-tree.h: Update.
+
+2013-06-01 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (cp_write_global_declarations): Replace same_body_alias
+ by symbol.cpp_implicit_alias.
+
+2013-05-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/57404
+ * cp-lang.c (cp_classify_record): Handle structs without
+ TYPE_LANG_SPECIFIC.
+
+ PR c++/52377
+ * class.c (common_enclosing_class): New.
+ * cp-tree.h: Declare it.
+ * init.c (sort_mem_initializers): Don't splice out a union member
+ with an NSDMI.
+
+2013-05-29 Jan Hubicka <jh@suse.cz>
+
+ * tree.c (cp_fix_function_decl_p): Update for new symtab flags.
+ * decl2.c )var_finalized_p, cp_write_global_declarations): Likewise.
+
2013-05-25 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/25666
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index d6684cfd68b..40e6d3eed73 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1354,11 +1354,11 @@ find_abi_tags_r (tree *tp, int */*walk_subtrees*/, void *data)
return NULL_TREE;
}
-/* Check that class T has all the abi tags that subobject SUBOB has, or
- warn if not. */
+/* Set IDENTIFIER_MARKED on all the ABI tags on T and its (transitively
+ complete) template arguments. */
static void
-check_abi_tags (tree t, tree subob)
+mark_type_abi_tags (tree t, bool val)
{
tree attributes = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (t));
if (attributes)
@@ -1368,25 +1368,41 @@ check_abi_tags (tree t, tree subob)
{
tree tag = TREE_VALUE (list);
tree id = get_identifier (TREE_STRING_POINTER (tag));
- IDENTIFIER_MARKED (id) = true;
+ IDENTIFIER_MARKED (id) = val;
}
}
+ /* Also mark ABI tags from template arguments. */
+ if (CLASSTYPE_TEMPLATE_INFO (t))
+ {
+ tree args = CLASSTYPE_TI_ARGS (t);
+ for (int i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
+ {
+ tree level = TMPL_ARGS_LEVEL (args, i+1);
+ for (int j = 0; j < TREE_VEC_LENGTH (level); ++j)
+ {
+ tree arg = TREE_VEC_ELT (level, j);
+ if (CLASS_TYPE_P (arg))
+ mark_type_abi_tags (arg, val);
+ }
+ }
+ }
+}
+
+/* Check that class T has all the abi tags that subobject SUBOB has, or
+ warn if not. */
+
+static void
+check_abi_tags (tree t, tree subob)
+{
+ mark_type_abi_tags (t, true);
+
tree subtype = TYPE_P (subob) ? subob : TREE_TYPE (subob);
struct abi_tag_data data = { t, subob };
cp_walk_tree_without_duplicates (&subtype, find_abi_tags_r, &data);
- if (attributes)
- {
- for (tree list = TREE_VALUE (attributes); list;
- list = TREE_CHAIN (list))
- {
- tree tag = TREE_VALUE (list);
- tree id = get_identifier (TREE_STRING_POINTER (tag));
- IDENTIFIER_MARKED (id) = false;
- }
- }
+ mark_type_abi_tags (t, false);
}
/* Run through the base classes of T, updating CANT_HAVE_CONST_CTOR_P,
@@ -9259,4 +9275,30 @@ publicly_uniquely_derived_p (tree parent, tree type)
return base && base != error_mark_node;
}
+/* CTX1 and CTX2 are declaration contexts. Return the innermost common
+ class between them, if any. */
+
+tree
+common_enclosing_class (tree ctx1, tree ctx2)
+{
+ if (!TYPE_P (ctx1) || !TYPE_P (ctx2))
+ return NULL_TREE;
+ gcc_assert (ctx1 == TYPE_MAIN_VARIANT (ctx1)
+ && ctx2 == TYPE_MAIN_VARIANT (ctx2));
+ if (ctx1 == ctx2)
+ return ctx1;
+ for (tree t = ctx1; TYPE_P (t); t = TYPE_CONTEXT (t))
+ TYPE_MARKED_P (t) = true;
+ tree found = NULL_TREE;
+ for (tree t = ctx2; TYPE_P (t); t = TYPE_CONTEXT (t))
+ if (TYPE_MARKED_P (t))
+ {
+ found = t;
+ break;
+ }
+ for (tree t = ctx1; TYPE_P (t); t = TYPE_CONTEXT (t))
+ TYPE_MARKED_P (t) = false;
+ return found;
+}
+
#include "gt-cp-class.h"
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index 47a6004258b..a7fa8e4b1e9 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -127,7 +127,8 @@ cxx_dwarf_name (tree t, int verbosity)
static enum classify_record
cp_classify_record (tree type)
{
- if (CLASSTYPE_DECLARED_CLASS (type))
+ if (TYPE_LANG_SPECIFIC (type)
+ && CLASSTYPE_DECLARED_CLASS (type))
return RECORD_IS_CLASS;
return RECORD_IS_STRUCT;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 1f85ca7196f..8be1077c99c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5112,6 +5112,7 @@ extern void deduce_noexcept_on_destructor (tree);
extern void insert_late_enum_def_into_classtype_sorted_fields (tree, tree);
extern bool uniquely_derived_from_p (tree, tree);
extern bool publicly_uniquely_derived_p (tree, tree);
+extern tree common_enclosing_class (tree, tree);
/* in cvt.c */
extern tree convert_to_reference (tree, tree, int, int, tree,
@@ -5277,6 +5278,7 @@ extern bool decl_constant_var_p (tree);
extern bool decl_maybe_constant_var_p (tree);
extern void check_default_args (tree);
extern bool mark_used (tree);
+extern bool mark_used (tree, tsubst_flags_t);
extern void finish_static_data_member_decl (tree, tree, bool, tree, int);
extern tree cp_build_parm_decl (tree, tree);
extern tree get_guard (tree);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 8119210fb06..373f8831173 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1703,9 +1703,10 @@ maybe_make_one_only (tree decl)
if (VAR_P (decl))
{
+ struct varpool_node *node = varpool_node_for_decl (decl);
DECL_COMDAT (decl) = 1;
/* Mark it needed so we don't forget to emit it. */
- mark_decl_referenced (decl);
+ node->symbol.forced_by_abi = true;
TREE_USED (decl) = 1;
}
}
@@ -1803,7 +1804,7 @@ import_export_class (tree ctype)
static bool
var_finalized_p (tree var)
{
- return varpool_node_for_decl (var)->finalized;
+ return varpool_node_for_decl (var)->symbol.definition;
}
/* DECL is a VAR_DECL or FUNCTION_DECL which, for whatever reason,
@@ -1813,7 +1814,22 @@ void
mark_needed (tree decl)
{
TREE_USED (decl) = 1;
- mark_decl_referenced (decl);
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ /* Extern inline functions don't become needed when referenced.
+ If we know a method will be emitted in other TU and no new
+ functions can be marked reachable, just use the external
+ definition. */
+ struct cgraph_node *node = cgraph_get_create_node (decl);
+ node->symbol.forced_by_abi = true;
+ }
+ else if (TREE_CODE (decl) == VAR_DECL)
+ {
+ struct varpool_node *node = varpool_node_for_decl (decl);
+ /* C++ frontend use mark_decl_references to force COMDAT variables
+ to be output that might appear dead otherwise. */
+ node->symbol.forced_by_abi = true;
+ }
}
/* DECL is either a FUNCTION_DECL or a VAR_DECL. This function
@@ -4201,8 +4217,8 @@ cp_write_global_declarations (void)
struct cgraph_node *node, *next;
node = cgraph_get_node (decl);
- if (node->same_body_alias)
- node = cgraph_alias_aliased_node (node);
+ if (node->symbol.cpp_implicit_alias)
+ node = cgraph_alias_target (node);
cgraph_for_node_and_aliases (node, clear_decl_external,
NULL, true);
@@ -4224,7 +4240,7 @@ cp_write_global_declarations (void)
if (!DECL_EXTERNAL (decl)
&& decl_needed_p (decl)
&& !TREE_ASM_WRITTEN (decl)
- && !cgraph_get_node (decl)->local.finalized)
+ && !cgraph_get_node (decl)->symbol.definition)
{
/* We will output the function; no longer consider it in this
loop. */
@@ -4499,7 +4515,7 @@ possibly_inlined_p (tree decl)
wrong, true otherwise. */
bool
-mark_used (tree decl)
+mark_used (tree decl, tsubst_flags_t complain)
{
/* If DECL is a BASELINK for a single function, then treat it just
like the DECL for the function. Otherwise, if the BASELINK is
@@ -4537,9 +4553,12 @@ mark_used (tree decl)
return false;
}
}
- error ("use of deleted function %qD", decl);
- if (!maybe_explain_implicit_delete (decl))
- error_at (DECL_SOURCE_LOCATION (decl), "declared here");
+ if (complain & tf_error)
+ {
+ error ("use of deleted function %qD", decl);
+ if (!maybe_explain_implicit_delete (decl))
+ inform (DECL_SOURCE_LOCATION (decl), "declared here");
+ }
return false;
}
@@ -4552,7 +4571,8 @@ mark_used (tree decl)
{
if (!processing_template_decl && type_uses_auto (TREE_TYPE (decl)))
{
- error ("use of %qD before deduction of %<auto%>", decl);
+ if (complain & tf_error)
+ error ("use of %qD before deduction of %<auto%>", decl);
return false;
}
return true;
@@ -4701,4 +4721,10 @@ mark_used (tree decl)
return true;
}
+bool
+mark_used (tree decl)
+{
+ return mark_used (decl, tf_warning_or_error);
+}
+
#include "gt-cp-decl2.h"
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 671c774587d..4edd150d913 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -914,13 +914,12 @@ sort_mem_initializers (tree t, tree mem_inits)
Here we also splice out uninitialized union members. */
if (uses_unions_p)
{
- tree last_field = NULL_TREE;
+ tree *last_p = NULL;
tree *p;
for (p = &sorted_inits; *p; )
{
tree field;
tree ctx;
- int done;
init = *p;
@@ -940,22 +939,25 @@ sort_mem_initializers (tree t, tree mem_inits)
for (ctx = DECL_CONTEXT (field);
!same_type_p (ctx, t);
ctx = TYPE_CONTEXT (ctx))
- if (TREE_CODE (ctx) == UNION_TYPE)
+ if (TREE_CODE (ctx) == UNION_TYPE
+ || !ANON_AGGR_TYPE_P (ctx))
break;
/* If this field is not a member of a union, skip it. */
if (TREE_CODE (ctx) != UNION_TYPE)
goto next;
- /* If this union member has no explicit initializer, splice
- it out. */
- if (!TREE_VALUE (init))
+ /* If this union member has no explicit initializer and no NSDMI,
+ splice it out. */
+ if (TREE_VALUE (init) || DECL_INITIAL (field))
+ /* OK. */;
+ else
goto splice;
/* It's only an error if we have two initializers for the same
union type. */
- if (!last_field)
+ if (!last_p)
{
- last_field = field;
+ last_p = p;
goto next;
}
@@ -967,41 +969,23 @@ sort_mem_initializers (tree t, tree mem_inits)
union { struct { int i; int j; }; };
initializing both `i' and `j' makes sense. */
- ctx = DECL_CONTEXT (field);
- done = 0;
- do
- {
- tree last_ctx;
-
- last_ctx = DECL_CONTEXT (last_field);
- while (1)
- {
- if (same_type_p (last_ctx, ctx))
- {
- if (TREE_CODE (ctx) == UNION_TYPE)
- error_at (DECL_SOURCE_LOCATION (current_function_decl),
- "initializations for multiple members of %qT",
- last_ctx);
- done = 1;
- break;
- }
+ ctx = common_enclosing_class (DECL_CONTEXT (field),
+ DECL_CONTEXT (TREE_PURPOSE (*last_p)));
- if (same_type_p (last_ctx, t))
- break;
-
- last_ctx = TYPE_CONTEXT (last_ctx);
- }
-
- /* If we've reached the outermost class, then we're
- done. */
- if (same_type_p (ctx, t))
- break;
-
- ctx = TYPE_CONTEXT (ctx);
+ if (ctx && TREE_CODE (ctx) == UNION_TYPE)
+ {
+ /* A mem-initializer hides an NSDMI. */
+ if (TREE_VALUE (init) && !TREE_VALUE (*last_p))
+ *last_p = TREE_CHAIN (*last_p);
+ else if (TREE_VALUE (*last_p) && !TREE_VALUE (init))
+ goto splice;
+ else
+ error_at (DECL_SOURCE_LOCATION (current_function_decl),
+ "initializations for multiple members of %qT",
+ ctx);
}
- while (!done);
- last_field = field;
+ last_p = p;
next:
p = &TREE_CHAIN (*p);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 061b5714790..dfeeb0a94c2 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -5546,6 +5546,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
tree type;
tree expression;
const char *saved_message;
+ bool saved_in_type_id_in_expr_p;
/* All of these can be handled in the same way from the point
of view of parsing. Begin by consuming the token
@@ -5560,7 +5561,10 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
/* Look for the opening `<'. */
cp_parser_require (parser, CPP_LESS, RT_LESS);
/* Parse the type to which we are casting. */
+ saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
+ parser->in_type_id_in_expr_p = true;
type = cp_parser_type_id (parser);
+ parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
/* Look for the closing `>'. */
cp_parser_require (parser, CPP_GREATER, RT_GREATER);
/* Restore the old message. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index c1385c10b60..048a7db5e1e 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1778,8 +1778,9 @@ finish_qualified_id_expr (tree qualifying_class,
if (error_operand_p (expr))
return error_mark_node;
- if (DECL_P (expr) || BASELINK_P (expr))
- mark_used (expr);
+ if ((DECL_P (expr) || BASELINK_P (expr))
+ && !mark_used (expr, complain))
+ return error_mark_node;
if (template_p)
check_template_keyword (expr);
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 0fbb33d2042..8524f6cff91 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -3980,7 +3980,7 @@ cp_fix_function_decl_p (tree decl)
/* Don't fix same_body aliases. Although they don't have their own
CFG, they share it with what they alias to. */
- if (!node || !node->alias
+ if (!node || !node->symbol.alias
|| !vec_safe_length (node->symbol.ref_list.references))
return true;
}
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 4d9fc4ea3e6..1cc5d524205 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -2480,7 +2480,7 @@ dbxout_expand_expr (tree expr)
return NULL, otherwise stabs might reference an undefined
symbol. */
struct varpool_node *node = varpool_get_node (expr);
- if (!node || !node->analyzed)
+ if (!node || !node->symbol.definition)
return NULL;
}
/* FALLTHRU */
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 5c5b4b44fd7..e16222c5993 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -82,6 +82,7 @@ extensions, accepted by GCC in C90 mode and in C++.
* x86 specific memory model extensions for transactional memory:: x86 memory models.
* Object Size Checking:: Built-in functions for limited buffer overflow
checking.
+* Cilk Plus Builtins:: Built-in functions for the Cilk Plus language extension.
* Other Builtins:: Other built-in functions.
* Target Builtins:: Built-in functions specific to particular targets.
* Target Format Checks:: Format checks specific to particular targets.
@@ -8788,6 +8789,32 @@ Similar to @code{__builtin_bswap32}, except the argument and return types
are 64 bit.
@end deftypefn
+@node Cilk Plus Builtins
+@section Cilk Plus C/C++ language extension Built-in Functions.
+
+GCC provides support for the following built-in reduction funtions if Cilk Plus
+is enabled. Cilk Plus can be enabled using the @option{-fcilkplus} flag.
+
+@itemize @bullet
+@item __sec_implicit_index
+@item __sec_reduce
+@item __sec_reduce_add
+@item __sec_reduce_all_nonzero
+@item __sec_reduce_all_zero
+@item __sec_reduce_any_nonzero
+@item __sec_reduce_any_zero
+@item __sec_reduce_max
+@item __sec_reduce_min
+@item __sec_reduce_max_ind
+@item __sec_reduce_min_ind
+@item __sec_reduce_mul
+@item __sec_reduce_mutating
+@end itemize
+
+Further details and examples about these built-in functions are described
+in the Cilk Plus language manual which can be found at
+@uref{http://www.cilkplus.org}.
+
@node Target Builtins
@section Built-in Functions Specific to Particular Target Machines
@@ -13937,6 +13964,143 @@ if the VSX instruction set is available. The @samp{vec_vsx_ld} and
@samp{vec_vsx_st} built-in functions always generate the VSX @samp{LXVD2X},
@samp{LXVW4X}, @samp{STXVD2X}, and @samp{STXVW4X} instructions.
+If the ISA 2.07 additions to the vector/scalar (power8-vector)
+instruction set is available, the following additional functions are
+available for both 32-bit and 64-bit targets. For 64-bit targets, you
+can use @var{vector long} instead of @var{vector long long},
+@var{vector bool long} instead of @var{vector bool long long}, and
+@var{vector unsigned long} instead of @var{vector unsigned long long}.
+
+@smallexample
+vector long long vec_abs (vector long long);
+
+vector long long vec_add (vector long long, vector long long);
+vector unsigned long long vec_add (vector unsigned long long,
+ vector unsigned long long);
+
+int vec_all_eq (vector long long, vector long long);
+int vec_all_ge (vector long long, vector long long);
+int vec_all_gt (vector long long, vector long long);
+int vec_all_le (vector long long, vector long long);
+int vec_all_lt (vector long long, vector long long);
+int vec_all_ne (vector long long, vector long long);
+int vec_any_eq (vector long long, vector long long);
+int vec_any_ge (vector long long, vector long long);
+int vec_any_gt (vector long long, vector long long);
+int vec_any_le (vector long long, vector long long);
+int vec_any_lt (vector long long, vector long long);
+int vec_any_ne (vector long long, vector long long);
+
+vector long long vec_max (vector long long, vector long long);
+vector unsigned long long vec_max (vector unsigned long long,
+ vector unsigned long long);
+
+vector long long vec_min (vector long long, vector long long);
+vector unsigned long long vec_min (vector unsigned long long,
+ vector unsigned long long);
+
+vector int vec_pack (vector long long, vector long long);
+vector unsigned int vec_pack (vector unsigned long long,
+ vector unsigned long long);
+vector bool int vec_pack (vector bool long long, vector bool long long);
+
+vector int vec_packs (vector long long, vector long long);
+vector unsigned int vec_packs (vector unsigned long long,
+ vector unsigned long long);
+
+vector unsigned int vec_packsu (vector long long, vector long long);
+
+vector long long vec_rl (vector long long,
+ vector unsigned long long);
+vector long long vec_rl (vector unsigned long long,
+ vector unsigned long long);
+
+vector long long vec_sl (vector long long, vector unsigned long long);
+vector long long vec_sl (vector unsigned long long,
+ vector unsigned long long);
+
+vector long long vec_sr (vector long long, vector unsigned long long);
+vector unsigned long long char vec_sr (vector unsigned long long,
+ vector unsigned long long);
+
+vector long long vec_sra (vector long long, vector unsigned long long);
+vector unsigned long long vec_sra (vector unsigned long long,
+ vector unsigned long long);
+
+vector long long vec_sub (vector long long, vector long long);
+vector unsigned long long vec_sub (vector unsigned long long,
+ vector unsigned long long);
+
+vector long long vec_unpackh (vector int);
+vector unsigned long long vec_unpackh (vector unsigned int);
+
+vector long long vec_unpackl (vector int);
+vector unsigned long long vec_unpackl (vector unsigned int);
+
+vector long long vec_vaddudm (vector long long, vector long long);
+vector long long vec_vaddudm (vector bool long long, vector long long);
+vector long long vec_vaddudm (vector long long, vector bool long long);
+vector unsigned long long vec_vaddudm (vector unsigned long long,
+ vector unsigned long long);
+vector unsigned long long vec_vaddudm (vector bool unsigned long long,
+ vector unsigned long long);
+vector unsigned long long vec_vaddudm (vector unsigned long long,
+ vector bool unsigned long long);
+
+vector long long vec_vmaxsd (vector long long, vector long long);
+
+vector unsigned long long vec_vmaxud (vector unsigned long long,
+ unsigned vector long long);
+
+vector long long vec_vminsd (vector long long, vector long long);
+
+vector unsigned long long vec_vminud (vector long long,
+ vector long long);
+
+vector int vec_vpksdss (vector long long, vector long long);
+vector unsigned int vec_vpksdss (vector long long, vector long long);
+
+vector unsigned int vec_vpkudus (vector unsigned long long,
+ vector unsigned long long);
+
+vector int vec_vpkudum (vector long long, vector long long);
+vector unsigned int vec_vpkudum (vector unsigned long long,
+ vector unsigned long long);
+vector bool int vec_vpkudum (vector bool long long, vector bool long long);
+
+vector long long vec_vrld (vector long long, vector unsigned long long);
+vector unsigned long long vec_vrld (vector unsigned long long,
+ vector unsigned long long);
+
+vector long long vec_vsld (vector long long, vector unsigned long long);
+vector long long vec_vsld (vector unsigned long long,
+ vector unsigned long long);
+
+vector long long vec_vsrad (vector long long, vector unsigned long long);
+vector unsigned long long vec_vsrad (vector unsigned long long,
+ vector unsigned long long);
+
+vector long long vec_vsrd (vector long long, vector unsigned long long);
+vector unsigned long long char vec_vsrd (vector unsigned long long,
+ vector unsigned long long);
+
+vector long long vec_vsubudm (vector long long, vector long long);
+vector long long vec_vsubudm (vector bool long long, vector long long);
+vector long long vec_vsubudm (vector long long, vector bool long long);
+vector unsigned long long vec_vsubudm (vector unsigned long long,
+ vector unsigned long long);
+vector unsigned long long vec_vsubudm (vector bool long long,
+ vector unsigned long long);
+vector unsigned long long vec_vsubudm (vector unsigned long long,
+ vector bool long long);
+
+vector long long vec_vupkhsw (vector int);
+vector unsigned long long vec_vupkhsw (vector unsigned int);
+
+vector long long vec_vupklsw (vector int);
+vector unsigned long long vec_vupklsw (vector int);
+@end smallexample
+
If the cryptographic instructions are enabled (@option{-mcrypto} or
@option{-mcpu=power8}), the following builtins are enabled.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 5ca55d9e58b..b7b32f73b75 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -512,7 +512,8 @@ Objective-C and Objective-C++ Dialects}.
-mword-relocations @gol
-mfix-cortex-m3-ldrd @gol
-munaligned-access @gol
--mneon-for-64bits}
+-mneon-for-64bits @gol
+-mrestrict-it}
@emph{AVR Options}
@gccoptlist{-mmcu=@var{mcu} -maccumulate-args -mbranch-cost=@var{cost} @gol
@@ -752,6 +753,7 @@ Objective-C and Objective-C++ Dialects}.
-mno-float -msingle-float -mdouble-float @gol
-mdsp -mno-dsp -mdspr2 -mno-dspr2 @gol
-mmcu -mmno-mcu @gol
+-meva -mno-eva @gol
-mmicromips -mno-micromips @gol
-mfpu=@var{fpu-type} @gol
-msmartmips -mno-smartmips @gol
@@ -936,7 +938,7 @@ See RS/6000 and PowerPC Options.
-mvis2 -mno-vis2 -mvis3 -mno-vis3 @gol
-mcbcond -mno-cbcond @gol
-mfmaf -mno-fmaf -mpopc -mno-popc @gol
--mfix-at697f}
+-mfix-at697f -mfix-ut699}
@emph{SPU Options}
@gccoptlist{-mwarn-reloc -merror-reloc @gol
@@ -1799,6 +1801,17 @@ Program Interface v3.0 @w{@uref{http://www.openmp.org/}}. This option
implies @option{-pthread}, and thus is only supported on targets that
have support for @option{-pthread}.
+@item -fcilkplus
+@opindex fcilkplus
+@cindex Enable Cilk Plus
+Enable the usage of Cilk Language extension features for C/C++. When the flag
+@option{-fcilkplus} is specified, all the Cilk Plus components are converted
+to the appropriate C/C++ code. The present implementation follows ABI version
+0.9. There are four major parts to Cilk Plus language
+extension: Array Notations, Cilk Keywords, SIMD annotations and elemental
+functions. Detailed information about Cilk Plus can be found at
+@w{@uref{http://www.cilkplus.org}}.
+
@item -fgnu-tm
@opindex fgnu-tm
When the option @option{-fgnu-tm} is specified, the compiler
@@ -6161,7 +6174,7 @@ Controls optimization dumps from various optimization passes. If the
@samp{-@var{options}} form is used, @var{options} is a list of
@samp{-} separated options to select the dump details and
optimizations. If @var{options} is not specified, it defaults to
-@option{all} for details and @option{optall} for optimization
+@option{optimized} for details and @option{optall} for optimization
groups. If the @var{filename} is not specified, it defaults to
@file{stderr}. Note that the output @var{filename} will be overwritten
in case of multiple translation units. If a combined output from
@@ -11621,6 +11634,12 @@ defined.
Enables using Neon to handle scalar 64-bits operations. This is
disabled by default since the cost of moving data from core registers
to Neon is high.
+
+@item -mrestrict-it
+@opindex mrestrict-it
+Restricts generation of IT blocks to conform to the rules of ARMv8.
+IT blocks can only contain a single 16-bit instruction from a select
+set of instructions. This option is on by default for ARMv8 Thumb mode.
@end table
@node AVR Options
@@ -16365,6 +16384,12 @@ Use (do not use) MT Multithreading instructions.
@opindex mno-mcu
Use (do not use) the MIPS MCU ASE instructions.
+@item -meva
+@itemx -mno-eva
+@opindex meva
+@opindex mno-eva
+Use (do not use) the MIPS Enhanced Virtual Addressing instructions.
+
@item -mlong64
@opindex mlong64
Force @code{long} types to be 64 bits wide. See @option{-mlong32} for
@@ -19449,6 +19474,11 @@ later.
@opindex mfix-at697f
Enable the documented workaround for the single erratum of the Atmel AT697F
processor (which corresponds to erratum #13 of the AT697E processor).
+
+@item -mfix-ut699
+@opindex mfix-ut699
+Enable the documented workarounds for the floating-point errata of the UT699
+processor.
@end table
These @samp{-m} options are supported in addition to the above
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 8c72c850852..3b20991af52 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -8866,7 +8866,8 @@ can be quite tedious to describe these forms directly in the
(define_cond_exec
[@var{predicate-pattern}]
"@var{condition}"
- "@var{output-template}")
+ "@var{output-template}"
+ "@var{optional-insn-attribues}")
@end smallexample
@var{predicate-pattern} is the condition that must be true for the
@@ -8887,6 +8888,13 @@ In order to handle the general case, there is a global variable
@code{current_insn_predicate} that will contain the entire predicate
if the current insn is predicated, and will otherwise be @code{NULL}.
+@var{optional-insn-attributes} is an optional vector of attributes that gets
+appended to the insn attributes of the produced cond_exec rtx. It can
+be used to add some distinguishing attribute to cond_exec rtxs produced
+that way. An example usage would be to use this attribute in conjunction
+with attributes on the main pattern to disable particular alternatives under
+certain conditions.
+
When @code{define_cond_exec} is used, an implicit reference to
the @code{predicable} instruction attribute is made.
@xref{Insn Attributes}. This attribute must be a boolean (i.e.@: have
diff --git a/gcc/doc/passes.texi b/gcc/doc/passes.texi
index 654f2295e39..045f964a939 100644
--- a/gcc/doc/passes.texi
+++ b/gcc/doc/passes.texi
@@ -17,6 +17,7 @@ where near complete.
@menu
* Parsing pass:: The language front end turns text into bits.
+* Cilk Plus Transformation:: Transform Cilk Plus Code to equivalent C/C++.
* Gimplification pass:: The bits are turned into something we can optimize.
* Pass manager:: Sequencing the optimization passes.
* Tree SSA passes:: Optimizations on a high-level representation.
@@ -101,6 +102,36 @@ that is more descriptive than "rest_of".
The middle-end will, at its option, emit the function and data
definitions immediately or queue them for later processing.
+@node Cilk Plus Transformation
+@section Cilk Plus Transformation
+@cindex CILK_PLUS
+
+If Cilk Plus generation (flag @option{-fcilkplus}) is enabled, all the Cilk
+Plus code is transformed into equivalent C and C++ functions. Majority of this
+transformation occurs toward the end of the parsing and right before the
+gimplification pass.
+
+These are the major components to the Cilk Plus language extension:
+@itemize @bullet
+@item Array Notations:
+During parsing phase, all the array notation specific information is stored in
+@code{ARRAY_NOTATION_REF} tree using the function
+@code{c_parser_array_notation}. During the end of parsing, we check the entire
+function to see if there are any array notation specific code (using the
+function @code{contains_array_notation_expr}). If this function returns
+true, then we expand them using either @code{expand_array_notation_exprs} or
+@code{build_array_notation_expr}. For the cases where array notations are
+inside conditions, they are transformed using the function
+@code{fix_conditional_array_notations}. The C language-specific routines are
+located in @file{c/c-array-notation.c} and the equivalent C++ routines are in
+file @file{cp/cp-array-notation.c}. Common routines such as functions to
+initialize builtin functions are stored in @file{array-notation-common.c}.
+@end itemize
+
+Detailed information about Cilk Plus and language specification is provided in
+@w{@uref{http://www.cilkplus.org/}}. It is worth mentioning that the current
+implementation follows ABI 0.9.
+
@node Gimplification pass
@section Gimplification pass
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index cfde14af8ac..f8404814c96 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -2898,6 +2898,10 @@ A target hook which returns true if we use LRA instead of reload pass. It means
A target hook which returns the register priority number to which the register @var{hard_regno} belongs to. The bigger the number, the more preferable the hard register usage (when all other conditions are the same). This hook can be used to prefer some hard register over others in LRA. For example, some x86-64 register usage needs additional prefix which makes instructions longer. The hook can return lower priority number for such registers make them less favorable and as result making the generated code smaller. The default version of this target hook returns always zero.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_REGISTER_USAGE_LEVELING_P (void)
+A target hook which returns true if we need register usage leveling. That means if a few hard registers are equally good for the assignment, we choose the least used hard register. The register usage leveling may be profitable for some targets. Don't use the usage leveling for targets with conditional execution or targets with big register files as it hurts if-conversion and cross-jumping optimizations. The default version of this target hook returns always false.
+@end deftypefn
+
@deftypefn {Target Hook} bool TARGET_DIFFERENT_ADDR_DISPLACEMENT_P (void)
A target hook which returns true if an address with the same structure can have different maximal legitimate displacement. For example, the displacement can depend on memory mode or on operand combinations in the insn. The default version of this target hook returns always false.
@end deftypefn
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 611d6813a56..b08dece763a 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -2870,6 +2870,8 @@ as below:
@hook TARGET_REGISTER_PRIORITY
+@hook TARGET_REGISTER_USAGE_LEVELING_P
+
@hook TARGET_DIFFERENT_ADDR_DISPLACEMENT_P
@hook TARGET_SPILL_CLASS
diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c
index 7442a27540a..55ad80451d6 100644
--- a/gcc/dumpfile.c
+++ b/gcc/dumpfile.c
@@ -866,7 +866,7 @@ opt_info_switch_p (const char *arg)
file_seen = xstrdup (filename);
if (!flags)
- flags = MSG_ALL;
+ flags = MSG_OPTIMIZED_LOCATIONS;
if (!optgroup_flags)
optgroup_flags = OPTGROUP_ALL;
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index e4a3c075520..b615b181a3b 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -14919,7 +14919,7 @@ reference_to_unused (tree * tp, int * walk_subtrees,
else if (TREE_CODE (*tp) == VAR_DECL)
{
struct varpool_node *node = varpool_get_node (*tp);
- if (!node || !node->analyzed)
+ if (!node || !node->symbol.definition)
return *tp;
}
else if (TREE_CODE (*tp) == FUNCTION_DECL
@@ -17597,7 +17597,7 @@ premark_types_used_by_global_vars_helper (void **slot,
/* Ask cgraph if the global variable really is to be emitted.
If yes, then we'll keep the DIE of ENTRY->TYPE. */
struct varpool_node *node = varpool_get_node (entry->var_decl);
- if (node && node->analyzed)
+ if (node && node->symbol.definition)
{
die->die_perennial_p = 1;
/* Keep the parent DIEs as well. */
diff --git a/gcc/expmed.c b/gcc/expmed.c
index daadd3def5d..79f3424961d 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -1486,6 +1486,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
This is because the most significant word is the one which may
be less than full. */
+ unsigned int backwards = WORDS_BIG_ENDIAN;
unsigned int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
unsigned int i;
rtx last;
@@ -1503,13 +1504,14 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
if I is 1, use the next to lowest word; and so on. */
/* Word number in TARGET to use. */
unsigned int wordnum
- = (WORDS_BIG_ENDIAN
+ = (backwards
? GET_MODE_SIZE (GET_MODE (target)) / UNITS_PER_WORD - i - 1
: i);
/* Offset from start of field in OP0. */
- unsigned int bit_offset = (WORDS_BIG_ENDIAN
- ? MAX (0, ((int) bitsize - ((int) i + 1)
- * (int) BITS_PER_WORD))
+ unsigned int bit_offset = (backwards
+ ? MAX ((int) bitsize - ((int) i + 1)
+ * BITS_PER_WORD,
+ 0)
: (int) i * BITS_PER_WORD);
rtx target_part = operand_subword (target, wordnum, 1, VOIDmode);
rtx result_part
@@ -1541,7 +1543,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
for (i = nwords; i < total_words; i++)
emit_move_insn
(operand_subword (target,
- WORDS_BIG_ENDIAN ? total_words - i - 1 : i,
+ backwards ? total_words - i - 1 : i,
1, VOIDmode),
const0_rtx);
}
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 38db3f1d832..a2b7ac18312 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -2664,10 +2664,10 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
case COMPONENT_REF:
/* Handle operand 2 the same as for ARRAY_REF. Operand 0
may be NULL when we're called to compare MEM_EXPRs. */
- if (!OP_SAME_WITH_NULL (0) || !OP_SAME (1))
+ if (!OP_SAME_WITH_NULL (0))
return 0;
flags &= ~OEP_CONSTANT_ADDRESS_OF;
- return OP_SAME_WITH_NULL (2);
+ return OP_SAME (1) && OP_SAME_WITH_NULL (2);
case BIT_FIELD_REF:
if (!OP_SAME (0))
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index eccce10ee11..d8ff752e588 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,127 @@
+2013-06-04 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/37336
+ * trans.h (gfc_build_final_call): Remove prototype.
+ (gfc_add_finalizer_call): Add prototype.
+ * trans-array.c (gfc_trans_dealloc_allocated): Support finalization.
+ (structure_alloc_comps): Update caller.
+ (gfc_trans_deferred_array): Call finalizer.
+ * trans-array.h (gfc_trans_dealloc_allocated): Update prototype.
+ * trans-decl.c (gfc_trans_deferred_vars): Don't deallocate/finalize
+ variables of the main program.
+ * trans-expr.c (gfc_conv_procedure_call): Support finalization.
+ * trans-openmp.c (gfc_omp_clause_dtor,
+ gfc_trans_omp_array_reduction): Update calls.
+ * trans-stmt.c (gfc_trans_deallocate): Avoid double deallocation
+ of alloc components.
+ * trans.c (gfc_add_finalizer_call): New function.
+ (gfc_deallocate_with_status,
+ gfc_deallocate_scalar_with_status): Call it
+ (gfc_build_final_call): Fix handling of scalar coarrays,
+ move up in the file and make static.
+
+2013-06-01 Janus Weil <janus@gcc.gnu.org>
+ Mikael Morin <mikael@gcc.gnu.org>
+
+ * error.c (get_terminal_width): Only limit the width if we're
+ outputting to a terminal. Try to determine width via ioctl.
+
+2013-06-01 Tobias Burnus <burnus@net-b.de>
+
+ * decl.c (add_global_entry): Take locus.
+ (gfc_match_entry): Update call.
+ (gfc_match_end): Better error location.
+ * parse.c (parse_block_data, parse_module, add_global_procedure,
+ add_global_program): Use better locus data.
+
+2013-05-31 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/57456
+ * trans-array.c (gfc_array_init_size): Use passed type spec,
+ when available.
+ (gfc_array_allocate): Pass typespec on.
+ * trans-array.h (gfc_array_allocate): Update prototype.
+ * trans-stmt.c (gfc_trans_allocate): Pass typespec on.
+
+2013-05-31 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/54190
+ PR fortran/57217
+ * gfortran.h (gfc_terminal_width): Remove prototype.
+ * error.c (get_terminal_width): Moved here from misc.c. Renamed.
+ Try to determine terminal width from environment variable.
+ * interface.c (compare_type, compare_rank): New functions. Fix assumed
+ type/rank handling.
+ (compare_type_rank, check_dummy_characteristics,
+ check_result_characteristics, gfc_compare_interfaces): Use them.
+ (symbol_rank): Slightly modified and moved.
+ * misc.c (gfc_terminal_width): Moved to error.c.
+
+2013-05-30 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/54189
+ * resolve.c (check_assumed_size_reference): Check for e->ref.
+
+2013-05-30 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/57458
+ * interface.c (compare_parameter): Update C1239/C1240 constraint
+ check for assumed-rank/TS29113.
+
+2013-05-29 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/37336
+ * class.c (finalize_component): Fix coarray array refs.
+ (generate_finalization_wrapper): Only gfc_convert_type_warn
+ when the kind value is different.
+ (gfc_find_intrinsic_vtab): _copy's dst is now intent(inout).
+ (gfc_find_derived_vtab): Ditto. Enable finalization-wrapper
+ generation.
+ * module.c (MOD_VERSION): Bump.
+ (gfc_dump_module, gfc_use_module): Remove empty line in .mod.
+ * trans-array.c (gfc_conv_descriptor_token): Accept nonrestricted
+ void pointer.
+ (gfc_array_allocate, structure_alloc_comps): Don't nullify for
+ BT_CLASS allocations.
+ * trans-stmt.c (gfc_trans_allocate): Ditto.
+
+2013-05-29 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/37336
+ * resolve.c (gfc_resolve_finalizers): Remove not implemented error.
+
+2013-05-28 Tobias Burnus <burnus@net-b.de>
+
+ * trans-expr.c (gfc_conv_procedure_call): Deallocate
+ polymorphic arrays for allocatable intent(out) dummies.
+ (gfc_reset_vptr): New function, moved from trans-stmt.c
+ and extended.
+ * trans-stmt.c (reset_vptr): Remove.
+ (gfc_trans_deallocate): Update calls.
+ * trans.h (gfc_reset_vptr): New prototype.
+
+2013-05-28 Dominique d'Humieres <dominiq@lps.ens.fr>
+
+ PR fortran/57435
+ * module.c (check_for_ambiguous): Avoid null pointer deref.
+
+2013-05-28 Janus Weil <janus@gcc.gnu.org>
+ Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/57217
+ * interface.c (check_dummy_characteristics): Symmetrize type check.
+
+2013-05-27 Bud Davis <jmdavis@link.com>
+
+ PR fortran/50405
+ * resolve.c (resolve_formal_arglist): Detect error when an argument
+ has the same name as the function.
+
+2013-05-27 Tobias Burnus <burnus@net-b.de>
+
+ * expr.c (gfc_build_intrinsic_call): Make symbol as attr.artificial.
+ * intrinsic.c (gfc_is_intrinsic): Disable std check for those.
+
2013-05-22 Tobias Burnus <burnus@net-b.de>
* resolve.c (get_temp_from_expr): Change mangling to
diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
index 349f494f62a..ba8efa91114 100644
--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -832,17 +832,18 @@ finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
ref->u.c.component = comp;
e->ts = comp->ts;
- if (comp->attr.dimension
+ if (comp->attr.dimension || comp->attr.codimension
|| (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
- && CLASS_DATA (comp)->attr.dimension))
+ && (CLASS_DATA (comp)->attr.dimension
+ || CLASS_DATA (comp)->attr.codimension)))
{
ref->next = gfc_get_ref ();
ref->next->type = REF_ARRAY;
- ref->next->u.ar.type = AR_FULL;
ref->next->u.ar.dimen = 0;
ref->next->u.ar.as = comp->ts.type == BT_CLASS ? CLASS_DATA (comp)->as
: comp->as;
e->rank = ref->next->u.ar.as->rank;
+ ref->next->u.ar.type = e->rank ? AR_FULL : AR_ELEMENT;
}
/* Call DEALLOCATE (comp, stat=ignore). */
@@ -1640,7 +1641,8 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
rank = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_RANK, "rank",
gfc_current_locus, 1,
gfc_lval_expr_from_sym (array));
- gfc_convert_type (rank, &idx->ts, 2);
+ if (rank->ts.kind != idx->ts.kind)
+ gfc_convert_type_warn (rank, &idx->ts, 2, 0);
/* Create is_contiguous variable. */
gfc_get_symbol ("is_contiguous", sub_ns, &is_contiguous);
@@ -2363,7 +2365,7 @@ gfc_find_derived_vtab (gfc_symbol *derived)
dst->attr.flavor = FL_VARIABLE;
dst->attr.dummy = 1;
dst->attr.artificial = 1;
- dst->attr.intent = INTENT_OUT;
+ dst->attr.intent = INTENT_INOUT;
gfc_set_sym_referenced (dst);
copy->formal->next = gfc_get_formal_arglist ();
copy->formal->next->sym = dst;
@@ -2382,9 +2384,6 @@ gfc_find_derived_vtab (gfc_symbol *derived)
components and the calls to finalization subroutines.
Note: The actual wrapper function can only be generated
at resolution time. */
- /* FIXME: Enable ABI-breaking "_final" generation. */
- if (0)
- {
if (!gfc_add_component (vtype, "_final", &c))
goto cleanup;
c->attr.proc_pointer = 1;
@@ -2392,7 +2391,6 @@ gfc_find_derived_vtab (gfc_symbol *derived)
c->tb = XCNEW (gfc_typebound_proc);
c->tb->ppc = 1;
generate_finalization_wrapper (derived, ns, tname, c);
- }
/* Add procedure pointers for type-bound procedures. */
if (!derived->attr.unlimited_polymorphic)
@@ -2651,7 +2649,7 @@ gfc_find_intrinsic_vtab (gfc_typespec *ts)
dst->ts.kind = ts->kind;
dst->attr.flavor = FL_VARIABLE;
dst->attr.dummy = 1;
- dst->attr.intent = INTENT_OUT;
+ dst->attr.intent = INTENT_INOUT;
gfc_set_sym_referenced (dst);
copy->formal->next = gfc_get_formal_arglist ();
copy->formal->next->sym = dst;
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 6ab9cc78438..f1aa31e07be 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -5354,7 +5354,8 @@ cleanup:
to return false upon finding an existing global entry. */
static bool
-add_global_entry (const char *name, const char *binding_label, bool sub)
+add_global_entry (const char *name, const char *binding_label, bool sub,
+ locus *where)
{
gfc_gsymbol *s;
enum gfc_symbol_type type;
@@ -5369,14 +5370,14 @@ add_global_entry (const char *name, const char *binding_label, bool sub)
if (s->defined || (s->type != GSYM_UNKNOWN && s->type != type))
{
- gfc_global_used(s, NULL);
+ gfc_global_used (s, where);
return false;
}
else
{
s->type = type;
s->sym_name = name;
- s->where = gfc_current_locus;
+ s->where = *where;
s->defined = 1;
s->ns = gfc_current_ns;
}
@@ -5391,7 +5392,7 @@ add_global_entry (const char *name, const char *binding_label, bool sub)
if (s->defined || (s->type != GSYM_UNKNOWN && s->type != type))
{
- gfc_global_used(s, NULL);
+ gfc_global_used (s, where);
return false;
}
else
@@ -5399,7 +5400,7 @@ add_global_entry (const char *name, const char *binding_label, bool sub)
s->type = type;
s->sym_name = name;
s->binding_label = binding_label;
- s->where = gfc_current_locus;
+ s->where = *where;
s->defined = 1;
s->ns = gfc_current_ns;
}
@@ -5528,6 +5529,7 @@ gfc_match_entry (void)
/* Check what next non-whitespace character is so we can tell if there
is the required parens if we have a BIND(C). */
+ old_loc = gfc_current_locus;
gfc_gobble_whitespace ();
peek_char = gfc_peek_ascii_char ();
@@ -5555,7 +5557,8 @@ gfc_match_entry (void)
}
if (!gfc_current_ns->parent
- && !add_global_entry (name, entry->binding_label, true))
+ && !add_global_entry (name, entry->binding_label, true,
+ &old_loc))
return MATCH_ERROR;
/* An entry in a subroutine. */
@@ -5574,7 +5577,6 @@ gfc_match_entry (void)
ENTRY f() RESULT (r)
can't be written as
ENTRY f RESULT (r). */
- old_loc = gfc_current_locus;
if (gfc_match_eos () == MATCH_YES)
{
gfc_current_locus = old_loc;
@@ -5624,7 +5626,8 @@ gfc_match_entry (void)
}
if (!gfc_current_ns->parent
- && !add_global_entry (name, entry->binding_label, false))
+ && !add_global_entry (name, entry->binding_label, false,
+ &old_loc))
return MATCH_ERROR;
}
@@ -6108,6 +6111,7 @@ gfc_match_end (gfc_statement *st)
goto cleanup;
}
+ old_loc = gfc_current_locus;
if (gfc_match_eos () == MATCH_YES)
{
if (!eos_ok && (*st == ST_END_SUBROUTINE || *st == ST_END_FUNCTION))
@@ -6131,10 +6135,12 @@ gfc_match_end (gfc_statement *st)
/* Verify that we've got the sort of end-block that we're expecting. */
if (gfc_match (target) != MATCH_YES)
{
- gfc_error ("Expecting %s statement at %C", gfc_ascii_statement (*st));
+ gfc_error ("Expecting %s statement at %L", gfc_ascii_statement (*st),
+ &old_loc);
goto cleanup;
}
+ old_loc = gfc_current_locus;
/* If we're at the end, make sure a block name wasn't required. */
if (gfc_match_eos () == MATCH_YES)
{
@@ -6147,8 +6153,8 @@ gfc_match_end (gfc_statement *st)
if (!block_name)
return MATCH_YES;
- gfc_error ("Expected block name of '%s' in %s statement at %C",
- block_name, gfc_ascii_statement (*st));
+ gfc_error ("Expected block name of '%s' in %s statement at %L",
+ block_name, gfc_ascii_statement (*st), &old_loc);
return MATCH_ERROR;
}
diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c
index 60b209354c5..35fe62706c6 100644
--- a/gcc/fortran/error.c
+++ b/gcc/fortran/error.c
@@ -30,6 +30,15 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "gfortran.h"
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#ifdef GWINSZ_IN_SYS_IOCTL
+# include <sys/ioctl.h>
+#endif
+
+
static int suppress_errors = 0;
static int warnings_not_errors = 0;
@@ -59,12 +68,45 @@ gfc_pop_suppress_errors (void)
}
+/* Determine terminal width (for trimming source lines in output). */
+
+static int
+get_terminal_width (void)
+{
+ /* Only limit the width if we're outputting to a terminal. */
+#ifdef HAVE_UNISTD_H
+ if (!isatty (STDERR_FILENO))
+ return INT_MAX;
+#endif
+
+ /* Method #1: Use ioctl (not available on all systems). */
+#ifdef TIOCGWINSZ
+ struct winsize w;
+ w.ws_col = 0;
+ if (ioctl (0, TIOCGWINSZ, &w) == 0 && w.ws_col > 0)
+ return w.ws_col;
+#endif
+
+ /* Method #2: Query environment variable $COLUMNS. */
+ const char *p = getenv ("COLUMNS");
+ if (p)
+ {
+ int value = atoi (p);
+ if (value > 0)
+ return value;
+ }
+
+ /* If both fail, use reasonable default. */
+ return 80;
+}
+
+
/* Per-file error initialization. */
void
gfc_error_init_1 (void)
{
- terminal_width = gfc_terminal_width ();
+ terminal_width = get_terminal_width ();
errors = 0;
warnings = 0;
buffer_flag = 0;
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index ab62c180d3d..3ece2d3b70c 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -4657,6 +4657,7 @@ gfc_build_intrinsic_call (gfc_namespace *ns, gfc_isym_id id, const char* name,
result->symtree->n.sym->intmod_sym_id = id;
result->symtree->n.sym->attr.flavor = FL_PROCEDURE;
result->symtree->n.sym->attr.intrinsic = 1;
+ result->symtree->n.sym->attr.artificial = 1;
va_start (ap, numarg);
atail = NULL;
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 27662f7ca40..14da0aff36f 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -2436,7 +2436,6 @@ void gfc_start_source_files (void);
void gfc_end_source_files (void);
/* misc.c */
-int gfc_terminal_width (void);
void gfc_clear_ts (gfc_typespec *);
FILE *gfc_open_file (const char *);
const char *gfc_basic_typename (bt);
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 1b967fac275..f06ecfe3ec4 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -508,18 +508,23 @@ gfc_compare_types (gfc_typespec *ts1, gfc_typespec *ts2)
}
-/* Given two symbols that are formal arguments, compare their ranks
- and types. Returns nonzero if they have the same rank and type,
- zero otherwise. */
+static int
+compare_type (gfc_symbol *s1, gfc_symbol *s2)
+{
+ if (s2->attr.ext_attr & (1 << EXT_ATTR_NO_ARG_CHECK))
+ return 1;
+
+ return gfc_compare_types (&s1->ts, &s2->ts) || s2->ts.type == BT_ASSUMED;
+}
+
static int
-compare_type_rank (gfc_symbol *s1, gfc_symbol *s2)
+compare_rank (gfc_symbol *s1, gfc_symbol *s2)
{
gfc_array_spec *as1, *as2;
int r1, r2;
- if (s1->attr.ext_attr & (1 << EXT_ATTR_NO_ARG_CHECK)
- || s2->attr.ext_attr & (1 << EXT_ATTR_NO_ARG_CHECK))
+ if (s2->attr.ext_attr & (1 << EXT_ATTR_NO_ARG_CHECK))
return 1;
as1 = (s1->ts.type == BT_CLASS) ? CLASS_DATA (s1)->as : s1->as;
@@ -528,13 +533,21 @@ compare_type_rank (gfc_symbol *s1, gfc_symbol *s2)
r1 = as1 ? as1->rank : 0;
r2 = as2 ? as2->rank : 0;
- if (r1 != r2
- && (!as1 || as1->type != AS_ASSUMED_RANK)
- && (!as2 || as2->type != AS_ASSUMED_RANK))
+ if (r1 != r2 && (!as2 || as2->type != AS_ASSUMED_RANK))
return 0; /* Ranks differ. */
- return gfc_compare_types (&s1->ts, &s2->ts)
- || s1->ts.type == BT_ASSUMED || s2->ts.type == BT_ASSUMED;
+ return 1;
+}
+
+
+/* Given two symbols that are formal arguments, compare their ranks
+ and types. Returns nonzero if they have the same rank and type,
+ zero otherwise. */
+
+static int
+compare_type_rank (gfc_symbol *s1, gfc_symbol *s2)
+{
+ return compare_type (s1, s2) && compare_rank (s1, s2);
}
@@ -1019,6 +1032,15 @@ generic_correspondence (gfc_formal_arglist *f1, gfc_formal_arglist *f2,
}
+static int
+symbol_rank (gfc_symbol *sym)
+{
+ gfc_array_spec *as;
+ as = (sym->ts.type == BT_CLASS) ? CLASS_DATA (sym)->as : sym->as;
+ return as ? as->rank : 0;
+}
+
+
/* Check if the characteristics of two dummy arguments match,
cf. F08:12.3.2. */
@@ -1030,11 +1052,20 @@ check_dummy_characteristics (gfc_symbol *s1, gfc_symbol *s2,
return s1 == s2 ? true : false;
/* Check type and rank. */
- if (type_must_agree && !compare_type_rank (s2, s1))
+ if (type_must_agree)
{
- snprintf (errmsg, err_len, "Type/rank mismatch in argument '%s'",
- s1->name);
- return false;
+ if (!compare_type (s1, s2) || !compare_type (s2, s1))
+ {
+ snprintf (errmsg, err_len, "Type mismatch in argument '%s' (%s/%s)",
+ s1->name, gfc_typename (&s1->ts), gfc_typename (&s2->ts));
+ return false;
+ }
+ if (!compare_rank (s1, s2))
+ {
+ snprintf (errmsg, err_len, "Rank mismatch in argument '%s' (%i/%i)",
+ s1->name, symbol_rank (s1), symbol_rank (s2));
+ return false;
+ }
}
/* Check INTENT. */
@@ -1202,9 +1233,16 @@ check_result_characteristics (gfc_symbol *s1, gfc_symbol *s2,
return true;
/* Check type and rank. */
- if (!compare_type_rank (r1, r2))
+ if (!compare_type (r1, r2))
+ {
+ snprintf (errmsg, err_len, "Type mismatch in function result (%s/%s)",
+ gfc_typename (&r1->ts), gfc_typename (&r2->ts));
+ return false;
+ }
+ if (!compare_rank (r1, r2))
{
- snprintf (errmsg, err_len, "Type/rank mismatch in function result");
+ snprintf (errmsg, err_len, "Rank mismatch in function result (%i/%i)",
+ symbol_rank (r1), symbol_rank (r2));
return false;
}
@@ -1436,13 +1474,26 @@ gfc_compare_interfaces (gfc_symbol *s1, gfc_symbol *s2, const char *name2,
errmsg, err_len))
return 0;
}
- else if (!compare_type_rank (f2->sym, f1->sym))
+ else
{
/* Only check type and rank. */
- if (errmsg != NULL)
- snprintf (errmsg, err_len, "Type/rank mismatch in argument '%s'",
- f1->sym->name);
- return 0;
+ if (!compare_type (f2->sym, f1->sym))
+ {
+ if (errmsg != NULL)
+ snprintf (errmsg, err_len, "Type mismatch in argument '%s' "
+ "(%s/%s)", f1->sym->name,
+ gfc_typename (&f1->sym->ts),
+ gfc_typename (&f2->sym->ts));
+ return 0;
+ }
+ if (!compare_rank (f2->sym, f1->sym))
+ {
+ if (errmsg != NULL)
+ snprintf (errmsg, err_len, "Rank mismatch in argument '%s' "
+ "(%i/%i)", f1->sym->name, symbol_rank (f1->sym),
+ symbol_rank (f2->sym));
+ return 0;
+ }
}
next:
f1 = f1->next;
@@ -1745,16 +1796,6 @@ done:
}
-static int
-symbol_rank (gfc_symbol *sym)
-{
- if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as)
- return CLASS_DATA (sym)->as->rank;
-
- return (sym->as == NULL) ? 0 : sym->as->rank;
-}
-
-
/* Given a symbol of a formal argument list and an expression, if the
formal argument is allocatable, check that the actual argument is
allocatable. Returns nonzero if compatible, zero if not compatible. */
@@ -2030,14 +2071,15 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
|| actual->symtree->n.sym->attr.volatile_)
&& (formal->attr.asynchronous || formal->attr.volatile_)
&& actual->rank && !gfc_is_simply_contiguous (actual, true)
- && ((formal->as->type != AS_ASSUMED_SHAPE && !formal->attr.pointer)
+ && ((formal->as->type != AS_ASSUMED_SHAPE
+ && formal->as->type != AS_ASSUMED_RANK && !formal->attr.pointer)
|| formal->attr.contiguous))
{
if (where)
- gfc_error ("Dummy argument '%s' has to be a pointer or assumed-shape "
- "array without CONTIGUOUS attribute - as actual argument at"
- " %L is not simply contiguous and both are ASYNCHRONOUS "
- "or VOLATILE", formal->name, &actual->where);
+ gfc_error ("Dummy argument '%s' has to be a pointer, assumed-shape or "
+ "assumed-rank array without CONTIGUOUS attribute - as actual"
+ " argument at %L is not simply contiguous and both are "
+ "ASYNCHRONOUS or VOLATILE", formal->name, &actual->where);
return 0;
}
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index 3251ebb558d..c2e1525a268 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -1046,7 +1046,8 @@ gfc_is_intrinsic (gfc_symbol* sym, int subroutine_flag, locus loc)
return false;
/* See if this intrinsic is allowed in the current standard. */
- if (!gfc_check_intrinsic_standard (isym, &symstd, false, loc))
+ if (!gfc_check_intrinsic_standard (isym, &symstd, false, loc)
+ && !sym->attr.artificial)
{
if (sym->attr.proc == PROC_UNKNOWN
&& gfc_option.warn_intrinsics_std)
diff --git a/gcc/fortran/misc.c b/gcc/fortran/misc.c
index cce599b3cbc..9b8f31f68fc 100644
--- a/gcc/fortran/misc.c
+++ b/gcc/fortran/misc.c
@@ -24,15 +24,6 @@ along with GCC; see the file COPYING3. If not see
#include "gfortran.h"
-/* Get terminal width. */
-
-int
-gfc_terminal_width (void)
-{
- return 80;
-}
-
-
/* Initialize a typespec to unknown. */
void
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index e6a4cd7046a..c390a95952e 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -80,10 +80,8 @@ along with GCC; see the file COPYING3. If not see
#define MODULE_EXTENSION ".mod"
/* Don't put any single quote (') in MOD_VERSION, if you want it to be
- recognized.
- TODO: When the version is bumped, remove the extra empty line at
- the beginning of module files. */
-#define MOD_VERSION "10"
+ recognized. */
+#define MOD_VERSION "11"
/* Structure that describes a position within a module file. */
@@ -4532,7 +4530,7 @@ check_for_ambiguous (gfc_symbol *st_sym, pointer_info *info)
module_locus locus;
symbol_attribute attr;
- if (st_sym->name == gfc_current_ns->proc_name->name)
+ if (gfc_current_ns->proc_name && st_sym->name == gfc_current_ns->proc_name->name)
{
gfc_error ("'%s' of module '%s', imported at %C, is also the name of the "
"current program unit", st_sym->name, module_name);
@@ -5567,14 +5565,9 @@ gfc_dump_module (const char *name, int dump_flag)
gfc_fatal_error ("Can't open module file '%s' for writing at %C: %s",
filename_tmp, xstrerror (errno));
- /* Write the header.
- FIXME: For backwards compatibility with the old uncompressed
- module format, write an extra empty line. When the module version
- is bumped, this can be removed. */
- gzprintf (module_fp, "GFORTRAN module version '%s' created from %s\n\n",
+ gzprintf (module_fp, "GFORTRAN module version '%s' created from %s\n",
MOD_VERSION, gfc_source_file);
-
/* Write the module itself. */
iomode = IO_OUTPUT;
module_name = gfc_get_string (name);
@@ -6364,10 +6357,10 @@ gfc_use_module (gfc_use_list *module)
read_module_to_tmpbuf ();
gzclose (module_fp);
- /* Skip the first two lines of the module, after checking that this is
+ /* Skip the first line of the module, after checking that this is
a gfortran module file. */
line = 0;
- while (line < 2)
+ while (line < 1)
{
c = module_char ();
if (c == EOF)
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index a223a2cb704..f98a21399e3 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -4270,11 +4270,11 @@ parse_block_data (void)
s = gfc_get_gsymbol (gfc_new_block->name);
if (s->defined
|| (s->type != GSYM_UNKNOWN && s->type != GSYM_BLOCK_DATA))
- gfc_global_used(s, NULL);
+ gfc_global_used (s, &gfc_new_block->declared_at);
else
{
s->type = GSYM_BLOCK_DATA;
- s->where = gfc_current_locus;
+ s->where = gfc_new_block->declared_at;
s->defined = 1;
}
}
@@ -4302,11 +4302,11 @@ parse_module (void)
s = gfc_get_gsymbol (gfc_new_block->name);
if (s->defined || (s->type != GSYM_UNKNOWN && s->type != GSYM_MODULE))
- gfc_global_used(s, NULL);
+ gfc_global_used (s, &gfc_new_block->declared_at);
else
{
s->type = GSYM_MODULE;
- s->where = gfc_current_locus;
+ s->where = gfc_new_block->declared_at;
s->defined = 1;
}
@@ -4360,7 +4360,7 @@ add_global_procedure (bool sub)
|| (s->type != GSYM_UNKNOWN
&& s->type != (sub ? GSYM_SUBROUTINE : GSYM_FUNCTION)))
{
- gfc_global_used (s, NULL);
+ gfc_global_used (s, &gfc_new_block->declared_at);
/* Silence follow-up errors. */
gfc_new_block->binding_label = NULL;
}
@@ -4368,7 +4368,7 @@ add_global_procedure (bool sub)
{
s->type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION;
s->sym_name = gfc_new_block->name;
- s->where = gfc_current_locus;
+ s->where = gfc_new_block->declared_at;
s->defined = 1;
s->ns = gfc_current_ns;
}
@@ -4385,7 +4385,7 @@ add_global_procedure (bool sub)
|| (s->type != GSYM_UNKNOWN
&& s->type != (sub ? GSYM_SUBROUTINE : GSYM_FUNCTION)))
{
- gfc_global_used (s, NULL);
+ gfc_global_used (s, &gfc_new_block->declared_at);
/* Silence follow-up errors. */
gfc_new_block->binding_label = NULL;
}
@@ -4394,7 +4394,7 @@ add_global_procedure (bool sub)
s->type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION;
s->sym_name = gfc_new_block->name;
s->binding_label = gfc_new_block->binding_label;
- s->where = gfc_current_locus;
+ s->where = gfc_new_block->declared_at;
s->defined = 1;
s->ns = gfc_current_ns;
}
@@ -4414,11 +4414,11 @@ add_global_program (void)
s = gfc_get_gsymbol (gfc_new_block->name);
if (s->defined || (s->type != GSYM_UNKNOWN && s->type != GSYM_PROGRAM))
- gfc_global_used(s, NULL);
+ gfc_global_used (s, &gfc_new_block->declared_at);
else
{
s->type = GSYM_PROGRAM;
- s->where = gfc_current_locus;
+ s->where = gfc_new_block->declared_at;
s->defined = 1;
s->ns = gfc_current_ns;
}
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index a63ee938544..b2e8fdc1bb9 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -306,6 +306,14 @@ resolve_formal_arglist (gfc_symbol *proc)
&& !resolve_procedure_interface (sym))
return;
+ if (strcmp (proc->name, sym->name) == 0)
+ {
+ gfc_error ("Self-referential argument "
+ "'%s' at %L is not allowed", sym->name,
+ &proc->declared_at);
+ return;
+ }
+
if (sym->attr.if_source != IFSRC_UNKNOWN)
resolve_formal_arglist (sym);
@@ -1451,7 +1459,7 @@ check_assumed_size_reference (gfc_symbol *sym, gfc_expr *e)
/* FIXME: The comparison "e->ref->u.ar.type == AR_FULL" is wrong.
What should it be? */
- if ((e->ref->u.ar.end[e->ref->u.ar.as->rank - 1] == NULL)
+ if (e->ref && (e->ref->u.ar.end[e->ref->u.ar.as->rank - 1] == NULL)
&& (e->ref->u.ar.as->type == AS_ASSUMED_SIZE)
&& (e->ref->u.ar.type == AR_FULL))
{
@@ -11233,10 +11241,6 @@ error:
" defined at %L, suggest also scalar one",
derived->name, &derived->declared_at);
- /* TODO: Remove this error when finalization is finished. */
- gfc_error ("Finalization at %L is not yet implemented",
- &derived->declared_at);
-
gfc_find_derived_vtab (derived);
return result;
}
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 6cb85d48311..89f26d7d976 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -300,7 +300,11 @@ gfc_conv_descriptor_token (tree desc)
gcc_assert (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE);
gcc_assert (gfc_option.coarray == GFC_FCOARRAY_LIB);
field = gfc_advance_chain (TYPE_FIELDS (type), CAF_TOKEN_FIELD);
- gcc_assert (field != NULL_TREE && TREE_TYPE (field) == prvoid_type_node);
+
+ /* Should be a restricted pointer - except in the finalization wrapper. */
+ gcc_assert (field != NULL_TREE
+ && (TREE_TYPE (field) == prvoid_type_node
+ || TREE_TYPE (field) == pvoid_type_node));
return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
desc, field, NULL_TREE);
@@ -4830,7 +4834,8 @@ static tree
gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
gfc_expr ** lower, gfc_expr ** upper, stmtblock_t * pblock,
stmtblock_t * descriptor_block, tree * overflow,
- tree expr3_elem_size, tree *nelems, gfc_expr *expr3)
+ tree expr3_elem_size, tree *nelems, gfc_expr *expr3,
+ gfc_typespec *ts)
{
tree type;
tree tmp;
@@ -5008,6 +5013,9 @@ gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
tmp = TYPE_SIZE_UNIT (tmp);
}
}
+ else if (ts->type != BT_UNKNOWN && ts->type != BT_CHARACTER)
+ /* FIXME: Properly handle characters. See PR 57456. */
+ tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (ts));
else
tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
@@ -5077,7 +5085,7 @@ gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
bool
gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg,
tree errlen, tree label_finish, tree expr3_elem_size,
- tree *nelems, gfc_expr *expr3)
+ tree *nelems, gfc_expr *expr3, gfc_typespec *ts)
{
tree tmp;
tree pointer;
@@ -5162,7 +5170,7 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg,
size = gfc_array_init_size (se->expr, ref->u.ar.as->rank,
ref->u.ar.as->corank, &offset, lower, upper,
&se->pre, &set_descriptor_block, &overflow,
- expr3_elem_size, nelems, expr3);
+ expr3_elem_size, nelems, expr3, ts);
if (dimension)
{
@@ -5222,18 +5230,6 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg,
gfc_add_expr_to_block (&se->pre, tmp);
- if (expr->ts.type == BT_CLASS)
- {
- tmp = build_int_cst (unsigned_char_type_node, 0);
- /* With class objects, it is best to play safe and null the
- memory because we cannot know if dynamic types have allocatable
- components or not. */
- tmp = build_call_expr_loc (input_location,
- builtin_decl_explicit (BUILT_IN_MEMSET),
- 3, pointer, tmp, size);
- gfc_add_expr_to_block (&se->pre, tmp);
- }
-
/* Update the array descriptors. */
if (dimension)
gfc_conv_descriptor_offset_set (&set_descriptor_block, se->expr, offset);
@@ -7251,7 +7247,7 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, bool g77,
/* Generate code to deallocate an array, if it is allocated. */
tree
-gfc_trans_dealloc_allocated (tree descriptor, bool coarray)
+gfc_trans_dealloc_allocated (tree descriptor, bool coarray, gfc_expr *expr)
{
tree tmp;
tree var;
@@ -7267,7 +7263,7 @@ gfc_trans_dealloc_allocated (tree descriptor, bool coarray)
are already deallocated are ignored. */
tmp = gfc_deallocate_with_status (coarray ? descriptor : var, NULL_TREE,
NULL_TREE, NULL_TREE, NULL_TREE, true,
- NULL, coarray);
+ expr, coarray);
gfc_add_expr_to_block (&block, tmp);
/* Zero the data pointer. */
@@ -7556,7 +7552,7 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
{
comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
decl, cdecl, NULL_TREE);
- tmp = gfc_trans_dealloc_allocated (comp, c->attr.codimension);
+ tmp = gfc_trans_dealloc_allocated (comp, c->attr.codimension, NULL);
gfc_add_expr_to_block (&tmpblock, tmp);
}
else if (c->attr.allocatable)
@@ -7588,7 +7584,7 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (comp)))
tmp = gfc_trans_dealloc_allocated (comp,
- CLASS_DATA (c)->attr.codimension);
+ CLASS_DATA (c)->attr.codimension, NULL);
else
{
tmp = gfc_deallocate_scalar_with_status (comp, NULL_TREE, true, NULL,
@@ -7699,6 +7695,10 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
{
nelems = gfc_conv_descriptor_size (src_data,
CLASS_DATA (c)->as->rank);
+ size = fold_build2_loc (input_location, MULT_EXPR,
+ size_type_node, size,
+ fold_convert (size_type_node,
+ nelems));
src_data = gfc_conv_descriptor_data_get (src_data);
dst_data = gfc_conv_descriptor_data_get (dst_data);
}
@@ -7707,11 +7707,8 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
gfc_init_block (&tmpblock);
- /* We need to use CALLOC as _copy might try to free allocatable
- components of the destination. */
- ftn_tree = builtin_decl_explicit (BUILT_IN_CALLOC);
- tmp = build_call_expr_loc (input_location, ftn_tree, 2, nelems,
- size);
+ ftn_tree = builtin_decl_explicit (BUILT_IN_MALLOC);
+ tmp = build_call_expr_loc (input_location, ftn_tree, 1, size);
gfc_add_modify (&tmpblock, dst_data,
fold_convert (TREE_TYPE (dst_data), tmp));
@@ -8299,7 +8296,7 @@ gfc_trans_deferred_array (gfc_symbol * sym, gfc_wrapped_block * block)
stmtblock_t cleanup;
locus loc;
int rank;
- bool sym_has_alloc_comp;
+ bool sym_has_alloc_comp, has_finalizer;
sym_has_alloc_comp = (sym->ts.type == BT_DERIVED
|| sym->ts.type == BT_CLASS)
@@ -8386,8 +8383,12 @@ gfc_trans_deferred_array (gfc_symbol * sym, gfc_wrapped_block * block)
/* Allocatable arrays need to be freed when they go out of scope.
The allocatable components of pointers must not be touched. */
- if (sym_has_alloc_comp && !(sym->attr.function || sym->attr.result)
- && !sym->attr.pointer && !sym->attr.save)
+ has_finalizer = sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED
+ ? gfc_is_finalizable (sym->ts.u.derived, NULL) : false;
+ if ((!sym->attr.allocatable || !has_finalizer)
+ && sym_has_alloc_comp && !(sym->attr.function || sym->attr.result)
+ && !sym->attr.pointer && !sym->attr.save
+ && !sym->ns->proc_name->attr.is_main_program)
{
int rank;
rank = sym->as ? sym->as->rank : 0;
@@ -8396,10 +8397,13 @@ gfc_trans_deferred_array (gfc_symbol * sym, gfc_wrapped_block * block)
}
if (sym->attr.allocatable && (sym->attr.dimension || sym->attr.codimension)
- && !sym->attr.save && !sym->attr.result)
+ && !sym->attr.save && !sym->attr.result
+ && !sym->ns->proc_name->attr.is_main_program)
{
tmp = gfc_trans_dealloc_allocated (sym->backend_decl,
- sym->attr.codimension);
+ sym->attr.codimension,
+ has_finalizer
+ ? gfc_lval_expr_from_sym (sym) : NULL);
gfc_add_expr_to_block (&cleanup, tmp);
}
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 6f44d797fad..8d9e46187c5 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -24,7 +24,7 @@ tree gfc_array_deallocate (tree, tree, tree, tree, tree, gfc_expr*);
/* Generate code to initialize and allocate an array. Statements are added to
se, which should contain an expression for the array descriptor. */
bool gfc_array_allocate (gfc_se *, gfc_expr *, tree, tree, tree, tree,
- tree, tree *, gfc_expr *);
+ tree, tree *, gfc_expr *, gfc_typespec *);
/* Allow the bounds of a loop to be set from a callee's array spec. */
void gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping *,
@@ -42,7 +42,7 @@ void gfc_trans_dummy_array_bias (gfc_symbol *, tree, gfc_wrapped_block *);
/* Generate entry and exit code for g77 calling convention arrays. */
void gfc_trans_g77_array (gfc_symbol *, gfc_wrapped_block *);
/* Generate code to deallocate an array, if it is allocated. */
-tree gfc_trans_dealloc_allocated (tree, bool);
+tree gfc_trans_dealloc_allocated (tree, bool, gfc_expr *);
tree gfc_duplicate_allocatable (tree dest, tree src, tree type, int rank);
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 100ec18be51..b0e3ffc21bd 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -3872,7 +3872,8 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
/* Deallocate when leaving the scope. Nullifying is not
needed. */
- if (!sym->attr.result && !sym->attr.dummy)
+ if (!sym->attr.result && !sym->attr.dummy
+ && !sym->ns->proc_name->attr.is_main_program)
{
if (sym->ts.type == BT_CLASS
&& CLASS_DATA (sym)->attr.codimension)
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index de851a26c03..9d073457db1 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -214,6 +214,55 @@ gfc_vtable_final_get (tree decl)
#undef VTABLE_FINAL_FIELD
+/* Reset the vptr to the declared type, e.g. after deallocation. */
+
+void
+gfc_reset_vptr (stmtblock_t *block, gfc_expr *e)
+{
+ gfc_expr *rhs, *lhs = gfc_copy_expr (e);
+ gfc_symbol *vtab;
+ tree tmp;
+ gfc_ref *ref;
+
+ /* If we have a class array, we need go back to the class
+ container. */
+ if (lhs->ref && lhs->ref->next && !lhs->ref->next->next
+ && lhs->ref->next->type == REF_ARRAY
+ && lhs->ref->next->u.ar.type == AR_FULL
+ && lhs->ref->type == REF_COMPONENT
+ && strcmp (lhs->ref->u.c.component->name, "_data") == 0)
+ {
+ gfc_free_ref_list (lhs->ref);
+ lhs->ref = NULL;
+ }
+ else
+ for (ref = lhs->ref; ref; ref = ref->next)
+ if (ref->next && ref->next->next && !ref->next->next->next
+ && ref->next->next->type == REF_ARRAY
+ && ref->next->next->u.ar.type == AR_FULL
+ && ref->next->type == REF_COMPONENT
+ && strcmp (ref->next->u.c.component->name, "_data") == 0)
+ {
+ gfc_free_ref_list (ref->next);
+ ref->next = NULL;
+ }
+
+ gfc_add_vptr_component (lhs);
+
+ if (UNLIMITED_POLY (e))
+ rhs = gfc_get_null_expr (NULL);
+ else
+ {
+ vtab = gfc_find_derived_vtab (e->ts.u.derived);
+ rhs = gfc_lval_expr_from_sym (vtab);
+ }
+ tmp = gfc_trans_pointer_assignment (lhs, rhs);
+ gfc_add_expr_to_block (block, tmp);
+ gfc_free_expr (lhs);
+ gfc_free_expr (rhs);
+}
+
+
/* Obtain the vptr of the last class reference in an expression.
Return NULL_TREE if no class reference is found. */
@@ -4225,10 +4274,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
if (e->ts.type == BT_CLASS)
ptr = gfc_class_data_get (ptr);
- tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
- NULL_TREE, NULL_TREE,
- NULL_TREE, true, NULL,
- false);
+ tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE,
+ true, e, e->ts);
gfc_add_expr_to_block (&block, tmp);
tmp = fold_build2_loc (input_location, MODIFY_EXPR,
void_type_node, ptr,
@@ -4320,6 +4367,49 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
{
/* Pass a class array. */
gfc_conv_expr_descriptor (&parmse, e);
+
+ /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
+ allocated on entry, it must be deallocated. */
+ if (fsym->attr.intent == INTENT_OUT
+ && CLASS_DATA (fsym)->attr.allocatable)
+ {
+ stmtblock_t block;
+ tree ptr;
+
+ gfc_init_block (&block);
+ ptr = parmse.expr;
+ ptr = gfc_class_data_get (ptr);
+
+ tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
+ NULL_TREE, NULL_TREE,
+ NULL_TREE, true, e,
+ false);
+ gfc_add_expr_to_block (&block, tmp);
+ tmp = fold_build2_loc (input_location, MODIFY_EXPR,
+ void_type_node, ptr,
+ null_pointer_node);
+ gfc_add_expr_to_block (&block, tmp);
+ gfc_reset_vptr (&block, e);
+
+ if (fsym->attr.optional
+ && e->expr_type == EXPR_VARIABLE
+ && (!e->ref
+ || (e->ref->type == REF_ARRAY
+ && !e->ref->u.ar.type != AR_FULL))
+ && e->symtree->n.sym->attr.optional)
+ {
+ tmp = fold_build3_loc (input_location, COND_EXPR,
+ void_type_node,
+ gfc_conv_expr_present (e->symtree->n.sym),
+ gfc_finish_block (&block),
+ build_empty_stmt (input_location));
+ }
+ else
+ tmp = gfc_finish_block (&block);
+
+ gfc_add_expr_to_block (&se->pre, tmp);
+ }
+
/* The conversion does not repackage the reference to a class
array - _data descriptor. */
gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
@@ -4419,7 +4509,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
{
tmp = build_fold_indirect_ref_loc (input_location,
parmse.expr);
- tmp = gfc_trans_dealloc_allocated (tmp, false);
+ tmp = gfc_trans_dealloc_allocated (tmp, false, e);
if (fsym->attr.optional
&& e->expr_type == EXPR_VARIABLE
&& e->symtree->n.sym->attr.optional)
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 882927e639a..2765561e889 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -325,7 +325,7 @@ gfc_omp_clause_dtor (tree clause ATTRIBUTE_UNUSED, tree decl)
/* Allocatable arrays in FIRSTPRIVATE/LASTPRIVATE etc. clauses need
to be deallocated if they were allocated. */
- return gfc_trans_dealloc_allocated (decl, false);
+ return gfc_trans_dealloc_allocated (decl, false, NULL);
}
@@ -707,7 +707,8 @@ gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where)
gfc_start_block (&block);
gfc_add_expr_to_block (&block, gfc_trans_assignment (e3, e4, false,
true));
- gfc_add_expr_to_block (&block, gfc_trans_dealloc_allocated (decl, false));
+ gfc_add_expr_to_block (&block, gfc_trans_dealloc_allocated (decl, false,
+ NULL));
stmt = gfc_finish_block (&block);
}
else
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 1b65f2ca78b..e2d0110ba96 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -4925,7 +4925,7 @@ gfc_trans_allocate (gfc_code * code)
nelems = NULL_TREE;
if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen, label_finish,
- memsz, &nelems, code->expr3))
+ memsz, &nelems, code->expr3, &code->ext.alloc.ts))
{
bool unlimited_char;
@@ -5071,16 +5071,6 @@ gfc_trans_allocate (gfc_code * code)
tmp = gfc_nullify_alloc_comp (expr->ts.u.derived, tmp, 0);
gfc_add_expr_to_block (&se.pre, tmp);
}
- else if (al->expr->ts.type == BT_CLASS)
- {
- /* With class objects, it is best to play safe and null the
- memory because we cannot know if dynamic types have allocatable
- components or not. */
- tmp = build_call_expr_loc (input_location,
- builtin_decl_explicit (BUILT_IN_MEMSET),
- 3, se.expr, integer_zero_node, memsz);
- gfc_add_expr_to_block (&se.pre, tmp);
- }
}
gfc_add_block_to_block (&block, &se.pre);
@@ -5349,30 +5339,6 @@ gfc_trans_allocate (gfc_code * code)
}
-/* Reset the vptr after deallocation. */
-
-static void
-reset_vptr (stmtblock_t *block, gfc_expr *e)
-{
- gfc_expr *rhs, *lhs = gfc_copy_expr (e);
- gfc_symbol *vtab;
- tree tmp;
-
- if (UNLIMITED_POLY (e))
- rhs = gfc_get_null_expr (NULL);
- else
- {
- vtab = gfc_find_derived_vtab (e->ts.u.derived);
- rhs = gfc_lval_expr_from_sym (vtab);
- }
- gfc_add_vptr_component (lhs);
- tmp = gfc_trans_pointer_assignment (lhs, rhs);
- gfc_add_expr_to_block (block, tmp);
- gfc_free_expr (lhs);
- gfc_free_expr (rhs);
-}
-
-
/* Translate a DEALLOCATE statement. */
tree
@@ -5432,7 +5398,8 @@ gfc_trans_deallocate (gfc_code *code)
if (expr->rank || gfc_is_coarray (expr))
{
- if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->attr.alloc_comp)
+ if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->attr.alloc_comp
+ && !gfc_is_finalizable (expr->ts.u.derived, NULL))
{
gfc_ref *ref;
gfc_ref *last = NULL;
@@ -5453,8 +5420,8 @@ gfc_trans_deallocate (gfc_code *code)
tmp = gfc_array_deallocate (se.expr, pstat, errmsg, errlen,
label_finish, expr);
gfc_add_expr_to_block (&se.pre, tmp);
- if (UNLIMITED_POLY (al->expr))
- reset_vptr (&se.pre, al->expr);
+ if (al->expr->ts.type == BT_CLASS)
+ gfc_reset_vptr (&se.pre, al->expr);
}
else
{
@@ -5469,7 +5436,7 @@ gfc_trans_deallocate (gfc_code *code)
gfc_add_expr_to_block (&se.pre, tmp);
if (al->expr->ts.type == BT_CLASS)
- reset_vptr (&se.pre, al->expr);
+ gfc_reset_vptr (&se.pre, al->expr);
}
if (code->expr1)
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index 8211573e1b3..a1ea3008ff7 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -838,6 +838,223 @@ gfc_call_free (tree var)
}
+/* Build a call to a FINAL procedure, which finalizes "var". */
+
+static tree
+gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var,
+ bool fini_coarray, gfc_expr *class_size)
+{
+ stmtblock_t block;
+ gfc_se se;
+ tree final_fndecl, array, size, tmp;
+ symbol_attribute attr;
+
+ gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE);
+ gcc_assert (var);
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr (&se, final_wrapper);
+ final_fndecl = se.expr;
+ if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
+ final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
+
+ if (ts.type == BT_DERIVED)
+ {
+ tree elem_size;
+
+ gcc_assert (!class_size);
+ elem_size = gfc_typenode_for_spec (&ts);
+ elem_size = TYPE_SIZE_UNIT (elem_size);
+ size = fold_convert (gfc_array_index_type, elem_size);
+
+ gfc_init_se (&se, NULL);
+ se.want_pointer = 1;
+ if (var->rank)
+ {
+ se.descriptor_only = 1;
+ gfc_conv_expr_descriptor (&se, var);
+ array = se.expr;
+ }
+ else
+ {
+ gfc_conv_expr (&se, var);
+ gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE);
+ array = se.expr;
+
+ /* No copy back needed, hence set attr's allocatable/pointer
+ to zero. */
+ gfc_clear_attr (&attr);
+ gfc_init_se (&se, NULL);
+ array = gfc_conv_scalar_to_descriptor (&se, array, attr);
+ gcc_assert (se.post.head == NULL_TREE);
+ }
+ }
+ else
+ {
+ gfc_expr *array_expr;
+ gcc_assert (class_size);
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr (&se, class_size);
+ gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE);
+ size = se.expr;
+
+ array_expr = gfc_copy_expr (var);
+ gfc_init_se (&se, NULL);
+ se.want_pointer = 1;
+ if (array_expr->rank)
+ {
+ gfc_add_class_array_ref (array_expr);
+ se.descriptor_only = 1;
+ gfc_conv_expr_descriptor (&se, array_expr);
+ array = se.expr;
+ }
+ else
+ {
+ gfc_add_data_component (array_expr);
+ gfc_conv_expr (&se, array_expr);
+ gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE);
+ array = se.expr;
+ if (TREE_CODE (array) == ADDR_EXPR
+ && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (array, 0))))
+ tmp = TREE_OPERAND (array, 0);
+
+ if (!gfc_is_coarray (array_expr))
+ {
+ /* No copy back needed, hence set attr's allocatable/pointer
+ to zero. */
+ gfc_clear_attr (&attr);
+ gfc_init_se (&se, NULL);
+ array = gfc_conv_scalar_to_descriptor (&se, array, attr);
+ }
+ gcc_assert (se.post.head == NULL_TREE);
+ }
+ gfc_free_expr (array_expr);
+ }
+
+ if (!POINTER_TYPE_P (TREE_TYPE (array)))
+ array = gfc_build_addr_expr (NULL, array);
+
+ gfc_start_block (&block);
+ gfc_add_block_to_block (&block, &se.pre);
+ tmp = build_call_expr_loc (input_location,
+ final_fndecl, 3, array,
+ size, fini_coarray ? boolean_true_node
+ : boolean_false_node);
+ gfc_add_block_to_block (&block, &se.post);
+ gfc_add_expr_to_block (&block, tmp);
+ return gfc_finish_block (&block);
+}
+
+
+/* Add a call to the finalizer, using the passed *expr. Returns
+ true when a finalizer call has been inserted. */
+
+bool
+gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2)
+{
+ tree tmp;
+ gfc_ref *ref;
+ gfc_expr *expr;
+ gfc_expr *final_expr = NULL;
+ gfc_expr *elem_size = NULL;
+ bool has_finalizer = false;
+
+ if (!expr2 || (expr2->ts.type != BT_DERIVED && expr2->ts.type != BT_CLASS))
+ return false;
+
+ if (expr2->ts.type == BT_DERIVED)
+ {
+ gfc_is_finalizable (expr2->ts.u.derived, &final_expr);
+ if (!final_expr)
+ return false;
+ }
+
+ /* If we have a class array, we need go back to the class
+ container. */
+ expr = gfc_copy_expr (expr2);
+
+ if (expr->ref && expr->ref->next && !expr->ref->next->next
+ && expr->ref->next->type == REF_ARRAY
+ && expr->ref->type == REF_COMPONENT
+ && strcmp (expr->ref->u.c.component->name, "_data") == 0)
+ {
+ gfc_free_ref_list (expr->ref);
+ expr->ref = NULL;
+ }
+ else
+ for (ref = expr->ref; ref; ref = ref->next)
+ if (ref->next && ref->next->next && !ref->next->next->next
+ && ref->next->next->type == REF_ARRAY
+ && ref->next->type == REF_COMPONENT
+ && strcmp (ref->next->u.c.component->name, "_data") == 0)
+ {
+ gfc_free_ref_list (ref->next);
+ ref->next = NULL;
+ }
+
+ if (expr->ts.type == BT_CLASS)
+ {
+ has_finalizer = gfc_is_finalizable (expr->ts.u.derived, NULL);
+
+ if (!expr2->rank && !expr2->ref && CLASS_DATA (expr2->symtree->n.sym)->as)
+ expr->rank = CLASS_DATA (expr2->symtree->n.sym)->as->rank;
+
+ final_expr = gfc_copy_expr (expr);
+ gfc_add_vptr_component (final_expr);
+ gfc_add_component_ref (final_expr, "_final");
+
+ elem_size = gfc_copy_expr (expr);
+ gfc_add_vptr_component (elem_size);
+ gfc_add_component_ref (elem_size, "_size");
+ }
+
+ gcc_assert (final_expr->expr_type == EXPR_VARIABLE);
+
+ tmp = gfc_build_final_call (expr->ts, final_expr, expr,
+ false, elem_size);
+
+ if (expr->ts.type == BT_CLASS && !has_finalizer)
+ {
+ tree cond;
+ gfc_se se;
+
+ gfc_init_se (&se, NULL);
+ se.want_pointer = 1;
+ gfc_conv_expr (&se, final_expr);
+ cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
+ se.expr, build_int_cst (TREE_TYPE (se.expr), 0));
+
+ /* For CLASS(*) not only sym->_vtab->_final can be NULL
+ but already sym->_vtab itself. */
+ if (UNLIMITED_POLY (expr))
+ {
+ tree cond2;
+ gfc_expr *vptr_expr;
+
+ vptr_expr = gfc_copy_expr (expr);
+ gfc_add_vptr_component (vptr_expr);
+
+ gfc_init_se (&se, NULL);
+ se.want_pointer = 1;
+ gfc_conv_expr (&se, vptr_expr);
+ gfc_free_expr (vptr_expr);
+
+ cond2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
+ se.expr,
+ build_int_cst (TREE_TYPE (se.expr), 0));
+ cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
+ boolean_type_node, cond2, cond);
+ }
+
+ tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
+ cond, tmp, build_empty_stmt (input_location));
+ }
+
+ gfc_add_expr_to_block (block, tmp);
+
+ return true;
+}
+
/* User-deallocate; we emit the code directly from the front-end, and the
logic is the same as the previous library function:
@@ -930,6 +1147,7 @@ gfc_deallocate_with_status (tree pointer, tree status, tree errmsg,
/* When POINTER is not NULL, we free it. */
gfc_start_block (&non_null);
+ gfc_add_finalizer_call (&non_null, expr);
if (!coarray || gfc_option.coarray != GFC_FCOARRAY_LIB)
{
tmp = build_call_expr_loc (input_location,
@@ -1022,125 +1240,6 @@ gfc_deallocate_with_status (tree pointer, tree status, tree errmsg,
}
-/* Build a call to a FINAL procedure, which finalizes "var". */
-
-tree
-gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var,
- bool fini_coarray, gfc_expr *class_size)
-{
- stmtblock_t block;
- gfc_se se;
- tree final_fndecl, array, size, tmp;
- symbol_attribute attr;
-
- gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE);
- gcc_assert (var);
-
- gfc_init_se (&se, NULL);
- gfc_conv_expr (&se, final_wrapper);
- final_fndecl = se.expr;
- if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
- final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
-
- attr = gfc_expr_attr (var);
-
- if (ts.type == BT_DERIVED)
- {
- tree elem_size;
-
- gcc_assert (!class_size);
- elem_size = gfc_typenode_for_spec (&ts);
- elem_size = TYPE_SIZE_UNIT (elem_size);
- size = fold_convert (gfc_array_index_type, elem_size);
-
- gfc_init_se (&se, NULL);
- se.want_pointer = 1;
- if (var->rank || attr.dimension
- || (attr.codimension && attr.allocatable
- && gfc_option.coarray == GFC_FCOARRAY_LIB))
- {
- if (var->rank == 0)
- se.want_coarray = 1;
- se.descriptor_only = 1;
- gfc_conv_expr_descriptor (&se, var);
- array = se.expr;
- if (!POINTER_TYPE_P (TREE_TYPE (array)))
- array = gfc_build_addr_expr (NULL, array);
- }
- else
- {
- gfc_clear_attr (&attr);
- gfc_conv_expr (&se, var);
- gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE);
- array = se.expr;
- if (TREE_CODE (array) == ADDR_EXPR
- && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (array, 0))))
- tmp = TREE_OPERAND (array, 0);
-
- gfc_init_se (&se, NULL);
- array = gfc_conv_scalar_to_descriptor (&se, array, attr);
- array = gfc_build_addr_expr (NULL, array);
- gcc_assert (se.post.head == NULL_TREE);
- }
- }
- else
- {
- gfc_expr *array_expr;
- gcc_assert (class_size);
- gfc_init_se (&se, NULL);
- gfc_conv_expr (&se, class_size);
- gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE);
- size = se.expr;
-
- array_expr = gfc_copy_expr (var);
- gfc_init_se (&se, NULL);
- se.want_pointer = 1;
- if (array_expr->rank || attr.dimension
- || (attr.codimension && attr.allocatable
- && gfc_option.coarray == GFC_FCOARRAY_LIB))
- {
- gfc_add_class_array_ref (array_expr);
- if (array_expr->rank == 0)
- se.want_coarray = 1;
- se.descriptor_only = 1;
- gfc_conv_expr_descriptor (&se, array_expr);
- array = se.expr;
- if (! POINTER_TYPE_P (TREE_TYPE (array)))
- array = gfc_build_addr_expr (NULL, array);
- }
- else
- {
- gfc_clear_attr (&attr);
- gfc_add_data_component (array_expr);
- gfc_conv_expr (&se, array_expr);
- gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE);
- array = se.expr;
- if (TREE_CODE (array) == ADDR_EXPR
- && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (array, 0))))
- tmp = TREE_OPERAND (array, 0);
-
- /* attr: Argument is neither a pointer/allocatable,
- i.e. no copy back needed */
- gfc_init_se (&se, NULL);
- array = gfc_conv_scalar_to_descriptor (&se, array, attr);
- array = gfc_build_addr_expr (NULL, array);
- gcc_assert (se.post.head == NULL_TREE);
- }
- gfc_free_expr (array_expr);
- }
-
- gfc_start_block (&block);
- gfc_add_block_to_block (&block, &se.pre);
- tmp = build_call_expr_loc (input_location,
- final_fndecl, 3, array,
- size, fini_coarray ? boolean_true_node
- : boolean_false_node);
- gfc_add_block_to_block (&block, &se.post);
- gfc_add_expr_to_block (&block, tmp);
- return gfc_finish_block (&block);
-}
-
-
/* Generate code for deallocation of allocatable scalars (variables or
components). Before the object itself is freed, any allocatable
subcomponents are being deallocated. */
@@ -1151,6 +1250,7 @@ gfc_deallocate_scalar_with_status (tree pointer, tree status, bool can_fail,
{
stmtblock_t null, non_null;
tree cond, tmp, error;
+ bool finalizable;
cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, pointer,
build_int_cst (TREE_TYPE (pointer), 0));
@@ -1195,20 +1295,13 @@ gfc_deallocate_scalar_with_status (tree pointer, tree status, bool can_fail,
gfc_start_block (&non_null);
/* Free allocatable components. */
- if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
+ finalizable = gfc_add_finalizer_call (&non_null, expr);
+ if (!finalizable && ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
{
tmp = build_fold_indirect_ref_loc (input_location, pointer);
tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0);
gfc_add_expr_to_block (&non_null, tmp);
}
- else if (ts.type == BT_CLASS
- && ts.u.derived->components->ts.u.derived->attr.alloc_comp)
- {
- tmp = build_fold_indirect_ref_loc (input_location, pointer);
- tmp = gfc_deallocate_alloc_comp (ts.u.derived->components->ts.u.derived,
- tmp, 0);
- gfc_add_expr_to_block (&non_null, tmp);
- }
tmp = build_call_expr_loc (input_location,
builtin_decl_explicit (BUILT_IN_FREE), 1,
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index ad6a1053a42..06cb63d8132 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -341,6 +341,7 @@ gfc_wrapped_block;
/* Class API functions. */
tree gfc_class_data_get (tree);
tree gfc_class_vptr_get (tree);
+void gfc_reset_vptr (stmtblock_t *, gfc_expr *);
tree gfc_class_set_static_fields (tree, tree, tree);
tree gfc_vtable_hash_get (tree);
tree gfc_vtable_size_get (tree);
@@ -351,8 +352,7 @@ tree gfc_vtable_final_get (tree);
tree gfc_get_vptr_from_expr (tree);
tree gfc_get_class_array_ref (tree, tree);
tree gfc_copy_class_to_class (tree, tree, tree);
-tree gfc_build_final_call (gfc_typespec, gfc_expr *, gfc_expr *, bool,
- gfc_expr *);
+bool gfc_add_finalizer_call (stmtblock_t *, gfc_expr *);
void gfc_conv_derived_to_class (gfc_se *, gfc_expr *, gfc_typespec, tree, bool,
bool);
void gfc_conv_class_to_class (gfc_se *, gfc_expr *, gfc_typespec, bool, bool,
diff --git a/gcc/gdbinit.in b/gcc/gdbinit.in
index 4a84700d167..503ef24e301 100644
--- a/gcc/gdbinit.in
+++ b/gcc/gdbinit.in
@@ -184,6 +184,7 @@ end
# Define some macros helpful to gdb when it is expanding macros.
macro define __FILE__ "gdb"
macro define __LINE__ 1
+macro define __FUNCTION__ "gdb"
macro define __null 0
# Gracefully handle aborts in functions used from gdb.
diff --git a/gcc/gensupport.c b/gcc/gensupport.c
index 1092bd8111e..19b92408dc4 100644
--- a/gcc/gensupport.c
+++ b/gcc/gensupport.c
@@ -1717,6 +1717,21 @@ process_one_cond_exec (struct queue_elem *ce_elem)
XVECEXP (insn, 1, 0) = pattern;
}
+ if (XVEC (ce_elem->data, 3) != NULL)
+ {
+ rtvec attributes = rtvec_alloc (XVECLEN (insn, 4)
+ + XVECLEN (ce_elem->data, 3));
+ int i = 0;
+ int j = 0;
+ for (i = 0; i < XVECLEN (insn, 4); i++)
+ RTVEC_ELT (attributes, i) = XVECEXP (insn, 4, i);
+
+ for (j = 0; j < XVECLEN (ce_elem->data, 3); j++, i++)
+ RTVEC_ELT (attributes, i) = XVECEXP (ce_elem->data, 3, j);
+
+ XVEC (insn, 4) = attributes;
+ }
+
XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
alternatives, max_operand);
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 1de281a97d5..181d28d1b61 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -114,7 +114,7 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
The second is important when devirtualization happens during final
compilation stage when making a new reference no longer makes callee
to be compiled. */
- if (!node || !node->analyzed || node->global.inlined_to)
+ if (!node || !node->symbol.definition || node->global.inlined_to)
{
gcc_checking_assert (!TREE_ASM_WRITTEN (decl));
return false;
@@ -123,7 +123,7 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
else if (TREE_CODE (decl) == VAR_DECL)
{
vnode = varpool_get_node (decl);
- if (!vnode || !vnode->analyzed)
+ if (!vnode || !vnode->symbol.definition)
{
gcc_checking_assert (!TREE_ASM_WRITTEN (decl));
return false;
diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
index dcd31809ab6..9a53bf7c339 100644
--- a/gcc/gimple-ssa-strength-reduction.c
+++ b/gcc/gimple-ssa-strength-reduction.c
@@ -3361,7 +3361,6 @@ analyze_candidates_and_replace (void)
less expensive to calculate than the replaced statements. */
else
{
- int length;
enum machine_mode mode;
bool speed;
@@ -3372,14 +3371,11 @@ analyze_candidates_and_replace (void)
/* If all candidates have already been replaced under other
interpretations, nothing remains to be done. */
- length = count_candidates (c);
- if (!length)
+ if (!count_candidates (c))
continue;
- if (length > MAX_INCR_VEC_LEN)
- length = MAX_INCR_VEC_LEN;
/* Construct an array of increments for this candidate chain. */
- incr_vec = XNEWVEC (incr_info, length);
+ incr_vec = XNEWVEC (incr_info, MAX_INCR_VEC_LEN);
incr_vec_len = 0;
record_increments (c);
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 4bb1754d2b5..af4e94862d3 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -440,14 +440,14 @@ determine_versionability (struct cgraph_node *node)
/* There are a number of generic reasons functions cannot be versioned. We
also cannot remove parameters if there are type attributes such as fnspec
present. */
- if (node->alias || node->thunk.thunk_p)
+ if (node->symbol.alias || node->thunk.thunk_p)
reason = "alias or thunk";
else if (!node->local.versionable)
reason = "not a tree_versionable_function";
else if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
reason = "insufficient body availability";
- if (reason && dump_file && !node->alias && !node->thunk.thunk_p)
+ if (reason && dump_file && !node->symbol.alias && !node->thunk.thunk_p)
fprintf (dump_file, "Function %s/%i is not versionable, reason: %s.\n",
cgraph_node_name (node), node->symbol.order, reason);
@@ -727,7 +727,7 @@ initialize_node_lattices (struct cgraph_node *node)
set_all_contains_variable (plats);
}
if (dump_file && (dump_flags & TDF_DETAILS)
- && !node->alias && !node->thunk.thunk_p)
+ && !node->symbol.alias && !node->thunk.thunk_p)
fprintf (dump_file, "Marking all lattices of %s/%i as %s\n",
cgraph_node_name (node), node->symbol.order,
disable ? "BOTTOM" : "VARIABLE");
@@ -1418,7 +1418,7 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
int i, args_count, parms_count;
callee = cgraph_function_node (cs->callee, &availability);
- if (!callee->analyzed)
+ if (!callee->symbol.definition)
return false;
gcc_checking_assert (cgraph_function_with_gimple_body_p (callee));
callee_info = IPA_NODE_REF (callee);
@@ -1431,8 +1431,8 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
parameter. However, we might need to uncover a thunk from below a series
of aliases first. */
alias_or_thunk = cs->callee;
- while (alias_or_thunk->alias)
- alias_or_thunk = cgraph_alias_aliased_node (alias_or_thunk);
+ while (alias_or_thunk->symbol.alias)
+ alias_or_thunk = cgraph_alias_target (alias_or_thunk);
if (alias_or_thunk->thunk.thunk_p)
{
ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
@@ -1601,7 +1601,7 @@ devirtualization_time_bonus (struct cgraph_node *node,
/* Only bare minimum benefit for clearly un-inlineable targets. */
res += 1;
callee = cgraph_get_node (target);
- if (!callee || !callee->analyzed)
+ if (!callee || !callee->symbol.definition)
continue;
isummary = inline_summary (callee);
if (!isummary->inlinable)
@@ -2231,9 +2231,10 @@ ipcp_propagate_stage (struct topo_info *topo)
ipa_get_param_count (info));
initialize_node_lattices (node);
}
+ if (node->symbol.definition && !node->symbol.alias)
+ overall_size += inline_summary (node)->self_size;
if (node->count > max_count)
max_count = node->count;
- overall_size += inline_summary (node)->self_size;
}
max_new_size = overall_size;
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index c6f127ebbd2..a25f51755e3 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -1351,7 +1351,7 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
void
dump_inline_summary (FILE *f, struct cgraph_node *node)
{
- if (node->analyzed)
+ if (node->symbol.definition)
{
struct inline_summary *s = inline_summary (node);
size_time_entry *e;
@@ -1427,7 +1427,7 @@ initialize_inline_failed (struct cgraph_edge *e)
if (e->indirect_unknown_callee)
e->inline_failed = CIF_INDIRECT_UNKNOWN_CALL;
- else if (!callee->analyzed)
+ else if (!callee->symbol.definition)
e->inline_failed = CIF_BODY_NOT_AVAILABLE;
else if (callee->local.redefined_extern_inline)
e->inline_failed = CIF_REDEFINED_EXTERN_INLINE;
@@ -2765,7 +2765,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
gcc_checking_assert (*size >= 0);
callee = cgraph_get_node (target);
- if (!callee || !callee->analyzed)
+ if (!callee || !callee->symbol.definition)
return false;
isummary = inline_summary (callee);
return isummary->inlinable;
@@ -3683,7 +3683,7 @@ inline_generate_summary (void)
inline_free_summary ();
FOR_EACH_DEFINED_FUNCTION (node)
- if (!node->alias)
+ if (!node->symbol.alias)
inline_analyze_function (node);
}
@@ -3917,7 +3917,7 @@ inline_write_summary (void)
{
symtab_node snode = lto_symtab_encoder_deref (encoder, i);
cgraph_node *cnode = dyn_cast <cgraph_node> (snode);
- if (cnode && cnode->analyzed)
+ if (cnode && cnode->symbol.definition && !cnode->symbol.alias)
count++;
}
streamer_write_uhwi (ob, count);
@@ -3926,7 +3926,7 @@ inline_write_summary (void)
{
symtab_node snode = lto_symtab_encoder_deref (encoder, i);
cgraph_node *cnode = dyn_cast <cgraph_node> (snode);
- if (cnode && (node = cnode)->analyzed)
+ if (cnode && (node = cnode)->symbol.definition && !node->symbol.alias)
{
struct inline_summary *info = inline_summary (node);
struct bitpack_d bp;
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index cb819d7cbb2..9e131a4aa0e 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -153,7 +153,7 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
cgraph_remove_unreachable_functions gets rid of them. */
gcc_assert (!e->callee->global.inlined_to);
symtab_dissolve_same_comdat_group_list ((symtab_node) e->callee);
- if (e->callee->analyzed && !DECL_EXTERNAL (e->callee->symbol.decl))
+ if (e->callee->symbol.definition && !DECL_EXTERNAL (e->callee->symbol.decl))
{
if (overall_size)
*overall_size -= inline_summary (e->callee)->size;
@@ -236,7 +236,7 @@ inline_call (struct cgraph_edge *e, bool update_original,
if (!alias->callers
&& can_remove_node_now_p (alias, e))
{
- next_alias = cgraph_alias_aliased_node (alias);
+ next_alias = cgraph_alias_target (alias);
cgraph_remove_node (alias);
alias = next_alias;
}
@@ -381,7 +381,7 @@ static bool
preserve_function_body_p (struct cgraph_node *node)
{
gcc_assert (cgraph_global_info_ready);
- gcc_assert (!node->alias && !node->thunk.thunk_p);
+ gcc_assert (!node->symbol.alias && !node->thunk.thunk_p);
/* Look if there is any clone around. */
if (node->clones)
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 35fce6d4a1a..283e517c6dc 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -253,7 +253,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report)
gcc_assert (e->inline_failed);
- if (!callee || !callee->analyzed)
+ if (!callee || !callee->symbol.definition)
{
e->inline_failed = CIF_BODY_NOT_AVAILABLE;
inlinable = false;
@@ -1100,8 +1100,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
int i;
struct ipa_ref *ref;
- if ((!node->alias && !inline_summary (node)->inlinable)
- || cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE
+ if ((!node->symbol.alias && !inline_summary (node)->inlinable)
|| node->global.inlined_to)
return;
if (!bitmap_set_bit (updated_nodes, node->uid))
@@ -1162,7 +1161,7 @@ update_callee_keys (fibheap_t heap, struct cgraph_node *node,
if (e->inline_failed
&& (callee = cgraph_function_or_thunk_node (e->callee, &avail))
&& inline_summary (callee)->inlinable
- && cgraph_function_body_availability (callee) >= AVAIL_AVAILABLE
+ && avail >= AVAIL_AVAILABLE
&& !bitmap_bit_p (updated_nodes, callee->uid))
{
if (can_inline_edge_p (e, false)
@@ -1795,6 +1794,9 @@ ipa_inline (void)
}
inline_small_functions ();
+
+ /* Do first after-inlining removal. We want to remove all "stale" extern inline
+ functions and virtual functions so we really know what is called once. */
symtab_remove_unreachable_nodes (false, dump_file);
free (order);
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 7c3987e222e..8918c5b3bf5 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -1521,7 +1521,7 @@ ipa_compute_jump_functions (struct cgraph_node *node,
NULL);
/* We do not need to bother analyzing calls to unknown
functions unless they may become known during lto/whopr. */
- if (!callee->analyzed && !flag_lto)
+ if (!callee->symbol.definition && !flag_lto)
continue;
ipa_compute_jump_functions_for_edge (parms_ainfo, cs);
}
@@ -2978,7 +2978,7 @@ ipa_print_node_params (FILE *f, struct cgraph_node *node)
tree temp;
struct ipa_node_params *info;
- if (!node->analyzed)
+ if (!node->symbol.definition)
return;
info = IPA_NODE_REF (node);
fprintf (f, " function %s/%i parameter descriptors:\n",
@@ -3972,7 +3972,7 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
index = streamer_read_uhwi (&ib_main);
encoder = file_data->symtab_node_encoder;
node = cgraph (lto_symtab_encoder_deref (encoder, index));
- gcc_assert (node->analyzed);
+ gcc_assert (node->symbol.definition);
ipa_read_node_info (&ib_main, node, data_in);
}
lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
@@ -4016,8 +4016,7 @@ ipa_update_after_lto_read (void)
ipa_check_create_edge_args ();
FOR_EACH_DEFINED_FUNCTION (node)
- if (node->analyzed)
- ipa_initialize_node_params (node);
+ ipa_initialize_node_params (node);
}
void
@@ -4154,7 +4153,7 @@ read_replacements_section (struct lto_file_decl_data *file_data,
index = streamer_read_uhwi (&ib_main);
encoder = file_data->symtab_node_encoder;
node = cgraph (lto_symtab_encoder_deref (encoder, index));
- gcc_assert (node->analyzed);
+ gcc_assert (node->symbol.definition);
read_agg_replacement_chain (&ib_main, node, data_in);
}
lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index 0dd68380161..9705db19e12 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -738,7 +738,7 @@ analyze_function (struct cgraph_node *fn, bool ipa)
flags_from_decl_or_type (fn->symbol.decl),
cgraph_node_cannot_return (fn));
- if (fn->thunk.thunk_p || fn->alias)
+ if (fn->thunk.thunk_p || fn->symbol.alias)
{
/* Thunk gets propagated through, so nothing interesting happens. */
gcc_assert (ipa);
@@ -951,7 +951,7 @@ pure_const_write_summary (void)
lsei_next_function_in_partition (&lsei))
{
node = lsei_cgraph_node (lsei);
- if (node->analyzed && has_function_state (node))
+ if (node->symbol.definition && has_function_state (node))
count++;
}
@@ -962,7 +962,7 @@ pure_const_write_summary (void)
lsei_next_function_in_partition (&lsei))
{
node = lsei_cgraph_node (lsei);
- if (node->analyzed && has_function_state (node))
+ if (node->symbol.definition && has_function_state (node))
{
struct bitpack_d bp;
funct_state fs;
@@ -1110,7 +1110,7 @@ propagate_pure_const (void)
if (dump_file)
{
dump_cgraph (dump_file);
- ipa_print_order(dump_file, "reduced", order, order_pos);
+ ipa_print_order (dump_file, "reduced", order, order_pos);
}
/* Propagate the local information through the call graph to produce
@@ -1124,7 +1124,7 @@ propagate_pure_const (void)
int count = 0;
node = order[i];
- if (node->alias)
+ if (node->symbol.alias)
continue;
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -1394,7 +1394,7 @@ propagate_nothrow (void)
bool can_throw = false;
node = order[i];
- if (node->alias)
+ if (node->symbol.alias)
continue;
/* Find the worst state for any node in the cycle. */
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index f3c483f67f9..9c56b7f5518 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -684,7 +684,7 @@ propagate (void)
|| TREE_ADDRESSABLE (vnode->symbol.decl)
|| TREE_READONLY (vnode->symbol.decl)
|| !is_proper_for_analysis (vnode->symbol.decl)
- || !vnode->analyzed)
+ || !vnode->symbol.definition)
bitmap_clear_bit (all_module_statics, DECL_UID (vnode->symbol.decl));
/* Forget info we collected "just for fun" on variables that turned out to be
@@ -716,7 +716,7 @@ propagate (void)
bool write_all = false;
node = order[i];
- if (node->alias)
+ if (node->symbol.alias)
continue;
node_info = get_reference_vars_info (node);
@@ -794,7 +794,7 @@ propagate (void)
struct cgraph_node *w;
node = order[i];
- if (node->alias)
+ if (node->symbol.alias)
continue;
fprintf (dump_file,
@@ -835,7 +835,7 @@ propagate (void)
ipa_reference_optimization_summary_t opt;
node_info = get_reference_vars_info (node);
- if (!node->alias
+ if (!node->symbol.alias
&& (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE
|| (flags_from_decl_or_type (node->symbol.decl) & ECF_LEAF)))
{
@@ -894,7 +894,7 @@ write_node_summary_p (struct cgraph_node *node,
ipa_reference_optimization_summary_t info;
/* See if we have (non-empty) info. */
- if (!node->analyzed || node->global.inlined_to)
+ if (!node->symbol.definition || node->global.inlined_to)
return false;
info = get_reference_optimization_summary (node);
if (!info || (bitmap_empty_p (info->statics_not_read)
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 107c7a90d95..e786478981e 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -367,23 +367,46 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
unsigned int i;
int incoming_freq = 0;
tree retval;
+ bool back_edge = false;
if (dump_file && (dump_flags & TDF_DETAILS))
dump_split_point (dump_file, current);
FOR_EACH_EDGE (e, ei, current->entry_bb->preds)
- if (!bitmap_bit_p (current->split_bbs, e->src->index))
- incoming_freq += EDGE_FREQUENCY (e);
+ {
+ if (e->flags & EDGE_DFS_BACK)
+ back_edge = true;
+ if (!bitmap_bit_p (current->split_bbs, e->src->index))
+ incoming_freq += EDGE_FREQUENCY (e);
+ }
/* Do not split when we would end up calling function anyway. */
if (incoming_freq
>= (ENTRY_BLOCK_PTR->frequency
* PARAM_VALUE (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY) / 100))
{
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- " Refused: incoming frequency is too large.\n");
- return;
+ /* When profile is guessed, we can not expect it to give us
+ realistic estimate on likelyness of function taking the
+ complex path. As a special case, when tail of the function is
+ a loop, enable splitting since inlining code skipping the loop
+ is likely noticeable win. */
+ if (back_edge
+ && profile_status != PROFILE_READ
+ && incoming_freq < ENTRY_BLOCK_PTR->frequency)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ " Split before loop, accepting despite low frequencies %i %i.\n",
+ incoming_freq,
+ ENTRY_BLOCK_PTR->frequency);
+ }
+ else
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ " Refused: incoming frequency is too large.\n");
+ return;
+ }
}
if (!current->header_size)
@@ -1533,6 +1556,11 @@ execute_split_functions (void)
return 0;
}
+ /* We enforce splitting after loop headers when profile info is not
+ available. */
+ if (profile_status != PROFILE_READ)
+ mark_dfs_back_edges ();
+
/* Initialize bitmap to track forbidden calls. */
forbidden_dominators = BITMAP_ALLOC (NULL);
calculate_dominance_info (CDI_DOMINATORS);
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index cef67de6076..00e65285c54 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -287,7 +287,7 @@ ipa_reverse_postorder (struct cgraph_node **order)
&& (pass
|| (!node->symbol.address_taken
&& !node->global.inlined_to
- && !node->alias && !node->thunk.thunk_p
+ && !node->symbol.alias && !node->thunk.thunk_p
&& !cgraph_only_called_directly_p (node))))
{
stack_size = 0;
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 5613c26f7fa..a73cbb1c089 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -39,6 +39,53 @@ along with GCC; see the file COPYING3. If not see
#include "lto-streamer.h"
#include "data-streamer.h"
+/* Return true when NODE can not be local. Worker for cgraph_local_node_p. */
+
+static bool
+cgraph_non_local_node_p_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
+{
+ /* FIXME: Aliases can be local, but i386 gets thunks wrong then. */
+ return !(cgraph_only_called_directly_or_aliased_p (node)
+ && !ipa_ref_has_aliases_p (&node->symbol.ref_list)
+ && node->symbol.definition
+ && !DECL_EXTERNAL (node->symbol.decl)
+ && !node->symbol.externally_visible
+ && !node->symbol.used_from_other_partition
+ && !node->symbol.in_other_partition);
+}
+
+/* Return true when function can be marked local. */
+
+static bool
+cgraph_local_node_p (struct cgraph_node *node)
+{
+ struct cgraph_node *n = cgraph_function_or_thunk_node (node, NULL);
+
+ /* FIXME: thunks can be considered local, but we need prevent i386
+ from attempting to change calling convention of them. */
+ if (n->thunk.thunk_p)
+ return false;
+ return !cgraph_for_node_and_aliases (n,
+ cgraph_non_local_node_p_1, NULL, true);
+
+}
+
+/* Return true when NODE has ADDR reference. */
+
+static bool
+has_addr_references_p (struct cgraph_node *node,
+ void *data ATTRIBUTE_UNUSED)
+{
+ int i;
+ struct ipa_ref *ref;
+
+ for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
+ i, ref); i++)
+ if (ref->use == IPA_REF_ADDR)
+ return true;
+ return false;
+}
+
/* Look for all functions inlined to NODE and update their inlined_to pointers
to INLINED_TO. */
@@ -89,79 +136,22 @@ process_references (struct ipa_ref_list *list,
struct ipa_ref *ref;
for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
{
- if (is_a <cgraph_node> (ref->referred))
- {
- struct cgraph_node *node = ipa_ref_node (ref);
-
- if (node->analyzed
- && (!DECL_EXTERNAL (node->symbol.decl)
- || node->alias
- || before_inlining_p))
- pointer_set_insert (reachable, node);
- enqueue_node ((symtab_node) node, first, reachable);
- }
- else
- {
- struct varpool_node *node = ipa_ref_varpool_node (ref);
-
- if (node->analyzed
- && (!DECL_EXTERNAL (node->symbol.decl)
- || node->alias
- || before_inlining_p))
- pointer_set_insert (reachable, node);
- enqueue_node ((symtab_node) node, first, reachable);
- }
+ symtab_node node = ref->referred;
+
+ if (node->symbol.definition
+ && ((!DECL_EXTERNAL (node->symbol.decl) || node->symbol.alias)
+ || (before_inlining_p
+ /* We use variable constructors during late complation for
+ constant folding. Keep references alive so partitioning
+ knows about potential references. */
+ || (TREE_CODE (node->symbol.decl) == VAR_DECL
+ && flag_wpa && const_value_known_p (node->symbol.decl)))))
+ pointer_set_insert (reachable, node);
+ enqueue_node ((symtab_node) node, first, reachable);
}
}
-/* Return true when NODE can not be local. Worker for cgraph_local_node_p. */
-
-static bool
-cgraph_non_local_node_p_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
-{
- /* FIXME: Aliases can be local, but i386 gets thunks wrong then. */
- return !(cgraph_only_called_directly_or_aliased_p (node)
- && !ipa_ref_has_aliases_p (&node->symbol.ref_list)
- && node->analyzed
- && !DECL_EXTERNAL (node->symbol.decl)
- && !node->symbol.externally_visible
- && !node->symbol.used_from_other_partition
- && !node->symbol.in_other_partition);
-}
-
-/* Return true when function can be marked local. */
-
-static bool
-cgraph_local_node_p (struct cgraph_node *node)
-{
- struct cgraph_node *n = cgraph_function_or_thunk_node (node, NULL);
-
- /* FIXME: thunks can be considered local, but we need prevent i386
- from attempting to change calling convention of them. */
- if (n->thunk.thunk_p)
- return false;
- return !cgraph_for_node_and_aliases (n,
- cgraph_non_local_node_p_1, NULL, true);
-
-}
-
-/* Return true when NODE has ADDR reference. */
-
-static bool
-has_addr_references_p (struct cgraph_node *node,
- void *data ATTRIBUTE_UNUSED)
-{
- int i;
- struct ipa_ref *ref;
-
- for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
- i, ref); i++)
- if (ref->use == IPA_REF_ADDR)
- return true;
- return false;
-}
-
/* Perform reachability analysis and reclaim all unreachable nodes.
The algorithm is basically mark&sweep but with some extra refinements:
@@ -303,10 +293,10 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
struct cgraph_edge *e;
for (e = cnode->callees; e; e = e->next_callee)
{
- if (e->callee->analyzed
+ if (e->callee->symbol.definition
&& (!e->inline_failed
|| !DECL_EXTERNAL (e->callee->symbol.decl)
- || cnode->alias
+ || e->callee->symbol.alias
|| before_inlining_p))
pointer_set_insert (reachable, e->callee);
enqueue_node ((symtab_node) e->callee, &first, reachable);
@@ -314,7 +304,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
/* When inline clone exists, mark body to be preserved so when removing
offline copy of the function we don't kill it. */
- if (!cnode->alias && cnode->global.inlined_to)
+ if (!cnode->symbol.alias && cnode->global.inlined_to)
pointer_set_insert (body_needed_for_clonning, cnode->symbol.decl);
}
@@ -339,7 +329,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
varpool_node *vnode = dyn_cast <varpool_node> (node);
if (vnode
&& DECL_EXTERNAL (node->symbol.decl)
- && !vnode->alias
+ && !vnode->symbol.alias
&& in_boundary_p)
{
struct ipa_ref *ref;
@@ -352,6 +342,8 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
for (node = cgraph_first_function (); node; node = next)
{
next = cgraph_next_function (node);
+
+ /* If node is not needed at all, remove it. */
if (!node->symbol.aux)
{
if (file)
@@ -359,20 +351,18 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
cgraph_remove_node (node);
changed = true;
}
+ /* If node is unreachable, remove its body. */
else if (!pointer_set_contains (reachable, node))
{
- if (node->analyzed)
+ if (!pointer_set_contains (body_needed_for_clonning, node->symbol.decl))
+ cgraph_release_function_body (node);
+ if (node->symbol.definition)
{
if (file)
fprintf (file, " %s", cgraph_node_name (node));
- cgraph_node_remove_callees (node);
- ipa_remove_all_references (&node->symbol.ref_list);
+ cgraph_reset_node (node);
changed = true;
}
- if (!pointer_set_contains (body_needed_for_clonning, node->symbol.decl)
- && (node->local.finalized || !DECL_ARTIFICIAL (node->symbol.decl)))
- cgraph_release_function_body (node);
- node->analyzed = false;
}
}
@@ -397,7 +387,11 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
for (vnode = varpool_first_variable (); vnode; vnode = vnext)
{
vnext = varpool_next_variable (vnode);
- if (!vnode->symbol.aux)
+ if (!vnode->symbol.aux
+ /* For can_refer_decl_in_current_unit_p we want to track for
+ all external variables if they are defined in other partition
+ or not. */
+ && (!flag_ltrans || !DECL_EXTERNAL (vnode->symbol.decl)))
{
if (file)
fprintf (file, " %s", varpool_node_name (vnode));
@@ -406,14 +400,20 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
}
else if (!pointer_set_contains (reachable, vnode))
{
- if (vnode->analyzed)
+ if (vnode->symbol.definition)
{
if (file)
fprintf (file, " %s", varpool_node_name (vnode));
changed = true;
}
- vnode->analyzed = false;
+ vnode->symbol.definition = false;
+ vnode->symbol.analyzed = false;
vnode->symbol.aux = NULL;
+
+ /* Keep body if it may be useful for constant folding. */
+ if (!const_value_known_p (vnode->symbol.decl))
+ varpool_remove_initializer (vnode);
+ ipa_remove_all_references (&vnode->symbol.ref_list);
}
else
vnode->symbol.aux = NULL;
@@ -474,7 +474,7 @@ ipa_discover_readonly_nonaddressable_vars (void)
if (dump_file)
fprintf (dump_file, "Clearing variable flags:");
FOR_EACH_VARIABLE (vnode)
- if (vnode->finalized && varpool_all_refs_explicit_p (vnode)
+ if (vnode->symbol.definition && varpool_all_refs_explicit_p (vnode)
&& (TREE_ADDRESSABLE (vnode->symbol.decl)
|| !TREE_READONLY (vnode->symbol.decl)))
{
@@ -519,7 +519,7 @@ ipa_discover_readonly_nonaddressable_vars (void)
/* Return true when there is a reference to node and it is not vtable. */
static bool
-cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node)
+address_taken_from_non_vtable_p (symtab_node node)
{
int i;
struct ipa_ref *ref;
@@ -537,6 +537,38 @@ cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node)
return false;
}
+/* A helper for comdat_can_be_unshared_p. */
+
+static bool
+comdat_can_be_unshared_p_1 (symtab_node node)
+{
+ /* When address is taken, we don't know if equality comparison won't
+ break eventaully. Exception are virutal functions and vtables, where
+ this is not possible by language standard. */
+ if (!DECL_VIRTUAL_P (node->symbol.decl)
+ && address_taken_from_non_vtable_p (node))
+ return false;
+
+ /* If the symbol is used in some weird way, better to not touch it. */
+ if (node->symbol.force_output)
+ return false;
+
+ /* Explicit instantiations needs to be output when possibly
+ used externally. */
+ if (node->symbol.forced_by_abi
+ && TREE_PUBLIC (node->symbol.decl)
+ && (node->symbol.resolution != LDPR_PREVAILING_DEF_IRONLY
+ && !flag_whole_program))
+ return false;
+
+ /* Non-readonly and volatile variables can not be duplicated. */
+ if (is_a <varpool_node> (node)
+ && (!TREE_READONLY (node->symbol.decl)
+ || TREE_THIS_VOLATILE (node->symbol.decl)))
+ return false;
+ return true;
+}
+
/* COMDAT functions must be shared only if they have address taken,
otherwise we can produce our own private implementation with
-fwhole-program.
@@ -546,25 +578,22 @@ cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node)
Virtual functions do have their addresses taken from the vtables,
but in C++ there is no way to compare their addresses for equality. */
-bool
-cgraph_comdat_can_be_unshared_p (struct cgraph_node *node)
+static bool
+comdat_can_be_unshared_p (symtab_node node)
{
- if ((cgraph_address_taken_from_non_vtable_p (node)
- && !DECL_VIRTUAL_P (node->symbol.decl))
- || !node->analyzed)
+ if (!comdat_can_be_unshared_p_1 (node))
return false;
if (node->symbol.same_comdat_group)
{
- struct cgraph_node *next;
+ symtab_node next;
/* If more than one function is in the same COMDAT group, it must
be shared even if just one function in the comdat group has
address taken. */
- for (next = cgraph (node->symbol.same_comdat_group);
- next != node; next = cgraph (next->symbol.same_comdat_group))
- if (cgraph_address_taken_from_non_vtable_p (next)
- && !DECL_VIRTUAL_P (next->symbol.decl))
- return false;
+ for (next = node->symbol.same_comdat_group;
+ next != node; next = next->symbol.same_comdat_group)
+ if (!comdat_can_be_unshared_p_1 (next))
+ return false;
}
return true;
}
@@ -575,7 +604,7 @@ static bool
cgraph_externally_visible_p (struct cgraph_node *node,
bool whole_program)
{
- if (!node->local.finalized)
+ if (!node->symbol.definition)
return false;
if (!DECL_COMDAT (node->symbol.decl)
&& (!TREE_PUBLIC (node->symbol.decl)
@@ -610,7 +639,7 @@ cgraph_externally_visible_p (struct cgraph_node *node,
implementing same COMDAT) */
if ((in_lto_p || whole_program)
&& DECL_COMDAT (node->symbol.decl)
- && cgraph_comdat_can_be_unshared_p (node))
+ && comdat_can_be_unshared_p ((symtab_node) node))
return false;
/* When doing link time optimizations, hidden symbols become local. */
@@ -619,7 +648,7 @@ cgraph_externally_visible_p (struct cgraph_node *node,
|| DECL_VISIBILITY (node->symbol.decl) == VISIBILITY_INTERNAL)
/* Be sure that node is defined in IR file, not in other object
file. In that case we don't set used_from_other_object_file. */
- && node->analyzed)
+ && node->symbol.definition)
;
else if (!whole_program)
return true;
@@ -638,7 +667,7 @@ varpool_externally_visible_p (struct varpool_node *vnode)
/* Do not touch weakrefs; while they are not externally visible,
dropping their DECL_EXTERNAL flags confuse most
of code handling them. */
- if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl))
+ if (vnode->symbol.alias && DECL_EXTERNAL (vnode->symbol.decl))
return true;
if (DECL_EXTERNAL (vnode->symbol.decl))
@@ -680,8 +709,8 @@ varpool_externally_visible_p (struct varpool_node *vnode)
is faster for dynamic linking. Also this match logic hidding vtables
from LTO symbol tables. */
if ((in_lto_p || flag_whole_program)
- && !vnode->symbol.force_output
- && DECL_COMDAT (vnode->symbol.decl) && DECL_VIRTUAL_P (vnode->symbol.decl))
+ && DECL_COMDAT (vnode->symbol.decl)
+ && comdat_can_be_unshared_p ((symtab_node) vnode))
return false;
/* When doing link time optimizations, hidden symbols become local. */
@@ -690,7 +719,7 @@ varpool_externally_visible_p (struct varpool_node *vnode)
|| DECL_VISIBILITY (vnode->symbol.decl) == VISIBILITY_INTERNAL)
/* Be sure that node is defined in IR file, not in other object
file. In that case we don't set used_from_other_object_file. */
- && vnode->finalized)
+ && vnode->symbol.definition)
;
else if (!flag_whole_program)
return true;
@@ -743,9 +772,11 @@ function_and_variable_visibility (bool whole_program)
/* Frontends and alias code marks nodes as needed before parsing is finished.
We may end up marking as node external nodes where this flag is meaningless
strip it. */
- if (node->symbol.force_output
- && (DECL_EXTERNAL (node->symbol.decl) || !node->analyzed))
- node->symbol.force_output = 0;
+ if (DECL_EXTERNAL (node->symbol.decl) || !node->symbol.definition)
+ {
+ node->symbol.force_output = 0;
+ node->symbol.forced_by_abi = 0;
+ }
/* C++ FE on lack of COMDAT support create local COMDAT functions
(that ought to be shared but can not due to object format
@@ -780,8 +811,11 @@ function_and_variable_visibility (bool whole_program)
node->symbol.externally_visible = true;
}
else
- node->symbol.externally_visible = false;
- if (!node->symbol.externally_visible && node->analyzed
+ {
+ node->symbol.externally_visible = false;
+ node->symbol.forced_by_abi = false;
+ }
+ if (!node->symbol.externally_visible && node->symbol.definition
&& !DECL_EXTERNAL (node->symbol.decl))
{
gcc_assert (whole_program || in_lto_p
@@ -854,12 +888,15 @@ function_and_variable_visibility (bool whole_program)
}
FOR_EACH_DEFINED_VARIABLE (vnode)
{
- if (!vnode->finalized)
+ if (!vnode->symbol.definition)
continue;
if (varpool_externally_visible_p (vnode))
vnode->symbol.externally_visible = true;
else
- vnode->symbol.externally_visible = false;
+ {
+ vnode->symbol.externally_visible = false;
+ vnode->symbol.forced_by_abi = false;
+ }
if (!vnode->symbol.externally_visible)
{
gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->symbol.decl));
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 2857b06b400..9cc34c51a5a 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,12 @@
+2013-06-05 Jan Hubicka <jh@suse.cz>
+
+ * class.c (emit_register_classes_in_jcr_section): Use DECL_PRESERVE_P
+ instead of mark_decl_referenced.
+
+2013-05-29 Jan Hubicka <jh@suse.cz>
+
+ * decl.c (java_mark_decl_local): Update for new symtab flags.
+
2013-05-22 Matthias Klose <doko@ubuntu.com>
* jvspec.c (jvgenmain_spec): Add %I to cc1 call.
diff --git a/gcc/java/class.c b/gcc/java/class.c
index 30679f72b39..cb6789643d3 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -2814,10 +2814,10 @@ emit_register_classes_in_jcr_section (void)
TREE_CONSTANT (cdecl) = 1;
DECL_ARTIFICIAL (cdecl) = 1;
DECL_IGNORED_P (cdecl) = 1;
+ DECL_PRESERVE_P (cdecl) = 1;
pushdecl_top_level (cdecl);
relayout_decl (cdecl);
rest_of_decl_compilation (cdecl, 1, 0);
- mark_decl_referenced (cdecl);
#else
/* A target has defined TARGET_USE_JCR_SECTION,
but doesn't have a JCR_SECTION_NAME. */
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 566435fb9e7..c5a654d1c61 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -1904,7 +1904,7 @@ java_mark_decl_local (tree decl)
if (TREE_CODE (decl) == FUNCTION_DECL)
{
struct cgraph_node *node = cgraph_get_node (decl);
- gcc_assert (!node || !node->local.finalized);
+ gcc_assert (!node || !node->symbol.definition);
}
#endif
gcc_assert (!DECL_RTL_SET_P (decl));
diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c
index 78bc2e7fcf6..9719f0dc9e7 100644
--- a/gcc/lra-assigns.c
+++ b/gcc/lra-assigns.c
@@ -603,11 +603,7 @@ find_hard_regno_for (int regno, int *cost, int try_only_hard_regno)
if (best_hard_regno < 0 || hard_regno_costs[hard_regno] < best_cost
|| (hard_regno_costs[hard_regno] == best_cost
&& (priority > best_priority
- /* Hard register usage leveling actually results
- in bigger code for targets with conditional
- execution like ARM because it reduces chance
- of if-conversion after LRA. */
- || (! targetm.have_conditional_execution ()
+ || (targetm.register_usage_leveling_p ()
&& priority == best_priority
&& best_usage > lra_hard_reg_usage[hard_regno]))))
{
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index 34188cbf26f..bc9e5cdbf75 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -320,7 +320,7 @@ bool
reachable_from_other_partition_p (struct cgraph_node *node, lto_symtab_encoder_t encoder)
{
struct cgraph_edge *e;
- if (!node->analyzed)
+ if (!node->symbol.definition)
return false;
if (node->global.inlined_to)
return false;
@@ -377,10 +377,11 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
struct cgraph_node *clone_of;
struct ipa_opt_pass_d *pass;
int i;
+ bool alias_p;
boundary_p = !lto_symtab_encoder_in_partition_p (encoder, (symtab_node)node);
- if (node->analyzed && !boundary_p)
+ if (node->symbol.analyzed && !boundary_p)
tag = LTO_symtab_analyzed_node;
else
tag = LTO_symtab_unavail_node;
@@ -399,7 +400,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
Cherry-picked nodes: These are nodes we pulled from other
translation units into SET during IPA-inlining. We make them as
local static nodes to prevent clashes with other local statics. */
- if (boundary_p && node->analyzed && !DECL_EXTERNAL (node->symbol.decl))
+ if (boundary_p && node->symbol.analyzed && !DECL_EXTERNAL (node->symbol.decl))
{
/* Inline clones can not be part of boundary.
gcc_assert (!node->global.inlined_to);
@@ -463,11 +464,12 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, node->local.local, 1);
bp_pack_value (&bp, node->symbol.externally_visible, 1);
- bp_pack_value (&bp, node->local.finalized, 1);
+ bp_pack_value (&bp, node->symbol.definition, 1);
bp_pack_value (&bp, node->local.versionable, 1);
bp_pack_value (&bp, node->local.can_change_signature, 1);
bp_pack_value (&bp, node->local.redefined_extern_inline, 1);
bp_pack_value (&bp, node->symbol.force_output, 1);
+ bp_pack_value (&bp, node->symbol.forced_by_abi, 1);
bp_pack_value (&bp, node->symbol.unique_name, 1);
bp_pack_value (&bp, node->symbol.address_taken, 1);
bp_pack_value (&bp, node->abstract_and_needed, 1);
@@ -485,7 +487,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
defined in other unit, we may use the info on aliases to resolve
symbol1 != symbol2 type tests that we can do only for locally defined objects
otherwise. */
- bp_pack_value (&bp, node->alias && (!boundary_p || DECL_EXTERNAL (node->symbol.decl)), 1);
+ alias_p = node->symbol.alias && (!boundary_p || DECL_EXTERNAL (node->symbol.decl));
+ bp_pack_value (&bp, alias_p, 1);
bp_pack_value (&bp, node->frequency, 2);
bp_pack_value (&bp, node->only_called_at_startup, 1);
bp_pack_value (&bp, node->only_called_at_exit, 1);
@@ -504,15 +507,6 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
streamer_write_uhwi_stream (ob->main_stream, node->thunk.fixed_offset);
streamer_write_uhwi_stream (ob->main_stream, node->thunk.virtual_value);
}
- if ((node->alias || node->thunk.thunk_p)
- && (!boundary_p || (node->alias && DECL_EXTERNAL (node->symbol.decl))))
- {
- streamer_write_hwi_in_range (ob->main_stream, 0, 1,
- node->thunk.alias != NULL);
- if (node->thunk.alias != NULL)
- lto_output_fn_decl_index (ob->decl_state, ob->main_stream,
- node->thunk.alias);
- }
}
/* Output the varpool NODE to OB.
@@ -522,10 +516,10 @@ static void
lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node *node,
lto_symtab_encoder_t encoder)
{
- bool boundary_p = (node->analyzed
- && !lto_symtab_encoder_in_partition_p (encoder, (symtab_node)node));
+ bool boundary_p = !lto_symtab_encoder_in_partition_p (encoder, (symtab_node)node);
struct bitpack_d bp;
int ref;
+ bool alias_p;
streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag,
LTO_symtab_variable);
@@ -534,11 +528,13 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node
bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, node->symbol.externally_visible, 1);
bp_pack_value (&bp, node->symbol.force_output, 1);
+ bp_pack_value (&bp, node->symbol.forced_by_abi, 1);
bp_pack_value (&bp, node->symbol.unique_name, 1);
- bp_pack_value (&bp, node->finalized, 1);
- bp_pack_value (&bp, node->alias, 1);
- bp_pack_value (&bp, node->alias_of != NULL, 1);
- gcc_assert (node->finalized || !node->analyzed);
+ bp_pack_value (&bp, node->symbol.definition, 1);
+ alias_p = node->symbol.alias && (!boundary_p || DECL_EXTERNAL (node->symbol.decl));
+ bp_pack_value (&bp, alias_p, 1);
+ bp_pack_value (&bp, node->symbol.analyzed && !boundary_p, 1);
+ gcc_assert (node->symbol.definition || !node->symbol.analyzed);
/* Constant pool initializers can be de-unified into individual ltrans units.
FIXME: Alternatively at -Os we may want to avoid generating for them the local
labels and share them across LTRANS partitions. */
@@ -551,15 +547,14 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node
}
else
{
- bp_pack_value (&bp, node->analyzed
+ bp_pack_value (&bp, node->symbol.definition
&& referenced_from_other_partition_p (&node->symbol.ref_list,
encoder), 1);
- bp_pack_value (&bp, boundary_p && !DECL_EXTERNAL (node->symbol.decl), 1);
+ bp_pack_value (&bp, node->symbol.analyzed
+ && boundary_p && !DECL_EXTERNAL (node->symbol.decl), 1);
/* in_other_partition. */
}
streamer_write_bitpack (&bp);
- if (node->alias_of)
- lto_output_var_decl_index (ob->decl_state, ob->main_stream, node->alias_of);
if (node->symbol.same_comdat_group && !boundary_p)
{
ref = lto_symtab_encoder_lookup (encoder,
@@ -679,7 +674,7 @@ output_refs (lto_symtab_encoder_t encoder)
count = ipa_ref_list_nreferences (&node->symbol.ref_list);
if (count)
{
- streamer_write_uhwi_stream (ob->main_stream, count);
+ streamer_write_gcov_count_stream (ob->main_stream, count);
streamer_write_uhwi_stream (ob->main_stream,
lto_symtab_encoder_lookup (encoder, node));
for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list,
@@ -756,7 +751,7 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
!lsei_end_p (lsei); lsei_next_variable_in_partition (&lsei))
{
struct varpool_node *vnode = lsei_varpool_node (lsei);
- gcc_assert (!vnode->alias || vnode->alias_of);
+
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode);
lto_set_symtab_encoder_encode_initializer (encoder, vnode);
add_references (encoder, &vnode->symbol.ref_list);
@@ -883,17 +878,18 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
node->local.local = bp_unpack_value (bp, 1);
node->symbol.externally_visible = bp_unpack_value (bp, 1);
- node->local.finalized = bp_unpack_value (bp, 1);
+ node->symbol.definition = bp_unpack_value (bp, 1);
node->local.versionable = bp_unpack_value (bp, 1);
node->local.can_change_signature = bp_unpack_value (bp, 1);
node->local.redefined_extern_inline = bp_unpack_value (bp, 1);
node->symbol.force_output = bp_unpack_value (bp, 1);
+ node->symbol.forced_by_abi = bp_unpack_value (bp, 1);
node->symbol.unique_name = bp_unpack_value (bp, 1);
node->symbol.address_taken = bp_unpack_value (bp, 1);
node->abstract_and_needed = bp_unpack_value (bp, 1);
node->symbol.used_from_other_partition = bp_unpack_value (bp, 1);
node->lowered = bp_unpack_value (bp, 1);
- node->analyzed = tag == LTO_symtab_analyzed_node;
+ node->symbol.analyzed = tag == LTO_symtab_analyzed_node;
node->symbol.in_other_partition = bp_unpack_value (bp, 1);
if (node->symbol.in_other_partition
/* Avoid updating decl when we are seeing just inline clone.
@@ -909,7 +905,7 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
DECL_EXTERNAL (node->symbol.decl) = 1;
TREE_STATIC (node->symbol.decl) = 0;
}
- node->alias = bp_unpack_value (bp, 1);
+ node->symbol.alias = bp_unpack_value (bp, 1);
node->frequency = (enum node_frequency)bp_unpack_value (bp, 2);
node->only_called_at_startup = bp_unpack_value (bp, 1);
node->only_called_at_exit = bp_unpack_value (bp, 1);
@@ -919,6 +915,16 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
LDPR_NUM_KNOWN);
}
+/* Return string alias is alias of. */
+
+static tree
+get_alias_symbol (tree decl)
+{
+ tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
+ return get_identifier (TREE_STRING_POINTER
+ (TREE_VALUE (TREE_VALUE (alias))));
+}
+
/* Read a node from input_block IB. TAG is the node's tag just read.
Return the node read or overwriten. */
@@ -1004,15 +1010,9 @@ input_node (struct lto_file_decl_data *file_data,
node->thunk.virtual_value = virtual_value;
node->thunk.virtual_offset_p = (type & 4);
}
- if (node->thunk.thunk_p || node->alias)
- {
- if (streamer_read_hwi_in_range (ib, "alias nonzero flag", 0, 1))
- {
- decl_index = streamer_read_uhwi (ib);
- node->thunk.alias = lto_file_decl_data_get_fn_decl (file_data,
- decl_index);
- }
- }
+ if (node->symbol.alias && !node->symbol.analyzed
+ && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
+ node->symbol.alias_target = get_alias_symbol (node->symbol.decl);
return node;
}
@@ -1028,7 +1028,6 @@ input_varpool_node (struct lto_file_decl_data *file_data,
struct varpool_node *node;
struct bitpack_d bp;
int ref = LCC_NOT_FOUND;
- bool non_null_aliasof;
int order;
order = streamer_read_hwi (ib) + order_base;
@@ -1043,23 +1042,21 @@ input_varpool_node (struct lto_file_decl_data *file_data,
bp = streamer_read_bitpack (ib);
node->symbol.externally_visible = bp_unpack_value (&bp, 1);
node->symbol.force_output = bp_unpack_value (&bp, 1);
+ node->symbol.forced_by_abi = bp_unpack_value (&bp, 1);
node->symbol.unique_name = bp_unpack_value (&bp, 1);
- node->finalized = bp_unpack_value (&bp, 1);
- node->alias = bp_unpack_value (&bp, 1);
- non_null_aliasof = bp_unpack_value (&bp, 1);
+ node->symbol.definition = bp_unpack_value (&bp, 1);
+ node->symbol.alias = bp_unpack_value (&bp, 1);
+ node->symbol.analyzed = bp_unpack_value (&bp, 1);
node->symbol.used_from_other_partition = bp_unpack_value (&bp, 1);
node->symbol.in_other_partition = bp_unpack_value (&bp, 1);
- node->analyzed = (node->finalized && (!node->alias || !node->symbol.in_other_partition));
if (node->symbol.in_other_partition)
{
DECL_EXTERNAL (node->symbol.decl) = 1;
TREE_STATIC (node->symbol.decl) = 0;
}
- if (non_null_aliasof)
- {
- decl_index = streamer_read_uhwi (ib);
- node->alias_of = lto_file_decl_data_get_var_decl (file_data, decl_index);
- }
+ if (node->symbol.alias && !node->symbol.analyzed
+ && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
+ node->symbol.alias_target = get_alias_symbol (node->symbol.decl);
ref = streamer_read_hwi (ib);
/* Store a reference for now, and fix up later to be a pointer. */
node->symbol.same_comdat_group = (symtab_node) (intptr_t) ref;
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index dfaf2806b74..5e1a332952c 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -1013,7 +1013,7 @@ lto_output (void)
cgraph_node *node = dyn_cast <cgraph_node> (snode);
if (node
&& lto_symtab_encoder_encode_body_p (encoder, node)
- && !node->alias
+ && !node->symbol.alias
&& !node->thunk.thunk_p)
{
#ifdef ENABLE_CHECKING
@@ -1243,10 +1243,10 @@ write_symbol (struct streamer_tree_cache_d *cache,
/* When something is defined, it should have node attached. */
gcc_assert (alias || TREE_CODE (t) != VAR_DECL
- || varpool_get_node (t)->finalized);
+ || varpool_get_node (t)->symbol.definition);
gcc_assert (alias || TREE_CODE (t) != FUNCTION_DECL
|| (cgraph_get_node (t)
- && cgraph_get_node (t)->analyzed));
+ && cgraph_get_node (t)->symbol.definition));
}
/* Imitate what default_elf_asm_output_external do.
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index e0db8b10a70..0f05d180183 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -898,7 +898,7 @@ lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder);
/* In lto-symtab.c. */
extern void lto_symtab_merge_decls (void);
-extern void lto_symtab_merge_cgraph_nodes (void);
+extern void lto_symtab_merge_symbols (void);
extern tree lto_symtab_prevailing_decl (tree decl);
extern GTY(()) vec<tree, va_gc> *lto_global_var_decls;
diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c
index 8091d36193e..2b41933c67e 100644
--- a/gcc/lto-symtab.c
+++ b/gcc/lto-symtab.c
@@ -91,8 +91,8 @@ static void
lto_varpool_replace_node (struct varpool_node *vnode,
struct varpool_node *prevailing_node)
{
- gcc_assert (!vnode->finalized || prevailing_node->finalized);
- gcc_assert (!vnode->analyzed || prevailing_node->analyzed);
+ gcc_assert (!vnode->symbol.definition || prevailing_node->symbol.definition);
+ gcc_assert (!vnode->symbol.analyzed || prevailing_node->symbol.analyzed);
ipa_clone_referring ((symtab_node)prevailing_node, &vnode->symbol.ref_list);
@@ -255,14 +255,7 @@ lto_symtab_resolve_can_prevail_p (symtab_node e)
if (DECL_EXTERNAL (e->symbol.decl))
return false;
- /* For functions we need a non-discarded body. */
- if (TREE_CODE (e->symbol.decl) == FUNCTION_DECL)
- return (cgraph (e)->analyzed);
-
- else if (TREE_CODE (e->symbol.decl) == VAR_DECL)
- return varpool (e)->finalized;
-
- gcc_unreachable ();
+ return e->symbol.definition;
}
/* Resolve the symbol with the candidates in the chain *SLOT and store
@@ -549,7 +542,7 @@ lto_symtab_merge_decls (void)
/* Helper to process the decl chain for the symbol table entry *SLOT. */
static void
-lto_symtab_merge_cgraph_nodes_1 (symtab_node prevailing)
+lto_symtab_merge_symbols_1 (symtab_node prevailing)
{
symtab_node e, next;
@@ -575,88 +568,32 @@ lto_symtab_merge_cgraph_nodes_1 (symtab_node prevailing)
lto_symtab_merge_decls. */
void
-lto_symtab_merge_cgraph_nodes (void)
+lto_symtab_merge_symbols (void)
{
- struct cgraph_node *cnode;
- struct varpool_node *vnode;
symtab_node node;
- /* Populate assembler name hash. */
- symtab_initialize_asm_name_hash ();
-
if (!flag_ltrans)
- FOR_EACH_SYMBOL (node)
- if (lto_symtab_symbol_p (node)
- && node->symbol.next_sharing_asm_name
- && !node->symbol.previous_sharing_asm_name)
- lto_symtab_merge_cgraph_nodes_1 (node);
-
- FOR_EACH_FUNCTION (cnode)
- {
- /* Resolve weakrefs to symbol defined in other unit. */
- if (!cnode->analyzed && cnode->thunk.alias && !DECL_P (cnode->thunk.alias))
- {
- symtab_node node = symtab_node_for_asm (cnode->thunk.alias);
- if (node && is_a <cgraph_node> (node))
- {
- struct cgraph_node *n;
-
- for (n = cgraph (node); n && n->alias;
- n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
- if (n == cnode)
- {
- error ("function %q+D part of alias cycle", cnode->symbol.decl);
- cnode->alias = false;
- break;
- }
- if (cnode->alias)
- {
- cgraph_create_function_alias (cnode->symbol.decl, node->symbol.decl);
- ipa_record_reference ((symtab_node)cnode, (symtab_node)node,
- IPA_REF_ALIAS, NULL);
- cnode->analyzed = true;
- }
- }
- else if (node)
- error ("%q+D alias in between function and variable is not supported", cnode->symbol.decl);
- }
- if ((cnode->thunk.thunk_p || cnode->alias)
- && cnode->thunk.alias && DECL_P (cnode->thunk.alias))
- cnode->thunk.alias = lto_symtab_prevailing_decl (cnode->thunk.alias);
- cnode->symbol.aux = NULL;
- }
- FOR_EACH_VARIABLE (vnode)
{
- /* Resolve weakrefs to symbol defined in other unit. */
- if (!vnode->analyzed && vnode->alias_of && !DECL_P (vnode->alias_of))
+ symtab_initialize_asm_name_hash ();
+
+ /* Do the actual merging. */
+ FOR_EACH_SYMBOL (node)
+ if (lto_symtab_symbol_p (node)
+ && node->symbol.next_sharing_asm_name
+ && !node->symbol.previous_sharing_asm_name)
+ lto_symtab_merge_symbols_1 (node);
+
+ /* Resolve weakref aliases whose target are now in the compilation unit. */
+ FOR_EACH_SYMBOL (node)
{
- symtab_node node = symtab_node_for_asm (vnode->alias_of);
- if (node && is_a <cgraph_node> (node))
+ if (!node->symbol.analyzed && node->symbol.alias_target)
{
- struct varpool_node *n;
-
- for (n = varpool (node); n && n->alias;
- n = n->analyzed ? varpool_alias_aliased_node (n) : NULL)
- if (n == vnode)
- {
- error ("function %q+D part of alias cycle", vnode->symbol.decl);
- vnode->alias = false;
- break;
- }
- if (vnode->alias)
- {
- varpool_create_variable_alias (vnode->symbol.decl, node->symbol.decl);
- ipa_record_reference ((symtab_node)vnode, (symtab_node)node,
- IPA_REF_ALIAS, NULL);
- vnode->analyzed = true;
- }
+ symtab_node tgt = symtab_node_for_asm (node->symbol.alias_target);
+ if (tgt)
+ symtab_resolve_alias (node, tgt);
}
- else if (node)
- error ("%q+D alias in between function and variable is not supported", vnode->symbol.decl);
+ node->symbol.aux = NULL;
}
- if (vnode->alias_of)
- vnode->alias_of = lto_symtab_prevailing_decl (vnode->alias_of);
- vnode->symbol.aux = NULL;
}
}
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index 3ea106b8545..f98c31d725a 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,21 @@
+2013-06-05 Richard Biener <rguenther@suse.de>
+
+ * lto.c (num_merged_types): New global variable.
+ (uniquify_nodes): Increase num_merged_types when merging a type.
+ (print_lto_report_1): Output the number of merged types.
+
+2013-06-01 Jan Hubicka <jh@suse.cz>
+
+ * lto.c (read_cgraph_and_symbols): Simplify dumping; Replace
+ lto_symtab_merge_cgraph_nodes by lto_symtab_merge_symbols.
+ (do_whole_program_analysis): Update dumping.
+
+2013-05-29 Jan Hubicka <jh@suse.cz>
+
+ * lto.c (has_analyzed_clone_p, lto_materialize_function): Update for new symtab
+ flags.
+ * lto-partition.c (get_symbol_class, lto_balanced_map): Likewise.
+
2013-05-15 Jan Hubicka <jh@suse.cz>
* lto-partition.c (privatize_symbol_name): Return true when
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 62341c12c04..921b4e26e31 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -74,13 +74,13 @@ get_symbol_class (symtab_node node)
objects that can not be duplicated across partitions. */
if (DECL_IN_CONSTANT_POOL (node->symbol.decl))
return SYMBOL_DUPLICATE;
- gcc_checking_assert (vnode->analyzed);
+ gcc_checking_assert (vnode->symbol.definition);
}
/* Functions that are cloned may stay in callgraph even if they are unused.
Handle them as external; compute_ltrans_boundary take care to make
proper things to happen (i.e. to make them appear in the boundary but
with body streamed, so clone can me materialized). */
- else if (!cgraph (node)->analyzed)
+ else if (!cgraph (node)->symbol.definition)
return SYMBOL_EXTERNAL;
/* Comdats are duplicated to every use unless they are keyed.
@@ -561,12 +561,12 @@ lto_balanced_map (void)
last_visited_node++;
- gcc_assert (node->analyzed
+ gcc_assert (node->symbol.definition
|| lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)));
/* Compute boundary cost of callgraph edges. */
for (edge = node->callees; edge; edge = edge->next_callee)
- if (edge->callee->analyzed)
+ if (edge->callee->symbol.definition)
{
int edge_cost = edge->frequency;
int index;
@@ -587,7 +587,7 @@ lto_balanced_map (void)
int edge_cost = edge->frequency;
int index;
- gcc_assert (edge->caller->analyzed);
+ gcc_assert (edge->caller->symbol.definition);
if (!edge_cost)
edge_cost = 1;
gcc_assert (edge_cost > 0);
@@ -614,7 +614,7 @@ lto_balanced_map (void)
int index;
vnode = ipa_ref_varpool_node (ref);
- if (!vnode->finalized)
+ if (!vnode->symbol.definition)
continue;
if (!symbol_partitioned_p ((symtab_node) vnode) && flag_toplevel_reorder
&& get_symbol_class ((symtab_node) vnode) == SYMBOL_PARTITION)
@@ -632,7 +632,7 @@ lto_balanced_map (void)
int index;
node = ipa_ref_node (ref);
- if (!node->analyzed)
+ if (!node->symbol.definition)
continue;
index = lto_symtab_encoder_lookup (partition->encoder,
(symtab_node)node);
@@ -648,7 +648,7 @@ lto_balanced_map (void)
int index;
vnode = ipa_ref_referring_varpool_node (ref);
- gcc_assert (vnode->finalized);
+ gcc_assert (vnode->symbol.definition);
if (!symbol_partitioned_p ((symtab_node) vnode) && flag_toplevel_reorder
&& get_symbol_class ((symtab_node) vnode) == SYMBOL_PARTITION)
add_symbol_to_partition (partition, (symtab_node) vnode);
@@ -665,7 +665,7 @@ lto_balanced_map (void)
int index;
node = ipa_ref_referring_node (ref);
- gcc_assert (node->analyzed);
+ gcc_assert (node->symbol.definition);
index = lto_symtab_encoder_lookup (partition->encoder,
(symtab_node)node);
if (index != LCC_NOT_FOUND
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 09433353e88..c90a2d8496e 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -166,7 +166,7 @@ has_analyzed_clone_p (struct cgraph_node *node)
if (node)
while (node != orig)
{
- if (node->analyzed)
+ if (node->symbol.analyzed)
return true;
if (node->clones)
node = node->clones;
@@ -196,7 +196,8 @@ lto_materialize_function (struct cgraph_node *node)
decl = node->symbol.decl;
/* Read in functions with body (analyzed nodes)
and also functions that are needed to produce virtual clones. */
- if (cgraph_function_with_gimple_body_p (node) || has_analyzed_clone_p (node))
+ if ((cgraph_function_with_gimple_body_p (node) && node->symbol.analyzed)
+ || has_analyzed_clone_p (node))
{
/* Clones don't need to be read. */
if (node->clone_of)
@@ -1787,6 +1788,7 @@ lto_register_function_decl_in_symtab (struct data_in *data_in, tree decl)
}
}
+static unsigned long num_merged_types = 0;
/* Given a streamer cache structure DATA_IN (holding a sequence of trees
for one compilation unit) go over all trees starting at index FROM until the
@@ -1816,7 +1818,10 @@ uniquify_nodes (struct data_in *data_in, unsigned from)
to reset that flag afterwards - nothing that refers
to those types is left and they are collected. */
if (newt != t)
- TREE_VISITED (t) = 1;
+ {
+ num_merged_types++;
+ TREE_VISITED (t) = 1;
+ }
}
}
@@ -3032,10 +3037,9 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
if (cgraph_dump_file)
{
fprintf (cgraph_dump_file, "Before merging:\n");
- dump_cgraph (cgraph_dump_file);
- dump_varpool (cgraph_dump_file);
+ dump_symtab (cgraph_dump_file);
}
- lto_symtab_merge_cgraph_nodes ();
+ lto_symtab_merge_symbols ();
ggc_collect ();
/* FIXME: ipa_transforms_to_apply holds list of passes that have optimization
@@ -3136,6 +3140,7 @@ print_lto_report_1 (void)
htab_collisions (type_hash_cache));
else
fprintf (stderr, "[%s] GIMPLE type hash cache table is empty\n", pfx);
+ fprintf (stderr, "[%s] Merged %lu types\n", pfx, num_merged_types);
print_gimple_types_stats (pfx);
print_lto_report (pfx);
@@ -3168,10 +3173,7 @@ do_whole_program_analysis (void)
cgraph_function_flags_ready = true;
if (cgraph_dump_file)
- {
- dump_cgraph (cgraph_dump_file);
- dump_varpool (cgraph_dump_file);
- }
+ dump_symtab (cgraph_dump_file);
bitmap_obstack_initialize (NULL);
cgraph_state = CGRAPH_STATE_IPA_SSA;
@@ -3181,8 +3183,7 @@ do_whole_program_analysis (void)
if (cgraph_dump_file)
{
fprintf (cgraph_dump_file, "Optimized ");
- dump_cgraph (cgraph_dump_file);
- dump_varpool (cgraph_dump_file);
+ dump_symtab (cgraph_dump_file);
}
#ifdef ENABLE_CHECKING
verify_cgraph ();
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 2cae478fcb9..afddf377407 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -5665,7 +5665,7 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
struct loop *loop = alloc_loop ();
loop->header = loop_header;
- loop->latch = loop_header;
+ loop->latch = store_bb;
add_loop (loop, loop_header->loop_father);
if (gimple_in_ssa_p (cfun))
diff --git a/gcc/passes.c b/gcc/passes.c
index 02f2022cea5..a4dad2aace4 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -718,7 +718,7 @@ dump_passes (void)
create_pass_tab();
- FOR_EACH_DEFINED_FUNCTION (n)
+ FOR_EACH_FUNCTION (n)
if (DECL_STRUCT_FUNCTION (n->symbol.decl))
{
node = n;
@@ -1300,6 +1300,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_lower_eh);
NEXT_PASS (pass_build_cfg);
NEXT_PASS (pass_warn_function_return);
+ NEXT_PASS (pass_expand_omp);
NEXT_PASS (pass_build_cgraph_edges);
*p = NULL;
@@ -1312,7 +1313,6 @@ init_optimization_passes (void)
struct opt_pass **p = &pass_early_local_passes.pass.sub;
NEXT_PASS (pass_fixup_cfg);
NEXT_PASS (pass_init_datastructures);
- NEXT_PASS (pass_expand_omp);
NEXT_PASS (pass_build_ssa);
NEXT_PASS (pass_early_warn_uninitialized);
@@ -1709,7 +1709,7 @@ do_per_function (void (*callback) (void *data), void *data)
{
struct cgraph_node *node;
FOR_EACH_DEFINED_FUNCTION (node)
- if (gimple_has_body_p (node->symbol.decl)
+ if (node->symbol.analyzed && gimple_has_body_p (node->symbol.decl)
&& (!node->clone_of || node->symbol.decl != node->clone_of->symbol.decl))
{
push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
@@ -2461,6 +2461,7 @@ ipa_write_summaries (void)
lto_symtab_encoder_t encoder;
int i, order_pos;
struct varpool_node *vnode;
+ struct cgraph_node *node;
struct cgraph_node **order;
if (!flag_generate_lto || seen_error ())
@@ -2492,13 +2493,15 @@ ipa_write_summaries (void)
renumber_gimple_stmt_uids ();
pop_cfun ();
}
- if (node->analyzed)
+ if (node->symbol.definition)
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)node);
}
+ FOR_EACH_DEFINED_FUNCTION (node)
+ if (node->symbol.alias)
+ lto_set_symtab_encoder_in_partition (encoder, (symtab_node)node);
FOR_EACH_DEFINED_VARIABLE (vnode)
- if ((!vnode->alias || vnode->alias_of))
- lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode);
+ lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode);
ipa_write_summaries_1 (compute_ltrans_boundary (encoder));
@@ -2564,7 +2567,7 @@ ipa_write_optimization_summaries (lto_symtab_encoder_t encoder)
For functions newly born at WPA stage we need to initialize
the uids here. */
- if (node->analyzed
+ if (node->symbol.definition
&& gimple_has_body_p (node->symbol.decl))
{
push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
diff --git a/gcc/postreload.c b/gcc/postreload.c
index 33462e4dbad..f340503f69c 100644
--- a/gcc/postreload.c
+++ b/gcc/postreload.c
@@ -1645,14 +1645,22 @@ reload_combine_note_use (rtx *xp, rtx insn, int ruid, rtx containing_mem)
later disable any optimization that would cross it.
reg_offset[n] / reg_base_reg[n] / reg_symbol_ref[n] / reg_mode[n]
are only valid if reg_set_luid[n] is greater than
- move2add_last_label_luid. */
+ move2add_last_label_luid.
+ For a set that established a new (potential) base register with
+ non-constant value, we use move2add_luid from the place where the
+ setting insn is encountered; registers based off that base then
+ get the same reg_set_luid. Constants all get
+ move2add_last_label_luid + 1 as their reg_set_luid. */
static int reg_set_luid[FIRST_PSEUDO_REGISTER];
/* If reg_base_reg[n] is negative, register n has been set to
reg_offset[n] or reg_symbol_ref[n] + reg_offset[n] in mode reg_mode[n].
If reg_base_reg[n] is non-negative, register n has been set to the
sum of reg_offset[n] and the value of register reg_base_reg[n]
- before reg_set_luid[n], calculated in mode reg_mode[n] . */
+ before reg_set_luid[n], calculated in mode reg_mode[n] .
+ For multi-hard-register registers, all but the first one are
+ recorded as BLKmode in reg_mode. Setting reg_mode to VOIDmode
+ marks it as invalid. */
static HOST_WIDE_INT reg_offset[FIRST_PSEUDO_REGISTER];
static int reg_base_reg[FIRST_PSEUDO_REGISTER];
static rtx reg_symbol_ref[FIRST_PSEUDO_REGISTER];
@@ -1674,6 +1682,77 @@ static int move2add_last_label_luid;
|| (GET_MODE_SIZE (OUTMODE) <= GET_MODE_SIZE (INMODE) \
&& TRULY_NOOP_TRUNCATION_MODES_P (OUTMODE, INMODE)))
+/* Record that REG is being set to a value with the mode of REG. */
+
+static void
+move2add_record_mode (rtx reg)
+{
+ int regno, nregs;
+ enum machine_mode mode = GET_MODE (reg);
+
+ if (GET_CODE (reg) == SUBREG)
+ {
+ regno = subreg_regno (reg);
+ nregs = subreg_nregs (reg);
+ }
+ else if (REG_P (reg))
+ {
+ regno = REGNO (reg);
+ nregs = hard_regno_nregs[regno][mode];
+ }
+ else
+ gcc_unreachable ();
+ for (int i = nregs - 1; i > 0; i--)
+ reg_mode[regno + i] = BLKmode;
+ reg_mode[regno] = mode;
+}
+
+/* Record that REG is being set to the sum of SYM and OFF. */
+
+static void
+move2add_record_sym_value (rtx reg, rtx sym, rtx off)
+{
+ int regno = REGNO (reg);
+
+ move2add_record_mode (reg);
+ reg_set_luid[regno] = move2add_luid;
+ reg_base_reg[regno] = -1;
+ reg_symbol_ref[regno] = sym;
+ reg_offset[regno] = INTVAL (off);
+}
+
+/* Check if REGNO contains a valid value in MODE. */
+
+static bool
+move2add_valid_value_p (int regno, enum machine_mode mode)
+{
+ if (reg_set_luid[regno] <= move2add_last_label_luid)
+ return false;
+
+ if (mode != reg_mode[regno])
+ {
+ if (!MODES_OK_FOR_MOVE2ADD (mode, reg_mode[regno]))
+ return false;
+ /* The value loaded into regno in reg_mode[regno] is also valid in
+ mode after truncation only if (REG:mode regno) is the lowpart of
+ (REG:reg_mode[regno] regno). Now, for big endian, the starting
+ regno of the lowpart might be different. */
+ int s_off = subreg_lowpart_offset (mode, reg_mode[regno]);
+ s_off = subreg_regno_offset (regno, reg_mode[regno], s_off, mode);
+ if (s_off != 0)
+ /* We could in principle adjust regno, check reg_mode[regno] to be
+ BLKmode, and return s_off to the caller (vs. -1 for failure),
+ but we currently have no callers that could make use of this
+ information. */
+ return false;
+ }
+
+ for (int i = hard_regno_nregs[regno][mode] - 1; i > 0; i--)
+ if (reg_mode[regno + i] != BLKmode)
+ return false;
+ return true;
+}
+
/* This function is called with INSN that sets REG to (SYM + OFF),
while REG is known to already have value (SYM + offset).
This function tries to change INSN into an add instruction
@@ -1732,8 +1811,7 @@ move2add_use_add2_insn (rtx reg, rtx sym, rtx off, rtx insn)
&& ((reg_offset[regno] & ~GET_MODE_MASK (narrow_mode))
== (INTVAL (off) & ~GET_MODE_MASK (narrow_mode))))
{
- rtx narrow_reg = gen_rtx_REG (narrow_mode,
- REGNO (reg));
+ rtx narrow_reg = gen_lowpart_common (narrow_mode, reg);
rtx narrow_src = gen_int_mode (INTVAL (off),
narrow_mode);
rtx new_set
@@ -1749,11 +1827,7 @@ move2add_use_add2_insn (rtx reg, rtx sym, rtx off, rtx insn)
}
}
}
- reg_set_luid[regno] = move2add_luid;
- reg_base_reg[regno] = -1;
- reg_mode[regno] = GET_MODE (reg);
- reg_symbol_ref[regno] = sym;
- reg_offset[regno] = INTVAL (off);
+ move2add_record_sym_value (reg, sym, off);
return changed;
}
@@ -1787,8 +1861,7 @@ move2add_use_add3_insn (rtx reg, rtx sym, rtx off, rtx insn)
SET_SRC (pat) = plus_expr;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (reg_set_luid[i] > move2add_last_label_luid
- && reg_mode[i] == GET_MODE (reg)
+ if (move2add_valid_value_p (i, GET_MODE (reg))
&& reg_base_reg[i] < 0
&& reg_symbol_ref[i] != NULL_RTX
&& rtx_equal_p (sym, reg_symbol_ref[i]))
@@ -1836,10 +1909,7 @@ move2add_use_add3_insn (rtx reg, rtx sym, rtx off, rtx insn)
changed = true;
}
reg_set_luid[regno] = move2add_luid;
- reg_base_reg[regno] = -1;
- reg_mode[regno] = GET_MODE (reg);
- reg_symbol_ref[regno] = sym;
- reg_offset[regno] = INTVAL (off);
+ move2add_record_sym_value (reg, sym, off);
return changed;
}
@@ -1890,8 +1960,7 @@ reload_cse_move2add (rtx first)
/* Check if we have valid information on the contents of this
register in the mode of REG. */
- if (reg_set_luid[regno] > move2add_last_label_luid
- && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), reg_mode[regno])
+ if (move2add_valid_value_p (regno, GET_MODE (reg))
&& dbg_cnt (cse2_move2add))
{
/* Try to transform (set (REGX) (CONST_INT A))
@@ -1928,8 +1997,7 @@ reload_cse_move2add (rtx first)
else if (REG_P (src)
&& reg_set_luid[regno] == reg_set_luid[REGNO (src)]
&& reg_base_reg[regno] == reg_base_reg[REGNO (src)]
- && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg),
- reg_mode[REGNO (src)]))
+ && move2add_valid_value_p (REGNO (src), GET_MODE (reg)))
{
rtx next = next_nonnote_nondebug_insn (insn);
rtx set = NULL_RTX;
@@ -1982,10 +2050,10 @@ reload_cse_move2add (rtx first)
delete_insn (insn);
changed |= success;
insn = next;
- reg_mode[regno] = GET_MODE (reg);
- reg_offset[regno] =
- trunc_int_for_mode (added_offset + base_offset,
- GET_MODE (reg));
+ move2add_record_mode (reg);
+ reg_offset[regno]
+ = trunc_int_for_mode (added_offset + base_offset,
+ GET_MODE (reg));
continue;
}
}
@@ -2021,8 +2089,7 @@ reload_cse_move2add (rtx first)
/* If the reg already contains the value which is sum of
sym and some constant value, we can use an add2 insn. */
- if (reg_set_luid[regno] > move2add_last_label_luid
- && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), reg_mode[regno])
+ if (move2add_valid_value_p (regno, GET_MODE (reg))
&& reg_base_reg[regno] < 0
&& reg_symbol_ref[regno] != NULL_RTX
&& rtx_equal_p (sym, reg_symbol_ref[regno]))
@@ -2045,7 +2112,10 @@ reload_cse_move2add (rtx first)
/* Reset the information about this register. */
int regno = REGNO (XEXP (note, 0));
if (regno < FIRST_PSEUDO_REGISTER)
- reg_set_luid[regno] = 0;
+ {
+ move2add_record_mode (XEXP (note, 0));
+ reg_mode[regno] = VOIDmode;
+ }
}
}
note_stores (PATTERN (insn), move2add_note_store, insn);
@@ -2082,7 +2152,7 @@ reload_cse_move2add (rtx first)
{
if (call_used_regs[i])
/* Reset the information about this register. */
- reg_set_luid[i] = 0;
+ reg_mode[i] = VOIDmode;
}
}
}
@@ -2099,20 +2169,8 @@ move2add_note_store (rtx dst, const_rtx set, void *data)
{
rtx insn = (rtx) data;
unsigned int regno = 0;
- unsigned int nregs = 0;
- unsigned int i;
enum machine_mode mode = GET_MODE (dst);
- if (GET_CODE (dst) == SUBREG)
- {
- regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
- GET_MODE (SUBREG_REG (dst)),
- SUBREG_BYTE (dst),
- GET_MODE (dst));
- nregs = subreg_nregs (dst);
- dst = SUBREG_REG (dst);
- }
-
/* Some targets do argument pushes without adding REG_INC notes. */
if (MEM_P (dst))
@@ -2120,27 +2178,28 @@ move2add_note_store (rtx dst, const_rtx set, void *data)
dst = XEXP (dst, 0);
if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC
|| GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC)
- reg_set_luid[REGNO (XEXP (dst, 0))] = 0;
+ reg_mode[REGNO (XEXP (dst, 0))] = VOIDmode;
return;
}
- if (!REG_P (dst))
- return;
- regno += REGNO (dst);
- if (!nregs)
- nregs = hard_regno_nregs[regno][mode];
+ if (GET_CODE (dst) == SUBREG)
+ regno = subreg_regno (dst);
+ else if (REG_P (dst))
+ regno = REGNO (dst);
+ else
+ return;
- if (SCALAR_INT_MODE_P (GET_MODE (dst))
- && nregs == 1 && GET_CODE (set) == SET)
+ if (SCALAR_INT_MODE_P (mode)
+ && GET_CODE (set) == SET)
{
rtx note, sym = NULL_RTX;
- HOST_WIDE_INT off;
+ rtx off;
note = find_reg_equal_equiv_note (insn);
if (note && GET_CODE (XEXP (note, 0)) == SYMBOL_REF)
{
sym = XEXP (note, 0);
- off = 0;
+ off = const0_rtx;
}
else if (note && GET_CODE (XEXP (note, 0)) == CONST
&& GET_CODE (XEXP (XEXP (note, 0), 0)) == PLUS
@@ -2148,22 +2207,18 @@ move2add_note_store (rtx dst, const_rtx set, void *data)
&& CONST_INT_P (XEXP (XEXP (XEXP (note, 0), 0), 1)))
{
sym = XEXP (XEXP (XEXP (note, 0), 0), 0);
- off = INTVAL (XEXP (XEXP (XEXP (note, 0), 0), 1));
+ off = XEXP (XEXP (XEXP (note, 0), 0), 1);
}
if (sym != NULL_RTX)
{
- reg_base_reg[regno] = -1;
- reg_symbol_ref[regno] = sym;
- reg_offset[regno] = off;
- reg_mode[regno] = mode;
- reg_set_luid[regno] = move2add_luid;
+ move2add_record_sym_value (dst, sym, off);
return;
}
}
- if (SCALAR_INT_MODE_P (GET_MODE (dst))
- && nregs == 1 && GET_CODE (set) == SET
+ if (SCALAR_INT_MODE_P (mode)
+ && GET_CODE (set) == SET
&& GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
&& GET_CODE (SET_DEST (set)) != STRICT_LOW_PART)
{
@@ -2171,9 +2226,6 @@ move2add_note_store (rtx dst, const_rtx set, void *data)
rtx base_reg;
HOST_WIDE_INT offset;
int base_regno;
- /* This may be different from mode, if SET_DEST (set) is a
- SUBREG. */
- enum machine_mode dst_mode = GET_MODE (dst);
switch (GET_CODE (src))
{
@@ -2185,20 +2237,14 @@ move2add_note_store (rtx dst, const_rtx set, void *data)
if (CONST_INT_P (XEXP (src, 1)))
offset = INTVAL (XEXP (src, 1));
else if (REG_P (XEXP (src, 1))
- && (reg_set_luid[REGNO (XEXP (src, 1))]
- > move2add_last_label_luid)
- && (MODES_OK_FOR_MOVE2ADD
- (dst_mode, reg_mode[REGNO (XEXP (src, 1))])))
+ && move2add_valid_value_p (REGNO (XEXP (src, 1)), mode))
{
if (reg_base_reg[REGNO (XEXP (src, 1))] < 0
&& reg_symbol_ref[REGNO (XEXP (src, 1))] == NULL_RTX)
offset = reg_offset[REGNO (XEXP (src, 1))];
/* Maybe the first register is known to be a
constant. */
- else if (reg_set_luid[REGNO (base_reg)]
- > move2add_last_label_luid
- && (MODES_OK_FOR_MOVE2ADD
- (dst_mode, reg_mode[REGNO (base_reg)]))
+ else if (move2add_valid_value_p (REGNO (base_reg), mode)
&& reg_base_reg[REGNO (base_reg)] < 0
&& reg_symbol_ref[REGNO (base_reg)] == NULL_RTX)
{
@@ -2228,33 +2274,26 @@ move2add_note_store (rtx dst, const_rtx set, void *data)
reg_offset[regno] = INTVAL (SET_SRC (set));
/* We assign the same luid to all registers set to constants. */
reg_set_luid[regno] = move2add_last_label_luid + 1;
- reg_mode[regno] = mode;
+ move2add_record_mode (dst);
return;
default:
- invalidate:
- /* Invalidate the contents of the register. */
- reg_set_luid[regno] = 0;
- return;
+ goto invalidate;
}
base_regno = REGNO (base_reg);
/* If information about the base register is not valid, set it
up as a new base register, pretending its value is known
starting from the current insn. */
- if (reg_set_luid[base_regno] <= move2add_last_label_luid)
+ if (!move2add_valid_value_p (base_regno, mode))
{
reg_base_reg[base_regno] = base_regno;
reg_symbol_ref[base_regno] = NULL_RTX;
reg_offset[base_regno] = 0;
reg_set_luid[base_regno] = move2add_luid;
- reg_mode[base_regno] = mode;
+ gcc_assert (GET_MODE (base_reg) == mode);
+ move2add_record_mode (base_reg);
}
- else if (! MODES_OK_FOR_MOVE2ADD (dst_mode,
- reg_mode[base_regno]))
- goto invalidate;
-
- reg_mode[regno] = mode;
/* Copy base information from our base register. */
reg_set_luid[regno] = reg_set_luid[base_regno];
@@ -2262,17 +2301,17 @@ move2add_note_store (rtx dst, const_rtx set, void *data)
reg_symbol_ref[regno] = reg_symbol_ref[base_regno];
/* Compute the sum of the offsets or constants. */
- reg_offset[regno] = trunc_int_for_mode (offset
- + reg_offset[base_regno],
- dst_mode);
+ reg_offset[regno]
+ = trunc_int_for_mode (offset + reg_offset[base_regno], mode);
+
+ move2add_record_mode (dst);
}
else
{
- unsigned int endregno = regno + nregs;
-
- for (i = regno; i < endregno; i++)
- /* Reset the information about this register. */
- reg_set_luid[i] = 0;
+ invalidate:
+ /* Invalidate the contents of the register. */
+ move2add_record_mode (dst);
+ reg_mode[regno] = VOIDmode;
}
}
diff --git a/gcc/rtl.def b/gcc/rtl.def
index f8aea32b397..b4ce1b99f3f 100644
--- a/gcc/rtl.def
+++ b/gcc/rtl.def
@@ -962,8 +962,9 @@ DEF_RTL_EXPR(DEFINE_ASM_ATTRIBUTES, "define_asm_attributes", "V", RTX_EXTRA)
relational operator. Operands should have only one alternative.
1: A C expression giving an additional condition for recognizing
the generated pattern.
- 2: A template or C code to produce assembler output. */
-DEF_RTL_EXPR(DEFINE_COND_EXEC, "define_cond_exec", "Ess", RTX_EXTRA)
+ 2: A template or C code to produce assembler output.
+ 3: A vector of attributes to append to the resulting cond_exec insn. */
+DEF_RTL_EXPR(DEFINE_COND_EXEC, "define_cond_exec", "EssV", RTX_EXTRA)
/* Definition of an operand predicate. The difference between
DEFINE_PREDICATE and DEFINE_SPECIAL_PREDICATE is that genrecog will
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index b19868579a8..fe708488444 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -2711,6 +2711,7 @@ tablejump_p (const_rtx insn, rtx *labelp, rtx *tablep)
&& (table = next_active_insn (label)) != NULL_RTX
&& JUMP_TABLE_DATA_P (table))
{
+ gcc_assert (table == NEXT_INSN (label));
if (labelp)
*labelp = label;
if (tablep)
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index c7ef1d8e67e..8270d5880cf 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -2690,8 +2690,15 @@ sched_analyze_2 (struct deps_desc *deps, rtx x, rtx insn)
/* Always add these dependencies to pending_reads, since
this insn may be followed by a write. */
- if (!deps->readonly)
- add_insn_mem_dependence (deps, true, insn, x);
+ if (!deps->readonly)
+ {
+ if ((deps->pending_read_list_length
+ + deps->pending_write_list_length)
+ > MAX_PENDING_LIST_LENGTH
+ && !DEBUG_INSN_P (insn))
+ flush_pending_lists (deps, insn, true, true);
+ add_insn_mem_dependence (deps, true, insn, x);
+ }
sched_analyze_2 (deps, XEXP (x, 0), insn);
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 5c1dd25d8a4..9bb31e76ed9 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -2067,8 +2067,7 @@ simplify_byte_swapping_operation (enum rtx_code code, enum machine_mode mode,
rtx tem;
/* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
- if (GET_CODE (op0) == BSWAP
- && (CONST_INT_P (op1) || CONST_DOUBLE_AS_INT_P (op1)))
+ if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
{
tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
simplify_gen_unary (BSWAP, mode, op1, mode));
@@ -4814,7 +4813,7 @@ simplify_relational_operation_1 (enum rtx_code code, enum machine_mode mode,
/* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
if ((code == EQ || code == NE)
&& GET_CODE (op0) == BSWAP
- && (CONST_INT_P (op1) || CONST_DOUBLE_AS_INT_P (op1)))
+ && CONST_SCALAR_INT_P (op1))
return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
simplify_gen_unary (BSWAP, cmp_mode,
op1, cmp_mode));
diff --git a/gcc/symtab.c b/gcc/symtab.c
index 56f0de94d9c..f0355412e06 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -473,15 +473,31 @@ dump_symtab_base (FILE *f, symtab_node node)
node->symbol.order,
symtab_node_name (node));
dump_addr (f, " @", (void *)node);
- fprintf (f, "\n Type: %s\n", symtab_type_names[node->symbol.type]);
- fprintf (f, " Visibility:");
-
+ fprintf (f, "\n Type: %s", symtab_type_names[node->symbol.type]);
+
+ if (node->symbol.definition)
+ fprintf (f, " definition");
+ if (node->symbol.analyzed)
+ fprintf (f, " analyzed");
+ if (node->symbol.alias)
+ fprintf (f, " alias");
+ if (node->symbol.cpp_implicit_alias)
+ fprintf (f, " cpp_implicit_alias");
+ if (node->symbol.alias_target)
+ fprintf (f, " target:%s",
+ DECL_P (node->symbol.alias_target)
+ ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME
+ (node->symbol.alias_target))
+ : IDENTIFIER_POINTER (node->symbol.alias_target));
+ fprintf (f, "\n Visibility:");
if (node->symbol.in_other_partition)
fprintf (f, " in_other_partition");
if (node->symbol.used_from_other_partition)
fprintf (f, " used_from_other_partition");
if (node->symbol.force_output)
fprintf (f, " force_output");
+ if (node->symbol.forced_by_abi)
+ fprintf (f, " forced_by_abi");
if (node->symbol.resolution != LDPR_UNKNOWN)
fprintf (f, " %s",
ld_plugin_symbol_resolution_names[(int)node->symbol.resolution]);
@@ -653,6 +669,23 @@ verify_symtab_base (symtab_node node)
&& node->symbol.previous_sharing_asm_name->symbol.next_sharing_asm_name != node)
{
error ("double linked list of assembler names corrupted");
+ error_found = true;
+ }
+ if (node->symbol.analyzed && !node->symbol.definition)
+ {
+ error ("node is analyzed byt it is not a definition");
+ error_found = true;
+ }
+ if (node->symbol.cpp_implicit_alias && !node->symbol.alias)
+ {
+ error ("node is alias but not implicit alias");
+ error_found = true;
+ }
+ if (node->symbol.alias && !node->symbol.definition
+ && !lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
+ {
+ error ("node is alias but not definition");
+ error_found = true;
}
if (node->symbol.same_comdat_group)
{
@@ -745,6 +778,7 @@ symtab_used_from_object_file_p (symtab_node node)
/* Make DECL local. FIXME: We shouldn't need to mess with rtl this early,
but other code such as notice_global_symbol generates rtl. */
+
void
symtab_make_decl_local (tree decl)
{
@@ -783,4 +817,176 @@ symtab_make_decl_local (tree decl)
SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl);
}
+
+/* Return availability of NODE. */
+
+enum availability
+symtab_node_availability (symtab_node node)
+{
+ if (is_a <cgraph_node> (node))
+ return cgraph_function_body_availability (cgraph (node));
+ else
+ return cgraph_variable_initializer_availability (varpool (node));
+}
+
+/* Given NODE, walk the alias chain to return the symbol NODE is alias of.
+ If NODE is not an alias, return NODE.
+ When AVAILABILITY is non-NULL, get minimal availability in the chain. */
+
+symtab_node
+symtab_alias_ultimate_target (symtab_node node, enum availability *availability)
+{
+ bool weakref_p = false;
+
+ if (!node->symbol.alias)
+ {
+ if (availability)
+ *availability = symtab_node_availability (node);
+ return node;
+ }
+
+ /* To determine visibility of the target, we follow ELF semantic of aliases.
+ Here alias is an alternative assembler name of a given definition. Its
+ availablity prevails the availablity of its target (i.e. static alias of
+ weak definition is available.
+
+ Weakref is a different animal (and not part of ELF per se). It is just
+ alternative name of a given symbol used within one complation unit
+ and is translated prior hitting the object file. It inherits the
+ visibility of its target (i.e. weakref of non-overwritable definition
+ is non-overwritable, while weakref of weak definition is weak).
+
+ If we ever get into supporting targets with different semantics, a target
+ hook will be needed here. */
+
+ if (availability)
+ {
+ weakref_p = DECL_EXTERNAL (node->symbol.decl) && node->symbol.alias;
+ if (!weakref_p)
+ *availability = symtab_node_availability (node);
+ else
+ *availability = AVAIL_LOCAL;
+ }
+ while (node)
+ {
+ if (node->symbol.alias && node->symbol.analyzed)
+ node = symtab_alias_target (node);
+ else
+ {
+ if (!availability)
+ ;
+ else if (node->symbol.analyzed)
+ {
+ if (weakref_p)
+ {
+ enum availability a = symtab_node_availability (node);
+ if (a < *availability)
+ *availability = a;
+ }
+ }
+ else
+ *availability = AVAIL_NOT_AVAILABLE;
+ return node;
+ }
+ if (node && availability && weakref_p)
+ {
+ enum availability a = symtab_node_availability (node);
+ if (a < *availability)
+ *availability = a;
+ weakref_p = DECL_EXTERNAL (node->symbol.decl) && node->symbol.alias;
+ }
+ }
+ if (availability)
+ *availability = AVAIL_NOT_AVAILABLE;
+ return NULL;
+}
+
+/* C++ FE sometimes change linkage flags after producing same body aliases.
+
+ FIXME: C++ produce implicit aliases for virtual functions and vtables that
+ are obviously equivalent. The way it is doing so is however somewhat
+ kludgy and interferes with the visibility code. As a result we need to
+ copy the visibility from the target to get things right. */
+
+void
+fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target)
+{
+ if (is_a <cgraph_node> (node))
+ {
+ DECL_DECLARED_INLINE_P (node->symbol.decl)
+ = DECL_DECLARED_INLINE_P (target->symbol.decl);
+ DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
+ = DECL_DISREGARD_INLINE_LIMITS (target->symbol.decl);
+ }
+ /* FIXME: It is not really clear why those flags should not be copied for
+ functions, too. */
+ else
+ {
+ DECL_WEAK (node->symbol.decl) = DECL_WEAK (target->symbol.decl);
+ DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (target->symbol.decl);
+ DECL_VISIBILITY (node->symbol.decl) = DECL_VISIBILITY (target->symbol.decl);
+ }
+ DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (target->symbol.decl);
+ if (TREE_PUBLIC (node->symbol.decl))
+ {
+ DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (target->symbol.decl);
+ DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (target->symbol.decl);
+ DECL_COMDAT_GROUP (node->symbol.decl)
+ = DECL_COMDAT_GROUP (target->symbol.decl);
+ if (DECL_ONE_ONLY (target->symbol.decl)
+ && !node->symbol.same_comdat_group)
+ symtab_add_to_same_comdat_group ((symtab_node)node, (symtab_node)target);
+ }
+ node->symbol.externally_visible = target->symbol.externally_visible;
+}
+
+/* Add reference recording that NODE is alias of TARGET.
+ The function can fail in the case of aliasing cycles; in this case
+ it returns false. */
+
+bool
+symtab_resolve_alias (symtab_node node, symtab_node target)
+{
+ symtab_node n;
+
+ gcc_assert (!node->symbol.analyzed
+ && !vec_safe_length (node->symbol.ref_list.references));
+
+ /* Never let cycles to creep into the symbol table alias references;
+ those will make alias walkers to be infinite. */
+ for (n = target; n && n->symbol.alias;
+ n = n->symbol.analyzed ? symtab_alias_target (n) : NULL)
+ if (n == node)
+ {
+ if (is_a <cgraph_node> (node))
+ error ("function %q+D part of alias cycle", node->symbol.decl);
+ else if (is_a <varpool_node> (node))
+ error ("variable %q+D part of alias cycle", node->symbol.decl);
+ else
+ gcc_unreachable ();
+ node->symbol.alias = false;
+ return false;
+ }
+
+ /* "analyze" the node - i.e. mark the reference. */
+ node->symbol.definition = true;
+ node->symbol.alias = true;
+ node->symbol.analyzed = true;
+ ipa_record_reference (node, target, IPA_REF_ALIAS, NULL);
+
+ /* Alias targets become reudndant after alias is resolved into an reference.
+ We do not want to keep it around or we would have to mind updating them
+ when renaming symbols. */
+ node->symbol.alias_target = NULL;
+ DECL_ATTRIBUTES (node->symbol.decl)
+ = remove_attribute ("alias", DECL_ATTRIBUTES (node->symbol.decl));
+
+ if (node->symbol.cpp_implicit_alias && cgraph_state >= CGRAPH_STATE_CONSTRUCTION)
+ fixup_same_cpp_alias_visibility (node, target);
+
+ /* If alias has address taken, so does the target. */
+ if (node->symbol.address_taken)
+ symtab_alias_ultimate_target (target, NULL)->symbol.address_taken = true;
+ return true;
+}
#include "gt-symtab.h"
diff --git a/gcc/target.def b/gcc/target.def
index f4776a8df37..3ba3e0a2454 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2444,6 +2444,21 @@ DEFHOOK
int, (int),
default_register_priority)
+/* Return true if we need register usage leveling. */
+DEFHOOK
+(register_usage_leveling_p,
+ "A target hook which returns true if we need register usage leveling.\
+ That means if a few hard registers are equally good for the\
+ assignment, we choose the least used hard register. The register\
+ usage leveling may be profitable for some targets. Don't use the\
+ usage leveling for targets with conditional execution or targets\
+ with big register files as it hurts if-conversion and cross-jumping\
+ optimizations.\
+ \
+ The default version of this target hook returns always false.",
+ bool, (void),
+ default_register_usage_leveling_p)
+
/* Return true if maximal address displacement can be different. */
DEFHOOK
(different_addr_displacement_p,
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 80b4aa6bafd..d3a3f5fdd42 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -859,6 +859,12 @@ default_register_priority (int hard_regno ATTRIBUTE_UNUSED)
}
extern bool
+default_register_usage_leveling_p (void)
+{
+ return false;
+}
+
+extern bool
default_different_addr_displacement_p (void)
{
return false;
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index ce10ebc947b..2da6fb80631 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -135,6 +135,7 @@ extern int default_return_pops_args (tree, tree, int);
extern reg_class_t default_branch_target_register_class (void);
extern bool default_lra_p (void);
extern int default_register_priority (int);
+extern bool default_register_usage_leveling_p (void);
extern bool default_different_addr_displacement_p (void);
extern reg_class_t default_secondary_reload (bool, rtx, reg_class_t,
enum machine_mode,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d0f01c84c01..6385c7dc3b8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,434 @@
+2013-06-06 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * gcc.dg/vect/no-section-anchors-vect-68.c:
+ Add dg-skip-if aarch64_tiny.
+
+2013-06-05 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ PR C/57457
+ * c-c++-common/cilk-plus/AN/pr57457.c: New test.
+ * c-c++-common/cilk-plus/AN/pr57457-2.c: Likewise.
+
+2013-06-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51908
+ * g++.dg/cpp0x/decltype54.C: New.
+
+2013-06-05 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * gcc.dg/fshort-wchar.c: Add extra dg-options for
+ arm*-*-*eabi* targets.
+ * gcc.dg/tree-ssa/pr42585.c: Change dg-final to catch
+ arm*-*-* targets.
+ * gcc.dg/tree-ssa/pr43491.c: Likewise.
+
+2013-06-05 Manfred Schwarb <manfred99@gmx.ch>
+ Tobias Burnus <burnus@net-b.de>
+
+ * gfortran.dg/string_length_2.f90: Fix dg-do run.
+ * gfortran.dg/io_real_boz_3.f90: Remove extra space in "dg-do run".
+ * gfortran.dg/io_real_boz_4.f90: Ditto.
+ * gfortran.dg/io_real_boz_5.f90: Ditto.
+
+2013-06-05 Andreas Schwab <schwab@suse.de>
+
+ * gcc.dg/tree-ssa/attr-alias.c: Remove duplicated contents.
+
+2013-06-04 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/tree-ssa/attr-alias.c: New testcase.
+
+2013-06-04 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * c-c++-common/cilk-plus/AN/array_test1.c (main): Replaced argc, argv
+ parameters with void.
+ (main2): Removed argc parameter.
+ * c-c++-common/cilk-plus/AN/array_test2.c (main2): Likewise.
+ (main): Replaced argc, argv parameters with void.
+ * c-c++-common/cilk-plus/AN/array_test_ND.c (main): Likewise.
+ (main2): Removed argc parameter.
+ * c-c++-common/cilk-plus/AN/builtin_fn_custom.c (main): Replaced argc
+ argv parameters with void. Added __asm volatile to avoid optimization
+ on argc, if necessary.
+ * c-c++-common/cilk-plus/AN/builtin_fn_mutating (main): Likewise.
+ * c-c++-common/cilk-plus/AN/builtin_func_double.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/builtin_func_double2.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/conditional.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/exec-once.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/exec-once2.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/fn_ptr.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/gather-scatter-errors.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/gather_scatter.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/misc.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/parser_errors.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/parser_errors2.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/parser_errors3.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/parser_errors4.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/rank_mismatch2.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/sec_implicit_ex.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/sec_reduce_return.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/test_builtin_return.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/vla.c (main): Likewise.
+ * c-c++-common/cilk-plus/AN/comma-exp.c (main): Replaced argc, argv
+ parameters with void.
+ (main2): Removed argc parameter.
+ * c-c++-common/cilk-plus/AN/if_test.c (main2): Likewise.
+ (main): Replaced argc, argv parameters with void.
+ * c-c++-common/cilk-plus/AN/fp_triplet_values (main2): Replace argc,
+ argv parameters with void. Also renamed this function as main, and
+ delete the existing main.
+ * c-c++-common/cilk-plus/AN/sec_implicit.c (main2): Likewise.
+ * c-c++-common/cilk-plus/AN/sec_implicit2.c (main2): Likewise.
+ * c-c++-common/cilk-plus/AN/sec_reduce_max_min_ind.c (main2): Likewise.
+
+2013-06-04 Ian Bolton <ian.bolton@arm.com>
+
+ * gcc.target/aarch64/movi_1.c: New test.
+
+2013-06-04 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/37336
+ * gfortran.dg/finalize_12.f90: New.
+ * gfortran.dg/alloc_comp_basics_1.f90: Add BLOCK for
+ end of scope finalization.
+ * gfortran.dg/alloc_comp_constructor_1.f90: Ditto.
+ * gfortran.dg/allocatable_scalar_9.f90: Ditto.
+ * gfortran.dg/auto_dealloc_2.f90: Ditto.
+ * gfortran.dg/class_19.f03: Ditto.
+ * gfortran.dg/coarray_lib_alloc_1.f90: Ditto.
+ * gfortran.dg/coarray_lib_alloc_2.f90: Ditto.
+ * gfortran.dg/extends_14.f03: Ditto.
+ * gfortran.dg/move_alloc_4.f90: Ditto.
+ * gfortran.dg/typebound_proc_27.f03: Ditto.
+
+2013-06-04 Manfred Schwarb <manfred99@gmx.ch>
+
+ * gfortran.dg/bounds_check_7.f90: Remove "! {".
+ * gfortran.dg/coarray_poly_3.f90: Remove inactive, broken dg-*.
+ * gfortran.dg/default_initialization_5.f90: Update dg-do.
+ * gfortran.dg/g77/f77-edit-s-out.f: Fix broken dg-output.
+ * gfortran.dg/g77/f77-edit-t-out.f: Fix broken dg-output.
+ * gfortran.dg/g77/f77-edit-x-out.f: Fix broken dg-output.
+ * gfortran.dg/init_flag_11.f90: Fix broken dg-options.
+ * gfortran.dg/io_real_boz_3.f90: Add comment regarding dg-do run.
+ * gfortran.dg/io_real_boz_4.f90: Ditto.
+ * gfortran.dg/io_real_boz_5.f90: Ditto.
+ * gfortran.dg/namelist_print_1.f: Fix broken dg-output.
+ * gfortran.dg/read_x_eor.f90: Fix broken dg-output.
+ * gfortran.dg/repeat_1.f90: Improve dg-output pattern.
+ * gfortran.dg/spread_bounds_1.f90: Fix broken dg-output.
+ * gfortran.dg/transpose_2.f90: Fix dg-output.
+
+2013-06-03 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * c-c++-common/cilk-plus/AN/if_test_errors.c (main): New testcase.
+ * c-c++-common/cilk-plus/AN/rank_mismatch.c: Added a '-w' option to
+ dg-option and an header comment.
+
+2013-06-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57419
+ * g++.dg/cpp0x/sfinae46.C: New.
+ * g++.dg/cpp0x/defaulted13.C: Adjust.
+ * g++.dg/cpp0x/defaulted2.C: Likewise.
+ * g++.dg/cpp0x/defaulted26.C: Likewise.
+ * g++.dg/cpp0x/defaulted3.C: Likewise.
+ * g++.dg/cpp0x/error1.C: Likewise.
+ * g++.dg/cpp0x/implicit1.C: Likewise.
+ * g++.dg/cpp0x/implicit11.C: Likewise.
+ * g++.dg/cpp0x/inh-ctor13.C: Likewise.
+ * g++.dg/cpp0x/initlist47.C: Likewise.
+ * g++.dg/cpp0x/initlist9.C: Likewise.
+ * g++.dg/cpp0x/lambda/lambda-errloc.C: Likewise.
+ * g++.dg/cpp0x/lambda/lambda-errloc2.C: Likewise.
+ * g++.dg/cpp0x/nsdmi-local.C: Likewise.
+ * g++.dg/cpp0x/union4.C: Likewise.
+ * g++.dg/template/crash108.C: Likewise.
+ * g++.dg/template/crash41.C: Likewise.
+ * g++.old-deja/g++.jason/local.C: Likewise.
+ * g++.old-deja/g++.law/visibility3.C: Likewise.
+
+2013-06-03 Teresa Johnson <tejohnson@google.com>
+
+ * gcc.dg/vect/bb-slp-31.c: Update vect dump message.
+ * gcc.dg/vect/bb-slp-14.c: Ditto.
+ * gcc.dg/vect/fast-math-bb-slp-call-1.c: Ditto.
+ * gcc.dg/vect/bb-slp-23.c: Ditto.
+ * gcc.dg/vect/bb-slp-15.c: Ditto.
+ * gcc.dg/vect/fast-math-bb-slp-call-2.c: Ditto.
+ * gcc.dg/vect/bb-slp-24.c: Ditto.
+ * gcc.dg/vect/bb-slp-16.c: Ditto.
+ * gcc.dg/vect/bb-slp-25.c: Ditto.
+ * gcc.dg/vect/bb-slp-pattern-2.c: Ditto.
+ * gcc.dg/vect/bb-slp-17.c: Ditto.
+ * gcc.dg/vect/bb-slp-1.c: Ditto.
+ * gcc.dg/vect/bb-slp-26.c: Ditto.
+ * gcc.dg/vect/bb-slp-18.c: Ditto.
+ * gcc.dg/vect/bb-slp-2.c: Ditto.
+ * gcc.dg/vect/no-tree-reassoc-bb-slp-12.c: Ditto.
+ * gcc.dg/vect/bb-slp-27.c: Ditto.
+ * gcc.dg/vect/bb-slp-19.c: Ditto.
+ * gcc.dg/vect/bb-slp-3.c: Ditto.
+ * gcc.dg/vect/bb-slp-28.c: Ditto.
+ * gcc.dg/vect/bb-slp-4.c: Ditto.
+ * gcc.dg/vect/bb-slp-29.c: Ditto.
+ * gcc.dg/vect/bb-slp-5.c: Ditto.
+ * gcc.dg/vect/bb-slp-6.c: Ditto.
+ * gcc.dg/vect/bb-slp-8a.c: Ditto.
+ * gcc.dg/vect/bb-slp-7.c: Ditto.
+ * gcc.dg/vect/bb-slp-8b.c: Ditto.
+ * gcc.dg/vect/bb-slp-8.c: Ditto.
+ * gcc.dg/vect/bb-slp-9.c: Ditto.
+ * gcc.dg/vect/bb-slp-10.c: Ditto.
+ * gcc.dg/vect/bb-slp-11.c: Ditto.
+ * gcc.dg/vect/bb-slp-20.c: Ditto.
+ * gcc.dg/vect/bb-slp-cond-1.c: Ditto.
+ * gcc.dg/vect/bb-slp-21.c: Ditto.
+ * gcc.dg/vect/bb-slp-30.c: Ditto.
+ * gcc.dg/vect/bb-slp-13.c: Ditto.
+ * gcc.dg/vect/bb-slp-22.c: Ditto.
+ * g++.dg/vect/slp-pr50413.cc: Ditto.
+ * g++.dg/vect/slp-pr56812.cc: Ditto.
+ * g++.dg/vect/slp-pr50819.cc: Ditto.
+
+2013-06-01 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/57456
+ * gfortran.dg/class_array_17.f90: New.
+
+2013-05-31 Eric Botcazou <ebotcazou@adacore.com>
+
+ * ada/acats/floatstore.lst: New.
+ * ada/acats/run_all.sh: Process it.
+
+2013-05-31 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.target/powerpc/e500-ord-1.c: New test.
+ * gcc.target/powerpc/e500-ord-2.c: Likewise.
+ * gcc.target/powerpc/e500-unord-1.c: Likewise.
+ * gcc.target/powerpc/e500-unord-2.c: Likewise.
+
+2013-05-31 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * g++.dg/torture/pr54684.C: Add -fno-short-enums.
+
+2013-05-31 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * gcc.target/arm/pr56184.C: Add -fno-short-enums.
+
+2013-05-31 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * g++.old-deja/g++.robertl/eb76.C: Add -fno-short-enums.
+
+2013-05-31 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ PR c/57452
+ * c-c++-common/cilk-plus/AN/if_test.c: Fixed out of bounds issue in
+ test-case.
+
+2013-05-31 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.dg/shrink-wrap-alloca.c: Use __builtin_alloca.
+
+2013-05-31 Marek Polacek <polacek@redhat.com>
+
+ PR tree-optimization/57478
+ PR tree-optimization/57453
+ * gcc.dg/torture/pr57478.c: New test.
+
+2013-05-31 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/57456
+ * gfortran.dg/class_array_17.f90: New.
+
+2013-05-31 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/56315
+ * gcc.target/arm/iordi3-opt.c: New test.
+
+2013-05-31 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/54190
+ PR fortran/57217
+ * gfortran.dg/dummy_procedure_5.f90: Modified error message.
+ * gfortran.dg/interface_26.f90: Ditto.
+ * gfortran.dg/proc_ptr_11.f90: Ditto.
+ * gfortran.dg/proc_ptr_15.f90: Ditto.
+ * gfortran.dg/proc_ptr_comp_20.f90: Ditto.
+ * gfortran.dg/proc_ptr_comp_33.f90: Ditto.
+ * gfortran.dg/proc_ptr_result_5.f90: Ditto.
+ * gfortran.dg/typebound_override_1.f90: Ditto.
+ * gfortran.dg/typebound_override_4.f90: Ditto.
+ * gfortran.dg/typebound_proc_6.f03: Ditto.
+ * gfortran.dg/assumed_type_7.f90: New test.
+ * gfortran.dg/typebound_override_5.f90: New test.
+ * gfortran.dg/typebound_override_6.f90: New test.
+ * gfortran.dg/typebound_override_7.f90: New test.
+
+2013-05-30 Tobias Burnus <burnus@net-b.de>
+
+ PR middle-end/57073
+ * gfortran.dg/power_6.f90: New.
+
+2013-05-30 Ian Bolton <ian.bolton@arm.com>
+
+ * gcc.target/aarch64/insv_1.c: New test.
+
+2013-05-30 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * g++.dg/cpp0x/alias-decl-debug-0.C: Add aarch64*-*-* to the
+ dg-skip-if "No stabs".
+
+2013-05-30 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/54189
+ * gfortran.dg/assumed_size_1.f90: New.
+
+2013-05-30 Zhenqiang Chen <zhenqiang.chen@linaro.org>
+
+ * gcc.dg/shrink-wrap-alloca.c: New added.
+ * gcc.dg/shrink-wrap-pretend.c: New added.
+ * gcc.dg/shrink-wrap-sibcall.c: New added.
+
+2013-05-30 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/57458
+ * gfortran.dg/assumed_rank_13.f90: New.
+
+2013-05-29 Easwaran Raman <eraman@google.com>
+
+ PR tree-optimization/57442
+ * gcc.dg/tree-ssa/reassoc-30.c: New testcase.
+
+2013-05-29 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ PR tree-optimization/57441
+ * gcc.c-torture/compile/pr57441.c: New.
+
+2013-05-29 Dehao Chen <dehao@google.com>
+
+ PR testsuite/57413
+ * gcc.dg/debug/dwarf2/discriminator.c: Restrict the test to linux-gnu.
+
+2013-05-29 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/37336
+ * gfortran.dg/auto_dealloc_2.f90: Update _free count in the dump.
+ * gfortran.dg/class_19.f03: Ditto.
+
+2013-05-29 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/vect/bb-slp-32.c: New testcase.
+
+2013-05-28 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * c-c++-common/cilk-plus/AN/array_test1.c: New test.
+ * c-c++-common/cilk-plus/AN/array_test2.c: Likewise.
+ * c-c++-common/cilk-plus/AN/array_test_ND.c: Likewise.
+ * c-c++-common/cilk-plus/AN/builtin_func_double.c: Likewise.
+ * c-c++-common/cilk-plus/AN/builtin_func_double2.c: Likewise.
+ * c-c++-common/cilk-plus/AN/gather-scatter-errors.c: Likewise.
+ * c-c++-common/cilk-plus/AN/if_test.c: Likewise.
+ * c-c++-common/cilk-plus/AN/sec_implicit_ex.c: Likewise.
+ * c-c++-common/cilk-plus/AN/decl-ptr-colon.c: Likewise.
+ * c-c++-common/cilk-plus/AN/dimensionless-arrays.c: Likewise.
+ * c-c++-common/cilk-plus/AN/fn_ptr.c: Likewise.
+ * c-c++-common/cilk-plus/AN/fp_triplet_values.c: Likewise.
+ * c-c++-common/cilk-plus/AN/gather-scatter.c: Likewise.
+ * c-c++-common/cilk-plus/AN/misc.c: Likewise.
+ * c-c++-common/cilk-plus/AN/parser_errors.c: Likewise.
+ * c-c++-common/cilk-plus/AN/parser_errors2.c: Likewise.
+ * c-c++-common/cilk-plus/AN/parser_errors3.c: Likewise.
+ * c-c++-common/cilk-plus/AN/parser_errors4.c: Likewise.
+ * c-c++-common/cilk-plus/AN/rank_mismatch.c: Likewise.
+ * c-c++-common/cilk-plus/AN/rank_mismatch2.c: Likewise.
+ * c-c++-common/cilk-plus/AN/rank_mismatch3.c: Likewise.
+ * c-c++-common/cilk-plus/AN/sec_implicit.c: Likewise.
+ * c-c++-common/cilk-plus/AN/sec_implicit2.c: Likewise.
+ * c-c++-common/cilk-plus/AN/sec_reduce_max_min_ind.c: Likewise.
+ * c-c++-common/cilk-plus/AN/tst_lngth.c: Likewise.
+ * c-c++-common/cilk-plus/AN/vla.c: Likewise.
+ * c-c++-common/cilk-plus/AN/an-if.c: Likewise.
+ * c-c++-common/cilk-plus/AN/builtin_fn_custom.c: Likewise.
+ * c-c++-common/cilk-plus/AN/builtin_fn_mutating.c: Likewise.
+ * c-c++-common/cilk-plus/AN/comma_exp.c: Likewise.
+ * c-c++-common/cilk-plus/AN/conditional.c: Likewise.
+ * c-c++-common/cilk-plus/AN/exec-once.c: Likewise.
+ * c-c++-common/cilk-plus/AN/exec-once2.c: Likewise.
+ * c-c++-common/cilk-plus/AN/gather_scatter.c: Likewise.
+ * c-c++-common/cilk-plus/AN/n-ptr-test.c: Likewise.
+ * c-c++-common/cilk-plus/AN/side-effects-1.c: Likewise.
+ * c-c++-common/cilk-plus/AN/test_builtin_return.c: Likewise.
+ * c-c++-common/cilk-plus/AN/test_sec_limits.c: Likewise.
+ * gcc.dg/cilk-plus/cilk-plus.exp: New script.
+
+2013-05-29 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/37336
+ * gfortran.dg/finalize_11.f90: New.
+ * gfortran.dg/finalize_4.f03: Remove dg-error.
+ * gfortran.dg/finalize_5.f03: Ditto.
+ * gfortran.dg/finalize_6.f03: Ditto.
+ * gfortran.dg/finalize_7.f03: Ditto.
+
+2013-05-28 Tobias Burnus <burnus@net-b.de>
+
+ * gfortran.dg/class_array_16.f90: New.
+
+2013-05-28 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/57435
+ * testsuite/gfortran.dg/use_29.f90: New.
+
+2013-05-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/fp_exception.adb: New test.
+
+2013-05-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/56787
+ * gcc.dg/vect/pr56787.c: New testcase.
+
+2013-05-28 Janus Weil <janus@gcc.gnu.org>
+ Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/57217
+ * gfortran.dg/typebound_override_4.f90: New.
+
+2013-05-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/57411
+ * g++.dg/opt/pr57411.C: New testcase.
+
+2013-05-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/builtin-bswap-8.c: Compile at -O2.
+ * gcc.dg/builtin-bswap-9.c: Likewise.
+
+2013-05-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.target/sparc/bmaskbshuf.c: Remove superfluous options.
+
+2013-05-27 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/57412
+ * gcc.dg/gomp/pr57412.c: New testcase.
+
+2013-05-27 Bud Davis <jmdavis@link.com>
+
+ PR fortran/50405
+ * gfortran.dg/stfunc_8.f90: New.
+
+2013-05-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/57343
+ * gcc.dg/torture/pr57343.c: New testcase.
+
+2013-05-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/57417
+ * gcc.dg/torture/pr57417.c: New testcase.
+
2013-05-27 Richard Biener <rguenther@suse.de>
PR tree-optimization/57396
@@ -58,6 +489,10 @@
PR tree-optimization/57294
* gcc.dg/ipa/pr57294.c: New test.
+2013-05-24 Dehao Chen <dehao@google.com>
+
+ * gcc.dg/debug/dwarf2/discriminator.c: New Testcase.
+
2013-05-24 Ian Bolton <ian.bolton@arm.com>
* gcc.target/aarch64/scalar_intrinsics.c
diff --git a/gcc/testsuite/ada/acats/floatstore.lst b/gcc/testsuite/ada/acats/floatstore.lst
new file mode 100644
index 00000000000..fe1746983e4
--- /dev/null
+++ b/gcc/testsuite/ada/acats/floatstore.lst
@@ -0,0 +1 @@
+cxg2021
diff --git a/gcc/testsuite/ada/acats/run_all.sh b/gcc/testsuite/ada/acats/run_all.sh
index 3d8aca91105..5ec3e13083c 100755
--- a/gcc/testsuite/ada/acats/run_all.sh
+++ b/gcc/testsuite/ada/acats/run_all.sh
@@ -225,6 +225,10 @@ for chapter in $chapters; do
if [ $? -eq 0 ]; then
extraflags="$extraflags -gnatE"
fi
+ grep $i $testdir/floatstore.lst > /dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ extraflags="$extraflags -ffloat-store"
+ fi
grep $i $testdir/stackcheck.lst > /dev/null 2>&1
if [ $? -eq 0 ]; then
extraflags="$extraflags -fstack-check"
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/an-if.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/an-if.c
new file mode 100644
index 00000000000..4bf85b5ca93
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/an-if.c
@@ -0,0 +1,48 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+#if HAVE_IO
+#include <stdio.h>
+#endif
+#include <assert.h>
+
+const int n = 8;
+
+float x[8], y[8], z[8];
+
+int main() {
+ int i = 0;
+ float x_sum =0;
+ for(i=1; i<=5; i+=4 ) {
+ x[0:n] = 3;
+ y[0:n] = i;
+ z[0:n] = 0;
+#if HAVE_IO
+ printf("x\ty\tz\n");
+ for( size_t k=0; k<n; ++k ) {
+ printf("%g\t%g\t%g\n",x[k],y[k],z[k]);
+ }
+ x_sum = __sec_reduce_add (x[0:n]);
+ printf("sec_reduce_add (x[0:n]) = %6.3f\n", x_sum);
+#endif
+ assert( __sec_reduce_add(x[0:n])==3*n );
+ assert( __sec_reduce_add(y[0:n])==i*n );
+ assert( __sec_reduce_add(z[0:n])==0 );
+
+ if (x[0:n] >= y[0:n]) {
+ z[0:n] = x[0:n] - y[0:n];
+ } else {
+ z[0:n] = x[0:n] + y[0:n];
+ }
+#if HAVE_IO
+ printf("x\ty\tz\n");
+ for( size_t k=0; k<n; ++k ) {
+ printf("%g\t%g\t%g\n",x[k],y[k],z[k]);
+ }
+#endif
+ assert( __sec_reduce_add(x[0:n])==3*n );
+ assert( __sec_reduce_add(y[0:n])==i*n );
+ assert( __sec_reduce_add(z[0:n])==(3>=i?3-i:3+i)*n );
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/array_test1.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/array_test1.c
new file mode 100644
index 00000000000..e4f1ea8a73a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/array_test1.c
@@ -0,0 +1,84 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+#include <stdlib.h>
+
+int main2 (char **argv);
+
+int main(void)
+{
+ int x = 0;
+ const char *array[] = {"a.out", "5"};
+ x = main2 ((char **)array);
+ return x;
+}
+
+int main2 (char **argv)
+{
+ int array[10], ii = 0, x = 2, z= 0 , y = 0 ;
+ for (ii = 0; ii < 10; ii++)
+ array[ii] = 10;
+
+ array[0:10:1] = 15;
+
+ for (ii = 0; ii < 10; ii++)
+ if (array[ii] != 15)
+ return 5;
+ array[0:5:2] = 20;
+
+ for (ii = 0; ii < 10; ii += 2)
+ if (array[ii] != 20)
+ return 4;
+
+
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+
+ array[x:5:z] = 50;
+
+ for (ii = x; ii < 10; ii += z)
+ if (array[ii] != 50)
+ return 3;
+
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+ y = 10-atoi(argv[1]);
+
+ array[x:y:z] = 505;
+ for (ii = x; ii < 10; ii += z)
+ if (array[ii] != 505)
+ return 2;
+
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+ y = 10-atoi(argv[1]);
+
+ array[x:y:((10-atoi(argv[1]))/atoi(argv[1]))] = 25;
+
+ for (ii = x; ii < 10; ii += z)
+ if (array[ii] != 25)
+ return 1;
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+ y = 10-atoi(argv[1]);
+
+ array[atoi(argv[1]):(10-atoi(argv[1])):((10-atoi(argv[1]))/atoi(argv[1]))] =
+ 1400;
+ for (ii = x; ii < 10; ii += z)
+ if (array[ii] != 1400)
+ return 1;
+
+
+ array[atoi("5"):5:1] = 5555;
+
+ for (ii = atoi ("5"); ii < 10; ii++)
+ if (array[ii] != 5555)
+ return 2;
+
+
+ array[atoi("5"):atoi("5"):atoi("1")] = 9999;
+ for (ii = atoi ("5"); ii < (atoi ("5") + atoi ("5")); ii += atoi ("1"))
+ if (array[ii] != 9999)
+ return 3;
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/array_test2.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/array_test2.c
new file mode 100644
index 00000000000..60f2de2834a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/array_test2.c
@@ -0,0 +1,128 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+#include <stdlib.h>
+int main2 (char **argv);
+int main(void)
+{
+ int x = 0;
+ const char *array[] = {"a.out", "5"};
+ x = main2 ((char **)array);
+ return x;
+}
+
+
+int main2(char **argv)
+{
+ int array[10], array2[10], ii = 0, x = 2, z= 0 , y = 0 ;
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 10;
+ array2[ii] = 5000000;
+ }
+
+ array2[0:10:1] = array[0:10:1];
+
+ for (ii = 0; ii < 10; ii++)
+ if (array2[ii] != array[ii])
+ return 1;
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 10;
+ array2[ii] = 5000000;
+ }
+
+ array2[0:5:2] = array[0:5:2];
+
+ for (ii = 0; ii < 10; ii += 2)
+ if (array[ii] != array2[ii])
+ return 2;
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 10;
+ array2[ii] = 5000000;
+ }
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+
+ array2[x:5:z] = array[x:5:z];
+
+ for (ii = x; ii < 5; ii += z)
+ if (array2[ii] != array[ii])
+ return 3;
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 500;
+ array2[ii] = 1000000;
+ }
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+ y = 10-atoi(argv[1]);
+
+ array2[x:y:z] = array[x:y:z];
+ for (ii = x; ii < 10; ii = ii + z)
+ if (array2[ii] != array[ii])
+ return 4;
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 500;
+ array2[ii] = 1000000;
+ }
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+ y = 10-atoi(argv[1]);
+
+ array[x:y:((10-atoi(argv[1]))/atoi(argv[1]))] =
+ array2[x:y:((10-atoi(argv[1]))/atoi(argv[1]))];
+
+ for (ii = x; ii < 10; ii += z)
+ if (array[ii] != array2[ii])
+ return 5;
+
+
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+ y = 10-atoi(argv[1]);
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 500;
+ array2[ii] = 1000000;
+ }
+
+ array[atoi(argv[1]):(10-atoi(argv[1])):((10-atoi(argv[1]))/atoi(argv[1]))] =
+ array2[atoi(argv[1]):(10-atoi(argv[1])):((10-atoi(argv[1]))/atoi(argv[1]))];
+ for (ii = x; ii < 10; ii += z)
+ if (array[ii] != array2[ii])
+ return 6;
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 4;
+ array2[ii] = 2;
+ }
+
+ array[atoi("5"):5:1] = array2[atoi("5"):5:1];
+
+ for (ii = atoi ("5"); ii < 10; ii++)
+ if (array[ii] != array2[ii])
+ return (7);
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 5;
+ array2[ii] = 1;
+ }
+ array[atoi("5"):atoi("5"):atoi("1")] = array2[atoi("5"):atoi("5"):atoi("1")];
+
+ for (ii = 5; ii < 10; ii++)
+ if (array2[ii] != array[ii])
+ return 8;
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/array_test_ND.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/array_test_ND.c
new file mode 100644
index 00000000000..e89bbab268b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/array_test_ND.c
@@ -0,0 +1,102 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+#include <stdlib.h>
+int main2(char **argv);
+int main(void)
+{
+ int x = 0;
+ const char *array[] = {"a.out", "10", "15"};
+ x = main2 ((char **)array);
+ return x;
+}
+
+int main2(char **argv)
+{
+ int array[10][15], ii = 0, jj = 0,x = 0, z= 1 , y = 10 ;
+ int array_2[10][15];
+ int argc = 3;
+ __asm volatile ("" : "+r" (argc));
+
+ for (ii = 0; ii < 10; ii++) {
+ for (jj = 0; jj< 15; jj++) {
+ array[ii][jj] = ii+jj;
+ array_2[ii][jj] = 0;
+ }
+ }
+ array_2[0:5:2][0:5:3] = array[0:5:2][0:5:3] + 1 + 5 + array[0][5] + x;
+
+ for (ii = 0; ii < 10; ii += 2)
+ {
+ for (jj = 0; jj < 15; jj += 3)
+ {
+ if (array_2[ii][jj] != array[ii][jj] + 1 + 5 + array[0][5] + x)
+ return 2;
+ }
+ }
+
+
+ for (ii = 0; ii < 10; ii++) {
+ for (jj = 0; jj< 15; jj++) {
+ array[ii][jj] = ii+jj;
+ array_2[ii][jj] = 0;
+ }
+ }
+ x = atoi(argv[1]);
+ y = atoi(argv[2]);
+ array_2[0:x:1][0:y:1] = array[0:x:1][0:y:1] + x + y + array[0:x:1][0:y:1];
+
+ for (ii = 0; ii < x; ii++)
+ {
+ for (jj = 0; jj < y; jj++)
+ {
+ if (array_2[ii][jj] != array[ii][jj] + x + y + array[ii][jj])
+ return 3;
+ }
+ }
+
+ for (ii = 0; ii < 10; ii++) {
+ for (jj = 0; jj< 15; jj++) {
+ array[ii][jj] = ii+jj;
+ array_2[ii][jj] = 0;
+ }
+ }
+ x = atoi(argv[1]);
+ y = atoi(argv[2]);
+ z = (20- atoi (argv[1]))/atoi(argv[1]);
+ /* (20-10)/10 evaluates to 1 all the time :-). */
+ array_2[0:x:z][0:y:z] = array[0:x:z][0:y:z] + array[0:x:z][0:y:z] + y + z;
+
+ for (ii = 0; ii < x; ii += z)
+ {
+ for (jj = 0; jj < y; jj += z)
+ {
+ if (array_2[ii][jj] != array[ii][jj] + array[ii][jj] + y + z)
+ return 4;
+ }
+ }
+
+
+
+ for (ii = 0; ii < 10; ii++) {
+ for (jj = 0; jj< 15; jj++) {
+ array[ii][jj] = ii+jj;
+ array_2[ii][jj] = 0;
+ }
+ }
+ x = argc-3;
+ y = 20-atoi(argv[1]);
+ z = (20- atoi (argv[1]))/atoi(argv[1]);
+ /* (20-10)/10 evaluates to 1 all the time :-). */
+ array_2[(argc-3):(20-atoi(argv[1])):(20-atoi(argv[1]))/atoi(argv[1])][(argc-3):(30-atoi(argv[2])): ((30-atoi(argv[2]))/atoi(argv[2]))] = array[(argc-3):20-atoi(argv[1]):(20-atoi(argv[1]))/atoi(argv[1])][(argc-3):(30-atoi(argv[2])): (30-atoi(argv[2]))/atoi(argv[2])] + array[(argc-3):20-atoi(argv[1]):(20-atoi(argv[1]))/atoi(argv[1])][(argc-3):(30-atoi(argv[2])): (30-atoi(argv[2]))/atoi(argv[2])] * array[(argc-3):20-atoi(argv[1]):(20-atoi(argv[1]))/atoi(argv[1])][(argc-3):(30-atoi(argv[2])): (30-atoi(argv[2]))/atoi(argv[2])];
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ for (jj = 0; jj < 15; jj++)
+ {
+ if (array_2[ii][jj] != array[ii][jj] + array[ii][jj] * array[ii][jj])
+ return 5;
+ }
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_fn_custom.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_fn_custom.c
new file mode 100644
index 00000000000..c5d3d7c7530
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_fn_custom.c
@@ -0,0 +1,68 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+#if HAVE_IO
+#include <stdio.h>
+#endif
+/* #include <stdlib.h> */
+
+double my_func (double x, double y)
+{
+ if (x > y)
+ return x;
+ else
+ return y;
+}
+
+
+/* char __sec_reduce_add (int *); */
+int main(void)
+{
+ int ii,array[10], y = 0, y_int = 0, array2[10];
+ double x, yy, array3[10], array4[10];
+ double max_value = 0.000, min_value = 0.000, add_value, mul_value = 1.00;
+ int max_index = 0, min_index = 0;
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 1+ii;
+ array2[ii]= 2;
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ if (ii%2 && ii)
+ array3[ii] = (double)(1.0000/(double)ii);
+ else
+ array3[ii] = (double) ii + 0.10;
+ array4[ii] = (double) (1.00000/ (double)(ii+1));
+ }
+
+ /* array[:] = 5; */
+ x = __sec_reduce (0, array3[:] * array4[:], my_func);
+ y = __sec_reduce_max_ind ( array3[:] * array4[:]);
+
+ /* Initialize it to the first variable. */
+ max_value = array3[0] * array4[0];
+ for (ii = 0; ii < 10; ii++)
+ if (array3[ii] * array4[ii] > max_value) {
+ max_value = array3[ii] * array4[ii];
+ max_index = ii;
+ }
+
+
+
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ printf("%5.3f ", array3[ii] * array4[ii]);
+ printf("\n");
+ printf("Max = %5.3f\t Max Index = %2d\n", x, y);
+#endif
+
+ if (x != max_value)
+ return 1;
+
+ if (y != max_index)
+ return 2;
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_fn_mutating.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_fn_mutating.c
new file mode 100644
index 00000000000..66355650920
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_fn_mutating.c
@@ -0,0 +1,68 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+#if HAVE_IO
+#include <stdio.h>
+#endif
+/* #include <stdlib.h> */
+
+void my_func (double *x, double y)
+{
+ if (*x < y)
+ *x = y;
+}
+
+
+int main(void)
+{
+ int ii,array[10], y = 0, y_int = 0, array2[10];
+ double x = 0.000, yy, array3[10], array4[10];
+ double max_value = 0.000, min_value = 0.000, add_value, mul_value = 1.00;
+ int max_index = 0, min_index = 0;
+#if 1
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 1+ii;
+ array2[ii]= 2;
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ if (ii%2 && ii)
+ array3[ii] = (double)(1.0000/(double)ii);
+ else
+ array3[ii] = (double) ii + 0.10;
+ array4[ii] = (double) (1.00000/ (double)(ii+1));
+ }
+#endif
+ /* array[:] = 5; */
+ __sec_reduce_mutating (&x, array3[:] * array4[:], my_func);
+#if 1
+ y = __sec_reduce_max_ind ( array3[:] * array4[:]);
+
+ /* Initialize it to the first variable. */
+ max_value = array3[0] * array4[0];
+ for (ii = 0; ii < 10; ii++)
+ if (array3[ii] * array4[ii] > max_value) {
+ max_value = array3[ii] * array4[ii];
+ max_index = ii;
+ }
+
+
+
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ printf("%5.3f ", array3[ii] * array4[ii]);
+ printf("\n");
+ printf("Max = %5.3f\t Max Index = %2d\n", x, y);
+ printf("Max = %5.3f\t Max Index = %2d\n", max_value, max_index);
+#endif
+
+ if (x != max_value)
+ return 1;
+
+ if (y != max_index)
+ return 2;
+#endif
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_func_double.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_func_double.c
new file mode 100644
index 00000000000..0c05994ee30
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_func_double.c
@@ -0,0 +1,124 @@
+#if HAVE_IO
+#include <stdio.h>
+#endif
+/* #include <stdlib.h> */
+
+/* char __sec_reduce_add (int *); */
+int main(void)
+{
+ int ii,array[10], y = 0, y_int = 0, array2[10];
+ double x, yy, array3[10], array4[10];
+ double max_value = 0.000, min_value = 0.000, add_value, mul_value = 1.00;
+ int max_index = 0, min_index = 0;
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 1+ii;
+ array2[ii]= 2;
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ if (ii%2 && ii)
+ array3[ii] = (double)(1.0000/(double)ii);
+ else
+ array3[ii] = (double) ii + 0.10;
+ array4[ii] = (double) (1.00000/ (double)(ii+1));
+ }
+
+ /* array[:] = 5; */
+ x = __sec_reduce_max (array3[:] * array4[:]);
+ y = __sec_reduce_max_ind ( array3[:] * array4[:]);
+
+ /* Initialize it to the first variable. */
+ max_value = array3[0] * array4[0];
+ for (ii = 0; ii < 10; ii++)
+ if (array3[ii] * array4[ii] > max_value) {
+ max_value = array3[ii] * array4[ii];
+ max_index = ii;
+ }
+
+
+
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ printf("%5.3f ", array3[ii] * array4[ii]);
+ printf("\n");
+ printf("Max = %5.3f\t Max Index = %2d\n", x, y);
+#endif
+
+ if (x != max_value)
+ return 1;
+
+ if (y != max_index)
+ return 2;
+
+ x = __sec_reduce_min (array3[:] * array4[:]);
+ y = __sec_reduce_min_ind ( array3[:] * array4[:]);
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ printf("%5.3f ", array3[ii] * array4[ii]);
+ printf("\n");
+ printf("Min = %5.3f\t Min Index = %2d\n", x, y);
+#endif
+
+ /* Initialize it to the first variable. */
+ min_value = array3[0] * array4[0];
+ for (ii = 0; ii < 10; ii++)
+ if (array3[ii] * array4[ii] < min_value) {
+ min_value = array3[ii] * array4[ii];
+ min_index = ii;
+ }
+
+ if (x != min_value)
+ return 3;
+ if (y != min_index)
+ return 4;
+
+ x = __sec_reduce_add (array3[:] * array4[:]);
+ yy = __sec_reduce_mul ( array3[:] * array4[:]);
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ printf("%5.3f ", array3[ii] * array4[ii]);
+ printf("\n");
+ printf("Add = %5.3f\t Mul = %f\n", x, yy);
+#endif
+
+ /* Initialize it to the first variable. */
+ add_value = 0.0000;
+ mul_value = 1.0000;
+ for (ii = 0; ii < 10; ii++)
+ {
+ add_value += (array3[ii] * array4[ii]);
+ mul_value *= (array3[ii] * array4[ii]);
+ }
+
+ if (x != add_value)
+ return 5;
+ if (yy != mul_value)
+ return 6;
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ if (ii%2 && ii)
+ array3[ii] = (double)(1.0000/(double)ii);
+ else
+ array3[ii] = (double) ii + 0.00;
+ array4[ii] = (double) (1.00000/ (double)(ii+1));
+ }
+ y_int = __sec_reduce_any_zero (array3[:] * array4[:]);
+ y = __sec_reduce_all_zero ( array3[:] * array4[:]);
+
+ if (y_int != 1)
+ return 7;
+
+ if (y != 0)
+ return 8;
+
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ printf("%5.3f ", array3[ii] * array4[ii]);
+ printf("\n");
+ printf("Any Zeros = %d\t All Zeros = %d\n", y_int, y);
+#endif
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_func_double2.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_func_double2.c
new file mode 100644
index 00000000000..7337a5106d9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/builtin_func_double2.c
@@ -0,0 +1,76 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+#if HAVE_IO
+#include <stdio.h>
+#endif
+
+int main(void)
+{
+ int argc = 1;
+ int ii,array[10], y = 0, y_int = 0, array2[10], y_int2=0, y2=0;
+ double x, yy, array3[10], array4[10];
+ int all_zero, all_nonzero, any_zero, any_nonzero;
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 0;
+ array2[ii] = 5;
+ if (ii%2 && ii)
+ array3[ii] = (double)(1.0000/(double)ii);
+ else
+ array3[ii] = (double) ii + 0.00;
+ array4[ii] = (double) (1.00000/ (double)(ii+1));
+ }
+ __asm volatile ("" : "+r" (argc));
+ y_int = __sec_reduce_any_nonzero (array3[:] + array[4]);
+ y_int2 = __sec_reduce_any_zero (array3[:] + array[4]);
+ y = __sec_reduce_all_nonzero ((array3[:] + array4[:]) * (argc-1));
+ y2 = __sec_reduce_all_zero ((array3[:] + array4[:]) * (argc-1));
+
+ any_zero = 0;
+ any_nonzero = 0;
+ for (ii = 0; ii < 10; ii++)
+ {
+ if ((array3[ii] + array[4]) == 0)
+ any_zero = 1;
+ else
+ any_nonzero = 1;
+ }
+
+ if (any_nonzero != y_int)
+ return 1;
+ if (any_zero != y_int2)
+ return 2;
+
+
+ all_zero = 0;
+ all_nonzero = 0;
+ for (ii = 0; ii < 10; ii++)
+ {
+ if (((array3[ii] + array4[ii]) * (argc-1)) == 0)
+ all_zero = 1;
+ else
+ all_nonzero = 1;
+ }
+
+ if (y != all_nonzero)
+ return 3;
+ if (all_zero != y2)
+ return 4;
+
+
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++) {
+ printf("%5.3f ", array3[ii] +array4[ii]);
+ }
+ printf("\n");
+ for (ii = 0; ii < 10; ii++) {
+ printf("%5.3f ", (array3[ii] + array4[ii]) * (argc-1));
+ }
+ printf("\n");
+ printf("Any Non-zeros (1st line) = %d\t All non-zeros (1st line) = %d\n",
+ y_int, y);
+ printf("Any zeros (2nd line) = %d\t All zeros (2nd line) = %d\n", y_int2, y2);
+#endif
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/comma_exp.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/comma_exp.c
new file mode 100644
index 00000000000..845d916ab96
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/comma_exp.c
@@ -0,0 +1,55 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+#include <stdlib.h>
+
+int main2 (char **argv);
+int main(void)
+{
+ int x = 0;
+ const char *array[] = {"a.out", "5"};
+ x = main2 ((char **)array);
+ return x;
+}
+
+int main2 (char **argv)
+{
+ int argc = 2;
+ int array[10], array2[10], ii = 0, x = 2, z= 0 , y = 0 ;
+ __asm volatile ("" : "+r" (argc));
+ for (ii = 0; ii < 10; ii++)
+ array[ii] = 10;
+
+ for (ii = 0; ii < 10; ii++)
+ array2[ii] = 1;
+
+ array[0:10:1] = (array[:], 15);
+
+ for (ii = 0; ii < 10; ii++)
+ if (array[ii] != 15)
+ return 1;
+ array[0:5:2] = (argc+2, 20);
+
+ for (ii = 0; ii < 10; ii += 2)
+ if (array[ii] != 20)
+ return 2;
+
+
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+
+ array[x:5:z] = 50;
+
+ array[:] = (atoi(argv[1]), (array2[0:10]+5));
+
+ for (ii = 0; ii < 10; ii++)
+ if (array[ii] != 6)
+ return (3);
+
+ array[:] = (atoi(argv[1]), (array2[0:10]+array2[0:10]));
+ for (ii = 0; ii < 10; ii++)
+ if (array[ii] != 2)
+ return 4;
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/conditional.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/conditional.c
new file mode 100644
index 00000000000..07c50173bfb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/conditional.c
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+#include <stdlib.h>
+int main(void)
+{
+ int argc = 1;
+ short array[1000], array2[1000], *array3, cond[1000], ii = 0;
+
+ __asm volatile ("" : "+r" (argc));
+ for (ii = 0; ii < 1000; ii++) {
+ cond[ii] = 1;
+ array[ii] = 1000;
+ array2[ii] = 2000;
+ }
+ array2[:] = cond[:] ? array[:] : array2[:];
+
+ for (ii = 0; ii < 1000; ii++) {
+ if (array2[ii] != 1000)
+ return 1;
+ }
+
+ array2[0:500:2] = cond[0:500] ? array[0:500:1] : array2[0:500:2];
+
+ for (ii = 0; ii < 1000; ii++) {
+ if (array2[ii] != 1000)
+ return 2;
+ }
+
+ for (ii = 0; ii < 1000; ii++) {
+ cond[ii] = ii % 2; /* This should give 0, 1, 0, 1, 0, 1, 0,... */
+ array2[ii] = 5;
+ array[ii] = 3;
+ }
+ array3 = (short *) malloc (sizeof (short) * 1000);
+ array3[0:1000:argc] = cond[:] ? array[0:(argc * 1000)] : array2[argc-1:1000];
+
+ for (ii = 0; ii < 1000; ii++) {
+ if ((cond[ii] == 0 && array3[ii] != 5)
+ || (cond[ii] == 1 && array3[ii] != 3))
+ return 3;
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c
new file mode 100644
index 00000000000..68c88590da2
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c
@@ -0,0 +1,18 @@
+/* { dg-options "-fcilkplus" } */
+
+int main(void)
+{
+ extern int func(int);
+ int array3[:], x, q; /* { dg-error "array notations cannot be used in declaration" } */
+ int array3[1:2:x]; /* { dg-error "array notations cannot be used in declaration" } */
+ extern char array3[1:func(x)]; /* { dg-error "array notations cannot be used in declaration" } */
+ int *a, ***b;
+ extern char *c;
+ int array2[10];
+
+ a[:] = 5; /* { dg-error "start-index and length fields necessary for using array notations in pointers" } */
+ c[1:2] = 3; /* This is OK. */
+ (array2)[:] = 5; /* This is OK. */
+ b[1:2][1:func(x)][:] = 3; /* { dg-error "start-index and length fields necessary for using array notations in pointers" } */
+}
+
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c
new file mode 100644
index 00000000000..69aaa523727
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c
@@ -0,0 +1,10 @@
+/* { dg-options "-fcilkplus" } */
+
+extern int a[];
+extern int *b;
+
+void foo()
+{
+ a[:] = 5; // { dg-error "start-index and length fields necessary for using array notations in dimensionless arrays" }
+ b[:] = 5; // { dg-error "start-index and length fields necessary for using array notations in pointers" }
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/exec-once.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/exec-once.c
new file mode 100644
index 00000000000..00b018a2c85
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/exec-once.c
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+#define NUMBER 1000
+
+#if HAVE_IO
+#include <stdio.h>
+#endif
+
+int func (int *x)
+{
+ int q = *x;
+ q++;
+ *x = q;
+#if HAVE_IO
+ printf("%d\n", (q));
+#endif
+ return *x;
+}
+int main (void)
+{
+ char array[NUMBER], array2[NUMBER];
+ int ii, d = 2;
+#if 1
+ for (ii = 0; ii < NUMBER; ii++) {
+ array[ii] = 5;
+ array2[ii]= 2;
+ }
+#endif
+ d = func (&d); /* d = 1 */
+ array2[:] = d * array[:] + (char) func (&d); /* 3 * 5 + 4 */
+#if HAVE_IO
+ for (ii = 0; ii < NUMBER; ii++)
+ printf("array2[%d] = %d\n", ii, array2[ii]);
+#endif
+ for (ii = 0; ii < NUMBER; ii++)
+ if (array2[ii] != (3 * 5 + 4))
+ return 1;
+
+ return 0;
+}
+
+
+
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/exec-once2.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/exec-once2.c
new file mode 100644
index 00000000000..d9f39dd66a8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/exec-once2.c
@@ -0,0 +1,87 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+#ifdef HAVE_IO
+#include <stdio.h>
+#endif
+
+
+int func1(int x)
+{
+ /* If x == 2 then it should return 0. */
+ return (x - 2);
+}
+
+int func2(int x)
+{
+ /* If x == 2 then it should return 1000. */
+ return (x * 500);
+}
+
+int func3 (int x)
+{
+ /* If x == 2 then it should return 1. */
+ /* If x == 1 then it should return 0. */
+ return (x-1);
+}
+
+int func4(int x)
+{
+ if (x > 0)
+ return x;
+ else
+ return x--;
+}
+
+
+/* This program makes an assumption that argc == 1. */
+int main (void)
+{
+ int argc = 1;
+ int array[2500];
+
+ /* This is done to make sure the compiler does not optimize out argc. */
+ __asm volatile ("" : "+r" (argc));
+ /* This should set array[0->999] to 5. */
+ array[argc-1:func2(++argc):1] = 5;
+ array[1000:500:1] = 10; /* set all variables in array[1000-->1499] to 10. */
+ array[1500:500:1] = 15; /* set all variables in array[1500-->1999] to 15. */
+ array[2000:500:1] = 20; /* set all variables in array[2000-->2499] to 20. */
+ array[2000:500:1] = 25; /* set all variables in array[2500-->2999] to 25. */
+ array[2000:500:1] = 30; /* set all variables in array[3000-->3499] to 30. */
+
+ argc = func3 (argc); /* This will set argc back to 1. */
+#if HAVE_IO
+ printf("argc = %d\n", argc);
+#endif
+ /* If the parameters inside the function get evaluated only once, then this
+ if statement must work fine, i.e. the triplet values will be 0, 1000, 1.
+
+ Otherwise, the program should crash or give some uneasy value. */
+
+ /* If done correctly, it should boil down to: array[0:1000:1]. */
+ if (array[func3(argc):func2(++argc)] != 5) {
+#ifdef HAVE_IO
+ printf ("Should not be there(1).\n");
+#endif
+ return 1;
+ }
+
+ /* If done correctly, it should boil down to: array[999:500:-1]. */
+ if (func4(array[func2(argc)-1:func2(argc--):func1(argc)]) != 5) {
+#ifdef HAVE_IO
+ printf ("Should not be there(2).\n");
+#endif
+ return 2;
+ }
+
+ /* If done correctly, it should boil down to: array[1000:500:1]. */
+ if (func4 (func4(array[func2(argc++):500: func1(argc--)])) != 5) {
+#ifdef HAVE_IO
+ printf ("Should not be there(3).\n");
+#endif
+ return 3;
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c
new file mode 100644
index 00000000000..024a1589994
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c
@@ -0,0 +1,20 @@
+/* { dg-options "-fcilkplus" } */
+
+typedef int (*foo)(int);
+
+int main(void)
+{
+ int array[10], array2[10][10];
+ foo func_array[10];
+ foo func_array2[10][10];
+ foo ***func_array_ptr;
+ int argc = 5;
+
+ array[:] = func_array[:](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */
+ func_array[0:5](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */
+ func_array2[0:5][:](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */
+ array2[0:5][:] = func_array2[0:5][:](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */
+ func_array_ptr[0:5][0:4][0:argc:2](argc); /* { dg-error "array notations cannot be used with function pointer arrays" } */
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/fp_triplet_values.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/fp_triplet_values.c
new file mode 100644
index 00000000000..b2ac7bcc85a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/fp_triplet_values.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+float q;
+
+void func (int *x)
+{
+ *x = 5;
+}
+
+int main (void)
+{
+ int array[10], array2[10];
+ array2[:] = array[1.5:2]; /* { dg-error "start-index of array notation triplet is not an integer" } */
+ array2[:] = array[1:2.32333333333]; /* { dg-error "length of array notation triplet is not an integer" } */
+ array2[1:2:1.5] = array[:]; /* { dg-error "stride of array notation triplet is not an integer" } */
+ func (&array2[1:2.34:3]); /* { dg-error "length of array notation triplet is not an integer" } */
+ array2[1.43:9]++; /* { dg-error "start-index of array notation triplet is not an integer" } */
+ array2[1:9.3]++; /* { dg-error "length of array notation triplet is not an integer" } */
+ array2[1:9:0.3]++; /* { dg-error "stride of array notation triplet is not an integer" } */
+
+ ++array2[1:q:3]; /* { dg-error "length of array notation triplet is not an integer" } */
+ array2[:] = array[q:1:3]; /* { dg-error "start-index of array notation triplet is not an integer" } */
+ array2[:] = array[1:q:3]; /* { dg-error "length of array notation triplet is not an integer" } */
+ array2[:] = array[1:3:q]; /* { dg-error "stride of array notation triplet is not an integer" } */
+ func (&array2[1:q:3]); /* { dg-error "length of array notation triplet is not an integer" } */
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/gather-scatter-errors.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/gather-scatter-errors.c
new file mode 100644
index 00000000000..f425fbec0f5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/gather-scatter-errors.c
@@ -0,0 +1,19 @@
+/* { dg-options "-fcilkplus" } */
+
+int main (void)
+{
+ extern int func (int);
+ int array[10][10], array2[10];
+ int argc = 1;
+ array2[array[:][:]] = 5; /* { dg-error "rank of the array's index is greater than 1" } */
+
+ array2[array[:][:]] = 5; /* { dg-error "rank of the array's index is greater than 1" } */
+ func (array2[array[:][:]]); /* { dg-error "rank of the array's index is greater than 1" } */
+ func (array2[array[argc:func(5)][0:10:2]]); /* { dg-error "rank of the array's index is greater than 1" } */
+
+ array[array2[:]][array2[:]] = 5; /* This is OK. */
+ array[array2[:]][array2[:]] = array2[array[:][:]]; /* { dg-error "rank of the array's index is greater than 1" } */
+ array[array2[:]][array2[:]] = array2[array[0:10:1][:]]; /* { dg-error "rank of the array's index is greater than 1" } */
+ array[array2[:]][array2[:]] = array2[array[:][argc:func (argc)]]; /* { dg-error "rank of the array's index is greater than 1" } */
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/gather_scatter.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/gather_scatter.c
new file mode 100644
index 00000000000..b11a40ed325
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/gather_scatter.c
@@ -0,0 +1,59 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+#if HAVE_IO
+#include <stdio.h>
+#endif
+
+int main(void)
+{
+ int array[10][10], array2[10], array3[10], x = 0, y;
+ int x_correct, y_correct, ii, jj = 0;
+ float array4[10][10][10][10];
+ for (ii = 0; ii < 10; ii++)
+ {
+ for (jj = 0; jj < 10; jj++)
+ {
+ array[ii][jj] = 1+ii;
+ array2[ii]= 2;
+ array3[ii]= 3;
+ }
+ }
+
+ array[array2[:]][array3[:]] = 1000;
+
+ for (ii = 0; ii < 10; ii++)
+ if (array[array2[ii]][array3[ii]] != 1000)
+ return 1;
+
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++) {
+ for (jj = 0; jj < 10; jj++) {
+ printf("%4d\t", array[ii][jj]);
+ }
+ printf("\n");
+ }
+#endif
+
+ array4[array2[:]][array3[0:10:1]][array2[0:10:1]][array3[0:10:1]] =
+ (float)array[array2[:]][array3[:]];
+
+ for (ii = 0; ii < 10; ii++)
+ if (array4[array2[ii]][array3[ii]][array2[ii]][array3[ii]] !=
+ (float)array[array2[ii]][array3[ii]])
+ return 2;
+
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++) {
+ for (jj = 0; jj < 10; jj++) {
+ for (kk = 0; kk < 10; kk++) {
+ for (ll = 0; ll < 10; ll++) {
+ printf("%4d\n", array4[ii][jj][kk][ll]);
+ }
+ }
+ }
+ }
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/if_test.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/if_test.c
new file mode 100644
index 00000000000..5544d4550aa
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/if_test.c
@@ -0,0 +1,306 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+#if HAVE_IO
+#include <stdio.h>
+#endif
+#include <stdlib.h>
+int main2 (char **argv);
+int main(int argc, char **argv)
+{
+ int x = 0;
+ const char *array[] = {"a.out", "10", "15"};
+ x = main2 ((char **) array);
+ return x;
+}
+
+
+int main2 (char **argv)
+{
+ int x = 3, y, z, array[10], array2[10], TwodArray[10][10], jj,kk,ll ;
+ int array2_check[10], array2d_check[10][10], array2d[10][10];
+ int FourDArray[10][10][10][10], array4[10][10][10][10];
+ int array4_check[10][10][10][10];
+ int ii = 0, argc = 3;
+
+ __asm volatile ("" : "+r" (argc));
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = argc%3;
+ array2[ii]= 10;
+ array2_check[ii] = 10;
+ }
+
+ if (!array[:])
+ array2[:] = 5;
+ else
+ array2[:] = 10;
+
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ if (!array[ii])
+ array2_check[ii] = 5;
+ else
+ array2_check[ii] = 10;
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ if (array2_check[ii] != array2[ii])
+ return 2;
+
+
+
+ if (!(array[0:10:1] + array[0:10:1]))
+ array2[:] = 5;
+ else
+ array2[:] = 10;
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ if (!(array[ii]+ array[ii]))
+ array2_check[ii] = 5;
+ else
+ array2_check[ii] = 10;
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ if (array2_check[ii] != array2[ii])
+ return 3;
+
+ x = atoi (argv[1])-10;
+ y = atoi (argv[1])/2;
+ z = (atoi (argv[1]))/5;
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ if (ii % 2)
+ array[ii] = 0;
+ else
+ array[ii] = 1;
+ }
+
+ /*printf("x = %2d y = %2d z = %2d\n", x, y, z); */
+
+ for (ii = 0; ii < 10; ii++)
+ array[ii] = 10;
+
+ /* This if loop will change all the 10's to 5's */
+ if (array[x:y:z] != 9)
+ array2[:] = 5;
+ else
+ array2[:] = 10;
+
+ for (ii = x; ii < (x+y); ii += z)
+ {
+ if (array[ii] != 9)
+ array2_check[ii] = 5;
+ else
+ array2_check[ii] = 10;
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ if (array2_check[ii] != array2[ii])
+ return 4;
+
+ for (ii = 0; ii < 10; ii++) {
+ array2[ii] = 10;
+ array2_check[ii] = 10;
+ }
+
+ /* This if loop will change all the 10's to 5's */
+ if (array[atoi(argv[1])-10:atoi(argv[1])/2: atoi(argv[1])/5])
+ array2[atoi(argv[1])-10: atoi (argv[1])/2: atoi(argv[1])/5] = 5;
+ else
+ array2[atoi(argv[1])-10: atoi (argv[1])/2: atoi(argv[1])/5] = 10;
+
+ for (ii = atoi(argv[1])-10; ii < atoi(argv[1]) + (atoi (argv[1])-10);
+ ii +=atoi(argv[1])/5)
+ if (array[ii])
+ array2_check[ii] = 5;
+ else
+ array2_check[ii] = 10;
+
+ for (ii = 0; ii < 10; ii++)
+ if (array2_check[ii] != array2[ii]) {
+#if HAVE_IO
+ printf("array2[%2d] = %2d array2_check[%2d] = %2d\n", ii, array2[ii],
+ ii, array2_check[ii]);
+#endif
+ return 5;
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ TwodArray[ii][jj] = atoi(argv[1]);
+
+
+ for (ii = 0; ii < 10; ii++)
+ for (ii = 0; ii < 10; ii++) {
+ array2d[ii][jj] = 10;
+ array2d_check[ii][jj] = 10;
+ }
+
+ /* atoi(argv[1]) == 10, so it will convert all 10's to 5's */
+ if (TwodArray[:][:] != 10)
+ array2d[:][:] = 10;
+ else
+ array2d[:][:] = 5;
+
+ for (ii = 0; ii < 10; ii++) {
+ for (jj = 0; jj < 10; jj++) {
+ if (TwodArray[ii][jj] != 10)
+ array2d_check[ii][jj] = 10;
+ else
+ array2d_check[ii][jj] = 5;
+ }
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ if (array2d[ii][jj] != array2d_check[ii][jj])
+ return 6;
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ for (kk = 0; kk < 10; kk++)
+ for (ll = 0; ll < 10; ll++)
+ {
+ array4[ii][jj][kk][ll] = 10;
+ array4_check[ii][jj][kk][ll] = 10;
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ for (kk = 0; kk < 10; kk++)
+ for (ll = 0; ll < 10; ll++)
+ FourDArray[ii][jj][kk][ll] = atoi(argv[1]);
+
+ /* atoi(argv[1]) == 10, so it will convert all 10's to 5's */
+ if (FourDArray[:][:][:][:] != 10)
+ array4[:][:][:][:] = 10;
+ else
+ array4[:][:][:][:] = 5;
+
+ for (ii = 0; ii < 10; ii++) {
+ for (jj = 0; jj < 10; jj++) {
+ for (kk = 0; kk < 10; kk++) {
+ for (ll = 0; ll < 10; ll++) {
+ if (FourDArray[ii][jj][kk][ll] != 10)
+ array4_check[ii][jj][kk][ll] = 10;
+ else
+ array4_check[ii][jj][kk][ll] = 5;
+ }
+ }
+ }
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ for (kk = 0; kk < 10; kk++)
+ for (ll = 0; ll < 10; ll++)
+ if (array4_check[ii][jj][kk][ll] != array4[ii][jj][kk][ll])
+ return 7;
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ for (kk = 0; kk < 10; kk++)
+ for (ll = 0; ll < 10; ll++)
+ {
+ array4[ii][jj][kk][ll] = 10;
+ array4_check[ii][jj][kk][ll] = 10;
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ for (kk = 0; kk < 10; kk++)
+ for (ll = 0; ll < 10; ll++)
+ FourDArray[ii][jj][kk][ll] = atoi(argv[1]);
+
+ /* atoi(argv[1]) == 10, so it will convert all 10's to 5's */
+ if (FourDArray[0:10:1][0:5:2][9:10:-1][0:5:2] != 10)
+ array4[0:10:1][0:5:2][9:10:-1][0:5:2] = 10;
+ else
+ array4[0:10:1][0:5:2][9:10:-1][0:5:2] = 5;
+
+ for (ii = 0; ii < 10; ii++) {
+ for (jj = 0; jj < 10; jj += 2) {
+ for (kk = 9; kk >= 0; kk--) {
+ for (ll = 0; ll < 10; ll += 2) {
+ if (FourDArray[ii][jj][kk][ll] != 10)
+ array4_check[ii][jj][kk][ll] = 10;
+ else
+ array4_check[ii][jj][kk][ll] = 5;
+ }
+ }
+ }
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ for (kk = 0; kk < 10; kk++)
+ for (ll = 0; ll < 10; ll++)
+ if (array4_check[ii][jj][kk][ll] != array4[ii][jj][kk][ll]) {
+#if HAVE_IO
+ printf("array4_check[%d][%d][%d][%d] = %d\n",ii, jj, kk, ll,
+ array4_check[ii][jj][kk][ll]);
+ printf("array4[%d][%d][%d][%d] = %d\n",ii, jj, kk, ll,
+ array4[ii][jj][kk][ll]);
+#endif
+ return 8;
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ for (kk = 0; kk < 10; kk++)
+ for (ll = 0; ll < 10; ll++)
+ FourDArray[ii][jj][kk][ll] = atoi(argv[1]);
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ for (kk = 0; kk < 10; kk++)
+ for (ll = 0; ll < 10; ll++)
+ {
+ array4[ii][jj][kk][ll] = 10;
+ array4_check[ii][jj][kk][ll] = 10;
+ }
+
+
+ /* atoi(argv[1]) == 10, so it will convert all 10's to 5's */
+ if (FourDArray[0:10:1][0:5:2][9:10:-1][x:y:z] +
+ FourDArray[0:10:1][0:5:2][9:-10:1][x:y:z] != 20)
+ array4[0:10:1][0:5:2][9:10:-1][x:y:z] = 10;
+ else
+ array4[0:10][0:5:2][9:10:-1][x:y:z] = 5;
+
+ for (ii = 0; ii < 10; ii++) {
+ for (jj = 0; jj < 10; jj += 2) {
+ for (kk = 9; kk >= 0; kk--) {
+ for (ll = 0; ll < 10; ll += 2) {
+ if (FourDArray[ii][jj][kk][ll] != 10)
+ array4_check[ii][jj][kk][ll] = 10;
+ else
+ array4_check[ii][jj][kk][ll] = 5;
+ }
+ }
+ }
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ for (kk = 0; kk < 10; kk++)
+ for (ll = 0; ll < 10; ll++)
+ if (array4_check[ii][jj][kk][ll] != array4[ii][jj][kk][ll]) {
+#if HAVE_IO
+ printf("array4_check[%d][%d][%d][%d] = %d\n",ii, jj, kk, ll,
+ array4_check[ii][jj][kk][ll]);
+ printf("array4[%d][%d][%d][%d] = %d\n",ii, jj, kk, ll,
+ array4[ii][jj][kk][ll]);
+#endif
+ return 9;
+ }
+
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/if_test_errors.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/if_test_errors.c
new file mode 100644
index 00000000000..d17d8cf5de2
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/if_test_errors.c
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+#include <stdlib.h>
+int main (void)
+{
+ int x = 3, y, z, array[10], array2[10], TwodArray[10][10], jj,kk,ll ;
+ int array2_check[10], array2d_check[10][10], array2d[10][10];
+ int FourDArray[10][10][10][10], array4[10][10][10][10];
+ int array4_check[10][10][10][10];
+ int ii = 0;
+
+ x = 5;
+ y = 10;
+ z = 2;
+
+ if (!array[:]) /* This is OK! */
+ array2[:] = 5;
+ else
+ array2[:] = 10;
+ if (!(array[0:10:1] + array[0:10:1])) /* { dg-error "condition and the then-block" } */
+ array2d[:][:] = 5;
+ else
+ array2[:] = 10;
+
+ if (!(array[0:10:1] + array[0:10:1])) /* { dg-error "condition and the else-block" } */
+ array2[:] = 5;
+ else
+ array2d[:][:] = 10;
+
+
+ if (TwodArray[:][:] != 10) /* { dg-error "condition and the then-block" } */
+ array2[:] = 10;
+ else
+ array2[:] = 5;
+
+ if (FourDArray[43][:][:][:] != 10) /* This is OK! */
+ array4[45][:][:][:] = 10;
+ else
+ array4[32][:][:][:] = 5;
+
+ /* atoi(argv[1]) == 10, so it will convert all 10's to 5's */
+ if (FourDArray[42][0:10:1][9:10:-1][0:5:2] != 10) /* { dg-error "condition and the then-block" } */
+ array4[0:10:1][0:5:2][9:10:-1][0:5:2] = 10;
+ else
+ array4[0:10:1][0:5:2][9:10:-1][0:5:2] = 5;
+
+ /* atoi(argv[1]) == 10, so it will convert all 10's to 5's */
+ if (FourDArray[0:10:1][0:5:2][9:10:-1][x:y:z] +
+ FourDArray[0:10:1][0:5:2][9:-10:1][x:y:z] != 20)
+ array4[0:10:1][0:5:2][9:10:-1][x:y:z] = 10;
+ else
+ array4[0:10][0:5:2][9:10:-1][x:y:z] = 5;
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c
new file mode 100644
index 00000000000..35eb11537d1
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c
@@ -0,0 +1,112 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+int main (void)
+{
+ int array[10], array2[10][10];
+ int x, ii, jj ;
+
+ switch (array[:]) { /* { dg-error "array notations cannot be used as a condition for switch statement" } */
+ case 1:
+ x = 5;
+ break;
+ case 2:
+ x = 2;
+ break;
+ default:
+ x = 9;
+ }
+
+ switch (array2[:][:]) { /* { dg-error "array notations cannot be used as a condition for switch statement" } */
+ case 1:
+ x = 5;
+ break;
+ case 2:
+ x = 2;
+ break;
+ default:
+ x = 9;
+ }
+
+ switch (array[:] + x) { /* { dg-error "array notations cannot be used as a condition for switch statement" } */
+ case 1:
+ x = 5;
+ break;
+ case 2:
+ x = 2;
+ break;
+ default:
+ x = 9;
+ }
+
+ switch (array2[:][1:x:4] + x) { /* { dg-error "array notations cannot be used as a condition for switch statement" } */
+ case 1:
+ x = 5;
+ break;
+ case 2:
+ x = 2;
+ break;
+ default:
+ x = 9;
+ }
+
+ for (ii = 0; ii < array[:]; ii++) /* { dg-error "array notations cannot be used in a condition for a for-loop" } */
+ {
+ x = 2;
+ }
+
+ for (ii = 0; ii < array2[:][:]; ii++) /* { dg-error "array notations cannot be used in a condition for a for-loop" } */
+ {
+ x = 3;
+ }
+
+ for (; array2[:][:] < 2;) /* { dg-error "array notations cannot be used in a condition for a for-loop" } */
+ x = 4;
+
+
+ while (array2[:][:]) /* { dg-error "array notations cannot be used as a condition for while statement" } */
+ x = 3;
+
+ while (array[1:1:1]) /* { dg-error "array notations cannot be used as a condition for while statement" } */
+ x = 1;
+
+ while (ii != array2[1:x:3][1:2:1]) /* { dg-error "array notations cannot be used as a condition for while statement" } */
+ x = 2;
+
+ do { /* { dg-error "array notations cannot be used as a condition for a do-while statement" } */
+ x = 3;
+ } while (ii != array2[:][:]);
+
+ do { /* { dg-error "array notations cannot be used as a condition for a do-while statement" } */
+ x = 2;
+ } while (ii != (x + array2[:][1:x:2]) + 2);
+
+ do {
+ x += 3;
+ if (x == 5)
+ return array2[:][:]; /* { dg-error "array notation expression cannot be used as a return value" } */
+ } while (ii != 0);
+
+ for (ii = 0; ii < 10; ii++)
+ if (ii % 2)
+ return array[1:x:ii]; /* { dg-error "array notation expression cannot be used as a return value" } */
+
+ for (ii = 0; ii < x; ii++)
+ if (ii)
+ return array2[:][:]; /* { dg-error "array notation expression cannot be used as a return value" } */
+
+ for (array[:] = 0; ii < x; ii++) /* This should be OK. */
+ x= 2;
+
+ for (ii = 0; ii < 10; array[:]++) /* This is OK. */
+ x = 5;
+
+ for (jj = 0; jj < 10; array2[:][:]++) /* This is OK. */
+ x = 3;
+
+ for (jj = 0; jj < 10; array2[:][1:x:4]++, jj++) /* This is OK. */
+ x = 3;
+
+ return x;
+}
+
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/n-ptr-test.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/n-ptr-test.c
new file mode 100644
index 00000000000..750446c87d2
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/n-ptr-test.c
@@ -0,0 +1,48 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+#define NUMBER 10
+#include <stdlib.h>
+
+int ***func2 (int ***a1, int ***a2, int size)
+{
+ a1[0:size:1][0:size:1][0:size] += (a2[0:size][0:size][0:size:1] + size);
+ return a1;
+}
+
+int main (void)
+{
+ int ii, jj, kk;
+ int ***array3, ***array2 = NULL, ***array = NULL;
+
+ array = (int ***) malloc (sizeof (int **) * NUMBER);
+ array2 = (int ***) malloc (sizeof (int **) * NUMBER);
+ for (ii = 0; ii < NUMBER; ii++) {
+ array[ii] = (int **) malloc (sizeof (int *) * NUMBER);
+ array2[ii] = (int **) malloc (sizeof (int *) * NUMBER);
+ for (jj = 0; jj < NUMBER; jj++) {
+ array[ii][jj] = (int *) malloc (sizeof (int) * NUMBER);
+ array2[ii][jj] = (int *) malloc (sizeof (int) * NUMBER);
+ }
+ }
+
+ for (ii = 0; ii < NUMBER; ii++) {
+ for (jj = 0; jj < NUMBER; jj++) {
+ for (kk = 0; kk < NUMBER; kk++) {
+ array[ii][jj][kk] = 5;
+ array2[ii][jj][kk]= 2;
+ }
+ }
+ }
+ array3 = func2 ((int ***)array, (int ***)array2, NUMBER);
+
+ for (ii = 0; ii < NUMBER; ii++) {
+ for (jj = 0; jj < NUMBER; jj++) {
+ for (kk = 0; kk < NUMBER; kk++) {
+ if (array3[ii][jj][kk] != (7 + NUMBER))
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors.c
new file mode 100644
index 00000000000..a0a3742f5df
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+int main (void)
+{
+ int array[10][10], array2[10];
+
+ array2[:] = array2[: ; /* { dg-error "expected ']'" } */
+
+ return 0;
+} /* { dg-error "expected ';' before" } */
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors2.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors2.c
new file mode 100644
index 00000000000..2e86b4f92da
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+int main (void)
+{
+ int array[10][10], array2[10];
+
+ array2[:] = array2[1:2:] ; /* { dg-error "expected expression before" } */
+
+ return 0; /* { dg-error "expected ';' before" } */
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors3.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors3.c
new file mode 100644
index 00000000000..34dfa16dd81
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+int main (void)
+{
+ int array[10][10], array2[10];
+
+ array2[:] = array2[1::] ; /* { dg-error "expected expression before" } */
+
+ return 0; /* { dg-error "expected ';' before" } */
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors4.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors4.c
new file mode 100644
index 00000000000..eba28a81ce3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors4.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+int main (void)
+{
+ int array[10][10], array2[10];
+
+ array2[:] = array2[::] ; /* { dg-error " expected ']' before ':' token" } */
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/pr57457-2.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/pr57457-2.c
new file mode 100644
index 00000000000..ac11b9209b1
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/pr57457-2.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+/* Test-case contains no array notation but is compiled with -fcilkplus.
+ It will still print the too few arguments func, thereby saying the
+ if-statement after the for-loop to check for !flag_enable_cilkplus ||
+ !is_cilkplus_reduce_function (fundecl) is not valid is always taken. */
+
+int func (int, int); /* { dg-message "declared here" } */
+
+int main (void)
+{
+ int a = 5, b = 2;
+ return func (a); /* { dg-error "too few arguments to function" } */
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/pr57457.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/pr57457.c
new file mode 100644
index 00000000000..68a1fd81185
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/pr57457.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+/* This test has no array notation components in it and thus should compile
+ fine without crashing. */
+
+typedef unsigned int size_t;
+typedef int (*__compar_fn_t) (const void *, const void *);
+extern void *bsearch (const void *__key, const void *__base,
+ size_t __nmemb, size_t __size, __compar_fn_t
+ __compar)
+ __attribute__ ((__nonnull__ (1, 2, 5))) ;
+extern __inline __attribute__ ((__gnu_inline__)) void *
+bsearch (const void *__key, const void *__base, size_t __nmemb, size_t
+ __size,
+ __compar_fn_t __compar)
+{
+ size_t __l, __u, __idx;
+ const void *__p;
+ int __comparison;
+ __l = 0;
+ __u = __nmemb;
+ while (__l < __u)
+ {
+ __idx = (__l + __u) / 2;
+ __p = (void *) (((const char *) __base) +
+ (__idx * __size));
+ __comparison = (*__compar) (__key,
+ __p);
+ if (__comparison < 0)
+ __u = __idx;
+ else if (__comparison > 0)
+ __l = __idx + 1;
+ else
+ return (void *)
+ __p;
+ }
+ return ((void *)0);
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c
new file mode 100644
index 00000000000..b5e37ced12d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus -w" } */
+
+/* We use -w because in the first error, there will be a warning of setting an
+ integer to a pointer. Just ignore it to expose the rank mismatch error. */
+
+int main (void)
+{
+ int x = 0;
+ int array[10][10], array2[10];
+
+ array[:][:] = array[:]; /* { dg-error "rank mismatch between" } */
+
+ x = array2[:]; /* { dg-error "cannot be scalar when" } */
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch2.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch2.c
new file mode 100644
index 00000000000..4a4882dbae6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch2.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+int function_call (int x);
+int function_call (int x)
+{
+ return x;
+}
+
+int main (void)
+{
+ int array[100], array2[100][100];
+ int argc = 4;
+ array[:] = array[:] + array2[:][:]; /* { dg-error "rank mismatch between" } */
+
+ if (array[:] + array2[:][:]) /* { dg-error "rank mismatch between" } */
+ return argc == 5;
+
+ argc += function_call (array[:] + array2[5:10:2][:]); /* { dg-error "rank mismatch between" } */
+
+ argc += function_call (function_call (array[:] + array2[5:10:2][:])); /* { dg-error "rank mismatch between" } */
+
+ argc += __sec_reduce_add (array[:], array2[:][:]); /* { dg-error "rank mismatch between" } */
+
+ argc += __sec_reduce_add (array2[:][:]) + argc; /* This is OK. */
+ return argc;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch3.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch3.c
new file mode 100644
index 00000000000..de335922f8a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch3.c
@@ -0,0 +1,19 @@
+/* { dg-options "-fcilkplus" } */
+
+int funct (int x, int y);
+void funct_void (int x, int y, int z);
+int main(void)
+{
+ int y, array[100], array2[100], array3[100][100], array4[100];
+
+ array[:] = ((array2[:] + array[:]) * array4[:]) + array3[:][:]; /* { dg-error "rank mismatch between" } */
+ array[:] = funct (array2[:], array3[:][:]); /* { dg-error "rank mismatch between" } */
+ array[:] = array3[:][:]; /* { dg-error "rank mismatch between" } */
+ array3[:][:] = array[:]; /* { dg-error "rank mismatch between" } */
+ array3[:][:] = array[5]; /* This is OK! */
+ funct_void (array2[:], array3[:][:], array[:]); /* { dg-error "rank mismatch between" } */
+ funct_void (array2[:], array3[:][:], array[:]); /* { dg-error "rank mismatch between" } */
+ funct_void (array3[:][:], array2[:], array[:]); /* { dg-error "rank mismatch between" } */
+ funct_void (array2[:], array[:], array3[:][0:10:1]); /* { dg-error "rank mismatch between" } */
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/sec_implicit.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/sec_implicit.c
new file mode 100644
index 00000000000..bacbf350566
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/sec_implicit.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+int main (void)
+{
+ int array[10][10], array2[10];
+
+ array[:][:] = __sec_implicit_index(5) + array[:][:]; /* { dg-error "__sec_implicit_index argument" } */
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/sec_implicit2.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/sec_implicit2.c
new file mode 100644
index 00000000000..0aef0c29aca
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/sec_implicit2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+int main (void)
+{
+ int argc = 2;
+ int array[10][10], array2[10];
+ __asm volatile ("" : "+r" (argc));
+ array[:][:] = __sec_implicit_index(argc) + array[:][:]; /* { dg-error "__sec_implicit_index parameter" } */
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/sec_implicit_ex.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/sec_implicit_ex.c
new file mode 100644
index 00000000000..c22b818434a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/sec_implicit_ex.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+void abort (void);
+void exit (int);
+
+
+int main(void)
+{
+ int jj, kk, array_3C[10][10][10];
+ int ii,array[10], y = 0, y_int = 0, array2[10], array_3[10][10][10];
+ double x, yy, array3[10], array4[10];
+
+ array[:] = __sec_implicit_index (0);
+ array_3[:][:][:] = __sec_implicit_index (1) + __sec_implicit_index(0) +
+ __sec_implicit_index (2);
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ for (kk = 0; kk < 10; kk++)
+ array_3C[ii][jj][kk] = ii+jj+kk;
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ for (kk = 0; kk < 10; kk++)
+ if (array_3[ii][jj][kk] != array_3C[ii][jj][kk])
+ abort ();
+
+
+ exit (0);
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/sec_reduce_max_min_ind.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/sec_reduce_max_min_ind.c
new file mode 100644
index 00000000000..9652e1594b4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/sec_reduce_max_min_ind.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+int main (void)
+{
+ int array[10][10], array2[10];
+ int x, y;
+ x = __sec_reduce_max_ind (array[:][:]); /* { dg-error "cannot have arrays with dimension greater than" } */
+
+ y = __sec_reduce_max_ind (array2[:]); /* this should be OK. */
+
+ x = __sec_reduce_min_ind (array[:][:]); /* { dg-error "cannot have arrays with dimension greater than" } */
+
+ y = __sec_reduce_min_ind (array2[:]); /* this should be OK. */
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/sec_reduce_return.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/sec_reduce_return.c
new file mode 100644
index 00000000000..034017146f3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/sec_reduce_return.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+int add_all (int *my_array, int size)
+{
+ return __sec_reduce_add (my_array[0:size]);
+}
+
+int mult_all (int *my_array, int size)
+{
+ return __sec_reduce_mul (my_array[0:size]);
+}
+
+int main (void)
+{
+ int argc = 1;
+ int array[10000];
+
+ __asm volatile ("" : "+r" (argc));
+ array[:] = argc; /* All elements should be one. */
+
+ if (add_all (array, 10000) != 10000)
+ return 1;
+
+ if (mult_all (array, 10000) != 1)
+ return 2;
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/side-effects-1.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/side-effects-1.c
new file mode 100644
index 00000000000..8b0034e727b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/side-effects-1.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+/* Test that the array index, limit, and stride are evaluated only
+ once. */
+
+int array[1000];
+
+int func1_times = 0;
+int func2_times = 0;
+int func3_times = 0;
+int func1() { func1_times++; return 0; }
+int func2() { func2_times++; return 0; }
+int func3() { func3_times++; return 0; }
+
+int main()
+{
+ array[func1() + 11 : func2() + 22 : func3() + 33] = 666;
+
+ if (func1_times != 1
+ || func2_times != 1
+ || func3_times != 1)
+ return 1;
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/test_builtin_return.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/test_builtin_return.c
new file mode 100644
index 00000000000..b9f9f8d6507
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/test_builtin_return.c
@@ -0,0 +1,73 @@
+/* { dg-options "-lm -fcilkplus" } */
+/* { dg-do run } */
+
+#if HAVE_IO
+#include <stdio.h>
+#endif
+#include <math.h>
+#define NUMBER 5
+
+int func1 (int *a1, int *a2)
+{
+ return __sec_reduce_add (a1[0:NUMBER] * a2[0:NUMBER:1]);
+}
+
+int func2 (int *a1, int *a2)
+{
+ return (__sec_reduce_add (a1[0:NUMBER] * a2[0:NUMBER]) +
+ __sec_reduce_mul (a1[0:NUMBER] + a2[0:NUMBER]));
+}
+
+int func3 (int *a1, int *a2)
+{
+ return (int) sqrt ((double)(__sec_reduce_add (a1[0:NUMBER] * a2[0:NUMBER]) +
+ a2[0] + a2[1] + a2[3]));
+}
+
+int func4 (int *a1, int *a2)
+{
+ return a1[NUMBER-1] * (__sec_reduce_add (a1[0:NUMBER] * a2[0:NUMBER]) + a2[0] + a2[1] + a2[3])/a1[NUMBER-2];
+}
+int main(void)
+{
+ int array[NUMBER], array2[NUMBER];
+ int return_value = 0;
+ int ii = 0;
+ int argc = 1;
+ __asm volatile ("" : "+r" (argc));
+ for (ii = 0; ii < NUMBER; ii++)
+ {
+ array[ii] = argc; /* This should calculate to 1. */
+ array2[ii] = argc * argc + argc; /* This should calculate to 2. */
+ }
+
+ return_value = func1 (array, array2);
+#if HAVE_IO
+ printf("Return_value = %d\n", return_value);
+#endif
+ if (return_value != (2+2+2+2+2))
+ return 1;
+
+ return_value = func2 (array2, array);
+#if HAVE_IO
+ printf("Return_value = %d\n", return_value);
+#endif
+ if (return_value != (3*3*3*3*3) + (2+2+2+2+2))
+ return 2;
+
+ return_value = func3 (array, array2);
+#if HAVE_IO
+ printf("Return_value = %d\n", return_value);
+#endif
+ if (return_value != 4)
+ return 3;
+
+ return_value = func4 (array, array2);
+#if HAVE_IO
+ printf("Return_value = %d\n", return_value);
+#endif
+ if (return_value != 16)
+ return 4;
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/test_sec_limits.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/test_sec_limits.c
new file mode 100644
index 00000000000..f4f3ca5a6bb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/test_sec_limits.c
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+#include <limits.h>
+int A[16];
+int a = 0;
+
+int main () {
+ if (__sec_reduce_max(A[0:0:2]) != INT_MIN)
+ a++;
+
+ if (__sec_reduce_min(A[0:0:2]) != INT_MAX)
+ a++;
+
+ return a;
+}
+
+
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/tst_lngth.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/tst_lngth.c
new file mode 100644
index 00000000000..015a7eb7370
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/tst_lngth.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options " -fcilkplus " } */
+
+#if HAVE_IO
+#include <stdio.h>
+#endif
+
+#define N 256
+int A[N], B[N];
+
+int
+main ()
+{
+ A[0:(N / 4)] = A[4]+ B[0:(N / 2):2]; /* { dg-error "length mismatch between" } */
+ A[0:(N / 4)] = B[0:(N / 2):2] + N; /* { dg-error "length mismatch between" } */
+ A[0:(N / 4)] = B[0:(N / 2):2] + A[4]; /* { dg-error "length mismatch between" } */
+ return 0;
+}
+
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/vla.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/vla.c
new file mode 100644
index 00000000000..843745e384f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/vla.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus -std=c99" } */
+
+int func (int x)
+{
+ return x++;
+}
+int main(void)
+{
+ int argc = 1;
+ __asm volatile ("" : "+r" (argc));
+ int array[argc];
+
+ array[:] = 5; /* { dg-error "start-index and length fields necessary for using array notations in variable-length arrays." } */
+ array[0:argc] = 5; /* This is OK. */
+ array[0:5:2] = 5; /* This is OK. */
+ array[0:argc:2] = 5; /* This is OK. */
+ array[0:argc:func (argc-2)] = 5; /* This is OK. */
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag5.C b/gcc/testsuite/g++.dg/abi/abi-tag5.C
new file mode 100644
index 00000000000..de5580239dd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/abi-tag5.C
@@ -0,0 +1,6 @@
+// { dg-options -Wabi-tag }
+
+struct __attribute__ ((abi_tag ("foo"))) A { };
+template <class T> struct B: T { };
+
+B<A> b;
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-debug-0.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-debug-0.C
index 63655286b03..a9aae374947 100644
--- a/gcc/testsuite/g++.dg/cpp0x/alias-decl-debug-0.C
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-debug-0.C
@@ -1,5 +1,5 @@
// Origin: PR c++/51032
-// { dg-skip-if "No stabs" { mmix-*-* *-*-aix* alpha*-*-* hppa*64*-*-* ia64-*-* *-*-vxworks* } { "*" } { "" } }
+// { dg-skip-if "No stabs" { aarch64*-*-* mmix-*-* *-*-aix* alpha*-*-* hppa*64*-*-* ia64-*-* *-*-vxworks* } { "*" } { "" } }
// { dg-options "-std=c++0x -gstabs+" }
template <class C>
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype54.C b/gcc/testsuite/g++.dg/cpp0x/decltype54.C
new file mode 100644
index 00000000000..9d301c0a739
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype54.C
@@ -0,0 +1,26 @@
+// PR c++/51908
+// { dg-do compile { target c++11 } }
+
+struct foo1
+{
+ template <typename Ret, typename... Args>
+ operator decltype(static_cast<Ret (*)(Args...)>(nullptr)) () const;
+};
+
+struct foo2
+{
+ template <typename Ret, typename... Args>
+ operator decltype(static_cast<Ret (*)(Args... args)>(nullptr)) () const;
+};
+
+struct foo3
+{
+ template <typename Ret, typename Arg>
+ operator decltype(static_cast<Ret (*)(Arg)>(nullptr)) () const;
+};
+
+struct foo4
+{
+ template <typename Ret, typename Arg>
+ operator decltype(static_cast<Ret (*)(Arg arg)>(nullptr)) () const;
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted13.C b/gcc/testsuite/g++.dg/cpp0x/defaulted13.C
index 8b23579217e..5ddbcb38c1c 100644
--- a/gcc/testsuite/g++.dg/cpp0x/defaulted13.C
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted13.C
@@ -7,13 +7,13 @@ struct NonCopyable {
};
template<>
-NonCopyable<int>::NonCopyable(NonCopyable<int> const&) = delete; // { dg-error "declared" }
+NonCopyable<int>::NonCopyable(NonCopyable<int> const&) = delete; // { dg-message "declared" }
template<typename T>
NonCopyable<T>::NonCopyable(NonCopyable<T> const&) = default;
template<>
-NonCopyable<double>::NonCopyable(NonCopyable<double> const&) = delete; // { dg-error "declared" }
+NonCopyable<double>::NonCopyable(NonCopyable<double> const&) = delete; // { dg-message "declared" }
int main()
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted2.C b/gcc/testsuite/g++.dg/cpp0x/defaulted2.C
index e3aac8f1a9f..ce551a3fee2 100644
--- a/gcc/testsuite/g++.dg/cpp0x/defaulted2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted2.C
@@ -42,7 +42,7 @@ struct E
struct F
{
F() = default;
- F(const F&) = delete; // { dg-error "declared" }
+ F(const F&) = delete; // { dg-message "declared" }
};
struct G
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted26.C b/gcc/testsuite/g++.dg/cpp0x/defaulted26.C
index 69bd0accbd4..746fa908180 100644
--- a/gcc/testsuite/g++.dg/cpp0x/defaulted26.C
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted26.C
@@ -1,7 +1,7 @@
// PR c++/49066
// { dg-options -std=c++0x }
-void foo() = delete; // { dg-error "declared here" }
+void foo() = delete; // { dg-message "declared here" }
void foo();
int main() { foo(); } // { dg-error "deleted" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted3.C b/gcc/testsuite/g++.dg/cpp0x/defaulted3.C
index 5e2116b53b3..bc5b14d2d59 100644
--- a/gcc/testsuite/g++.dg/cpp0x/defaulted3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted3.C
@@ -4,7 +4,7 @@
template<class T>
struct A {
template<class U>
- bool operator==(const A<U>&) = delete; // { dg-error "declared" }
+ bool operator==(const A<U>&) = delete; // { dg-message "declared" }
operator bool () { return true; }
};
diff --git a/gcc/testsuite/g++.dg/cpp0x/error1.C b/gcc/testsuite/g++.dg/cpp0x/error1.C
index 751b3b75e0c..15cd38f8807 100644
--- a/gcc/testsuite/g++.dg/cpp0x/error1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/error1.C
@@ -2,7 +2,7 @@
// { dg-do compile }
// { dg-options "-std=c++0x" }
-template<int... N> void foo (int... x[N]) // { dg-error "int \\\[N\\\]\\.\\.\\. x" }
+template<int... N> void foo (int... x[N]) // { dg-message "int \\\[N\\\]\\.\\.\\. x" }
{
struct A
{
diff --git a/gcc/testsuite/g++.dg/cpp0x/implicit1.C b/gcc/testsuite/g++.dg/cpp0x/implicit1.C
index 2efbde6a93a..e4e16e1ad35 100644
--- a/gcc/testsuite/g++.dg/cpp0x/implicit1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/implicit1.C
@@ -15,7 +15,7 @@ D d; // { dg-error "deleted" }
struct E
{
- ~E() = delete; // { dg-error "declared here" }
+ ~E() = delete; // { dg-message "declared here" }
};
struct F
diff --git a/gcc/testsuite/g++.dg/cpp0x/implicit11.C b/gcc/testsuite/g++.dg/cpp0x/implicit11.C
index 7ec8e95dcb6..c974e2b7761 100644
--- a/gcc/testsuite/g++.dg/cpp0x/implicit11.C
+++ b/gcc/testsuite/g++.dg/cpp0x/implicit11.C
@@ -4,7 +4,7 @@
struct A
{
- ~A() = delete; // { dg-error "declared here" }
+ ~A() = delete; // { dg-message "declared here" }
};
struct B: A { }; // { dg-error "deleted" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor13.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor13.C
index 2e18e5d62f3..95cf932d001 100644
--- a/gcc/testsuite/g++.dg/cpp0x/inh-ctor13.C
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor13.C
@@ -8,7 +8,7 @@ struct A
struct C
{
- C() = delete; // { dg-error "declared here" }
+ C() = delete; // { dg-message "declared here" }
};
struct B: A, C
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist47.C b/gcc/testsuite/g++.dg/cpp0x/initlist47.C
index b76fb58361f..06d683e038a 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist47.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist47.C
@@ -1,6 +1,6 @@
// { dg-options -std=c++0x }
-struct A { ~A() = delete; }; // { dg-error "declared" }
+struct A { ~A() = delete; }; // { dg-message "declared" }
int main()
{
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist9.C b/gcc/testsuite/g++.dg/cpp0x/initlist9.C
index d596b391508..197fdd4ad04 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist9.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist9.C
@@ -8,7 +8,7 @@ struct b
b() = default;
~b() = default;
b& operator=(const b&) = delete;
- b(const b&) = delete; // { dg-error "declared" }
+ b(const b&) = delete; // { dg-message "declared" }
b(bool _t): t (_t) { }
};
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc.C
index f4766691eec..92c54313874 100644
--- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc.C
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc.C
@@ -5,7 +5,7 @@
struct A
{
A();
- A(const A& a) = delete; // { dg-error "declared" }
+ A(const A& a) = delete; // { dg-message "declared" }
};
int main()
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc2.C
index f94d64ec0ea..213f7c0babf 100644
--- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc2.C
@@ -3,7 +3,7 @@
struct A {
A();
- A(const A&) = delete; // { dg-error "declared" }
+ A(const A&) = delete; // { dg-message "declared" }
};
template <class T>
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-local.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-local.C
index 9b84c8c3ded..2330365f7ce 100644
--- a/gcc/testsuite/g++.dg/cpp0x/nsdmi-local.C
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-local.C
@@ -3,6 +3,6 @@
int main()
{
- int q = 1; // { dg-error "declared here" }
+ int q = 1; // { dg-message "declared here" }
struct test { int x = q; } instance; // { dg-error "local variable" }
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-union1.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-union1.C
new file mode 100644
index 00000000000..11bdd88eea2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-union1.C
@@ -0,0 +1,25 @@
+// PR c++/52377
+// { dg-do run { target c++11 } }
+
+union Test
+{
+ int a{4};
+};
+
+union B
+{
+ int i = 42;
+ double d;
+ B() = default;
+ B(double d): d(d) { }
+};
+
+int main()
+{
+ Test t;
+ B b;
+ B b2(4.2);
+
+ if (t.a != 4 || b.i != 42 || b2.d != 4.2)
+ __builtin_abort();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-union2.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-union2.C
new file mode 100644
index 00000000000..069232755f9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-union2.C
@@ -0,0 +1,18 @@
+// PR c++/52377
+// { dg-require-effective-target c++11 }
+
+union A // { dg-error "multiple" }
+{
+ int i = 4;
+ int j = 2;
+};
+
+A a;
+
+union B
+{
+ int i,j;
+ B(): i(1), j(2) {} // { dg-error "multiple" }
+};
+
+B b;
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae46.C b/gcc/testsuite/g++.dg/cpp0x/sfinae46.C
new file mode 100644
index 00000000000..20e859c23ee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/sfinae46.C
@@ -0,0 +1,13 @@
+// PR c++/57419
+// { dg-do compile { target c++11 } }
+
+template< typename q >
+decltype( &q::f ) t( q ) {}
+
+char t( ... ) { return {}; }
+
+class c { void f() = delete; };
+class d { static void f() = delete; };
+
+static_assert( sizeof( t( c() ) ), "c" );
+static_assert( sizeof( t( d() ) ), "d" );
diff --git a/gcc/testsuite/g++.dg/cpp0x/union4.C b/gcc/testsuite/g++.dg/cpp0x/union4.C
index 07050475d36..c82a81cdba8 100644
--- a/gcc/testsuite/g++.dg/cpp0x/union4.C
+++ b/gcc/testsuite/g++.dg/cpp0x/union4.C
@@ -3,7 +3,7 @@
struct SFoo
{
- SFoo() =delete; // { dg-error "declared" }
+ SFoo() =delete; // { dg-message "declared" }
};
union UFoo // { dg-error "deleted" }
diff --git a/gcc/testsuite/g++.dg/cpp1y/vla6.C b/gcc/testsuite/g++.dg/cpp1y/vla6.C
new file mode 100644
index 00000000000..b725e7b6f9c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/vla6.C
@@ -0,0 +1,14 @@
+// PR c++/57404
+// { dg-options "-std=c++11 -g" }
+
+void f (int i)
+{
+ int a[i];
+ [&a] {};
+}
+
+void g (int i)
+{
+ int a[i];
+ [&a] {} ();
+}
diff --git a/gcc/testsuite/g++.dg/opt/pr57411.C b/gcc/testsuite/g++.dg/opt/pr57411.C
new file mode 100644
index 00000000000..9c99ee0619c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr57411.C
@@ -0,0 +1,23 @@
+// { dg-do compile }
+// { dg-options "-O -fno-tree-dce -ftree-vectorize" }
+
+static inline void
+iota (int *__first, int *__last, int __value)
+{
+ for (; __first != __last; ++__first)
+ {
+ *__first = __value;
+ }
+}
+
+void assert_fail ();
+
+int A[] = { 0, 0, 0 };
+
+void
+test01 (int equal)
+{
+ iota (A, A + 3, 1);
+ if (equal)
+ assert_fail ();
+}
diff --git a/gcc/testsuite/g++.dg/template/crash108.C b/gcc/testsuite/g++.dg/template/crash108.C
index b6f49a19e58..221d80ee5f1 100644
--- a/gcc/testsuite/g++.dg/template/crash108.C
+++ b/gcc/testsuite/g++.dg/template/crash108.C
@@ -1,5 +1,5 @@
// PR c++/50861
template<class T> struct A {A(int b=k(0));}; // { dg-error "parameter|arguments" }
-void f(int k){A<int> a;} // // { dg-error "declared" }
+void f(int k){A<int> a;} // // { dg-message "declared" }
// { dg-message "note" "note" { target *-*-* } 3 }
diff --git a/gcc/testsuite/g++.dg/template/crash41.C b/gcc/testsuite/g++.dg/template/crash41.C
index 9a440b0761e..16e7028a668 100644
--- a/gcc/testsuite/g++.dg/template/crash41.C
+++ b/gcc/testsuite/g++.dg/template/crash41.C
@@ -1,7 +1,7 @@
// PR c++/22464
template<typename T>
-void do_something(const T* A) // { dg-error "declared" }
+void do_something(const T* A) // { dg-message "declared" }
{
struct helper_t{
helper_t() {
diff --git a/gcc/testsuite/g++.dg/torture/pr54684.C b/gcc/testsuite/g++.dg/torture/pr54684.C
index 40c47f3fa29..4934011e45f 100644
--- a/gcc/testsuite/g++.dg/torture/pr54684.C
+++ b/gcc/testsuite/g++.dg/torture/pr54684.C
@@ -1,4 +1,5 @@
// { dg-do compile }
+// { dg-options "-fno-short-enums" }
typedef union tree_node *tree;
typedef union gimple_statement_d *gimple;
diff --git a/gcc/testsuite/g++.dg/vect/slp-pr50413.cc b/gcc/testsuite/g++.dg/vect/slp-pr50413.cc
index e7bdf1f1c32..c47caf10747 100644
--- a/gcc/testsuite/g++.dg/vect/slp-pr50413.cc
+++ b/gcc/testsuite/g++.dg/vect/slp-pr50413.cc
@@ -160,6 +160,6 @@ void shift(unsigned char t)
V.bitmap.b96 = t;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 0 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/g++.dg/vect/slp-pr50819.cc b/gcc/testsuite/g++.dg/vect/slp-pr50819.cc
index 402218bc5b7..96f82c30218 100644
--- a/gcc/testsuite/g++.dg/vect/slp-pr50819.cc
+++ b/gcc/testsuite/g++.dg/vect/slp-pr50819.cc
@@ -49,5 +49,5 @@ const & v2) {
res = res + s*(v1+v2);
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 2 "slp" } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 2 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/g++.dg/vect/slp-pr56812.cc b/gcc/testsuite/g++.dg/vect/slp-pr56812.cc
index 9b2fcc683c3..9570fb31e86 100644
--- a/gcc/testsuite/g++.dg/vect/slp-pr56812.cc
+++ b/gcc/testsuite/g++.dg/vect/slp-pr56812.cc
@@ -17,5 +17,5 @@ void mydata::Set (float x)
data[i] = x;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/local.C b/gcc/testsuite/g++.old-deja/g++.jason/local.C
index 21fa9f58771..18d810a33ba 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/local.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/local.C
@@ -5,7 +5,7 @@ int x;
void f ()
{
static int s;
- int x; // { dg-error "" } referenced below
+ int x; // { dg-message "" } referenced below
extern int q();
struct local {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility3.C b/gcc/testsuite/g++.old-deja/g++.law/visibility3.C
index 64d64df647f..ddbbc84badc 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility3.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility3.C
@@ -11,7 +11,7 @@ int x;
int main(void)
{
static int s;
- int x; // { dg-error "" } declared
+ int x; // { dg-message "" } declared
extern int g();
struct local {
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb76.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb76.C
index c74e7bd8134..3125dc15f34 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb76.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb76.C
@@ -1,4 +1,5 @@
// { dg-do assemble }
+// { dg-options "-fno-short-enums" }
// the template operator!= interferes. It should be in a namespace.
#include <utility>
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr57441.c b/gcc/testsuite/gcc.c-torture/compile/pr57441.c
new file mode 100644
index 00000000000..e357c100518
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr57441.c
@@ -0,0 +1,26 @@
+/* PR tree-optimization/57441 */
+
+int a, c, d, *e;
+unsigned char b;
+
+char
+baz (char p1)
+{
+ return p1 * a;
+}
+
+void func_65 ();
+func_1 ()
+{
+ func_65 ();
+ func_65 ();
+}
+
+void
+func_65 ()
+{
+ d = baz (b--);
+ if (*e)
+ b--;
+ c = 0;
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-bswap-8.c b/gcc/testsuite/gcc.dg/builtin-bswap-8.c
index 8bf8902cafe..38c00a31420 100644
--- a/gcc/testsuite/gcc.dg/builtin-bswap-8.c
+++ b/gcc/testsuite/gcc.dg/builtin-bswap-8.c
@@ -1,7 +1,7 @@
/* { dg-do compile { target arm*-*-* alpha*-*-* i?86-*-* powerpc*-*-* rs6000-*-* x86_64-*-* s390*-*-* } } */
/* { dg-require-effective-target stdint_types } */
-/* { dg-options "-O -fdump-rtl-combine" } */
-/* { dg-options "-O -fdump-rtl-combine -march=z900" { target s390-*-* } } */
+/* { dg-options "-O2 -fdump-rtl-combine" } */
+/* { dg-options "-O2 -fdump-rtl-combine -march=z900" { target s390-*-* } } */
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.dg/builtin-bswap-9.c b/gcc/testsuite/gcc.dg/builtin-bswap-9.c
index 632dddfb322..4aa1a40c43e 100644
--- a/gcc/testsuite/gcc.dg/builtin-bswap-9.c
+++ b/gcc/testsuite/gcc.dg/builtin-bswap-9.c
@@ -1,7 +1,7 @@
/* { dg-do compile { target arm*-*-* alpha*-*-* ia64*-*-* x86_64-*-* s390x-*-* powerpc*-*-* rs6000-*-* } } */
/* { dg-require-effective-target stdint_types } */
/* { dg-require-effective-target lp64 } */
-/* { dg-options "-O -fdump-rtl-combine" } */
+/* { dg-options "-O2 -fdump-rtl-combine" } */
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/cilk-plus.exp b/gcc/testsuite/gcc.dg/cilk-plus/cilk-plus.exp
new file mode 100644
index 00000000000..59b23056c72
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cilk-plus/cilk-plus.exp
@@ -0,0 +1,45 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Written by Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+
+load_lib gcc-dg.exp
+
+dg-init
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -O0 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -O1 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -O2 -ftree-vectorize -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -O3 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -g -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -g -O0 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -g -O1 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -g -O2 -ftree-vectorize -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -g -O3 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -O3 -ftree-vectorize -fcilkplus -g" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -std=c99" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -O0 -std=c99" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -O1 -std=c99" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -O2 -ftree-vectorize -std=c99" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -O3 -std=c99" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -g -std=c99" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -g -O0 -std=c99" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -g -O1 -std=c99" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -g -O2 -ftree-vectorize -std=c99" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -g -O3 -std=c99" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -O3 -ftree-vectorize -std=c99 -g -fcilkplus" " "
+dg-finish
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/discriminator.c b/gcc/testsuite/gcc.dg/debug/dwarf2/discriminator.c
index 64434d2801e..d88a1f5332b 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/discriminator.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/discriminator.c
@@ -1,8 +1,10 @@
-/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
-/* { dg-options "-O0 -gdwarf-2" } */
-/* { dg-final { scan-assembler "loc \[0-9] 9 \[0-9]( is_stmt \[0-9])?\n" } } */
-/* { dg-final { scan-assembler "loc \[0-9] 9 \[0-9]( is_stmt \[0-9])? discriminator 2\n" } } */
-/* { dg-final { scan-assembler "loc \[0-9] 9 \[0-9]( is_stmt \[0-9])? discriminator 1\n" } } */
+/* HAVE_AS_DWARF2_DEBUG_LINE macro needs to be defined to pass the unittest.
+ However, there dg cannot defin it as, so we restrict the target to linux. */
+/* { dg-do compile { target *-*-linux-gnu } } */
+/* { dg-additional-options "-O0" } */
+/* { dg-final { scan-assembler "loc \[0-9] 11 \[0-9]( is_stmt \[0-9])?\n" } } */
+/* { dg-final { scan-assembler "loc \[0-9] 11 \[0-9]( is_stmt \[0-9])? discriminator 2\n" } } */
+/* { dg-final { scan-assembler "loc \[0-9] 11 \[0-9]( is_stmt \[0-9])? discriminator 1\n" } } */
int foo(int n) {
int i, ret = 0;
diff --git a/gcc/testsuite/gcc.dg/fshort-wchar.c b/gcc/testsuite/gcc.dg/fshort-wchar.c
index c9c751504df..bb698816774 100644
--- a/gcc/testsuite/gcc.dg/fshort-wchar.c
+++ b/gcc/testsuite/gcc.dg/fshort-wchar.c
@@ -2,7 +2,7 @@
/* { dg-do run } */
/* { dg-options "-fshort-wchar" } */
-/* { dg-options "-fshort-wchar -Wl,--no-wchar-size-warning" { target arm*-*-*eabi } } */
+/* { dg-options "-fshort-wchar -Wl,--no-wchar-size-warning" { target arm*-*-*eabi* } } */
/* Source: Neil Booth, 10 Dec 2002.
diff --git a/gcc/testsuite/gcc.dg/gomp/pr57412.c b/gcc/testsuite/gcc.dg/gomp/pr57412.c
new file mode 100644
index 00000000000..246f5323954
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/pr57412.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+int thr;
+#pragma omp threadprivate (thr)
+int foo ()
+{
+ int l;
+#pragma omp parallel copyin (thr) reduction (||:l)
+ ;
+}
diff --git a/gcc/testsuite/gcc.dg/shrink-wrap-alloca.c b/gcc/testsuite/gcc.dg/shrink-wrap-alloca.c
new file mode 100644
index 00000000000..fbe6f4fd20d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/shrink-wrap-alloca.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -g" } */
+
+int *p;
+
+void
+test (int a)
+{
+ if (a > 0)
+ p = __builtin_alloca (4);
+}
diff --git a/gcc/testsuite/gcc.dg/shrink-wrap-pretend.c b/gcc/testsuite/gcc.dg/shrink-wrap-pretend.c
new file mode 100644
index 00000000000..6e20ca12e98
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/shrink-wrap-pretend.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -g" } */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#define DEBUG_BUFFER_SIZE 80
+int unifi_debug = 5;
+
+void
+unifi_trace (void* ospriv, int level, const char *fmt, ...)
+{
+ static char s[DEBUG_BUFFER_SIZE];
+ va_list args;
+ unsigned int len;
+
+ if (!ospriv)
+ return;
+
+ if (unifi_debug >= level)
+ {
+ va_start (args, fmt);
+ len = vsnprintf (&(s)[0], (DEBUG_BUFFER_SIZE), fmt, args);
+ va_end (args);
+
+ if (len >= DEBUG_BUFFER_SIZE)
+ {
+ (s)[DEBUG_BUFFER_SIZE - 2] = '\n';
+ (s)[DEBUG_BUFFER_SIZE - 1] = 0;
+ }
+
+ printf ("%s", s);
+ }
+}
+
diff --git a/gcc/testsuite/gcc.dg/shrink-wrap-sibcall.c b/gcc/testsuite/gcc.dg/shrink-wrap-sibcall.c
new file mode 100644
index 00000000000..193bec2ce69
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/shrink-wrap-sibcall.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -g" } */
+
+unsigned char a, b, d, f, g;
+
+int test (void);
+
+int
+baz (int c)
+{
+ if (c == 0) return test ();
+ if (b & 1)
+ {
+ g = 0;
+ int e = (a & 0x0f) - (g & 0x0f);
+
+ if (!a) b |= 0x80;
+ a = e + test ();
+ f = g/5 + a*3879 + b *2985;
+ }
+ else
+ {
+ f = g + a*39879 + b *25;
+ }
+ return test ();
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr57343.c b/gcc/testsuite/gcc.dg/torture/pr57343.c
new file mode 100644
index 00000000000..b05bad5cb43
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr57343.c
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+
+int c = 0;
+
+int
+main ()
+{
+ int i, f = 1;
+ for (i = 0; i < 5; i++)
+ {
+ --c;
+ unsigned char h = c * 100;
+ if (h == 0)
+ {
+ f = 0;
+ break;
+ }
+ }
+ if (f != 1)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr57417.c b/gcc/testsuite/gcc.dg/torture/pr57417.c
new file mode 100644
index 00000000000..6eac6f932b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr57417.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+int a, b;
+volatile int *c;
+
+void foo ()
+{
+ volatile int d[1];
+ b = 0;
+ for (;; a--)
+ c = &d[b];
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr57478.c b/gcc/testsuite/gcc.dg/torture/pr57478.c
new file mode 100644
index 00000000000..e81348dfd73
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr57478.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+typedef struct Node Node;
+
+struct Node
+{
+ Node *Pred, *Suc;
+ Node *SubBestPred;
+ Node *SubBestSuc;
+};
+
+void
+foo (Node *N)
+{
+ do
+ {
+ N->SubBestPred = N->Pred;
+ N->SubBestSuc = N->Suc;
+ }
+ while (N = N->Suc);
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/attr-alias.c b/gcc/testsuite/gcc.dg/tree-ssa/attr-alias.c
new file mode 100644
index 00000000000..b2001821afd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/attr-alias.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-alias "" } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+void abort (void);
+__attribute__ ((weak))
+int test()
+{
+ return 0;
+}
+static int test2() __attribute__ ((alias("test")));
+static int test3() __attribute__ ((weakref)) __attribute__ ((alias("test2")));
+static int test4() __attribute__ ((weakref)) __attribute__ ((alias("test")));
+main()
+{
+ test();
+ test2();
+ test3();
+ test4();
+}
+
+/* calls to test1 and test2 can be inlined and optmized away. Calls
+ to test and test4 are overwritable. */
+
+/* { dg-final { scan-tree-dump-times "test (" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "test4 (" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "test1 (" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "test2 (" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr42585.c b/gcc/testsuite/gcc.dg/tree-ssa/pr42585.c
index d01b8abdda7..520c357a3ad 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr42585.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr42585.c
@@ -35,6 +35,6 @@ Cyc_string_ungetc (int ignore, struct _fat_ptr *sptr)
/* Whether the structs are totally scalarized or not depends on the
MOVE_RATIO macro defintion in the back end. The scalarization will
not take place when using small values for MOVE_RATIO. */
-/* { dg-final { scan-tree-dump-times "struct _fat_ptr _ans" 0 "optimized" { target { ! "arm-*-* powerpc*-*-* s390*-*-* sh*-*-*" } } } } */
-/* { dg-final { scan-tree-dump-times "struct _fat_ptr _T2" 0 "optimized" { target { ! "arm-*-* powerpc*-*-* s390*-*-* sh*-*-*" } } } } */
+/* { dg-final { scan-tree-dump-times "struct _fat_ptr _ans" 0 "optimized" { target { ! "arm*-*-* powerpc*-*-* s390*-*-* sh*-*-*" } } } } */
+/* { dg-final { scan-tree-dump-times "struct _fat_ptr _T2" 0 "optimized" { target { ! "arm*-*-* powerpc*-*-* s390*-*-* sh*-*-*" } } } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr43491.c b/gcc/testsuite/gcc.dg/tree-ssa/pr43491.c
index 24734004456..44dc5f2d3cf 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr43491.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr43491.c
@@ -37,6 +37,6 @@ long foo(long data, long v)
}
/* We should not eliminate global register variable when it is the RHS of
a single assignment. */
-/* { dg-final { scan-tree-dump-times "Eliminated: 2" 1 "pre" { target { arm-*-* i?86-*-* mips*-*-* x86_64-*-* } } } } */
-/* { dg-final { scan-tree-dump-times "Eliminated: 3" 1 "pre" { target { ! { arm-*-* i?86-*-* mips*-*-* x86_64-*-* } } } } } */
+/* { dg-final { scan-tree-dump-times "Eliminated: 2" 1 "pre" { target { arm*-*-* i?86-*-* mips*-*-* x86_64-*-* } } } } */
+/* { dg-final { scan-tree-dump-times "Eliminated: 3" 1 "pre" { target { ! { arm*-*-* i?86-*-* mips*-*-* x86_64-*-* } } } } } */
/* { dg-final { cleanup-tree-dump "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-30.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-30.c
new file mode 100644
index 00000000000..66289848322
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-30.c
@@ -0,0 +1,13 @@
+/* PR tree-optimization/57442 */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+short a;
+unsigned b;
+long c;
+int d;
+
+void f(void)
+{
+ b = a ? : (a = b) - c + (d - (b + b));
+}
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-1.c
index c13ee3b181d..11882ec5d4a 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-1.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-1.c
@@ -56,6 +56,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-10.c b/gcc/testsuite/gcc.dg/vect/bb-slp-10.c
index f127c7f11ef..6eb8f5465f8 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-10.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-10.c
@@ -50,6 +50,6 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "unsupported alignment in basic block." 1 "slp" { xfail vect_element_align } } } */
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_element_align } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_element_align } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-11.c b/gcc/testsuite/gcc.dg/vect/bb-slp-11.c
index 225d08ec33b..9844788ea0d 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-11.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-11.c
@@ -48,6 +48,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect64 } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect64 } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-13.c b/gcc/testsuite/gcc.dg/vect/bb-slp-13.c
index 4e114d5f94a..f312ea64fc1 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-13.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-13.c
@@ -46,6 +46,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-14.c b/gcc/testsuite/gcc.dg/vect/bb-slp-14.c
index fc6b457811f..9a36033ca7b 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-14.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-14.c
@@ -47,6 +47,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 0 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-15.c b/gcc/testsuite/gcc.dg/vect/bb-slp-15.c
index cab46d6092c..842699ecb0a 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-15.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-15.c
@@ -51,6 +51,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-16.c b/gcc/testsuite/gcc.dg/vect/bb-slp-16.c
index 4390753db4d..609dc7b6a3e 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-16.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-16.c
@@ -65,6 +65,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-17.c b/gcc/testsuite/gcc.dg/vect/bb-slp-17.c
index a64543f8297..5a917b8b3f7 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-17.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-17.c
@@ -57,6 +57,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-18.c b/gcc/testsuite/gcc.dg/vect/bb-slp-18.c
index 7869e32fe3e..98501ccf6a6 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-18.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-18.c
@@ -46,6 +46,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-19.c b/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
index a314626f0d6..2f726121c94 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
@@ -53,6 +53,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-2.c
index 20a61a08d2d..da228f7c33c 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-2.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-2.c
@@ -53,6 +53,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-20.c b/gcc/testsuite/gcc.dg/vect/bb-slp-20.c
index 9991fe39985..caaecb9bafb 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-20.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-20.c
@@ -63,7 +63,7 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-21.c b/gcc/testsuite/gcc.dg/vect/bb-slp-21.c
index acd332079cd..eba9d08c951 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-21.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-21.c
@@ -63,7 +63,7 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "slp" { target { ! {vect_int_mult } } } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-22.c b/gcc/testsuite/gcc.dg/vect/bb-slp-22.c
index 2fa2c1b3276..30bc57a6bbb 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-22.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-22.c
@@ -63,7 +63,7 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target { ! {vect_int_mult } } } } } */
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 2 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { ! {vect_int_mult } } } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 2 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-23.c b/gcc/testsuite/gcc.dg/vect/bb-slp-23.c
index 1c09048ee07..a736c385c81 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-23.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-23.c
@@ -51,6 +51,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-24.c b/gcc/testsuite/gcc.dg/vect/bb-slp-24.c
index cbe1cb3edea..10d8e406647 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-24.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-24.c
@@ -54,6 +54,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_element_align } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_element_align } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-25.c b/gcc/testsuite/gcc.dg/vect/bb-slp-25.c
index 193ab9d4db3..b92535df00c 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-25.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-25.c
@@ -54,6 +54,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_element_align } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_element_align } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-26.c b/gcc/testsuite/gcc.dg/vect/bb-slp-26.c
index cf8f9587d03..f40c12402b6 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-26.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-26.c
@@ -55,6 +55,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect64 } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect64 } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-27.c b/gcc/testsuite/gcc.dg/vect/bb-slp-27.c
index 7157ebadddc..e9b386f4921 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-27.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-27.c
@@ -44,6 +44,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target { vect_int_mult && { vect_unpack && vect_pack_trunc } } } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { vect_int_mult && { vect_unpack && vect_pack_trunc } } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-28.c b/gcc/testsuite/gcc.dg/vect/bb-slp-28.c
index 996f8f3cad8..3dc1a0d8a7c 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-28.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-28.c
@@ -66,6 +66,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target { vect_int_mult && { vect_pack_trunc && vect_unpack } } } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { vect_int_mult && { vect_pack_trunc && vect_unpack } } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-29.c b/gcc/testsuite/gcc.dg/vect/bb-slp-29.c
index e37b96d14d9..c2bc391885d 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-29.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-29.c
@@ -54,6 +54,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target { vect_int_mult && vect_element_align } } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { vect_int_mult && vect_element_align } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-3.c b/gcc/testsuite/gcc.dg/vect/bb-slp-3.c
index fee62d7f98f..98cbc5b80ea 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-3.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-3.c
@@ -42,6 +42,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-30.c b/gcc/testsuite/gcc.dg/vect/bb-slp-30.c
index 63689e3434e..a587780364f 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-30.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-30.c
@@ -43,5 +43,5 @@ test1(void)
int main() { test1(); return a[21]; }
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-31.c b/gcc/testsuite/gcc.dg/vect/bb-slp-31.c
index 9a3eac62b52..e2704dc721f 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-31.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-31.c
@@ -9,4 +9,4 @@ void f(){
a[1]=1+2*a[1]*a[1];
}
-/* { dg-final { scan-tree-dump "basic block vectorized using SLP" "slp" } } */
+/* { dg-final { scan-tree-dump "Vectorized basic-block" "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-32.c b/gcc/testsuite/gcc.dg/vect/bb-slp-32.c
new file mode 100644
index 00000000000..df8008396a0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-32.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-additional-options "-fvect-cost-model" } */
+
+void bar (int *);
+int foo (int *p)
+{
+ int x[4];
+ int tem0, tem1, tem2, tem3;
+ tem0 = p[0] + 1;
+ x[0] = tem0;
+ tem1 = p[1] + 2;
+ x[1] = tem1;
+ tem2 = p[2] + 3;
+ x[2] = tem2;
+ tem3 = p[3] + 4;
+ x[3] = tem3;
+ bar (x);
+ return tem0 + tem1 + tem2 + tem3;
+}
+
+/* { dg-final { scan-tree-dump "vectorization is not profitable" "slp" } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-4.c b/gcc/testsuite/gcc.dg/vect/bb-slp-4.c
index a7632f9832b..5b983c7e63e 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-4.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-4.c
@@ -38,6 +38,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 0 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-5.c b/gcc/testsuite/gcc.dg/vect/bb-slp-5.c
index c4a8a881e02..cd1679e981d 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-5.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-5.c
@@ -47,6 +47,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-6.c b/gcc/testsuite/gcc.dg/vect/bb-slp-6.c
index 176010ae5d9..39d8c04cc9a 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-6.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-6.c
@@ -45,6 +45,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-7.c b/gcc/testsuite/gcc.dg/vect/bb-slp-7.c
index 4f82122111a..c0ca017d0d8 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-7.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-7.c
@@ -46,6 +46,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 0 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8.c
index b1203f4dbba..1cb3ddd65e6 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-8.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8.c
@@ -48,6 +48,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c
index 2251275d4fb..9db6747985e 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c
@@ -47,6 +47,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 0 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c
index 62a691e1baf..dc6353999f3 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c
@@ -49,6 +49,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-9.c b/gcc/testsuite/gcc.dg/vect/bb-slp-9.c
index 5535dee0641..3b950897249 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-9.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-9.c
@@ -46,6 +46,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { xfail vect_no_align } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c
index ae833e53dc0..38c18a71fc7 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c
@@ -41,6 +41,6 @@ int main ()
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_element_align } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_element_align } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
index 30fa487cbf6..0d4d54fe0c2 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
@@ -48,5 +48,5 @@ int main ()
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target { vect_element_align && vect_pack_trunc } } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { vect_element_align && vect_pack_trunc } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c
index 7b76b440e1b..d842658c679 100644
--- a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c
+++ b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c
@@ -45,5 +45,5 @@ main ()
return main1 ();
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target { vect_call_copysignf && vect_call_sqrtf } } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { vect_call_copysignf && vect_call_sqrtf } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c
index bf19fcd1594..d6fb6a2b6f9 100644
--- a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c
+++ b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c
@@ -63,5 +63,5 @@ main ()
return main1 ();
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 2 "slp" { target vect_call_lrint } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 2 "slp" { target vect_call_lrint } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c
index 4b613050a4c..7a7765110ec 100644
--- a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c
+++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c
@@ -1,4 +1,6 @@
-/* { dg-require-effective-target vect_int } */
+/* { dg-require-effective-target vect_int }
+ { dg-skip-if "AArch64 tiny code model does not support programs larger than 1MiB" {aarch64_tiny} {"*"} {""} }
+ */
#include <stdarg.h>
#include "tree-vect.h"
diff --git a/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c b/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c
index 349bf8b30fe..b4154835a11 100644
--- a/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c
+++ b/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c
@@ -47,6 +47,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr56787.c b/gcc/testsuite/gcc.dg/vect/pr56787.c
new file mode 100644
index 00000000000..313d477492f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr56787.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_float } */
+
+inline void
+bar (const float s[5], float z[3][5])
+{
+ float a = s[0], b = s[1], c = s[2], d = s[3], e = s[4];
+ float f = 1.0f / a;
+ float u = f * b, v = f * c, w = f * d;
+ float p = 0.4f * (e - 0.5f * (b * u + c * v + d * w));
+ z[0][3] = b * w;
+ z[1][3] = c * w;
+ z[2][3] = d * w + p;
+}
+
+void
+foo (unsigned long n, const float *__restrict u0,
+ const float *__restrict u1, const float *__restrict u2,
+ const float *__restrict u3, const float *__restrict u4,
+ const float *__restrict s0, const float *__restrict s1,
+ const float *__restrict s2, float *__restrict t3,
+ float *__restrict t4)
+{
+ unsigned long i;
+ for (i = 0; i < n; i++)
+ {
+ float u[5], f[3][5];
+ u[0] = u0[i]; u[1] = u1[i]; u[2] = u2[i]; u[3] = u3[i]; u[4] = u4[i];
+ bar (u, f);
+ t3[i] = s0[i] * f[0][3] + s1[i] * f[1][3] + s2[i] * f[2][3];
+ }
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/insv_1.c b/gcc/testsuite/gcc.target/aarch64/insv_1.c
new file mode 100644
index 00000000000..bc8928d7347
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/insv_1.c
@@ -0,0 +1,84 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps -fno-inline" } */
+
+extern void abort (void);
+
+typedef struct bitfield
+{
+ unsigned short eight: 8;
+ unsigned short four: 4;
+ unsigned short five: 5;
+ unsigned short seven: 7;
+ unsigned int sixteen: 16;
+} bitfield;
+
+bitfield
+bfi1 (bitfield a)
+{
+ /* { dg-final { scan-assembler "bfi\tx\[0-9\]+, x\[0-9\]+, 0, 8" } } */
+ a.eight = 3;
+ return a;
+}
+
+bitfield
+bfi2 (bitfield a)
+{
+ /* { dg-final { scan-assembler "bfi\tx\[0-9\]+, x\[0-9\]+, 16, 5" } } */
+ a.five = 7;
+ return a;
+}
+
+bitfield
+movk (bitfield a)
+{
+ /* { dg-final { scan-assembler "movk\tx\[0-9\]+, 0x1d6b, lsl 32" } } */
+ a.sixteen = 7531;
+ return a;
+}
+
+bitfield
+set1 (bitfield a)
+{
+ /* { dg-final { scan-assembler "orr\tx\[0-9\]+, x\[0-9\]+, 2031616" } } */
+ a.five = 0x1f;
+ return a;
+}
+
+bitfield
+set0 (bitfield a)
+{
+ /* { dg-final { scan-assembler "and\tx\[0-9\]+, x\[0-9\]+, -2031617" } } */
+ a.five = 0;
+ return a;
+}
+
+
+int
+main (int argc, char** argv)
+{
+ static bitfield a;
+ bitfield b = bfi1 (a);
+ bitfield c = bfi2 (b);
+ bitfield d = movk (c);
+
+ if (d.eight != 3)
+ abort ();
+
+ if (d.five != 7)
+ abort ();
+
+ if (d.sixteen != 7531)
+ abort ();
+
+ d = set1 (d);
+ if (d.five != 0x1f)
+ abort ();
+
+ d = set0 (d);
+ if (d.five != 0)
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/movi_1.c b/gcc/testsuite/gcc.target/aarch64/movi_1.c
new file mode 100644
index 00000000000..e2842b39e02
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/movi_1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void
+dummy (short* b)
+{
+ /* { dg-final { scan-assembler "movi\tv\[0-9\]+\.4h, 0x4, lsl 8" } } */
+ /* { dg-final { scan-assembler-not "movi\tv\[0-9\]+\.4h, 0x400" } } */
+ /* { dg-final { scan-assembler-not "movi\tv\[0-9\]+\.4h, 1024" } } */
+ register short x asm ("h8") = 1024;
+ asm volatile ("" : : "w" (x));
+ *b = x;
+}
diff --git a/gcc/testsuite/gcc.target/arm/iordi3-opt.c b/gcc/testsuite/gcc.target/arm/iordi3-opt.c
new file mode 100644
index 00000000000..b3f465b7492
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/iordi3-opt.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+unsigned long long or64 (unsigned long long input)
+{
+ return input | 0x200000004ULL;
+}
+
+/* { dg-final { scan-assembler-not "mov\[\\t \]+.+,\[\\t \]*.+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/pr56184.C b/gcc/testsuite/gcc.target/arm/pr56184.C
index db92db13f9e..d44c1b432da 100644
--- a/gcc/testsuite/gcc.target/arm/pr56184.C
+++ b/gcc/testsuite/gcc.target/arm/pr56184.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mthumb -march=armv7-a -mfpu=neon -mfloat-abi=softfp -mtune=cortex-a9 -fno-section-anchors" } */
+/* { dg-options "-fno-short-enums -O2 -mthumb -march=armv7-a -mfpu=neon -mfloat-abi=softfp -mtune=cortex-a9 -fno-section-anchors" } */
typedef unsigned int size_t;
__extension__ typedef int __intptr_t;
diff --git a/gcc/testsuite/gcc.target/powerpc/e500-ord-1.c b/gcc/testsuite/gcc.target/powerpc/e500-ord-1.c
new file mode 100644
index 00000000000..c4f2769901c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/e500-ord-1.c
@@ -0,0 +1,29 @@
+/* { dg-do compile { target powerpc*-*-eabi* } } */
+/* { dg-options "-O -ftrapping-math -fdump-rtl-final" } */
+
+int isgreater (float f1, float f2)
+{
+ int r = (f1 > f2);
+ return !r ? -1 : 1;
+}
+
+int isgreaterequal (float f1, float f2)
+{
+ int r = (f1 >= f2);
+ return !r ? -1 : 1;
+}
+
+int isless (float f1, float f2)
+{
+ int r = (f1 < f2);
+ return !r ? -1 : 1;
+}
+
+int islessequal (float f1, float f2)
+{
+ int r = (f1 <= f2);
+ return !r ? -1 : 1;
+}
+
+/* { dg-final { scan-rtl-dump-not "__unordsf2" "final" } } */
+/* { dg-final { cleanup-rtl-dump "final" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/e500-ord-2.c b/gcc/testsuite/gcc.target/powerpc/e500-ord-2.c
new file mode 100644
index 00000000000..a6b5c297370
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/e500-ord-2.c
@@ -0,0 +1,29 @@
+/* { dg-do compile { target powerpc*-*-eabi* } } */
+/* { dg-options "-O -fno-trapping-math -fdump-rtl-final" } */
+
+int isgreater (float f1, float f2)
+{
+ int r = (f1 > f2);
+ return !r ? -1 : 1;
+}
+
+int isgreaterequal (float f1, float f2)
+{
+ int r = (f1 >= f2);
+ return !r ? -1 : 1;
+}
+
+int isless (float f1, float f2)
+{
+ int r = (f1 < f2);
+ return !r ? -1 : 1;
+}
+
+int islessequal (float f1, float f2)
+{
+ int r = (f1 <= f2);
+ return !r ? -1 : 1;
+}
+
+/* { dg-final { scan-rtl-dump-not "__unordsf2" "final" } } */
+/* { dg-final { cleanup-rtl-dump "final" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/e500-unord-1.c b/gcc/testsuite/gcc.target/powerpc/e500-unord-1.c
new file mode 100644
index 00000000000..0cd75d8d30d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/e500-unord-1.c
@@ -0,0 +1,29 @@
+/* { dg-do compile { target powerpc*-*-eabi* } } */
+/* { dg-options "-O -ftrapping-math -fdump-rtl-final" } */
+
+int isgreater (float f1, float f2)
+{
+ int r = __builtin_isgreater (f1, f2);
+ return !r ? -1 : 1;
+}
+
+int isgreaterequal (float f1, float f2)
+{
+ int r = __builtin_isgreaterequal (f1, f2);
+ return !r ? -1 : 1;
+}
+
+int isless (float f1, float f2)
+{
+ int r = __builtin_isless (f1, f2);
+ return !r ? -1 : 1;
+}
+
+int islessequal (float f1, float f2)
+{
+ int r = __builtin_islessequal (f1, f2);
+ return !r ? -1 : 1;
+}
+
+/* { dg-final { scan-rtl-dump-times "__unordsf2" 4 "final" } } */
+/* { dg-final { cleanup-rtl-dump "final" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/e500-unord-2.c b/gcc/testsuite/gcc.target/powerpc/e500-unord-2.c
new file mode 100644
index 00000000000..51b1316f271
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/e500-unord-2.c
@@ -0,0 +1,29 @@
+/* { dg-do compile { target powerpc*-*-eabi* } } */
+/* { dg-options "-O -fno-trapping-math -fdump-rtl-final" } */
+
+int isgreater (float f1, float f2)
+{
+ int r = __builtin_isgreater (f1, f2);
+ return !r ? -1 : 1;
+}
+
+int isgreaterequal (float f1, float f2)
+{
+ int r = __builtin_isgreaterequal (f1, f2);
+ return !r ? -1 : 1;
+}
+
+int isless (float f1, float f2)
+{
+ int r = __builtin_isless (f1, f2);
+ return !r ? -1 : 1;
+}
+
+int islessequal (float f1, float f2)
+{
+ int r = __builtin_islessequal (f1, f2);
+ return !r ? -1 : 1;
+}
+
+/* { dg-final { scan-rtl-dump-not "__unordsf2" "final" } } */
+/* { dg-final { cleanup-rtl-dump "final" } } */
diff --git a/gcc/testsuite/gcc.target/sparc/bmaskbshuf.c b/gcc/testsuite/gcc.target/sparc/bmaskbshuf.c
index 7108a018e5e..22809b5f5e9 100644
--- a/gcc/testsuite/gcc.target/sparc/bmaskbshuf.c
+++ b/gcc/testsuite/gcc.target/sparc/bmaskbshuf.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-O -mcpu=ultrasparc3 -mvis -mvis2" } */
+/* { dg-options "-O -mvis2" } */
+
typedef long long int64_t;
typedef int vec32 __attribute__((vector_size(8)));
typedef short vec16 __attribute__((vector_size(8)));
diff --git a/gcc/testsuite/gfortran.dg/alloc_comp_basics_1.f90 b/gcc/testsuite/gfortran.dg/alloc_comp_basics_1.f90
index 9b08129add6..65724fe4b72 100644
--- a/gcc/testsuite/gfortran.dg/alloc_comp_basics_1.f90
+++ b/gcc/testsuite/gfortran.dg/alloc_comp_basics_1.f90
@@ -33,8 +33,10 @@ program alloc
integer, allocatable :: a2(:)
end type alloc2
- type(alloc2) :: b
integer :: i
+
+ BLOCK ! To ensure that the allocatables are freed at the end of the scope
+ type(alloc2) :: b
type(alloc2), allocatable :: c(:)
if (allocated(b%a2) .OR. allocated(b%a1)) then
@@ -64,7 +66,7 @@ program alloc
deallocate(c)
! 7 calls to _gfortran_deallocate (b (3) and c(4) goes aout of scope)
-
+ END BLOCK
contains
subroutine allocate_alloc2(b)
diff --git a/gcc/testsuite/gfortran.dg/alloc_comp_constructor_1.f90 b/gcc/testsuite/gfortran.dg/alloc_comp_constructor_1.f90
index 969e703094c..8003c051477 100644
--- a/gcc/testsuite/gfortran.dg/alloc_comp_constructor_1.f90
+++ b/gcc/testsuite/gfortran.dg/alloc_comp_constructor_1.f90
@@ -19,9 +19,12 @@ Program test_constructor
type(thytype), allocatable :: q(:)
end type mytype
- type (mytype) :: x
type (thytype) :: foo = thytype(reshape ([43, 100, 54, 76], [2,2]))
integer :: y(0:1, -1:0) = reshape ([42, 99, 55, 77], [2,2])
+
+ BLOCK ! Add scoping unit as the vars are otherwise implicitly SAVEd
+
+ type (mytype) :: x
integer, allocatable :: yy(:,:)
type (thytype), allocatable :: bar(:)
integer :: i
@@ -70,7 +73,7 @@ Program test_constructor
! Check that passing the constructor to a procedure works
call check_mytype (mytype(y, [foo, foo]))
-
+ END BLOCK
contains
subroutine check_mytype(x)
diff --git a/gcc/testsuite/gfortran.dg/allocatable_scalar_9.f90 b/gcc/testsuite/gfortran.dg/allocatable_scalar_9.f90
index 3488c0d7277..fd0b4dbf216 100644
--- a/gcc/testsuite/gfortran.dg/allocatable_scalar_9.f90
+++ b/gcc/testsuite/gfortran.dg/allocatable_scalar_9.f90
@@ -28,10 +28,12 @@ end type t4
end module m
use m
+block ! Start new scoping unit as otherwise the vars are implicitly SAVEd
type(t1) :: na1, a1, aa1(:)
type(t2) :: na2, a2, aa2(:)
type(t3) :: na3, a3, aa3(:)
type(t4) :: na4, a4, aa4(:)
+
allocatable :: a1, a2, a3, a4, aa1, aa2, aa3,aa4
if(allocated(a1)) call abort()
@@ -47,6 +49,7 @@ if(allocated(na1%b1)) call abort()
if(allocated(na2%b2)) call abort()
if(allocated(na3%b3)) call abort()
if(allocated(na4%b4)) call abort()
+end block
end
! { dg-final { scan-tree-dump-times "__builtin_free" 32 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/assumed_rank_13.f90 b/gcc/testsuite/gfortran.dg/assumed_rank_13.f90
new file mode 100644
index 00000000000..99a982b33ed
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/assumed_rank_13.f90
@@ -0,0 +1,26 @@
+! { dg-do compile }
+!
+! PR fortran/57458
+!
+!
+
+ integer, pointer, asynchronous :: i(:)
+ integer, pointer, volatile :: j(:)
+ call foo(i)
+ call foo2(i)
+ call foo3(j)
+ call foo4(j)
+contains
+ subroutine foo(x)
+ type(*), dimension(:), asynchronous :: x
+ end subroutine foo
+ subroutine foo2(x)
+ type(*), dimension(..), asynchronous :: x
+ end subroutine foo2
+ subroutine foo3(x)
+ type(*), dimension(:), asynchronous :: x
+ end subroutine foo3
+ subroutine foo4(x)
+ type(*), dimension(..), asynchronous :: x
+ end subroutine foo4
+end
diff --git a/gcc/testsuite/gfortran.dg/assumed_size_1.f90 b/gcc/testsuite/gfortran.dg/assumed_size_1.f90
new file mode 100644
index 00000000000..1ad1ae844ad
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/assumed_size_1.f90
@@ -0,0 +1,17 @@
+! { dg-do compile }
+!
+! PR 54189: ICE (segfault) with invalid assumed-size dummy
+!
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+
+ implicit none
+ procedure(g), pointer :: x ! { dg-error "must be a dummy argument" }
+ x => g
+
+contains
+
+ function g() ! { dg-error "must be a dummy argument" }
+ integer :: g(*)
+ end function
+
+end
diff --git a/gcc/testsuite/gfortran.dg/assumed_type_7.f90 b/gcc/testsuite/gfortran.dg/assumed_type_7.f90
new file mode 100644
index 00000000000..48cb43e7f8d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/assumed_type_7.f90
@@ -0,0 +1,23 @@
+! { dg-do compile }
+!
+! PR 54190: TYPE(*)/assumed-rank: Type/rank check too relaxed for dummy procedure
+!
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+
+implicit none
+call sub(f) ! { dg-error "Type mismatch in argument" }
+contains
+
+ subroutine f(x)
+ type(*) :: x
+ end subroutine
+
+ subroutine sub(g)
+ interface
+ subroutine g(x)
+ integer :: x
+ end subroutine
+ end interface
+ end subroutine
+
+end
diff --git a/gcc/testsuite/gfortran.dg/auto_dealloc_2.f90 b/gcc/testsuite/gfortran.dg/auto_dealloc_2.f90
index e607b6ad91d..f47ec87c46f 100644
--- a/gcc/testsuite/gfortran.dg/auto_dealloc_2.f90
+++ b/gcc/testsuite/gfortran.dg/auto_dealloc_2.f90
@@ -11,11 +11,12 @@ type :: t
integer, allocatable :: i(:)
end type
+block ! New block as the main program implies SAVE
type(t) :: a
call init(a)
call init(a)
-
+end block
contains
subroutine init(x)
@@ -25,5 +26,5 @@ contains
end program
-! { dg-final { scan-tree-dump-times "__builtin_free" 3 "original" } }
+! { dg-final { scan-tree-dump-times "__builtin_free" 5 "original" } }
! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/bounds_check_7.f90 b/gcc/testsuite/gfortran.dg/bounds_check_7.f90
index c488a68cadc..b38419908bb 100644
--- a/gcc/testsuite/gfortran.dg/bounds_check_7.f90
+++ b/gcc/testsuite/gfortran.dg/bounds_check_7.f90
@@ -5,7 +5,7 @@
subroutine foo(a)
integer a(*), i
i = 0
- a(i) = 42 ! {
+ a(i) = 42
end subroutine foo
program test
diff --git a/gcc/testsuite/gfortran.dg/class_19.f03 b/gcc/testsuite/gfortran.dg/class_19.f03
index 63b8e06965a..428015c99ec 100644
--- a/gcc/testsuite/gfortran.dg/class_19.f03
+++ b/gcc/testsuite/gfortran.dg/class_19.f03
@@ -39,5 +39,5 @@ program main
end program main
-! { dg-final { scan-tree-dump-times "__builtin_free" 11 "original" } }
+! { dg-final { scan-tree-dump-times "__builtin_free" 12 "original" } }
! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/class_array_16.f90 b/gcc/testsuite/gfortran.dg/class_array_16.f90
new file mode 100644
index 00000000000..fc8edbf140a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/class_array_16.f90
@@ -0,0 +1,71 @@
+! { dg-do run }
+! { dg-options "-fdump-tree-original" }
+!
+module m
+ implicit none
+ type t
+ end type t
+
+ type, extends(t) :: t2
+ end type t2
+
+ type(t) :: var_t
+ type(t2) :: var_t2
+contains
+ subroutine sub(x)
+ class(t), allocatable, intent(out) :: x(:)
+
+ if (allocated (x)) call abort()
+ if (.not. same_type_as(x, var_t)) call abort()
+
+ allocate (t2 :: x(5))
+ end subroutine sub
+
+ subroutine sub2(x)
+ class(t), allocatable, OPTIONAL, intent(out) :: x(:)
+
+ if (.not. present(x)) return
+ if (allocated (x)) call abort()
+ if (.not. same_type_as(x, var_t)) call abort()
+
+ allocate (t2 :: x(5))
+ end subroutine sub2
+end module m
+
+use m
+implicit none
+class(t), save, allocatable :: y(:)
+
+if (allocated (y)) call abort()
+if (.not. same_type_as(y,var_t)) call abort()
+
+call sub(y)
+if (.not.allocated(y)) call abort()
+if (.not. same_type_as(y, var_t2)) call abort()
+if (size (y) /= 5) call abort()
+
+call sub(y)
+if (.not.allocated(y)) call abort()
+if (.not. same_type_as(y, var_t2)) call abort()
+if (size (y) /= 5) call abort()
+
+deallocate (y)
+if (allocated (y)) call abort()
+if (.not. same_type_as(y,var_t)) call abort()
+
+call sub2()
+
+call sub2(y)
+if (.not.allocated(y)) call abort()
+if (.not. same_type_as(y, var_t2)) call abort()
+if (size (y) /= 5) call abort()
+
+call sub2(y)
+if (.not.allocated(y)) call abort()
+if (.not. same_type_as(y, var_t2)) call abort()
+if (size (y) /= 5) call abort()
+end
+
+! { dg-final { scan-tree-dump-times "__builtin_free" 5 "original" } }
+! { dg-final { scan-tree-dump-times "finally" 0 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/class_array_17.f90 b/gcc/testsuite/gfortran.dg/class_array_17.f90
new file mode 100644
index 00000000000..e5961e11035
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/class_array_17.f90
@@ -0,0 +1,34 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+!
+! PR fortran/57456
+!
+module m
+ implicit none
+ type t
+ integer :: i
+ end type t
+ type, extends(t) :: t2
+ integer :: j
+ end type t2
+end module m
+
+program test
+ use m
+ implicit none
+ integer :: i
+ class(t), save, allocatable :: y(:)
+
+ allocate (t2 :: y(5))
+ select type(y)
+ type is (t2)
+ do i = 1, 5
+ y(i)%i = i
+ y(i)%j = i*10
+ end do
+ end select
+ deallocate(y)
+end
+
+! { dg-final { scan-tree-dump-times "__builtin_malloc \\(40\\);" 1 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/coarray_lib_alloc_1.f90 b/gcc/testsuite/gfortran.dg/coarray_lib_alloc_1.f90
index c0d06a4bd2a..926d531ef7d 100644
--- a/gcc/testsuite/gfortran.dg/coarray_lib_alloc_1.f90
+++ b/gcc/testsuite/gfortran.dg/coarray_lib_alloc_1.f90
@@ -4,6 +4,7 @@
! Allocate/deallocate with libcaf.
!
+ subroutine test()
integer(4), allocatable :: xx[:], yy(:)[:]
integer :: stat
character(len=200) :: errmsg
diff --git a/gcc/testsuite/gfortran.dg/coarray_lib_alloc_2.f90 b/gcc/testsuite/gfortran.dg/coarray_lib_alloc_2.f90
index 3aaff1e8c35..472e0beb719 100644
--- a/gcc/testsuite/gfortran.dg/coarray_lib_alloc_2.f90
+++ b/gcc/testsuite/gfortran.dg/coarray_lib_alloc_2.f90
@@ -4,6 +4,7 @@
! Allocate/deallocate with libcaf.
!
+ subroutine test()
type t
end type t
class(t), allocatable :: xx[:], yy(:)[:]
diff --git a/gcc/testsuite/gfortran.dg/coarray_poly_3.f90 b/gcc/testsuite/gfortran.dg/coarray_poly_3.f90
index 8edd8d3c63e..fd46206ea15 100644
--- a/gcc/testsuite/gfortran.dg/coarray_poly_3.f90
+++ b/gcc/testsuite/gfortran.dg/coarray_poly_3.f90
@@ -25,7 +25,7 @@ end
function func() ! { dg-error "shall not be a coarray or have a coarray component" }
type t
end type t
- class(t), allocatable :: func[*] ! { dg-error ""
+ class(t), allocatable :: func[*]
end
function func2() ! { dg-error "must be dummy, allocatable or pointer" }
@@ -33,7 +33,7 @@ function func2() ! { dg-error "must be dummy, allocatable or pointer" }
integer, allocatable :: caf[:]
end type t
class(t) :: func2a ! { dg-error "CLASS variable 'func2a' at .1. must be dummy, allocatable or pointer" }
- class(t) :: func2 ! {CLASS variable 'func' at (1) must be dummy, allocatable or pointer
+ class(t) :: func2
end
subroutine foo1(x1) ! { dg-error "Coarray variable 'x1' at .1. shall not have codimensions with deferred shape" }
diff --git a/gcc/testsuite/gfortran.dg/default_initialization_5.f90 b/gcc/testsuite/gfortran.dg/default_initialization_5.f90
index b32dae7c6cb..50860e0d064 100644
--- a/gcc/testsuite/gfortran.dg/default_initialization_5.f90
+++ b/gcc/testsuite/gfortran.dg/default_initialization_5.f90
@@ -1,4 +1,4 @@
-! { dg-do run }
+! { dg-do run }
! { dg-options "-fdump-tree-original" }
!
! PR fortran/51435
diff --git a/gcc/testsuite/gfortran.dg/dummy_procedure_5.f90 b/gcc/testsuite/gfortran.dg/dummy_procedure_5.f90
index 5ab4e7cec8e..cb0e7c04d0e 100644
--- a/gcc/testsuite/gfortran.dg/dummy_procedure_5.f90
+++ b/gcc/testsuite/gfortran.dg/dummy_procedure_5.f90
@@ -15,7 +15,7 @@ program main
end type
type(u), external :: ufunc
- call sub(ufunc) ! { dg-error "Type/rank mismatch in function result" }
+ call sub(ufunc) ! { dg-error "Type mismatch in function result" }
contains
diff --git a/gcc/testsuite/gfortran.dg/extends_14.f03 b/gcc/testsuite/gfortran.dg/extends_14.f03
index 876e8c703cf..15e38ff9081 100644
--- a/gcc/testsuite/gfortran.dg/extends_14.f03
+++ b/gcc/testsuite/gfortran.dg/extends_14.f03
@@ -16,12 +16,13 @@ program evolve_aflow
type, extends(state_t) :: astate_t
end type
+ block ! New scoping unit as "a"/"b" are otherwise implicitly SAVEd
type(astate_t) :: a,b
allocate(a%U(1000))
a = b
-
+ end block
end program
! { dg-final { scan-tree-dump-times "__builtin_free" 3 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/finalize_11.f90 b/gcc/testsuite/gfortran.dg/finalize_11.f90
new file mode 100644
index 00000000000..e9bb8147789
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/finalize_11.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-std=f2003" }
+!
+! Copied from finalize_6.f90 - was before rejected as the finalization
+! wrapper uses TS29913 (-std=f2008ts) features.
+!
+
+MODULE final_type
+ IMPLICIT NONE
+
+ TYPE :: mytype
+ INTEGER :: fooarr(42)
+ REAL :: foobar
+ CONTAINS
+ FINAL :: finalize_single
+ END TYPE mytype
+
+CONTAINS
+
+ SUBROUTINE finalize_single (el)
+ IMPLICIT NONE
+ TYPE(mytype) :: el
+ ! Do nothing in this test
+ END SUBROUTINE finalize_single
+
+END MODULE final_type
+
+PROGRAM finalizer
+ IMPLICIT NONE
+ ! Do nothing
+END PROGRAM finalizer
diff --git a/gcc/testsuite/gfortran.dg/finalize_12.f90 b/gcc/testsuite/gfortran.dg/finalize_12.f90
new file mode 100644
index 00000000000..f1508ec8135
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/finalize_12.f90
@@ -0,0 +1,175 @@
+! { dg-do run }
+! { dg-options "-fcoarray=single" }
+!
+! PR fortran/37336
+!
+module m
+ implicit none
+ type t
+ integer :: i
+ contains
+ final :: fini, fini2
+ end type t
+ integer :: global_count1, global_count2
+contains
+ subroutine fini(x)
+ type(t) :: x
+ !print *, 'fini:',x%i
+ if (global_count1 == -1) call abort ()
+ if (x%i /= 42) call abort()
+ x%i = 33
+ global_count1 = global_count1 + 1
+ end subroutine fini
+ subroutine fini2(x)
+ type(t) :: x(:)
+ !print *, 'fini2', x%i
+ if (global_count2 == -1) call abort ()
+ if (size(x) /= 5) call abort()
+ if (any (x%i /= [1,2,3,4,5]) .and. any (x%i /= [6,7,8,9,10])) call abort()
+ x%i = 33
+ global_count2 = global_count2 + 10
+ end subroutine fini2
+end module m
+
+program pp
+ use m
+ implicit none
+ type(t), allocatable :: ya
+ class(t), allocatable :: yc
+ type(t), allocatable :: yaa(:)
+ class(t), allocatable :: yca(:)
+
+ type(t), allocatable :: ca[:]
+ class(t), allocatable :: cc[:]
+ type(t), allocatable :: caa(:)[:]
+ class(t), allocatable :: cca(:)[:]
+
+ global_count1 = -1
+ global_count2 = -1
+ allocate (ya, yc, yaa(5), yca(5))
+ global_count1 = 0
+ global_count2 = 0
+ ya%i = 42
+ yc%i = 42
+ yaa%i = [1,2,3,4,5]
+ yca%i = [1,2,3,4,5]
+
+ call foo(ya, yc, yaa, yca)
+ if (global_count1 /= 2) call abort ()
+ if (global_count2 /= 20) call abort ()
+
+ ! Coarray finalization
+ allocate (ca[*], cc[*], caa(5)[*], cca(5)[*])
+ global_count1 = 0
+ global_count2 = 0
+ ca%i = 42
+ cc%i = 42
+ caa%i = [1,2,3,4,5]
+ cca%i = [1,2,3,4,5]
+ deallocate (ca, cc, caa, cca)
+ if (global_count1 /= 2) call abort ()
+ if (global_count2 /= 20) call abort ()
+ global_count1 = -1
+ global_count2 = -1
+
+ block
+ type(t), allocatable :: za
+ class(t), allocatable :: zc
+ type(t), allocatable :: zaa(:)
+ class(t), allocatable :: zca(:)
+
+ ! Test intent(out) finalization
+ allocate (za, zc, zaa(5), zca(5))
+ global_count1 = 0
+ global_count2 = 0
+ za%i = 42
+ zc%i = 42
+ zaa%i = [1,2,3,4,5]
+ zca%i = [1,2,3,4,5]
+
+ call foo(za, zc, zaa, zca)
+ if (global_count1 /= 2) call abort ()
+ if (global_count2 /= 20) call abort ()
+
+ ! Test intent(out) finalization with optional
+ call foo_opt()
+ call opt()
+
+ ! Test intent(out) finalization with optional
+ allocate (za, zc, zaa(5), zca(5))
+ global_count1 = 0
+ global_count2 = 0
+ za%i = 42
+ zc%i = 42
+ zaa%i = [1,2,3,4,5]
+ zca%i = [1,2,3,4,5]
+
+ call foo_opt(za, zc, zaa, zca)
+ if (global_count1 /= 2) call abort ()
+ if (global_count2 /= 20) call abort ()
+
+ ! Test DEALLOCATE finalization
+ allocate (za, zc, zaa(5), zca(5))
+ global_count1 = 0
+ global_count2 = 0
+ za%i = 42
+ zc%i = 42
+ zaa%i = [1,2,3,4,5]
+ zca%i = [6,7,8,9,10]
+ deallocate (za, zc, zaa, zca)
+ if (global_count1 /= 2) call abort ()
+ if (global_count2 /= 20) call abort ()
+
+ ! Test end-of-scope finalization
+ allocate (za, zc, zaa(5), zca(5))
+ global_count1 = 0
+ global_count2 = 0
+ za%i = 42
+ zc%i = 42
+ zaa%i = [1,2,3,4,5]
+ zca%i = [6,7,8,9,10]
+ end block
+
+ if (global_count1 /= 2) call abort ()
+ if (global_count2 /= 20) call abort ()
+
+ ! Test that no end-of-scope finalization occurs
+ ! for SAVED variable in main
+ allocate (ya, yc, yaa(5), yca(5))
+ global_count1 = -1
+ global_count2 = -1
+
+contains
+
+ subroutine opt(xa, xc, xaa, xca)
+ type(t), allocatable, optional :: xa
+ class(t), allocatable, optional :: xc
+ type(t), allocatable, optional :: xaa(:)
+ class(t), allocatable, optional :: xca(:)
+ call foo_opt(xc, xc, xaa)
+ !call foo_opt(xa, xc, xaa, xca) ! FIXME: Fails (ICE) due to PR 57445
+ end subroutine opt
+ subroutine foo_opt(xa, xc, xaa, xca)
+ type(t), allocatable, intent(out), optional :: xa
+ class(t), allocatable, intent(out), optional :: xc
+ type(t), allocatable, intent(out), optional :: xaa(:)
+ class(t), allocatable, intent(out), optional :: xca(:)
+
+ if (.not. present(xa)) &
+ return
+ if (allocated (xa)) call abort ()
+ if (allocated (xc)) call abort ()
+ if (allocated (xaa)) call abort ()
+ if (allocated (xca)) call abort ()
+ end subroutine foo_opt
+ subroutine foo(xa, xc, xaa, xca)
+ type(t), allocatable, intent(out) :: xa
+ class(t), allocatable, intent(out) :: xc
+ type(t), allocatable, intent(out) :: xaa(:)
+ class(t), allocatable, intent(out) :: xca(:)
+ if (allocated (xa)) call abort ()
+ if (allocated (xc)) call abort ()
+ if (allocated (xaa)) call abort ()
+ if (allocated (xca)) call abort ()
+ end subroutine foo
+end program
diff --git a/gcc/testsuite/gfortran.dg/finalize_13.f90 b/gcc/testsuite/gfortran.dg/finalize_13.f90
new file mode 100644
index 00000000000..78b20acd5d7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/finalize_13.f90
@@ -0,0 +1,161 @@
+! { dg-do run }
+!
+! PR fortran/37336
+!
+module m
+ implicit none
+ type t
+ integer :: i
+ contains
+ final :: fini3, fini2, fini_elm
+ end type t
+
+ type, extends(t) :: t2
+ integer :: j
+ contains
+ final :: f2ini2, f2ini_elm
+ end type t2
+
+ logical :: elem_call
+ logical :: rank2_call
+ logical :: rank3_call
+ integer :: cnt, cnt2
+ integer :: fini_call
+
+contains
+ subroutine fini2 (x)
+ type(t), intent(in), contiguous :: x(:,:)
+ if (.not. rank2_call) call abort ()
+ if (size(x,1) /= 2 .or. size(x,2) /= 3) call abort()
+ !print *, 'fini2:', x%i
+ if (any (x%i /= reshape([11, 12, 21, 22, 31, 32], [2,3]))) call abort()
+ fini_call = fini_call + 1
+ end subroutine
+
+ subroutine fini3 (x)
+ type(t), intent(in) :: x(2,2,*)
+ integer :: i,j,k
+ if (.not. elem_call) call abort ()
+ if (.not. rank3_call) call abort ()
+ if (cnt2 /= 9) call abort()
+ if (cnt /= 1) call abort()
+ do i = 1, 2
+ do j = 1, 2
+ do k = 1, 2
+ !print *, k,j,i,x(k,j,i)%i
+ if (x(k,j,i)%i /= k+10*j+100*i) call abort()
+ end do
+ end do
+ end do
+ fini_call = fini_call + 1
+ end subroutine
+
+ impure elemental subroutine fini_elm (x)
+ type(t), intent(in) :: x
+ if (.not. elem_call) call abort ()
+ if (rank3_call) call abort ()
+ if (cnt2 /= 6) call abort()
+ if (cnt /= x%i) call abort()
+ !print *, 'fini_elm:', cnt, x%i
+ fini_call = fini_call + 1
+ cnt = cnt + 1
+ end subroutine
+
+ subroutine f2ini2 (x)
+ type(t2), intent(in), target :: x(:,:)
+ if (.not. rank2_call) call abort ()
+ if (size(x,1) /= 2 .or. size(x,2) /= 3) call abort()
+ !print *, 'f2ini2:', x%i
+ !print *, 'f2ini2:', x%j
+ if (any (x%i /= reshape([11, 12, 21, 22, 31, 32], [2,3]))) call abort()
+ if (any (x%j /= 100*reshape([11, 12, 21, 22, 31, 32], [2,3]))) call abort()
+ fini_call = fini_call + 1
+ end subroutine
+
+ impure elemental subroutine f2ini_elm (x)
+ type(t2), intent(in) :: x
+ integer, parameter :: exprected(*) &
+ = [111, 112, 121, 122, 211, 212, 221, 222]
+
+ if (.not. elem_call) call abort ()
+ !print *, 'f2ini_elm:', cnt2, x%i, x%j
+ if (rank3_call) then
+ if (x%i /= exprected(cnt2)) call abort ()
+ if (x%j /= 1000*exprected(cnt2)) call abort ()
+ else
+ if (cnt2 /= x%i .or. cnt2*10 /= x%j) call abort()
+ end if
+ cnt2 = cnt2 + 1
+ fini_call = fini_call + 1
+ end subroutine
+end module m
+
+
+program test
+ use m
+ implicit none
+ class(t), save, allocatable :: y(:), z(:,:), zz(:,:,:)
+ target :: z, zz
+ integer :: i,j,k
+
+ elem_call = .false.
+ rank2_call = .false.
+ rank3_call = .false.
+ allocate (t2 :: y(5))
+ select type (y)
+ type is (t2)
+ do i = 1, 5
+ y(i)%i = i
+ y(i)%j = i*10
+ end do
+ end select
+ cnt = 1
+ cnt2 = 1
+ fini_call = 0
+ elem_call = .true.
+ deallocate (y)
+ if (fini_call /= 10) call abort ()
+
+ elem_call = .false.
+ rank2_call = .false.
+ rank3_call = .false.
+ allocate (t2 :: z(2,3))
+ select type (z)
+ type is (t2)
+ do i = 1, 3
+ do j = 1, 2
+ z(j,i)%i = j+10*i
+ z(j,i)%j = (j+10*i)*100
+ end do
+ end do
+ end select
+ cnt = 1
+ cnt2 = 1
+ fini_call = 0
+ rank2_call = .true.
+ deallocate (z)
+ if (fini_call /= 2) call abort ()
+
+ elem_call = .false.
+ rank2_call = .false.
+ rank3_call = .false.
+ allocate (t2 :: zz(2,2,2))
+ select type (zz)
+ type is (t2)
+ do i = 1, 2
+ do j = 1, 2
+ do k = 1, 2
+ zz(k,j,i)%i = k+10*j+100*i
+ zz(k,j,i)%j = (k+10*j+100*i)*1000
+ end do
+ end do
+ end do
+ end select
+ cnt = 1
+ cnt2 = 1
+ fini_call = 0
+ rank3_call = .true.
+ elem_call = .true.
+ deallocate (zz)
+ if (fini_call /= 2*2*2+1) call abort ()
+end program test
diff --git a/gcc/testsuite/gfortran.dg/finalize_14.f90 b/gcc/testsuite/gfortran.dg/finalize_14.f90
new file mode 100644
index 00000000000..edec8841ee6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/finalize_14.f90
@@ -0,0 +1,220 @@
+! { dg-do compile }
+!
+! PR fortran/37336
+!
+! Started to fail when finalization was added.
+!
+! Contributed by Ian Chivers in PR fortran/44465
+!
+module shape_module
+
+ type shape_type
+ integer :: x_=0
+ integer :: y_=0
+ contains
+ procedure , pass(this) :: getx
+ procedure , pass(this) :: gety
+ procedure , pass(this) :: setx
+ procedure , pass(this) :: sety
+ procedure , pass(this) :: moveto
+ procedure , pass(this) :: draw
+ end type shape_type
+
+interface assignment(=)
+ module procedure generic_shape_assign
+end interface
+
+contains
+
+ integer function getx(this)
+ implicit none
+ class (shape_type) , intent(in) :: this
+ getx=this%x_
+ end function getx
+
+ integer function gety(this)
+ implicit none
+ class (shape_type) , intent(in) :: this
+ gety=this%y_
+ end function gety
+
+ subroutine setx(this,x)
+ implicit none
+ class (shape_type), intent(inout) :: this
+ integer , intent(in) :: x
+ this%x_=x
+ end subroutine setx
+
+ subroutine sety(this,y)
+ implicit none
+ class (shape_type), intent(inout) :: this
+ integer , intent(in) :: y
+ this%y_=y
+ end subroutine sety
+
+ subroutine moveto(this,newx,newy)
+ implicit none
+ class (shape_type), intent(inout) :: this
+ integer , intent(in) :: newx
+ integer , intent(in) :: newy
+ this%x_=newx
+ this%y_=newy
+ end subroutine moveto
+
+ subroutine draw(this)
+ implicit none
+ class (shape_type), intent(in) :: this
+ print *,' x = ' , this%x_
+ print *,' y = ' , this%y_
+ end subroutine draw
+
+ subroutine generic_shape_assign(lhs,rhs)
+ implicit none
+ class (shape_type) , intent(out) , allocatable :: lhs
+ class (shape_type) , intent(in) :: rhs
+ print *,' In generic_shape_assign'
+ if ( allocated(lhs) ) then
+ deallocate(lhs)
+ end if
+ allocate(lhs,source=rhs)
+ end subroutine generic_shape_assign
+
+end module shape_module
+
+! Circle_p.f90
+
+module circle_module
+
+use shape_module
+
+type , extends(shape_type) :: circle_type
+
+ integer :: radius_
+
+ contains
+
+ procedure , pass(this) :: getradius
+ procedure , pass(this) :: setradius
+ procedure , pass(this) :: draw => draw_circle
+
+end type circle_type
+
+ contains
+
+ integer function getradius(this)
+ implicit none
+ class (circle_type) , intent(in) :: this
+ getradius=this%radius_
+ end function getradius
+
+ subroutine setradius(this,radius)
+ implicit none
+ class (circle_type) , intent(inout) :: this
+ integer , intent(in) :: radius
+ this%radius_=radius
+ end subroutine setradius
+
+ subroutine draw_circle(this)
+ implicit none
+ class (circle_type), intent(in) :: this
+ print *,' x = ' , this%x_
+ print *,' y = ' , this%y_
+ print *,' radius = ' , this%radius_
+ end subroutine draw_circle
+
+end module circle_module
+
+
+! Rectangle_p.f90
+
+module rectangle_module
+
+use shape_module
+
+type , extends(shape_type) :: rectangle_type
+
+ integer :: width_
+ integer :: height_
+
+ contains
+
+ procedure , pass(this) :: getwidth
+ procedure , pass(this) :: setwidth
+ procedure , pass(this) :: getheight
+ procedure , pass(this) :: setheight
+ procedure , pass(this) :: draw => draw_rectangle
+
+end type rectangle_type
+
+ contains
+
+ integer function getwidth(this)
+ implicit none
+ class (rectangle_type) , intent(in) :: this
+ getwidth=this%width_
+ end function getwidth
+
+ subroutine setwidth(this,width)
+ implicit none
+ class (rectangle_type) , intent(inout) :: this
+ integer , intent(in) :: width
+ this%width_=width
+ end subroutine setwidth
+
+ integer function getheight(this)
+ implicit none
+ class (rectangle_type) , intent(in) :: this
+ getheight=this%height_
+ end function getheight
+
+ subroutine setheight(this,height)
+ implicit none
+ class (rectangle_type) , intent(inout) :: this
+ integer , intent(in) :: height
+ this%height_=height
+ end subroutine setheight
+
+ subroutine draw_rectangle(this)
+ implicit none
+ class (rectangle_type), intent(in) :: this
+ print *,' x = ' , this%x_
+ print *,' y = ' , this%y_
+ print *,' width = ' , this%width_
+ print *,' height = ' , this%height_
+
+ end subroutine draw_rectangle
+
+end module rectangle_module
+
+
+
+program polymorphic
+
+use shape_module
+use circle_module
+use rectangle_module
+
+implicit none
+
+type shape_w
+ class (shape_type) , allocatable :: shape_v
+end type shape_w
+
+type (shape_w) , dimension(3) :: p
+
+ print *,' shape '
+
+ p(1)%shape_v=shape_type(10,20)
+ call p(1)%shape_v%draw()
+
+ print *,' circle '
+
+ p(2)%shape_v=circle_type(100,200,300)
+ call p(2)%shape_v%draw()
+
+ print *,' rectangle '
+
+ p(3)%shape_v=rectangle_type(1000,2000,3000,4000)
+ call p(3)%shape_v%draw()
+
+end program polymorphic
diff --git a/gcc/testsuite/gfortran.dg/finalize_4.f03 b/gcc/testsuite/gfortran.dg/finalize_4.f03
index 11e094f0d8f..b4c08f236da 100644
--- a/gcc/testsuite/gfortran.dg/finalize_4.f03
+++ b/gcc/testsuite/gfortran.dg/finalize_4.f03
@@ -48,6 +48,3 @@ PROGRAM finalizer
DEALLOCATE(mat)
END PROGRAM finalizer
-
-! TODO: Remove this once finalization is implemented.
-! { dg-excess-errors "not yet implemented" }
diff --git a/gcc/testsuite/gfortran.dg/finalize_5.f03 b/gcc/testsuite/gfortran.dg/finalize_5.f03
index b9ec3768fe4..fb8153140b7 100644
--- a/gcc/testsuite/gfortran.dg/finalize_5.f03
+++ b/gcc/testsuite/gfortran.dg/finalize_5.f03
@@ -107,6 +107,3 @@ PROGRAM finalizer
IMPLICIT NONE
! Nothing here, errors above
END PROGRAM finalizer
-
-! TODO: Remove this once finalization is implemented.
-! { dg-excess-errors "not yet implemented" }
diff --git a/gcc/testsuite/gfortran.dg/finalize_6.f90 b/gcc/testsuite/gfortran.dg/finalize_6.f90
index 82d662f8c8d..d155c7bd0a5 100644
--- a/gcc/testsuite/gfortran.dg/finalize_6.f90
+++ b/gcc/testsuite/gfortran.dg/finalize_6.f90
@@ -10,9 +10,9 @@ MODULE final_type
TYPE :: mytype
INTEGER :: fooarr(42)
REAL :: foobar
- CONTAINS ! { dg-error "Fortran 2003" }
- FINAL :: finalize_single ! { dg-error "Fortran 2003" }
- END TYPE mytype
+ CONTAINS ! { dg-error "Fortran 2003: CONTAINS block in derived type definition" }
+ FINAL :: finalize_single ! { dg-error "Fortran 2003: FINAL procedure declaration|FINAL procedure 'finalize_single' at .1. is not a SUBROUTINE" }
+ END TYPE mytype ! { dg-error "Fortran 2008: Derived type definition at .1. with empty CONTAINS section" }
CONTAINS
@@ -28,6 +28,3 @@ PROGRAM finalizer
IMPLICIT NONE
! Do nothing
END PROGRAM finalizer
-
-! TODO: Remove this once finalization is implemented.
-! { dg-excess-errors "not yet implemented" }
diff --git a/gcc/testsuite/gfortran.dg/finalize_7.f03 b/gcc/testsuite/gfortran.dg/finalize_7.f03
index 6ca4f55db7a..5807ed50e15 100644
--- a/gcc/testsuite/gfortran.dg/finalize_7.f03
+++ b/gcc/testsuite/gfortran.dg/finalize_7.f03
@@ -52,6 +52,3 @@ PROGRAM finalizer
IMPLICIT NONE
! Nothing here
END PROGRAM finalizer
-
-! TODO: Remove this once finalization is implemented.
-! { dg-excess-errors "not yet implemented" }
diff --git a/gcc/testsuite/gfortran.dg/g77/f77-edit-s-out.f b/gcc/testsuite/gfortran.dg/g77/f77-edit-s-out.f
index 89a8df2caff..7a22ae6b814 100644
--- a/gcc/testsuite/gfortran.dg/g77/f77-edit-s-out.f
+++ b/gcc/testsuite/gfortran.dg/g77/f77-edit-s-out.f
@@ -4,7 +4,7 @@ C
C Origin: David Billinghurst <David.Billinghurst@riotinto.com>
C
C { dg-do run }
-C ( dg-output "^" }
+C { dg-output "^" }
10 format(SP,I3,1X,SS,I3)
20 format(SP,I3,1X,SS,I3,SP,I3)
30 format(SP,I3,1X,SS,I3,S,I3)
diff --git a/gcc/testsuite/gfortran.dg/g77/f77-edit-t-out.f b/gcc/testsuite/gfortran.dg/g77/f77-edit-t-out.f
index 8e411888f2b..b47b7477603 100644
--- a/gcc/testsuite/gfortran.dg/g77/f77-edit-t-out.f
+++ b/gcc/testsuite/gfortran.dg/g77/f77-edit-t-out.f
@@ -4,9 +4,9 @@ C
C Origin: David Billinghurst <David.Billinghurst@riotinto.com>
C
C { dg-do run }
-C ( dg-output "^" }
+C { dg-output "^" }
write(*,'(I4,T8,I1)') 1234,8 ! { dg-output "1234 8(\n|\r\n|\r)" }
write(*,'(I4,TR3,I1)') 1234,8 ! { dg-output "1234 8(\n|\r\n|\r)" }
write(*,'(I4,5X,TL2,I1)') 1234,8 ! { dg-output "1234 8(\n|\r\n|\r)" }
-C ( dg-output "\$" }
+C { dg-output "\$" }
end
diff --git a/gcc/testsuite/gfortran.dg/g77/f77-edit-x-out.f b/gcc/testsuite/gfortran.dg/g77/f77-edit-x-out.f
index 9d196331dd1..13a9d7a93e8 100644
--- a/gcc/testsuite/gfortran.dg/g77/f77-edit-x-out.f
+++ b/gcc/testsuite/gfortran.dg/g77/f77-edit-x-out.f
@@ -4,7 +4,7 @@ C
C Origin: David Billinghurst <David.Billinghurst@riotinto.com>
C
C { dg-do run }
-C ( dg-output "^" }
+C { dg-output "^" }
write(*,'(I1,1X,I1,2X,I1)') 1,2,3 ! { dg-output "1 2 3(\n|\r\n|\r)" }
C Section 13.5.3 explains why there are no trailing blanks
write(*,'(I1,1X,I1,2X,I1,3X)') 1,2,3 ! { dg-output "1 2 3(\n|\r\n|\r)" }
diff --git a/gcc/testsuite/gfortran.dg/init_flag_11.f90 b/gcc/testsuite/gfortran.dg/init_flag_11.f90
index 7a5239fc457..d881c2c9ce8 100644
--- a/gcc/testsuite/gfortran.dg/init_flag_11.f90
+++ b/gcc/testsuite/gfortran.dg/init_flag_11.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
-! { dg-flags "-finit-local-zero -fno-automatic"
+! { dg-options "-finit-local-zero -fno-automatic" }
!
! PR fortran/53818
!
diff --git a/gcc/testsuite/gfortran.dg/interface_26.f90 b/gcc/testsuite/gfortran.dg/interface_26.f90
index 330c434d2a3..6f8325faf32 100644
--- a/gcc/testsuite/gfortran.dg/interface_26.f90
+++ b/gcc/testsuite/gfortran.dg/interface_26.f90
@@ -23,7 +23,7 @@ PROGRAM test
USE funcs
INTEGER :: rs
INTEGER, PARAMETER :: a = 2, b = 1
- rs = recSum( a, b, test1, sumInts ) ! { dg-error "Type/rank mismatch in argument" }
+ rs = recSum( a, b, test1, sumInts ) ! { dg-error "Type mismatch in argument" }
write(*,*) "Results", rs
CONTAINS
RECURSIVE INTEGER FUNCTION recSum( a,b,UserFunction,UserOp ) RESULT( res )
@@ -37,7 +37,7 @@ CONTAINS
END INTERFACE
INTEGER, EXTERNAL :: UserOp
- res = UserFunction( a,b, UserOp ) ! { dg-error "Type/rank mismatch in function result" }
+ res = UserFunction( a,b, UserOp ) ! { dg-error "Type mismatch in function result" }
if( res .lt. 10 ) then
res = recSum( a, res, UserFunction, UserOp )
diff --git a/gcc/testsuite/gfortran.dg/io_real_boz_3.f90 b/gcc/testsuite/gfortran.dg/io_real_boz_3.f90
index 8043167cd7f..abf02ba168d 100644
--- a/gcc/testsuite/gfortran.dg/io_real_boz_3.f90
+++ b/gcc/testsuite/gfortran.dg/io_real_boz_3.f90
@@ -1,4 +1,4 @@
-! { dg-do run }
+! { dg-do run }
! { dg-options "-std=f2008" }
! { dg-require-effective-target fortran_real_16 }
!
diff --git a/gcc/testsuite/gfortran.dg/io_real_boz_4.f90 b/gcc/testsuite/gfortran.dg/io_real_boz_4.f90
index f2c2aca4bd6..044f755e23e 100644
--- a/gcc/testsuite/gfortran.dg/io_real_boz_4.f90
+++ b/gcc/testsuite/gfortran.dg/io_real_boz_4.f90
@@ -1,4 +1,4 @@
-! { dg-do run }
+! { dg-do run }
! { dg-options "-std=f2003" }
! { dg-require-effective-target fortran_real_16 }
!
diff --git a/gcc/testsuite/gfortran.dg/io_real_boz_5.f90 b/gcc/testsuite/gfortran.dg/io_real_boz_5.f90
index db8e6e7557c..a908dd7bbc0 100644
--- a/gcc/testsuite/gfortran.dg/io_real_boz_5.f90
+++ b/gcc/testsuite/gfortran.dg/io_real_boz_5.f90
@@ -1,4 +1,4 @@
-! { dg-do run }
+! { dg-do run }
! { dg-options "-std=f2008" }
! { dg-require-effective-target fortran_real_16 }
!
diff --git a/gcc/testsuite/gfortran.dg/move_alloc_4.f90 b/gcc/testsuite/gfortran.dg/move_alloc_4.f90
index 4dc493f097f..b23ef70bb93 100644
--- a/gcc/testsuite/gfortran.dg/move_alloc_4.f90
+++ b/gcc/testsuite/gfortran.dg/move_alloc_4.f90
@@ -10,13 +10,14 @@ program testmv3
integer, allocatable :: ia(:), ja(:)
end type
+ block ! For auto-dealloc, as PROGRAM implies SAVE
type(bar), allocatable :: sm,sm2
allocate(sm)
allocate(sm%ia(10),sm%ja(10))
call move_alloc(sm2,sm)
-
+ end block
end program testmv3
! { dg-final { scan-tree-dump-times "__builtin_free" 9 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/namelist_print_1.f b/gcc/testsuite/gfortran.dg/namelist_print_1.f
index 2e5de8305b8..d97d1c9e9a4 100644
--- a/gcc/testsuite/gfortran.dg/namelist_print_1.f
+++ b/gcc/testsuite/gfortran.dg/namelist_print_1.f
@@ -8,6 +8,6 @@
real x
namelist /mynml/ x
x = 1
-! ( dg-output "^" }
+! { dg-output "^" }
print mynml ! { dg-output "&MYNML(\n|\r\n|\r) X= 1.00000000 ,(\n|\r\n|\r) /(\n|\r\n|\r)" }
end
diff --git a/gcc/testsuite/gfortran.dg/power_6.f90 b/gcc/testsuite/gfortran.dg/power_6.f90
new file mode 100644
index 00000000000..65d1bd02684
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/power_6.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! { dg-options "-O1 -fdump-tree-optimized" }
+!
+! PR middle-end/57073
+! See also PR 57073
+!
+real function f(k)
+ integer, value :: k
+ f = (-1.0)**k
+end
+
+! { dg-final { scan-tree-dump-not "__builtin_powif" "optimized" } }
+! { dg-final { scan-tree-dump "powi_cond_\[0-9\] = k_\[0-9\]\\(D\\) & 1;" "optimized" } }
+! { dg-final { scan-tree-dump "powi_\[0-9\] = powi_cond_\[0-9\] \\? -1.0e\\+0 : 1.0e\\+0;" "optimized" } }
+! { dg-final { cleanup-tree-dump "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_11.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_11.f90
index e00594ab7a4..bee73f45213 100644
--- a/gcc/testsuite/gfortran.dg/proc_ptr_11.f90
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_11.f90
@@ -40,11 +40,11 @@ program bsp
p2 => p1
p1 => p2
- p1 => abs ! { dg-error "Type/rank mismatch in function result" }
- p2 => abs ! { dg-error "Type/rank mismatch in function result" }
+ p1 => abs ! { dg-error "Type mismatch in function result" }
+ p2 => abs ! { dg-error "Type mismatch in function result" }
p3 => dsin
- p3 => sin ! { dg-error "Type/rank mismatch in function result" }
+ p3 => sin ! { dg-error "Type mismatch in function result" }
contains
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_15.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_15.f90
index f1d3d184c96..b4f1b2f6ee8 100644
--- a/gcc/testsuite/gfortran.dg/proc_ptr_15.f90
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_15.f90
@@ -19,10 +19,10 @@ p4 => p3
p6 => p1
! invalid
-p1 => iabs ! { dg-error "Type/rank mismatch in function result" }
-p1 => p2 ! { dg-error "Type/rank mismatch in function result" }
-p1 => p5 ! { dg-error "Type/rank mismatch in function result" }
-p6 => iabs ! { dg-error "Type/rank mismatch in function result" }
+p1 => iabs ! { dg-error "Type mismatch in function result" }
+p1 => p2 ! { dg-error "Type mismatch in function result" }
+p1 => p5 ! { dg-error "Type mismatch in function result" }
+p6 => iabs ! { dg-error "Type mismatch in function result" }
p4 => p2 ! { dg-error "is not a subroutine" }
contains
@@ -32,4 +32,3 @@ contains
end subroutine
end
-
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_comp_20.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_comp_20.f90
index 3cad7dfa66b..29a2ef9f0d4 100644
--- a/gcc/testsuite/gfortran.dg/proc_ptr_comp_20.f90
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_comp_20.f90
@@ -27,11 +27,11 @@ type(t2) :: o2
procedure(logical),pointer :: pp1
procedure(complex),pointer :: pp2
-pp1 => pp2 ! { dg-error "Type/rank mismatch" }
-pp2 => o2%ppc ! { dg-error "Type/rank mismatch" }
+pp1 => pp2 ! { dg-error "Type mismatch in function result" }
+pp2 => o2%ppc ! { dg-error "Type mismatch in function result" }
-o1%ppc => pp1 ! { dg-error "Type/rank mismatch" }
-o1%ppc => o2%ppc ! { dg-error "Type/rank mismatch" }
+o1%ppc => pp1 ! { dg-error "Type mismatch in function result" }
+o1%ppc => o2%ppc ! { dg-error "Type mismatch in function result" }
contains
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_comp_33.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_comp_33.f90
index b6a31fe3a0b..55a768017fa 100644
--- a/gcc/testsuite/gfortran.dg/proc_ptr_comp_33.f90
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_comp_33.f90
@@ -11,7 +11,7 @@ module m
type :: rectangle
real :: width, height
- procedure(get_area_ai), pointer :: get_area => get_my_area ! { dg-error "Type/rank mismatch" }
+ procedure(get_area_ai), pointer :: get_area => get_my_area ! { dg-error "Type mismatch in argument" }
end type rectangle
abstract interface
@@ -51,7 +51,7 @@ program p
type(rectangle) :: rect
rect = rectangle (1.0, 2.0, get1)
- rect = rectangle (3.0, 4.0, get2) ! { dg-error "Type/rank mismatch" }
+ rect = rectangle (3.0, 4.0, get2) ! { dg-error "Type mismatch in argument" }
contains
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_result_5.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_result_5.f90
index b021ca7c76e..121fd4d87f9 100644
--- a/gcc/testsuite/gfortran.dg/proc_ptr_result_5.f90
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_result_5.f90
@@ -6,7 +6,7 @@
program test
procedure(real), pointer :: p
- p => f() ! { dg-error "Type/rank mismatch in function result" }
+ p => f() ! { dg-error "Type mismatch in function result" }
contains
function f()
pointer :: f
diff --git a/gcc/testsuite/gfortran.dg/read_x_eor.f90 b/gcc/testsuite/gfortran.dg/read_x_eor.f90
index 064835a8b28..a06e6df1453 100644
--- a/gcc/testsuite/gfortran.dg/read_x_eor.f90
+++ b/gcc/testsuite/gfortran.dg/read_x_eor.f90
@@ -1,5 +1,5 @@
! { dg-do run }
-! ( dg-output "^" }
+! { dg-output "^" }
!
! Test fix for pr24785 - EOR used to scrub the 2X.
! Reduced from PR example submitted by Harald Anlauf <anlauf@gmx.de>
diff --git a/gcc/testsuite/gfortran.dg/repeat_1.f90 b/gcc/testsuite/gfortran.dg/repeat_1.f90
index 7a1d6f9294c..1ac105c2e3c 100644
--- a/gcc/testsuite/gfortran.dg/repeat_1.f90
+++ b/gcc/testsuite/gfortran.dg/repeat_1.f90
@@ -17,4 +17,4 @@ contains
f = x
end function f
end
-! { dg-output "Fortran runtime error: Argument NCOPIES of REPEAT intrinsic is negative .* line 6)"
+! { dg-output "Fortran runtime error: Argument NCOPIES of REPEAT intrinsic is negative \\(its value is -1\\)" }
diff --git a/gcc/testsuite/gfortran.dg/spread_bounds_1.f90 b/gcc/testsuite/gfortran.dg/spread_bounds_1.f90
index 7e5bc651ff5..53e08b1c657 100644
--- a/gcc/testsuite/gfortran.dg/spread_bounds_1.f90
+++ b/gcc/testsuite/gfortran.dg/spread_bounds_1.f90
@@ -8,5 +8,5 @@ program main
times = 2
target = spread(source,2,times)
end program main
-! { dg-output "Fortran runtime error: Incorrect extent in return value of SPREAD intrinsic in dimension 2: is 3, should be 2"
+! { dg-output "Fortran runtime error: Incorrect extent in return value of SPREAD intrinsic in dimension 2: is 3, should be 2" }
diff --git a/gcc/testsuite/gfortran.dg/stfunc_8.f90 b/gcc/testsuite/gfortran.dg/stfunc_8.f90
new file mode 100644
index 00000000000..f13cacaeb8f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/stfunc_8.f90
@@ -0,0 +1,9 @@
+! { dg-do compile }
+! { dg-options "" }
+!
+! PR fortran/50405
+!
+! Submitted by zeccav@gmail.com
+!
+ f(f) = 0 ! { dg-error "Self-referential argument" }
+ end
diff --git a/gcc/testsuite/gfortran.dg/string_length_2.f90 b/gcc/testsuite/gfortran.dg/string_length_2.f90
index 63cea9e1dab..8ea76bfe3bb 100644
--- a/gcc/testsuite/gfortran.dg/string_length_2.f90
+++ b/gcc/testsuite/gfortran.dg/string_length_2.f90
@@ -1,4 +1,4 @@
-! { dg-run }
+! { dg-do run }
! { dg-options "-fdump-tree-original" }
! Test that all string length calculations are
! optimized away.
diff --git a/gcc/testsuite/gfortran.dg/transpose_2.f90 b/gcc/testsuite/gfortran.dg/transpose_2.f90
index 4ab3bc4bb1a..e509d3686bd 100644
--- a/gcc/testsuite/gfortran.dg/transpose_2.f90
+++ b/gcc/testsuite/gfortran.dg/transpose_2.f90
@@ -15,5 +15,4 @@ program main
b = 2.1
b = transpose(a)
end program main
-! { dg-output "Fortran runtime error: Array bound mismatch for dimension 1 of
-! array 'b' (3/2)" }
+! { dg-output "Fortran runtime error: Array bound mismatch for dimension 1 of array 'b' \\(3/2\\)" }
diff --git a/gcc/testsuite/gfortran.dg/typebound_override_1.f90 b/gcc/testsuite/gfortran.dg/typebound_override_1.f90
index 96f90256342..7eb685615f4 100644
--- a/gcc/testsuite/gfortran.dg/typebound_override_1.f90
+++ b/gcc/testsuite/gfortran.dg/typebound_override_1.f90
@@ -20,7 +20,7 @@ module m
type, extends(t1) :: t2
contains
procedure, nopass :: a => a2 ! { dg-error "Character length mismatch in function result" }
- procedure, nopass :: b => b2 ! { dg-error "Type/rank mismatch in function result" }
+ procedure, nopass :: b => b2 ! { dg-error "Rank mismatch in function result" }
procedure, nopass :: c => c2 ! FIXME: dg-warning "Possible character length mismatch"
procedure, nopass :: d => d2 ! valid, check for commutativity (+,*)
procedure, nopass :: e => e2 ! { dg-error "Character length mismatch in function result" }
diff --git a/gcc/testsuite/gfortran.dg/typebound_override_4.f90 b/gcc/testsuite/gfortran.dg/typebound_override_4.f90
new file mode 100644
index 00000000000..95131dea3b8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/typebound_override_4.f90
@@ -0,0 +1,34 @@
+! { dg-do compile }
+!
+! PR 57217: [4.7/4.8/4.9 Regression][OOP] Accepts invalid TBP overriding - lacking arguments check
+!
+! Contributed by Salvatore Filippone <filippone.salvatore@gmail.com>
+
+module base_mod
+ implicit none
+ type base_type
+ contains
+ procedure, pass(map) :: clone => base_clone
+ end type
+contains
+ subroutine base_clone(map,mapout)
+ class(base_type) :: map
+ class(base_type) :: mapout
+ end subroutine
+end module
+
+module r_mod
+ use base_mod
+ implicit none
+ type, extends(base_type) :: r_type
+ contains
+ procedure, pass(map) :: clone => r_clone ! { dg-error "Type mismatch in argument" }
+ end type
+contains
+ subroutine r_clone(map,mapout)
+ class(r_type) :: map
+ class(r_type) :: mapout
+ end subroutine
+end module
+
+! { dg-final { cleanup-modules "base_mod r_mod" } }
diff --git a/gcc/testsuite/gfortran.dg/typebound_override_5.f90 b/gcc/testsuite/gfortran.dg/typebound_override_5.f90
new file mode 100644
index 00000000000..565dd48d4fd
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/typebound_override_5.f90
@@ -0,0 +1,40 @@
+! { dg-do compile }
+!
+! PR 54190: TYPE(*)/assumed-rank: Type/rank check too relaxed for dummy procedure
+! PR 57217: [4.7/4.8/4.9 Regression][OOP] Accepts invalid TBP overriding - lacking arguments check
+!
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+
+module base_mod
+ implicit none
+ type base_type
+ integer :: kind
+ contains
+ procedure, pass(map) :: clone => base_clone
+ end type
+contains
+ subroutine base_clone(map,mapout,info)
+ class(base_type), intent(inout) :: map
+ class(base_type), intent(inout) :: mapout
+ integer :: info
+ end subroutine
+end module
+
+module r_mod
+ use base_mod
+ implicit none
+ type, extends(base_type) :: r_type
+ real :: dat
+ contains
+ procedure, pass(map) :: clone => r_clone ! { dg-error "Type mismatch in argument" }
+ end type
+contains
+ subroutine r_clone(map,mapout,info)
+ class(r_type), intent(inout) :: map
+!gcc$ attributes no_arg_check :: mapout
+ integer, intent(inout) :: mapout
+ integer :: info
+ end subroutine
+end module
+
+! { dg-final { cleanup-modules "base_mod r_mod" } }
diff --git a/gcc/testsuite/gfortran.dg/typebound_override_6.f90 b/gcc/testsuite/gfortran.dg/typebound_override_6.f90
new file mode 100644
index 00000000000..45720fd610f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/typebound_override_6.f90
@@ -0,0 +1,39 @@
+! { dg-do compile }
+!
+! PR 54190: TYPE(*)/assumed-rank: Type/rank check too relaxed for dummy procedure
+! PR 57217: [4.7/4.8/4.9 Regression][OOP] Accepts invalid TBP overriding - lacking arguments check
+!
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+
+module base_mod
+ implicit none
+ type base_type
+ integer :: kind
+ contains
+ procedure, pass(map) :: clone => base_clone
+ end type
+contains
+ subroutine base_clone(map,mapout,info)
+ class(base_type), intent(inout) :: map
+ class(base_type), intent(inout) :: mapout
+ integer :: info
+ end subroutine
+end module
+
+module r_mod
+ use base_mod
+ implicit none
+ type, extends(base_type) :: r_type
+ real :: dat
+ contains
+ procedure, pass(map) :: clone => r_clone ! { dg-error "Rank mismatch in argument" }
+ end type
+contains
+ subroutine r_clone(map,mapout,info)
+ class(r_type), intent(inout) :: map
+ class(base_type), intent(inout) :: mapout(..)
+ integer :: info
+ end subroutine
+end module
+
+! { dg-final { cleanup-modules "base_mod r_mod" } }
diff --git a/gcc/testsuite/gfortran.dg/typebound_override_7.f90 b/gcc/testsuite/gfortran.dg/typebound_override_7.f90
new file mode 100644
index 00000000000..0c7c48ad566
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/typebound_override_7.f90
@@ -0,0 +1,39 @@
+! { dg-do compile }
+!
+! PR 54190: TYPE(*)/assumed-rank: Type/rank check too relaxed for dummy procedure
+! PR 57217: [4.7/4.8/4.9 Regression][OOP] Accepts invalid TBP overriding - lacking arguments check
+!
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+
+module base_mod
+ implicit none
+ type base_type
+ integer :: kind
+ contains
+ procedure, pass(map) :: clone => base_clone
+ end type
+contains
+ subroutine base_clone(map,mapout,info)
+ class(base_type), intent(inout) :: map
+ class(base_type), intent(inout) :: mapout
+ integer :: info
+ end subroutine
+end module
+
+module r_mod
+ use base_mod
+ implicit none
+ type, extends(base_type) :: r_type
+ real :: dat
+ contains
+ procedure, pass(map) :: clone => r_clone ! { dg-error "Type mismatch in argument" }
+ end type
+contains
+ subroutine r_clone(map,mapout,info)
+ class(r_type), intent(inout) :: map
+ type(*), intent(inout) :: mapout
+ integer :: info
+ end subroutine
+end module
+
+! { dg-final { cleanup-modules "base_mod r_mod" } }
diff --git a/gcc/testsuite/gfortran.dg/typebound_proc_27.f03 b/gcc/testsuite/gfortran.dg/typebound_proc_27.f03
index 28c44dff120..ce845a03b06 100644
--- a/gcc/testsuite/gfortran.dg/typebound_proc_27.f03
+++ b/gcc/testsuite/gfortran.dg/typebound_proc_27.f03
@@ -33,6 +33,7 @@ program prog
use m
+ block ! Start new scoping unit as PROGRAM implies SAVE
type(tx) :: this
type(tx), target :: that
type(tx), pointer :: p
@@ -64,6 +65,7 @@ program prog
!print *,this%i
if(any (this%i /= [8, 9])) call abort()
+ end block
end program prog
!
diff --git a/gcc/testsuite/gfortran.dg/typebound_proc_6.f03 b/gcc/testsuite/gfortran.dg/typebound_proc_6.f03
index 3a32cbc96a2..1e1d871c39f 100644
--- a/gcc/testsuite/gfortran.dg/typebound_proc_6.f03
+++ b/gcc/testsuite/gfortran.dg/typebound_proc_6.f03
@@ -72,7 +72,7 @@ MODULE testmod
PROCEDURE, NOPASS :: subroutine2 => proc_intfunc ! { dg-error "must also be a SUBROUTINE" }
PROCEDURE, NOPASS :: intfunction1 => proc_intfunc ! Ok, matching functions.
PROCEDURE, NOPASS :: intfunction2 => proc_sub ! { dg-error "must also be a FUNCTION" }
- PROCEDURE, NOPASS :: intfunction3 => proc_realfunc ! { dg-error "Type/rank mismatch in function result" }
+ PROCEDURE, NOPASS :: intfunction3 => proc_realfunc ! { dg-error "Type mismatch in function result" }
! For access-based checks.
PROCEDURE, NOPASS, PUBLIC :: priv => proc_sub ! Ok, increases visibility.
@@ -89,7 +89,7 @@ MODULE testmod
! For corresponding dummy arguments.
PROCEDURE, PASS :: corresp1 => proc_tmeint ! Ok.
PROCEDURE, PASS :: corresp2 => proc_tmeintx ! { dg-error "should be named 'a'" }
- PROCEDURE, PASS :: corresp3 => proc_tmereal ! { dg-error "Type/rank mismatch in argument 'a'" }
+ PROCEDURE, PASS :: corresp3 => proc_tmereal ! { dg-error "Type mismatch in argument 'a'" }
END TYPE t
diff --git a/gcc/testsuite/gfortran.dg/use_29.f90 b/gcc/testsuite/gfortran.dg/use_29.f90
new file mode 100644
index 00000000000..89dfe509314
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/use_29.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+!
+! PR fortran/57435
+!
+! Contributed by Lorenz Hüdepohl
+!
+module precision
+end module precision
+ contains
+ use precision ! { dg-error "Unexpected USE statement in CONTAINS section" }
+module stressten_rt ! { dg-error "Unexpected MODULE statement in CONTAINS section" }
+ use precision ! { dg-error "Unexpected USE statement in CONTAINS section" }
+ implicit none ! { dg-error "Unexpected IMPLICIT NONE statement in CONTAINS section" }
+
+! { dg-error "Unexpected end of file" "" { target "*-*-*" } 0 }
diff --git a/gcc/testsuite/gnat.dg/fp_exception.adb b/gcc/testsuite/gnat.dg/fp_exception.adb
new file mode 100644
index 00000000000..a8bf62fa923
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/fp_exception.adb
@@ -0,0 +1,24 @@
+-- { dg-do run { target *-*-solaris2.* } }
+-- { dg-options "-ftrapping-math" }
+
+procedure FP_Exception is
+
+ type my_fixed is digits 15;
+ for my_fixed'size use 64;
+ fixed1 : my_fixed := 1.0;
+ fixed2 : my_fixed := -0.0;
+ mask_all : constant integer := 16#1F#;
+
+ procedure fpsetmask(mask : in integer);
+ pragma IMPORT (C, fpsetmask, "fpsetmask");
+
+begin
+
+ -- Mask all floating point exceptions so they can be trapped
+ fpsetmask (mask_all);
+
+ fixed1 := fixed1 / fixed2;
+
+exception
+ when others => null;
+end;
diff --git a/gcc/toplev.c b/gcc/toplev.c
index d41283de931..a2ee4913090 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -393,15 +393,15 @@ wrapup_global_declaration_2 (tree decl)
if (!node && flag_ltrans)
needed = false;
- else if (node && node->finalized)
+ else if (node && node->symbol.definition)
needed = false;
- else if (node && node->alias)
+ else if (node && node->symbol.alias)
needed = false;
else if (!cgraph_global_info_ready
&& (TREE_USED (decl)
|| TREE_USED (DECL_ASSEMBLER_NAME (decl))))
/* needed */;
- else if (node && node->analyzed)
+ else if (node && node->symbol.analyzed)
/* needed */;
else if (DECL_COMDAT (decl))
needed = false;
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index c66278c0110..6289ea46a89 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -3932,8 +3932,8 @@ get_cg_data (struct cgraph_node **node, bool traverse_aliases)
{
struct tm_ipa_cg_data *d;
- if (traverse_aliases && (*node)->alias)
- *node = cgraph_get_node ((*node)->thunk.alias);
+ if (traverse_aliases && (*node)->symbol.alias)
+ *node = cgraph_alias_target (*node);
d = (struct tm_ipa_cg_data *) (*node)->symbol.aux;
@@ -4518,7 +4518,7 @@ ipa_tm_mayenterirr_function (struct cgraph_node *node)
/* Recurse on the main body for aliases. In general, this will
result in one of the bits above being set so that we will not
have to recurse next time. */
- if (node->alias)
+ if (node->symbol.alias)
return ipa_tm_mayenterirr_function (cgraph_get_node (node->thunk.alias));
/* What remains is unmarked local functions without items that force
@@ -4678,9 +4678,14 @@ static inline void
ipa_tm_mark_force_output_node (struct cgraph_node *node)
{
cgraph_mark_force_output_node (node);
- /* ??? function_and_variable_visibility will reset
- the needed bit, without actually checking. */
- node->analyzed = 1;
+ node->symbol.analyzed = true;
+}
+
+static inline void
+ipa_tm_mark_forced_by_abi_node (struct cgraph_node *node)
+{
+ node->symbol.forced_by_abi = true;
+ node->symbol.analyzed = true;
}
/* Callback data for ipa_tm_create_version_alias. */
@@ -4701,7 +4706,7 @@ ipa_tm_create_version_alias (struct cgraph_node *node, void *data)
tree old_decl, new_decl, tm_name;
struct cgraph_node *new_node;
- if (!node->same_body_alias)
+ if (!node->symbol.cpp_implicit_alias)
return false;
old_decl = node->symbol.decl;
@@ -4739,6 +4744,8 @@ ipa_tm_create_version_alias (struct cgraph_node *node, void *data)
if (info->old_node->symbol.force_output
|| ipa_ref_list_first_referring (&info->old_node->symbol.ref_list))
ipa_tm_mark_force_output_node (new_node);
+ if (info->old_node->symbol.forced_by_abi)
+ ipa_tm_mark_forced_by_abi_node (new_node);
return false;
}
@@ -4794,6 +4801,8 @@ ipa_tm_create_version (struct cgraph_node *old_node)
if (old_node->symbol.force_output
|| ipa_ref_list_first_referring (&old_node->symbol.ref_list))
ipa_tm_mark_force_output_node (new_node);
+ if (old_node->symbol.forced_by_abi)
+ ipa_tm_mark_forced_by_abi_node (new_node);
/* Do the same thing, but for any aliases of the original node. */
{
@@ -5250,7 +5259,7 @@ ipa_tm_execute (void)
{
/* If this is an alias, make sure its base is queued as well.
we need not scan the callees now, as the base will do. */
- if (node->alias)
+ if (node->symbol.alias)
{
node = cgraph_get_node (node->thunk.alias);
d = get_cg_data (&node, true);
@@ -5371,7 +5380,7 @@ ipa_tm_execute (void)
bool doit = false;
node = tm_callees[i];
- if (node->same_body_alias)
+ if (node->symbol.cpp_implicit_alias)
continue;
a = cgraph_function_body_availability (node);
@@ -5393,7 +5402,7 @@ ipa_tm_execute (void)
for (i = 0; i < tm_callees.length (); ++i)
{
node = tm_callees[i];
- if (node->analyzed)
+ if (node->symbol.analyzed)
{
d = get_cg_data (&node, true);
if (d->clone)
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index f38a32a4e73..4b91a35f17d 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -2668,10 +2668,45 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
case REALPART_EXPR:
case IMAGPART_EXPR:
+ case BIT_FIELD_REF:
+ if (!is_gimple_reg_type (TREE_TYPE (t)))
+ {
+ error ("non-scalar BIT_FIELD_REF, IMAGPART_EXPR or REALPART_EXPR");
+ return t;
+ }
+
+ if (TREE_CODE (t) == BIT_FIELD_REF)
+ {
+ if (!host_integerp (TREE_OPERAND (t, 1), 1)
+ || !host_integerp (TREE_OPERAND (t, 2), 1))
+ {
+ error ("invalid position or size operand to BIT_FIELD_REF");
+ return t;
+ }
+ if (INTEGRAL_TYPE_P (TREE_TYPE (t))
+ && (TYPE_PRECISION (TREE_TYPE (t))
+ != TREE_INT_CST_LOW (TREE_OPERAND (t, 1))))
+ {
+ error ("integral result type precision does not match "
+ "field size of BIT_FIELD_REF");
+ return t;
+ }
+ else if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
+ && TYPE_MODE (TREE_TYPE (t)) != BLKmode
+ && (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (t)))
+ != TREE_INT_CST_LOW (TREE_OPERAND (t, 1))))
+ {
+ error ("mode precision of non-integral result does not "
+ "match field size of BIT_FIELD_REF");
+ return t;
+ }
+ }
+ t = TREE_OPERAND (t, 0);
+
+ /* Fall-through. */
case COMPONENT_REF:
case ARRAY_REF:
case ARRAY_RANGE_REF:
- case BIT_FIELD_REF:
case VIEW_CONVERT_EXPR:
/* We have a nest of references. Verify that each of the operands
that determine where to reference is either a constant or a variable,
@@ -2690,32 +2725,13 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
if (TREE_OPERAND (t, 3))
CHECK_OP (3, "invalid array stride");
}
- else if (TREE_CODE (t) == BIT_FIELD_REF)
+ else if (TREE_CODE (t) == BIT_FIELD_REF
+ || TREE_CODE (t) == REALPART_EXPR
+ || TREE_CODE (t) == IMAGPART_EXPR)
{
- if (!host_integerp (TREE_OPERAND (t, 1), 1)
- || !host_integerp (TREE_OPERAND (t, 2), 1))
- {
- error ("invalid position or size operand to BIT_FIELD_REF");
- return t;
- }
- if (INTEGRAL_TYPE_P (TREE_TYPE (t))
- && (TYPE_PRECISION (TREE_TYPE (t))
- != TREE_INT_CST_LOW (TREE_OPERAND (t, 1))))
- {
- error ("integral result type precision does not match "
- "field size of BIT_FIELD_REF");
- return t;
- }
- else if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
- && !AGGREGATE_TYPE_P (TREE_TYPE (t))
- && TYPE_MODE (TREE_TYPE (t)) != BLKmode
- && (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (t)))
- != TREE_INT_CST_LOW (TREE_OPERAND (t, 1))))
- {
- error ("mode precision of non-integral result does not "
- "match field size of BIT_FIELD_REF");
- return t;
- }
+ error ("non-top-level BIT_FIELD_REF, IMAGPART_EXPR or "
+ "REALPART_EXPR");
+ return t;
}
t = TREE_OPERAND (t, 0);
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index fc350bd945f..fb80b30a44c 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -2580,7 +2580,7 @@ tree_could_trap_p (tree expr)
/* Assume that accesses to weak functions may trap, unless we know
they are certainly defined in current TU or in some other
LTO partition. */
- if (DECL_WEAK (expr))
+ if (DECL_WEAK (expr) && !DECL_COMDAT (expr))
{
struct cgraph_node *node;
if (!DECL_EXTERNAL (expr))
@@ -2596,7 +2596,7 @@ tree_could_trap_p (tree expr)
/* Assume that accesses to weak vars may trap, unless we know
they are certainly defined in current TU or in some other
LTO partition. */
- if (DECL_WEAK (expr))
+ if (DECL_WEAK (expr) && !DECL_COMDAT (expr))
{
struct varpool_node *node;
if (!DECL_EXTERNAL (expr))
diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c
index fc75b3144e3..6329fdd5015 100644
--- a/gcc/tree-emutls.c
+++ b/gcc/tree-emutls.c
@@ -699,20 +699,22 @@ create_emultls_var (struct varpool_node *var, void *data)
tree cdecl;
struct varpool_node *cvar;
- cdecl = new_emutls_decl (var->symbol.decl, var->alias_of);
+ cdecl = new_emutls_decl (var->symbol.decl,
+ var->symbol.alias && var->symbol.analyzed
+ ? varpool_alias_target (var)->symbol.decl : NULL);
cvar = varpool_get_node (cdecl);
control_vars.quick_push (cvar);
- if (!var->alias)
+ if (!var->symbol.alias)
{
/* Make sure the COMMON block control variable gets initialized.
Note that there's no point in doing this for aliases; we only
need to do this once for the main variable. */
emutls_common_1 (var->symbol.decl, cdecl, (tree *)data);
}
- if (var->alias && !var->alias_of)
- cvar->alias = true;
+ if (var->symbol.alias && !var->symbol.analyzed)
+ cvar->symbol.alias = true;
/* Indicate that the value of the TLS variable may be found elsewhere,
preventing the variable from re-appearing in the GIMPLE. We cheat
@@ -743,7 +745,7 @@ ipa_lower_emutls (void)
gcc_checking_assert (TREE_STATIC (var->symbol.decl)
|| DECL_EXTERNAL (var->symbol.decl));
varpool_node_set_add (tls_vars, var);
- if (var->alias && var->analyzed)
+ if (var->symbol.alias && var->symbol.definition)
varpool_node_set_add (tls_vars, varpool_variable_node (var, NULL));
}
@@ -767,9 +769,9 @@ ipa_lower_emutls (void)
{
var = tls_vars->nodes[i];
- if (var->alias && !var->alias_of)
+ if (var->symbol.alias && !var->symbol.analyzed)
any_aliases = true;
- else if (!var->alias)
+ else if (!var->symbol.alias)
varpool_for_node_and_aliases (var, create_emultls_var, &ctor_body, true);
}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 57af7de2c09..bee77666497 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1726,7 +1726,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
if ((!edge
|| (edge->indirect_inlining_edge
&& id->transform_call_graph_edges == CB_CGE_MOVE_CLONES))
- && id->dst_node->analyzed
+ && id->dst_node->symbol.definition
&& (fn = gimple_call_fndecl (stmt)) != NULL)
{
struct cgraph_node *dest = cgraph_get_node (fn);
@@ -1737,10 +1737,10 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
producing dead clone (for further cloning). In all
other cases we hit a bug (incorrect node sharing is the
most common reason for missing edges). */
- gcc_assert (!dest->analyzed
+ gcc_assert (!dest->symbol.definition
|| dest->symbol.address_taken
- || !id->src_node->analyzed
- || !id->dst_node->analyzed);
+ || !id->src_node->symbol.definition
+ || !id->dst_node->symbol.definition);
if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)
cgraph_create_edge_including_clones
(id->dst_node, dest, orig_stmt, stmt, bb->count,
@@ -3611,7 +3611,7 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
/* Do not special case builtins where we see the body.
This just confuse inliner. */
- if (!decl || !(node = cgraph_get_node (decl)) || node->analyzed)
+ if (!decl || !(node = cgraph_get_node (decl)) || node->symbol.definition)
;
/* For buitins that are likely expanded to nothing or
inlined do not account operand costs. */
@@ -4344,7 +4344,7 @@ optimize_inline_calls (tree fn)
memset (&id, 0, sizeof (id));
id.src_node = id.dst_node = cgraph_get_node (fn);
- gcc_assert (id.dst_node->analyzed);
+ gcc_assert (id.dst_node->symbol.definition);
id.dst_fn = fn;
/* Or any functions that aren't finished yet. */
if (current_function_decl)
@@ -5238,7 +5238,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
pointer_set_destroy (id.statements_to_fold);
fold_cond_expr_cond ();
delete_unreachable_blocks_update_callgraph (&id);
- if (id.dst_node->analyzed)
+ if (id.dst_node->symbol.definition)
cgraph_rebuild_references ();
update_ssa (TODO_update_ssa);
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index f58f7b3a0ec..625f46e1942 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -73,14 +73,10 @@ may_propagate_copy (tree dest, tree orig)
if (!useless_type_conversion_p (type_d, type_o))
return false;
- /* Propagating virtual operands is always ok. */
+ /* Generally propagating virtual operands is not ok as that may
+ create overlapping life-ranges. */
if (TREE_CODE (dest) == SSA_NAME && virtual_operand_p (dest))
- {
- /* But only between virtual operands. */
- gcc_assert (TREE_CODE (orig) == SSA_NAME && virtual_operand_p (orig));
-
- return true;
- }
+ return false;
/* Anything else is OK. */
return true;
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 602289d7886..83ca27a0bf4 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -2936,7 +2936,22 @@ eliminate_const_or_copy (gimple stmt, bitmap interesting_names)
return;
}
- propagate_rhs_into_lhs (stmt, lhs, rhs, interesting_names);
+ if (!virtual_operand_p (lhs))
+ propagate_rhs_into_lhs (stmt, lhs, rhs, interesting_names);
+ else
+ {
+ gimple use_stmt;
+ imm_use_iterator iter;
+ use_operand_p use_p;
+ /* For virtual operands we have to propagate into all uses as
+ otherwise we will create overlapping life-ranges. */
+ FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
+ FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
+ SET_USE (use_p, rhs);
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs) = 1;
+ remove_stmt_or_phi (stmt);
+ }
/* Note that STMT may well have been deleted by now, so do
not access it, instead use the saved version # to clear
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 090e114c36d..f5629306e4b 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -552,10 +552,18 @@ number_of_iterations_ne_max (mpz_t bnd, bool no_overflow, tree c, tree s,
{
double_int max;
mpz_t d;
+ tree type = TREE_TYPE (c);
bool bnds_u_valid = ((no_overflow && exit_must_be_taken)
|| mpz_sgn (bnds->below) >= 0);
- if (multiple_of_p (TREE_TYPE (c), c, s))
+ if (integer_onep (s)
+ || (TREE_CODE (c) == INTEGER_CST
+ && TREE_CODE (s) == INTEGER_CST
+ && tree_to_double_int (c).mod (tree_to_double_int (s),
+ TYPE_UNSIGNED (type),
+ EXACT_DIV_EXPR).is_zero ())
+ || (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (c))
+ && multiple_of_p (type, c, s)))
{
/* If C is an exact multiple of S, then its value will be reached before
the induction variable overflows (unless the loop is exited in some
@@ -572,16 +580,15 @@ number_of_iterations_ne_max (mpz_t bnd, bool no_overflow, tree c, tree s,
the whole # of iterations analysis will fail). */
if (!no_overflow)
{
- max = double_int::mask (TYPE_PRECISION (TREE_TYPE (c))
- - tree_low_cst (num_ending_zeros (s), 1));
+ max = double_int::mask (TYPE_PRECISION (type)
+ - tree_low_cst (num_ending_zeros (s), 1));
mpz_set_double_int (bnd, max, true);
return;
}
/* Now we know that the induction variable does not overflow, so the loop
iterates at most (range of type / S) times. */
- mpz_set_double_int (bnd, double_int::mask (TYPE_PRECISION (TREE_TYPE (c))),
- true);
+ mpz_set_double_int (bnd, double_int::mask (TYPE_PRECISION (type)), true);
/* If the induction variable is guaranteed to reach the value of C before
overflow, ... */
@@ -1311,7 +1318,8 @@ number_of_iterations_cond (struct loop *loop,
}
/* If the loop exits immediately, there is nothing to do. */
- if (integer_zerop (fold_build2 (code, boolean_type_node, iv0->base, iv1->base)))
+ tree tem = fold_binary (code, boolean_type_node, iv0->base, iv1->base);
+ if (tem && integer_zerop (tem))
{
niter->niter = build_int_cst (unsigned_type_for (type), 0);
niter->max = double_int_zero;
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index a94172d01cd..e9c32b3c8be 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -1445,12 +1445,41 @@ execute_cse_sincos (void)
CASE_FLT_FN (BUILT_IN_POWI):
arg0 = gimple_call_arg (stmt, 0);
arg1 = gimple_call_arg (stmt, 1);
- if (!host_integerp (arg1, 0))
- break;
-
- n = TREE_INT_CST_LOW (arg1);
loc = gimple_location (stmt);
- result = gimple_expand_builtin_powi (&gsi, loc, arg0, n);
+
+ if (real_minus_onep (arg0))
+ {
+ tree t0, t1, cond, one, minus_one;
+ gimple stmt;
+
+ t0 = TREE_TYPE (arg0);
+ t1 = TREE_TYPE (arg1);
+ one = build_real (t0, dconst1);
+ minus_one = build_real (t0, dconstm1);
+
+ cond = make_temp_ssa_name (t1, NULL, "powi_cond");
+ stmt = gimple_build_assign_with_ops (BIT_AND_EXPR, cond,
+ arg1,
+ build_int_cst (t1,
+ 1));
+ gimple_set_location (stmt, loc);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+
+ result = make_temp_ssa_name (t0, NULL, "powi");
+ stmt = gimple_build_assign_with_ops (COND_EXPR, result,
+ cond,
+ minus_one, one);
+ gimple_set_location (stmt, loc);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ }
+ else
+ {
+ if (!host_integerp (arg1, 0))
+ break;
+
+ n = TREE_INT_CST_LOW (arg1);
+ result = gimple_expand_builtin_powi (&gsi, loc, arg0, n);
+ }
if (result)
{
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 8e137630624..784477b5922 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -2866,6 +2866,31 @@ not_dominated_by (gimple a, gimple b)
}
+/* Among STMT1 and STMT2, return the statement that appears later. Both
+ statements are in same BB and have the same UID. */
+
+static gimple
+appears_later_in_bb (gimple stmt1, gimple stmt2)
+{
+ unsigned uid = gimple_uid (stmt1);
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt1);
+ gsi_next (&gsi);
+ if (gsi_end_p (gsi))
+ return stmt1;
+ for (; !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+
+ /* If STMT has a different UID than STMT1 and we haven't seen
+ STMT2 during traversal, we know STMT1 appears later. */
+ if (gimple_uid (stmt) != uid)
+ return stmt1;
+ else if (stmt == stmt2)
+ return stmt2;
+ }
+ return stmt1;
+}
+
/* Find the statement after which STMT must be moved so that the
dependency from DEP_STMT to STMT is maintained. */
@@ -2875,7 +2900,11 @@ find_insert_point (gimple stmt, gimple dep_stmt)
gimple insert_stmt = stmt;
if (dep_stmt == NULL)
return stmt;
- if (not_dominated_by (insert_stmt, dep_stmt))
+ if (gimple_uid (insert_stmt) == gimple_uid (dep_stmt)
+ && gimple_bb (insert_stmt) == gimple_bb (dep_stmt)
+ && insert_stmt != dep_stmt)
+ insert_stmt = appears_later_in_bb (insert_stmt, dep_stmt);
+ else if (not_dominated_by (insert_stmt, dep_stmt))
insert_stmt = dep_stmt;
return insert_stmt;
}
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 0e7a74c2a9c..6886efbe3eb 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1145,7 +1145,7 @@ vn_reference_fold_indirect (vec<vn_reference_op_s> *ops,
addr_base = get_addr_base_and_unit_offset (TREE_OPERAND (op->op0, 0),
&addr_offset);
gcc_checking_assert (addr_base && TREE_CODE (addr_base) != MEM_REF);
- if (addr_base != op->op0)
+ if (addr_base != TREE_OPERAND (op->op0, 0))
{
double_int off = tree_to_double_int (mem_op->op0);
off = off.sext (TYPE_PRECISION (TREE_TYPE (mem_op->op0)));
@@ -2608,6 +2608,7 @@ static inline bool
set_ssa_val_to (tree from, tree to)
{
tree currval = SSA_VAL (from);
+ HOST_WIDE_INT toff, coff;
if (from != to)
{
@@ -2643,7 +2644,17 @@ set_ssa_val_to (tree from, tree to)
print_generic_expr (dump_file, to, 0);
}
- if (currval != to && !operand_equal_p (currval, to, OEP_PURE_SAME))
+ if (currval != to
+ && !operand_equal_p (currval, to, 0)
+ /* ??? For addresses involving volatile objects or types operand_equal_p
+ does not reliably detect ADDR_EXPRs as equal. We know we are only
+ getting invariant gimple addresses here, so can use
+ get_addr_base_and_unit_offset to do this comparison. */
+ && !(TREE_CODE (currval) == ADDR_EXPR
+ && TREE_CODE (to) == ADDR_EXPR
+ && (get_addr_base_and_unit_offset (TREE_OPERAND (currval, 0), &coff)
+ == get_addr_base_and_unit_offset (TREE_OPERAND (to, 0), &toff))
+ && coff == toff))
{
VN_INFO (from)->valnum = to;
if (dump_file && (dump_flags & TDF_DETAILS))
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 9eb06f6b097..d7aeefe0b22 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -382,7 +382,7 @@ new_var_info (tree t, const char *name)
/* A map mapping call statements to per-stmt variables for uses
and clobbers specific to the call. */
-struct pointer_map_t *call_stmt_vars;
+static struct pointer_map_t *call_stmt_vars;
/* Lookup or create the variable for the call statement CALL. */
@@ -2874,7 +2874,7 @@ get_constraint_for_ssa_var (tree t, vec<ce_s> *results, bool address_p)
&& (TREE_STATIC (t) || DECL_EXTERNAL (t)))
{
struct varpool_node *node = varpool_get_node (t);
- if (node && node->alias)
+ if (node && node->symbol.alias && node->symbol.analyzed)
{
node = varpool_variable_node (node, NULL);
t = node->symbol.decl;
@@ -5751,7 +5751,7 @@ create_variable_info_for (tree decl, const char *name)
/* If this is a global variable with an initializer and we are in
IPA mode generate constraints for it. */
if (DECL_INITIAL (decl)
- && vnode->analyzed)
+ && vnode->symbol.definition)
{
vec<ce_s> rhsc = vNULL;
struct constraint_expr lhs, *rhsp;
@@ -7023,7 +7023,8 @@ struct pt_solution ipa_escaped_pt
static bool
associate_varinfo_to_alias (struct cgraph_node *node, void *data)
{
- if (node->alias || node->thunk.thunk_p)
+ if ((node->symbol.alias || node->thunk.thunk_p)
+ && node->symbol.analyzed)
insert_vi_for_tree (node->symbol.decl, (varinfo_t)data);
return false;
}
@@ -7066,7 +7067,7 @@ ipa_pta_execute (void)
/* Create constraints for global variables and their initializers. */
FOR_EACH_VARIABLE (var)
{
- if (var->alias)
+ if (var->symbol.alias && var->symbol.analyzed)
continue;
get_vi_for_tree (var->symbol.decl);
diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c
index 2625dd6b42f..39b212e47b3 100644
--- a/gcc/tree-streamer-out.c
+++ b/gcc/tree-streamer-out.c
@@ -87,8 +87,9 @@ pack_ts_base_value_fields (struct bitpack_d *bp, tree expr)
bp_pack_value (bp, TYPE_UNSIGNED (expr), 1);
else
bp_pack_value (bp, 0, 1);
- /* We write debug info two times, do not confuse the second one. */
- bp_pack_value (bp, ((TYPE_P (expr) || TREE_CODE (expr) == TYPE_DECL)
+ /* We write debug info two times, do not confuse the second one.
+ The only relevant TREE_ASM_WRITTEN use is on SSA names. */
+ bp_pack_value (bp, (TREE_CODE (expr) != SSA_NAME
? 0 : TREE_ASM_WRITTEN (expr)), 1);
if (TYPE_P (expr))
bp_pack_value (bp, TYPE_ARTIFICIAL (expr), 1);
diff --git a/gcc/tree-streamer.c b/gcc/tree-streamer.c
index f29690f62b9..e4d948b4cca 100644
--- a/gcc/tree-streamer.c
+++ b/gcc/tree-streamer.c
@@ -152,6 +152,7 @@ streamer_tree_cache_insert_1 (struct streamer_tree_cache_d *cache,
the requested location slot. */
ix = *ix_p;
streamer_tree_cache_add_to_node_array (cache, ix, t);
+ *slot = (void *)(size_t) (ix + 1);
}
/* Indicate that T was already in the cache. */
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index c26d25dabbb..47ecad3528d 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -2861,6 +2861,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
bool gather = false;
int vf;
+again:
if (!dr || !DR_REF (dr))
{
if (dump_enabled_p ())
@@ -2872,6 +2873,19 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
stmt = DR_STMT (dr);
stmt_info = vinfo_for_stmt (stmt);
+ /* Discard clobbers from the dataref vector. We will remove
+ clobber stmts during vectorization. */
+ if (gimple_clobber_p (stmt))
+ {
+ if (i == datarefs.length () - 1)
+ {
+ datarefs.pop ();
+ break;
+ }
+ datarefs[i] = datarefs.pop ();
+ goto again;
+ }
+
/* Check that analysis of the data-ref succeeded. */
if (!DR_BASE_ADDRESS (dr) || !DR_OFFSET (dr) || !DR_INIT (dr)
|| !DR_STEP (dr))
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 058e4a4ec54..3b10b1989b4 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -270,8 +270,9 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
gcc_assert (stmt_info);
/* Skip stmts which do not need to be vectorized. */
- if (!STMT_VINFO_RELEVANT_P (stmt_info)
- && !STMT_VINFO_LIVE_P (stmt_info))
+ if ((!STMT_VINFO_RELEVANT_P (stmt_info)
+ && !STMT_VINFO_LIVE_P (stmt_info))
+ || gimple_clobber_p (stmt))
{
if (STMT_VINFO_IN_PATTERN_P (stmt_info)
&& (pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info))
@@ -1431,7 +1432,8 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp)
for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
gimple stmt = gsi_stmt (si);
- if (!vect_analyze_stmt (stmt, &need_to_vectorize, NULL))
+ if (!gimple_clobber_p (stmt)
+ && !vect_analyze_stmt (stmt, &need_to_vectorize, NULL))
return false;
}
} /* bbs */
@@ -5595,7 +5597,17 @@ vect_transform_loop (loop_vec_info loop_vinfo)
if (transform_pattern_stmt)
stmt = pattern_stmt;
else
- stmt = gsi_stmt (si);
+ {
+ stmt = gsi_stmt (si);
+ /* During vectorization remove existing clobber stmts. */
+ if (gimple_clobber_p (stmt))
+ {
+ unlink_stmt_vdef (stmt);
+ gsi_remove (&si, true);
+ release_defs (stmt);
+ continue;
+ }
+ }
if (dump_enabled_p ())
{
@@ -5789,7 +5801,7 @@ vect_transform_loop (loop_vec_info loop_vinfo)
if (dump_enabled_p ())
{
- dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ dump_printf_loc (MSG_NOTE, vect_location,
"LOOP VECTORIZED\n");
if (loop->inner)
dump_printf_loc (MSG_NOTE, vect_location,
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index e3b38ff2d52..ea8c202d187 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -1898,6 +1898,71 @@ vect_slp_analyze_operations (bb_vec_info bb_vinfo)
return true;
}
+
+/* Compute the scalar cost of the SLP node NODE and its children
+ and return it. Do not account defs that are marked in LIFE and
+ update LIFE according to uses of NODE. */
+
+static unsigned
+vect_bb_slp_scalar_cost (basic_block bb,
+ slp_tree node, vec<bool, va_stack> life)
+{
+ unsigned scalar_cost = 0;
+ unsigned i;
+ gimple stmt;
+ slp_tree child;
+
+ FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
+ {
+ unsigned stmt_cost;
+ ssa_op_iter op_iter;
+ def_operand_p def_p;
+ stmt_vec_info stmt_info;
+
+ if (life[i])
+ continue;
+
+ /* If there is a non-vectorized use of the defs then the scalar
+ stmt is kept live in which case we do not account it or any
+ required defs in the SLP children in the scalar cost. This
+ way we make the vectorization more costly when compared to
+ the scalar cost. */
+ FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, op_iter, SSA_OP_DEF)
+ {
+ imm_use_iterator use_iter;
+ gimple use_stmt;
+ FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, DEF_FROM_PTR (def_p))
+ if (gimple_code (use_stmt) == GIMPLE_PHI
+ || gimple_bb (use_stmt) != bb
+ || !STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (use_stmt)))
+ {
+ life[i] = true;
+ BREAK_FROM_IMM_USE_STMT (use_iter);
+ }
+ }
+ if (life[i])
+ continue;
+
+ stmt_info = vinfo_for_stmt (stmt);
+ if (STMT_VINFO_DATA_REF (stmt_info))
+ {
+ if (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)))
+ stmt_cost = vect_get_stmt_cost (scalar_load);
+ else
+ stmt_cost = vect_get_stmt_cost (scalar_store);
+ }
+ else
+ stmt_cost = vect_get_stmt_cost (scalar_stmt);
+
+ scalar_cost += stmt_cost;
+ }
+
+ FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
+ scalar_cost += vect_bb_slp_scalar_cost (bb, child, life);
+
+ return scalar_cost;
+}
+
/* Check if vectorization of the basic block is profitable. */
static bool
@@ -1908,10 +1973,6 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo)
int i, j;
unsigned int vec_inside_cost = 0, vec_outside_cost = 0, scalar_cost = 0;
unsigned int vec_prologue_cost = 0, vec_epilogue_cost = 0;
- unsigned int stmt_cost;
- gimple stmt;
- gimple_stmt_iterator si;
- basic_block bb = BB_VINFO_BB (bb_vinfo);
void *target_cost_data = BB_VINFO_TARGET_COST_DATA (bb_vinfo);
stmt_vec_info stmt_info = NULL;
stmt_vector_for_cost body_cost_vec;
@@ -1931,26 +1992,15 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo)
}
/* Calculate scalar cost. */
- for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
+ FOR_EACH_VEC_ELT (slp_instances, i, instance)
{
- stmt = gsi_stmt (si);
- stmt_info = vinfo_for_stmt (stmt);
-
- if (!stmt_info || !STMT_VINFO_VECTORIZABLE (stmt_info)
- || !PURE_SLP_STMT (stmt_info))
- continue;
-
- if (STMT_VINFO_DATA_REF (stmt_info))
- {
- if (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)))
- stmt_cost = vect_get_stmt_cost (scalar_load);
- else
- stmt_cost = vect_get_stmt_cost (scalar_store);
- }
- else
- stmt_cost = vect_get_stmt_cost (scalar_stmt);
-
- scalar_cost += stmt_cost;
+ vec<bool, va_stack> life;
+ vec_stack_alloc (bool, life, SLP_INSTANCE_GROUP_SIZE (instance));
+ life.quick_grow_cleared (SLP_INSTANCE_GROUP_SIZE (instance));
+ scalar_cost += vect_bb_slp_scalar_cost (BB_VINFO_BB (bb_vinfo),
+ SLP_INSTANCE_TREE (instance),
+ life);
+ life.release ();
}
/* Complete the target-specific cost calculation. */
@@ -3132,7 +3182,7 @@ vect_slp_transform_bb (basic_block bb)
}
if (dump_enabled_p ())
- dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ dump_printf_loc (MSG_NOTE, vect_location,
"BASIC BLOCK VECTORIZED\n");
destroy_bb_vec_info (bb_vinfo);
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 814f96c3017..1ef31eefd1d 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -118,8 +118,8 @@ vectorize_loops (void)
if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOC
&& dump_enabled_p ())
- dump_printf (MSG_NOTE, "\n\nVectorizing loop at %s:%d\n",
- LOC_FILE (vect_location), LOC_LINE (vect_location));
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "Vectorized loop\n");
vect_transform_loop (loop_vinfo);
num_vectorized_loops++;
}
@@ -179,8 +179,8 @@ execute_vect_slp (void)
{
vect_slp_transform_bb (bb);
if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "basic block vectorized using SLP\n");
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "Vectorized basic-block\n");
}
}
diff --git a/gcc/tsan.c b/gcc/tsan.c
index a3b65650e38..d218eed5a1b 100644
--- a/gcc/tsan.c
+++ b/gcc/tsan.c
@@ -198,7 +198,7 @@ enum tsan_atomic_action
/* Table how to map sync/atomic builtins to their corresponding
tsan equivalents. */
-static struct tsan_map_atomic
+static const struct tsan_map_atomic
{
enum built_in_function fcode, tsan_fcode;
enum tsan_atomic_action action;
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 5f62677b2cc..c088ebf9008 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -2256,7 +2256,7 @@ mark_decl_referenced (tree decl)
definition. */
struct cgraph_node *node = cgraph_get_create_node (decl);
if (!DECL_EXTERNAL (decl)
- && !node->local.finalized)
+ && !node->symbol.definition)
cgraph_mark_force_output_node (node);
}
else if (TREE_CODE (decl) == VAR_DECL)
@@ -4612,28 +4612,21 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
switch (TREE_CODE (exp))
{
case CONSTRUCTOR:
- output_constructor (exp, size, align, NULL);
+ output_constructor (exp, size, align, NULL);
return;
case STRING_CST:
- thissize = MIN ((unsigned HOST_WIDE_INT)TREE_STRING_LENGTH (exp),
- size);
+ thissize
+ = MIN ((unsigned HOST_WIDE_INT)TREE_STRING_LENGTH (exp), size);
assemble_string (TREE_STRING_POINTER (exp), thissize);
break;
-
case VECTOR_CST:
{
- int elt_size;
- unsigned int i, nalign;
- enum machine_mode inner;
-
- inner = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
- nalign = MIN (align, GET_MODE_ALIGNMENT (inner));
-
- elt_size = GET_MODE_SIZE (inner);
-
+ enum machine_mode inner = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
+ unsigned int nalign = MIN (align, GET_MODE_ALIGNMENT (inner));
+ int elt_size = GET_MODE_SIZE (inner);
output_constant (VECTOR_CST_ELT (exp, 0), elt_size, align);
thissize = elt_size;
- for (i = 1; i < VECTOR_CST_NELTS (exp); ++i)
+ for (unsigned int i = 1; i < VECTOR_CST_NELTS (exp); i++)
{
output_constant (VECTOR_CST_ELT (exp, i), elt_size, nalign);
thissize += elt_size;
@@ -5560,13 +5553,6 @@ assemble_alias (tree decl, tree target)
if (alias == target)
error ("weakref %q+D ultimately targets itself", decl);
- else
- {
-#ifndef ASM_OUTPUT_WEAKREF
- IDENTIFIER_TRANSPARENT_ALIAS (alias) = 1;
- TREE_CHAIN (alias) = target;
-#endif
- }
if (TREE_PUBLIC (decl))
error ("weakref %q+D must have static linkage", decl);
}
@@ -5595,9 +5581,9 @@ assemble_alias (tree decl, tree target)
/* Allow aliases to aliases. */
if (TREE_CODE (decl) == FUNCTION_DECL)
- cgraph_get_create_node (decl)->alias = true;
+ cgraph_get_create_node (decl)->symbol.alias = true;
else
- varpool_node_for_decl (decl)->alias = true;
+ varpool_node_for_decl (decl)->symbol.alias = true;
/* If the target has already been emitted, we don't have to queue the
alias. This saves a tad of memory. */
@@ -5700,12 +5686,12 @@ dump_tm_clone_pairs (vec<tm_alias_pair> tm_alias_pairs)
TM_GETTMCLONE. If neither of these are true, we didn't generate
a clone, and we didn't call it indirectly... no sense keeping it
in the clone table. */
- if (!dst_n || !dst_n->analyzed)
+ if (!dst_n || !dst_n->symbol.definition)
continue;
/* This covers the case where we have optimized the original
function away, and only access the transactional clone. */
- if (!src_n || !src_n->analyzed)
+ if (!src_n || !src_n->symbol.definition)
continue;
if (!switched)
diff --git a/gcc/varpool.c b/gcc/varpool.c
index e3ad22b1cfd..a3e9325a2ce 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -58,6 +58,19 @@ void
varpool_remove_node (struct varpool_node *node)
{
symtab_unregister_node ((symtab_node)node);
+
+ /* Because we remove references from external functions before final compilation,
+ we may end up removing useful constructors.
+ FIXME: We probably want to trace boundaries better. */
+ if (!const_value_known_p (node->symbol.decl))
+ varpool_remove_initializer (node);
+ ggc_free (node);
+}
+
+/* Renove node initializer when it is no longer needed. */
+void
+varpool_remove_initializer (struct varpool_node *node)
+{
if (DECL_INITIAL (node->symbol.decl)
&& !DECL_IN_CONSTANT_POOL (node->symbol.decl)
/* Keep vtables for BINFO folding. */
@@ -65,7 +78,6 @@ varpool_remove_node (struct varpool_node *node)
/* FIXME: http://gcc.gnu.org/PR55395 */
&& debug_info_level == DINFO_LEVEL_NONE)
DECL_INITIAL (node->symbol.decl) = error_mark_node;
- ggc_free (node);
}
/* Dump given cgraph node. */
@@ -80,10 +92,6 @@ dump_varpool_node (FILE *f, struct varpool_node *node)
fprintf (f, " Varpool flags:");
if (DECL_INITIAL (node->symbol.decl))
fprintf (f, " initialized");
- if (node->analyzed)
- fprintf (f, " analyzed");
- if (node->finalized)
- fprintf (f, " finalized");
if (node->output)
fprintf (f, " output");
if (TREE_READONLY (node->symbol.decl))
@@ -117,31 +125,9 @@ struct varpool_node *
varpool_node_for_asm (tree asmname)
{
if (symtab_node node = symtab_node_for_asm (asmname))
- if (varpool_node *vnode = dyn_cast <varpool_node> (node))
- return vnode;
- return NULL;
-}
-
-/* Determine if variable DECL is needed. That is, visible to something
- either outside this translation unit, something magic in the system
- configury */
-bool
-decide_is_variable_needed (struct varpool_node *node, tree decl)
-{
- if (DECL_EXTERNAL (decl))
- return false;
-
- /* If the user told us it is used, then it must be so. */
- if (node->symbol.force_output)
- return true;
-
- /* Externally visible variables must be output. The exception is
- COMDAT variables that must be output only when they are needed. */
- if (TREE_PUBLIC (decl)
- && !DECL_COMDAT (decl))
- return true;
-
- return false;
+ return dyn_cast <varpool_node> (node);
+ else
+ return NULL;
}
/* Return if DECL is constant and its initial value is known (so we can do
@@ -205,12 +191,12 @@ enum availability
cgraph_variable_initializer_availability (struct varpool_node *node)
{
gcc_assert (cgraph_function_flags_ready);
- if (!node->finalized)
+ if (!node->symbol.definition)
return AVAIL_NOT_AVAILABLE;
if (!TREE_PUBLIC (node->symbol.decl))
return AVAIL_AVAILABLE;
/* If the variable can be overwritten, return OVERWRITABLE. Takes
- care of at least two notable extensions - the COMDAT variables
+ care of at least one notable extension - the COMDAT variables
used to share template instantiations in C++. */
if (!decl_replaceable_p (node->symbol.decl))
return AVAIL_OVERWRITABLE;
@@ -225,40 +211,19 @@ varpool_analyze_node (struct varpool_node *node)
/* When reading back varpool at LTO time, we re-construct the queue in order
to have "needed" list right by inserting all needed nodes into varpool.
We however don't want to re-analyze already analyzed nodes. */
- if (!node->analyzed)
+ if (!node->symbol.analyzed)
{
gcc_assert (!in_lto_p || cgraph_function_flags_ready);
/* Compute the alignment early so function body expanders are
already informed about increased alignment. */
align_variable (decl, 0);
}
- if (node->alias && node->alias_of)
- {
- struct varpool_node *tgt = varpool_node_for_decl (node->alias_of);
- struct varpool_node *n;
-
- for (n = tgt; n && n->alias;
- n = n->analyzed ? varpool_alias_aliased_node (n) : NULL)
- if (n == node)
- {
- error ("variable %q+D part of alias cycle", node->symbol.decl);
- node->alias = false;
- continue;
- }
- if (!vec_safe_length (node->symbol.ref_list.references))
- ipa_record_reference ((symtab_node)node, (symtab_node)tgt, IPA_REF_ALIAS, NULL);
- if (node->extra_name_alias)
- {
- DECL_WEAK (node->symbol.decl) = DECL_WEAK (node->alias_of);
- DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (node->alias_of);
- DECL_VISIBILITY (node->symbol.decl) = DECL_VISIBILITY (node->alias_of);
- fixup_same_cpp_alias_visibility ((symtab_node) node,
- (symtab_node) tgt, node->alias_of);
- }
- }
+ if (node->symbol.alias)
+ symtab_resolve_alias
+ ((symtab_node) node, (symtab_node) varpool_get_node (node->symbol.alias_target));
else if (DECL_INITIAL (decl))
- record_references_in_initializer (decl, node->analyzed);
- node->analyzed = true;
+ record_references_in_initializer (decl, node->symbol.analyzed);
+ node->symbol.analyzed = true;
}
/* Assemble thunks and aliases associated to NODE. */
@@ -273,7 +238,7 @@ assemble_aliases (struct varpool_node *node)
{
struct varpool_node *alias = ipa_ref_referring_varpool_node (ref);
do_assemble_alias (alias->symbol.decl,
- DECL_ASSEMBLER_NAME (alias->alias_of));
+ DECL_ASSEMBLER_NAME (node->symbol.decl));
assemble_aliases (alias);
}
}
@@ -287,7 +252,7 @@ varpool_assemble_decl (struct varpool_node *node)
/* Aliases are outout when their target is produced or by
output_weakrefs. */
- if (node->alias)
+ if (node->symbol.alias)
return false;
/* Constant pool is output from RTL land when the reference
@@ -316,7 +281,7 @@ varpool_assemble_decl (struct varpool_node *node)
{
assemble_variable (decl, 0, 1, 0);
gcc_assert (TREE_ASM_WRITTEN (decl));
- node->finalized = 1;
+ node->symbol.definition = true;
assemble_aliases (node);
return true;
}
@@ -357,7 +322,7 @@ varpool_remove_unreferenced_decls (void)
fprintf (cgraph_dump_file, "Trivially needed variables:");
FOR_EACH_DEFINED_VARIABLE (node)
{
- if (node->analyzed
+ if (node->symbol.analyzed
&& (!varpool_can_remove_if_no_refs (node)
/* We just expanded all function bodies. See if any of
them needed the variable. */
@@ -381,7 +346,7 @@ varpool_remove_unreferenced_decls (void)
next = next->symbol.same_comdat_group)
{
varpool_node *vnext = dyn_cast <varpool_node> (next);
- if (vnext && vnext->analyzed)
+ if (vnext && vnext->symbol.analyzed)
enqueue_node (vnext, &first);
}
}
@@ -390,8 +355,8 @@ varpool_remove_unreferenced_decls (void)
varpool_node *vnode = dyn_cast <varpool_node> (ref->referred);
if (vnode
&& (!DECL_EXTERNAL (ref->referred->symbol.decl)
- || vnode->alias)
- && vnode->analyzed)
+ || vnode->symbol.alias)
+ && vnode->symbol.analyzed)
enqueue_node (vnode, &first);
}
}
@@ -419,7 +384,7 @@ void
varpool_finalize_named_section_flags (struct varpool_node *node)
{
if (!TREE_ASM_WRITTEN (node->symbol.decl)
- && !node->alias
+ && !node->symbol.alias
&& !node->symbol.in_other_partition
&& !DECL_EXTERNAL (node->symbol.decl)
&& TREE_CODE (node->symbol.decl) == VAR_DECL
@@ -484,20 +449,9 @@ varpool_create_variable_alias (tree alias, tree decl)
gcc_assert (TREE_CODE (decl) == VAR_DECL);
gcc_assert (TREE_CODE (alias) == VAR_DECL);
alias_node = varpool_node_for_decl (alias);
- alias_node->alias = 1;
- alias_node->finalized = 1;
- alias_node->alias_of = decl;
-
- /* Extra name alias mechanizm creates aliases really late
- via DECL_ASSEMBLER_NAME mechanizm.
- This is unfortunate because they are not going through the
- standard channels. Ensure they get output. */
- if (cgraph_state >= CGRAPH_STATE_IPA)
- {
- varpool_analyze_node (alias_node);
- if (TREE_PUBLIC (alias))
- alias_node->symbol.externally_visible = true;
- }
+ alias_node->symbol.alias = true;
+ alias_node->symbol.definition = true;
+ alias_node->symbol.alias_target = decl;
return alias_node;
}
@@ -514,7 +468,15 @@ varpool_extra_name_alias (tree alias, tree decl)
return NULL;
#endif
alias_node = varpool_create_variable_alias (alias, decl);
- alias_node->extra_name_alias = true;
+ alias_node->symbol.cpp_implicit_alias = true;
+
+ /* Extra name alias mechanizm creates aliases really late
+ via DECL_ASSEMBLER_NAME mechanizm.
+ This is unfortunate because they are not going through the
+ standard channels. Ensure they get output. */
+ if (cpp_implicit_aliases_done)
+ symtab_resolve_alias ((symtab_node)alias_node,
+ (symtab_node)varpool_node_for_decl (decl));
return alias_node;
}
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 861d5da3358..81edf447f03 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,22 @@
+2013-06-04 Jürgen Urban <JuergenUrban@gmx.de>
+
+ * config.host (mipsr5900-*-elf*, mipsr5900el-*-elf*, mips64r5900-*-elf*)
+ (mips64r5900el-*-elf*): New configurations.
+
+2013-06-04 Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/ibm-ldouble.c: Enable for little-endian.
+
+2013-06-03 Yuri Rumyantsev <yuri.s.rumyantsev@intel.com>
+
+ * config/i386/cpuinfo.c (INTEL_SLM): New enum value.
+
+2013-05-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config/sparc/sol2-unwind.h (MD_FALLBACK_FRAME_STATE_FOR): Do not set
+ fs->signal_frame for SIGFPE raised for IEEE-754 exceptions.
+ * config/i386/sol2-unwind.h (x86_fallback_frame_state): Likewise.
+
2013-05-22 Eric Botcazou <ebotcazou@adacore.com>
* config.host (powerpc-*-elf*): Add rs6000/t-savresfgpr to tmake_file.
diff --git a/libgcc/config.host b/libgcc/config.host
index 0247bb0106d..8cf1c5f43bc 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -739,7 +739,17 @@ mips*-*-netbsd*) # NetBSD/mips, either endian.
;;
mips*-*-linux*) # Linux MIPS, either endian.
extra_parts="$extra_parts crtfastmath.o"
- tmake_file="${tmake_file} t-crtfm mips/t-mips16"
+ tmake_file="${tmake_file} t-crtfm"
+ # Check for MicroMIPS support.
+ case ${host} in
+ mips64r5900* | mipsr5900*)
+ # The MIPS16 support code uses floating point
+ # instructions that are not supported on r5900.
+ ;;
+ *)
+ tmake_file="${tmake_file} mips/t-mips16"
+ ;;
+ esac
md_unwind_header=mips/linux-unwind.h
if test "${ac_cv_sizeof_long_double}" = 16; then
tmake_file="${tmake_file} mips/t-tpbit"
@@ -777,10 +787,18 @@ mips-*-elf* | mipsel-*-elf*)
tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16"
extra_parts="$extra_parts crti.o crtn.o"
;;
+mipsr5900-*-elf* | mipsr5900el-*-elf*)
+ tmake_file="$tmake_file mips/t-elf mips/t-crtstuff"
+ extra_parts="$extra_parts crti.o crtn.o"
+ ;;
mips64-*-elf* | mips64el-*-elf*)
tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16"
extra_parts="$extra_parts crti.o crtn.o"
;;
+mips64r5900-*-elf* | mips64r5900el-*-elf*)
+ tmake_file="$tmake_file mips/t-elf mips/t-crtstuff"
+ extra_parts="$extra_parts crti.o crtn.o"
+ ;;
mips64vr-*-elf* | mips64vrel-*-elf*)
tmake_file="$tmake_file mips/t-elf mips/t-vr mips/t-crtstuff"
extra_parts="$extra_parts crti.o crtn.o"
diff --git a/libgcc/config/i386/cpuinfo.c b/libgcc/config/i386/cpuinfo.c
index 0ad00740350..b7e64c3d720 100644
--- a/libgcc/config/i386/cpuinfo.c
+++ b/libgcc/config/i386/cpuinfo.c
@@ -47,6 +47,8 @@ enum processor_vendor
VENDOR_MAX
};
+/* Any new types or subtypes have to be inserted at the end. */
+
enum processor_types
{
INTEL_ATOM = 1,
@@ -54,6 +56,7 @@ enum processor_types
INTEL_COREI7,
AMDFAM10H,
AMDFAM15H,
+ INTEL_SLM,
CPU_TYPE_MAX
};
diff --git a/libgcc/config/i386/sol2-unwind.h b/libgcc/config/i386/sol2-unwind.h
index f804aaf15a7..e67710907b1 100644
--- a/libgcc/config/i386/sol2-unwind.h
+++ b/libgcc/config/i386/sol2-unwind.h
@@ -249,7 +249,12 @@ x86_fallback_frame_state (struct _Unwind_Context *context,
fs->regs.reg[8].how = REG_SAVED_OFFSET;
fs->regs.reg[8].loc.offset = (long)&mctx->gregs[EIP] - new_cfa;
fs->retaddr_column = 8;
- fs->signal_frame = 1;
+
+ /* SIGFPE for IEEE-754 exceptions is delivered after the faulting insn
+ rather than before it, so don't set fs->signal_frame in that case.
+ We test whether the ES field of the Status Register is zero. */
+ if ((mctx->fpregs.fp_reg_set.fpchip_state.status & 0x80) == 0)
+ fs->signal_frame = 1;
return _URC_NO_REASON;
}
diff --git a/libgcc/config/rs6000/ibm-ldouble.c b/libgcc/config/rs6000/ibm-ldouble.c
index 96fcc77a881..28e02e995d4 100644
--- a/libgcc/config/rs6000/ibm-ldouble.c
+++ b/libgcc/config/rs6000/ibm-ldouble.c
@@ -42,10 +42,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
represented as (1.0, +0.0) or (1.0, -0.0), and the low part of a
NaN is don't-care.
- This code currently assumes big-endian. */
+ This code currently assumes the most significant double is in
+ the lower numbered register or lower addressed memory. */
-#if (!defined (__LITTLE_ENDIAN__) \
- && (defined (__MACH__) || defined (__powerpc__) || defined (_AIX)))
+#if defined (__MACH__) || defined (__powerpc__) || defined (_AIX)
#define fabs(x) __builtin_fabs(x)
#define isless(x, y) __builtin_isless (x, y)
diff --git a/libgcc/config/sparc/sol2-unwind.h b/libgcc/config/sparc/sol2-unwind.h
index 584a9b09666..4a8c42f5908 100644
--- a/libgcc/config/sparc/sol2-unwind.h
+++ b/libgcc/config/sparc/sol2-unwind.h
@@ -403,7 +403,12 @@ MD_FALLBACK_FRAME_STATE_FOR (struct _Unwind_Context *context,
fs->retaddr_column = 0;
fs->regs.reg[0].how = REG_SAVED_OFFSET;
fs->regs.reg[0].loc.offset = (long)shifted_ra_location - new_cfa;
- fs->signal_frame = 1;
+
+ /* SIGFPE for IEEE-754 exceptions is delivered after the faulting insn
+ rather than before it, so don't set fs->signal_frame in that case.
+ We test whether the cexc field of the FSR is zero. */
+ if ((mctx->fpregs.fpu_fsr & 0x1f) == 0)
+ fs->signal_frame = 1;
return _URC_NO_REASON;
}
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 59ac4da949f..38a53190179 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,11 @@
+2013-06-01 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/57496
+ * io/write_float.def (ISFINITE2Q, ISFINITE2, ISFINITE2L, ISFINITE,
+ SIGNBIT2Q, SIGNBIT2, SIGNBIT2L, SIGNBIT, ISNAN2Q, ISNAN2, ISNAN2L,
+ ISNAN): New macros.
+ (output_float_FMT_G_,WRITE_FLOAT): Use them.
+
2013-05-24 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* acinclude.m4 (libgfor_cv_have_as_needed): Check for -z ignore, too.
@@ -19,25 +27,25 @@
2013-04-29 Janne Blomqvist <jb@gcc.gnu.org>
- * intrinsics/system_clock (gf_gettime_mono): Use variable
- resolution for fractional seconds argument.
- (system_clock_4): Simplify, update for gf_gettime_mono change.
- (system_clock_8): Likewise.
+ * intrinsics/system_clock (gf_gettime_mono): Use variable
+ resolution for fractional seconds argument.
+ (system_clock_4): Simplify, update for gf_gettime_mono change.
+ (system_clock_8): Likewise.
2013-04-29 Janne Blomqvist <jb@gcc.gnu.org>
- PR fortran/56981
- * io/transfer.c (next_record_w_unf): First fix head marker, then
- write tail.
- (next_record): Call flush_if_unbuffered.
- * io/unix.c (struct unix_stream): Add field unbuffered.
- (flush_if_unbuffered): New function.
- (fd_to_stream): New argument.
- (open_external): Fix fd_to_stream call.
- (input_stream): Likewise.
- (output_stream): Likewise.
- (error_stream): Likewise.
- * io/unix.h (flush_if_unbuffered): New prototype.
+ PR fortran/56981
+ * io/transfer.c (next_record_w_unf): First fix head marker, then
+ write tail.
+ (next_record): Call flush_if_unbuffered.
+ * io/unix.c (struct unix_stream): Add field unbuffered.
+ (flush_if_unbuffered): New function.
+ (fd_to_stream): New argument.
+ (open_external): Fix fd_to_stream call.
+ (input_stream): Likewise.
+ (output_stream): Likewise.
+ (error_stream): Likewise.
+ * io/unix.h (flush_if_unbuffered): New prototype.
2013-04-28 Janne Blomqvist <jb@gcc.gnu.org>
diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def
index a157f0b6328..b634ff54f0b 100644
--- a/libgfortran/io/write_float.def
+++ b/libgfortran/io/write_float.def
@@ -961,6 +961,34 @@ __qmath_(quadmath_snprintf) (buffer, size, "%+-#.*Qf", \
#endif
+#if defined(GFC_REAL_16_IS_FLOAT128)
+#define ISFINITE2Q(val) finiteq(val)
+#endif
+#define ISFINITE2(val) isfinite(val)
+#define ISFINITE2L(val) isfinite(val)
+
+#define ISFINITE(suff,val) TOKENPASTE(ISFINITE2,suff)(val)
+
+
+#if defined(GFC_REAL_16_IS_FLOAT128)
+#define SIGNBIT2Q(val) signbitq(val)
+#endif
+#define SIGNBIT2(val) signbit(val)
+#define SIGNBIT2L(val) signbit(val)
+
+#define SIGNBIT(suff,val) TOKENPASTE(SIGNBIT2,suff)(val)
+
+
+#if defined(GFC_REAL_16_IS_FLOAT128)
+#define ISNAN2Q(val) isnanq(val)
+#endif
+#define ISNAN2(val) isnan(val)
+#define ISNAN2L(val) isnan(val)
+
+#define ISNAN(suff,val) TOKENPASTE(ISNAN2,suff)(val)
+
+
+
/* Generate corresponding I/O format for FMT_G and output.
The rules to translate FMT_G to FMT_E or FMT_F from DEC fortran
LRM (table 11-2, Chapter 11, "I/O Formatting", P11-25) is:
@@ -1127,7 +1155,7 @@ OUTPUT_FLOAT_FMT_G(16,L)
{\
GFC_REAL_ ## x tmp; \
tmp = * (GFC_REAL_ ## x *)source; \
- if (isfinite (tmp)) \
+ if (ISFINITE (y,tmp)) \
nprinted = DTOA(y,0,tmp); \
else\
nprinted = -1;\
@@ -1194,10 +1222,10 @@ determine_en_precision (st_parameter_dt *dtp, const fnode *f,
{\
GFC_REAL_ ## x tmp;\
tmp = * (GFC_REAL_ ## x *)source;\
- sign_bit = signbit (tmp);\
- if (!isfinite (tmp))\
+ sign_bit = SIGNBIT (y,tmp);\
+ if (!ISFINITE (y,tmp))\
{ \
- write_infnan (dtp, f, isnan (tmp), sign_bit);\
+ write_infnan (dtp, f, ISNAN (y,tmp), sign_bit);\
return;\
}\
tmp = sign_bit ? -tmp : tmp;\
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 1747cec0988..a78190f24fc 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,10 @@
+2013-06-06 Thomas Schwinge <thomas@codesourcery.com>
+
+ * configure.tgt (XCFLAGS): Add -ftls-model=initial-exec for
+ GNU/Hurd, as done for Linux-based systems.
+
+ * config/posix/ptrlock.h: Fix comment.
+
2013-05-27 Tobias Burnus <burnus@net-b.de>
PR fortran/57423
diff --git a/libgomp/config/posix/ptrlock.h b/libgomp/config/posix/ptrlock.h
index eec4e19df7c..76c2deb173d 100644
--- a/libgomp/config/posix/ptrlock.h
+++ b/libgomp/config/posix/ptrlock.h
@@ -22,9 +22,8 @@
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
-/* This is a Linux specific implementation of a mutex synchronization
- mechanism for libgomp. This type is private to the library. This
- implementation uses atomic instructions and the futex syscall. */
+/* This is a generic POSIX implementation of a mutex synchronization
+ mechanism for libgomp. This type is private to the library. */
#ifndef GOMP_PTRLOCK_H
#define GOMP_PTRLOCK_H 1
diff --git a/libgomp/configure.tgt b/libgomp/configure.tgt
index 2eecc93a349..8b1841792d4 100644
--- a/libgomp/configure.tgt
+++ b/libgomp/configure.tgt
@@ -14,7 +14,10 @@
if test $gcc_cv_have_tls = yes ; then
case "${target}" in
- *-*-linux*)
+ *-*-k*bsd*-gnu*)
+ ;;
+
+ *-*-linux* | *-*-gnu*)
XCFLAGS="${XCFLAGS} -ftls-model=initial-exec"
;;
esac
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index a30a363a3f5..96bc317b0a3 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,15 @@
+2013-05-31 Matt Burgess <matthew@linuxfromscratch.org>
+
+ PR other/56780
+ * libiberty/configure.ac: Move test for --enable-install-libiberty
+ outside of the 'with_target_subdir' test so that it actually gets
+ run. Add output messages to show the test result.
+ * libiberty/configure: Regenerate.
+ * libiberty/Makefile.in (install_to_libdir): Place the
+ installation of the libiberty library in the same guard as that
+ used for the headers to prevent it being installed unless
+ requested via --enable-install-libiberty.
+
2013-05-06 David Edelsohn <dje.gcc@gmail.com>
Peter Bergner <bergner@vnet.ibm.com>
Segher Boessenkool <segher@kernel.crashing.org>
diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in
index f6a3ebd6d3d..75ff82d984a 100644
--- a/libiberty/Makefile.in
+++ b/libiberty/Makefile.in
@@ -355,19 +355,19 @@ install-strip: install
# since it will be passed the multilib flags.
MULTIOSDIR = `$(CC) $(CFLAGS) -print-multi-os-directory`
install_to_libdir: all
- ${mkinstalldirs} $(DESTDIR)$(libdir)/$(MULTIOSDIR)
- $(INSTALL_DATA) $(TARGETLIB) $(DESTDIR)$(libdir)/$(MULTIOSDIR)/$(TARGETLIB)n
- ( cd $(DESTDIR)$(libdir)/$(MULTIOSDIR) ; chmod 644 $(TARGETLIB)n ;$(RANLIB) $(TARGETLIB)n )
- mv -f $(DESTDIR)$(libdir)/$(MULTIOSDIR)/$(TARGETLIB)n $(DESTDIR)$(libdir)/$(MULTIOSDIR)/$(TARGETLIB)
if test -n "${target_header_dir}"; then \
- case "${target_header_dir}" in \
- /*) thd=${target_header_dir};; \
- *) thd=${includedir}/${target_header_dir};; \
- esac; \
- ${mkinstalldirs} $(DESTDIR)$${thd}; \
- for h in ${INSTALLED_HEADERS}; do \
- ${INSTALL_DATA} $$h $(DESTDIR)$${thd}; \
- done; \
+ ${mkinstalldirs} $(DESTDIR)$(libdir)/$(MULTIOSDIR); \
+ $(INSTALL_DATA) $(TARGETLIB) $(DESTDIR)$(libdir)/$(MULTIOSDIR)/$(TARGETLIB)n; \
+ ( cd $(DESTDIR)$(libdir)/$(MULTIOSDIR) ; chmod 644 $(TARGETLIB)n ;$(RANLIB) $(TARGETLIB)n ); \
+ mv -f $(DESTDIR)$(libdir)/$(MULTIOSDIR)/$(TARGETLIB)n $(DESTDIR)$(libdir)/$(MULTIOSDIR)/$(TARGETLIB); \
+ case "${target_header_dir}" in \
+ /*) thd=${target_header_dir};; \
+ *) thd=${includedir}/${target_header_dir};; \
+ esac; \
+ ${mkinstalldirs} $(DESTDIR)$${thd}; \
+ for h in ${INSTALLED_HEADERS}; do \
+ ${INSTALL_DATA} $$h $(DESTDIR)$${thd}; \
+ done; \
fi
@$(MULTIDO) $(FLAGS_TO_PASS) multi-do DO=install
diff --git a/libiberty/configure b/libiberty/configure
index 17bd3c5bacb..e601ccd99f4 100755
--- a/libiberty/configure
+++ b/libiberty/configure
@@ -675,8 +675,8 @@ with_cross_host
with_newlib
enable_maintainer_mode
enable_multilib
-enable_largefile
enable_install_libiberty
+enable_largefile
'
ac_precious_vars='build_alias
host_alias
@@ -1303,8 +1303,8 @@ Optional Features:
enable make rules and dependencies not useful
(and sometimes confusing) to the casual installer
--enable-multilib build many library versions (default)
+ --enable-install-libiberty Install headers and library for end users
--disable-largefile omit support for large files
- --enable-install-libiberty Install headers for end users
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -2784,6 +2784,35 @@ if test $cross_compiling = no && test $multilib = yes \
cross_compiling=maybe
fi
+# We may wish to install the target headers somewhere.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to install libiberty headers and static library" >&5
+$as_echo_n "checking whether to install libiberty headers and static library... " >&6; }
+
+# Check whether --enable-install-libiberty was given.
+if test "${enable_install_libiberty+set}" = set; then :
+ enableval=$enable_install_libiberty; enable_install_libiberty=$enableval
+else
+ enable_install_libiberty=no
+fi
+
+# Option parsed, now set things appropriately.
+case x"$enable_install_libiberty" in
+ xyes|x)
+ target_header_dir=libiberty
+ ;;
+ xno)
+ target_header_dir=
+ ;;
+ *)
+ # This could be sanity-checked in various ways...
+ target_header_dir="${enable_install_libiberty}"
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_install_libiberty" >&5
+$as_echo "$enable_install_libiberty" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: target_header_dir = $target_header_dir" >&5
+$as_echo "$as_me: target_header_dir = $target_header_dir" >&6;}
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
@@ -5761,29 +5790,6 @@ _ACEOF
esac
- # We may wish to install the target headers somewhere.
- # Check whether --enable-install-libiberty was given.
-if test "${enable_install_libiberty+set}" = set; then :
- enableval=$enable_install_libiberty; enable_install_libiberty=$enableval
-else
- enable_install_libiberty=no
-fi
-
- # Option parsed, now set things appropriately.
- case x"$enable_install_libiberty" in
- xyes|x)
- target_header_dir=libiberty
- ;;
- xno)
- target_header_dir=
- ;;
- *)
- # This could be sanity-checked in various ways...
- target_header_dir="${enable_install_libiberty}"
- ;;
- esac
-
-
else
# Not a target library, so we set things up to run the test suite.
diff --git a/libiberty/configure.ac b/libiberty/configure.ac
index c7638942644..fcea46f6c7b 100644
--- a/libiberty/configure.ac
+++ b/libiberty/configure.ac
@@ -128,6 +128,31 @@ if test $cross_compiling = no && test $multilib = yes \
cross_compiling=maybe
fi
+# We may wish to install the target headers somewhere.
+AC_MSG_CHECKING([whether to install libiberty headers and static library])
+dnl install-libiberty is disabled by default
+
+AC_ARG_ENABLE(install-libiberty,
+[ --enable-install-libiberty Install headers and library for end users],
+enable_install_libiberty=$enableval,
+enable_install_libiberty=no)dnl
+
+# Option parsed, now set things appropriately.
+case x"$enable_install_libiberty" in
+ xyes|x)
+ target_header_dir=libiberty
+ ;;
+ xno)
+ target_header_dir=
+ ;;
+ *)
+ # This could be sanity-checked in various ways...
+ target_header_dir="${enable_install_libiberty}"
+ ;;
+esac
+AC_MSG_RESULT($enable_install_libiberty)
+AC_MSG_NOTICE([target_header_dir = $target_header_dir])
+
GCC_NO_EXECUTABLES
AC_PROG_CC
AC_SYS_LARGEFILE
@@ -492,27 +517,6 @@ if test -n "${with_target_subdir}"; then
esac
- # We may wish to install the target headers somewhere.
- AC_ARG_ENABLE(install-libiberty,
- [ --enable-install-libiberty Install headers for end users],
- enable_install_libiberty=$enableval,
- enable_install_libiberty=no)dnl
-
- # Option parsed, now set things appropriately.
- case x"$enable_install_libiberty" in
- xyes|x)
- target_header_dir=libiberty
- ;;
- xno)
- target_header_dir=
- ;;
- *)
- # This could be sanity-checked in various ways...
- target_header_dir="${enable_install_libiberty}"
- ;;
- esac
-
-
else
# Not a target library, so we set things up to run the test suite.
diff --git a/libitm/ChangeLog b/libitm/ChangeLog
index 04490fd8b1d..ed9114b9147 100644
--- a/libitm/ChangeLog
+++ b/libitm/ChangeLog
@@ -1,3 +1,15 @@
+2013-03-31 Gerald Pfeifer <gerald@pfeifer.com>
+
+ PR bootstrap/56714
+ * local_atomic (__always_inline): Always define our version.
+ (__calculate_memory_order): Mark inline.
+ (atomic_thread_fence): Ditto.
+ (atomic_signal_fence): Ditto.
+ (atomic_bool::atomic_flag_test_and_set_explicit): Ditto.
+ (atomic_bool::atomic_flag_clear_explicit): Ditto.
+ (atomic_bool::atomic_flag_test_and_set): Ditto.
+ (atomic_bool::atomic_flag_clear): Ditto.
+
2013-04-23 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* config/s390/sjlj.S: New file.
diff --git a/libitm/local_atomic b/libitm/local_atomic
index 4cd961af9ba..f6bbb11695c 100644
--- a/libitm/local_atomic
+++ b/libitm/local_atomic
@@ -41,9 +41,8 @@
#ifndef _GLIBCXX_ATOMIC
#define _GLIBCXX_ATOMIC 1
-#ifndef __always_inline
-#define __always_inline inline __attribute__((always_inline))
-#endif
+#undef __always_inline
+#define __always_inline __attribute__((always_inline))
// #pragma GCC system_header
@@ -75,7 +74,7 @@ namespace std // _GLIBCXX_VISIBILITY(default)
memory_order_seq_cst
} memory_order;
- __always_inline memory_order
+ inline __always_inline memory_order
__calculate_memory_order(memory_order __m) noexcept
{
const bool __cond1 = __m == memory_order_release;
@@ -85,13 +84,13 @@ namespace std // _GLIBCXX_VISIBILITY(default)
return __mo2;
}
- __always_inline void
+ inline __always_inline void
atomic_thread_fence(memory_order __m) noexcept
{
__atomic_thread_fence (__m);
}
- __always_inline void
+ inline __always_inline void
atomic_signal_fence(memory_order __m) noexcept
{
__atomic_thread_fence (__m);
@@ -1545,38 +1544,38 @@ namespace std // _GLIBCXX_VISIBILITY(default)
// Function definitions, atomic_flag operations.
- __always_inline bool
+ inline __always_inline bool
atomic_flag_test_and_set_explicit(atomic_flag* __a,
memory_order __m) noexcept
{ return __a->test_and_set(__m); }
- __always_inline bool
+ inline __always_inline bool
atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
memory_order __m) noexcept
{ return __a->test_and_set(__m); }
- __always_inline void
+ inline __always_inline void
atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
{ __a->clear(__m); }
- __always_inline void
+ inline __always_inline void
atomic_flag_clear_explicit(volatile atomic_flag* __a,
memory_order __m) noexcept
{ __a->clear(__m); }
- __always_inline bool
+ inline __always_inline bool
atomic_flag_test_and_set(atomic_flag* __a) noexcept
{ return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
- __always_inline bool
+ inline __always_inline bool
atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
{ return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
- __always_inline void
+ inline __always_inline void
atomic_flag_clear(atomic_flag* __a) noexcept
{ atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
- __always_inline void
+ inline __always_inline void
atomic_flag_clear(volatile atomic_flag* __a) noexcept
{ atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index 8cc31a318fc..d2c80b35704 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,3 +1,8 @@
+2013-06-03 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * sanitizer_common/sanitizer_linux.cc (MemoryMappingLayout::Next):
+ Cherry pick upstream r182922.
+
2013-05-07 Christophe Lyon <christophe.lyon@linaro.org>
* configure.tgt: Add ARM pattern.
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cc b/libsanitizer/sanitizer_common/sanitizer_linux.cc
index 06e5a0a6441..1ab6f780fa3 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_linux.cc
@@ -410,7 +410,9 @@ bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset,
CHECK_EQ(*current_++, ' ');
while (IsDecimal(*current_))
current_++;
- CHECK_EQ(*current_++, ' ');
+ // Qemu may lack the trailing space.
+ // http://code.google.com/p/address-sanitizer/issues/detail?id=160
+ // CHECK_EQ(*current_++, ' ');
// Skip spaces.
while (current_ < next_line && *current_ == ' ')
current_++;
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index f4faf6b1cb4..842a9afc9f1 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,46 @@
+2013-06-05 Tom Tromey <tromey@redhat.com>
+
+ * testsuite/libstdc++-prettyprinters/shared_ptr.cc: Use -O0.
+
+2013-06-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57419
+ * testsuite/20_util/default_delete/48631_neg.cc: Adjust.
+
+2013-06-01 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ * include/std/chrono: Collapse redundant 'inline' from 'inline
+ constexpr'.
+ * include/std/tuple: Ditto.
+ * include/bits/move.h: Ditto.
+
+2013-05-30 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ Implement N3642 - User-defined Literals for Standard Library Types
+ * include/bits/parse_numbers.h: New.
+ * include/std/chrono: Add duration literal operators.
+ * include/bits/basic_string.h: Add string literal operators.
+ * include/Makefile.in: Add parse_numbers.h.
+ * include/Makefile.am: Ditto.
+ * testsuite/20_util/duration/literals/values.cc: New.
+ * testsuite/20_util/duration/literals/types.cc: New.
+ * testsuite/20_util/duration/requirements/typedefs_neg1.cc: Adjust.
+ * testsuite/20_util/duration/requirements/typedefs_neg2.cc: Adjust.
+ * testsuite/20_util/duration/requirements/typedefs_neg3.cc: Adjust.
+ * testsuite/21_strings/basic_string/literals/values.cc: New.
+ * testsuite/21_strings/basic_string/literals/types.cc: New.
+
+2013-05-28 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * src/c++11/compatibility-chrono.cc (steady_clock::now()): If
+ !_GLIBCXX_USE_GETTIMEOFDAY perform conversion inline instead of
+ calling non-existent from_time_t.
+
+2013-05-28 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * config/abi/post/solaris2.10/sparcv9/baseline_symbols.txt:
+ Regenerate.
+
2013-05-24 Benjamin Kosnik <bkoz@redhat.com>
* include/std/chrono: Wrap clocks in inline namespace _V2.
diff --git a/libstdc++-v3/config/abi/post/solaris2.10/sparcv9/baseline_symbols.txt b/libstdc++-v3/config/abi/post/solaris2.10/sparcv9/baseline_symbols.txt
index d324ca0db9f..ff69637851f 100644
--- a/libstdc++-v3/config/abi/post/solaris2.10/sparcv9/baseline_symbols.txt
+++ b/libstdc++-v3/config/abi/post/solaris2.10/sparcv9/baseline_symbols.txt
@@ -1904,7 +1904,6 @@ FUNC:_ZNSt6__norm15_List_node_base7_M_hookEPS0_@@GLIBCXX_3.4.14
FUNC:_ZNSt6__norm15_List_node_base7reverseEv@@GLIBCXX_3.4.9
FUNC:_ZNSt6__norm15_List_node_base8transferEPS0_S1_@@GLIBCXX_3.4.9
FUNC:_ZNSt6__norm15_List_node_base9_M_unhookEv@@GLIBCXX_3.4.14
-FUNC:_ZNSt6chrono12steady_clock3nowEv@@GLIBCXX_3.4.19
FUNC:_ZNSt6chrono12system_clock3nowEv@@GLIBCXX_3.4.11
FUNC:_ZNSt6gslice8_IndexerC1EmRKSt8valarrayImES4_@@GLIBCXX_3.4
FUNC:_ZNSt6gslice8_IndexerC2EmRKSt8valarrayImES4_@@GLIBCXX_3.4
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index e8ef7066bcd..f09300b8bee 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -117,6 +117,7 @@ bits_headers = \
${bits_srcdir}/move.h \
${bits_srcdir}/ostream.tcc \
${bits_srcdir}/ostream_insert.h \
+ ${bits_srcdir}/parse_numbers.h \
${bits_srcdir}/postypes.h \
${bits_srcdir}/ptr_traits.h \
${bits_srcdir}/random.h \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 2ba9433bd7d..a090cad9fce 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -379,6 +379,7 @@ bits_headers = \
${bits_srcdir}/move.h \
${bits_srcdir}/ostream.tcc \
${bits_srcdir}/ostream_insert.h \
+ ${bits_srcdir}/parse_numbers.h \
${bits_srcdir}/postypes.h \
${bits_srcdir}/ptr_traits.h \
${bits_srcdir}/random.h \
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index 23bd9b9c096..a249df23742 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -3106,6 +3106,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
+#if __cplusplus > 201103L
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+inline namespace literals {
+inline namespace string_literals {
+
+ inline basic_string<char>
+ operator"" s(const char* __str, size_t __len)
+ { return basic_string<char>{__str, __len}; }
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+ inline basic_string<wchar_t>
+ operator"" s(const wchar_t* __str, size_t __len)
+ { return basic_string<wchar_t>{__str, __len}; }
+#endif
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+ inline basic_string<char16_t>
+ operator"" s(const char16_t* __str, size_t __len)
+ { return basic_string<char16_t>{__str, __len}; }
+
+ inline basic_string<char32_t>
+ operator"" s(const char32_t* __str, size_t __len)
+ { return basic_string<char32_t>{__str, __len}; }
+#endif
+
+} // inline namespace string_literals
+} // inline namespace literals
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // __cplusplus > 201103L
+
#endif // C++11
#endif /* _BASIC_STRING_H */
diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index fb6c61fcc0a..d54edcd4168 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -116,7 +116,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* type is copyable, in which case an lvalue-reference is returned instead.
*/
template<typename _Tp>
- inline constexpr typename
+ constexpr typename
conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>::type
move_if_noexcept(_Tp& __x) noexcept
{ return std::move(__x); }
diff --git a/libstdc++-v3/include/bits/parse_numbers.h b/libstdc++-v3/include/bits/parse_numbers.h
new file mode 100644
index 00000000000..eaa3d27a18a
--- /dev/null
+++ b/libstdc++-v3/include/bits/parse_numbers.h
@@ -0,0 +1,417 @@
+// Components for compile-time parsing of numbers -*- C++ -*-
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/parse_numbers.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{chrono}
+ */
+
+#ifndef _PARSE_NUMBERS_H
+#define _PARSE_NUMBERS_H 1
+
+#pragma GCC system_header
+
+// From n3642.pdf except I added binary literals and digit separator '`'.
+
+#if __cplusplus > 201103L
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+namespace __parse_int {
+
+ template<unsigned _Base, char _Dig>
+ struct _Digit;
+
+ template<unsigned _Base>
+ struct _Digit<_Base, '0'>
+ {
+ static constexpr bool valid{true};
+ static constexpr unsigned value{0};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, '1'>
+ {
+ static constexpr bool valid{true};
+ static constexpr unsigned value{1};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, '2'>
+ {
+ static_assert(_Base > 2, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{2};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, '3'>
+ {
+ static_assert(_Base > 3, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{3};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, '4'>
+ {
+ static_assert(_Base > 4, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{4};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, '5'>
+ {
+ static_assert(_Base > 5, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{5};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, '6'>
+ {
+ static_assert(_Base > 6, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{6};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, '7'>
+ {
+ static_assert(_Base > 7, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{7};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, '8'>
+ {
+ static_assert(_Base > 8, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{8};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, '9'>
+ {
+ static_assert(_Base > 9, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{9};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, 'a'>
+ {
+ static_assert(_Base > 0xa, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{0xa};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, 'A'>
+ {
+ static_assert(_Base > 0xa, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{0xa};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, 'b'>
+ {
+ static_assert(_Base > 0xb, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{0xb};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, 'B'>
+ {
+ static_assert(_Base > 0xb, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{0xb};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, 'c'>
+ {
+ static_assert(_Base > 0xc, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{0xc};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, 'C'>
+ {
+ static_assert(_Base > 0xc, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{0xc};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, 'd'>
+ {
+ static_assert(_Base > 0xd, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{0xd};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, 'D'>
+ {
+ static_assert(_Base > 0xd, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{0xd};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, 'e'>
+ {
+ static_assert(_Base > 0xe, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{0xe};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, 'E'>
+ {
+ static_assert(_Base > 0xe, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{0xe};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, 'f'>
+ {
+ static_assert(_Base > 0xf, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{0xf};
+ };
+
+ template<unsigned _Base>
+ struct _Digit<_Base, 'F'>
+ {
+ static_assert(_Base > 0xf, "invalid digit");
+ static constexpr bool valid{true};
+ static constexpr unsigned value{0xf};
+ };
+
+ // Digit separator
+ template<unsigned _Base>
+ struct _Digit<_Base, '`'>
+ {
+ static constexpr bool valid{false};
+ static constexpr unsigned value{0};
+ };
+
+
+//------------------------------------------------------------------------------
+
+ template<unsigned _Base, char _Dig, char... _Digs>
+ struct _Digits_help
+ {
+ static constexpr unsigned
+ value{_Digit<_Base, _Dig>::valid ?
+ 1U + _Digits_help<_Base, _Digs...>::value :
+ _Digits_help<_Base, _Digs...>::value};
+ };
+
+ template<unsigned _Base, char _Dig>
+ struct _Digits_help<_Base, _Dig>
+ {
+ static constexpr unsigned value{_Digit<_Base, _Dig>::valid ? 1U : 0U};
+ };
+
+ template<unsigned _Base, char... _Digs>
+ struct _Digits
+ {
+ static constexpr unsigned value{_Digits_help<_Base, _Digs...>::value};
+ };
+
+ template<unsigned _Base>
+ struct _Digits<_Base>
+ {
+ static constexpr unsigned value{0U};
+ };
+
+//------------------------------------------------------------------------------
+
+ template<unsigned _Base, char _Dig, char... _Digs>
+ struct _Power_help
+ {
+ static constexpr unsigned
+ value{_Digit<_Base, _Dig>::valid ?
+ _Base * _Power_help<_Base, _Digs...>::value :
+ _Power_help<_Base, _Digs...>::value};
+ };
+
+ template<unsigned _Base, char _Dig>
+ struct _Power_help<_Base, _Dig>
+ {
+ static constexpr unsigned value{_Digit<_Base, _Dig>::valid ? 1U : 0U};
+ };
+
+ template<unsigned _Base, char... _Digs>
+ struct _Power
+ {
+ static constexpr unsigned value{_Power_help<_Base, _Digs...>::value};
+ };
+
+ template<unsigned _Base>
+ struct _Power<_Base>
+ {
+ static constexpr unsigned value{0U};
+ };
+
+//------------------------------------------------------------------------------
+
+ template<unsigned _Base, unsigned _Pow, char _Dig, char... _Digs>
+ struct _Number_help
+ {
+ static constexpr unsigned
+ value{_Digit<_Base, _Dig>::valid ?
+ _Pow * _Digit<_Base, _Dig>::value
+ + _Number_help<_Base, _Pow / _Base, _Digs...>::value :
+ _Number_help<_Base, _Pow, _Digs...>::value};
+ };
+
+ template<unsigned _Base, unsigned _Pow, char _Dig>
+ struct _Number_help<_Base, _Pow, _Dig>
+ {
+ //static_assert(_Pow == 1U, "power should be one");
+ static constexpr unsigned
+ value{_Digit<_Base, _Dig>::valid ? _Digit<_Base, _Dig>::value : 0U};
+ };
+
+ template<unsigned _Base, char... _Digs>
+ struct _Number
+ {
+ static constexpr unsigned
+ value{_Number_help<_Base, _Power<_Base, _Digs...>::value,
+ _Digs...>::value};
+ };
+
+ template<unsigned _Base>
+ struct _Number<_Base>
+ {
+ static constexpr unsigned value{0U};
+ };
+
+//------------------------------------------------------------------------------
+// This _Parse_int is the same 'level' as the old _Base_dispatch.
+
+ template<char... _Digs>
+ struct _Parse_int;
+
+ template<char... _Digs>
+ struct _Parse_int<'0', 'b', _Digs...>
+ {
+ static constexpr unsigned long long
+ value{_Number<2U, _Digs...>::value};
+ };
+
+ template<char... _Digs>
+ struct _Parse_int<'0', 'B', _Digs...>
+ {
+ static constexpr unsigned long long
+ value{_Number<2U, _Digs...>::value};
+ };
+
+ template<char... _Digs>
+ struct _Parse_int<'0', 'x', _Digs...>
+ {
+ static constexpr unsigned long long
+ value{_Number<16U, _Digs...>::value};
+ };
+
+ template<char... _Digs>
+ struct _Parse_int<'0', 'X', _Digs...>
+ {
+ static constexpr unsigned long long
+ value{_Number<16U, _Digs...>::value};
+ };
+
+ template<char... _Digs>
+ struct _Parse_int<'0', _Digs...>
+ {
+ static constexpr unsigned long long
+ value{_Number<8U, _Digs...>::value};
+ };
+
+ template<char... _Digs>
+ struct _Parse_int
+ {
+ static constexpr unsigned long long
+ value{_Number<10U, _Digs...>::value};
+ };
+
+} // namespace __parse_int
+
+
+namespace __select_int {
+
+ template<unsigned long long _Val, typename... _Ints>
+ struct _Select_int_base;
+
+ template<unsigned long long _Val, typename _IntType, typename... _Ints>
+ struct _Select_int_base<_Val, _IntType, _Ints...>
+ : integral_constant
+ <
+ typename conditional
+ <
+ _Val <= static_cast<unsigned long long>
+ (std::numeric_limits<_IntType>::max()),
+ _IntType,
+ typename _Select_int_base<_Val, _Ints...>::value_type
+ >::type,
+ _Val
+ >
+ { };
+
+ template<unsigned long long _Val>
+ struct _Select_int_base<_Val> : integral_constant<unsigned long long, _Val>
+ { };
+
+ template<char... _Digs>
+ struct _Select_int
+ : _Select_int_base<
+ __parse_int::_Parse_int<_Digs...>::value,
+ unsigned char,
+ unsigned short,
+ unsigned int,
+ unsigned long,
+ unsigned long long
+ >
+ { };
+
+} // namespace __select_int
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // __cplusplus > 201103L
+
+#endif // _PARSE_NUMBERS_H
diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index 6d9df7d7dda..7a574a62894 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -39,6 +39,7 @@
#include <type_traits>
#include <limits>
#include <ctime>
+#include <bits/parse_numbers.h> // for literals support.
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
@@ -786,4 +787,136 @@ _GLIBCXX_END_NAMESPACE_VERSION
#endif // C++11
+#if __cplusplus > 201103L
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+inline namespace literals {
+inline namespace chrono_literals {
+
+ namespace __detail {
+
+ using namespace __parse_int;
+
+ template<unsigned long long _Val, typename _Dur>
+ struct _Select_type
+ : conditional<
+ _Val <= static_cast<unsigned long long>
+ (numeric_limits<typename _Dur::rep>::max()),
+ _Dur, void>
+ {
+ static constexpr typename _Select_type::type
+ value{static_cast<typename _Select_type::type>(_Val)};
+ };
+
+ template<unsigned long long _Val, typename _Dur>
+ constexpr typename _Select_type<_Val, _Dur>::type
+ _Select_type<_Val, _Dur>::value;
+
+ } // __detail
+
+ constexpr chrono::duration<long double, ratio<3600,1>>
+ operator"" h(long double __hours)
+ { return chrono::duration<long double, ratio<3600,1>>{__hours}; }
+
+ template <char... _Digits>
+ constexpr typename
+ __detail::_Select_type<__select_int::_Select_int<_Digits...>::value,
+ chrono::hours>::type
+ operator"" h()
+ {
+ return __detail::_Select_type<
+ __select_int::_Select_int<_Digits...>::value,
+ chrono::hours>::value;
+ }
+
+ constexpr chrono::duration<long double, ratio<60,1>>
+ operator"" min(long double __mins)
+ { return chrono::duration<long double, ratio<60,1>>{__mins}; }
+
+ template <char... _Digits>
+ constexpr typename
+ __detail::_Select_type<__select_int::_Select_int<_Digits...>::value,
+ chrono::minutes>::type
+ operator"" min()
+ {
+ return __detail::_Select_type<
+ __select_int::_Select_int<_Digits...>::value,
+ chrono::minutes>::value;
+ }
+
+ constexpr chrono::duration<long double>
+ operator"" s(long double __secs)
+ { return chrono::duration<long double>{__secs}; }
+
+ template <char... _Digits>
+ constexpr typename
+ __detail::_Select_type<__select_int::_Select_int<_Digits...>::value,
+ chrono::seconds>::type
+ operator"" s()
+ {
+ return __detail::_Select_type<
+ __select_int::_Select_int<_Digits...>::value,
+ chrono::seconds>::value;
+ }
+
+ constexpr chrono::duration<long double, milli>
+ operator"" ms(long double __msecs)
+ { return chrono::duration<long double, milli>{__msecs}; }
+
+ template <char... _Digits>
+ constexpr typename
+ __detail::_Select_type<__select_int::_Select_int<_Digits...>::value,
+ chrono::milliseconds>::type
+ operator"" ms()
+ {
+ return __detail::_Select_type<
+ __select_int::_Select_int<_Digits...>::value,
+ chrono::milliseconds>::value;
+ }
+
+ constexpr chrono::duration<long double, micro>
+ operator"" us(long double __usecs)
+ { return chrono::duration<long double, micro>{__usecs}; }
+
+ template <char... _Digits>
+ constexpr typename
+ __detail::_Select_type<__select_int::_Select_int<_Digits...>::value,
+ chrono::microseconds>::type
+ operator"" us()
+ {
+ return __detail::_Select_type<
+ __select_int::_Select_int<_Digits...>::value,
+ chrono::microseconds>::value;
+ }
+
+ constexpr chrono::duration<long double, nano>
+ operator"" ns(long double __nsecs)
+ { return chrono::duration<long double, nano>{__nsecs}; }
+
+ template <char... _Digits>
+ constexpr typename
+ __detail::_Select_type<__select_int::_Select_int<_Digits...>::value,
+ chrono::nanoseconds>::type
+ operator"" ns()
+ {
+ return __detail::_Select_type<
+ __select_int::_Select_int<_Digits...>::value,
+ chrono::nanoseconds>::value;
+ }
+
+} // inline namespace chrono_literals
+} // inline namespace literals
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif //_GLIBCXX_USE_C99_STDINT_TR1
+
+#endif // __cplusplus > 201103L
+
#endif //_GLIBCXX_CHRONO
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 69f5bd1f72f..063ce02e9c7 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -856,25 +856,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename... _TElements, typename... _UElements>
- inline constexpr bool
+ constexpr bool
operator!=(const tuple<_TElements...>& __t,
const tuple<_UElements...>& __u)
{ return !(__t == __u); }
template<typename... _TElements, typename... _UElements>
- inline constexpr bool
+ constexpr bool
operator>(const tuple<_TElements...>& __t,
const tuple<_UElements...>& __u)
{ return __u < __t; }
template<typename... _TElements, typename... _UElements>
- inline constexpr bool
+ constexpr bool
operator<=(const tuple<_TElements...>& __t,
const tuple<_UElements...>& __u)
{ return !(__u < __t); }
template<typename... _TElements, typename... _UElements>
- inline constexpr bool
+ constexpr bool
operator>=(const tuple<_TElements...>& __t,
const tuple<_UElements...>& __u)
{ return !(__t < __u); }
diff --git a/libstdc++-v3/src/c++11/compatibility-chrono.cc b/libstdc++-v3/src/c++11/compatibility-chrono.cc
index fd67daec4c5..efc32f5ff95 100644
--- a/libstdc++-v3/src/c++11/compatibility-chrono.cc
+++ b/libstdc++-v3/src/c++11/compatibility-chrono.cc
@@ -78,7 +78,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
+ chrono::microseconds(tv.tv_usec)));
#else
std::time_t __sec = std::time(0);
- return system_clock::from_time_t(__sec);
+ // This is the conversion done by system_clock::from_time_t(__sec)
+ typedef chrono::time_point<system_clock, seconds> __from;
+ return time_point_cast<system_clock::duration>
+ (__from(chrono::seconds(__sec)));
#endif
}
diff --git a/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc b/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc
index d0619fd9ca0..d4c17288a99 100644
--- a/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc
@@ -27,4 +27,4 @@ struct D : B { };
D d;
std::default_delete<B[]> db;
typedef decltype(db(&d)) type; // { dg-error "use of deleted function" }
-// { dg-error "declared here" "" { target *-*-* } 122 }
+// { dg-prune-output "declared" }
diff --git a/libstdc++-v3/testsuite/20_util/duration/literals/types.cc b/libstdc++-v3/testsuite/20_util/duration/literals/types.cc
new file mode 100644
index 00000000000..67ef2faf292
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/duration/literals/types.cc
@@ -0,0 +1,74 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on string (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <chrono>
+#include <type_traits>
+
+void
+test03()
+{
+ using namespace std::literals::chrono_literals;
+
+ static_assert(std::is_same<decltype(1h), std::chrono::hours>::value,
+ "1h is std::chrono::hours");
+
+ static_assert(std::is_same<decltype(1.0h),
+ std::chrono::duration<long double, std::ratio<3600L, 1L>>>::value,
+ "1.0h is std::chrono::duration<long double, std::ratio<3600L, 1L>>");
+
+ static_assert(std::is_same<decltype(1min), std::chrono::minutes>::value,
+ "1min is std::chrono::minutes");
+
+ static_assert(std::is_same<decltype(1.0min),
+ std::chrono::duration<long double, std::ratio<60L, 1L>>>::value,
+ "1.0min is std::chrono::duration<long double, std::ratio<60L, 1L>>");
+
+ static_assert(std::is_same<decltype(1s), std::chrono::seconds>::value,
+ "1s is std::chrono::seconds");
+
+ static_assert(std::is_same<decltype(1.0s),
+ std::chrono::duration<long double, std::ratio<1L, 1L>>>::value,
+ "1.0s is std::chrono::duration<long double, std::ratio<1L, 1L>>");
+
+ static_assert(std::is_same<decltype(1ms), std::chrono::milliseconds>::value,
+ "1ms is std::chrono::milliseconds");
+
+ static_assert(std::is_same<decltype(1.0ms),
+ std::chrono::duration<long double, std::ratio<1L, 1000L>>>::value,
+ "1.0ms is std::chrono::duration<long double, std::ratio<1L, 1000L>>");
+
+ static_assert(std::is_same<decltype(1us), std::chrono::microseconds>::value,
+ "1us is std::chrono::microseconds");
+
+ static_assert(std::is_same<decltype(1.0us),
+ std::chrono::duration<long double, std::ratio<1L, 1000000L>>>::value,
+ "1.0us is std::chrono::duration<long double, std::ratio<1L, 1000000L>>");
+
+ static_assert(std::is_same<decltype(1ns), std::chrono::nanoseconds>::value,
+ "1ns is std::chrono::nanoseconds");
+
+ static_assert(std::is_same<decltype(1.0ns),
+ std::chrono::duration<long double, std::ratio<1L, 1000000000L>>>::value,
+ "1.0ns is std::chrono::duration<long double, std::ratio<1L, 1000000000L>>");
+}
diff --git a/libstdc++-v3/testsuite/20_util/duration/literals/values.cc b/libstdc++-v3/testsuite/20_util/duration/literals/values.cc
new file mode 100644
index 00000000000..37bbbd02cb7
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/duration/literals/values.cc
@@ -0,0 +1,69 @@
+// { dg-do run }
+// { dg-options "-std=gnu++1y" }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on string (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <chrono>
+#include <testsuite_hooks.h>
+
+void
+test03()
+{
+ using namespace std::literals::chrono_literals;
+
+ auto jiffy = 23ns;
+ VERIFY( jiffy == std::chrono::nanoseconds(23) );
+ auto fjiffy = 23.0ns;
+ VERIFY( (fjiffy == std::chrono::duration<long double, std::nano>(23.0L)) );
+ auto blip = 14us;
+ VERIFY( blip == std::chrono::microseconds(14) );
+ auto fblip = 14.0us;
+ VERIFY( (fblip == std::chrono::duration<long double, std::micro>(14.0L)) );
+ auto bit = 77ms;
+ VERIFY( bit == std::chrono::milliseconds(77) );
+ auto fbit = 77.0ms;
+ VERIFY( (fbit == std::chrono::duration<long double, std::milli>(77.0L)) );
+ auto warmup = 33s;
+ VERIFY( warmup == std::chrono::seconds(33) );
+ auto fwarmup = 33.0s;
+ VERIFY( (fwarmup == std::chrono::duration<long double, std::ratio<1,1>>(33.0L)) );
+ auto classtime = 50min;
+ VERIFY( classtime == std::chrono::minutes(50) );
+ auto fclasstime = 50.0min;
+ VERIFY( (fclasstime == std::chrono::duration<long double, std::ratio<60,1>>(50.0L)) );
+ auto longtime = 1h + 30min;
+ VERIFY( longtime == std::chrono::minutes(90) );
+ auto flongtime = 1.0h + 30.0min;
+ VERIFY( (flongtime == std::chrono::duration<long double, std::ratio<3600,1>>(1.0L)
+ + std::chrono::duration<long double, std::ratio<60,1>>(30.0L)) );
+ VERIFY( (flongtime == std::chrono::duration<long double, std::ratio<60,1>>(90.0L)) );
+ auto workday = 8h;
+ VERIFY( workday == std::chrono::hours(8) );
+ auto fworkday = 8.0h;
+ VERIFY( (fworkday == std::chrono::duration<long double, std::ratio<3600,1>>(8.0L)) );
+}
+
+int
+main()
+{
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg1.cc b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg1.cc
index 1b686e476cf..db4237991bf 100644
--- a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg1.cc
+++ b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg1.cc
@@ -31,5 +31,5 @@ void test01()
test_type d;
}
-// { dg-error "rep cannot be a duration" "" { target *-*-* } 245 }
+// { dg-error "rep cannot be a duration" "" { target *-*-* } 246 }
// { dg-error "required from here" "" { target *-*-* } 31 }
diff --git a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg2.cc b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg2.cc
index 2cc5cd68e0a..8da5dbff431 100644
--- a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg2.cc
+++ b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg2.cc
@@ -32,5 +32,5 @@ void test01()
test_type d; // { dg-error "required from here" }
}
-// { dg-error "must be a specialization of ratio" "" { target *-*-* } 246 }
+// { dg-error "must be a specialization of ratio" "" { target *-*-* } 247 }
// { dg-prune-output "not a member" }
diff --git a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg3.cc b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg3.cc
index a9313ccb2cc..4837f5d64fc 100644
--- a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg3.cc
+++ b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg3.cc
@@ -33,5 +33,5 @@ void test01()
test_type d;
}
-// { dg-error "period must be positive" "" { target *-*-* } 248 }
+// { dg-error "period must be positive" "" { target *-*-* } 249 }
// { dg-error "required from here" "" { target *-*-* } 33 }
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/literals/types.cc b/libstdc++-v3/testsuite/21_strings/basic_string/literals/types.cc
new file mode 100644
index 00000000000..677f5bf8560
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/literals/types.cc
@@ -0,0 +1,47 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on string (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <string>
+#include <type_traits>
+
+void
+test01()
+{
+ using namespace std::literals::string_literals;
+
+ static_assert(std::is_same<decltype("Hello"s), std::string>::value,
+ "\"Hello\"s is std::string");
+
+ static_assert(std::is_same<decltype(u8"Hello"s), std::string>::value,
+ "u8\"Hello\"s is std::string");
+
+ static_assert(std::is_same<decltype(L"Hello"s), std::wstring>::value,
+ "L\"Hello\"s is std::wstring");
+
+ static_assert(std::is_same<decltype(u"Hello"s), std::u16string>::value,
+ "u\"Hello\"s is std::u16string");
+
+ static_assert(std::is_same<decltype(U"Hello"s), std::u32string>::value,
+ "U\"Hello\"s is std::u32string");
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/literals/values.cc b/libstdc++-v3/testsuite/21_strings/basic_string/literals/values.cc
new file mode 100644
index 00000000000..09285590e2a
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/literals/values.cc
@@ -0,0 +1,50 @@
+// { dg-do run }
+// { dg-options "-std=gnu++1y" }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on string (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <string>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ using namespace std::literals::string_literals;
+
+ std::string planet = "Mercury"s;
+ std::wstring wplanet = L"Venus"s;
+ std::string u8planet = u8"Mars"s;
+ std::u16string u16planet = u"Juiter"s;
+ std::u32string u32planet = U"Saturn"s;
+
+ VERIFY( planet == std::string("Mercury") );
+ VERIFY( wplanet == std::wstring(L"Venus") );
+ VERIFY( u8planet == std::string(u8"Mars") );
+ VERIFY( u16planet == std::u16string(u"Juiter") );
+ VERIFY( u32planet == std::u32string(U"Saturn") );
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc
index 547213f9b85..0e4e6c20260 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc
@@ -1,5 +1,5 @@
// { dg-do run }
-// { dg-options "-std=gnu++11 -g" }
+// { dg-options "-std=gnu++11 -g -O0" }
// Copyright (C) 2012-2013 Free Software Foundation, Inc.
//